15 #include "windowsRegistry.h"
16 #include "config_express.h"
17 #include "textEncoder.h"
20 #ifndef WIN32_LEAN_AND_MEAN
21 #define WIN32_LEAN_AND_MEAN 1
35 bool WindowsRegistry::
36 set_string_value(
const string &key,
const string &name,
const string &value,
37 WindowsRegistry::RegLevel rl)
52 WideCharToMultiByte(CP_ACP, 0,
53 wvalue.data(), wvalue.length(),
56 if (mb_result_len == 0) {
58 <<
"Unable to convert '" << value
59 <<
"' from Unicode to MultiByte form.\n";
63 char *mb_result = (
char *)alloca(mb_result_len);
64 WideCharToMultiByte(CP_ACP, 0,
65 wvalue.data(), wvalue.length(),
66 mb_result, mb_result_len,
69 if (express_cat.is_debug()) {
71 <<
"Converted '" << value <<
"' to '" << mb_result
72 <<
"' for storing in registry.\n";
75 return do_set(key, name, REG_SZ, mb_result, mb_result_len, rl);
85 bool WindowsRegistry::
86 set_int_value(
const string &key,
const string &name,
int value,
87 WindowsRegistry::RegLevel rl)
90 return do_set(key, name, REG_DWORD, &dw,
sizeof(dw), rl);
99 WindowsRegistry::Type WindowsRegistry::
100 get_key_type(
const string &key,
const string &name,
101 WindowsRegistry::RegLevel rl)
105 if (!do_get(key, name, data_type, data, rl)) {
131 string WindowsRegistry::
132 get_string_value(
const string &key,
const string &name,
133 const string &default_value,
134 WindowsRegistry::RegLevel rl)
138 if (!do_get(key, name, data_type, data, rl)) {
139 return default_value;
142 if (data_type != REG_SZ) {
143 express_cat.warning()
144 <<
"Registry key " << key <<
" does not contain a string value.\n";
145 return default_value;
155 int wide_result_len =
156 MultiByteToWideChar(CP_ACP, 0,
157 data.data(), data.length(),
159 if (wide_result_len == 0) {
161 <<
"Unable to convert '" << data
162 <<
"' from MultiByte to Unicode form.\n";
166 wchar_t *wide_result = (
wchar_t *)alloca(wide_result_len *
sizeof(
wchar_t));
167 MultiByteToWideChar(CP_ACP, 0,
168 data.data(), data.length(),
169 wide_result, wide_result_len);
171 wstring wdata(wide_result, wide_result_len);
176 if (express_cat.is_debug()) {
178 <<
"Converted '" << data <<
"' from registry to '" << result <<
"'\n";
192 int WindowsRegistry::
193 get_int_value(
const string &key,
const string &name,
int default_value,
194 WindowsRegistry::RegLevel rl)
198 if (!do_get(key, name, data_type, data, rl)) {
199 return default_value;
202 if (data_type != REG_DWORD) {
203 express_cat.warning()
204 <<
"Registry key " << key <<
" does not contain an integer value.\n";
205 return default_value;
209 nassertr(data.length() ==
sizeof(DWORD), default_value);
210 DWORD dw = *(DWORD *)data.data();
220 bool WindowsRegistry::
221 do_set(
const string &key,
const string &name,
222 int data_type,
const void *data,
int data_length,
223 const WindowsRegistry::RegLevel rl)
225 HKEY hkey, regkey = HKEY_LOCAL_MACHINE;
229 regkey = HKEY_CURRENT_USER;
232 RegOpenKeyEx(regkey, key.c_str(), 0, KEY_SET_VALUE, &hkey);
233 if (error != ERROR_SUCCESS) {
235 <<
"Unable to open registry key " << key
236 <<
": " << format_message(error) <<
"\n";
243 RegSetValueEx(hkey, name.c_str(), 0, data_type,
244 (CONST BYTE *)data, data_length);
245 if (error != ERROR_SUCCESS) {
247 <<
"Unable to set registry key " << key <<
" name " << name
248 <<
": " << format_message(error) <<
"\n";
252 error = RegCloseKey(hkey);
253 if (error != ERROR_SUCCESS) {
254 express_cat.warning()
255 <<
"Unable to close opened registry key " << key
256 <<
": " << format_message(error) <<
"\n";
269 bool WindowsRegistry::
270 do_get(
const string &key,
const string &name,
int &data_type,
string &data,
271 const WindowsRegistry::RegLevel rl)
273 HKEY hkey, regkey = HKEY_LOCAL_MACHINE;
277 regkey = HKEY_CURRENT_USER;
280 RegOpenKeyEx(regkey, key.c_str(), 0, KEY_QUERY_VALUE, &hkey);
281 if (error != ERROR_SUCCESS) {
283 <<
"Unable to open registry key " << key
284 <<
": " << format_message(error) <<
"\n";
292 static const size_t init_buffer_size = 1024;
293 char init_buffer[init_buffer_size];
294 DWORD buffer_size = init_buffer_size;
298 RegQueryValueEx(hkey, name.c_str(), 0, &dw_data_type,
299 (BYTE *)init_buffer, &buffer_size);
300 if (error == ERROR_SUCCESS) {
301 data_type = dw_data_type;
302 if (data_type == REG_SZ ||
303 data_type == REG_MULTI_SZ ||
304 data_type == REG_EXPAND_SZ) {
309 data = string(init_buffer, buffer_size);
311 }
else if (error == ERROR_MORE_DATA) {
318 char *new_buffer = (
char *)PANDA_MALLOC_ARRAY(buffer_size);
320 RegQueryValueEx(hkey, name.c_str(), 0, &dw_data_type,
321 (BYTE *)new_buffer, &buffer_size);
322 if (error == ERROR_SUCCESS) {
323 data_type = dw_data_type;
324 if (data_type == REG_SZ ||
325 data_type == REG_MULTI_SZ ||
326 data_type == REG_EXPAND_SZ) {
331 data = string(new_buffer, buffer_size);
333 PANDA_FREE_ARRAY(new_buffer);
336 if (error != ERROR_SUCCESS) {
338 <<
"Unable to get registry value " << name
339 <<
": " << format_message(error) <<
"\n";
343 error = RegCloseKey(hkey);
344 if (error != ERROR_SUCCESS) {
345 express_cat.warning()
346 <<
"Unable to close opened registry key " << key
347 <<
": " << format_message(error) <<
"\n";
351 if (data_type == REG_EXPAND_SZ) {
353 DWORD destSize=ExpandEnvironmentStrings(data.c_str(), 0, 0);
354 char *dest = (
char *)PANDA_MALLOC_ARRAY(destSize);
355 ExpandEnvironmentStrings(data.c_str(), dest, destSize);
357 PANDA_FREE_ARRAY(dest);
371 string WindowsRegistry::
372 format_message(
int error_code) {
375 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
376 NULL, error_code, 0, (LPTSTR)&buffer, 0, NULL);
378 return "Unknown error message";
381 const char *text = (
const char *)buffer;
385 (text[length - 1] ==
'\r' || text[length - 1] ==
'\n')) {
389 string result((
const char *)text, length);
This class can be used to convert text between multiple representations, e.g.
string encode_wtext(const wstring &wtext) const
Encodes a wide-text string into a single-char string, according to the current encoding.
wstring decode_text(const string &text) const
Returns the given wstring decoded to a single-byte string, via the current encoding system...