Module: wine Branch: master Commit: 3f82f6ff59f4024f67e2d646883cbea223fba84a URL: https://gitlab.winehq.org/wine/wine/-/commit/3f82f6ff59f4024f67e2d646883cbea...
Author: Sven Baars sbaars@codeweavers.com Date: Fri Mar 17 16:52:51 2023 +0100
kernelbase: Use open_key() to obtain any existing Wow6432node in create_key().
---
dlls/advapi32/tests/registry.c | 8 ++++---- dlls/kernelbase/registry.c | 26 +++++++++++++++++++++----- 2 files changed, 25 insertions(+), 9 deletions(-)
diff --git a/dlls/advapi32/tests/registry.c b/dlls/advapi32/tests/registry.c index d5d1274b708..80bf39bb178 100644 --- a/dlls/advapi32/tests/registry.c +++ b/dlls/advapi32/tests/registry.c @@ -2958,7 +2958,7 @@ static void test_redirection(void)
err = RegOpenKeyExA( HKEY_CLASSES_ROOT, "Interface", 0, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &root32 ); - ok( err == ERROR_SUCCESS, "RegOpenKeyExA failed: %lu\n", err ); + todo_wine_if(ptr_size == 64) ok( err == ERROR_SUCCESS, "RegOpenKeyExA failed: %lu\n", err );
err = RegOpenKeyExA( HKEY_CLASSES_ROOT, "Interface", 0, KEY_ALL_ACCESS, &root ); @@ -2966,7 +2966,7 @@ static void test_redirection(void)
err = RegCreateKeyExA( root32, "Wine", 0, NULL, 0, KEY_WOW64_32KEY | KEY_ALL_ACCESS, NULL, &key32, NULL); - ok( err == ERROR_SUCCESS, "RegCreateKeyA failed: %lu\n", err ); + todo_wine_if(ptr_size == 64) ok( err == ERROR_SUCCESS, "RegCreateKeyA failed: %lu\n", err );
err = RegOpenKeyExA( root, "Wine", 0, KEY_ALL_ACCESS, &key ); ok( err == (ptr_size == 64 ? ERROR_FILE_NOT_FOUND : ERROR_SUCCESS), @@ -2978,10 +2978,10 @@ static void test_redirection(void)
err = RegCreateKeyExA( root64, "Wine", 0, NULL, 0, KEY_WOW64_64KEY | KEY_ALL_ACCESS, NULL, &key64, NULL); - ok( err == ERROR_SUCCESS, "RegCreateKeyA failed: %lu\n", err ); + todo_wine_if(ptr_size == 64) ok( err == ERROR_SUCCESS, "RegCreateKeyA failed: %lu\n", err );
err = RegOpenKeyExA( root, "Wine", 0, KEY_ALL_ACCESS, &key ); - ok( err == (ptr_size == 32 ? ERROR_FILE_NOT_FOUND : ERROR_SUCCESS), + todo_wine_if(ptr_size == 64) ok( err == (ptr_size == 32 ? ERROR_FILE_NOT_FOUND : ERROR_SUCCESS), "RegOpenKeyExA failed: %lu\n", err ); if (!err) RegCloseKey( key );
diff --git a/dlls/kernelbase/registry.c b/dlls/kernelbase/registry.c index b294ff7e926..93f8236aa43 100644 --- a/dlls/kernelbase/registry.c +++ b/dlls/kernelbase/registry.c @@ -144,13 +144,15 @@ static NTSTATUS open_key( HKEY *retkey, HKEY root, UNICODE_STRING name, DWORD op
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; DWORD i = 0, len = name->Length / sizeof(WCHAR); WCHAR *buffer = name->Buffer; UNICODE_STRING str; NTSTATUS status;
- if (len > 0 && buffer[0] == '\') return STATUS_OBJECT_PATH_INVALID; + if (!root && len > 10 && !wcsnicmp( buffer, L"\Registry\", 10 )) i += 10; + if (i < len && buffer[i] == '\') return STATUS_OBJECT_PATH_INVALID; while (i < len && buffer[i] != '\') i++;
str.Buffer = name->Buffer; @@ -167,7 +169,7 @@ static NTSTATUS open_subkey( HKEY *subkey, HKEY root, UNICODE_STRING *name, DWOR name->Buffer += i; name->Length -= i * sizeof(WCHAR);
- if (!is_wow6432node( name )) + if (is_wow64_key && !is_wow6432node( name )) { HKEY wow6432node = open_wow6432node( *subkey ); if (wow6432node) @@ -230,7 +232,7 @@ static NTSTATUS create_key( HKEY *retkey, HKEY root, UNICODE_STRING name, ULONG BOOL force_wow32 = is_win64 && (access & KEY_WOW64_32KEY); NTSTATUS status = STATUS_OBJECT_NAME_NOT_FOUND; OBJECT_ATTRIBUTES attr; - HANDLE subkey; + HKEY subkey;
attr.Length = sizeof(attr); attr.RootDirectory = root; @@ -253,11 +255,25 @@ static NTSTATUS create_key( HKEY *retkey, HKEY root, UNICODE_STRING name, ULONG return status; }
+ status = open_key( &subkey, root, name, options & REG_OPTION_OPEN_LINK, access ); + if (!status && (options & REG_OPTION_CREATE_LINK)) + { + NtClose( subkey ); + status = STATUS_OBJECT_NAME_COLLISION; + } + + if (!status) + { + if (dispos) *dispos = REG_OPENED_EXISTING_KEY; + attr.RootDirectory = subkey; + } + if (status == STATUS_OBJECT_NAME_NOT_FOUND) { WCHAR *buffer = name.Buffer; DWORD attrs, i, len = name.Length / sizeof(WCHAR);
+ attr.RootDirectory = root; attrs = attr.Attributes;
while (len) @@ -274,12 +290,12 @@ static NTSTATUS create_key( HKEY *retkey, HKEY root, UNICODE_STRING name, ULONG if (i == len) { attr.Attributes = attrs; - status = NtCreateKey( &subkey, access, &attr, 0, class, options, dispos ); + status = NtCreateKey( (HANDLE *)&subkey, access, &attr, 0, class, options, dispos ); } else { attr.Attributes = attrs & ~OBJ_OPENLINK; - status = NtCreateKey( &subkey, access, &attr, 0, class, + status = NtCreateKey( (HANDLE *)&subkey, access, &attr, 0, class, options & ~REG_OPTION_CREATE_LINK, dispos ); } if (attr.RootDirectory != root) NtClose( attr.RootDirectory );