Currently if anything has created, e. g., HKLM\Software\Wow6432Node\Wow6432Node key, all the WOW keys with subkeys for HKLM\Software will be created in HKLM\Software\Wow6432Node\Wow6432Node\ instead of HKLM\Software\Wow6432Node. And then those keys cannot be found. The test in the patch demonstrates such a case.
This should fix Tom Clancy's The Division (more exactly, Ubisoft launcher setup) from Steam where Steam prerequisite setup step creates "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Ubisoft\The Division - Steam" from a 32 bit program, which results in HKLM\Software\Wow6432Node\Wow6432Node presence (correctly), and from this point everything gets broken.
From: Paul Gofman pgofman@codeweavers.com
--- dlls/advapi32/tests/registry.c | 22 ++++++++++++++++++++++ dlls/kernelbase/registry.c | 4 ++-- 2 files changed, 24 insertions(+), 2 deletions(-)
diff --git a/dlls/advapi32/tests/registry.c b/dlls/advapi32/tests/registry.c index cff09e1a5c5..d66b10e8952 100644 --- a/dlls/advapi32/tests/registry.c +++ b/dlls/advapi32/tests/registry.c @@ -2778,6 +2778,28 @@ static void test_redirection(void) RegCloseKey( root32 ); RegCloseKey( root64 );
+ err = RegCreateKeyExW( HKEY_LOCAL_MACHINE, L"Software\WOW6432Node\test1\test2", 0, NULL, 0, + KEY_WRITE | KEY_WOW64_32KEY, NULL, &key, NULL ); + ok(!err, "got %#lx.\n", err); + RegCloseKey(key); + + err = RegCreateKeyExW( HKEY_LOCAL_MACHINE, L"Software\test1\test2", 0, NULL, 0, KEY_WRITE | KEY_WOW64_32KEY, + NULL, &key, NULL ); + ok(!err, "got %#lx.\n", err); + RegCloseKey(key); + + err = RegOpenKeyExW( HKEY_LOCAL_MACHINE, L"Software\test1\test2", 0, KEY_WRITE | KEY_WOW64_32KEY, &key ); + ok(!err, "got %#lx.\n", err); + RegCloseKey(key); + + if (pRegDeleteTreeA) + { + err = pRegDeleteTreeA(HKEY_LOCAL_MACHINE, "Software\WOW6432Node\test1"); + ok(!err, "got %#lx.\n", err); + err = pRegDeleteTreeA(HKEY_LOCAL_MACHINE, "Software\test1"); + ok(err == ERROR_FILE_NOT_FOUND, "got %#lx.\n", err); + } + /* Software\Classes is shared/reflected so behavior is different */
err = RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software\Classes\Wine", diff --git a/dlls/kernelbase/registry.c b/dlls/kernelbase/registry.c index a767d993254..dcdb1cf84eb 100644 --- a/dlls/kernelbase/registry.c +++ b/dlls/kernelbase/registry.c @@ -165,7 +165,7 @@ static HANDLE open_wow6432node( HANDLE key ) attr.Attributes = 0; attr.SecurityDescriptor = NULL; attr.SecurityQualityOfService = NULL; - if (NtOpenKeyEx( &ret, MAXIMUM_ALLOWED, &attr, 0 )) return key; + if (NtOpenKeyEx( &ret, MAXIMUM_ALLOWED | KEY_WOW64_64KEY, &attr, 0 )) return key; return ret; }
@@ -211,7 +211,7 @@ static NTSTATUS open_key( HKEY *retkey, HKEY root, UNICODE_STRING *name, DWORD o static NTSTATUS open_subkey( HKEY *subkey, HKEY root, UNICODE_STRING *name, DWORD options, ACCESS_MASK access ) { BOOL is_wow64_key = (is_win64 && (access & KEY_WOW64_32KEY)) || (is_wow64 && !(access & KEY_WOW64_64KEY)); - ACCESS_MASK access_64 = access & ~KEY_WOW64_32KEY; + ACCESS_MASK access_64 = (access & ~KEY_WOW64_32KEY) | KEY_WOW64_64KEY; DWORD i = 0, len = name->Length / sizeof(WCHAR); WCHAR *buffer = name->Buffer; UNICODE_STRING str;