|
|
|
@@ -24,6 +24,7 @@
|
|
|
|
|
#include "wine/test.h"
|
|
|
|
|
#include "windef.h"
|
|
|
|
|
#include "winbase.h"
|
|
|
|
|
#include "winternl.h"
|
|
|
|
|
#include "winreg.h"
|
|
|
|
|
#include "winsvc.h"
|
|
|
|
|
#include "winerror.h"
|
|
|
|
@@ -34,10 +35,13 @@ static DWORD GLE;
|
|
|
|
|
static const char * sTestpath1 = "%LONGSYSTEMVAR%\\subdir1";
|
|
|
|
|
static const char * sTestpath2 = "%FOO%\\subdir1";
|
|
|
|
|
|
|
|
|
|
static HMODULE hadvapi32;
|
|
|
|
|
static DWORD (WINAPI *pRegGetValueA)(HKEY,LPCSTR,LPCSTR,DWORD,LPDWORD,PVOID,LPDWORD);
|
|
|
|
|
static DWORD (WINAPI *pRegDeleteTreeA)(HKEY,LPCSTR);
|
|
|
|
|
|
|
|
|
|
static DWORD (WINAPI *pRegDeleteKeyExA)(HKEY,LPCSTR,REGSAM,DWORD);
|
|
|
|
|
static BOOL (WINAPI *pIsWow64Process)(HANDLE,PBOOL);
|
|
|
|
|
static NTSTATUS (WINAPI * pNtDeleteKey)(HANDLE);
|
|
|
|
|
static NTSTATUS (WINAPI * pRtlFormatCurrentUserKeyPath)(UNICODE_STRING*);
|
|
|
|
|
static NTSTATUS (WINAPI * pRtlFreeUnicodeString)(PUNICODE_STRING);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Debugging functions from wine/libs/wine/debug.c */
|
|
|
|
@@ -112,16 +116,23 @@ static const char *wine_debugstr_an( const char *str, int n )
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#define ADVAPI32_GET_PROC(func) \
|
|
|
|
|
p ## func = (void*)GetProcAddress(hadvapi32, #func);
|
|
|
|
|
|
|
|
|
|
p ## func = (void*)GetProcAddress(hadvapi32, #func)
|
|
|
|
|
|
|
|
|
|
static void InitFunctionPtrs(void)
|
|
|
|
|
{
|
|
|
|
|
hadvapi32 = GetModuleHandleA("advapi32.dll");
|
|
|
|
|
HMODULE hntdll = GetModuleHandleA("ntdll.dll");
|
|
|
|
|
HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
|
|
|
|
|
HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
|
|
|
|
|
|
|
|
|
|
/* This function was introduced with Windows 2003 SP1 */
|
|
|
|
|
ADVAPI32_GET_PROC(RegGetValueA)
|
|
|
|
|
ADVAPI32_GET_PROC(RegDeleteTreeA)
|
|
|
|
|
ADVAPI32_GET_PROC(RegGetValueA);
|
|
|
|
|
ADVAPI32_GET_PROC(RegDeleteTreeA);
|
|
|
|
|
ADVAPI32_GET_PROC(RegDeleteKeyExA);
|
|
|
|
|
|
|
|
|
|
pIsWow64Process = (void *)GetProcAddress( hkernel32, "IsWow64Process" );
|
|
|
|
|
pRtlFormatCurrentUserKeyPath = (void *)GetProcAddress( hntdll, "RtlFormatCurrentUserKeyPath" );
|
|
|
|
|
pRtlFreeUnicodeString = (void *)GetProcAddress(hntdll, "RtlFreeUnicodeString");
|
|
|
|
|
pNtDeleteKey = (void *)GetProcAddress( hntdll, "NtDeleteKey" );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* delete key and all its subkeys */
|
|
|
|
@@ -916,9 +927,11 @@ static void test_reg_open_key(void)
|
|
|
|
|
|
|
|
|
|
/* beginning backslash character */
|
|
|
|
|
ret = RegOpenKeyA(HKEY_CURRENT_USER, "\\Software\\Wine\\Test", &hkResult);
|
|
|
|
|
ok(ret == ERROR_BAD_PATHNAME || /* NT/2k/XP */
|
|
|
|
|
ret == ERROR_FILE_NOT_FOUND /* Win9x,ME */
|
|
|
|
|
, "expected ERROR_BAD_PATHNAME or ERROR_FILE_NOT_FOUND, got %d\n", ret);
|
|
|
|
|
ok(ret == ERROR_BAD_PATHNAME || /* NT/2k/XP */
|
|
|
|
|
ret == ERROR_FILE_NOT_FOUND || /* Win9x,ME */
|
|
|
|
|
broken(ret == ERROR_SUCCESS), /* wow64 */
|
|
|
|
|
"expected ERROR_BAD_PATHNAME or ERROR_FILE_NOT_FOUND, got %d\n", ret);
|
|
|
|
|
if (!ret) RegCloseKey(hkResult);
|
|
|
|
|
|
|
|
|
|
hkResult = NULL;
|
|
|
|
|
ret = RegOpenKeyExA(HKEY_CLASSES_ROOT, "\\clsid", 0, KEY_QUERY_VALUE, &hkResult);
|
|
|
|
@@ -1503,6 +1516,400 @@ static void test_rw_order(void)
|
|
|
|
|
ok(!RegDeleteKey(HKEY_CURRENT_USER, keyname), "Failed to delete key\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void test_symlinks(void)
|
|
|
|
|
{
|
|
|
|
|
static const WCHAR targetW[] = {'\\','S','o','f','t','w','a','r','e','\\','W','i','n','e',
|
|
|
|
|
'\\','T','e','s','t','\\','t','a','r','g','e','t',0};
|
|
|
|
|
BYTE buffer[1024];
|
|
|
|
|
UNICODE_STRING target_str;
|
|
|
|
|
WCHAR *target;
|
|
|
|
|
HKEY key, link;
|
|
|
|
|
NTSTATUS status;
|
|
|
|
|
DWORD target_len, type, len, dw, err;
|
|
|
|
|
|
|
|
|
|
if (!pRtlFormatCurrentUserKeyPath || !pNtDeleteKey)
|
|
|
|
|
{
|
|
|
|
|
win_skip( "Can't perform symlink tests\n" );
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pRtlFormatCurrentUserKeyPath( &target_str );
|
|
|
|
|
|
|
|
|
|
target_len = target_str.Length + sizeof(targetW);
|
|
|
|
|
target = HeapAlloc( GetProcessHeap(), 0, target_len );
|
|
|
|
|
memcpy( target, target_str.Buffer, target_str.Length );
|
|
|
|
|
memcpy( target + target_str.Length/sizeof(WCHAR), targetW, sizeof(targetW) );
|
|
|
|
|
|
|
|
|
|
err = RegCreateKeyExA( hkey_main, "link", 0, NULL, REG_OPTION_CREATE_LINK,
|
|
|
|
|
KEY_ALL_ACCESS, NULL, &link, NULL );
|
|
|
|
|
ok( err == ERROR_SUCCESS, "RegCreateKeyEx failed: %u\n", err );
|
|
|
|
|
|
|
|
|
|
/* REG_SZ is not allowed */
|
|
|
|
|
err = RegSetValueExA( link, "SymbolicLinkValue", 0, REG_SZ, (BYTE *)"foobar", sizeof("foobar") );
|
|
|
|
|
ok( err == ERROR_ACCESS_DENIED, "RegSetValueEx wrong error %u\n", err );
|
|
|
|
|
err = RegSetValueExA( link, "SymbolicLinkValue", 0, REG_LINK,
|
|
|
|
|
(BYTE *)target, target_len - sizeof(WCHAR) );
|
|
|
|
|
ok( err == ERROR_SUCCESS, "RegSetValueEx failed error %u\n", err );
|
|
|
|
|
/* other values are not allowed */
|
|
|
|
|
err = RegSetValueExA( link, "link", 0, REG_LINK, (BYTE *)target, target_len - sizeof(WCHAR) );
|
|
|
|
|
ok( err == ERROR_ACCESS_DENIED, "RegSetValueEx wrong error %u\n", err );
|
|
|
|
|
|
|
|
|
|
/* try opening the target through the link */
|
|
|
|
|
|
|
|
|
|
err = RegOpenKeyA( hkey_main, "link", &key );
|
|
|
|
|
ok( err == ERROR_FILE_NOT_FOUND, "RegOpenKey wrong error %u\n", err );
|
|
|
|
|
|
|
|
|
|
err = RegCreateKeyExA( hkey_main, "target", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &key, NULL );
|
|
|
|
|
ok( err == ERROR_SUCCESS, "RegCreateKeyEx failed error %u\n", err );
|
|
|
|
|
|
|
|
|
|
dw = 0xbeef;
|
|
|
|
|
err = RegSetValueExA( key, "value", 0, REG_DWORD, (BYTE *)&dw, sizeof(dw) );
|
|
|
|
|
ok( err == ERROR_SUCCESS, "RegSetValueEx failed error %u\n", err );
|
|
|
|
|
RegCloseKey( key );
|
|
|
|
|
|
|
|
|
|
err = RegOpenKeyA( hkey_main, "link", &key );
|
|
|
|
|
ok( err == ERROR_SUCCESS, "RegOpenKey failed error %u\n", err );
|
|
|
|
|
|
|
|
|
|
len = sizeof(buffer);
|
|
|
|
|
err = RegQueryValueExA( key, "value", NULL, &type, buffer, &len );
|
|
|
|
|
ok( err == ERROR_SUCCESS, "RegOpenKey failed error %u\n", err );
|
|
|
|
|
ok( len == sizeof(DWORD), "wrong len %u\n", len );
|
|
|
|
|
|
|
|
|
|
len = sizeof(buffer);
|
|
|
|
|
err = RegQueryValueExA( key, "SymbolicLinkValue", NULL, &type, buffer, &len );
|
|
|
|
|
ok( err == ERROR_FILE_NOT_FOUND, "RegQueryValueEx wrong error %u\n", err );
|
|
|
|
|
|
|
|
|
|
/* REG_LINK can be created in non-link keys */
|
|
|
|
|
err = RegSetValueExA( key, "SymbolicLinkValue", 0, REG_LINK,
|
|
|
|
|
(BYTE *)target, target_len - sizeof(WCHAR) );
|
|
|
|
|
ok( err == ERROR_SUCCESS, "RegSetValueEx failed error %u\n", err );
|
|
|
|
|
len = sizeof(buffer);
|
|
|
|
|
err = RegQueryValueExA( key, "SymbolicLinkValue", NULL, &type, buffer, &len );
|
|
|
|
|
ok( err == ERROR_SUCCESS, "RegQueryValueEx failed error %u\n", err );
|
|
|
|
|
ok( len == target_len - sizeof(WCHAR), "wrong len %u\n", len );
|
|
|
|
|
err = RegDeleteValueA( key, "SymbolicLinkValue" );
|
|
|
|
|
ok( err == ERROR_SUCCESS, "RegDeleteValue failed error %u\n", err );
|
|
|
|
|
|
|
|
|
|
RegCloseKey( key );
|
|
|
|
|
|
|
|
|
|
err = RegCreateKeyExA( hkey_main, "link", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &key, NULL );
|
|
|
|
|
ok( err == ERROR_SUCCESS, "RegCreateKeyEx failed error %u\n", err );
|
|
|
|
|
|
|
|
|
|
len = sizeof(buffer);
|
|
|
|
|
err = RegQueryValueExA( key, "value", NULL, &type, buffer, &len );
|
|
|
|
|
ok( err == ERROR_SUCCESS, "RegQueryValueEx failed error %u\n", err );
|
|
|
|
|
ok( len == sizeof(DWORD), "wrong len %u\n", len );
|
|
|
|
|
|
|
|
|
|
err = RegQueryValueExA( key, "SymbolicLinkValue", NULL, &type, buffer, &len );
|
|
|
|
|
ok( err == ERROR_FILE_NOT_FOUND, "RegQueryValueEx wrong error %u\n", err );
|
|
|
|
|
RegCloseKey( key );
|
|
|
|
|
|
|
|
|
|
/* now open the symlink itself */
|
|
|
|
|
|
|
|
|
|
err = RegOpenKeyExA( hkey_main, "link", REG_OPTION_OPEN_LINK, KEY_ALL_ACCESS, &key );
|
|
|
|
|
ok( err == ERROR_SUCCESS, "RegOpenKeyEx failed error %u\n", err );
|
|
|
|
|
len = sizeof(buffer);
|
|
|
|
|
err = RegQueryValueExA( key, "SymbolicLinkValue", NULL, &type, buffer, &len );
|
|
|
|
|
ok( err == ERROR_SUCCESS, "RegQueryValueEx failed error %u\n", err );
|
|
|
|
|
ok( len == target_len - sizeof(WCHAR), "wrong len %u\n", len );
|
|
|
|
|
RegCloseKey( key );
|
|
|
|
|
|
|
|
|
|
err = RegCreateKeyExA( hkey_main, "link", 0, NULL, REG_OPTION_OPEN_LINK,
|
|
|
|
|
KEY_ALL_ACCESS, NULL, &key, NULL );
|
|
|
|
|
ok( err == ERROR_SUCCESS, "RegCreateKeyEx failed error %u\n", err );
|
|
|
|
|
len = sizeof(buffer);
|
|
|
|
|
err = RegQueryValueExA( key, "SymbolicLinkValue", NULL, &type, buffer, &len );
|
|
|
|
|
ok( err == ERROR_SUCCESS, "RegQueryValueEx failed error %u\n", err );
|
|
|
|
|
ok( len == target_len - sizeof(WCHAR), "wrong len %u\n", len );
|
|
|
|
|
RegCloseKey( key );
|
|
|
|
|
|
|
|
|
|
err = RegCreateKeyExA( hkey_main, "link", 0, NULL, REG_OPTION_CREATE_LINK,
|
|
|
|
|
KEY_ALL_ACCESS, NULL, &key, NULL );
|
|
|
|
|
ok( err == ERROR_ALREADY_EXISTS, "RegCreateKeyEx wrong error %u\n", err );
|
|
|
|
|
|
|
|
|
|
err = RegCreateKeyExA( hkey_main, "link", 0, NULL, REG_OPTION_CREATE_LINK | REG_OPTION_OPEN_LINK,
|
|
|
|
|
KEY_ALL_ACCESS, NULL, &key, NULL );
|
|
|
|
|
ok( err == ERROR_ALREADY_EXISTS, "RegCreateKeyEx wrong error %u\n", err );
|
|
|
|
|
|
|
|
|
|
err = RegDeleteKey( hkey_main, "target" );
|
|
|
|
|
ok( err == ERROR_SUCCESS, "RegDeleteKey failed error %u\n", err );
|
|
|
|
|
|
|
|
|
|
err = RegDeleteKey( hkey_main, "link" );
|
|
|
|
|
ok( err == ERROR_FILE_NOT_FOUND, "RegDeleteKey wrong error %u\n", err );
|
|
|
|
|
|
|
|
|
|
status = pNtDeleteKey( link );
|
|
|
|
|
ok( !status, "NtDeleteKey failed: 0x%08x\n", status );
|
|
|
|
|
RegCloseKey( link );
|
|
|
|
|
|
|
|
|
|
HeapFree( GetProcessHeap(), 0, target );
|
|
|
|
|
pRtlFreeUnicodeString( &target_str );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static const DWORD ptr_size = 8 * sizeof(void*);
|
|
|
|
|
|
|
|
|
|
static DWORD get_key_value( HKEY root, const char *name, DWORD flags )
|
|
|
|
|
{
|
|
|
|
|
HKEY key;
|
|
|
|
|
DWORD err, type, dw, len = sizeof(dw);
|
|
|
|
|
|
|
|
|
|
err = RegCreateKeyExA( root, name, 0, NULL, 0, flags | KEY_ALL_ACCESS, NULL, &key, NULL );
|
|
|
|
|
if (err == ERROR_FILE_NOT_FOUND) return 0;
|
|
|
|
|
ok( err == ERROR_SUCCESS, "%08x: RegCreateKeyEx failed: %u\n", flags, err );
|
|
|
|
|
|
|
|
|
|
err = RegQueryValueExA( key, "value", NULL, &type, (BYTE *)&dw, &len );
|
|
|
|
|
if (err == ERROR_FILE_NOT_FOUND)
|
|
|
|
|
dw = 0;
|
|
|
|
|
else
|
|
|
|
|
ok( err == ERROR_SUCCESS, "%08x: RegQueryValueEx failed: %u\n", flags, err );
|
|
|
|
|
RegCloseKey( key );
|
|
|
|
|
return dw;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void _check_key_value( int line, HANDLE root, const char *name, DWORD flags, DWORD expect )
|
|
|
|
|
{
|
|
|
|
|
DWORD dw = get_key_value( root, name, flags );
|
|
|
|
|
ok_(__FILE__,line)( dw == expect, "%08x: wrong value %u/%u\n", flags, dw, expect );
|
|
|
|
|
}
|
|
|
|
|
#define check_key_value(root,name,flags,expect) _check_key_value( __LINE__, root, name, flags, expect )
|
|
|
|
|
|
|
|
|
|
static void test_redirection(void)
|
|
|
|
|
{
|
|
|
|
|
DWORD err, type, dw, len;
|
|
|
|
|
HKEY key, root32, root64, key32, key64;
|
|
|
|
|
BOOL is_vista = FALSE;
|
|
|
|
|
|
|
|
|
|
if (ptr_size != 64)
|
|
|
|
|
{
|
|
|
|
|
BOOL is_wow64;
|
|
|
|
|
if (!pIsWow64Process || !pIsWow64Process( GetCurrentProcess(), &is_wow64 ) || !is_wow64)
|
|
|
|
|
{
|
|
|
|
|
skip( "Not on Wow64, no redirection\n" );
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err = RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software\\Wine", 0, NULL, 0,
|
|
|
|
|
KEY_WOW64_64KEY | KEY_ALL_ACCESS, NULL, &root64, NULL );
|
|
|
|
|
ok( err == ERROR_SUCCESS, "RegCreateKeyExA failed: %u\n", err );
|
|
|
|
|
|
|
|
|
|
err = RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software\\Wine", 0, NULL, 0,
|
|
|
|
|
KEY_WOW64_32KEY | KEY_ALL_ACCESS, NULL, &root32, NULL );
|
|
|
|
|
ok( err == ERROR_SUCCESS, "RegCreateKeyExA failed: %u\n", err );
|
|
|
|
|
|
|
|
|
|
err = RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software\\Wine\\Winetest", 0, NULL, 0,
|
|
|
|
|
KEY_WOW64_64KEY | KEY_ALL_ACCESS, NULL, &key64, NULL );
|
|
|
|
|
ok( err == ERROR_SUCCESS, "RegCreateKeyExA failed: %u\n", err );
|
|
|
|
|
|
|
|
|
|
err = RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software\\Wine\\Winetest", 0, NULL, 0,
|
|
|
|
|
KEY_WOW64_32KEY | KEY_ALL_ACCESS, NULL, &key32, NULL );
|
|
|
|
|
ok( err == ERROR_SUCCESS, "RegCreateKeyExA failed: %u\n", err );
|
|
|
|
|
|
|
|
|
|
dw = 64;
|
|
|
|
|
err = RegSetValueExA( key64, "value", 0, REG_DWORD, (BYTE *)&dw, sizeof(dw) );
|
|
|
|
|
ok( err == ERROR_SUCCESS, "RegSetValueExA failed: %u\n", err );
|
|
|
|
|
|
|
|
|
|
dw = 32;
|
|
|
|
|
err = RegSetValueExA( key32, "value", 0, REG_DWORD, (BYTE *)&dw, sizeof(dw) );
|
|
|
|
|
ok( err == ERROR_SUCCESS, "RegSetValueExA failed: %u\n", err );
|
|
|
|
|
|
|
|
|
|
dw = 0;
|
|
|
|
|
len = sizeof(dw);
|
|
|
|
|
err = RegQueryValueExA( key32, "value", NULL, &type, (BYTE *)&dw, &len );
|
|
|
|
|
ok( err == ERROR_SUCCESS, "RegQueryValueExA failed: %u\n", err );
|
|
|
|
|
ok( dw == 32, "wrong value %u\n", dw );
|
|
|
|
|
|
|
|
|
|
dw = 0;
|
|
|
|
|
len = sizeof(dw);
|
|
|
|
|
err = RegQueryValueExA( key64, "value", NULL, &type, (BYTE *)&dw, &len );
|
|
|
|
|
ok( err == ERROR_SUCCESS, "RegQueryValueExA failed: %u\n", err );
|
|
|
|
|
ok( dw == 64, "wrong value %u\n", dw );
|
|
|
|
|
|
|
|
|
|
err = RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software", 0, NULL, 0,
|
|
|
|
|
KEY_ALL_ACCESS, NULL, &key, NULL );
|
|
|
|
|
ok( err == ERROR_SUCCESS, "RegCreateKeyExA failed: %u\n", err );
|
|
|
|
|
|
|
|
|
|
if (ptr_size == 32)
|
|
|
|
|
{
|
|
|
|
|
/* the Vista mechanism allows opening Wow6432Node from a 32-bit key too */
|
|
|
|
|
/* the new (and simpler) Win7 mechanism doesn't */
|
|
|
|
|
if (get_key_value( key, "Wow6432Node\\Wine\\Winetest", 0 ) == 32)
|
|
|
|
|
{
|
|
|
|
|
trace( "using Vista-style Wow6432Node handling\n" );
|
|
|
|
|
is_vista = TRUE;
|
|
|
|
|
}
|
|
|
|
|
check_key_value( key, "Wine\\Winetest", 0, 32 );
|
|
|
|
|
check_key_value( key, "Wine\\Winetest", KEY_WOW64_64KEY, is_vista ? 64 : 32 );
|
|
|
|
|
check_key_value( key, "Wine\\Winetest", KEY_WOW64_32KEY, 32 );
|
|
|
|
|
check_key_value( key, "Wow6432Node\\Wine\\Winetest", 0, is_vista ? 32 : 0 );
|
|
|
|
|
check_key_value( key, "Wow6432Node\\Wine\\Winetest", KEY_WOW64_64KEY, is_vista ? 64 : 0 );
|
|
|
|
|
check_key_value( key, "Wow6432Node\\Wine\\Winetest", KEY_WOW64_32KEY, is_vista ? 32 : 0 );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (get_key_value( HKEY_LOCAL_MACHINE, "Software\\Wow6432Node\\Wine\\Winetest", KEY_WOW64_64KEY ) == 64)
|
|
|
|
|
{
|
|
|
|
|
trace( "using Vista-style Wow6432Node handling\n" );
|
|
|
|
|
is_vista = TRUE;
|
|
|
|
|
}
|
|
|
|
|
check_key_value( key, "Wine\\Winetest", 0, 64 );
|
|
|
|
|
check_key_value( key, "Wow6432Node\\Wine\\Winetest", 0, 32 );
|
|
|
|
|
}
|
|
|
|
|
RegCloseKey( key );
|
|
|
|
|
|
|
|
|
|
if (ptr_size == 32)
|
|
|
|
|
{
|
|
|
|
|
err = RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software", 0, NULL, 0,
|
|
|
|
|
KEY_WOW64_64KEY | KEY_ALL_ACCESS, NULL, &key, NULL );
|
|
|
|
|
ok( err == ERROR_SUCCESS, "RegCreateKeyExA failed: %u\n", err );
|
|
|
|
|
dw = get_key_value( key, "Wine\\Winetest", 0 );
|
|
|
|
|
ok( dw == 64 || broken(dw == 32) /* xp64 */, "wrong value %u\n", dw );
|
|
|
|
|
check_key_value( key, "Wine\\Winetest", KEY_WOW64_64KEY, 64 );
|
|
|
|
|
check_key_value( key, "Wine\\Winetest", KEY_WOW64_32KEY, 32 );
|
|
|
|
|
check_key_value( key, "Wow6432Node\\Wine\\Winetest", 0, 32 );
|
|
|
|
|
dw = get_key_value( key, "Wow6432Node\\Wine\\Winetest", KEY_WOW64_64KEY );
|
|
|
|
|
ok( dw == 32 || broken(dw == 64) /* xp64 */, "wrong value %u\n", dw );
|
|
|
|
|
check_key_value( key, "Wow6432Node\\Wine\\Winetest", KEY_WOW64_32KEY, 32 );
|
|
|
|
|
RegCloseKey( key );
|
|
|
|
|
|
|
|
|
|
err = RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software", 0, NULL, 0,
|
|
|
|
|
KEY_WOW64_32KEY | KEY_ALL_ACCESS, NULL, &key, NULL );
|
|
|
|
|
ok( err == ERROR_SUCCESS, "RegCreateKeyExA failed: %u\n", err );
|
|
|
|
|
check_key_value( key, "Wine\\Winetest", 0, 32 );
|
|
|
|
|
check_key_value( key, "Wine\\Winetest", KEY_WOW64_64KEY, is_vista ? 64 : 32 );
|
|
|
|
|
check_key_value( key, "Wine\\Winetest", KEY_WOW64_32KEY, 32 );
|
|
|
|
|
check_key_value( key, "Wow6432Node\\Wine\\Winetest", 0, is_vista ? 32 : 0 );
|
|
|
|
|
check_key_value( key, "Wow6432Node\\Wine\\Winetest", KEY_WOW64_64KEY, is_vista ? 64 : 0 );
|
|
|
|
|
check_key_value( key, "Wow6432Node\\Wine\\Winetest", KEY_WOW64_32KEY, is_vista ? 32 : 0 );
|
|
|
|
|
RegCloseKey( key );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
check_key_value( HKEY_LOCAL_MACHINE, "Software\\Wine\\Winetest", 0, ptr_size );
|
|
|
|
|
check_key_value( HKEY_LOCAL_MACHINE, "Software\\Wow6432Node\\Wine\\Winetest", 0, 32 );
|
|
|
|
|
if (ptr_size == 64)
|
|
|
|
|
{
|
|
|
|
|
/* KEY_WOW64 flags have no effect on 64-bit */
|
|
|
|
|
check_key_value( HKEY_LOCAL_MACHINE, "Software\\Wine\\Winetest", KEY_WOW64_64KEY, 64 );
|
|
|
|
|
check_key_value( HKEY_LOCAL_MACHINE, "Software\\Wine\\Winetest", KEY_WOW64_32KEY, 32 );
|
|
|
|
|
check_key_value( HKEY_LOCAL_MACHINE, "Software\\Wow6432Node\\Wine\\Winetest", KEY_WOW64_64KEY, is_vista ? 64 : 32 );
|
|
|
|
|
check_key_value( HKEY_LOCAL_MACHINE, "Software\\Wow6432Node\\Wine\\Winetest", KEY_WOW64_32KEY, 32 );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
check_key_value( HKEY_LOCAL_MACHINE, "Software\\Wine\\Winetest", KEY_WOW64_64KEY, 64 );
|
|
|
|
|
check_key_value( HKEY_LOCAL_MACHINE, "Software\\Wine\\Winetest", KEY_WOW64_32KEY, 32 );
|
|
|
|
|
check_key_value( HKEY_LOCAL_MACHINE, "Software\\Wow6432Node\\Wine\\Winetest", KEY_WOW64_64KEY, is_vista ? 64 : 32 );
|
|
|
|
|
check_key_value( HKEY_LOCAL_MACHINE, "Software\\Wow6432Node\\Wine\\Winetest", KEY_WOW64_32KEY, 32 );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err = RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software\\Wow6432Node", 0, NULL, 0,
|
|
|
|
|
KEY_ALL_ACCESS, NULL, &key, NULL );
|
|
|
|
|
ok( err == ERROR_SUCCESS, "RegCreateKeyExA failed: %u\n", err );
|
|
|
|
|
check_key_value( key, "Wine\\Winetest", 0, 32 );
|
|
|
|
|
check_key_value( key, "Wine\\Winetest", KEY_WOW64_64KEY, is_vista ? 64 : 32 );
|
|
|
|
|
check_key_value( key, "Wine\\Winetest", KEY_WOW64_32KEY, 32 );
|
|
|
|
|
RegCloseKey( key );
|
|
|
|
|
|
|
|
|
|
if (ptr_size == 32)
|
|
|
|
|
{
|
|
|
|
|
err = RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software\\Wow6432Node", 0, NULL, 0,
|
|
|
|
|
KEY_WOW64_64KEY | KEY_ALL_ACCESS, NULL, &key, NULL );
|
|
|
|
|
ok( err == ERROR_SUCCESS, "RegCreateKeyExA failed: %u\n", err );
|
|
|
|
|
dw = get_key_value( key, "Wine\\Winetest", 0 );
|
|
|
|
|
ok( dw == (is_vista ? 64 : 32) || broken(dw == 32) /* xp64 */, "wrong value %u\n", dw );
|
|
|
|
|
check_key_value( key, "Wine\\Winetest", KEY_WOW64_64KEY, is_vista ? 64 : 32 );
|
|
|
|
|
check_key_value( key, "Wine\\Winetest", KEY_WOW64_32KEY, 32 );
|
|
|
|
|
RegCloseKey( key );
|
|
|
|
|
|
|
|
|
|
err = RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software\\Wow6432Node", 0, NULL, 0,
|
|
|
|
|
KEY_WOW64_32KEY | KEY_ALL_ACCESS, NULL, &key, NULL );
|
|
|
|
|
ok( err == ERROR_SUCCESS, "RegCreateKeyExA failed: %u\n", err );
|
|
|
|
|
check_key_value( key, "Wine\\Winetest", 0, 32 );
|
|
|
|
|
check_key_value( key, "Wine\\Winetest", KEY_WOW64_64KEY, is_vista ? 64 : 32 );
|
|
|
|
|
check_key_value( key, "Wine\\Winetest", KEY_WOW64_32KEY, 32 );
|
|
|
|
|
RegCloseKey( key );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err = RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software\\Wow6432Node\\Wine", 0, NULL, 0,
|
|
|
|
|
KEY_ALL_ACCESS, NULL, &key, NULL );
|
|
|
|
|
ok( err == ERROR_SUCCESS, "RegCreateKeyExA failed: %u\n", err );
|
|
|
|
|
check_key_value( key, "Winetest", 0, 32 );
|
|
|
|
|
check_key_value( key, "Winetest", KEY_WOW64_64KEY, is_vista ? 64 : 32 );
|
|
|
|
|
check_key_value( key, "Winetest", KEY_WOW64_32KEY, 32 );
|
|
|
|
|
RegCloseKey( key );
|
|
|
|
|
|
|
|
|
|
if (ptr_size == 32)
|
|
|
|
|
{
|
|
|
|
|
err = RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software\\Wow6432Node\\Wine", 0, NULL, 0,
|
|
|
|
|
KEY_WOW64_64KEY | KEY_ALL_ACCESS, NULL, &key, NULL );
|
|
|
|
|
ok( err == ERROR_SUCCESS, "RegCreateKeyExA failed: %u\n", err );
|
|
|
|
|
dw = get_key_value( key, "Winetest", 0 );
|
|
|
|
|
ok( dw == 32 || (is_vista && dw == 64), "wrong value %u\n", dw );
|
|
|
|
|
check_key_value( key, "Winetest", KEY_WOW64_64KEY, is_vista ? 64 : 32 );
|
|
|
|
|
check_key_value( key, "Winetest", KEY_WOW64_32KEY, 32 );
|
|
|
|
|
RegCloseKey( key );
|
|
|
|
|
|
|
|
|
|
err = RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software\\Wow6432Node\\Wine", 0, NULL, 0,
|
|
|
|
|
KEY_WOW64_32KEY | KEY_ALL_ACCESS, NULL, &key, NULL );
|
|
|
|
|
ok( err == ERROR_SUCCESS, "RegCreateKeyExA failed: %u\n", err );
|
|
|
|
|
check_key_value( key, "Winetest", 0, 32 );
|
|
|
|
|
check_key_value( key, "Winetest", KEY_WOW64_64KEY, is_vista ? 64 : 32 );
|
|
|
|
|
check_key_value( key, "Winetest", KEY_WOW64_32KEY, 32 );
|
|
|
|
|
RegCloseKey( key );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err = RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software\\Wine", 0, NULL, 0,
|
|
|
|
|
KEY_ALL_ACCESS, NULL, &key, NULL );
|
|
|
|
|
ok( err == ERROR_SUCCESS, "RegCreateKeyExA failed: %u\n", err );
|
|
|
|
|
check_key_value( key, "Winetest", 0, ptr_size );
|
|
|
|
|
check_key_value( key, "Winetest", KEY_WOW64_64KEY, is_vista ? 64 : ptr_size );
|
|
|
|
|
check_key_value( key, "Winetest", KEY_WOW64_32KEY, 32 );
|
|
|
|
|
RegCloseKey( key );
|
|
|
|
|
|
|
|
|
|
if (ptr_size == 32)
|
|
|
|
|
{
|
|
|
|
|
err = RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software\\Wine", 0, NULL, 0,
|
|
|
|
|
KEY_WOW64_64KEY | KEY_ALL_ACCESS, NULL, &key, NULL );
|
|
|
|
|
ok( err == ERROR_SUCCESS, "RegCreateKeyExA failed: %u\n", err );
|
|
|
|
|
dw = get_key_value( key, "Winetest", 0 );
|
|
|
|
|
ok( dw == 64 || broken(dw == 32) /* xp64 */, "wrong value %u\n", dw );
|
|
|
|
|
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 %u\n", dw );
|
|
|
|
|
RegCloseKey( key );
|
|
|
|
|
|
|
|
|
|
err = RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software\\Wine", 0, NULL, 0,
|
|
|
|
|
KEY_WOW64_32KEY | KEY_ALL_ACCESS, NULL, &key, NULL );
|
|
|
|
|
ok( err == ERROR_SUCCESS, "RegCreateKeyExA failed: %u\n", err );
|
|
|
|
|
check_key_value( key, "Winetest", 0, 32 );
|
|
|
|
|
check_key_value( key, "Winetest", KEY_WOW64_64KEY, is_vista ? 64 : 32 );
|
|
|
|
|
check_key_value( key, "Winetest", KEY_WOW64_32KEY, 32 );
|
|
|
|
|
RegCloseKey( key );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pRegDeleteKeyExA)
|
|
|
|
|
{
|
|
|
|
|
err = pRegDeleteKeyExA( key32, "", KEY_WOW64_32KEY, 0 );
|
|
|
|
|
ok( err == ERROR_SUCCESS, "RegDeleteKey failed: %u\n", err );
|
|
|
|
|
err = pRegDeleteKeyExA( key64, "", KEY_WOW64_64KEY, 0 );
|
|
|
|
|
ok( err == ERROR_SUCCESS, "RegDeleteKey failed: %u\n", err );
|
|
|
|
|
pRegDeleteKeyExA( key64, "", KEY_WOW64_64KEY, 0 );
|
|
|
|
|
pRegDeleteKeyExA( root64, "", KEY_WOW64_64KEY, 0 );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
err = RegDeleteKeyA( key32, "" );
|
|
|
|
|
ok( err == ERROR_SUCCESS, "RegDeleteKey failed: %u\n", err );
|
|
|
|
|
err = RegDeleteKeyA( key64, "" );
|
|
|
|
|
ok( err == ERROR_SUCCESS, "RegDeleteKey failed: %u\n", err );
|
|
|
|
|
RegDeleteKeyA( key64, "" );
|
|
|
|
|
RegDeleteKeyA( root64, "" );
|
|
|
|
|
}
|
|
|
|
|
RegCloseKey( key32 );
|
|
|
|
|
RegCloseKey( key64 );
|
|
|
|
|
RegCloseKey( root32 );
|
|
|
|
|
RegCloseKey( root64 );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
START_TEST(registry)
|
|
|
|
|
{
|
|
|
|
|
/* Load pointers for functions that are not available in all Windows versions */
|
|
|
|
@@ -1520,6 +1927,8 @@ START_TEST(registry)
|
|
|
|
|
test_reg_delete_key();
|
|
|
|
|
test_reg_query_value();
|
|
|
|
|
test_string_termination();
|
|
|
|
|
test_symlinks();
|
|
|
|
|
test_redirection();
|
|
|
|
|
|
|
|
|
|
/* SaveKey/LoadKey require the SE_BACKUP_NAME privilege to be set */
|
|
|
|
|
if (set_privileges(SE_BACKUP_NAME, TRUE) &&
|
|
|
|
|