mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-31 12:54:13 +00:00
kernelbase: Add support for shared registry keys.
This commit is contained in:
parent
3bbd37d0bb
commit
63c6b89314
2 changed files with 171 additions and 72 deletions
|
@ -2589,8 +2589,7 @@ static void _todo_check_key_value( int line, HANDLE root, const char *name, DWOR
|
|||
}
|
||||
#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)
|
||||
static void _check_enum_value( int line, const char *name, DWORD flags, DWORD subkeys_in, BOOL found_in)
|
||||
{
|
||||
char buffer[1024];
|
||||
DWORD err, i, subkeys;
|
||||
|
@ -2603,7 +2602,7 @@ static void _check_enum_value( int line, const char *name, DWORD flags, DWORD su
|
|||
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 );
|
||||
ok_( __FILE__, line )( subkeys == subkeys_in, "wrong number of subkeys: %lu\n", subkeys );
|
||||
|
||||
found = FALSE;
|
||||
for (i = 0; i < subkeys; i++)
|
||||
|
@ -2614,11 +2613,10 @@ static void _check_enum_value( int line, const char *name, DWORD flags, DWORD su
|
|||
if (!strcmp(buffer, "Wine"))
|
||||
found = TRUE;
|
||||
}
|
||||
todo_wine_if(todo_found) ok_( __FILE__, line )( found == found_in, "found equals %d\n", 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 )
|
||||
#define check_enum_value(name, flags, subkeys, found) _check_enum_value( __LINE__, name, flags, subkeys, found )
|
||||
|
||||
static void test_redirection(void)
|
||||
{
|
||||
|
@ -2834,7 +2832,7 @@ static void test_redirection(void)
|
|||
|
||||
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 );
|
||||
ok( err == ERROR_SUCCESS, "RegOpenKeyExA failed: %lu\n", err );
|
||||
RegCloseKey( key );
|
||||
|
||||
err = RegOpenKeyExA( HKEY_LOCAL_MACHINE, "Software\\Classes\\Wow6432Node\\Wine",
|
||||
|
@ -2857,16 +2855,16 @@ static void test_redirection(void)
|
|||
|
||||
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\\Wine", KEY_WOW64_32KEY, 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 );
|
||||
check_key_value( HKEY_LOCAL_MACHINE, "Software\\Classes\\Wow6432Node\\Wine", KEY_WOW64_32KEY, 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", 0, 0 );
|
||||
check_key_value( HKEY_LOCAL_MACHINE, "Software\\Classes\\Wine", KEY_WOW64_64KEY, 0 );
|
||||
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 );
|
||||
|
@ -2892,11 +2890,11 @@ static void test_redirection(void)
|
|||
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 );
|
||||
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 );
|
||||
ok( err == ERROR_SUCCESS, "RegOpenKeyExA failed: %lu\n", err );
|
||||
RegCloseKey( key );
|
||||
|
||||
err = RegCreateKeyExA( root32, "Wine", 0, NULL, 0,
|
||||
|
@ -2914,16 +2912,16 @@ static void test_redirection(void)
|
|||
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 );
|
||||
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 );
|
||||
|
||||
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( 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 );
|
||||
|
@ -2939,9 +2937,9 @@ static void test_redirection(void)
|
|||
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( 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 );
|
||||
|
@ -2958,7 +2956,7 @@ static void test_redirection(void)
|
|||
|
||||
err = RegOpenKeyExA( HKEY_CLASSES_ROOT, "Interface",
|
||||
0, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &root32 );
|
||||
todo_wine_if(ptr_size == 64) ok( err == ERROR_SUCCESS, "RegOpenKeyExA failed: %lu\n", err );
|
||||
ok( err == ERROR_SUCCESS, "RegOpenKeyExA failed: %lu\n", err );
|
||||
|
||||
err = RegOpenKeyExA( HKEY_CLASSES_ROOT, "Interface",
|
||||
0, KEY_ALL_ACCESS, &root );
|
||||
|
@ -2966,10 +2964,10 @@ static void test_redirection(void)
|
|||
|
||||
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 );
|
||||
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),
|
||||
todo_wine_if(ptr_size == 64) ok( err == (ptr_size == 64 ? ERROR_FILE_NOT_FOUND : ERROR_SUCCESS),
|
||||
"RegOpenKeyExA failed: %lu\n", err );
|
||||
if (!err) RegCloseKey( key );
|
||||
|
||||
|
@ -2978,10 +2976,10 @@ static void test_redirection(void)
|
|||
|
||||
err = RegCreateKeyExA( root64, "Wine", 0, NULL, 0,
|
||||
KEY_WOW64_64KEY | KEY_ALL_ACCESS, NULL, &key64, NULL);
|
||||
todo_wine_if(ptr_size == 64) ok( err == ERROR_SUCCESS, "RegCreateKeyA failed: %lu\n", err );
|
||||
ok( err == ERROR_SUCCESS, "RegCreateKeyA failed: %lu\n", err );
|
||||
|
||||
err = RegOpenKeyExA( root, "Wine", 0, KEY_ALL_ACCESS, &key );
|
||||
todo_wine_if(ptr_size == 64) ok( err == (ptr_size == 32 ? ERROR_FILE_NOT_FOUND : ERROR_SUCCESS),
|
||||
ok( err == (ptr_size == 32 ? ERROR_FILE_NOT_FOUND : ERROR_SUCCESS),
|
||||
"RegOpenKeyExA failed: %lu\n", err );
|
||||
if (!err) RegCloseKey( key );
|
||||
|
||||
|
@ -3014,7 +3012,7 @@ static void test_redirection(void)
|
|||
|
||||
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 );
|
||||
ok( err == ERROR_SUCCESS, "RegOpenKeyExA failed: %lu\n", err );
|
||||
|
||||
err = RegOpenKeyExA( root, "Interface",
|
||||
0, KEY_ALL_ACCESS, &key );
|
||||
|
@ -3030,10 +3028,10 @@ static void test_redirection(void)
|
|||
|
||||
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 );
|
||||
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),
|
||||
todo_wine_if(ptr_size == 64) ok( err == (ptr_size == 64 ? ERROR_FILE_NOT_FOUND : ERROR_SUCCESS),
|
||||
"RegOpenKeyExA failed: %lu\n", err );
|
||||
if (!err) RegCloseKey( key );
|
||||
|
||||
|
@ -3067,11 +3065,11 @@ static void test_redirection(void)
|
|||
|
||||
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 );
|
||||
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 );
|
||||
ok( err == ERROR_SUCCESS, "RegSetValueExA failed: %lu\n", err );
|
||||
|
||||
dw = 64;
|
||||
err = RegSetValueExA( key64, "value", 0, REG_DWORD, (BYTE *)&dw, sizeof(dw) );
|
||||
|
@ -3080,9 +3078,9 @@ static void test_redirection(void)
|
|||
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 );
|
||||
todo_check_key_value( root32, "Wine", 0, 32, ptr_size == 64 );
|
||||
todo_check_key_value( root32, "Wine", KEY_WOW64_64KEY, 32, ptr_size == 64 );
|
||||
todo_check_key_value( root32, "Wine", KEY_WOW64_32KEY, 32, ptr_size == 64 );
|
||||
|
||||
err = RegOpenKeyExA( HKEY_LOCAL_MACHINE, "Software\\Classes\\Interface",
|
||||
0, KEY_WOW64_64KEY | KEY_ALL_ACCESS, &key );
|
||||
|
@ -3094,10 +3092,10 @@ static void test_redirection(void)
|
|||
|
||||
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 );
|
||||
ok( err == ERROR_SUCCESS, "RegOpenKeyExA failed: %lu\n", err );
|
||||
todo_check_key_value( key, "Wine", 0, 32, ptr_size == 64 );
|
||||
todo_check_key_value( key, "Wine", KEY_WOW64_64KEY, 32, ptr_size == 64 );
|
||||
todo_check_key_value( key, "Wine", KEY_WOW64_32KEY, 32, ptr_size == 64 );
|
||||
RegCloseKey( key );
|
||||
|
||||
check_key_value( HKEY_LOCAL_MACHINE, "Software\\Classes\\Interface\\Wine", 0, ptr_size );
|
||||
|
@ -3107,15 +3105,15 @@ static void test_redirection(void)
|
|||
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 );
|
||||
todo_check_key_value( root64, "Wine", 0, 64, ptr_size == 64 );
|
||||
todo_check_key_value( root64, "Wine", KEY_WOW64_64KEY, 64, ptr_size == 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 );
|
||||
|
||||
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 );
|
||||
todo_wine_if(ptr_size == 64) check_key_value( HKEY_LOCAL_MACHINE, "Software\\Classes\\Interface\\Wine", 0, ptr_size == 64 ? 64 : 0 );
|
||||
todo_wine_if(ptr_size == 64) 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, "" );
|
||||
|
@ -3123,18 +3121,18 @@ static void test_redirection(void)
|
|||
|
||||
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 );
|
||||
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 );
|
||||
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 );
|
||||
todo_check_key_value( root64, "Wine", 0, 0, ptr_size == 64 );
|
||||
todo_check_key_value( root64, "Wine", KEY_WOW64_64KEY, 0, ptr_size == 64 );
|
||||
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 );
|
||||
|
||||
RegDeleteKeyA( key32, "" );
|
||||
RegCloseKey( key32 );
|
||||
|
@ -3153,7 +3151,7 @@ static void test_redirection(void)
|
|||
|
||||
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),
|
||||
todo_wine_if(ptr_size == 64) ok( err == (ptr_size == 64 ? ERROR_FILE_NOT_FOUND : ERROR_SUCCESS),
|
||||
"RegOpenKeyExA failed: %lu\n", err );
|
||||
if (!err) RegCloseKey( key );
|
||||
|
||||
|
@ -3171,7 +3169,7 @@ static void test_redirection(void)
|
|||
|
||||
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),
|
||||
todo_wine_if(ptr_size == 64) ok( err == (ptr_size == 64 ? ERROR_FILE_NOT_FOUND : ERROR_SUCCESS),
|
||||
"RegOpenKeyExA failed: %lu\n", err );
|
||||
if (!err) RegCloseKey( key );
|
||||
|
||||
|
@ -3188,7 +3186,7 @@ static void test_redirection(void)
|
|||
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 );
|
||||
ok( subkeys > 0, "wrong number of subkeys: %lu\n", subkeys );
|
||||
subkeys32 = subkeys;
|
||||
RegCloseKey( root32 );
|
||||
|
||||
|
@ -3204,23 +3202,23 @@ static void test_redirection(void)
|
|||
RegCloseKey( root64 );
|
||||
|
||||
check_enum_value( "Software\\Classes",
|
||||
KEY_WOW64_32KEY | KEY_ALL_ACCESS, subkeys64, ptr_size == 32, ptr_size == 64, FALSE );
|
||||
KEY_WOW64_32KEY | KEY_ALL_ACCESS, subkeys64, ptr_size == 32 );
|
||||
check_enum_value( "Software\\Classes",
|
||||
KEY_WOW64_64KEY | KEY_ALL_ACCESS, subkeys64, ptr_size == 32, FALSE, FALSE );
|
||||
KEY_WOW64_64KEY | KEY_ALL_ACCESS, subkeys64, ptr_size == 32 );
|
||||
check_enum_value( "Software\\Classes",
|
||||
KEY_ALL_ACCESS, subkeys64, ptr_size == 32, FALSE, FALSE );
|
||||
KEY_ALL_ACCESS, subkeys64, ptr_size == 32 );
|
||||
check_enum_value( "Software\\Classes\\Wow6432Node",
|
||||
KEY_WOW64_32KEY | KEY_ALL_ACCESS, subkeys32, ptr_size == 64, FALSE, ptr_size == 64 );
|
||||
KEY_WOW64_32KEY | KEY_ALL_ACCESS, subkeys32, ptr_size == 64 );
|
||||
check_enum_value( "Software\\Classes\\Wow6432Node",
|
||||
KEY_WOW64_64KEY | KEY_ALL_ACCESS, subkeys32, ptr_size == 64, ptr_size == 64, FALSE );
|
||||
KEY_WOW64_64KEY | KEY_ALL_ACCESS, subkeys32, ptr_size == 64 );
|
||||
check_enum_value( "Software\\Classes\\Wow6432Node",
|
||||
KEY_ALL_ACCESS, subkeys32, ptr_size == 64, ptr_size == 64, FALSE );
|
||||
KEY_ALL_ACCESS, subkeys32, ptr_size == 64 );
|
||||
check_enum_value( "Software\\Wow6432Node\\Classes",
|
||||
KEY_WOW64_32KEY | KEY_ALL_ACCESS, subkeys64, ptr_size == 32, ptr_size == 64, FALSE );
|
||||
KEY_WOW64_32KEY | KEY_ALL_ACCESS, subkeys64, ptr_size == 32 );
|
||||
check_enum_value( "Software\\Wow6432Node\\Classes",
|
||||
KEY_WOW64_64KEY | KEY_ALL_ACCESS, subkeys32, ptr_size == 64, ptr_size == 64, FALSE );
|
||||
KEY_WOW64_64KEY | KEY_ALL_ACCESS, subkeys32, ptr_size == 64 );
|
||||
check_enum_value( "Software\\Wow6432Node\\Classes",
|
||||
KEY_ALL_ACCESS, ptr_size == 32 ? subkeys64 : subkeys32, TRUE, ptr_size == 64, FALSE );
|
||||
KEY_ALL_ACCESS, ptr_size == 32 ? subkeys64 : subkeys32, TRUE );
|
||||
|
||||
RegDeleteKeyA( key32, "" );
|
||||
RegCloseKey( key32 );
|
||||
|
|
|
@ -104,11 +104,59 @@ static BOOL is_wow6432node( const UNICODE_STRING *name )
|
|||
return (len >= 11 && !wcsnicmp( name->Buffer, L"Wow6432Node\\", min( len, 12 ) ));
|
||||
}
|
||||
|
||||
/* open the Wow6432Node subkey of the specified key */
|
||||
static BOOL is_classes_root( const UNICODE_STRING *name )
|
||||
{
|
||||
static const WCHAR classes_root[] = L"\\Registry\\Machine\\Software\\Classes\\";
|
||||
DWORD classes_root_len = ARRAY_SIZE( classes_root ) - 1;
|
||||
DWORD len = name->Length / sizeof(WCHAR);
|
||||
return (len >= classes_root_len - 1 && !wcsnicmp( name->Buffer, classes_root, min( len, classes_root_len ) ));
|
||||
}
|
||||
|
||||
static BOOL is_classes_wow6432node( HKEY key )
|
||||
{
|
||||
char buffer[256], *buf_ptr = buffer;
|
||||
KEY_NAME_INFORMATION *info = (KEY_NAME_INFORMATION *)buffer;
|
||||
DWORD len = sizeof(buffer);
|
||||
UNICODE_STRING name;
|
||||
NTSTATUS status;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
/* Obtain the name of the root key */
|
||||
status = NtQueryKey( key, KeyNameInformation, info, len, &len );
|
||||
if (status && status != STATUS_BUFFER_OVERFLOW) return FALSE;
|
||||
|
||||
/* Retry with a dynamically allocated buffer */
|
||||
while (status == STATUS_BUFFER_OVERFLOW)
|
||||
{
|
||||
if (buf_ptr != buffer) heap_free( buf_ptr );
|
||||
if (!(buf_ptr = heap_alloc( len ))) return FALSE;
|
||||
info = (KEY_NAME_INFORMATION *)buf_ptr;
|
||||
status = NtQueryKey( key, KeyNameInformation, info, len, &len );
|
||||
}
|
||||
|
||||
/* Check if the key ends in Wow6432Node and if the root is the Classes key*/
|
||||
if (!status && info->NameLength / sizeof(WCHAR) >= 11)
|
||||
{
|
||||
name.Buffer = info->Name + info->NameLength / sizeof(WCHAR) - 11;
|
||||
name.Length = 11 * sizeof(WCHAR);
|
||||
if (is_wow6432node( &name ))
|
||||
{
|
||||
name.Buffer = info->Name;
|
||||
name.Length = info->NameLength;
|
||||
ret = is_classes_root( &name );
|
||||
}
|
||||
}
|
||||
|
||||
if (buf_ptr != buffer) heap_free( buf_ptr );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Open the Wow6432Node subkey of the specified key */
|
||||
static HANDLE open_wow6432node( HANDLE key )
|
||||
{
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
UNICODE_STRING nameW = RTL_CONSTANT_STRING( L"Wow6432Node" );
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
HANDLE ret;
|
||||
|
||||
attr.Length = sizeof(attr);
|
||||
|
@ -117,7 +165,25 @@ static HANDLE open_wow6432node( HANDLE key )
|
|||
attr.Attributes = 0;
|
||||
attr.SecurityDescriptor = NULL;
|
||||
attr.SecurityQualityOfService = NULL;
|
||||
if (NtOpenKeyEx( &ret, MAXIMUM_ALLOWED, &attr, 0 )) ret = 0;
|
||||
if (NtOpenKeyEx( &ret, MAXIMUM_ALLOWED, &attr, 0 )) return key;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Open HKCR, which should already exist because it's used when we're in its Wow6432Node child */
|
||||
static HANDLE open_classes_root( void )
|
||||
{
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
UNICODE_STRING nameW;
|
||||
HANDLE ret = 0;
|
||||
|
||||
attr.Length = sizeof(attr);
|
||||
attr.RootDirectory = 0;
|
||||
attr.ObjectName = &nameW;
|
||||
attr.Attributes = 0;
|
||||
attr.SecurityDescriptor = NULL;
|
||||
attr.SecurityQualityOfService = NULL;
|
||||
RtlInitUnicodeString( &nameW, root_key_names[0] );
|
||||
NtOpenKeyEx( &ret, MAXIMUM_ALLOWED, &attr, 0 );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -162,6 +228,21 @@ static NTSTATUS open_subkey( HKEY *subkey, HKEY root, UNICODE_STRING *name, DWOR
|
|||
options &= ~REG_OPTION_OPEN_LINK;
|
||||
|
||||
status = open_key( subkey, root, &str, options, access_64, FALSE );
|
||||
if (status == STATUS_OBJECT_NAME_NOT_FOUND && root && is_wow64_key)
|
||||
{
|
||||
/* Try to open the shared parent if we can't find the key in the Wow6432Node */
|
||||
if (!is_classes_wow6432node( root ))
|
||||
return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
|
||||
root = open_classes_root();
|
||||
status = open_key( subkey, root, &str, options, access_64, FALSE );
|
||||
|
||||
if (!status)
|
||||
NtClose( root );
|
||||
else
|
||||
*subkey = root;
|
||||
}
|
||||
|
||||
if (!status)
|
||||
{
|
||||
while (i < len && buffer[i] == '\\') i++;
|
||||
|
@ -172,7 +253,7 @@ static NTSTATUS open_subkey( HKEY *subkey, HKEY root, UNICODE_STRING *name, DWOR
|
|||
if (is_wow64_key && !is_wow6432node( name ))
|
||||
{
|
||||
HKEY wow6432node = open_wow6432node( *subkey );
|
||||
if (wow6432node)
|
||||
if (wow6432node != *subkey)
|
||||
{
|
||||
NtClose( *subkey );
|
||||
*subkey = wow6432node;
|
||||
|
@ -186,8 +267,10 @@ 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, BOOL create )
|
||||
{
|
||||
BOOL is_wow64_key = (is_win64 && (access & KEY_WOW64_32KEY)) || (is_wow64 && !(access & KEY_WOW64_64KEY));
|
||||
HKEY subkey = 0, subkey_root = root;
|
||||
NTSTATUS status = 0;
|
||||
NTSTATUS status = STATUS_SUCCESS;
|
||||
BOOL was_wow6432node = TRUE;
|
||||
|
||||
*retkey = NULL;
|
||||
|
||||
|
@ -212,13 +295,31 @@ static NTSTATUS open_key( HKEY *retkey, HKEY root, UNICODE_STRING *name, DWORD o
|
|||
return status;
|
||||
}
|
||||
|
||||
if (root && is_wow64 && !(access & KEY_WOW64_64KEY) && !is_wow6432node( name ))
|
||||
{
|
||||
subkey_root = open_wow6432node( root );
|
||||
if (!is_classes_wow6432node( subkey_root ) && subkey_root != root)
|
||||
{
|
||||
NtClose( subkey_root );
|
||||
subkey_root = root;
|
||||
}
|
||||
}
|
||||
|
||||
while (!status && (name->Length || !subkey))
|
||||
{
|
||||
was_wow6432node = is_wow6432node( name );
|
||||
status = open_subkey( &subkey, subkey_root, name, options, access );
|
||||
if (subkey && subkey_root && subkey_root != root) NtClose( subkey_root );
|
||||
if (subkey) subkey_root = subkey;
|
||||
}
|
||||
|
||||
/* Return the shared parent if we didn't explicitly look for the Wow6432Node */
|
||||
if (!status && !was_wow6432node && is_wow64_key && is_classes_wow6432node( subkey_root ))
|
||||
{
|
||||
if (subkey_root && subkey_root != root) NtClose( subkey_root );
|
||||
subkey_root = open_classes_root();
|
||||
}
|
||||
|
||||
if (!status || (status == STATUS_OBJECT_NAME_NOT_FOUND && create))
|
||||
*retkey = subkey_root;
|
||||
else if (subkey_root && subkey_root != root)
|
||||
|
|
Loading…
Reference in a new issue