From: Sven Baars sbaars@codeweavers.com
--- dlls/kernelbase/registry.c | 46 +++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 16 deletions(-)
diff --git a/dlls/kernelbase/registry.c b/dlls/kernelbase/registry.c index f490c849c17..d7f69ed687c 100644 --- a/dlls/kernelbase/registry.c +++ b/dlls/kernelbase/registry.c @@ -150,6 +150,8 @@ static NTSTATUS open_subkey( HKEY *subkey, HKEY root, UNICODE_STRING *name, DWOR UNICODE_STRING str; NTSTATUS status = 0;
+ *subkey = 0; + attr.Length = sizeof(attr); attr.RootDirectory = (HANDLE)root; attr.ObjectName = &str; @@ -202,12 +204,30 @@ static NTSTATUS open_subkey( HKEY *subkey, HKEY root, UNICODE_STRING *name, DWOR return status; }
+/* wrapper for NtOpenKeyEx that handles Wow6432 nodes but also returns a key on error */ +static NTSTATUS unsafe_open_key( HKEY *retkey, HKEY root, UNICODE_STRING *name, DWORD options, ACCESS_MASK access ) +{ + HKEY subkey = 0, subkey_root = root; + NTSTATUS status = 0; + + while (!status && (name->Length || !subkey)) + { + status = open_subkey( &subkey, subkey_root, name, options, access ); + if (subkey && subkey_root && subkey_root != root) NtClose( subkey_root ); + if (subkey) subkey_root = subkey; + } + + *retkey = subkey_root; + + return status; +} + /* wrapper for NtOpenKeyEx to handle Wow6432 nodes */ static NTSTATUS open_key( HKEY *retkey, HKEY root, DWORD options, ACCESS_MASK access, OBJECT_ATTRIBUTES *attr ) { - HKEY subkey, subkey_root = root; UNICODE_STRING name; NTSTATUS status = 0; + HKEY subkey;
*retkey = NULL;
@@ -226,15 +246,11 @@ static NTSTATUS open_key( HKEY *retkey, HKEY root, DWORD options, ACCESS_MASK ac name.Buffer = attr->ObjectName->Buffer; name.Length = attr->ObjectName->Length;
- 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; - } - + status = unsafe_open_key( &subkey, root, &name, options, access ); if (!status) - *retkey = subkey_root; + *retkey = subkey; + else if (subkey && subkey != root) + NtClose( subkey );
return status; } @@ -293,21 +309,19 @@ static NTSTATUS create_key( HKEY *retkey, ACCESS_MASK access, OBJECT_ATTRIBUTES const UNICODE_STRING *class, ULONG options, PULONG dispos ) { HKEY subkey, root = attr->RootDirectory, subkey_root = root; - NTSTATUS status = STATUS_OBJECT_NAME_NOT_FOUND; UNICODE_STRING name; + NTSTATUS status;
*retkey = NULL;
name.Buffer = attr->ObjectName->Buffer; name.Length = attr->ObjectName->Length;
- while (name.Length) - { - status = open_subkey( &subkey, subkey_root, &name, options & REG_OPTION_OPEN_LINK, access ); - if (status) break; - if (subkey_root && subkey_root != root) NtClose( subkey_root ); + status = unsafe_open_key( &subkey, subkey_root, &name, options & REG_OPTION_OPEN_LINK, access ); + if (!status || status == STATUS_OBJECT_NAME_NOT_FOUND) subkey_root = subkey; - } + else if (subkey && subkey != root) + NtClose( subkey );
if (!status && (options & REG_OPTION_CREATE_LINK)) {