kernelbase: Restructure the open_key() loop.

This commit is contained in:
Sven Baars 2022-11-30 11:42:39 +01:00 committed by Alexandre Julliard
parent e146c33351
commit 0da843f082

View file

@ -100,7 +100,8 @@ static inline BOOL is_version_nt(void)
static BOOL is_wow6432node( const UNICODE_STRING *name ) static BOOL is_wow6432node( const UNICODE_STRING *name )
{ {
return (name->Length == 11 * sizeof(WCHAR) && !wcsnicmp( name->Buffer, L"Wow6432Node", 11 )); DWORD len = name->Length / sizeof(WCHAR);
return (len >= 11 && !wcsnicmp( name->Buffer, L"Wow6432Node\\", min( len, 12 ) ));
} }
/* open the Wow6432Node subkey of the specified key */ /* open the Wow6432Node subkey of the specified key */
@ -228,7 +229,7 @@ static NTSTATUS open_key( HKEY *retkey, HKEY root, UNICODE_STRING name, DWORD op
BOOL force_wow32 = is_win64 && (access & KEY_WOW64_32KEY); BOOL force_wow32 = is_win64 && (access & KEY_WOW64_32KEY);
HANDLE subkey; HANDLE subkey;
WCHAR *buffer = name.Buffer; WCHAR *buffer = name.Buffer;
DWORD pos = 0, i = 0, len = name.Length / sizeof(WCHAR); DWORD i, len = name.Length / sizeof(WCHAR);
*retkey = NULL; *retkey = NULL;
@ -251,23 +252,15 @@ static NTSTATUS open_key( HKEY *retkey, HKEY root, UNICODE_STRING name, DWORD op
return status; return status;
} }
if (len && buffer[0] == '\\') return STATUS_OBJECT_PATH_INVALID; while (len)
while (i < len && buffer[i] != '\\') i++;
for (;;)
{ {
name.Buffer = buffer + pos; i = 0;
name.Length = (i - pos) * sizeof(WCHAR); if (buffer[0] == '\\') return STATUS_OBJECT_PATH_INVALID;
if (force_wow32 && pos) while (i < len && buffer[i] != '\\') i++;
{
if (is_wow6432node( &name )) force_wow32 = FALSE; name.Buffer = buffer;
else if ((subkey = open_wow6432node( attr.RootDirectory ))) name.Length = i * sizeof(WCHAR);
{
if (attr.RootDirectory != root) NtClose( attr.RootDirectory );
attr.RootDirectory = subkey;
force_wow32 = FALSE;
}
}
if (i == len) if (i == len)
{ {
if (options & REG_OPTION_OPEN_LINK) attr.Attributes |= OBJ_OPENLINK; if (options & REG_OPTION_OPEN_LINK) attr.Attributes |= OBJ_OPENLINK;
@ -281,15 +274,22 @@ static NTSTATUS open_key( HKEY *retkey, HKEY root, UNICODE_STRING name, DWORD op
if (attr.RootDirectory != root) NtClose( attr.RootDirectory ); if (attr.RootDirectory != root) NtClose( attr.RootDirectory );
if (status) return status; if (status) return status;
attr.RootDirectory = subkey; attr.RootDirectory = subkey;
if (i == len) break;
while (i < len && buffer[i] == '\\') i++; while (i < len && buffer[i] == '\\') i++;
pos = i; buffer += i;
while (i < len && buffer[i] != '\\') i++; len -= i;
}
if (force_wow32 && (subkey = open_wow6432node( attr.RootDirectory ))) if (force_wow32)
{ {
if (attr.RootDirectory != root) NtClose( attr.RootDirectory ); name.Buffer = buffer;
attr.RootDirectory = subkey; name.Length = len * sizeof(WCHAR);
if (is_wow6432node( &name )) force_wow32 = FALSE;
else if ((subkey = open_wow6432node( attr.RootDirectory )))
{
NtClose( attr.RootDirectory );
attr.RootDirectory = subkey;
force_wow32 = FALSE;
}
}
} }
if (status == STATUS_PREDEFINED_HANDLE) if (status == STATUS_PREDEFINED_HANDLE)
{ {