576 lines
13 KiB
C++
576 lines
13 KiB
C++
/*++
|
|
|
|
Copyright (c) 1998 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
registry.cpp
|
|
|
|
Abstract:
|
|
|
|
SIS Groveler/registry interface
|
|
|
|
Authors:
|
|
|
|
John Douceur, 1998
|
|
|
|
Environment:
|
|
|
|
User Mode
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
#include "all.hxx"
|
|
|
|
_TCHAR Registry::id_buffer[id_buffer_length];
|
|
|
|
bool
|
|
Registry::read(
|
|
HKEY base_key,
|
|
const _TCHAR *path,
|
|
int num_entries,
|
|
EntrySpec *entries)
|
|
{
|
|
ASSERT(base_key == HKEY_CLASSES_ROOT
|
|
|| base_key == HKEY_CURRENT_CONFIG
|
|
|| base_key == HKEY_CURRENT_USER
|
|
|| base_key == HKEY_LOCAL_MACHINE
|
|
|| base_key == HKEY_USERS);
|
|
ASSERT(path != 0);
|
|
ASSERT(num_entries > 0);
|
|
ASSERT(entries != 0);
|
|
for (int index = 0; index < num_entries; index++)
|
|
{
|
|
load_string_into_value(entries[index].type,
|
|
entries[index].default_value, entries[index].pointer);
|
|
}
|
|
HKEY path_key;
|
|
long result = RegOpenKeyEx(base_key, path, 0, KEY_ALL_ACCESS, &path_key);
|
|
if (result != ERROR_SUCCESS)
|
|
{
|
|
return false;
|
|
}
|
|
ASSERT(path_key != 0);
|
|
for (index = 0; index < num_entries; index++)
|
|
{
|
|
DWORD data_type;
|
|
DWORD data_length = id_buffer_length;
|
|
result = RegQueryValueEx(path_key, entries[index].identifier, 0,
|
|
&data_type, (BYTE *)id_buffer, &data_length);
|
|
if (result == ERROR_SUCCESS && data_type == REG_SZ)
|
|
{
|
|
load_string_into_value(entries[index].type, id_buffer,
|
|
entries[index].pointer);
|
|
}
|
|
}
|
|
ASSERT(path_key != 0);
|
|
RegCloseKey(path_key);
|
|
path_key = 0;
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
Registry::write(
|
|
HKEY base_key,
|
|
const _TCHAR *path,
|
|
int num_entries,
|
|
EntrySpec *entries)
|
|
{
|
|
ASSERT(base_key == HKEY_CLASSES_ROOT
|
|
|| base_key == HKEY_CURRENT_CONFIG
|
|
|| base_key == HKEY_CURRENT_USER
|
|
|| base_key == HKEY_LOCAL_MACHINE
|
|
|| base_key == HKEY_USERS);
|
|
ASSERT(path != 0);
|
|
ASSERT(num_entries > 0);
|
|
ASSERT(entries != 0);
|
|
HKEY path_key;
|
|
DWORD disposition;
|
|
long result = RegCreateKeyEx(base_key, path, 0, 0, REG_OPTION_NON_VOLATILE,
|
|
KEY_ALL_ACCESS, 0, &path_key, &disposition);
|
|
if (result != ERROR_SUCCESS)
|
|
{
|
|
PRINT_DEBUG_MSG((_T("GROVELER: RegCreateKeyEx() failed with error %d\n"),
|
|
result));
|
|
return false;
|
|
}
|
|
ASSERT(path_key != 0);
|
|
for (int index = 0; index < num_entries; index++)
|
|
{
|
|
DWORD data_type;
|
|
DWORD data_length = id_buffer_length;
|
|
result = RegQueryValueEx(path_key, entries[index].identifier, 0,
|
|
&data_type, (BYTE *)id_buffer, &data_length);
|
|
if (result != ERROR_SUCCESS || data_type != REG_SZ)
|
|
{
|
|
store_value_in_string(entries[index].type, entries[index].pointer,
|
|
id_buffer);
|
|
result =
|
|
RegSetValueEx(path_key, entries[index].identifier, 0, REG_SZ,
|
|
(BYTE *)id_buffer, (_tcslen(id_buffer) + 1) * sizeof(_TCHAR));
|
|
|
|
if (result != ERROR_SUCCESS)
|
|
{
|
|
PRINT_DEBUG_MSG((_T("GROVELER: RegSetValueEx() failed with error %d\n"),
|
|
result));
|
|
}
|
|
}
|
|
}
|
|
ASSERT(path_key != 0);
|
|
RegCloseKey(path_key);
|
|
path_key = 0;
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
Registry::overwrite(
|
|
HKEY base_key,
|
|
const _TCHAR *path,
|
|
int num_entries,
|
|
EntrySpec *entries)
|
|
{
|
|
ASSERT(base_key == HKEY_CLASSES_ROOT
|
|
|| base_key == HKEY_CURRENT_CONFIG
|
|
|| base_key == HKEY_CURRENT_USER
|
|
|| base_key == HKEY_LOCAL_MACHINE
|
|
|| base_key == HKEY_USERS);
|
|
ASSERT(path != 0);
|
|
ASSERT(num_entries > 0);
|
|
ASSERT(entries != 0);
|
|
HKEY path_key;
|
|
DWORD disposition;
|
|
long result = RegCreateKeyEx(base_key, path, 0, 0, REG_OPTION_NON_VOLATILE,
|
|
KEY_ALL_ACCESS, 0, &path_key, &disposition);
|
|
if (result != ERROR_SUCCESS)
|
|
{
|
|
PRINT_DEBUG_MSG((_T("GROVELER: RegCreateKeyEx() failed with error %d\n"),
|
|
result));
|
|
return false;
|
|
}
|
|
ASSERT(path_key != 0);
|
|
for (int index = 0; index < num_entries; index++)
|
|
{
|
|
store_value_in_string(entries[index].type, entries[index].pointer,
|
|
id_buffer);
|
|
result =
|
|
RegSetValueEx(path_key, entries[index].identifier, 0, REG_SZ,
|
|
(BYTE *)id_buffer, (_tcslen(id_buffer) + 1) * sizeof(_TCHAR));
|
|
if (result != ERROR_SUCCESS)
|
|
{
|
|
PRINT_DEBUG_MSG((_T("GROVELER: RegSetValueEx() failed with error %d\n"),
|
|
result));
|
|
}
|
|
}
|
|
ASSERT(path_key != 0);
|
|
RegCloseKey(path_key);
|
|
path_key = 0;
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
Registry::write_defaults(
|
|
HKEY base_key,
|
|
const _TCHAR *path,
|
|
int num_entries,
|
|
EntrySpec *entries)
|
|
{
|
|
ASSERT(base_key == HKEY_CLASSES_ROOT
|
|
|| base_key == HKEY_CURRENT_CONFIG
|
|
|| base_key == HKEY_CURRENT_USER
|
|
|| base_key == HKEY_LOCAL_MACHINE
|
|
|| base_key == HKEY_USERS);
|
|
ASSERT(path != 0);
|
|
ASSERT(num_entries > 0);
|
|
ASSERT(entries != 0);
|
|
HKEY path_key;
|
|
DWORD disposition;
|
|
long result = RegCreateKeyEx(base_key, path, 0, 0, REG_OPTION_NON_VOLATILE,
|
|
KEY_ALL_ACCESS, 0, &path_key, &disposition);
|
|
if (result != ERROR_SUCCESS)
|
|
{
|
|
PRINT_DEBUG_MSG((_T("GROVELER: RegCreateKeyEx() failed with error %d\n"),
|
|
result));
|
|
return false;
|
|
}
|
|
ASSERT(path_key != 0);
|
|
for (int index = 0; index < num_entries; index++)
|
|
{
|
|
DWORD data_type;
|
|
DWORD data_length = id_buffer_length;
|
|
result = RegQueryValueEx(path_key, entries[index].identifier, 0,
|
|
&data_type, (BYTE *)id_buffer, &data_length);
|
|
if (result != ERROR_SUCCESS)
|
|
{
|
|
result = RegSetValueEx(path_key, entries[index].identifier, 0,
|
|
REG_SZ, (BYTE *)entries[index].default_value,
|
|
(_tcslen(entries[index].default_value) + 1) * sizeof(_TCHAR));
|
|
if (result != ERROR_SUCCESS)
|
|
{
|
|
PRINT_DEBUG_MSG((_T("GROVELER: RegSetValueEx() failed with error %d\n"),
|
|
result));
|
|
}
|
|
}
|
|
}
|
|
ASSERT(path_key != 0);
|
|
RegCloseKey(path_key);
|
|
path_key = 0;
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
Registry::overwrite_defaults(
|
|
HKEY base_key,
|
|
const _TCHAR *path,
|
|
int num_entries,
|
|
EntrySpec *entries)
|
|
{
|
|
ASSERT(base_key == HKEY_CLASSES_ROOT
|
|
|| base_key == HKEY_CURRENT_CONFIG
|
|
|| base_key == HKEY_CURRENT_USER
|
|
|| base_key == HKEY_LOCAL_MACHINE
|
|
|| base_key == HKEY_USERS);
|
|
ASSERT(path != 0);
|
|
ASSERT(num_entries > 0);
|
|
ASSERT(entries != 0);
|
|
HKEY path_key;
|
|
DWORD disposition;
|
|
long result = RegCreateKeyEx(base_key, path, 0, 0, REG_OPTION_NON_VOLATILE,
|
|
KEY_ALL_ACCESS, 0, &path_key, &disposition);
|
|
if (result != ERROR_SUCCESS)
|
|
{
|
|
PRINT_DEBUG_MSG((_T("GROVELER: RegCreateKeyEx() failed with error %d\n"),
|
|
result));
|
|
return false;
|
|
}
|
|
ASSERT(path_key != 0);
|
|
for (int index = 0; index < num_entries; index++)
|
|
{
|
|
result = RegSetValueEx(path_key, entries[index].identifier, 0, REG_SZ,
|
|
(BYTE *)entries[index].default_value,
|
|
(_tcslen(entries[index].default_value) + 1) * sizeof(_TCHAR));
|
|
if (result != ERROR_SUCCESS)
|
|
{
|
|
PRINT_DEBUG_MSG((_T("GROVELER: RegSetValueEx() failed with error %d\n"),
|
|
result));
|
|
}
|
|
}
|
|
ASSERT(path_key != 0);
|
|
RegCloseKey(path_key);
|
|
path_key = 0;
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
Registry::read_string_set(
|
|
HKEY base_key,
|
|
const _TCHAR *path,
|
|
int *num_strings,
|
|
_TCHAR ***strings,
|
|
BYTE **buffer)
|
|
{
|
|
ASSERT(base_key == HKEY_CLASSES_ROOT
|
|
|| base_key == HKEY_CURRENT_CONFIG
|
|
|| base_key == HKEY_CURRENT_USER
|
|
|| base_key == HKEY_LOCAL_MACHINE
|
|
|| base_key == HKEY_USERS);
|
|
ASSERT(path != 0);
|
|
ASSERT(num_strings != 0);
|
|
ASSERT(strings != 0);
|
|
ASSERT(buffer != 0);
|
|
HKEY path_key;
|
|
*num_strings = 0;
|
|
*strings = 0;
|
|
*buffer = 0;
|
|
long result = RegOpenKeyEx(base_key, path, 0, KEY_ALL_ACCESS, &path_key);
|
|
if (result != ERROR_SUCCESS)
|
|
{
|
|
return false;
|
|
}
|
|
unsigned long num_values;
|
|
unsigned long max_value_length;
|
|
unsigned long max_string_length;
|
|
result = RegQueryInfoKey(path_key, 0, 0, 0, 0, 0, 0,
|
|
&num_values, &max_value_length, &max_string_length, 0, 0);
|
|
if (result != ERROR_SUCCESS || num_values == 0)
|
|
{
|
|
return true;
|
|
}
|
|
_TCHAR *value = new _TCHAR[max_value_length + 1];
|
|
_TCHAR **string_set = new _TCHAR *[num_values];
|
|
BYTE *string_buffer =
|
|
new BYTE[num_values * max_string_length * sizeof(_TCHAR)];
|
|
int string_index = 0;
|
|
int buffer_offset = 0;
|
|
for (unsigned int index = 0; index < num_values; index++)
|
|
{
|
|
DWORD value_length = max_value_length + 1;
|
|
DWORD string_length = max_string_length;
|
|
DWORD data_type;
|
|
result = RegEnumValue(path_key, index, value, &value_length, 0,
|
|
&data_type, &string_buffer[buffer_offset], &string_length);
|
|
if (result == ERROR_SUCCESS && data_type == REG_SZ)
|
|
{
|
|
ASSERT(unsigned(string_index) < num_values);
|
|
string_set[string_index] = (_TCHAR *)&string_buffer[buffer_offset];
|
|
string_index++;
|
|
buffer_offset += string_length;
|
|
}
|
|
}
|
|
*num_strings = string_index;
|
|
ASSERT(value != 0);
|
|
delete[] value;
|
|
value = 0;
|
|
*strings = string_set;
|
|
*buffer = string_buffer;
|
|
ASSERT(path_key != 0);
|
|
RegCloseKey(path_key);
|
|
path_key = 0;
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
Registry::write_string_set(
|
|
HKEY base_key,
|
|
const _TCHAR *path,
|
|
int num_strings,
|
|
_TCHAR **strings,
|
|
_TCHAR **identifiers)
|
|
{
|
|
ASSERT(base_key == HKEY_CLASSES_ROOT
|
|
|| base_key == HKEY_CURRENT_CONFIG
|
|
|| base_key == HKEY_CURRENT_USER
|
|
|| base_key == HKEY_LOCAL_MACHINE
|
|
|| base_key == HKEY_USERS);
|
|
ASSERT(path != 0);
|
|
ASSERT(num_strings > 0);
|
|
ASSERT(strings != 0);
|
|
ASSERT(identifiers != 0);
|
|
HKEY path_key;
|
|
DWORD disposition;
|
|
long result = RegCreateKeyEx(base_key, path, 0, 0, REG_OPTION_NON_VOLATILE,
|
|
KEY_ALL_ACCESS, 0, &path_key, &disposition);
|
|
if (result != ERROR_SUCCESS)
|
|
{
|
|
PRINT_DEBUG_MSG((_T("GROVELER: RegCreateKeyEx() failed with error %d\n"),
|
|
result));
|
|
return false;
|
|
}
|
|
ASSERT(path_key != 0);
|
|
for (int index = 0; index < num_strings; index++)
|
|
{
|
|
DWORD data_type;
|
|
DWORD data_length = id_buffer_length;
|
|
result = RegQueryValueEx(path_key, identifiers[index], 0,
|
|
&data_type, (BYTE *)id_buffer, &data_length);
|
|
if (result != ERROR_SUCCESS || data_type != REG_SZ)
|
|
{
|
|
result = RegSetValueEx(
|
|
path_key, identifiers[index], 0, REG_SZ, (BYTE *)strings[index],
|
|
(_tcslen(strings[index]) + 1) * sizeof(_TCHAR));
|
|
if (result != ERROR_SUCCESS)
|
|
{
|
|
PRINT_DEBUG_MSG((_T("GROVELER: RegSetValueEx() failed with error %d\n"),
|
|
result));
|
|
}
|
|
}
|
|
}
|
|
ASSERT(path_key != 0);
|
|
RegCloseKey(path_key);
|
|
path_key = 0;
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
Registry::overwrite_string_set(
|
|
HKEY base_key,
|
|
const _TCHAR *path,
|
|
int num_strings,
|
|
_TCHAR **strings,
|
|
_TCHAR **identifiers)
|
|
{
|
|
ASSERT(base_key == HKEY_CLASSES_ROOT
|
|
|| base_key == HKEY_CURRENT_CONFIG
|
|
|| base_key == HKEY_CURRENT_USER
|
|
|| base_key == HKEY_LOCAL_MACHINE
|
|
|| base_key == HKEY_USERS);
|
|
ASSERT(path != 0);
|
|
ASSERT(num_strings > 0);
|
|
ASSERT(strings != 0);
|
|
ASSERT(identifiers != 0);
|
|
HKEY path_key;
|
|
DWORD disposition;
|
|
long result = RegCreateKeyEx(base_key, path, 0, 0, REG_OPTION_NON_VOLATILE,
|
|
KEY_ALL_ACCESS, 0, &path_key, &disposition);
|
|
if (result != ERROR_SUCCESS)
|
|
{
|
|
PRINT_DEBUG_MSG((_T("GROVELER: RegCreateKeyEx() failed with error %d\n"),
|
|
result));
|
|
return false;
|
|
}
|
|
ASSERT(path_key != 0);
|
|
for (int index = 0; index < num_strings; index++)
|
|
{
|
|
result = RegSetValueEx(
|
|
path_key, identifiers[index], 0, REG_SZ, (BYTE *)strings[index],
|
|
(_tcslen(strings[index]) + 1) * sizeof(_TCHAR));
|
|
if (result != ERROR_SUCCESS)
|
|
{
|
|
PRINT_DEBUG_MSG((_T("GROVELER: RegSetValueEx() failed with error %d\n"),
|
|
result));
|
|
}
|
|
}
|
|
ASSERT(path_key != 0);
|
|
RegCloseKey(path_key);
|
|
path_key = 0;
|
|
return true;
|
|
}
|
|
|
|
void
|
|
Registry::create_key_ex(
|
|
HKEY hKey,
|
|
LPCTSTR lpSubKey,
|
|
DWORD Reserved,
|
|
LPTSTR lpClass,
|
|
DWORD dwOptions,
|
|
REGSAM samDesired,
|
|
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
|
|
PHKEY phkResult,
|
|
LPDWORD lpdwDisposition)
|
|
{
|
|
DWORD result = RegCreateKeyEx(hKey, lpSubKey, Reserved, lpClass, dwOptions,
|
|
samDesired, lpSecurityAttributes, phkResult, lpdwDisposition);
|
|
if (result != ERROR_SUCCESS)
|
|
{
|
|
PRINT_DEBUG_MSG((_T("GROVELER: RegCreateKeyEx() failed with error %d\n"),
|
|
result));
|
|
throw result;
|
|
}
|
|
}
|
|
|
|
void
|
|
Registry::open_key_ex(
|
|
HKEY hKey,
|
|
LPCTSTR lpSubKey,
|
|
DWORD ulOptions,
|
|
REGSAM samDesired,
|
|
PHKEY phkResult)
|
|
{
|
|
DWORD result =
|
|
RegOpenKeyEx(hKey, lpSubKey, ulOptions, samDesired, phkResult);
|
|
if (result != ERROR_SUCCESS)
|
|
{
|
|
throw result;
|
|
}
|
|
}
|
|
|
|
void
|
|
Registry::close_key(
|
|
HKEY hKey)
|
|
{
|
|
DWORD result = RegCloseKey(hKey);
|
|
if (result != ERROR_SUCCESS)
|
|
{
|
|
PRINT_DEBUG_MSG((_T("GROVELER: RegCloseKey() failed with error %d\n"), result));
|
|
throw result;
|
|
}
|
|
}
|
|
|
|
void
|
|
Registry::query_value_ex(
|
|
HKEY hKey,
|
|
LPCTSTR lpValueName,
|
|
LPDWORD lpReserved,
|
|
LPDWORD lpType,
|
|
LPBYTE lpData,
|
|
LPDWORD lpcbData)
|
|
{
|
|
DWORD result = RegQueryValueEx(hKey, lpValueName,
|
|
lpReserved, lpType, lpData, lpcbData);
|
|
if (result != ERROR_SUCCESS)
|
|
{
|
|
throw result;
|
|
}
|
|
}
|
|
|
|
void
|
|
Registry::set_value_ex(
|
|
HKEY hKey,
|
|
LPCTSTR lpValueName,
|
|
DWORD Reserved,
|
|
DWORD dwType,
|
|
CONST BYTE *lpData,
|
|
DWORD cbData)
|
|
{
|
|
DWORD result =
|
|
RegSetValueEx(hKey, lpValueName, Reserved, dwType, lpData, cbData);
|
|
if (result != ERROR_SUCCESS)
|
|
{
|
|
PRINT_DEBUG_MSG((_T("GROVELER: RegSetValueEx() failed with error %d\n"), result));
|
|
throw result;
|
|
}
|
|
}
|
|
|
|
void
|
|
Registry::load_string_into_value(
|
|
EntryType type,
|
|
const _TCHAR *string,
|
|
void *value)
|
|
{
|
|
ASSERT(string != 0);
|
|
ASSERT(value != 0);
|
|
switch (type)
|
|
{
|
|
case entry_bool:
|
|
*((bool *)value) = _ttoi(string) != 0;
|
|
break;
|
|
case entry_char:
|
|
*((_TCHAR *)value) = string[0];
|
|
break;
|
|
case entry_int:
|
|
_stscanf(string, _T("%d"), (int *)value);
|
|
break;
|
|
case entry_int64:
|
|
_stscanf(string, _T("%I64d"), (__int64 *)value);
|
|
break;
|
|
case entry_double:
|
|
_stscanf(string, _T("%lf"), (double *)value);
|
|
break;
|
|
default:
|
|
ASSERT(false);
|
|
}
|
|
}
|
|
|
|
void
|
|
Registry::store_value_in_string(
|
|
EntryType type,
|
|
void *value,
|
|
_TCHAR *string)
|
|
{
|
|
ASSERT(string != 0);
|
|
ASSERT(value != 0);
|
|
switch (type)
|
|
{
|
|
case entry_bool:
|
|
_stprintf(string, *((bool *)value) ? _T("1") : _T("0"));
|
|
break;
|
|
case entry_char:
|
|
_stprintf(string, _T("%c"), *((_TCHAR *)value));
|
|
break;
|
|
case entry_int:
|
|
_stprintf(string, _T("%d"), *((int *)value));
|
|
break;
|
|
case entry_int64:
|
|
_stprintf(string, _T("%I64d"), *((__int64 *)value));
|
|
break;
|
|
case entry_double:
|
|
_stprintf(string, _T("%g"), *((double *)value));
|
|
break;
|
|
default:
|
|
ASSERT(false);
|
|
}
|
|
}
|