This seems to be more correct than what we previously had with fewer lines of code, so I like that. I still don't really like the extra flag I had to add for Nt{Create,Open}Key, but I couldn't find a way to make things work without it. I also checked that Windows doesn't use a similar flag (by iterating over all bit masks).
-- v5: ntdll/tests: Refactor the Software\Classes tests. ntdll/tests: Factor out the NtEnumerateKey() tests. server: Don't return the actual 32-bit Software\Classes key. ntdll/tests: Add some some Software\Classes query and enumerate tests. ntdll/tests: Test that NtCreateKeyEx() also recursively obtains the Wow6432Node parent. server: Recursively obtain the Wow6432Node parent. ntdll/tests: Add some Software\Classes subkey tests.
From: Sven Baars sbaars@codeweavers.com
--- dlls/ntdll/tests/reg.c | 196 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 194 insertions(+), 2 deletions(-)
diff --git a/dlls/ntdll/tests/reg.c b/dlls/ntdll/tests/reg.c index 4b0e558e271..12b243f77de 100644 --- a/dlls/ntdll/tests/reg.c +++ b/dlls/ntdll/tests/reg.c @@ -1472,7 +1472,7 @@ static void test_redirection(void) char buffer[1024]; KEY_VALUE_PARTIAL_INFORMATION *info = (KEY_VALUE_PARTIAL_INFORMATION *)buffer; DWORD dw, len; - HANDLE key, root32, root64, key32, key64; + HANDLE key, key32, key64, root, root32, root64;
if (ptr_size != 64) { @@ -1760,6 +1760,12 @@ static void test_redirection(void) status = pNtCreateKey( &key64, KEY_ALL_ACCESS, &attr, 0, 0, 0, 0 ); ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status );
+ attr.RootDirectory = key64; + status = pNtCreateKey( &key, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr, 0, 0, 0, 0 ); + ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status ); + pNtDeleteKey( key ); + pNtClose( key ); + attr.RootDirectory = root32; status = pNtOpenKey( &key, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr ); ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status ); @@ -1819,10 +1825,16 @@ static void test_redirection(void) status = pNtOpenKey( &key, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr ); ok( status == STATUS_OBJECT_NAME_NOT_FOUND, "NtOpenKey failed: 0x%08lx\n", status );
+ attr.RootDirectory = root32; + status = pNtOpenKey( &key, KEY_ALL_ACCESS, &attr ); + ok( status == STATUS_OBJECT_NAME_NOT_FOUND, "NtOpenKey failed: 0x%08lx\n", status ); + + status = pNtOpenKey( &key, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr ); + ok( status == STATUS_OBJECT_NAME_NOT_FOUND, "NtOpenKey failed: 0x%08lx\n", status ); + pNtDeleteKey( key64 ); pNtClose( key64 );
- attr.RootDirectory = root32; status = pNtCreateKey( &key32, KEY_ALL_ACCESS, &attr, 0, 0, 0, 0 ); ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status ); dw = 32; @@ -1847,6 +1859,186 @@ static void test_redirection(void) ok( status == STATUS_SUCCESS, "NtQueryValueKey failed: 0x%08lx\n", status ); dw = *(DWORD *)info->Data; ok( dw == 32, "wrong value %lu\n", dw ); + pNtClose( key64 ); + + pNtDeleteKey( key32 ); + pNtClose( key32 ); + + pNtClose( root64 ); + pNtClose( root32 ); + + pRtlInitUnicodeString( &str, L"\Registry\Machine\Software\Classes" ); + attr.RootDirectory = 0; + status = pNtOpenKey( &root64, KEY_WOW64_64KEY | KEY_ALL_ACCESS, &attr ); + ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status ); + + status = pNtOpenKey( &root32, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr ); + ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status ); + + status = pNtOpenKey( &root, KEY_ALL_ACCESS, &attr ); + ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status ); + + pRtlInitUnicodeString( &str, L"Interface" ); + attr.RootDirectory = root64; + status = pNtOpenKey( &key64, KEY_WOW64_64KEY | KEY_ALL_ACCESS, &attr ); + ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status ); + + attr.RootDirectory = root32; + status = pNtOpenKey( &key32, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr ); + ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status ); + + attr.RootDirectory = root; + status = pNtOpenKey( &key, KEY_ALL_ACCESS, &attr ); + ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status ); + + pNtClose( root64 ); + pNtClose( root32 ); + pNtClose( root ); + + root64 = key64; + root32 = key32; + root = key; + + pRtlInitUnicodeString( &str, L"Wine" ); + attr.RootDirectory = root32; + status = pNtCreateKey( &key32, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr, 0, 0, 0, 0 ); + ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status ); + + attr.RootDirectory = root; + status = pNtOpenKey( &key, KEY_ALL_ACCESS, &attr ); + ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status ); + pNtClose( key ); + + pNtDeleteKey( key32 ); + pNtClose( key32 ); + + attr.RootDirectory = root64; + status = pNtCreateKey( &key64, KEY_WOW64_64KEY | KEY_ALL_ACCESS, &attr, 0, 0, 0, 0 ); + ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status ); + + attr.RootDirectory = root; + status = pNtOpenKey( &key, KEY_ALL_ACCESS, &attr ); + ok( status == (ptr_size == 32 ? STATUS_OBJECT_NAME_NOT_FOUND : STATUS_SUCCESS), + "NtOpenKey failed: 0x%08lx\n", status ); + if (!status) pNtClose( key ); + + pNtDeleteKey( key64 ); + pNtClose( key64 ); + + pNtDeleteKey( root ); + pNtClose( root ); + + attr.RootDirectory = root64; + status = pNtCreateKey( &key64, KEY_ALL_ACCESS, &attr, 0, 0, 0, 0 ); + ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status ); + + attr.RootDirectory = root32; + status = pNtOpenKey( &key, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr ); + ok( status == (ptr_size == 32 ? STATUS_OBJECT_NAME_NOT_FOUND : STATUS_SUCCESS), + "NtOpenKey failed: 0x%08lx\n", status ); + if (!status) pNtClose( key ); + + status = pNtOpenKey( &key, KEY_ALL_ACCESS, &attr ); + ok( status == (ptr_size == 32 ? STATUS_OBJECT_NAME_NOT_FOUND : STATUS_SUCCESS), + "NtOpenKey failed: 0x%08lx\n", status ); + if (!status) pNtClose( key ); + + status = pNtCreateKey( &key32, KEY_ALL_ACCESS, &attr, 0, 0, 0, 0 ); + ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status ); + + dw = 32; + status = pNtSetValueKey( key32, &value_str, 0, REG_DWORD, &dw, sizeof(dw) ); + ok( status == STATUS_SUCCESS, "NtSetValueKey failed: 0x%08lx\n", status ); + pNtClose( key32 ); + + dw = 64; + status = pNtSetValueKey( key64, &value_str, 0, REG_DWORD, &dw, sizeof(dw) ); + ok( status == STATUS_SUCCESS, "NtSetValueKey failed: 0x%08lx\n", status ); + pNtClose( key64 ); + + attr.RootDirectory = root64; + status = pNtOpenKey( &key, KEY_ALL_ACCESS, &attr ); + ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status ); + len = sizeof(buffer); + status = pNtQueryValueKey( key, &value_str, KeyValuePartialInformation, info, len, &len ); + ok( status == STATUS_SUCCESS, "NtQueryValueKey failed: 0x%08lx\n", status ); + dw = *(DWORD *)info->Data; + ok( dw == 64, "wrong value %lu\n", dw ); + pNtClose( key ); + + attr.RootDirectory = root64; + status = pNtOpenKey( &key64, KEY_WOW64_64KEY | KEY_ALL_ACCESS, &attr ); + ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status ); + len = sizeof(buffer); + status = pNtQueryValueKey( key64, &value_str, KeyValuePartialInformation, info, len, &len ); + ok( status == STATUS_SUCCESS, "NtQueryValueKey failed: 0x%08lx\n", status ); + dw = *(DWORD *)info->Data; + ok( dw == 64, "wrong value %lu\n", dw ); + + attr.RootDirectory = root32; + status = pNtOpenKey( &key32, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr ); + ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status ); + len = sizeof(buffer); + status = pNtQueryValueKey( key32, &value_str, KeyValuePartialInformation, info, len, &len ); + ok( status == STATUS_SUCCESS, "NtQueryValueKey failed: 0x%08lx\n", status ); + dw = *(DWORD *)info->Data; + ok( dw == ptr_size, "wrong value %lu\n", dw ); + pNtDeleteKey( key32 ); + pNtClose( key32 ); + + attr.RootDirectory = root64; + status = pNtOpenKey( &key, KEY_ALL_ACCESS, &attr ); + ok( status == (ptr_size == 64 ? STATUS_OBJECT_NAME_NOT_FOUND : STATUS_SUCCESS), + "NtOpenKey failed: 0x%08lx\n", status ); + if (!status) pNtClose( key ); + + status = pNtOpenKey( &key, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr ); + todo_wine_if(ptr_size == 32) ok( status == STATUS_OBJECT_NAME_NOT_FOUND, "NtOpenKey failed: 0x%08lx\n", status ); + if (!status) pNtClose( key ); + + attr.RootDirectory = root32; + status = pNtOpenKey( &key, KEY_ALL_ACCESS, &attr ); + ok( status == STATUS_OBJECT_NAME_NOT_FOUND, "NtOpenKey failed: 0x%08lx\n", status ); + + status = pNtOpenKey( &key, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr ); + ok( status == STATUS_OBJECT_NAME_NOT_FOUND, "NtOpenKey failed: 0x%08lx\n", status ); + + pNtDeleteKey( key64 ); + pNtClose( key64 ); + + status = pNtCreateKey( &key32, KEY_ALL_ACCESS, &attr, 0, 0, 0, 0 ); + ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status ); + dw = 32; + status = pNtSetValueKey( key32, &value_str, 0, REG_DWORD, &dw, sizeof(dw) ); + ok( status == STATUS_SUCCESS, "NtSetValueKey failed: 0x%08lx\n", status ); + + attr.RootDirectory = root64; + status = pNtOpenKey( &key, KEY_ALL_ACCESS, &attr ); + ok( status == (ptr_size == 32 ? STATUS_OBJECT_NAME_NOT_FOUND : STATUS_SUCCESS), + "NtOpenKey failed: 0x%08lx\n", status ); + if (!status) + { + len = sizeof(buffer); + status = pNtQueryValueKey( key, &value_str, KeyValuePartialInformation, info, len, &len ); + ok( status == STATUS_SUCCESS, "NtQueryValueKey failed: 0x%08lx\n", status ); + dw = *(DWORD *)info->Data; + ok( dw == 32, "wrong value %lu\n", dw ); + pNtClose( key ); + } + + attr.RootDirectory = root64; + status = pNtOpenKey( &key64, KEY_WOW64_64KEY | KEY_ALL_ACCESS, &attr ); + ok( status == (ptr_size == 32 ? STATUS_OBJECT_NAME_NOT_FOUND : STATUS_SUCCESS), + "NtOpenKey failed: 0x%08lx\n", status ); + if (!status) + { + len = sizeof(buffer); + status = pNtQueryValueKey( key64, &value_str, KeyValuePartialInformation, info, len, &len ); + ok( status == STATUS_SUCCESS, "NtQueryValueKey failed: 0x%08lx\n", status ); + dw = *(DWORD *)info->Data; + ok( dw == 32, "wrong value %lu\n", dw ); + pNtClose( key64 ); + }
pNtDeleteKey( key32 ); pNtClose( key32 );
From: Sven Baars sbaars@codeweavers.com
--- dlls/advapi32/tests/registry.c | 2 +- dlls/ntdll/tests/reg.c | 5 ++--- server/registry.c | 36 +++++++++++++++++++++++++++++----- 3 files changed, 34 insertions(+), 9 deletions(-)
diff --git a/dlls/advapi32/tests/registry.c b/dlls/advapi32/tests/registry.c index 55a8074f1b7..b4f0398b358 100644 --- a/dlls/advapi32/tests/registry.c +++ b/dlls/advapi32/tests/registry.c @@ -2721,7 +2721,7 @@ static void test_redirection(void) check_key_value( key, "Winetest", 0, 64 ); check_key_value( key, "Winetest", KEY_WOW64_64KEY, 64 ); dw = get_key_value( key, "Winetest", KEY_WOW64_32KEY ); - todo_wine ok( dw == 32, "wrong value %lu\n", dw ); + todo_wine_if (ptr_size == 64) ok( dw == 32, "wrong value %lu\n", dw ); RegCloseKey( key );
err = RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software\Wine", 0, NULL, 0, diff --git a/dlls/ntdll/tests/reg.c b/dlls/ntdll/tests/reg.c index 12b243f77de..383397bd9da 100644 --- a/dlls/ntdll/tests/reg.c +++ b/dlls/ntdll/tests/reg.c @@ -1630,8 +1630,7 @@ static void test_redirection(void) ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status ); check_key_value( key, "Winetest", 0, 64 ); check_key_value( key, "Winetest", KEY_WOW64_64KEY, 64 ); - dw = get_key_value( key, "Winetest", KEY_WOW64_32KEY ); - todo_wine_if (ptr_size == 32) ok( dw == ptr_size, "wrong value %lu\n", dw ); + check_key_value( key, "Winetest", KEY_WOW64_32KEY, ptr_size ); pNtClose( key );
status = pNtCreateKey( &key, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr, 0, 0, 0, 0 ); @@ -1993,7 +1992,7 @@ static void test_redirection(void) if (!status) pNtClose( key );
status = pNtOpenKey( &key, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr ); - todo_wine_if(ptr_size == 32) ok( status == STATUS_OBJECT_NAME_NOT_FOUND, "NtOpenKey failed: 0x%08lx\n", status ); + ok( status == STATUS_OBJECT_NAME_NOT_FOUND, "NtOpenKey failed: 0x%08lx\n", status ); if (!status) pNtClose( key );
attr.RootDirectory = root32; diff --git a/server/registry.c b/server/registry.c index 96ba18a0a5a..d112987b2b9 100644 --- a/server/registry.c +++ b/server/registry.c @@ -773,6 +773,31 @@ static struct key *grab_wow6432node( struct key *key ) return ret; }
+/* recursively obtain the wow6432node parent key if any */ +static struct key *get_wow6432node( struct key *key ) +{ + struct key *parent, *ret; + struct unicode_str name; + int index; + + if (!key) + return NULL; + + if (key->wow6432node) + return key->wow6432node; + + parent = get_parent( key ); + if (parent && key == parent->wow6432node) + return key; + + if (!(ret = get_wow6432node( parent ))) + return key; + + name.str = key->obj.name->name; + name.len = key->obj.name->len; + return find_subkey( ret, &name, &index ); +} + /* open a subkey */ static struct key *open_key( struct key *parent, const struct unicode_str *name, unsigned int access, unsigned int attributes ) @@ -785,10 +810,10 @@ static struct key *open_key( struct key *parent, const struct unicode_str *name, return NULL; }
- if (parent && (access & KEY_WOW64_32KEY)) + if (parent && (access & KEY_WOW64_32KEY) && !is_wow6432node( name->str, name->len )) { - if (parent->wow6432node && !is_wow6432node( name->str, name->len )) - parent = parent->wow6432node; + if ((key = get_wow6432node( parent ))) + parent = key; }
if (!(access & KEY_WOW64_64KEY)) attributes |= OBJ_KEY_WOW64; @@ -810,9 +835,10 @@ static struct key *create_key( struct key *parent, const struct unicode_str *nam
if (options & REG_OPTION_CREATE_LINK) attributes = (attributes & ~OBJ_OPENIF) | OBJ_OPENLINK;
- if (parent && (access & KEY_WOW64_32KEY)) + if (parent && (access & KEY_WOW64_32KEY) && !is_wow6432node( name->str, name->len )) { - if (parent->wow6432node && !is_wow6432node( name->str, name->len )) parent = parent->wow6432node; + if ((key = get_wow6432node( parent ))) + parent = key; }
if (!(access & KEY_WOW64_64KEY)) attributes |= OBJ_KEY_WOW64;
From: Sven Baars sbaars@codeweavers.com
--- dlls/ntdll/tests/reg.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
diff --git a/dlls/ntdll/tests/reg.c b/dlls/ntdll/tests/reg.c index 383397bd9da..fb08a4e5650 100644 --- a/dlls/ntdll/tests/reg.c +++ b/dlls/ntdll/tests/reg.c @@ -1648,6 +1648,22 @@ static void test_redirection(void) ok( status == STATUS_SUCCESS, "NtDeleteKey failed: 0x%08lx\n", status ); pNtClose( key64 );
+ pRtlInitUnicodeString( &str, L"Winetest" ); + attr.RootDirectory = root64; + status = pNtCreateKey( &key32, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr, 0, 0, 0, 0 ); + ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status ); + + pRtlInitUnicodeString( &str, L"\Registry\Machine\Software\Wow6432Node\Wine\Winetest" ); + attr.RootDirectory = 0; + status = pNtOpenKey( &key, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr ); + ok( status == (ptr_size == 64 ? STATUS_OBJECT_NAME_NOT_FOUND : STATUS_SUCCESS), + "NtOpenKey failed: 0x%08lx\n", status ); + pNtClose( key ); + + status = pNtDeleteKey( key32 ); + ok( status == STATUS_SUCCESS, "NtDeleteKey failed: 0x%08lx\n", status ); + pNtClose( key32 ); + pNtDeleteKey( root32 ); pNtClose( root32 ); pNtDeleteKey( root64 );
From: Sven Baars sbaars@codeweavers.com
--- dlls/ntdll/tests/reg.c | 244 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 244 insertions(+)
diff --git a/dlls/ntdll/tests/reg.c b/dlls/ntdll/tests/reg.c index fb08a4e5650..4dfdfb87391 100644 --- a/dlls/ntdll/tests/reg.c +++ b/dlls/ntdll/tests/reg.c @@ -1466,13 +1466,18 @@ static void _check_key_value( int line, HANDLE root, const char *name, DWORD fla
static void test_redirection(void) { + WCHAR wineW[] = {'W','i','n','e'}; NTSTATUS status; OBJECT_ATTRIBUTES attr; UNICODE_STRING str; char buffer[1024]; KEY_VALUE_PARTIAL_INFORMATION *info = (KEY_VALUE_PARTIAL_INFORMATION *)buffer; + KEY_BASIC_INFORMATION *basic_info = (KEY_BASIC_INFORMATION *)buffer; + KEY_FULL_INFORMATION *full_info = (KEY_FULL_INFORMATION *)buffer; DWORD dw, len; HANDLE key, key32, key64, root, root32, root64; + int i, subkeys, subkeys64, subkeys32; + BOOL found;
if (ptr_size != 64) { @@ -2060,6 +2065,245 @@ static void test_redirection(void)
pNtClose( root64 ); pNtClose( root32 ); + + pRtlInitUnicodeString( &str, L"\Registry\Machine\Software\Classes\Wow6432Node\Wine" ); + attr.RootDirectory = 0; + status = pNtCreateKey( &key32, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr, 0, 0, 0, 0 ); + ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status ); + + status = pNtOpenKey( &key, KEY_ALL_ACCESS, &attr ); + ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status ); + pNtClose( key ); + + status = pNtOpenKey( &key, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr ); + ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status ); + pNtClose( key ); + + status = pNtOpenKey( &key, KEY_WOW64_64KEY | KEY_ALL_ACCESS, &attr ); + ok( status == (ptr_size == 32 ? STATUS_OBJECT_NAME_NOT_FOUND : STATUS_SUCCESS), + "NtOpenKey failed: 0x%08lx\n", status ); + if (!status) pNtClose( key ); + + pRtlInitUnicodeString( &str, L"\Registry\Machine\Software\Classes\Wine" ); + status = pNtOpenKey( &key, KEY_ALL_ACCESS, &attr ); + ok( status == (ptr_size == 64 ? STATUS_OBJECT_NAME_NOT_FOUND : STATUS_SUCCESS), + "NtOpenKey failed: 0x%08lx\n", status ); + if (!status) pNtClose( key ); + + status = pNtOpenKey( &key, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr ); + ok( status == (ptr_size == 64 ? STATUS_OBJECT_NAME_NOT_FOUND : STATUS_SUCCESS), + "NtOpenKey failed: 0x%08lx\n", status ); + if (!status) pNtClose( key ); + + status = pNtOpenKey( &key, KEY_WOW64_64KEY | KEY_ALL_ACCESS, &attr ); + ok( status == (ptr_size == 64 ? STATUS_OBJECT_NAME_NOT_FOUND : STATUS_SUCCESS), + "NtOpenKey failed: 0x%08lx\n", status ); + if (!status) pNtClose( key ); + + pRtlInitUnicodeString( &str, L"\Registry\Machine\Software\Classes\Wow6432Node" ); + status = pNtOpenKey( &root32, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr ); + ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status ); + + status = pNtQueryKey( root32, KeyFullInformation, full_info, sizeof(buffer), &len ); + ok( status == STATUS_SUCCESS, "NtQueryKey failed: 0x%08lx\n", status ); + ok( full_info->SubKeys > 0, "wrong number of subkeys: %lu\n", full_info->SubKeys ); + subkeys32 = full_info->SubKeys; + pNtClose( root32 ); + + pRtlInitUnicodeString( &str, L"\Registry\Machine\Software\Classes" ); + status = pNtOpenKey( &root64, KEY_WOW64_64KEY | KEY_ALL_ACCESS, &attr ); + ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status ); + + status = pNtQueryKey( root64, KeyFullInformation, full_info, sizeof(buffer), &len ); + ok( status == STATUS_SUCCESS, "NtQueryKey failed: 0x%08lx\n", status ); + ok( full_info->SubKeys > subkeys32, "wrong number of subkeys: %lu\n", full_info->SubKeys ); + subkeys64 = full_info->SubKeys; + pNtClose( root64 ); + + status = pNtOpenKey( &root32, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr ); + ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status ); + + status = pNtQueryKey( root32, KeyFullInformation, full_info, sizeof(buffer), &len ); + ok( status == STATUS_SUCCESS, "NtQueryKey failed: 0x%08lx\n", status ); + todo_wine_if(ptr_size == 32) ok( full_info->SubKeys == subkeys64, "wrong number of subkeys: %lu\n", full_info->SubKeys ); + subkeys = full_info->SubKeys; + + found = FALSE; + for (i = 0; i < subkeys; i++) + { + status = pNtEnumerateKey( root32, i, KeyBasicInformation, basic_info, sizeof(buffer), &len ); + ok( status == STATUS_SUCCESS, "NtEnumerateKey failed: 0x%08lx\n", status ); + + if (basic_info->NameLength == sizeof(wineW) && !memcmp(basic_info->Name, wineW, sizeof(wineW) )) + found = TRUE; + } + todo_wine_if(ptr_size == 32) ok( ptr_size == 32 ? found : !found, "key not found\n" ); + pNtClose( root32 ); + + status = pNtOpenKey( &root64, KEY_WOW64_64KEY | KEY_ALL_ACCESS, &attr ); + ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status ); + + status = pNtQueryKey( root64, KeyFullInformation, full_info, sizeof(buffer), &len ); + ok( status == STATUS_SUCCESS, "NtQueryKey failed: 0x%08lx\n", status ); + ok( full_info->SubKeys == subkeys64, "wrong number of subkeys: %lu\n", full_info->SubKeys ); + subkeys = full_info->SubKeys; + + found = FALSE; + for (i = 0; i < subkeys; i++) + { + status = pNtEnumerateKey( root64, i, KeyBasicInformation, basic_info, sizeof(buffer), &len ); + ok( status == STATUS_SUCCESS, "NtEnumerateKey failed: 0x%08lx\n", status ); + + if (basic_info->NameLength == sizeof(wineW) && !memcmp(basic_info->Name, wineW, sizeof(wineW) )) + found = TRUE; + } + ok( ptr_size == 32 ? found : !found, "key not found\n" ); + pNtClose( root64 ); + + status = pNtOpenKey( &root64, KEY_ALL_ACCESS, &attr ); + ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status ); + + status = pNtQueryKey( root64, KeyFullInformation, full_info, sizeof(buffer), &len ); + ok( status == STATUS_SUCCESS, "NtQueryKey failed: 0x%08lx\n", status ); + todo_wine_if(ptr_size == 32) ok( full_info->SubKeys == subkeys64, "wrong number of subkeys: %lu\n", full_info->SubKeys ); + subkeys = full_info->SubKeys; + + found = FALSE; + for (i = 0; i < subkeys; i++) + { + status = pNtEnumerateKey( root64, i, KeyBasicInformation, basic_info, sizeof(buffer), &len ); + ok( status == STATUS_SUCCESS, "NtEnumerateKey failed: 0x%08lx\n", status ); + + if (basic_info->NameLength == sizeof(wineW) && !memcmp(basic_info->Name, wineW, sizeof(wineW) )) + found = TRUE; + } + todo_wine_if(ptr_size == 32) ok( ptr_size == 32 ? found : !found, "key not found\n" ); + pNtClose( root64 ); + + pRtlInitUnicodeString( &str, L"\Registry\Machine\Software\Classes\Wow6432Node" ); + status = pNtOpenKey( &root32, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr ); + ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status ); + + status = pNtQueryKey( root32, KeyFullInformation, full_info, sizeof(buffer), &len ); + ok( status == STATUS_SUCCESS, "NtQueryKey failed: 0x%08lx\n", status ); + ok( full_info->SubKeys == subkeys32, "wrong number of subkeys: %lu\n", full_info->SubKeys ); + subkeys = full_info->SubKeys; + + found = FALSE; + for (i = 0; i < subkeys; i++) + { + status = pNtEnumerateKey( root32, i, KeyBasicInformation, basic_info, sizeof(buffer), &len ); + ok( status == STATUS_SUCCESS, "NtEnumerateKey failed: 0x%08lx\n", status ); + + if (basic_info->NameLength == sizeof(wineW) && !memcmp(basic_info->Name, wineW, sizeof(wineW) )) + found = TRUE; + } + ok( ptr_size == 32 ? !found : found, "key not found\n" ); + pNtClose( root32 ); + + status = pNtOpenKey( &root64, KEY_WOW64_64KEY | KEY_ALL_ACCESS, &attr ); + ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status ); + + status = pNtQueryKey( root64, KeyFullInformation, full_info, sizeof(buffer), &len ); + ok( status == STATUS_SUCCESS, "NtQueryKey failed: 0x%08lx\n", status ); + ok( full_info->SubKeys == subkeys32, "wrong number of subkeys: %lu\n", full_info->SubKeys ); + subkeys = full_info->SubKeys; + + found = FALSE; + for (i = 0; i < subkeys; i++) + { + status = pNtEnumerateKey( root64, i, KeyBasicInformation, basic_info, sizeof(buffer), &len ); + ok( status == STATUS_SUCCESS, "NtEnumerateKey failed: 0x%08lx\n", status ); + + if (basic_info->NameLength == sizeof(wineW) && !memcmp(basic_info->Name, wineW, sizeof(wineW) )) + found = TRUE; + } + ok( ptr_size == 32 ? !found : found, "key not found\n" ); + pNtClose( root64 ); + + status = pNtOpenKey( &root64, KEY_ALL_ACCESS, &attr ); + ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status ); + + status = pNtQueryKey( root64, KeyFullInformation, full_info, sizeof(buffer), &len ); + ok( status == STATUS_SUCCESS, "NtQueryKey failed: 0x%08lx\n", status ); + ok( full_info->SubKeys == subkeys32, "wrong number of subkeys: %lu\n", full_info->SubKeys ); + subkeys = full_info->SubKeys; + + found = FALSE; + for (i = 0; i < subkeys; i++) + { + status = pNtEnumerateKey( root64, i, KeyBasicInformation, basic_info, sizeof(buffer), &len ); + ok( status == STATUS_SUCCESS, "NtEnumerateKey failed: 0x%08lx\n", status ); + + if (basic_info->NameLength == sizeof(wineW) && !memcmp(basic_info->Name, wineW, sizeof(wineW) )) + found = TRUE; + } + ok( ptr_size == 32 ? !found : found, "key not found\n" ); + pNtClose( root64 ); + + pRtlInitUnicodeString( &str, L"\Registry\Machine\Software\Wow6432Node\Classes" ); + status = pNtOpenKey( &root32, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr ); + ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status ); + + status = pNtQueryKey( root32, KeyFullInformation, full_info, sizeof(buffer), &len ); + ok( status == STATUS_SUCCESS, "NtQueryKey failed: 0x%08lx\n", status ); + todo_wine_if(ptr_size == 32) ok( full_info->SubKeys == (ptr_size == 32 ? subkeys64 : subkeys32), "wrong number of subkeys: %lu\n", full_info->SubKeys ); + subkeys = full_info->SubKeys; + + found = FALSE; + for (i = 0; i < subkeys; i++) + { + status = pNtEnumerateKey( root32, i, KeyBasicInformation, basic_info, sizeof(buffer), &len ); + ok( status == STATUS_SUCCESS, "NtEnumerateKey failed: 0x%08lx\n", status ); + + if (basic_info->NameLength == sizeof(wineW) && !memcmp(basic_info->Name, wineW, sizeof(wineW) )) + found = TRUE; + } + todo_wine_if(ptr_size == 32) ok( found, "key not found\n" ); + pNtClose( root32 ); + + status = pNtOpenKey( &root64, KEY_WOW64_64KEY | KEY_ALL_ACCESS, &attr ); + ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status ); + + status = pNtQueryKey( root64, KeyFullInformation, full_info, sizeof(buffer), &len ); + ok( status == STATUS_SUCCESS, "NtQueryKey failed: 0x%08lx\n", status ); + ok( full_info->SubKeys == subkeys32, "wrong number of subkeys: %lu\n", full_info->SubKeys ); + subkeys = full_info->SubKeys; + + found = FALSE; + for (i = 0; i < subkeys; i++) + { + status = pNtEnumerateKey( root64, i, KeyBasicInformation, basic_info, sizeof(buffer), &len ); + ok( status == STATUS_SUCCESS, "NtEnumerateKey failed: 0x%08lx\n", status ); + + if (basic_info->NameLength == sizeof(wineW) && !memcmp(basic_info->Name, wineW, sizeof(wineW) )) + found = TRUE; + } + ok( ptr_size == 32 ? !found : found, "key not found\n" ); + pNtClose( root64 ); + + status = pNtOpenKey( &root64, KEY_ALL_ACCESS, &attr ); + ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status ); + + status = pNtQueryKey( root64, KeyFullInformation, full_info, sizeof(buffer), &len ); + ok( status == STATUS_SUCCESS, "NQtueryKey failed: 0x%08lx\n", status ); + todo_wine_if(ptr_size == 32) ok( full_info->SubKeys == (ptr_size == 32 ? subkeys64 : subkeys32), "wrong number of subkeys: %lu\n", full_info->SubKeys ); + subkeys = full_info->SubKeys; + + found = FALSE; + for (i = 0; i < subkeys; i++) + { + status = pNtEnumerateKey( root64, i, KeyBasicInformation, basic_info, sizeof(buffer), &len ); + ok( status == STATUS_SUCCESS, "NtEnumerateKey failed: 0x%08lx\n", status ); + + if (basic_info->NameLength == sizeof(wineW) && !memcmp(basic_info->Name, wineW, sizeof(wineW) )) + found = TRUE; + } + todo_wine_if(ptr_size == 32) ok( found, "key not found\n" ); + pNtClose( root64 ); + + pNtDeleteKey( key32 ); + pNtClose( key32 ); }
static void test_long_value_name(void)
From: Sven Baars sbaars@codeweavers.com
--- dlls/ntdll/tests/reg.c | 16 ++++++++-------- server/registry.c | 20 ++++++++++++++++---- 2 files changed, 24 insertions(+), 12 deletions(-)
diff --git a/dlls/ntdll/tests/reg.c b/dlls/ntdll/tests/reg.c index 4dfdfb87391..30044d4e1f2 100644 --- a/dlls/ntdll/tests/reg.c +++ b/dlls/ntdll/tests/reg.c @@ -2125,7 +2125,7 @@ static void test_redirection(void)
status = pNtQueryKey( root32, KeyFullInformation, full_info, sizeof(buffer), &len ); ok( status == STATUS_SUCCESS, "NtQueryKey failed: 0x%08lx\n", status ); - todo_wine_if(ptr_size == 32) ok( full_info->SubKeys == subkeys64, "wrong number of subkeys: %lu\n", full_info->SubKeys ); + ok( full_info->SubKeys == subkeys64, "wrong number of subkeys: %lu\n", full_info->SubKeys ); subkeys = full_info->SubKeys;
found = FALSE; @@ -2137,7 +2137,7 @@ static void test_redirection(void) if (basic_info->NameLength == sizeof(wineW) && !memcmp(basic_info->Name, wineW, sizeof(wineW) )) found = TRUE; } - todo_wine_if(ptr_size == 32) ok( ptr_size == 32 ? found : !found, "key not found\n" ); + ok( ptr_size == 32 ? found : !found, "key not found\n" ); pNtClose( root32 );
status = pNtOpenKey( &root64, KEY_WOW64_64KEY | KEY_ALL_ACCESS, &attr ); @@ -2165,7 +2165,7 @@ static void test_redirection(void)
status = pNtQueryKey( root64, KeyFullInformation, full_info, sizeof(buffer), &len ); ok( status == STATUS_SUCCESS, "NtQueryKey failed: 0x%08lx\n", status ); - todo_wine_if(ptr_size == 32) ok( full_info->SubKeys == subkeys64, "wrong number of subkeys: %lu\n", full_info->SubKeys ); + ok( full_info->SubKeys == subkeys64, "wrong number of subkeys: %lu\n", full_info->SubKeys ); subkeys = full_info->SubKeys;
found = FALSE; @@ -2177,7 +2177,7 @@ static void test_redirection(void) if (basic_info->NameLength == sizeof(wineW) && !memcmp(basic_info->Name, wineW, sizeof(wineW) )) found = TRUE; } - todo_wine_if(ptr_size == 32) ok( ptr_size == 32 ? found : !found, "key not found\n" ); + ok( ptr_size == 32 ? found : !found, "key not found\n" ); pNtClose( root64 );
pRtlInitUnicodeString( &str, L"\Registry\Machine\Software\Classes\Wow6432Node" ); @@ -2247,7 +2247,7 @@ static void test_redirection(void)
status = pNtQueryKey( root32, KeyFullInformation, full_info, sizeof(buffer), &len ); ok( status == STATUS_SUCCESS, "NtQueryKey failed: 0x%08lx\n", status ); - todo_wine_if(ptr_size == 32) ok( full_info->SubKeys == (ptr_size == 32 ? subkeys64 : subkeys32), "wrong number of subkeys: %lu\n", full_info->SubKeys ); + ok( full_info->SubKeys == (ptr_size == 32 ? subkeys64 : subkeys32), "wrong number of subkeys: %lu\n", full_info->SubKeys ); subkeys = full_info->SubKeys;
found = FALSE; @@ -2259,7 +2259,7 @@ static void test_redirection(void) if (basic_info->NameLength == sizeof(wineW) && !memcmp(basic_info->Name, wineW, sizeof(wineW) )) found = TRUE; } - todo_wine_if(ptr_size == 32) ok( found, "key not found\n" ); + ok( found, "key not found\n" ); pNtClose( root32 );
status = pNtOpenKey( &root64, KEY_WOW64_64KEY | KEY_ALL_ACCESS, &attr ); @@ -2287,7 +2287,7 @@ static void test_redirection(void)
status = pNtQueryKey( root64, KeyFullInformation, full_info, sizeof(buffer), &len ); ok( status == STATUS_SUCCESS, "NQtueryKey failed: 0x%08lx\n", status ); - todo_wine_if(ptr_size == 32) ok( full_info->SubKeys == (ptr_size == 32 ? subkeys64 : subkeys32), "wrong number of subkeys: %lu\n", full_info->SubKeys ); + ok( full_info->SubKeys == (ptr_size == 32 ? subkeys64 : subkeys32), "wrong number of subkeys: %lu\n", full_info->SubKeys ); subkeys = full_info->SubKeys;
found = FALSE; @@ -2299,7 +2299,7 @@ static void test_redirection(void) if (basic_info->NameLength == sizeof(wineW) && !memcmp(basic_info->Name, wineW, sizeof(wineW) )) found = TRUE; } - todo_wine_if(ptr_size == 32) ok( found, "key not found\n" ); + ok( found, "key not found\n" ); pNtClose( root64 );
pNtDeleteKey( key32 ); diff --git a/server/registry.c b/server/registry.c index d112987b2b9..03e5f20cae5 100644 --- a/server/registry.c +++ b/server/registry.c @@ -516,6 +516,15 @@ static struct object *key_lookup_name( struct object *obj, struct unicode_str *n set_error( STATUS_OBJECT_NAME_NOT_FOUND ); } } + + key = (struct key *)obj; + if (key && (key->flags & KEY_WOWSHARE) && (attr & OBJ_KEY_WOW64) && !name->str) + { + key = get_parent( key ); + release_object( obj ); + return grab_object( key ); + } + return obj; }
@@ -768,6 +777,7 @@ static struct key *grab_wow6432node( struct key *key ) struct key *ret = key->wow6432node;
if (!ret) return key; + if (ret->flags & KEY_WOWSHARE) return key; grab_object( ret ); release_object( key ); return ret; @@ -810,9 +820,10 @@ static struct key *open_key( struct key *parent, const struct unicode_str *name, return NULL; }
- if (parent && (access & KEY_WOW64_32KEY) && !is_wow6432node( name->str, name->len )) + if (parent && !(access & KEY_WOW64_64KEY) && !is_wow6432node( name->str, name->len )) { - if ((key = get_wow6432node( parent ))) + key = get_wow6432node( parent ); + if (key && ((access & KEY_WOW64_32KEY) || (key->flags & KEY_WOWSHARE))) parent = key; }
@@ -835,9 +846,10 @@ static struct key *create_key( struct key *parent, const struct unicode_str *nam
if (options & REG_OPTION_CREATE_LINK) attributes = (attributes & ~OBJ_OPENIF) | OBJ_OPENLINK;
- if (parent && (access & KEY_WOW64_32KEY) && !is_wow6432node( name->str, name->len )) + if (parent && !(access & KEY_WOW64_64KEY) && !is_wow6432node( name->str, name->len )) { - if ((key = get_wow6432node( parent ))) + key = get_wow6432node( parent ); + if (key && ((access & KEY_WOW64_32KEY) || (key->flags & KEY_WOWSHARE))) parent = key; }
From: Sven Baars sbaars@codeweavers.com
--- dlls/ntdll/tests/reg.c | 268 +++++++++++++---------------------------- 1 file changed, 83 insertions(+), 185 deletions(-)
diff --git a/dlls/ntdll/tests/reg.c b/dlls/ntdll/tests/reg.c index 30044d4e1f2..7676c63a54a 100644 --- a/dlls/ntdll/tests/reg.c +++ b/dlls/ntdll/tests/reg.c @@ -1464,20 +1464,81 @@ static void _check_key_value( int line, HANDLE root, const char *name, DWORD fla } #define check_key_value(root,name,flags,expect) _check_key_value( __LINE__, root, name, flags, expect )
+static void _check_enum_value( int line, const WCHAR *name, DWORD flags, int subkeys, BOOL present) +{ + static const WCHAR wineW[] = {'W','i','n','e'}; + char buffer[1024]; + KEY_BASIC_INFORMATION *basic_info = (KEY_BASIC_INFORMATION *)buffer; + KEY_FULL_INFORMATION *full_info = (KEY_FULL_INFORMATION *)buffer; + OBJECT_ATTRIBUTES attr; + UNICODE_STRING str; + NTSTATUS status; + BOOL found; + HANDLE key; + DWORD len; + int i; + + attr.Length = sizeof(attr); + attr.RootDirectory = 0; + attr.Attributes = OBJ_CASE_INSENSITIVE; + attr.ObjectName = &str; + attr.SecurityDescriptor = NULL; + attr.SecurityQualityOfService = NULL; + + pRtlInitUnicodeString( &str, name ); + status = pNtOpenKey( &key, flags, &attr ); + ok_( __FILE__, line )( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status ); + + status = pNtQueryKey( key, KeyFullInformation, full_info, sizeof(buffer), &len ); + ok_( __FILE__, line )( status == STATUS_SUCCESS, "NtQueryKey failed: 0x%08lx\n", status ); + ok_( __FILE__, line )( full_info->SubKeys == subkeys, "wrong number of subkeys: %lu\n", full_info->SubKeys ); + subkeys = full_info->SubKeys; + + found = FALSE; + for (i = 0; i < subkeys; i++) + { + status = pNtEnumerateKey( key, i, KeyBasicInformation, basic_info, sizeof(buffer), &len ); + ok_( __FILE__, line )( status == STATUS_SUCCESS, "NtEnumerateKey failed: 0x%08lx\n", status ); + + if (basic_info->NameLength == sizeof(wineW) && !memcmp(basic_info->Name, wineW, sizeof(wineW) )) + found = TRUE; + } + ok_( __FILE__, line )( found == present, "found equals %d\n", found ); + pNtClose( key ); + + status = pNtCreateKey( &key, flags, &attr, 0, 0, 0, 0 ); + ok_( __FILE__, line )( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status ); + + status = pNtQueryKey( key, KeyFullInformation, full_info, sizeof(buffer), &len ); + ok_( __FILE__, line )( status == STATUS_SUCCESS, "NtQueryKey failed: 0x%08lx\n", status ); + ok_( __FILE__, line )( full_info->SubKeys == subkeys, "wrong number of subkeys: %lu\n", full_info->SubKeys ); + subkeys = full_info->SubKeys; + + found = FALSE; + for (i = 0; i < subkeys; i++) + { + status = pNtEnumerateKey( key, i, KeyBasicInformation, basic_info, sizeof(buffer), &len ); + ok_( __FILE__, line )( status == STATUS_SUCCESS, "NtEnumerateKey failed: 0x%08lx\n", status ); + + if (basic_info->NameLength == sizeof(wineW) && !memcmp(basic_info->Name, wineW, sizeof(wineW) )) + found = TRUE; + } + ok_( __FILE__, line )( found == present, "found equals %d\n", found ); + pNtClose( key ); +} +#define check_enum_value(name, flags, subkeys, present) _check_enum_value( __LINE__, name, flags, subkeys, present ) + static void test_redirection(void) { - WCHAR wineW[] = {'W','i','n','e'}; NTSTATUS status; OBJECT_ATTRIBUTES attr; UNICODE_STRING str; char buffer[1024]; KEY_VALUE_PARTIAL_INFORMATION *info = (KEY_VALUE_PARTIAL_INFORMATION *)buffer; - KEY_BASIC_INFORMATION *basic_info = (KEY_BASIC_INFORMATION *)buffer; KEY_FULL_INFORMATION *full_info = (KEY_FULL_INFORMATION *)buffer; DWORD dw, len; HANDLE key, key32, key64, root, root32, root64; - int i, subkeys, subkeys64, subkeys32; - BOOL found; + int subkeys64, subkeys32;
if (ptr_size != 64) { @@ -2120,187 +2181,24 @@ static void test_redirection(void) subkeys64 = full_info->SubKeys; pNtClose( root64 );
- status = pNtOpenKey( &root32, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr ); - ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status ); - - status = pNtQueryKey( root32, KeyFullInformation, full_info, sizeof(buffer), &len ); - ok( status == STATUS_SUCCESS, "NtQueryKey failed: 0x%08lx\n", status ); - ok( full_info->SubKeys == subkeys64, "wrong number of subkeys: %lu\n", full_info->SubKeys ); - subkeys = full_info->SubKeys; - - found = FALSE; - for (i = 0; i < subkeys; i++) - { - status = pNtEnumerateKey( root32, i, KeyBasicInformation, basic_info, sizeof(buffer), &len ); - ok( status == STATUS_SUCCESS, "NtEnumerateKey failed: 0x%08lx\n", status ); - - if (basic_info->NameLength == sizeof(wineW) && !memcmp(basic_info->Name, wineW, sizeof(wineW) )) - found = TRUE; - } - ok( ptr_size == 32 ? found : !found, "key not found\n" ); - pNtClose( root32 ); - - status = pNtOpenKey( &root64, KEY_WOW64_64KEY | KEY_ALL_ACCESS, &attr ); - ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status ); - - status = pNtQueryKey( root64, KeyFullInformation, full_info, sizeof(buffer), &len ); - ok( status == STATUS_SUCCESS, "NtQueryKey failed: 0x%08lx\n", status ); - ok( full_info->SubKeys == subkeys64, "wrong number of subkeys: %lu\n", full_info->SubKeys ); - subkeys = full_info->SubKeys; - - found = FALSE; - for (i = 0; i < subkeys; i++) - { - status = pNtEnumerateKey( root64, i, KeyBasicInformation, basic_info, sizeof(buffer), &len ); - ok( status == STATUS_SUCCESS, "NtEnumerateKey failed: 0x%08lx\n", status ); - - if (basic_info->NameLength == sizeof(wineW) && !memcmp(basic_info->Name, wineW, sizeof(wineW) )) - found = TRUE; - } - ok( ptr_size == 32 ? found : !found, "key not found\n" ); - pNtClose( root64 ); - - status = pNtOpenKey( &root64, KEY_ALL_ACCESS, &attr ); - ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status ); - - status = pNtQueryKey( root64, KeyFullInformation, full_info, sizeof(buffer), &len ); - ok( status == STATUS_SUCCESS, "NtQueryKey failed: 0x%08lx\n", status ); - ok( full_info->SubKeys == subkeys64, "wrong number of subkeys: %lu\n", full_info->SubKeys ); - subkeys = full_info->SubKeys; - - found = FALSE; - for (i = 0; i < subkeys; i++) - { - status = pNtEnumerateKey( root64, i, KeyBasicInformation, basic_info, sizeof(buffer), &len ); - ok( status == STATUS_SUCCESS, "NtEnumerateKey failed: 0x%08lx\n", status ); - - if (basic_info->NameLength == sizeof(wineW) && !memcmp(basic_info->Name, wineW, sizeof(wineW) )) - found = TRUE; - } - ok( ptr_size == 32 ? found : !found, "key not found\n" ); - pNtClose( root64 ); - - pRtlInitUnicodeString( &str, L"\Registry\Machine\Software\Classes\Wow6432Node" ); - status = pNtOpenKey( &root32, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr ); - ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status ); - - status = pNtQueryKey( root32, KeyFullInformation, full_info, sizeof(buffer), &len ); - ok( status == STATUS_SUCCESS, "NtQueryKey failed: 0x%08lx\n", status ); - ok( full_info->SubKeys == subkeys32, "wrong number of subkeys: %lu\n", full_info->SubKeys ); - subkeys = full_info->SubKeys; - - found = FALSE; - for (i = 0; i < subkeys; i++) - { - status = pNtEnumerateKey( root32, i, KeyBasicInformation, basic_info, sizeof(buffer), &len ); - ok( status == STATUS_SUCCESS, "NtEnumerateKey failed: 0x%08lx\n", status ); - - if (basic_info->NameLength == sizeof(wineW) && !memcmp(basic_info->Name, wineW, sizeof(wineW) )) - found = TRUE; - } - ok( ptr_size == 32 ? !found : found, "key not found\n" ); - pNtClose( root32 ); - - status = pNtOpenKey( &root64, KEY_WOW64_64KEY | KEY_ALL_ACCESS, &attr ); - ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status ); - - status = pNtQueryKey( root64, KeyFullInformation, full_info, sizeof(buffer), &len ); - ok( status == STATUS_SUCCESS, "NtQueryKey failed: 0x%08lx\n", status ); - ok( full_info->SubKeys == subkeys32, "wrong number of subkeys: %lu\n", full_info->SubKeys ); - subkeys = full_info->SubKeys; - - found = FALSE; - for (i = 0; i < subkeys; i++) - { - status = pNtEnumerateKey( root64, i, KeyBasicInformation, basic_info, sizeof(buffer), &len ); - ok( status == STATUS_SUCCESS, "NtEnumerateKey failed: 0x%08lx\n", status ); - - if (basic_info->NameLength == sizeof(wineW) && !memcmp(basic_info->Name, wineW, sizeof(wineW) )) - found = TRUE; - } - ok( ptr_size == 32 ? !found : found, "key not found\n" ); - pNtClose( root64 ); - - status = pNtOpenKey( &root64, KEY_ALL_ACCESS, &attr ); - ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status ); - - status = pNtQueryKey( root64, KeyFullInformation, full_info, sizeof(buffer), &len ); - ok( status == STATUS_SUCCESS, "NtQueryKey failed: 0x%08lx\n", status ); - ok( full_info->SubKeys == subkeys32, "wrong number of subkeys: %lu\n", full_info->SubKeys ); - subkeys = full_info->SubKeys; - - found = FALSE; - for (i = 0; i < subkeys; i++) - { - status = pNtEnumerateKey( root64, i, KeyBasicInformation, basic_info, sizeof(buffer), &len ); - ok( status == STATUS_SUCCESS, "NtEnumerateKey failed: 0x%08lx\n", status ); - - if (basic_info->NameLength == sizeof(wineW) && !memcmp(basic_info->Name, wineW, sizeof(wineW) )) - found = TRUE; - } - ok( ptr_size == 32 ? !found : found, "key not found\n" ); - pNtClose( root64 ); - - pRtlInitUnicodeString( &str, L"\Registry\Machine\Software\Wow6432Node\Classes" ); - status = pNtOpenKey( &root32, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr ); - ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status ); - - status = pNtQueryKey( root32, KeyFullInformation, full_info, sizeof(buffer), &len ); - ok( status == STATUS_SUCCESS, "NtQueryKey failed: 0x%08lx\n", status ); - ok( full_info->SubKeys == (ptr_size == 32 ? subkeys64 : subkeys32), "wrong number of subkeys: %lu\n", full_info->SubKeys ); - subkeys = full_info->SubKeys; - - found = FALSE; - for (i = 0; i < subkeys; i++) - { - status = pNtEnumerateKey( root32, i, KeyBasicInformation, basic_info, sizeof(buffer), &len ); - ok( status == STATUS_SUCCESS, "NtEnumerateKey failed: 0x%08lx\n", status ); - - if (basic_info->NameLength == sizeof(wineW) && !memcmp(basic_info->Name, wineW, sizeof(wineW) )) - found = TRUE; - } - ok( found, "key not found\n" ); - pNtClose( root32 ); - - status = pNtOpenKey( &root64, KEY_WOW64_64KEY | KEY_ALL_ACCESS, &attr ); - ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status ); - - status = pNtQueryKey( root64, KeyFullInformation, full_info, sizeof(buffer), &len ); - ok( status == STATUS_SUCCESS, "NtQueryKey failed: 0x%08lx\n", status ); - ok( full_info->SubKeys == subkeys32, "wrong number of subkeys: %lu\n", full_info->SubKeys ); - subkeys = full_info->SubKeys; - - found = FALSE; - for (i = 0; i < subkeys; i++) - { - status = pNtEnumerateKey( root64, i, KeyBasicInformation, basic_info, sizeof(buffer), &len ); - ok( status == STATUS_SUCCESS, "NtEnumerateKey failed: 0x%08lx\n", status ); - - if (basic_info->NameLength == sizeof(wineW) && !memcmp(basic_info->Name, wineW, sizeof(wineW) )) - found = TRUE; - } - ok( ptr_size == 32 ? !found : found, "key not found\n" ); - pNtClose( root64 ); - - status = pNtOpenKey( &root64, KEY_ALL_ACCESS, &attr ); - ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status ); - - status = pNtQueryKey( root64, KeyFullInformation, full_info, sizeof(buffer), &len ); - ok( status == STATUS_SUCCESS, "NQtueryKey failed: 0x%08lx\n", status ); - ok( full_info->SubKeys == (ptr_size == 32 ? subkeys64 : subkeys32), "wrong number of subkeys: %lu\n", full_info->SubKeys ); - subkeys = full_info->SubKeys; - - found = FALSE; - for (i = 0; i < subkeys; i++) - { - status = pNtEnumerateKey( root64, i, KeyBasicInformation, basic_info, sizeof(buffer), &len ); - ok( status == STATUS_SUCCESS, "NtEnumerateKey failed: 0x%08lx\n", status ); - - if (basic_info->NameLength == sizeof(wineW) && !memcmp(basic_info->Name, wineW, sizeof(wineW) )) - found = TRUE; - } - ok( found, "key not found\n" ); - pNtClose( root64 ); + check_enum_value( L"\Registry\Machine\Software\Classes", + KEY_WOW64_32KEY | KEY_ALL_ACCESS, subkeys64, ptr_size == 32 ); + check_enum_value( L"\Registry\Machine\Software\Classes", + KEY_WOW64_64KEY | KEY_ALL_ACCESS, subkeys64, ptr_size == 32 ); + check_enum_value( L"\Registry\Machine\Software\Classes", + KEY_ALL_ACCESS, subkeys64, ptr_size == 32 ); + check_enum_value( L"\Registry\Machine\Software\Classes\Wow6432Node", + KEY_WOW64_32KEY | KEY_ALL_ACCESS, subkeys32, ptr_size == 64 ); + check_enum_value( L"\Registry\Machine\Software\Classes\Wow6432Node", + KEY_WOW64_64KEY | KEY_ALL_ACCESS, subkeys32, ptr_size == 64 ); + check_enum_value( L"\Registry\Machine\Software\Classes\Wow6432Node", + KEY_ALL_ACCESS, subkeys32, ptr_size == 64 ); + check_enum_value( L"\Registry\Machine\Software\Wow6432Node\Classes", + KEY_WOW64_32KEY | KEY_ALL_ACCESS, ptr_size == 32 ? subkeys64 : subkeys32, TRUE ); + check_enum_value( L"\Registry\Machine\Software\Wow6432Node\Classes", + KEY_WOW64_64KEY | KEY_ALL_ACCESS, subkeys32, ptr_size == 64 ); + check_enum_value( L"\Registry\Machine\Software\Wow6432Node\Classes", + KEY_ALL_ACCESS, ptr_size == 32 ? subkeys64 : subkeys32, TRUE );
pNtDeleteKey( key32 ); pNtClose( key32 );
From: Sven Baars sbaars@codeweavers.com
And add some extra ones. --- dlls/ntdll/tests/reg.c | 251 ++++++++++++----------------------------- 1 file changed, 72 insertions(+), 179 deletions(-)
diff --git a/dlls/ntdll/tests/reg.c b/dlls/ntdll/tests/reg.c index 7676c63a54a..978d50dbd0d 100644 --- a/dlls/ntdll/tests/reg.c +++ b/dlls/ntdll/tests/reg.c @@ -1763,68 +1763,27 @@ static void test_redirection(void) dw = 32; status = pNtSetValueKey( key32, &value_str, 0, REG_DWORD, &dw, sizeof(dw) ); ok( status == STATUS_SUCCESS, "NtSetValueKey failed: 0x%08lx\n", status ); - pNtClose( key32 );
dw = 64; status = pNtSetValueKey( key64, &value_str, 0, REG_DWORD, &dw, sizeof(dw) ); ok( status == STATUS_SUCCESS, "NtSetValueKey failed: 0x%08lx\n", status ); - pNtClose( key64 ); - - pRtlInitUnicodeString( &str, L"\Registry\Machine\Software\Classes\Wine" ); - status = pNtOpenKey( &key, KEY_ALL_ACCESS, &attr ); - ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status ); - len = sizeof(buffer); - status = pNtQueryValueKey( key, &value_str, KeyValuePartialInformation, info, len, &len ); - ok( status == STATUS_SUCCESS, "NtQueryValueKey failed: 0x%08lx\n", status ); - dw = *(DWORD *)info->Data; - ok( dw == 64, "wrong value %lu\n", dw ); - pNtClose( key );
- status = pNtOpenKey( &key64, KEY_WOW64_64KEY | KEY_ALL_ACCESS, &attr ); - ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status ); - len = sizeof(buffer); - status = pNtQueryValueKey( key64, &value_str, KeyValuePartialInformation, info, len, &len ); - ok( status == STATUS_SUCCESS, "NtQueryValueKey failed: 0x%08lx\n", status ); - dw = *(DWORD *)info->Data; - ok( dw == 64, "wrong value %lu\n", dw ); + check_key_value( 0, "\Registry\Machine\Software\Classes\Wine", 0, 64 ); + check_key_value( 0, "\Registry\Machine\Software\Classes\Wine", KEY_WOW64_64KEY, 64 ); + check_key_value( 0, "\Registry\Machine\Software\Classes\Wine", KEY_WOW64_32KEY, 64 ); + check_key_value( 0, "\Registry\Machine\Software\Classes\Wow6432Node\Wine", 0, ptr_size == 64 ? 32 : 64 ); + check_key_value( 0, "\Registry\Machine\Software\Classes\Wow6432Node\Wine", KEY_WOW64_64KEY, ptr_size == 64 ? 32 : 0 ); + check_key_value( 0, "\Registry\Machine\Software\Classes\Wow6432Node\Wine", KEY_WOW64_32KEY, ptr_size == 64 ? 32 : 64 );
- pRtlInitUnicodeString( &str, L"\Registry\Machine\Software\Classes\Wow6432Node\Wine" ); - status = pNtOpenKey( &key32, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr ); - ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status ); - len = sizeof(buffer); - status = pNtQueryValueKey( key32, &value_str, KeyValuePartialInformation, info, len, &len ); - ok( status == STATUS_SUCCESS, "NtQueryValueKey failed: 0x%08lx\n", status ); - dw = *(DWORD *)info->Data; - ok( dw == (ptr_size == 64 ? 32 : 64), "wrong value %lu\n", dw ); pNtDeleteKey( key32 ); pNtClose( key32 );
- pRtlInitUnicodeString( &str, L"\Registry\Machine\Software\Classes\Wine" ); - status = pNtOpenKey( &key, KEY_ALL_ACCESS, &attr ); - ok( status == (ptr_size == 32 ? STATUS_OBJECT_NAME_NOT_FOUND : STATUS_SUCCESS), - "NtOpenKey failed: 0x%08lx\n", status ); - if (!status) - { - len = sizeof(buffer); - status = pNtQueryValueKey( key, &value_str, KeyValuePartialInformation, info, len, &len ); - ok( status == STATUS_SUCCESS, "NtQueryValueKey failed: 0x%08lx\n", status ); - dw = *(DWORD *)info->Data; - ok( dw == ptr_size, "wrong value %lu\n", dw ); - pNtClose( key ); - } - - status = pNtOpenKey( &key, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr ); - ok( status == (ptr_size == 32 ? STATUS_OBJECT_NAME_NOT_FOUND : STATUS_SUCCESS), - "NtOpenKey failed: 0x%08lx\n", status ); - if (!status) - { - len = sizeof(buffer); - status = pNtQueryValueKey( key, &value_str, KeyValuePartialInformation, info, len, &len ); - ok( status == STATUS_SUCCESS, "NtQueryValueKey failed: 0x%08lx\n", status ); - dw = *(DWORD *)info->Data; - ok( dw == ptr_size, "wrong value %lu\n", dw ); - pNtClose( key ); - } + check_key_value( 0, "\Registry\Machine\Software\Classes\Wine", 0, ptr_size == 32 ? 0 : 64 ); + check_key_value( 0, "\Registry\Machine\Software\Classes\Wine", KEY_WOW64_64KEY, ptr_size == 32 ? 0 : 64 ); + check_key_value( 0, "\Registry\Machine\Software\Classes\Wine", KEY_WOW64_32KEY, ptr_size == 32 ? 0 : 64 ); + check_key_value( 0, "\Registry\Machine\Software\Classes\Wow6432Node\Wine", 0, 0 ); + check_key_value( 0, "\Registry\Machine\Software\Classes\Wow6432Node\Wine", KEY_WOW64_64KEY, 0 ); + check_key_value( 0, "\Registry\Machine\Software\Classes\Wow6432Node\Wine", KEY_WOW64_32KEY, 0 );
pNtDeleteKey( key64 ); pNtClose( key64 ); @@ -1862,85 +1821,45 @@ static void test_redirection(void) dw = 32; status = pNtSetValueKey( key32, &value_str, 0, REG_DWORD, &dw, sizeof(dw) ); ok( status == STATUS_SUCCESS, "NtSetValueKey failed: 0x%08lx\n", status ); - pNtClose( key32 );
dw = 64; status = pNtSetValueKey( key64, &value_str, 0, REG_DWORD, &dw, sizeof(dw) ); ok( status == STATUS_SUCCESS, "NtSetValueKey failed: 0x%08lx\n", status ); - pNtClose( key64 ); - - attr.RootDirectory = root64; - status = pNtOpenKey( &key, KEY_ALL_ACCESS, &attr ); - ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status ); - len = sizeof(buffer); - status = pNtQueryValueKey( key, &value_str, KeyValuePartialInformation, info, len, &len ); - ok( status == STATUS_SUCCESS, "NtQueryValueKey failed: 0x%08lx\n", status ); - dw = *(DWORD *)info->Data; - ok( dw == 64, "wrong value %lu\n", dw ); - pNtClose( key );
- attr.RootDirectory = root64; - status = pNtOpenKey( &key64, KEY_WOW64_64KEY | KEY_ALL_ACCESS, &attr ); - ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status ); - len = sizeof(buffer); - status = pNtQueryValueKey( key64, &value_str, KeyValuePartialInformation, info, len, &len ); - ok( status == STATUS_SUCCESS, "NtQueryValueKey failed: 0x%08lx\n", status ); - dw = *(DWORD *)info->Data; - ok( dw == 64, "wrong value %lu\n", dw ); + check_key_value( root64, "Wine", 0, 64 ); + check_key_value( root64, "Wine", KEY_WOW64_64KEY, 64 ); + check_key_value( root64, "Wine", KEY_WOW64_32KEY, 64 ); + check_key_value( root32, "Wine", 0, 64 ); + check_key_value( root32, "Wine", KEY_WOW64_64KEY, 64 ); + check_key_value( root32, "Wine", KEY_WOW64_32KEY, 64 );
- attr.RootDirectory = root32; - status = pNtOpenKey( &key32, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr ); - ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status ); - len = sizeof(buffer); - status = pNtQueryValueKey( key32, &value_str, KeyValuePartialInformation, info, len, &len ); - ok( status == STATUS_SUCCESS, "NtQueryValueKey failed: 0x%08lx\n", status ); - dw = *(DWORD *)info->Data; - ok( dw == 64, "wrong value %lu\n", dw ); pNtDeleteKey( key32 ); pNtClose( key32 );
- attr.RootDirectory = root64; - status = pNtOpenKey( &key, KEY_ALL_ACCESS, &attr ); - ok( status == STATUS_OBJECT_NAME_NOT_FOUND, "NtOpenKey failed: 0x%08lx\n", status ); - - status = pNtOpenKey( &key, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr ); - ok( status == STATUS_OBJECT_NAME_NOT_FOUND, "NtOpenKey failed: 0x%08lx\n", status ); - - attr.RootDirectory = root32; - status = pNtOpenKey( &key, KEY_ALL_ACCESS, &attr ); - ok( status == STATUS_OBJECT_NAME_NOT_FOUND, "NtOpenKey failed: 0x%08lx\n", status ); - - status = pNtOpenKey( &key, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr ); - ok( status == STATUS_OBJECT_NAME_NOT_FOUND, "NtOpenKey failed: 0x%08lx\n", status ); + check_key_value( root64, "Wine", 0, 0 ); + check_key_value( root64, "Wine", KEY_WOW64_64KEY, 0 ); + check_key_value( root64, "Wine", KEY_WOW64_32KEY, 0 ); + check_key_value( root32, "Wine", 0, 0 ); + check_key_value( root32, "Wine", KEY_WOW64_64KEY, 0 ); + check_key_value( root32, "Wine", KEY_WOW64_32KEY, 0 );
pNtDeleteKey( key64 ); pNtClose( key64 );
+ attr.RootDirectory = root32; status = pNtCreateKey( &key32, KEY_ALL_ACCESS, &attr, 0, 0, 0, 0 ); ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status ); + dw = 32; status = pNtSetValueKey( key32, &value_str, 0, REG_DWORD, &dw, sizeof(dw) ); ok( status == STATUS_SUCCESS, "NtSetValueKey failed: 0x%08lx\n", status );
- attr.RootDirectory = root64; - status = pNtOpenKey( &key, KEY_ALL_ACCESS, &attr ); - ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status ); - len = sizeof(buffer); - status = pNtQueryValueKey( key, &value_str, KeyValuePartialInformation, info, len, &len ); - ok( status == STATUS_SUCCESS, "NtQueryValueKey failed: 0x%08lx\n", status ); - dw = *(DWORD *)info->Data; - ok( dw == 32, "wrong value %lu\n", dw ); - pNtClose( key ); - - attr.RootDirectory = root64; - status = pNtOpenKey( &key64, KEY_WOW64_64KEY | KEY_ALL_ACCESS, &attr ); - ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status ); - len = sizeof(buffer); - status = pNtQueryValueKey( key64, &value_str, KeyValuePartialInformation, info, len, &len ); - ok( status == STATUS_SUCCESS, "NtQueryValueKey failed: 0x%08lx\n", status ); - dw = *(DWORD *)info->Data; - ok( dw == 32, "wrong value %lu\n", dw ); - pNtClose( key64 ); + check_key_value( root64, "Wine", 0, 32 ); + check_key_value( root64, "Wine", KEY_WOW64_64KEY, 32 ); + check_key_value( root64, "Wine", KEY_WOW64_32KEY, 32 ); + check_key_value( root32, "Wine", 0, 32 ); + check_key_value( root32, "Wine", KEY_WOW64_64KEY, 32 ); + check_key_value( root32, "Wine", KEY_WOW64_32KEY, 32 );
pNtDeleteKey( key32 ); pNtClose( key32 ); @@ -2030,96 +1949,70 @@ static void test_redirection(void) dw = 32; status = pNtSetValueKey( key32, &value_str, 0, REG_DWORD, &dw, sizeof(dw) ); ok( status == STATUS_SUCCESS, "NtSetValueKey failed: 0x%08lx\n", status ); - pNtClose( key32 );
dw = 64; status = pNtSetValueKey( key64, &value_str, 0, REG_DWORD, &dw, sizeof(dw) ); ok( status == STATUS_SUCCESS, "NtSetValueKey failed: 0x%08lx\n", status ); - pNtClose( key64 );
- attr.RootDirectory = root64; - status = pNtOpenKey( &key, KEY_ALL_ACCESS, &attr ); + check_key_value( root64, "Wine", 0, 64 ); + check_key_value( root64, "Wine", KEY_WOW64_64KEY, 64 ); + check_key_value( root64, "Wine", KEY_WOW64_32KEY, ptr_size ); + check_key_value( root32, "Wine", 0, ptr_size ); + check_key_value( root32, "Wine", KEY_WOW64_64KEY, ptr_size ); + check_key_value( root32, "Wine", KEY_WOW64_32KEY, ptr_size ); + + pRtlInitUnicodeString( &str, L"\Registry\Machine\Software\Classes\Interface" ); + attr.RootDirectory = 0; + status = pNtOpenKey( &key, KEY_WOW64_64KEY | KEY_ALL_ACCESS, &attr ); ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status ); - len = sizeof(buffer); - status = pNtQueryValueKey( key, &value_str, KeyValuePartialInformation, info, len, &len ); - ok( status == STATUS_SUCCESS, "NtQueryValueKey failed: 0x%08lx\n", status ); - dw = *(DWORD *)info->Data; - ok( dw == 64, "wrong value %lu\n", dw ); + check_key_value( key, "Wine", 0, 64 ); + check_key_value( key, "Wine", KEY_WOW64_64KEY, 64 ); + check_key_value( key, "Wine", KEY_WOW64_32KEY, ptr_size ); pNtClose( key );
- attr.RootDirectory = root64; - status = pNtOpenKey( &key64, KEY_WOW64_64KEY | KEY_ALL_ACCESS, &attr ); + status = pNtOpenKey( &key, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr ); ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status ); - len = sizeof(buffer); - status = pNtQueryValueKey( key64, &value_str, KeyValuePartialInformation, info, len, &len ); - ok( status == STATUS_SUCCESS, "NtQueryValueKey failed: 0x%08lx\n", status ); - dw = *(DWORD *)info->Data; - ok( dw == 64, "wrong value %lu\n", dw ); + check_key_value( key, "Wine", 0, ptr_size ); + check_key_value( key, "Wine", KEY_WOW64_64KEY, ptr_size ); + check_key_value( key, "Wine", KEY_WOW64_32KEY, ptr_size ); + pNtClose( key ); + + check_key_value( 0, "\Registry\Machine\Software\Classes\Interface\Wine", 0, ptr_size ); + check_key_value( 0, "\Registry\Machine\Software\Classes\Interface\Wine", KEY_WOW64_64KEY, 64 ); + check_key_value( 0, "\Registry\Machine\Software\Classes\Interface\Wine", KEY_WOW64_32KEY, ptr_size );
- attr.RootDirectory = root32; - status = pNtOpenKey( &key32, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr ); - ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status ); - len = sizeof(buffer); - status = pNtQueryValueKey( key32, &value_str, KeyValuePartialInformation, info, len, &len ); - ok( status == STATUS_SUCCESS, "NtQueryValueKey failed: 0x%08lx\n", status ); - dw = *(DWORD *)info->Data; - ok( dw == ptr_size, "wrong value %lu\n", dw ); pNtDeleteKey( key32 ); pNtClose( key32 );
- attr.RootDirectory = root64; - status = pNtOpenKey( &key, KEY_ALL_ACCESS, &attr ); - ok( status == (ptr_size == 64 ? STATUS_OBJECT_NAME_NOT_FOUND : STATUS_SUCCESS), - "NtOpenKey failed: 0x%08lx\n", status ); - if (!status) pNtClose( key ); - - status = pNtOpenKey( &key, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr ); - ok( status == STATUS_OBJECT_NAME_NOT_FOUND, "NtOpenKey failed: 0x%08lx\n", status ); - if (!status) pNtClose( key ); + check_key_value( root64, "Wine", 0, ptr_size == 64 ? 0 : 64 ); + check_key_value( root64, "Wine", KEY_WOW64_64KEY, ptr_size == 64 ? 0 : 64 ); + check_key_value( root64, "Wine", KEY_WOW64_32KEY, 0 ); + check_key_value( root32, "Wine", 0, 0 ); + check_key_value( root32, "Wine", KEY_WOW64_64KEY, 0 ); + check_key_value( root32, "Wine", KEY_WOW64_32KEY, 0 );
- attr.RootDirectory = root32; - status = pNtOpenKey( &key, KEY_ALL_ACCESS, &attr ); - ok( status == STATUS_OBJECT_NAME_NOT_FOUND, "NtOpenKey failed: 0x%08lx\n", status ); - - status = pNtOpenKey( &key, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr ); - ok( status == STATUS_OBJECT_NAME_NOT_FOUND, "NtOpenKey failed: 0x%08lx\n", status ); + check_key_value( 0, "\Registry\Machine\Software\Classes\Interface\Wine", 0, 0 ); + check_key_value( 0, "\Registry\Machine\Software\Classes\Interface\Wine", KEY_WOW64_64KEY, ptr_size == 64 ? 0 : 64 ); + check_key_value( 0, "\Registry\Machine\Software\Classes\Interface\Wine", KEY_WOW64_32KEY, 0 );
pNtDeleteKey( key64 ); pNtClose( key64 );
+ pRtlInitUnicodeString( &str, L"Wine" ); + attr.RootDirectory = root32; status = pNtCreateKey( &key32, KEY_ALL_ACCESS, &attr, 0, 0, 0, 0 ); ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status ); + dw = 32; status = pNtSetValueKey( key32, &value_str, 0, REG_DWORD, &dw, sizeof(dw) ); ok( status == STATUS_SUCCESS, "NtSetValueKey failed: 0x%08lx\n", status );
- attr.RootDirectory = root64; - status = pNtOpenKey( &key, KEY_ALL_ACCESS, &attr ); - ok( status == (ptr_size == 32 ? STATUS_OBJECT_NAME_NOT_FOUND : STATUS_SUCCESS), - "NtOpenKey failed: 0x%08lx\n", status ); - if (!status) - { - len = sizeof(buffer); - status = pNtQueryValueKey( key, &value_str, KeyValuePartialInformation, info, len, &len ); - ok( status == STATUS_SUCCESS, "NtQueryValueKey failed: 0x%08lx\n", status ); - dw = *(DWORD *)info->Data; - ok( dw == 32, "wrong value %lu\n", dw ); - pNtClose( key ); - } - - attr.RootDirectory = root64; - status = pNtOpenKey( &key64, KEY_WOW64_64KEY | KEY_ALL_ACCESS, &attr ); - ok( status == (ptr_size == 32 ? STATUS_OBJECT_NAME_NOT_FOUND : STATUS_SUCCESS), - "NtOpenKey failed: 0x%08lx\n", status ); - if (!status) - { - len = sizeof(buffer); - status = pNtQueryValueKey( key64, &value_str, KeyValuePartialInformation, info, len, &len ); - ok( status == STATUS_SUCCESS, "NtQueryValueKey failed: 0x%08lx\n", status ); - dw = *(DWORD *)info->Data; - ok( dw == 32, "wrong value %lu\n", dw ); - pNtClose( key64 ); - } + check_key_value( root64, "Wine", 0, ptr_size == 64 ? 32 : 0 ); + check_key_value( root64, "Wine", KEY_WOW64_64KEY, ptr_size == 64 ? 32 : 0 ); + check_key_value( root64, "Wine", KEY_WOW64_32KEY, 32 ); + check_key_value( root32, "Wine", 0, 32 ); + check_key_value( root32, "Wine", KEY_WOW64_64KEY, 32 ); + check_key_value( root32, "Wine", KEY_WOW64_32KEY, 32 );
pNtDeleteKey( key32 ); pNtClose( key32 );
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=126143
Your paranoid android.
=== debian11 (32 bit report) ===
crypt32: cert.c:4191: Test failed: success cert.c:4192: Test failed: got 00000000 cert.c:4193: Test failed: got 00000000
I updated my patches such that all the work that is done in the server is duplicated in kernelbase. The full branch can be found here:
https://gitlab.winehq.org/sbaars/wine/-/commits/shared-classes-new
the correctness of that branch can be tested more thoroughly by commenting out the `if (!(is_win64 && (access & KEY_WOW64_32KEY)))` part of `open_key`. This is not done in the branch itself for obvious performance reasons.
The old implementation that does the opposite and removes special handling from kernelbase can be found here:
https://gitlab.winehq.org/sbaars/wine/-/commits/shared-classes-old
I still like this approach much better, because there is less opportunity for introducing bugs. The internal flag that is used is currently already exposed to the outside world anyway. If we don't take this approach, we should probably do a `& ~OBJ_KEY_WOW64` somewhere in the server.