19 #ifndef WIN32_LEAN_AND_MEAN
20 #define WIN32_LEAN_AND_MEAN 1
32 bool WindowsRegistry::
33 set_string_value(
const string &key,
const string &name,
const string &value,
34 WindowsRegistry::RegLevel rl)
47 WideCharToMultiByte(CP_ACP, 0,
48 wvalue.data(), wvalue.length(),
51 if (mb_result_len == 0) {
53 <<
"Unable to convert '" << value
54 <<
"' from Unicode to MultiByte form.\n";
58 char *mb_result = (
char *)alloca(mb_result_len);
59 WideCharToMultiByte(CP_ACP, 0,
60 wvalue.data(), wvalue.length(),
61 mb_result, mb_result_len,
64 if (express_cat.is_debug()) {
66 <<
"Converted '" << value <<
"' to '" << mb_result
67 <<
"' for storing in registry.\n";
70 return do_set(key, name, REG_SZ, mb_result, mb_result_len, rl);
77 bool WindowsRegistry::
78 set_int_value(
const string &key,
const string &name,
int value,
79 WindowsRegistry::RegLevel rl)
82 return do_set(key, name, REG_DWORD, &dw,
sizeof(dw), rl);
89 WindowsRegistry::Type WindowsRegistry::
90 get_key_type(
const string &key,
const string &name,
91 WindowsRegistry::RegLevel rl)
95 if (!do_get(key, name, data_type, data, rl)) {
117 string WindowsRegistry::
118 get_string_value(
const string &key,
const string &name,
119 const string &default_value,
120 WindowsRegistry::RegLevel rl)
124 if (!do_get(key, name, data_type, data, rl)) {
125 return default_value;
128 if (data_type != REG_SZ) {
129 express_cat.warning()
130 <<
"Registry key " << key <<
" does not contain a string value.\n";
131 return default_value;
141 int wide_result_len =
142 MultiByteToWideChar(CP_ACP, 0,
143 data.data(), data.length(),
145 if (wide_result_len == 0) {
147 <<
"Unable to convert '" << data
148 <<
"' from MultiByte to Unicode form.\n";
152 wchar_t *wide_result = (
wchar_t *)alloca(wide_result_len *
sizeof(
wchar_t));
153 MultiByteToWideChar(CP_ACP, 0,
154 data.data(), data.length(),
155 wide_result, wide_result_len);
157 std::wstring wdata(wide_result, wide_result_len);
162 if (express_cat.is_debug()) {
164 <<
"Converted '" << data <<
"' from registry to '" << result <<
"'\n";
175 int WindowsRegistry::
176 get_int_value(
const string &key,
const string &name,
int default_value,
177 WindowsRegistry::RegLevel rl)
181 if (!do_get(key, name, data_type, data, rl)) {
182 return default_value;
185 if (data_type != REG_DWORD) {
186 express_cat.warning()
187 <<
"Registry key " << key <<
" does not contain an integer value.\n";
188 return default_value;
192 nassertr(data.length() ==
sizeof(DWORD), default_value);
193 DWORD dw = *(DWORD *)data.data();
201 bool WindowsRegistry::
202 do_set(
const string &key,
const string &name,
203 int data_type,
const void *data,
int data_length,
204 const WindowsRegistry::RegLevel rl)
206 HKEY hkey, regkey = HKEY_LOCAL_MACHINE;
210 regkey = HKEY_CURRENT_USER;
213 RegOpenKeyEx(regkey, key.c_str(), 0, KEY_SET_VALUE, &hkey);
214 if (error != ERROR_SUCCESS) {
216 <<
"Unable to open registry key " << key
217 <<
": " << format_message(error) <<
"\n";
224 RegSetValueEx(hkey, name.c_str(), 0, data_type,
225 (CONST BYTE *)data, data_length);
226 if (error != ERROR_SUCCESS) {
228 <<
"Unable to set registry key " << key <<
" name " << name
229 <<
": " << format_message(error) <<
"\n";
233 error = RegCloseKey(hkey);
234 if (error != ERROR_SUCCESS) {
235 express_cat.warning()
236 <<
"Unable to close opened registry key " << key
237 <<
": " << format_message(error) <<
"\n";
247 bool WindowsRegistry::
248 do_get(
const string &key,
const string &name,
int &data_type,
string &data,
249 const WindowsRegistry::RegLevel rl)
251 HKEY hkey, regkey = HKEY_LOCAL_MACHINE;
255 regkey = HKEY_CURRENT_USER;
258 RegOpenKeyEx(regkey, key.c_str(), 0, KEY_QUERY_VALUE, &hkey);
259 if (error != ERROR_SUCCESS) {
261 <<
"Unable to open registry key " << key
262 <<
": " << format_message(error) <<
"\n";
270 static const size_t init_buffer_size = 1024;
271 char init_buffer[init_buffer_size];
272 DWORD buffer_size = init_buffer_size;
276 RegQueryValueEx(hkey, name.c_str(), 0, &dw_data_type,
277 (BYTE *)init_buffer, &buffer_size);
278 if (error == ERROR_SUCCESS) {
279 data_type = dw_data_type;
280 if (data_type == REG_SZ ||
281 data_type == REG_MULTI_SZ ||
282 data_type == REG_EXPAND_SZ) {
287 data = string(init_buffer, buffer_size);
289 }
else if (error == ERROR_MORE_DATA) {
295 char *new_buffer = (
char *)PANDA_MALLOC_ARRAY(buffer_size);
297 RegQueryValueEx(hkey, name.c_str(), 0, &dw_data_type,
298 (BYTE *)new_buffer, &buffer_size);
299 if (error == ERROR_SUCCESS) {
300 data_type = dw_data_type;
301 if (data_type == REG_SZ ||
302 data_type == REG_MULTI_SZ ||
303 data_type == REG_EXPAND_SZ) {
308 data = string(new_buffer, buffer_size);
310 PANDA_FREE_ARRAY(new_buffer);
313 if (error != ERROR_SUCCESS) {
315 <<
"Unable to get registry value " << name
316 <<
": " << format_message(error) <<
"\n";
320 error = RegCloseKey(hkey);
321 if (error != ERROR_SUCCESS) {
322 express_cat.warning()
323 <<
"Unable to close opened registry key " << key
324 <<
": " << format_message(error) <<
"\n";
328 if (data_type == REG_EXPAND_SZ) {
330 DWORD destSize=ExpandEnvironmentStrings(data.c_str(), 0, 0);
331 char *dest = (
char *)PANDA_MALLOC_ARRAY(destSize);
332 ExpandEnvironmentStrings(data.c_str(), dest, destSize);
334 PANDA_FREE_ARRAY(dest);
345 string WindowsRegistry::
346 format_message(
int error_code) {
349 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
350 nullptr, error_code, 0, (LPTSTR)&buffer, 0,
nullptr);
352 return "Unknown error message";
355 const char *text = (
const char *)buffer;
359 (text[length - 1] ==
'\r' || text[length - 1] ==
'\n')) {
363 string result((
const char *)text, length);