diff --git a/dlls/advapi32/registry.c b/dlls/advapi32/registry.c index cf5a1acb08c..2482b85da7e 100644 --- a/dlls/advapi32/registry.c +++ b/dlls/advapi32/registry.c @@ -476,6 +476,14 @@ LSTATUS WINAPI RegOpenKeyExW( HKEY hkey, LPCWSTR name, DWORD options, REGSAM acc OBJECT_ATTRIBUTES attr; UNICODE_STRING nameW; + if (retkey && (!name || !name[0]) && + (HandleToUlong(hkey) >= HandleToUlong(HKEY_SPECIAL_ROOT_FIRST)) && + (HandleToUlong(hkey) <= HandleToUlong(HKEY_SPECIAL_ROOT_LAST))) + { + *retkey = hkey; + return ERROR_SUCCESS; + } + /* NT+ allows beginning backslash for HKEY_CLASSES_ROOT */ if (HandleToUlong(hkey) == HandleToUlong(HKEY_CLASSES_ROOT) && name && *name == '\\') name++; @@ -520,6 +528,14 @@ LSTATUS WINAPI RegOpenKeyExA( HKEY hkey, LPCSTR name, DWORD options, REGSAM acce STRING nameA; NTSTATUS status; + if (retkey && (!name || !name[0]) && + (HandleToUlong(hkey) >= HandleToUlong(HKEY_SPECIAL_ROOT_FIRST)) && + (HandleToUlong(hkey) <= HandleToUlong(HKEY_SPECIAL_ROOT_LAST))) + { + *retkey = hkey; + return ERROR_SUCCESS; + } + if (!is_version_nt()) access = MAXIMUM_ALLOWED; /* Win95 ignores the access mask */ else { diff --git a/dlls/advapi32/tests/registry.c b/dlls/advapi32/tests/registry.c index b8b7e1c9517..a8e783c4d02 100644 --- a/dlls/advapi32/tests/registry.c +++ b/dlls/advapi32/tests/registry.c @@ -1075,7 +1075,6 @@ static void test_reg_open_key(void) ok(ret == ERROR_INVALID_HANDLE || ret == ERROR_BADKEY, /* Windows 95 returns BADKEY */ "expected ERROR_INVALID_HANDLE or ERROR_BADKEY, got %d\n", ret); ok(hkResult == hkPreserve, "expected hkResult == hkPreserve\n"); - RegCloseKey(hkResult); /* send in NULL hkResult */ ret = RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Test", NULL); @@ -1101,6 +1100,45 @@ static void test_reg_open_key(void) "expected ERROR_SUCCESS, ERROR_BAD_PATHNAME or ERROR_FILE_NOT_FOUND, got %d\n", ret); RegCloseKey(hkResult); + /* NULL or empty subkey of special root */ + hkResult = NULL; + ret = RegOpenKeyExA(HKEY_CLASSES_ROOT, NULL, 0, KEY_QUERY_VALUE, &hkResult); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret); + ok(hkResult == HKEY_CLASSES_ROOT, "expected hkResult == HKEY_CLASSES_ROOT\n"); + + hkResult = NULL; + ret = RegOpenKeyExA(HKEY_CLASSES_ROOT, "", 0, KEY_QUERY_VALUE, &hkResult); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret); + ok(hkResult == HKEY_CLASSES_ROOT, "expected hkResult == HKEY_CLASSES_ROOT\n"); + + hkResult = NULL; + ret = RegOpenKeyExA(HKEY_CLASSES_ROOT, "\\", 0, KEY_QUERY_VALUE, &hkResult); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret); + ok(hkResult != HKEY_CLASSES_ROOT, "expected hkResult to be a new key\n"); + ok(!RegCloseKey(hkResult), "got invalid hkey\n"); + + /* empty subkey of existing handle */ + hkResult = hkPreserve; + ret = RegOpenKeyExA(hkPreserve, "", 0, KEY_QUERY_VALUE, &hkResult); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret); + ok(hkResult != hkPreserve, "expected hkResult != hkPreserve\n"); + ok(!RegCloseKey(hkResult), "got invalid hkey\n"); + + /* NULL subkey of existing handle */ + hkResult = hkPreserve; + ret = RegOpenKeyExA(hkPreserve, NULL, 0, KEY_QUERY_VALUE, &hkResult); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret); + ok(hkResult != hkPreserve, "expected hkResult != hkPreserve\n"); + ok(!RegCloseKey(hkResult), "got invalid hkey\n"); + + /* empty subkey of NULL */ + hkResult = hkPreserve; + ret = RegOpenKeyExA(NULL, "", 0, KEY_QUERY_VALUE, &hkResult); + ok(ret == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %d\n", ret); + ok(hkResult == hkPreserve, "expected hkResult == hkPreserve\n"); + + RegCloseKey(hkPreserve); + /* WOW64 flags */ hkResult = NULL; ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software", 0, KEY_READ|KEY_WOW64_32KEY, &hkResult);