There is one more patch series of refactoring create_key() after this one, then I can start implementing things.
-- v3: kernelbase: Return the last existing key from open_key() when it's called from create_key(). kernelbase: Pass a name pointer to open_key(). kernelbase: Use open_key() to obtain any existing Wow6432node in create_key(). kernelbase: Call open_key() from open_subkey().
From: Sven Baars sbaars@codeweavers.com
--- dlls/advapi32/tests/registry.c | 465 +++++++++++++++++++++++++++++++-- 1 file changed, 438 insertions(+), 27 deletions(-)
diff --git a/dlls/advapi32/tests/registry.c b/dlls/advapi32/tests/registry.c index 528875261d6..d5d1274b708 100644 --- a/dlls/advapi32/tests/registry.c +++ b/dlls/advapi32/tests/registry.c @@ -2560,7 +2560,7 @@ static void test_symlinks(void) static DWORD get_key_value( HKEY root, const char *name, DWORD flags ) { HKEY key; - DWORD err, type, dw, len = sizeof(dw); + DWORD err, type, dw = 1, len = sizeof(dw);
err = RegOpenKeyExA( root, name, 0, flags | KEY_ALL_ACCESS, &key ); if (err == ERROR_FILE_NOT_FOUND) return 0; @@ -2582,11 +2582,49 @@ 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 _todo_check_key_value( int line, HANDLE root, const char *name, DWORD flags, DWORD expect, BOOL todo ) +{ + DWORD dw = get_key_value( root, name, flags ); + todo_wine_if(todo) ok_(__FILE__,line)( dw == expect, "%08lx: wrong value %lu/%lu\n", flags, dw, expect ); +} +#define todo_check_key_value(root,name,flags,expect, todo) _todo_check_key_value( __LINE__, root, name, flags, expect, todo ) + +static void _check_enum_value( int line, const char *name, DWORD flags, DWORD subkeys_in, BOOL found_in, + BOOL todo_subkeys, BOOL todo_found) +{ + char buffer[1024]; + DWORD err, i, subkeys; + BOOL found; + HKEY key; + + err = RegOpenKeyExA( HKEY_LOCAL_MACHINE, name, 0, flags, &key ); + ok_( __FILE__, line )( err == ERROR_SUCCESS, "RegOpenKeyExA failed: %lu\n", err ); + + err = RegQueryInfoKeyA( key, NULL, NULL, NULL, &subkeys, + NULL, NULL, NULL, NULL, NULL, NULL, NULL ); + ok_( __FILE__, line )( err == ERROR_SUCCESS, "RegQueryInfoKeyA failed: %lu\n", err ); + todo_wine_if(todo_subkeys) ok_( __FILE__, line )( subkeys == subkeys_in, "wrong number of subkeys: %lu\n", subkeys ); + + found = FALSE; + for (i = 0; i < subkeys; i++) + { + err = RegEnumKeyA( key, i, buffer, sizeof(buffer) ); + ok_( __FILE__, line )( err == ERROR_SUCCESS, "RegEnumKeyA failed: %lu\n", err ); + + if (!strcmp(buffer, "Wine")) + found = TRUE; + } + todo_wine_if(todo_found) ok_( __FILE__, line )( found == found_in, "found equals %d\n", found ); + RegCloseKey( key ); +} +#define check_enum_value(name, flags, subkeys, found, todo_subkeys, todo_found) _check_enum_value( \ + __LINE__, name, flags, subkeys, found, todo_subkeys, todo_found ) + static void test_redirection(void) { DWORD err, type, dw, len; - HKEY key, root32, root64, key32, key64, native, op_key; - REGSAM opposite = (sizeof(void*) == 8 ? KEY_WOW64_32KEY : KEY_WOW64_64KEY); + HKEY key, key32, key64, root, root32, root64; + DWORD subkeys, subkeys32, subkeys64;
if (ptr_size != 64) { @@ -2783,36 +2821,409 @@ static void test_redirection(void) RegCloseKey( root32 ); RegCloseKey( root64 );
- /* open key in native bit mode */ - err = RegOpenKeyExA(HKEY_CLASSES_ROOT, "Interface", 0, KEY_ALL_ACCESS, &native); - ok(err == ERROR_SUCCESS, "got %li\n", err); + /* Software\Classes is shared/reflected so behavior is different */
- pRegDeleteKeyExA(native, "AWineTest", 0, 0); - - /* write subkey in opposite bit mode */ - err = RegOpenKeyExA(HKEY_CLASSES_ROOT, "Interface", 0, KEY_ALL_ACCESS | opposite, &op_key); - ok(err == ERROR_SUCCESS, "got %li\n", err); - - err = RegCreateKeyExA(op_key, "AWineTest", 0, NULL, 0, KEY_ALL_ACCESS | opposite, - NULL, &key, NULL); - ok(err == ERROR_SUCCESS || err == ERROR_ACCESS_DENIED, "got %li\n", err); - if(err != ERROR_SUCCESS){ - win_skip("Can't write to registry\n"); - RegCloseKey(op_key); - RegCloseKey(native); + err = RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software\Classes\Wine", + 0, NULL, 0, KEY_WOW64_64KEY | KEY_ALL_ACCESS, NULL, &key64, NULL); + if (err == ERROR_ACCESS_DENIED) + { + skip("Not authorized to modify the Classes key\n"); return; } - RegCloseKey(key); + ok( err == ERROR_SUCCESS, "RegCreateKeyA failed: %lu\n", err ); + + err = RegOpenKeyExA( HKEY_LOCAL_MACHINE, "Software\Classes\Wow6432Node\Wine", + 0, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &key ); + todo_wine_if(ptr_size == 64) ok( err == ERROR_SUCCESS, "RegOpenKeyExA failed: %lu\n", err ); + RegCloseKey( key ); + + err = RegOpenKeyExA( HKEY_LOCAL_MACHINE, "Software\Classes\Wow6432Node\Wine", + 0, KEY_ALL_ACCESS, &key ); + ok( err == (ptr_size == 64 ? ERROR_FILE_NOT_FOUND : ERROR_SUCCESS), + "RegOpenKeyExA failed: %lu\n", err ); + if (!err) RegCloseKey( key ); + + err = RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software\Classes\Wow6432Node\Wine", + 0, NULL, 0, KEY_WOW64_32KEY | KEY_ALL_ACCESS, NULL, &key32, NULL); + ok( err == ERROR_SUCCESS, "RegCreateKeyA failed: %lu\n", err ); + + dw = 32; + err = RegSetValueExA( key32, "value", 0, REG_DWORD, (BYTE *)&dw, sizeof(dw) ); + ok( err == ERROR_SUCCESS, "RegSetValueExA failed: %lu\n", err ); + + dw = 64; + err = RegSetValueExA( key64, "value", 0, REG_DWORD, (BYTE *)&dw, sizeof(dw) ); + ok( err == ERROR_SUCCESS, "RegSetValueExA failed: %lu\n", err ); + + check_key_value( HKEY_LOCAL_MACHINE, "Software\Classes\Wine", 0, 64 ); + check_key_value( HKEY_LOCAL_MACHINE, "Software\Classes\Wine", KEY_WOW64_64KEY, 64 ); + todo_check_key_value( HKEY_LOCAL_MACHINE, "Software\Classes\Wine", KEY_WOW64_32KEY, 64, ptr_size == 64 ); + check_key_value( HKEY_LOCAL_MACHINE, "Software\Classes\Wow6432Node\Wine", 0, ptr_size == 64 ? 0 : 64 ); + check_key_value( HKEY_LOCAL_MACHINE, "Software\Classes\Wow6432Node\Wine", KEY_WOW64_64KEY, 0 ); + todo_check_key_value( HKEY_LOCAL_MACHINE, "Software\Classes\Wow6432Node\Wine", KEY_WOW64_32KEY, 64, ptr_size == 64 ); + + RegDeleteKeyA( key32, "" ); + RegCloseKey( key32 ); + + todo_check_key_value( HKEY_LOCAL_MACHINE, "Software\Classes\Wine", 0, 0, ptr_size == 64 ); + todo_check_key_value( HKEY_LOCAL_MACHINE, "Software\Classes\Wine", KEY_WOW64_64KEY, 0, ptr_size == 64 ); + check_key_value( HKEY_LOCAL_MACHINE, "Software\Classes\Wine", KEY_WOW64_32KEY, 0 ); + check_key_value( HKEY_LOCAL_MACHINE, "Software\Classes\Wow6432Node\Wine", 0, 0 ); + check_key_value( HKEY_LOCAL_MACHINE, "Software\Classes\Wow6432Node\Wine", KEY_WOW64_64KEY, 0 ); + check_key_value( HKEY_LOCAL_MACHINE, "Software\Classes\Wow6432Node\Wine", KEY_WOW64_32KEY, 0 ); + + RegDeleteKeyA( key64, "" ); + RegCloseKey( key64 ); + + err = RegOpenKeyExA( HKEY_LOCAL_MACHINE, "Software\Classes", 0, KEY_WOW64_64KEY | KEY_ALL_ACCESS, &root64 ); + ok( err == ERROR_SUCCESS, "RegOpenKeyExA failed: %lu\n", err ); + + err = RegOpenKeyExA( HKEY_LOCAL_MACHINE, "Software\Classes", 0, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &root32 ); + ok( err == ERROR_SUCCESS, "RegOpenKeyExA failed: %lu\n", err ); + + err = RegCreateKeyExA( root64, "Wine", 0, NULL, 0, + KEY_ALL_ACCESS, NULL, &key64, NULL); + ok( err == ERROR_SUCCESS, "RegCreateKeyA failed: %lu\n", err ); + + err = RegCreateKeyExA( key64, "Wine", 0, NULL, 0, + KEY_WOW64_32KEY | KEY_ALL_ACCESS, NULL, &key, NULL); + ok( err == ERROR_SUCCESS, "RegCreateKeyA failed: %lu\n", err ); + RegDeleteKeyA( key, "" ); + RegCloseKey( key ); + + err = RegOpenKeyExA( root32, "Wine", 0, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &key ); + todo_wine_if(ptr_size == 64) ok( err == ERROR_SUCCESS, "RegOpenKeyExA failed: %lu\n", err ); + RegCloseKey( key ); + + err = RegOpenKeyExA( root32, "Wine", 0, KEY_ALL_ACCESS, &key ); + todo_wine_if(ptr_size == 64) ok( err == ERROR_SUCCESS, "RegOpenKeyExA failed: %lu\n", err ); + RegCloseKey( key ); + + err = RegCreateKeyExA( root32, "Wine", 0, NULL, 0, + KEY_ALL_ACCESS, NULL, &key32, NULL); + ok( err == ERROR_SUCCESS, "RegCreateKeyA failed: %lu\n", err ); + + dw = 32; + err = RegSetValueExA( key32, "value", 0, REG_DWORD, (BYTE *)&dw, sizeof(dw) ); + ok( err == ERROR_SUCCESS, "RegSetValueExA failed: %lu\n", err ); + + dw = 64; + err = RegSetValueExA( key64, "value", 0, REG_DWORD, (BYTE *)&dw, sizeof(dw) ); + ok( err == ERROR_SUCCESS, "RegSetValueExA failed: %lu\n", err ); + + 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 ); + todo_check_key_value( root32, "Wine", 0, 64, ptr_size == 64 ); + todo_check_key_value( root32, "Wine", KEY_WOW64_64KEY, 64, ptr_size == 64 ); + todo_check_key_value( root32, "Wine", KEY_WOW64_32KEY, 64, ptr_size == 64 ); + + RegDeleteKeyA( key32, "" ); + RegCloseKey( key32 ); + + todo_check_key_value( root64, "Wine", 0, 0, ptr_size == 64 ); + todo_check_key_value( root64, "Wine", KEY_WOW64_64KEY, 0, ptr_size == 64 ); + todo_check_key_value( root64, "Wine", KEY_WOW64_32KEY, 0, ptr_size == 64 ); + 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 ); + + RegDeleteKeyA( key64, "" ); + RegCloseKey( key64 ); + + err = RegCreateKeyExA( root32, "Wine", 0, NULL, 0, + KEY_ALL_ACCESS, NULL, &key32, NULL); + ok( err == ERROR_SUCCESS, "RegCreateKeyA failed: %lu\n", err ); + + dw = 32; + err = RegSetValueExA( key32, "value", 0, REG_DWORD, (BYTE *)&dw, sizeof(dw) ); + ok( err == ERROR_SUCCESS, "RegSetValueExA failed: %lu\n", err ); + + todo_check_key_value( root64, "Wine", 0, 32, ptr_size == 64 ); + todo_check_key_value( root64, "Wine", KEY_WOW64_64KEY, 32, ptr_size == 64 ); + todo_check_key_value( root64, "Wine", KEY_WOW64_32KEY, 32, ptr_size == 64 ); + 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 ); + + RegDeleteKeyA( key32, "" ); + RegCloseKey( key32 ); + + RegCloseKey( root64 ); + RegCloseKey( root32 ); + + err = RegOpenKeyExA( HKEY_CLASSES_ROOT, "Interface", + 0, KEY_WOW64_64KEY | KEY_ALL_ACCESS, &root64 ); + ok( err == ERROR_SUCCESS, "RegOpenKeyExA failed: %lu\n", err );
- /* verify subkey is not present in native mode */ - err = RegOpenKeyExA(native, "AWineTest", 0, KEY_ALL_ACCESS, &key); - ok(err == ERROR_FILE_NOT_FOUND, "got %li\n", err); + err = RegOpenKeyExA( HKEY_CLASSES_ROOT, "Interface", + 0, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &root32 ); + ok( err == ERROR_SUCCESS, "RegOpenKeyExA failed: %lu\n", err );
- err = pRegDeleteKeyExA(op_key, "AWineTest", opposite, 0); - ok(err == ERROR_SUCCESS, "got %li\n", err); + err = RegOpenKeyExA( HKEY_CLASSES_ROOT, "Interface", + 0, KEY_ALL_ACCESS, &root ); + ok( err == ERROR_SUCCESS, "RegOpenKeyExA failed: %lu\n", err );
- RegCloseKey(op_key); - RegCloseKey(native); + 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 ); + + err = RegOpenKeyExA( root, "Wine", 0, KEY_ALL_ACCESS, &key ); + ok( err == (ptr_size == 64 ? ERROR_FILE_NOT_FOUND : ERROR_SUCCESS), + "RegOpenKeyExA failed: %lu\n", err ); + if (!err) RegCloseKey( key ); + + RegDeleteKeyA( key32, "" ); + RegCloseKey( key32 ); + + 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 ); + + err = RegOpenKeyExA( root, "Wine", 0, KEY_ALL_ACCESS, &key ); + ok( err == (ptr_size == 32 ? ERROR_FILE_NOT_FOUND : ERROR_SUCCESS), + "RegOpenKeyExA failed: %lu\n", err ); + if (!err) RegCloseKey( key ); + + RegDeleteKeyA( key64, "" ); + RegCloseKey( key64 ); + + RegDeleteKeyA( root64, "" ); + RegDeleteKeyA( root32, "" ); + RegDeleteKeyA( root, "" ); + + RegCloseKey( root64 ); + RegCloseKey( root32 ); + RegCloseKey( root ); + + err = RegOpenKeyExA( HKEY_LOCAL_MACHINE, "Software\Classes", + 0, KEY_WOW64_64KEY | KEY_ALL_ACCESS, &root64 ); + ok( err == ERROR_SUCCESS, "RegOpenKeyExA failed: %lu\n", err ); + + err = RegOpenKeyExA( HKEY_LOCAL_MACHINE, "Software\Classes", + 0, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &root32 ); + ok( err == ERROR_SUCCESS, "RegOpenKeyExA failed: %lu\n", err ); + + err = RegOpenKeyExA( HKEY_LOCAL_MACHINE, "Software\Classes", + 0, KEY_ALL_ACCESS, &root ); + ok( err == ERROR_SUCCESS, "RegOpenKeyExA failed: %lu\n", err ); + + err = RegOpenKeyExA( root64, "Interface", + 0, KEY_WOW64_64KEY | KEY_ALL_ACCESS, &key64 ); + ok( err == ERROR_SUCCESS, "RegOpenKeyExA failed: %lu\n", err ); + + err = RegOpenKeyExA( root32, "Interface", + 0, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &key32 ); + todo_wine_if(ptr_size == 64) ok( err == ERROR_SUCCESS, "RegOpenKeyExA failed: %lu\n", err ); + + err = RegOpenKeyExA( root, "Interface", + 0, KEY_ALL_ACCESS, &key ); + ok( err == ERROR_SUCCESS, "RegOpenKeyExA failed: %lu\n", err ); + + RegCloseKey( root64 ); + RegCloseKey( root32 ); + RegCloseKey( root ); + + root64 = key64; + root32 = key32; + root = key; + + err = RegCreateKeyExA( root32, "Wine", 0, NULL, 0, + KEY_WOW64_32KEY | KEY_ALL_ACCESS, NULL, &key32, NULL); + 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), + "RegOpenKeyExA failed: %lu\n", err ); + if (!err) RegCloseKey( key ); + + RegDeleteKeyA( key32, "" ); + RegCloseKey( key32 ); + + 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 ); + + err = RegOpenKeyExA( root, "Wine", 0, KEY_ALL_ACCESS, &key ); + ok( err == (ptr_size == 32 ? ERROR_FILE_NOT_FOUND : ERROR_SUCCESS), + "RegOpenKeyExA failed: %lu\n", err ); + if (!err) RegCloseKey( key ); + + RegDeleteKeyA( key64, "" ); + RegCloseKey( key64 ); + + RegDeleteKeyA( root, "" ); + RegCloseKey( root ); + + err = RegCreateKeyExA( root64, "Wine", 0, NULL, 0, + KEY_ALL_ACCESS, NULL, &key64, NULL); + ok( err == ERROR_SUCCESS, "RegCreateKeyA failed: %lu\n", err ); + + err = RegOpenKeyExA( root32, "Wine", 0, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &key ); + todo_wine_if(ptr_size == 64) ok( err == ERROR_FILE_NOT_FOUND, "RegOpenKeyExA failed: %lu\n", err ); + + err = RegOpenKeyExA( root32, "Wine", 0, KEY_ALL_ACCESS, &key ); + todo_wine_if(ptr_size == 64) ok( err == ERROR_FILE_NOT_FOUND, "RegOpenKeyExA failed: %lu\n", err ); + + err = RegCreateKeyExA( root32, "Wine", 0, NULL, 0, + KEY_ALL_ACCESS, NULL, &key32, NULL); + todo_wine_if(ptr_size == 64) ok( err == ERROR_SUCCESS, "RegCreateKeyA failed: %lu\n", err ); + + dw = 32; + err = RegSetValueExA( key32, "value", 0, REG_DWORD, (BYTE *)&dw, sizeof(dw) ); + todo_wine_if(ptr_size == 64) ok( err == ERROR_SUCCESS, "RegSetValueExA failed: %lu\n", err ); + + dw = 64; + err = RegSetValueExA( key64, "value", 0, REG_DWORD, (BYTE *)&dw, sizeof(dw) ); + ok( err == ERROR_SUCCESS, "RegSetValueExA failed: %lu\n", err ); + + check_key_value( root64, "Wine", 0, 64 ); + check_key_value( root64, "Wine", KEY_WOW64_64KEY, 64 ); + todo_check_key_value( root64, "Wine", KEY_WOW64_32KEY, 32, ptr_size == 64 ); + todo_wine_if(ptr_size == 64) check_key_value( root32, "Wine", 0, 32 ); + todo_wine_if(ptr_size == 64) check_key_value( root32, "Wine", KEY_WOW64_64KEY, 32 ); + todo_wine_if(ptr_size == 64) check_key_value( root32, "Wine", KEY_WOW64_32KEY, 32 ); + + err = RegOpenKeyExA( HKEY_LOCAL_MACHINE, "Software\Classes\Interface", + 0, KEY_WOW64_64KEY | KEY_ALL_ACCESS, &key ); + ok( err == ERROR_SUCCESS, "RegOpenKeyExA failed: %lu\n", err ); + check_key_value( key, "Wine", 0, 64 ); + check_key_value( key, "Wine", KEY_WOW64_64KEY, 64 ); + todo_check_key_value( key, "Wine", KEY_WOW64_32KEY, 32, ptr_size == 64 ); + RegCloseKey( key ); + + err = RegOpenKeyExA( HKEY_LOCAL_MACHINE, "Software\Classes\Interface", + 0, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &key ); + todo_wine_if(ptr_size == 64) ok( err == ERROR_SUCCESS, "RegOpenKeyExA failed: %lu\n", err ); + todo_wine_if(ptr_size == 64) check_key_value( key, "Wine", 0, 32 ); + todo_wine_if(ptr_size == 64) check_key_value( key, "Wine", KEY_WOW64_64KEY, 32 ); + todo_wine_if(ptr_size == 64) check_key_value( key, "Wine", KEY_WOW64_32KEY, 32 ); + RegCloseKey( key ); + + check_key_value( HKEY_LOCAL_MACHINE, "Software\Classes\Interface\Wine", 0, ptr_size ); + check_key_value( HKEY_LOCAL_MACHINE, "Software\Classes\Interface\Wine", KEY_WOW64_64KEY, 64 ); + todo_check_key_value( HKEY_LOCAL_MACHINE, "Software\Classes\Interface\Wine", KEY_WOW64_32KEY, 32, ptr_size == 64 ); + + RegDeleteKeyA( key32, "" ); + RegCloseKey( key32 ); + + check_key_value( root64, "Wine", 0, 64 ); + check_key_value( root64, "Wine", KEY_WOW64_64KEY, 64 ); + todo_check_key_value( root64, "Wine", KEY_WOW64_32KEY, 0, ptr_size == 64 ); + todo_wine_if(ptr_size == 64) check_key_value( root32, "Wine", 0, 0 ); + todo_wine_if(ptr_size == 64) check_key_value( root32, "Wine", KEY_WOW64_64KEY, 0 ); + todo_wine_if(ptr_size == 64) check_key_value( root32, "Wine", KEY_WOW64_32KEY, 0 ); + + check_key_value( HKEY_LOCAL_MACHINE, "Software\Classes\Interface\Wine", 0, ptr_size == 64 ? 64 : 0 ); + check_key_value( HKEY_LOCAL_MACHINE, "Software\Classes\Interface\Wine", KEY_WOW64_64KEY, 64 ); + check_key_value( HKEY_LOCAL_MACHINE, "Software\Classes\Interface\Wine", KEY_WOW64_32KEY, 0 ); + + RegDeleteKeyA( key64, "" ); + RegCloseKey( key64 ); + + err = RegCreateKeyExA( root32, "Wine", 0, NULL, 0, + KEY_ALL_ACCESS, NULL, &key32, NULL); + todo_wine_if(ptr_size == 64) ok( err == ERROR_SUCCESS, "RegCreateKeyA failed: %lu\n", err ); + + dw = 32; + err = RegSetValueExA( key32, "value", 0, REG_DWORD, (BYTE *)&dw, sizeof(dw) ); + todo_wine_if(ptr_size == 64) ok( err == ERROR_SUCCESS, "RegSetValueExA failed: %lu\n", err ); + + check_key_value( root64, "Wine", 0, 0 ); + check_key_value( root64, "Wine", KEY_WOW64_64KEY, 0 ); + todo_wine_if(ptr_size == 64) check_key_value( root64, "Wine", KEY_WOW64_32KEY, 32 ); + todo_wine_if(ptr_size == 64) check_key_value( root32, "Wine", 0, 32 ); + todo_wine_if(ptr_size == 64) check_key_value( root32, "Wine", KEY_WOW64_64KEY, 32 ); + todo_wine_if(ptr_size == 64) check_key_value( root32, "Wine", KEY_WOW64_32KEY, 32 ); + + RegDeleteKeyA( key32, "" ); + RegCloseKey( key32 ); + + RegCloseKey( root64 ); + RegCloseKey( root32 ); + + err = RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software\Classes\Wow6432Node\Wine", + 0, NULL, 0, KEY_ALL_ACCESS, NULL, &key32, NULL); + ok( err == ERROR_SUCCESS, "RegCreateKeyA failed: %lu\n", err ); + + err = RegOpenKeyExA( HKEY_LOCAL_MACHINE, "Software\Classes\Wow6432Node\Wine", + 0, KEY_ALL_ACCESS, &key ); + ok( err == ERROR_SUCCESS, "RegOpenKeyExA failed: %lu\n", err ); + RegCloseKey( key ); + + err = RegOpenKeyExA( HKEY_LOCAL_MACHINE, "Software\Classes\Wow6432Node\Wine", + 0, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &key ); + ok( err == (ptr_size == 64 ? ERROR_FILE_NOT_FOUND : ERROR_SUCCESS), + "RegOpenKeyExA failed: %lu\n", err ); + if (!err) RegCloseKey( key ); + + err = RegOpenKeyExA( HKEY_LOCAL_MACHINE, "Software\Classes\Wow6432Node\Wine", + 0, KEY_WOW64_64KEY | KEY_ALL_ACCESS, &key ); + ok( err == (ptr_size == 32 ? ERROR_FILE_NOT_FOUND : ERROR_SUCCESS), + "RegOpenKeyExA failed: %lu\n", err ); + if (!err) RegCloseKey( key ); + + err = RegOpenKeyExA( HKEY_LOCAL_MACHINE, "Software\Classes\Wine", + 0, KEY_ALL_ACCESS, &key ); + ok( err == (ptr_size == 64 ? ERROR_FILE_NOT_FOUND : ERROR_SUCCESS), + "RegOpenKeyExA failed: %lu\n", err ); + if (!err) RegCloseKey( key ); + + err = RegOpenKeyExA( HKEY_LOCAL_MACHINE, "Software\Classes\Wine", + 0, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &key ); + ok( err == (ptr_size == 64 ? ERROR_FILE_NOT_FOUND : ERROR_SUCCESS), + "RegOpenKeyExA failed: %lu\n", err ); + if (!err) RegCloseKey( key ); + + err = RegOpenKeyExA( HKEY_LOCAL_MACHINE, "Software\Classes\Wine", + 0, KEY_WOW64_64KEY | KEY_ALL_ACCESS, &key ); + ok( err == (ptr_size == 64 ? ERROR_FILE_NOT_FOUND : ERROR_SUCCESS), + "RegOpenKeyExA failed: %lu\n", err ); + if (!err) RegCloseKey( key ); + + err = RegOpenKeyExA( HKEY_LOCAL_MACHINE, "Software\Classes\Wow6432Node", + 0, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &root32 ); + ok( err == ERROR_SUCCESS, "RegOpenKeyExA failed: %lu\n", err ); + + err = RegQueryInfoKeyA(root32, NULL, NULL, NULL, &subkeys, + NULL, NULL, NULL, NULL, NULL, NULL, NULL ); + ok( err == ERROR_SUCCESS, "RegQueryInfoKeyA failed: %lu\n", err ); + todo_wine_if(ptr_size == 64) ok( subkeys > 0, "wrong number of subkeys: %lu\n", subkeys ); + subkeys32 = subkeys; + RegCloseKey( root32 ); + + err = RegOpenKeyExA( HKEY_LOCAL_MACHINE, "Software\Classes", + 0, KEY_WOW64_64KEY | KEY_ALL_ACCESS, &root64 ); + ok( err == ERROR_SUCCESS, "RegOpenKeyExA failed: %lu\n", err ); + + err = RegQueryInfoKeyA(root64, NULL, NULL, NULL, &subkeys, + NULL, NULL, NULL, NULL, NULL, NULL, NULL ); + ok( err == ERROR_SUCCESS, "RegQueryInfoKeyA failed: %lu\n", err ); + ok( subkeys > subkeys32, "wrong number of subkeys: %lu\n", subkeys ); + subkeys64 = subkeys; + RegCloseKey( root64 ); + + check_enum_value( "Software\Classes", + KEY_WOW64_32KEY | KEY_ALL_ACCESS, subkeys64, ptr_size == 32, ptr_size == 64, FALSE ); + check_enum_value( "Software\Classes", + KEY_WOW64_64KEY | KEY_ALL_ACCESS, subkeys64, ptr_size == 32, FALSE, FALSE ); + check_enum_value( "Software\Classes", + KEY_ALL_ACCESS, subkeys64, ptr_size == 32, FALSE, FALSE ); + check_enum_value( "Software\Classes\Wow6432Node", + KEY_WOW64_32KEY | KEY_ALL_ACCESS, subkeys32, ptr_size == 64, FALSE, ptr_size == 64 ); + check_enum_value( "Software\Classes\Wow6432Node", + KEY_WOW64_64KEY | KEY_ALL_ACCESS, subkeys32, ptr_size == 64, ptr_size == 64, FALSE ); + check_enum_value( "Software\Classes\Wow6432Node", + KEY_ALL_ACCESS, subkeys32, ptr_size == 64, ptr_size == 64, FALSE ); + check_enum_value( "Software\Wow6432Node\Classes", + KEY_WOW64_32KEY | KEY_ALL_ACCESS, subkeys64, ptr_size == 32, ptr_size == 64, FALSE ); + check_enum_value( "Software\Wow6432Node\Classes", + KEY_WOW64_64KEY | KEY_ALL_ACCESS, subkeys32, ptr_size == 64, ptr_size == 64, FALSE ); + check_enum_value( "Software\Wow6432Node\Classes", + KEY_ALL_ACCESS, ptr_size == 32 ? subkeys64 : subkeys32, TRUE, ptr_size == 64, FALSE ); + + RegDeleteKeyA( key32, "" ); + RegCloseKey( key32 ); }
static void test_classesroot(void)
From: Sven Baars sbaars@codeweavers.com
--- dlls/kernelbase/registry.c | 30 ++++++------------------------ 1 file changed, 6 insertions(+), 24 deletions(-)
diff --git a/dlls/kernelbase/registry.c b/dlls/kernelbase/registry.c index daf1afa2cd6..b294ff7e926 100644 --- a/dlls/kernelbase/registry.c +++ b/dlls/kernelbase/registry.c @@ -140,20 +140,15 @@ static HKEY get_perflib_key( HANDLE key ) return key; }
+static NTSTATUS open_key( HKEY *retkey, HKEY root, UNICODE_STRING name, DWORD options, ACCESS_MASK access ); + static NTSTATUS open_subkey( HKEY *subkey, HKEY root, UNICODE_STRING *name, DWORD options, ACCESS_MASK access ) { + ACCESS_MASK access_64 = access & ~KEY_WOW64_32KEY; DWORD i = 0, len = name->Length / sizeof(WCHAR); WCHAR *buffer = name->Buffer; - OBJECT_ATTRIBUTES attr; UNICODE_STRING str; - NTSTATUS status = 0; - - attr.Length = sizeof(attr); - attr.RootDirectory = root; - attr.ObjectName = &str; - attr.Attributes = 0; - attr.SecurityDescriptor = NULL; - attr.SecurityQualityOfService = NULL; + NTSTATUS status;
if (len > 0 && buffer[0] == '\') return STATUS_OBJECT_PATH_INVALID; while (i < len && buffer[i] != '\') i++; @@ -161,23 +156,10 @@ static NTSTATUS open_subkey( HKEY *subkey, HKEY root, UNICODE_STRING *name, DWOR str.Buffer = name->Buffer; str.Length = i * sizeof(WCHAR);
- if (i == len) - { - if (options & REG_OPTION_OPEN_LINK) attr.Attributes |= OBJ_OPENLINK; - } - else - { - if (!(options & REG_OPTION_OPEN_LINK)) attr.Attributes &= ~OBJ_OPENLINK; + if (i < len) options &= ~REG_OPTION_OPEN_LINK; - } - - status = NtOpenKeyEx( (HANDLE *)subkey, access, &attr, options ); - if (status == STATUS_PREDEFINED_HANDLE) - { - *subkey = get_perflib_key( *subkey ); - status = STATUS_SUCCESS; - }
+ status = open_key( subkey, root, str, options, access_64 ); if (!status) { while (i < len && buffer[i] == '\') i++;
From: Sven Baars sbaars@codeweavers.com
--- 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 );
From: Sven Baars sbaars@codeweavers.com
--- dlls/kernelbase/registry.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-)
diff --git a/dlls/kernelbase/registry.c b/dlls/kernelbase/registry.c index 93f8236aa43..c3223cca6fd 100644 --- a/dlls/kernelbase/registry.c +++ b/dlls/kernelbase/registry.c @@ -140,7 +140,7 @@ static HKEY get_perflib_key( HANDLE key ) return key; }
-static NTSTATUS open_key( HKEY *retkey, HKEY root, UNICODE_STRING name, DWORD options, ACCESS_MASK access ); +static NTSTATUS open_key( HKEY *retkey, HKEY root, UNICODE_STRING *name, DWORD options, ACCESS_MASK access );
static NTSTATUS open_subkey( HKEY *subkey, HKEY root, UNICODE_STRING *name, DWORD options, ACCESS_MASK access ) { @@ -161,7 +161,7 @@ static NTSTATUS open_subkey( HKEY *subkey, HKEY root, UNICODE_STRING *name, DWOR if (i < len) options &= ~REG_OPTION_OPEN_LINK;
- status = open_key( subkey, root, str, options, access_64 ); + status = open_key( subkey, root, &str, options, access_64 ); if (!status) { while (i < len && buffer[i] == '\') i++; @@ -184,7 +184,7 @@ static NTSTATUS open_subkey( HKEY *subkey, HKEY root, UNICODE_STRING *name, DWOR }
/* wrapper for NtOpenKeyEx to handle Wow6432 nodes */ -static NTSTATUS open_key( HKEY *retkey, HKEY root, UNICODE_STRING name, DWORD options, ACCESS_MASK access ) +static NTSTATUS open_key( HKEY *retkey, HKEY root, UNICODE_STRING *name, DWORD options, ACCESS_MASK access ) { HKEY subkey = 0, subkey_root = root; NTSTATUS status = 0; @@ -197,7 +197,7 @@ static NTSTATUS open_key( HKEY *retkey, HKEY root, UNICODE_STRING name, DWORD op
attr.Length = sizeof(attr); attr.RootDirectory = root; - attr.ObjectName = &name; + attr.ObjectName = name; attr.Attributes = 0; attr.SecurityDescriptor = NULL; attr.SecurityQualityOfService = NULL; @@ -212,9 +212,9 @@ static NTSTATUS open_key( HKEY *retkey, HKEY root, UNICODE_STRING name, DWORD op return status; }
- while (!status && (name.Length || !subkey)) + while (!status && (name->Length || !subkey)) { - status = open_subkey( &subkey, subkey_root, &name, options, access ); + status = open_subkey( &subkey, subkey_root, name, options, access ); if (subkey_root && subkey_root != root) NtClose( subkey_root ); subkey_root = subkey; } @@ -231,6 +231,8 @@ 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; + DWORD len = name.Length / sizeof(WCHAR); + WCHAR *buffer = name.Buffer; OBJECT_ATTRIBUTES attr; HKEY subkey;
@@ -255,7 +257,7 @@ 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 ); + status = open_key( &subkey, root, &name, options & REG_OPTION_OPEN_LINK, access ); if (!status && (options & REG_OPTION_CREATE_LINK)) { NtClose( subkey ); @@ -270,8 +272,7 @@ static NTSTATUS create_key( HKEY *retkey, HKEY root, UNICODE_STRING name, ULONG
if (status == STATUS_OBJECT_NAME_NOT_FOUND) { - WCHAR *buffer = name.Buffer; - DWORD attrs, i, len = name.Length / sizeof(WCHAR); + DWORD attrs, i;
attr.RootDirectory = root; attrs = attr.Attributes; @@ -548,7 +549,7 @@ LSTATUS WINAPI DECLSPEC_HOTPATCH RegOpenKeyExW( HKEY hkey, LPCWSTR name, DWORD o if (!(hkey = get_special_root_hkey( hkey, access ))) return ERROR_INVALID_HANDLE;
RtlInitUnicodeString( &nameW, name ); - return RtlNtStatusToDosError( open_key( retkey, hkey, nameW, options, access ) ); + return RtlNtStatusToDosError( open_key( retkey, hkey, &nameW, options, access ) ); }
@@ -598,7 +599,8 @@ LSTATUS WINAPI DECLSPEC_HOTPATCH RegOpenKeyExA( HKEY hkey, LPCSTR name, DWORD op if (!(status = RtlAnsiStringToUnicodeString( &NtCurrentTeb()->StaticUnicodeString, &nameA, FALSE ))) { - status = open_key( retkey, hkey, NtCurrentTeb()->StaticUnicodeString, options, access ); + UNICODE_STRING nameW = NtCurrentTeb()->StaticUnicodeString; + status = open_key( retkey, hkey, &nameW, options, access ); } return RtlNtStatusToDosError( status ); }
From: Sven Baars sbaars@codeweavers.com
--- dlls/kernelbase/registry.c | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-)
diff --git a/dlls/kernelbase/registry.c b/dlls/kernelbase/registry.c index c3223cca6fd..63855eeb555 100644 --- a/dlls/kernelbase/registry.c +++ b/dlls/kernelbase/registry.c @@ -140,7 +140,7 @@ static HKEY get_perflib_key( HANDLE key ) return key; }
-static NTSTATUS open_key( HKEY *retkey, HKEY root, UNICODE_STRING *name, DWORD options, ACCESS_MASK access ); +static NTSTATUS open_key( HKEY *retkey, HKEY root, UNICODE_STRING *name, DWORD options, ACCESS_MASK access, BOOL create );
static NTSTATUS open_subkey( HKEY *subkey, HKEY root, UNICODE_STRING *name, DWORD options, ACCESS_MASK access ) { @@ -161,7 +161,7 @@ static NTSTATUS open_subkey( HKEY *subkey, HKEY root, UNICODE_STRING *name, DWOR if (i < len) options &= ~REG_OPTION_OPEN_LINK;
- status = open_key( subkey, root, &str, options, access_64 ); + status = open_key( subkey, root, &str, options, access_64, FALSE ); if (!status) { while (i < len && buffer[i] == '\') i++; @@ -184,14 +184,14 @@ static NTSTATUS open_subkey( HKEY *subkey, HKEY root, UNICODE_STRING *name, DWOR }
/* wrapper for NtOpenKeyEx to handle Wow6432 nodes */ -static NTSTATUS open_key( HKEY *retkey, HKEY root, UNICODE_STRING *name, DWORD options, ACCESS_MASK access ) +static NTSTATUS open_key( HKEY *retkey, HKEY root, UNICODE_STRING *name, DWORD options, ACCESS_MASK access, BOOL create ) { HKEY subkey = 0, subkey_root = root; NTSTATUS status = 0;
*retkey = NULL;
- if (!(is_win64 && (access & KEY_WOW64_32KEY))) + if (!(is_win64 && (access & KEY_WOW64_32KEY)) && !create) { OBJECT_ATTRIBUTES attr;
@@ -215,12 +215,14 @@ static NTSTATUS open_key( HKEY *retkey, HKEY root, UNICODE_STRING *name, DWORD o while (!status && (name->Length || !subkey)) { status = open_subkey( &subkey, subkey_root, name, options, access ); - if (subkey_root && subkey_root != root) NtClose( subkey_root ); - subkey_root = subkey; + if (subkey && subkey_root && subkey_root != root) NtClose( subkey_root ); + if (subkey) subkey_root = subkey; }
- if (!status) + if (!status || (status == STATUS_OBJECT_NAME_NOT_FOUND && create)) *retkey = subkey_root; + else if (subkey_root && subkey_root != root) + NtClose( subkey_root );
return status; } @@ -231,8 +233,6 @@ 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; - DWORD len = name.Length / sizeof(WCHAR); - WCHAR *buffer = name.Buffer; OBJECT_ATTRIBUTES attr; HKEY subkey;
@@ -257,7 +257,7 @@ 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 ); + status = open_key( &subkey, root, &name, options & REG_OPTION_OPEN_LINK, access, TRUE ); if (!status && (options & REG_OPTION_CREATE_LINK)) { NtClose( subkey ); @@ -265,16 +265,14 @@ static NTSTATUS create_key( HKEY *retkey, HKEY root, UNICODE_STRING name, ULONG }
if (!status) - { if (dispos) *dispos = REG_OPENED_EXISTING_KEY; - attr.RootDirectory = subkey; - }
+ attr.RootDirectory = subkey; if (status == STATUS_OBJECT_NAME_NOT_FOUND) { - DWORD attrs, i; + DWORD attrs, i, len = name.Length / sizeof(WCHAR); + WCHAR *buffer = name.Buffer;
- attr.RootDirectory = root; attrs = attr.Attributes;
while (len) @@ -549,7 +547,7 @@ LSTATUS WINAPI DECLSPEC_HOTPATCH RegOpenKeyExW( HKEY hkey, LPCWSTR name, DWORD o if (!(hkey = get_special_root_hkey( hkey, access ))) return ERROR_INVALID_HANDLE;
RtlInitUnicodeString( &nameW, name ); - return RtlNtStatusToDosError( open_key( retkey, hkey, &nameW, options, access ) ); + return RtlNtStatusToDosError( open_key( retkey, hkey, &nameW, options, access, FALSE ) ); }
@@ -600,7 +598,7 @@ LSTATUS WINAPI DECLSPEC_HOTPATCH RegOpenKeyExA( HKEY hkey, LPCSTR name, DWORD op &nameA, FALSE ))) { UNICODE_STRING nameW = NtCurrentTeb()->StaticUnicodeString; - status = open_key( retkey, hkey, &nameW, options, access ); + status = open_key( retkey, hkey, &nameW, options, access, FALSE ); } return RtlNtStatusToDosError( status ); }