From: Sven Baars sbaars@codeweavers.com
--- dlls/advapi32/tests/registry.c | 2 +- dlls/ntdll/tests/reg.c | 4 ++-- server/registry.c | 36 +++++++++++++++++++++++++++++----- 3 files changed, 34 insertions(+), 8 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 dd7dbe19d17..ae681bb7aba 100644 --- a/dlls/ntdll/tests/reg.c +++ b/dlls/ntdll/tests/reg.c @@ -1631,7 +1631,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_if (ptr_size == 32) ok( dw == ptr_size, "wrong value %lu\n", dw ); + ok( dw == ptr_size, "wrong value %lu\n", dw ); pNtClose( key );
status = pNtCreateKey( &key, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr, 0, 0, 0, 0 ); @@ -1992,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;