Commit 0badf072 authored by Sven Baars's avatar Sven Baars Committed by Alexandre Julliard

kernelbase: Factor opening a subkey out of open_key().

parent 31ee0b30
......@@ -221,79 +221,104 @@ static NTSTATUS create_key( HKEY *retkey, HKEY root, UNICODE_STRING name, ULONG
return status;
}
/* wrapper for NtOpenKeyEx to handle Wow6432 nodes */
static NTSTATUS open_key( HKEY *retkey, HKEY root, UNICODE_STRING name, DWORD options, ACCESS_MASK access )
static NTSTATUS open_subkey( HKEY *subkey, HKEY root, UNICODE_STRING *name, DWORD options, ACCESS_MASK access )
{
DWORD i = 0, len = name->Length / sizeof(WCHAR);
WCHAR *buffer = name->Buffer;
OBJECT_ATTRIBUTES attr;
NTSTATUS status;
HANDLE subkey;
WCHAR *buffer = name.Buffer;
DWORD i, len = name.Length / sizeof(WCHAR);
*retkey = NULL;
UNICODE_STRING str;
NTSTATUS status = 0;
attr.Length = sizeof(attr);
attr.RootDirectory = root;
attr.ObjectName = &name;
attr.ObjectName = &str;
attr.Attributes = 0;
attr.SecurityDescriptor = NULL;
attr.SecurityQualityOfService = NULL;
if (!(is_win64 && (access & KEY_WOW64_32KEY)))
{
if (options & REG_OPTION_OPEN_LINK) attr.Attributes |= OBJ_OPENLINK;
status = NtOpenKeyEx( (HANDLE *)retkey, access, &attr, options );
if (status == STATUS_PREDEFINED_HANDLE)
{
*retkey = get_perflib_key( *retkey );
status = STATUS_SUCCESS;
}
return status;
}
while (len)
{
i = 0;
if (buffer[0] == '\\') return STATUS_OBJECT_PATH_INVALID;
while (i < len && buffer[i] != '\\') i++;
name.Buffer = buffer;
name.Length = i * sizeof(WCHAR);
str.Buffer = name->Buffer;
str.Length = i * sizeof(WCHAR);
if (i == len)
{
if (options & REG_OPTION_OPEN_LINK) attr.Attributes |= OBJ_OPENLINK;
status = NtOpenKeyEx( &subkey, access, &attr, options );
}
else
{
if (!(options & REG_OPTION_OPEN_LINK)) attr.Attributes &= ~OBJ_OPENLINK;
status = NtOpenKeyEx( &subkey, access, &attr, options & ~REG_OPTION_OPEN_LINK );
options &= ~REG_OPTION_OPEN_LINK;
}
if (attr.RootDirectory != root) NtClose( attr.RootDirectory );
if (status) return status;
attr.RootDirectory = subkey;
status = NtOpenKeyEx( (HANDLE *)subkey, access, &attr, options );
if (status == STATUS_PREDEFINED_HANDLE)
{
*subkey = get_perflib_key( *subkey );
status = STATUS_SUCCESS;
}
if (!status)
{
while (i < len && buffer[i] == '\\') i++;
buffer += i;
len -= i;
name.Buffer = buffer;
name.Length = len * sizeof(WCHAR);
if (!is_wow6432node( &name ))
name->Buffer += i;
name->Length -= i * sizeof(WCHAR);
if (!is_wow6432node( name ))
{
if ((subkey = open_wow6432node( attr.RootDirectory )))
HKEY wow6432node = open_wow6432node( *subkey );
if (wow6432node)
{
NtClose( attr.RootDirectory );
attr.RootDirectory = subkey;
NtClose( *subkey );
*subkey = wow6432node;
}
}
}
return status;
}
/* wrapper for NtOpenKeyEx to handle Wow6432 nodes */
static NTSTATUS open_key( HKEY *retkey, HKEY root, UNICODE_STRING name, DWORD options, ACCESS_MASK access )
{
HKEY subkey, subkey_root = root;
NTSTATUS status = 0;
*retkey = NULL;
if (!(is_win64 && (access & KEY_WOW64_32KEY)))
{
OBJECT_ATTRIBUTES attr;
attr.Length = sizeof(attr);
attr.RootDirectory = root;
attr.ObjectName = &name;
attr.Attributes = 0;
attr.SecurityDescriptor = NULL;
attr.SecurityQualityOfService = NULL;
if (options & REG_OPTION_OPEN_LINK) attr.Attributes |= OBJ_OPENLINK;
status = NtOpenKeyEx( (HANDLE *)retkey, access, &attr, options );
if (status == STATUS_PREDEFINED_HANDLE)
{
attr.RootDirectory = get_perflib_key( attr.RootDirectory );
*retkey = get_perflib_key( *retkey );
status = STATUS_SUCCESS;
}
*retkey = attr.RootDirectory;
return status;
}
while (!status && name.Length)
{
status = open_subkey( &subkey, subkey_root, &name, options, access );
if (subkey_root && subkey_root != root) NtClose( subkey_root );
subkey_root = subkey;
}
if (!status)
*retkey = subkey_root;
return 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