Commit f2ef2c2b authored by Alexandre Julliard's avatar Alexandre Julliard

Handle special registry root keys directly in advapi32, and avoid

using them in kernel and ntdll.
parent fb40a72f
...@@ -188,7 +188,7 @@ void CDROM_InitRegistry(int dev) ...@@ -188,7 +188,7 @@ void CDROM_InitRegistry(int dev)
DWORD disp; DWORD disp;
attr.Length = sizeof(attr); attr.Length = sizeof(attr);
attr.RootDirectory = HKEY_LOCAL_MACHINE; attr.RootDirectory = 0;
attr.ObjectName = &nameW; attr.ObjectName = &nameW;
attr.Attributes = 0; attr.Attributes = 0;
attr.SecurityDescriptor = NULL; attr.SecurityDescriptor = NULL;
...@@ -198,7 +198,7 @@ void CDROM_InitRegistry(int dev) ...@@ -198,7 +198,7 @@ void CDROM_InitRegistry(int dev)
return; return;
/* Ensure there is Scsi key */ /* Ensure there is Scsi key */
if (!RtlCreateUnicodeStringFromAsciiz( &nameW, "HARDWARE\\DEVICEMAP\\Scsi" ) || if (!RtlCreateUnicodeStringFromAsciiz( &nameW, "Machine\\HARDWARE\\DEVICEMAP\\Scsi" ) ||
NtCreateKey( &scsiKey, KEY_ALL_ACCESS, &attr, 0, NtCreateKey( &scsiKey, KEY_ALL_ACCESS, &attr, 0,
NULL, REG_OPTION_VOLATILE, &disp )) NULL, REG_OPTION_VOLATILE, &disp ))
{ {
......
...@@ -621,7 +621,7 @@ DWORD WINAPI RtlOpenCurrentUser( ...@@ -621,7 +621,7 @@ DWORD WINAPI RtlOpenCurrentUser(
RtlFormatCurrentUserKeyPath(&ObjectName); RtlFormatCurrentUserKeyPath(&ObjectName);
InitializeObjectAttributes(&ObjectAttributes,&ObjectName,OBJ_CASE_INSENSITIVE,0, NULL); InitializeObjectAttributes(&ObjectAttributes,&ObjectName,OBJ_CASE_INSENSITIVE,0, NULL);
ret = NtOpenKey(KeyHandle, DesiredAccess, &ObjectAttributes); ret = NtCreateKey(KeyHandle, DesiredAccess, &ObjectAttributes, 0, NULL, 0, NULL);
RtlFreeUnicodeString(&ObjectName); RtlFreeUnicodeString(&ObjectName);
return ret; return ret;
} }
...@@ -1086,7 +1086,8 @@ static void _save_at_exit(HKEY hkey,LPCSTR path) ...@@ -1086,7 +1086,8 @@ static void _save_at_exit(HKEY hkey,LPCSTR path)
} }
/* configure save files and start the periodic saving timer [Internal] */ /* configure save files and start the periodic saving timer [Internal] */
static void _init_registry_saving( HKEY hkey_users_default ) static void _init_registry_saving( HKEY hkey_local_machine, HKEY hkey_current_user,
HKEY hkey_users_default )
{ {
int all; int all;
int period = 0; int period = 0;
...@@ -1106,8 +1107,8 @@ static void _init_registry_saving( HKEY hkey_users_default ) ...@@ -1106,8 +1107,8 @@ static void _init_registry_saving( HKEY hkey_users_default )
if (PROFILE_GetWineIniBool(registryW, WritetoHomeRegistryFilesW, 1)) if (PROFILE_GetWineIniBool(registryW, WritetoHomeRegistryFilesW, 1))
{ {
_save_at_exit(HKEY_CURRENT_USER,"/" SAVE_LOCAL_REGBRANCH_CURRENT_USER ); _save_at_exit(hkey_current_user,"/" SAVE_LOCAL_REGBRANCH_CURRENT_USER );
_save_at_exit(HKEY_LOCAL_MACHINE,"/" SAVE_LOCAL_REGBRANCH_LOCAL_MACHINE); _save_at_exit(hkey_local_machine,"/" SAVE_LOCAL_REGBRANCH_LOCAL_MACHINE);
_save_at_exit(hkey_users_default,"/" SAVE_LOCAL_REGBRANCH_USER_DEFAULT); _save_at_exit(hkey_users_default,"/" SAVE_LOCAL_REGBRANCH_USER_DEFAULT);
} }
...@@ -1503,7 +1504,8 @@ static void _convert_and_load_native_registry(LPCWSTR fn, HKEY hkey, int reg_typ ...@@ -1503,7 +1504,8 @@ static void _convert_and_load_native_registry(LPCWSTR fn, HKEY hkey, int reg_typ
} }
/* load all native windows registry files [Internal] */ /* load all native windows registry files [Internal] */
static void _load_windows_registry( HKEY hkey_users_default ) static void _load_windows_registry( HKEY hkey_local_machine, HKEY hkey_current_user,
HKEY hkey_users_default )
{ {
int reg_type; int reg_type;
WCHAR windir[MAX_PATHNAME_LEN]; WCHAR windir[MAX_PATHNAME_LEN];
...@@ -1515,7 +1517,6 @@ static void _load_windows_registry( HKEY hkey_users_default ) ...@@ -1515,7 +1517,6 @@ static void _load_windows_registry( HKEY hkey_users_default )
static const WCHAR WineW[] = {'W','i','n','e',0}; static const WCHAR WineW[] = {'W','i','n','e',0};
static const WCHAR ProfileW[] = {'P','r','o','f','i','l','e',0}; static const WCHAR ProfileW[] = {'P','r','o','f','i','l','e',0};
static const WCHAR empty_strW[] = { 0 }; static const WCHAR empty_strW[] = { 0 };
static const WCHAR Machine[] = {'M','a','c','h','i','n','e',0};
static const WCHAR System[] = {'M','a','c','h','i','n','e','\\','S','y','s','t','e','m',0}; static const WCHAR System[] = {'M','a','c','h','i','n','e','\\','S','y','s','t','e','m',0};
static const WCHAR Software[] = {'M','a','c','h','i','n','e','\\','S','o','f','t','w','a','r','e',0}; static const WCHAR Software[] = {'M','a','c','h','i','n','e','\\','S','o','f','t','w','a','r','e',0};
static const WCHAR Clone[] = {'M','a','c','h','i','n','e','\\', static const WCHAR Clone[] = {'M','a','c','h','i','n','e','\\',
...@@ -1545,7 +1546,7 @@ static void _load_windows_registry( HKEY hkey_users_default ) ...@@ -1545,7 +1546,7 @@ static void _load_windows_registry( HKEY hkey_users_default )
/* user specific ntuser.dat */ /* user specific ntuser.dat */
if (PROFILE_GetWineIniString( WineW, ProfileW, empty_strW, path, MAX_PATHNAME_LEN )) { if (PROFILE_GetWineIniString( WineW, ProfileW, empty_strW, path, MAX_PATHNAME_LEN )) {
strcatW(path, ntuser_datW); strcatW(path, ntuser_datW);
_convert_and_load_native_registry(path,HKEY_CURRENT_USER,REG_WINNT,1); _convert_and_load_native_registry(path,hkey_current_user,REG_WINNT,1);
} }
/* default user.dat */ /* default user.dat */
...@@ -1576,18 +1577,13 @@ static void _load_windows_registry( HKEY hkey_users_default ) ...@@ -1576,18 +1577,13 @@ static void _load_windows_registry( HKEY hkey_users_default )
NtClose( hkey ); NtClose( hkey );
} }
RtlInitUnicodeString( &nameW, Machine );
if (!NtCreateKey( &hkey, KEY_ALL_ACCESS, &attr, 0, NULL, 0, NULL ))
{
strcpyW(path, windir); strcpyW(path, windir);
strcatW(path, samW); strcatW(path, samW);
_convert_and_load_native_registry(path,hkey,REG_WINNT,0); _convert_and_load_native_registry(path,hkey_local_machine,REG_WINNT,0);
strcpyW(path,windir); strcpyW(path,windir);
strcatW(path, securityW); strcatW(path, securityW);
_convert_and_load_native_registry(path,hkey,REG_WINNT,0); _convert_and_load_native_registry(path,hkey_local_machine,REG_WINNT,0);
NtClose( hkey );
}
/* this key is generated when the nt-core booted successfully */ /* this key is generated when the nt-core booted successfully */
RtlInitUnicodeString( &nameW, Clone ); RtlInitUnicodeString( &nameW, Clone );
...@@ -1602,16 +1598,11 @@ static void _load_windows_registry( HKEY hkey_users_default ) ...@@ -1602,16 +1598,11 @@ static void _load_windows_registry( HKEY hkey_users_default )
static const WCHAR classes_datW[] = {'\\','c','l','a','s','s','e','s','.','d','a','t',0}; static const WCHAR classes_datW[] = {'\\','c','l','a','s','s','e','s','.','d','a','t',0};
static const WCHAR user_datW[] = {'\\','u','s','e','r','.','d','a','t',0}; static const WCHAR user_datW[] = {'\\','u','s','e','r','.','d','a','t',0};
RtlInitUnicodeString( &nameW, Machine ); _convert_and_load_native_registry(system_1stW,hkey_local_machine,REG_WIN95,0);
if (!NtCreateKey( &hkey, KEY_ALL_ACCESS, &attr, 0, NULL, 0, NULL ))
{
_convert_and_load_native_registry(system_1stW,hkey,REG_WIN95,0);
strcpyW(path, windir); strcpyW(path, windir);
strcatW(path, system_datW); strcatW(path, system_datW);
_convert_and_load_native_registry(path,hkey,REG_WIN95,0); _convert_and_load_native_registry(path,hkey_local_machine,REG_WIN95,0);
NtClose( hkey );
}
RtlInitUnicodeString( &nameW, ClassesRootW ); RtlInitUnicodeString( &nameW, ClassesRootW );
if (!NtCreateKey( &hkey, KEY_ALL_ACCESS, &attr, 0, NULL, 0, NULL )) if (!NtCreateKey( &hkey, KEY_ALL_ACCESS, &attr, 0, NULL, 0, NULL ))
...@@ -1625,7 +1616,7 @@ static void _load_windows_registry( HKEY hkey_users_default ) ...@@ -1625,7 +1616,7 @@ static void _load_windows_registry( HKEY hkey_users_default )
if (PROFILE_GetWineIniString(WineW, ProfileW, empty_strW, path, MAX_PATHNAME_LEN)) { if (PROFILE_GetWineIniString(WineW, ProfileW, empty_strW, path, MAX_PATHNAME_LEN)) {
/* user specific user.dat */ /* user specific user.dat */
strcatW(path, user_datW); strcatW(path, user_datW);
_convert_and_load_native_registry(path,HKEY_CURRENT_USER,REG_WIN95,1); _convert_and_load_native_registry(path,hkey_current_user,REG_WIN95,1);
/* default user.dat */ /* default user.dat */
if (hkey_users_default) { if (hkey_users_default) {
...@@ -1636,7 +1627,7 @@ static void _load_windows_registry( HKEY hkey_users_default ) ...@@ -1636,7 +1627,7 @@ static void _load_windows_registry( HKEY hkey_users_default )
} else { } else {
strcpyW(path, windir); strcpyW(path, windir);
strcatW(path, user_datW); strcatW(path, user_datW);
_convert_and_load_native_registry(path,HKEY_CURRENT_USER,REG_WIN95,1); _convert_and_load_native_registry(path,hkey_current_user,REG_WIN95,1);
} }
break; break;
} }
...@@ -1658,19 +1649,20 @@ static void _load_windows_registry( HKEY hkey_users_default ) ...@@ -1658,19 +1649,20 @@ static void _load_windows_registry( HKEY hkey_users_default )
} }
/* load global registry files (stored in /etc/wine) [Internal] */ /* load global registry files (stored in /etc/wine) [Internal] */
static void _load_global_registry(void) static void _load_global_registry( HKEY hkey_local_machine, HKEY hkey_users )
{ {
TRACE("(void)\n"); TRACE("(void)\n");
/* Load the global HKU hive directly from sysconfdir */ /* Load the global HKU hive directly from sysconfdir */
load_wine_registry( HKEY_USERS, SAVE_GLOBAL_REGBRANCH_USER_DEFAULT ); load_wine_registry( hkey_users, SAVE_GLOBAL_REGBRANCH_USER_DEFAULT );
/* Load the global machine defaults directly from sysconfdir */ /* Load the global machine defaults directly from sysconfdir */
load_wine_registry( HKEY_LOCAL_MACHINE, SAVE_GLOBAL_REGBRANCH_LOCAL_MACHINE ); load_wine_registry( hkey_local_machine, SAVE_GLOBAL_REGBRANCH_LOCAL_MACHINE );
} }
/* load home registry files (stored in ~/.wine) [Internal] */ /* load home registry files (stored in ~/.wine) [Internal] */
static void _load_home_registry( HKEY hkey_users_default ) static void _load_home_registry( HKEY hkey_local_machine, HKEY hkey_current_user,
HKEY hkey_users_default )
{ {
LPCSTR confdir = wine_get_config_dir(); LPCSTR confdir = wine_get_config_dir();
LPSTR tmp = _xmalloc(strlen(confdir)+20); LPSTR tmp = _xmalloc(strlen(confdir)+20);
...@@ -1681,11 +1673,11 @@ static void _load_home_registry( HKEY hkey_users_default ) ...@@ -1681,11 +1673,11 @@ static void _load_home_registry( HKEY hkey_users_default )
strcpy(tmp,confdir); strcpy(tmp,confdir);
strcat(tmp,"/" SAVE_LOCAL_REGBRANCH_CURRENT_USER); strcat(tmp,"/" SAVE_LOCAL_REGBRANCH_CURRENT_USER);
load_wine_registry(HKEY_CURRENT_USER,tmp); load_wine_registry(hkey_current_user,tmp);
strcpy(tmp,confdir); strcpy(tmp,confdir);
strcat(tmp,"/" SAVE_LOCAL_REGBRANCH_LOCAL_MACHINE); strcat(tmp,"/" SAVE_LOCAL_REGBRANCH_LOCAL_MACHINE);
load_wine_registry(HKEY_LOCAL_MACHINE,tmp); load_wine_registry(hkey_local_machine,tmp);
free(tmp); free(tmp);
} }
...@@ -1693,11 +1685,13 @@ static void _load_home_registry( HKEY hkey_users_default ) ...@@ -1693,11 +1685,13 @@ static void _load_home_registry( HKEY hkey_users_default )
/* load all registry (native and global and home) */ /* load all registry (native and global and home) */
void SHELL_LoadRegistry( void ) void SHELL_LoadRegistry( void )
{ {
HKEY hkey_users_default; HKEY hkey_local_machine, hkey_users, hkey_users_default, hkey_current_user;
OBJECT_ATTRIBUTES attr; OBJECT_ATTRIBUTES attr;
UNICODE_STRING nameW; UNICODE_STRING nameW;
static const WCHAR DefaultW[] = {'U','s','e','r','\\','.','D','e','f','a','u','l','t',0}; static const WCHAR MachineW[] = {'M','a','c','h','i','n','e',0};
static const WCHAR UserW[] = {'U','s','e','r',0};
static const WCHAR DefaultW[] = {'.','D','e','f','a','u','l','t',0};
static const WCHAR RegistryW[] = {'R','e','g','i','s','t','r','y',0}; static const WCHAR RegistryW[] = {'R','e','g','i','s','t','r','y',0};
static const WCHAR load_win_reg_filesW[] = {'L','o','a','d','W','i','n','d','o','w','s','R','e','g','i','s','t','r','y','F','i','l','e','s',0}; static const WCHAR load_win_reg_filesW[] = {'L','o','a','d','W','i','n','d','o','w','s','R','e','g','i','s','t','r','y','F','i','l','e','s',0};
static const WCHAR load_global_reg_filesW[] = {'L','o','a','d','G','l','o','b','a','l','R','e','g','i','s','t','r','y','F','i','l','e','s',0}; static const WCHAR load_global_reg_filesW[] = {'L','o','a','d','G','l','o','b','a','l','R','e','g','i','s','t','r','y','F','i','l','e','s',0};
...@@ -1714,22 +1708,32 @@ void SHELL_LoadRegistry( void ) ...@@ -1714,22 +1708,32 @@ void SHELL_LoadRegistry( void )
attr.SecurityDescriptor = NULL; attr.SecurityDescriptor = NULL;
attr.SecurityQualityOfService = NULL; attr.SecurityQualityOfService = NULL;
RtlInitUnicodeString( &nameW, MachineW );
NtCreateKey( &hkey_local_machine, KEY_ALL_ACCESS, &attr, 0, NULL, 0, NULL );
RtlInitUnicodeString( &nameW, UserW );
NtCreateKey( &hkey_users, KEY_ALL_ACCESS, &attr, 0, NULL, 0, NULL );
attr.RootDirectory = hkey_users;
RtlInitUnicodeString( &nameW, DefaultW ); RtlInitUnicodeString( &nameW, DefaultW );
if (NtCreateKey( &hkey_users_default, KEY_ALL_ACCESS, &attr, 0, NULL, 0, NULL )) if (NtCreateKey( &hkey_users_default, KEY_ALL_ACCESS, &attr, 0, NULL, 0, NULL ))
{ {
ERR("Cannot create HKEY_USERS/.Default\n" ); ERR("Cannot create HKEY_USERS/.Default\n" );
ExitProcess(1); ExitProcess(1);
} }
RtlOpenCurrentUser( KEY_ALL_ACCESS, &hkey_current_user );
_set_registry_levels(0,0,0); _set_registry_levels(0,0,0);
_allocate_default_keys(); _allocate_default_keys();
if (PROFILE_GetWineIniBool(RegistryW, load_win_reg_filesW, 1)) if (PROFILE_GetWineIniBool(RegistryW, load_win_reg_filesW, 1))
_load_windows_registry( hkey_users_default ); _load_windows_registry( hkey_local_machine, hkey_current_user, hkey_users_default );
if (PROFILE_GetWineIniBool(RegistryW, load_global_reg_filesW, 1)) if (PROFILE_GetWineIniBool(RegistryW, load_global_reg_filesW, 1))
_load_global_registry(); _load_global_registry( hkey_local_machine, hkey_users );
_set_registry_levels(1,0,0); _set_registry_levels(1,0,0);
if (PROFILE_GetWineIniBool(RegistryW, load_home_reg_filesW, 1)) if (PROFILE_GetWineIniBool(RegistryW, load_home_reg_filesW, 1))
_load_home_registry( hkey_users_default ); _load_home_registry( hkey_local_machine, hkey_current_user, hkey_users_default );
_init_registry_saving( hkey_users_default ); _init_registry_saving( hkey_local_machine, hkey_current_user, hkey_users_default );
NtClose(hkey_users_default); NtClose(hkey_users_default);
NtClose(hkey_current_user);
NtClose(hkey_users);
NtClose(hkey_local_machine);
} }
...@@ -570,12 +570,95 @@ void VxDCall( DWORD service, CONTEXT86 *context ) ...@@ -570,12 +570,95 @@ void VxDCall( DWORD service, CONTEXT86 *context )
*/ */
#define HKEY_SPECIAL_ROOT_FIRST HKEY_CLASSES_ROOT
#define HKEY_SPECIAL_ROOT_LAST HKEY_DYN_DATA
#define NB_SPECIAL_ROOT_KEYS ((UINT)HKEY_SPECIAL_ROOT_LAST - (UINT)HKEY_SPECIAL_ROOT_FIRST + 1)
static HKEY special_root_keys[NB_SPECIAL_ROOT_KEYS];
static const WCHAR name_CLASSES_ROOT[] =
{'M','a','c','h','i','n','e','\\',
'S','o','f','t','w','a','r','e','\\',
'C','l','a','s','s','e','s',0};
static const WCHAR name_LOCAL_MACHINE[] =
{'M','a','c','h','i','n','e',0};
static const WCHAR name_USERS[] =
{'U','s','e','r',0};
static const WCHAR name_PERFORMANCE_DATA[] =
{'P','e','r','f','D','a','t','a',0};
static const WCHAR name_CURRENT_CONFIG[] =
{'M','a','c','h','i','n','e','\\',
'S','y','s','t','e','m','\\',
'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
'H','a','r','d','w','a','r','e','P','r','o','f','i','l','e','s','\\',
'C','u','r','r','e','n','t',0};
static const WCHAR name_DYN_DATA[] =
{'D','y','n','D','a','t','a',0};
#define DECL_STR(key) { sizeof(name_##key)-sizeof(WCHAR), sizeof(name_##key), (LPWSTR)name_##key }
static UNICODE_STRING root_key_names[NB_SPECIAL_ROOT_KEYS] =
{
DECL_STR(CLASSES_ROOT),
{ 0, 0, NULL }, /* HKEY_CURRENT_USER is determined dynamically */
DECL_STR(LOCAL_MACHINE),
DECL_STR(USERS),
DECL_STR(PERFORMANCE_DATA),
DECL_STR(CURRENT_CONFIG),
DECL_STR(DYN_DATA)
};
#undef DECL_STR
/* check if value type needs string conversion (Ansi<->Unicode) */ /* check if value type needs string conversion (Ansi<->Unicode) */
inline static int is_string( DWORD type ) inline static int is_string( DWORD type )
{ {
return (type == REG_SZ) || (type == REG_EXPAND_SZ) || (type == REG_MULTI_SZ); return (type == REG_SZ) || (type == REG_EXPAND_SZ) || (type == REG_MULTI_SZ);
} }
/* create one of the HKEY_* special root keys */
static HKEY create_special_root_hkey( HKEY hkey, DWORD access )
{
HKEY ret = 0;
int idx = (UINT)hkey - (UINT)HKEY_SPECIAL_ROOT_FIRST;
if (hkey == HKEY_CURRENT_USER)
{
if (RtlOpenCurrentUser( access, &hkey )) return 0;
}
else
{
OBJECT_ATTRIBUTES attr;
attr.Length = sizeof(attr);
attr.RootDirectory = 0;
attr.ObjectName = &root_key_names[idx];
attr.Attributes = 0;
attr.SecurityDescriptor = NULL;
attr.SecurityQualityOfService = NULL;
if (NtCreateKey( &hkey, access, &attr, 0, NULL, 0, NULL )) return 0;
}
if (!(ret = InterlockedCompareExchange( (PLONG)&special_root_keys[idx], hkey, 0 )))
ret = hkey;
else
NtClose( hkey ); /* somebody beat us to it */
return ret;
}
/* map the hkey from special root to normal key if necessary */
inline static HKEY get_special_root_hkey( HKEY hkey )
{
HKEY ret = hkey;
if ((hkey >= HKEY_SPECIAL_ROOT_FIRST) && (hkey <= HKEY_SPECIAL_ROOT_LAST))
{
if (!(ret = special_root_keys[(UINT)hkey - (UINT)HKEY_SPECIAL_ROOT_FIRST]))
ret = create_special_root_hkey( hkey, KEY_ALL_ACCESS );
}
return ret;
}
/****************************************************************************** /******************************************************************************
* VMM_RegCreateKeyA * VMM_RegCreateKeyA
*/ */
...@@ -586,6 +669,8 @@ static DWORD VMM_RegCreateKeyA( HKEY hkey, LPCSTR name, LPHKEY retkey ) ...@@ -586,6 +669,8 @@ static DWORD VMM_RegCreateKeyA( HKEY hkey, LPCSTR name, LPHKEY retkey )
ANSI_STRING nameA; ANSI_STRING nameA;
NTSTATUS status; NTSTATUS status;
if (!(hkey = get_special_root_hkey( hkey ))) return ERROR_INVALID_HANDLE;
attr.Length = sizeof(attr); attr.Length = sizeof(attr);
attr.RootDirectory = hkey; attr.RootDirectory = hkey;
attr.ObjectName = &nameW; attr.ObjectName = &nameW;
...@@ -614,6 +699,8 @@ DWORD WINAPI VMM_RegOpenKeyExA(HKEY hkey, LPCSTR name, DWORD reserved, REGSAM ac ...@@ -614,6 +699,8 @@ DWORD WINAPI VMM_RegOpenKeyExA(HKEY hkey, LPCSTR name, DWORD reserved, REGSAM ac
STRING nameA; STRING nameA;
NTSTATUS status; NTSTATUS status;
if (!(hkey = get_special_root_hkey( hkey ))) return ERROR_INVALID_HANDLE;
attr.Length = sizeof(attr); attr.Length = sizeof(attr);
attr.RootDirectory = hkey; attr.RootDirectory = hkey;
attr.ObjectName = &nameW; attr.ObjectName = &nameW;
...@@ -649,7 +736,9 @@ static DWORD VMM_RegDeleteKeyA( HKEY hkey, LPCSTR name ) ...@@ -649,7 +736,9 @@ static DWORD VMM_RegDeleteKeyA( HKEY hkey, LPCSTR name )
DWORD ret; DWORD ret;
HKEY tmp; HKEY tmp;
if (!name || !*name) return NtDeleteKey( hkey ); if (!(hkey = get_special_root_hkey( hkey ))) return ERROR_INVALID_HANDLE;
if (!name || !*name) return RtlNtStatusToDosError( NtDeleteKey( hkey ) );
if (!(ret = VMM_RegOpenKeyExA( hkey, name, 0, 0, &tmp ))) if (!(ret = VMM_RegOpenKeyExA( hkey, name, 0, 0, &tmp )))
{ {
ret = RtlNtStatusToDosError( NtDeleteKey( tmp ) ); ret = RtlNtStatusToDosError( NtDeleteKey( tmp ) );
...@@ -670,6 +759,8 @@ static DWORD VMM_RegSetValueExA( HKEY hkey, LPCSTR name, DWORD reserved, DWORD t ...@@ -670,6 +759,8 @@ static DWORD VMM_RegSetValueExA( HKEY hkey, LPCSTR name, DWORD reserved, DWORD t
WCHAR *dataW = NULL; WCHAR *dataW = NULL;
NTSTATUS status; NTSTATUS status;
if (!(hkey = get_special_root_hkey( hkey ))) return ERROR_INVALID_HANDLE;
if (is_string(type)) if (is_string(type))
{ {
DWORD lenW; DWORD lenW;
...@@ -726,6 +817,8 @@ static DWORD VMM_RegDeleteValueA( HKEY hkey, LPCSTR name ) ...@@ -726,6 +817,8 @@ static DWORD VMM_RegDeleteValueA( HKEY hkey, LPCSTR name )
STRING nameA; STRING nameA;
NTSTATUS status; NTSTATUS status;
if (!(hkey = get_special_root_hkey( hkey ))) return ERROR_INVALID_HANDLE;
RtlInitAnsiString( &nameA, name ); RtlInitAnsiString( &nameA, name );
if (!(status = RtlAnsiStringToUnicodeString( &nameW, &nameA, TRUE ))) if (!(status = RtlAnsiStringToUnicodeString( &nameW, &nameA, TRUE )))
{ {
...@@ -751,6 +844,7 @@ static DWORD VMM_RegQueryValueExA( HKEY hkey, LPCSTR name, LPDWORD reserved, LPD ...@@ -751,6 +844,7 @@ static DWORD VMM_RegQueryValueExA( HKEY hkey, LPCSTR name, LPDWORD reserved, LPD
static const int info_size = offsetof( KEY_VALUE_PARTIAL_INFORMATION, Data ); static const int info_size = offsetof( KEY_VALUE_PARTIAL_INFORMATION, Data );
if ((data && !count) || reserved) return ERROR_INVALID_PARAMETER; if ((data && !count) || reserved) return ERROR_INVALID_PARAMETER;
if (!(hkey = get_special_root_hkey( hkey ))) return ERROR_INVALID_HANDLE;
RtlInitAnsiString( &nameA, name ); RtlInitAnsiString( &nameA, name );
if ((status = RtlAnsiStringToUnicodeString( &nameW, &nameA, TRUE ))) if ((status = RtlAnsiStringToUnicodeString( &nameW, &nameA, TRUE )))
...@@ -862,6 +956,7 @@ static DWORD VMM_RegEnumValueA( HKEY hkey, DWORD index, LPSTR value, LPDWORD val ...@@ -862,6 +956,7 @@ static DWORD VMM_RegEnumValueA( HKEY hkey, DWORD index, LPSTR value, LPDWORD val
/* NT only checks count, not val_count */ /* NT only checks count, not val_count */
if ((data && !count) || reserved) return ERROR_INVALID_PARAMETER; if ((data && !count) || reserved) return ERROR_INVALID_PARAMETER;
if (!(hkey = get_special_root_hkey( hkey ))) return ERROR_INVALID_HANDLE;
total_size = info_size + (MAX_PATH + 1) * sizeof(WCHAR); total_size = info_size + (MAX_PATH + 1) * sizeof(WCHAR);
if (data) total_size += *count; if (data) total_size += *count;
...@@ -957,6 +1052,8 @@ static DWORD VMM_RegEnumKeyA( HKEY hkey, DWORD index, LPSTR name, DWORD name_len ...@@ -957,6 +1052,8 @@ static DWORD VMM_RegEnumKeyA( HKEY hkey, DWORD index, LPSTR name, DWORD name_len
KEY_NODE_INFORMATION *info = (KEY_NODE_INFORMATION *)buffer; KEY_NODE_INFORMATION *info = (KEY_NODE_INFORMATION *)buffer;
DWORD total_size; DWORD total_size;
if (!(hkey = get_special_root_hkey( hkey ))) return ERROR_INVALID_HANDLE;
status = NtEnumerateKey( hkey, index, KeyNodeInformation, status = NtEnumerateKey( hkey, index, KeyNodeInformation,
buffer, sizeof(buffer), &total_size ); buffer, sizeof(buffer), &total_size );
...@@ -1003,6 +1100,8 @@ static DWORD VMM_RegQueryInfoKeyA( HKEY hkey, LPDWORD subkeys, LPDWORD max_subke ...@@ -1003,6 +1100,8 @@ static DWORD VMM_RegQueryInfoKeyA( HKEY hkey, LPDWORD subkeys, LPDWORD max_subke
KEY_FULL_INFORMATION info; KEY_FULL_INFORMATION info;
DWORD total_size; DWORD total_size;
if (!(hkey = get_special_root_hkey( hkey ))) return ERROR_INVALID_HANDLE;
status = NtQueryKey( hkey, KeyFullInformation, &info, sizeof(info), &total_size ); status = NtQueryKey( hkey, KeyFullInformation, &info, sizeof(info), &total_size );
if (status && status != STATUS_BUFFER_OVERFLOW) return RtlNtStatusToDosError( status ); if (status && status != STATUS_BUFFER_OVERFLOW) return RtlNtStatusToDosError( status );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment