diff --git a/dlls/advapi32/registry.c b/dlls/advapi32/registry.c index 744908fc757..c01e12546f0 100644 --- a/dlls/advapi32/registry.c +++ b/dlls/advapi32/registry.c @@ -228,9 +228,9 @@ static NTSTATUS open_key( HKEY *retkey, ACCESS_MASK access, OBJECT_ATTRIBUTES *a static HKEY create_special_root_hkey( HKEY hkey, DWORD access ) { HKEY ret = 0; - int idx = (UINT_PTR)hkey - (UINT_PTR)HKEY_SPECIAL_ROOT_FIRST; + int idx = HandleToUlong(hkey) - HandleToUlong(HKEY_SPECIAL_ROOT_FIRST); - if (hkey == HKEY_CURRENT_USER) + if (HandleToUlong(hkey) == HandleToUlong(HKEY_CURRENT_USER)) { if (RtlOpenCurrentUser( access, (HANDLE *)&hkey )) return 0; TRACE( "HKEY_CURRENT_USER -> %p\n", hkey ); @@ -267,9 +267,10 @@ static inline HKEY get_special_root_hkey( HKEY hkey ) { HKEY ret = hkey; - if ((hkey >= HKEY_SPECIAL_ROOT_FIRST) && (hkey <= HKEY_SPECIAL_ROOT_LAST)) + if ((HandleToUlong(hkey) >= HandleToUlong(HKEY_SPECIAL_ROOT_FIRST)) + && (HandleToUlong(hkey) <= HandleToUlong(HKEY_SPECIAL_ROOT_LAST))) { - if (!(ret = special_root_keys[(UINT_PTR)hkey - (UINT_PTR)HKEY_SPECIAL_ROOT_FIRST])) + if (!(ret = special_root_keys[HandleToUlong(hkey) - HandleToUlong(HKEY_SPECIAL_ROOT_FIRST)])) ret = create_special_root_hkey( hkey, MAXIMUM_ALLOWED ); } return ret; @@ -286,9 +287,10 @@ LSTATUS WINAPI RegOverridePredefKey( HKEY hkey, HKEY override ) TRACE("(%p %p)\n", hkey, override); - if ((hkey < HKEY_SPECIAL_ROOT_FIRST) || (hkey > HKEY_SPECIAL_ROOT_LAST)) + if ((HandleToUlong(hkey) < HandleToUlong(HKEY_SPECIAL_ROOT_FIRST)) + || (HandleToUlong(hkey) > HandleToUlong(HKEY_SPECIAL_ROOT_LAST))) return ERROR_INVALID_PARAMETER; - idx = (UINT_PTR)hkey - (UINT_PTR)HKEY_SPECIAL_ROOT_FIRST; + idx = HandleToUlong(hkey) - HandleToUlong(HKEY_SPECIAL_ROOT_FIRST); if (override) { @@ -443,7 +445,7 @@ LSTATUS WINAPI RegOpenKeyExW( HKEY hkey, LPCWSTR name, DWORD options, REGSAM acc UNICODE_STRING nameW; /* NT+ allows beginning backslash for HKEY_CLASSES_ROOT */ - if (hkey == HKEY_CLASSES_ROOT && name && *name == '\\') name++; + if (HandleToUlong(hkey) == HandleToUlong(HKEY_CLASSES_ROOT) && name && *name == '\\') name++; if (!retkey) return ERROR_INVALID_PARAMETER; if (!(hkey = get_special_root_hkey( hkey ))) return ERROR_INVALID_HANDLE; @@ -490,7 +492,7 @@ LSTATUS WINAPI RegOpenKeyExA( HKEY hkey, LPCSTR name, DWORD options, REGSAM acce else { /* NT+ allows beginning backslash for HKEY_CLASSES_ROOT */ - if (hkey == HKEY_CLASSES_ROOT && name && *name == '\\') name++; + if (HandleToUlong(hkey) == HandleToUlong(HKEY_CLASSES_ROOT) && name && *name == '\\') name++; } if (!(hkey = get_special_root_hkey( hkey ))) return ERROR_INVALID_HANDLE; @@ -2814,7 +2816,7 @@ cleanup: LSTATUS WINAPI RegDisablePredefinedCache(void) { HKEY hkey_current_user; - int idx = (UINT_PTR)HKEY_CURRENT_USER - (UINT_PTR)HKEY_SPECIAL_ROOT_FIRST; + int idx = HandleToUlong(HKEY_CURRENT_USER) - HandleToUlong(HKEY_SPECIAL_ROOT_FIRST); /* prevent caching of future requests */ hkcu_cache_disabled = TRUE; diff --git a/dlls/advapi32/tests/registry.c b/dlls/advapi32/tests/registry.c index 33b5d9b13bb..b2483a70317 100644 --- a/dlls/advapi32/tests/registry.c +++ b/dlls/advapi32/tests/registry.c @@ -36,6 +36,7 @@ static DWORD GLE; static const char * sTestpath1 = "%LONGSYSTEMVAR%\\subdir1"; static const char * sTestpath2 = "%FOO%\\subdir1"; +static const DWORD ptr_size = 8 * sizeof(void*); static DWORD (WINAPI *pRegGetValueA)(HKEY,LPCSTR,LPCSTR,DWORD,LPDWORD,PVOID,LPDWORD); static DWORD (WINAPI *pRegDeleteTreeA)(HKEY,LPCSTR); @@ -947,6 +948,39 @@ static void test_reg_open_key(void) "RegOpenKeyEx with KEY_WOW64_64KEY failed (err=%u)\n", ret); RegCloseKey(hkResult); + /* check special HKEYs on 64bit + * only the lower 4 bytes of the supplied key are used + */ + if (ptr_size == 64) + { + /* HKEY_CURRENT_USER */ + ret = RegOpenKeyA(UlongToHandle(HandleToUlong(HKEY_CURRENT_USER)), "Software", &hkResult); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret); + ok(hkResult != NULL, "expected hkResult != NULL\n"); + RegCloseKey(hkResult); + + ret = RegOpenKeyA((HKEY)(HandleToUlong(HKEY_CURRENT_USER) | (ULONG64)1 << 32), "Software", &hkResult); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret); + ok(hkResult != NULL, "expected hkResult != NULL\n"); + RegCloseKey(hkResult); + + ret = RegOpenKeyA((HKEY)(HandleToUlong(HKEY_CURRENT_USER) | (ULONG64)0xdeadbeef << 32), "Software", &hkResult); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret); + ok(hkResult != NULL, "expected hkResult != NULL\n"); + RegCloseKey(hkResult); + + ret = RegOpenKeyA((HKEY)(HandleToUlong(HKEY_CURRENT_USER) | (ULONG64)0xffffffff << 32), "Software", &hkResult); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret); + ok(hkResult != NULL, "expected hkResult != NULL\n"); + RegCloseKey(hkResult); + + /* HKEY_LOCAL_MACHINE */ + ret = RegOpenKeyA((HKEY)(HandleToUlong(HKEY_LOCAL_MACHINE) | (ULONG64)0xdeadbeef << 32), "Software", &hkResult); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret); + ok(hkResult != NULL, "expected hkResult != NULL\n"); + RegCloseKey(hkResult); + } + /* Try using WOW64 flags when opening a key with a DACL set to verify that * the registry access check is performed correctly. Redirection isn't * being tested, so the tests don't care about whether the process is @@ -1798,8 +1832,6 @@ static void test_symlinks(void) 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;