From 267bd04e5f332d23a443916ef1a674ae6f7396e3 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Gardou?= Date: Mon, 29 Sep 2014 19:13:37 +0000 Subject: [PATCH 1/1] [ADVAPI32_APITEST] - Add tests testing behaviour of RegOpen/Create for HKEY_CLASSES_ROOT subkeys - Clean up a bit the other tests CORE-8582 svn path=/trunk/; revision=64402 --- .../apitests/advapi32/HKEY_CLASSES_ROOT.c | 349 ++++++++++++++++-- 1 file changed, 322 insertions(+), 27 deletions(-) diff --git a/rostests/apitests/advapi32/HKEY_CLASSES_ROOT.c b/rostests/apitests/advapi32/HKEY_CLASSES_ROOT.c index bc3b64830ec..570fb0395ff 100644 --- a/rostests/apitests/advapi32/HKEY_CLASSES_ROOT.c +++ b/rostests/apitests/advapi32/HKEY_CLASSES_ROOT.c @@ -13,31 +13,322 @@ #include #include -#define IS_HKCR(hk) ((UINT_PTR)hk > 0 && ((UINT_PTR)hk & 3) == 2) +#define IS_HKCR(hk) (((UINT_PTR)hk & 3) == 2) + +/* HKCU and HKLM system paths */ +static UNICODE_STRING HKLM_ClassesPath = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\Software\\Classes"); +static UNICODE_STRING HKCU_ClassesPath; + +static +LONG +DeleteSubKey(HKEY hKey, LPWSTR Root, LPWSTR SubKey) +{ + HKEY RootKey; + LONG ErrorCode; + + ErrorCode = RegOpenKeyExW( + hKey, + Root, + 0, + MAXIMUM_ALLOWED, + &RootKey); + ok_dec(ErrorCode, ERROR_SUCCESS); + ErrorCode = RegDeleteKeyW(RootKey, SubKey); + RegCloseKey(RootKey); + + return ErrorCode; +} static void -Test_KeyInformation(void) +GetKeyName(HKEY hKey, PUNICODE_STRING KeyName) +{ + UNICODE_STRING InfoName; + PKEY_NAME_INFORMATION NameInformation; + ULONG InfoLength; + NTSTATUS Status; + + /* Get info length */ + InfoLength = 0; + Status = NtQueryKey(hKey, KeyNameInformation, NULL, 0, &InfoLength); + ok_ntstatus(Status, STATUS_BUFFER_TOO_SMALL); + + /* Get it for real */ + NameInformation = RtlAllocateHeap(RtlGetProcessHeap(), 0, InfoLength); + ok(NameInformation != NULL, "\n"); + + Status = NtQueryKey(hKey, KeyNameInformation, NameInformation, InfoLength, &InfoLength); + ok_ntstatus(Status, STATUS_SUCCESS); + + RtlInitUnicodeString(&InfoName, NameInformation->Name); + InfoName.Length = NameInformation->NameLength; + + RtlDuplicateUnicodeString(RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE, &InfoName, KeyName); + + RtlFreeHeap(RtlGetProcessHeap(), 0, NameInformation); +} + +static void _test_key_deleted(HKEY hKey, BOOL Deleted, ULONG LineNumber) +{ + DWORD ErrorCode = RegQueryInfoKeyW(hKey, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + if (Deleted) + ok_(__FILE__, LineNumber)(ErrorCode == ERROR_KEY_DELETED, "\n"); + else + ok_(__FILE__, LineNumber)(ErrorCode == ERROR_SUCCESS, "\n"); +} +#define ok_key_deleted(hKey) _test_key_deleted(hKey, TRUE, __LINE__) +#define ok_key_not_deleted(hKey) _test_key_deleted(hKey, FALSE, __LINE__) + +static void _test_key_name(HKEY hKey, PUNICODE_STRING Prefix, LPCWSTR Name, ULONG LineNumber) +{ + UNICODE_STRING ExpectedName, KeyName; + WCHAR Buffer[1024]; + + ExpectedName.Length = 0; + ExpectedName.MaximumLength = sizeof(Buffer); + ExpectedName.Buffer = Buffer; + + RtlAppendUnicodeStringToString(&ExpectedName, Prefix); + RtlAppendUnicodeToString(&ExpectedName, L"\\"); + RtlAppendUnicodeToString(&ExpectedName, Name); + + GetKeyName(hKey, &KeyName); + + ok_(__FILE__, LineNumber)(RtlCompareUnicodeString(&KeyName, &ExpectedName, TRUE) == 0, + "Key name is %.*S, expected %.*S\n", + KeyName.Length, KeyName.Buffer, + ExpectedName.Length, ExpectedName.Buffer); + + RtlFreeUnicodeString(&KeyName); +} + +#define ok_key_name(hKey, Prefix, Name) _test_key_name(hKey, Prefix, Name, __LINE__) + +static +void +Test_CreateOpenKey(void) +{ + HKEY MachineKey, UserKey, ClassesRootKey; + DWORD ErrorCode; + + /* First create a subkey in HKLM */ + ErrorCode = RegCreateKeyExW( + HKEY_LOCAL_MACHINE, + L"Software\\Classes\\Apitest_HKLM_Only", + 0, + NULL, + 0, + MAXIMUM_ALLOWED, + NULL, + &MachineKey, + NULL); + ok_dec(ErrorCode, ERROR_SUCCESS); + ok(!IS_HKCR(MachineKey), "\n"); + + /* Open it in HKCR */ + ErrorCode = RegOpenKeyExW( + HKEY_CLASSES_ROOT, + L"Apitest_HKLM_Only", + 0, + MAXIMUM_ALLOWED, + &ClassesRootKey); + ok_dec(ErrorCode, ERROR_SUCCESS); + ok(IS_HKCR(ClassesRootKey), "\n"); + ok_key_name(ClassesRootKey, &HKLM_ClassesPath, L"Apitest_HKLM_Only"); + + /* Try opening it in HKCU */ + UserKey = (HKEY)0xCAFEF00D; + ErrorCode = RegOpenKeyExW( + HKEY_CURRENT_USER, + L"Software\\Classes\\Apitest_HKLM_Only", + 0, + MAXIMUM_ALLOWED, + &UserKey); + ok_dec(ErrorCode, ERROR_FILE_NOT_FOUND); + ok_hdl(UserKey, NULL); + + /* Cleanup */ + RegCloseKey(ClassesRootKey); + RegCloseKey(MachineKey); + ErrorCode = DeleteSubKey(HKEY_LOCAL_MACHINE, L"Software\\Classes", L"Apitest_HKLM_Only"); + ok_dec(ErrorCode, ERROR_SUCCESS); + + /* Try creating in HKCR */ + ErrorCode = RegCreateKeyExW( + HKEY_CLASSES_ROOT, + L"Apitest_HKCR", + 0, + NULL, + 0, + MAXIMUM_ALLOWED, + NULL, + &ClassesRootKey, + NULL); + ok_dec(ErrorCode, ERROR_SUCCESS); + ok(IS_HKCR(ClassesRootKey), "\n"); + ok_key_name(ClassesRootKey, &HKLM_ClassesPath, L"Apitest_HKCR"); + + /* It should be present in HKLM */ + ErrorCode = RegOpenKeyExW( + HKEY_LOCAL_MACHINE, + L"Software\\Classes\\Apitest_HKCR", + 0, + MAXIMUM_ALLOWED, + &MachineKey); + ok_dec(ErrorCode, ERROR_SUCCESS); + ok(!IS_HKCR(MachineKey), "\n"); + + /* But not in HKCU */ + UserKey = (HKEY)0xCAFEF00D; + ErrorCode = RegOpenKeyExW( + HKEY_CURRENT_USER, + L"Software\\Classes\\Apitest_HKCR", + 0, + MAXIMUM_ALLOWED, + &UserKey); + ok_dec(ErrorCode, ERROR_FILE_NOT_FOUND); + ok_hdl(UserKey, NULL); + + /* This must delete the one in HKLM */ + ErrorCode = RegDeleteKeyW(HKEY_CLASSES_ROOT, L"Apitest_HKCR"); + ok_dec(ErrorCode, ERROR_SUCCESS); + ok_key_deleted(ClassesRootKey); + ok_key_deleted(MachineKey); + RegCloseKey(ClassesRootKey); + RegCloseKey(MachineKey); + + /* Test that it is really not present anymore */ + MachineKey = (HKEY)0xCAFEF00D; + ErrorCode = RegOpenKeyExW( + HKEY_LOCAL_MACHINE, + L"Software\\Classes\\Apitest_HKCR", + 0, + MAXIMUM_ALLOWED, + &MachineKey); + ok_dec(ErrorCode, ERROR_FILE_NOT_FOUND); + ok_hdl(MachineKey, NULL); + + /* Try creating in HKCU */ + ErrorCode = RegCreateKeyExW( + HKEY_CURRENT_USER, + L"Software\\Classes\\Apitest_HKCU", + 0, + NULL, + 0, + MAXIMUM_ALLOWED, + NULL, + &UserKey, + NULL); + ok_dec(ErrorCode, ERROR_SUCCESS); + ok(!IS_HKCR(UserKey), "\n"); + + /* Try opening it in HKCR */ + ErrorCode = RegOpenKeyExW( + HKEY_CLASSES_ROOT, + L"Apitest_HKCU", + 0, + MAXIMUM_ALLOWED, + &ClassesRootKey); + ok_dec(ErrorCode, ERROR_SUCCESS); + ok(IS_HKCR(ClassesRootKey), "\n"); + ok_key_name(ClassesRootKey, &HKCU_ClassesPath, L"Apitest_HKCU"); + + /* And in HKLM */ + ErrorCode = RegOpenKeyExW( + HKEY_LOCAL_MACHINE, + L"Software\\Classes\\Apitest_HKCU", + 0, + MAXIMUM_ALLOWED, + &MachineKey); + ok_dec(ErrorCode, ERROR_FILE_NOT_FOUND); + ok_hdl(MachineKey, NULL); + + ErrorCode = RegDeleteKeyW(HKEY_CLASSES_ROOT, L"Apitest_HKCU"); + ok_dec(ErrorCode, ERROR_SUCCESS); + ok_key_deleted(ClassesRootKey); + ok_key_deleted(UserKey); + RegCloseKey(ClassesRootKey); + RegCloseKey(UserKey); + + /* Test that it is really not present anymore */ + UserKey = (HKEY)0xCAFEF00D; + ErrorCode = RegOpenKeyExW( + HKEY_CURRENT_USER, + L"Software\\Classes\\Apitest_HKCU", + 0, + MAXIMUM_ALLOWED, + &UserKey); + ok_dec(ErrorCode, ERROR_FILE_NOT_FOUND); + ok_hdl(UserKey, NULL); + + /* Try creating in both HKLM and HKCU */ + ErrorCode = RegCreateKeyExW( + HKEY_CURRENT_USER, + L"Software\\Classes\\Apitest_HKLM_HKCU", + 0, + NULL, + 0, + MAXIMUM_ALLOWED, + NULL, + &UserKey, + NULL); + ok_dec(ErrorCode, ERROR_SUCCESS); + ok(!IS_HKCR(UserKey), "\n"); + + ErrorCode = RegCreateKeyExW( + HKEY_LOCAL_MACHINE, + L"Software\\Classes\\Apitest_HKLM_HKCU", + 0, + NULL, + 0, + MAXIMUM_ALLOWED, + NULL, + &MachineKey, + NULL); + ok_dec(ErrorCode, ERROR_SUCCESS); + ok(!IS_HKCR(MachineKey), "\n"); + + /* Open it in HKCR */ + ErrorCode = RegOpenKeyExW( + HKEY_CLASSES_ROOT, + L"Apitest_HKLM_HKCU", + 0, + MAXIMUM_ALLOWED, + &ClassesRootKey); + ok_dec(ErrorCode, ERROR_SUCCESS); + ok(IS_HKCR(ClassesRootKey), "\n"); + /* Verify it has opened the HKCU one */ + ok_key_name(ClassesRootKey, &HKCU_ClassesPath, L"Apitest_HKLM_HKCU"); + + /* Deleting it from HKCR first deletes the one in HKCU */ + ErrorCode = RegDeleteKeyW(HKEY_CLASSES_ROOT, L"Apitest_HKLM_HKCU"); + ok_dec(ErrorCode, ERROR_SUCCESS); + ok_key_deleted(UserKey); + ok_key_deleted(ClassesRootKey); + ok_key_not_deleted(MachineKey); + + RegCloseKey(UserKey); + RegCloseKey(ClassesRootKey); + + /* This deletes it from HKLM this time */ + ErrorCode = RegDeleteKeyW(HKEY_CLASSES_ROOT, L"Apitest_HKLM_HKCU"); + ok_dec(ErrorCode, ERROR_SUCCESS); + ok_key_deleted(MachineKey); + RegCloseKey(MachineKey); +} + +static +void +Test_KeyName(void) { HKEY KeyHandle; DWORD ErrorCode; - NTSTATUS Status; - UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\Software\\Classes\\CLSID"); - UNICODE_STRING InfoName; - CHAR Buffer[FIELD_OFFSET(KEY_NAME_INFORMATION, Name[512])]; - PKEY_NAME_INFORMATION NameInfo = (PKEY_NAME_INFORMATION)Buffer; - ULONG ResultLength; ErrorCode = RegOpenKeyExW(HKEY_CLASSES_ROOT, L"CLSID", 0, KEY_READ, &KeyHandle); ok_dec(ErrorCode, ERROR_SUCCESS); ok(IS_HKCR(KeyHandle), "\n"); - - Status = NtQueryKey(KeyHandle, KeyNameInformation, NameInfo, sizeof(Buffer), &ResultLength); - ok_ntstatus(Status, STATUS_SUCCESS); - RtlInitUnicodeString(&InfoName, NameInfo->Name); - InfoName.Length = NameInfo->NameLength; - ok(RtlCompareUnicodeString(&KeyName, &InfoName, TRUE) == 0, "%.*S\n", InfoName.Length, InfoName.Buffer); + ok_key_name(KeyHandle, &HKLM_ClassesPath, L"CLSID"); RegCloseKey(KeyHandle); } @@ -49,13 +340,6 @@ Test_DuplicateHandle(void) HKEY KeyHandle, DupHandle; DWORD ErrorCode; BOOL Duplicated; - NTSTATUS Status; - UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\Software\\Classes\\CLSID"); - UNICODE_STRING InfoName; - CHAR Buffer[FIELD_OFFSET(KEY_NAME_INFORMATION, Name[512])]; - PKEY_NAME_INFORMATION NameInfo = (PKEY_NAME_INFORMATION)Buffer; - ULONG ResultLength; - ErrorCode = RegOpenKeyExW(HKEY_CLASSES_ROOT, L"CLSID", 0, KEY_READ, &KeyHandle); ok_dec(ErrorCode, ERROR_SUCCESS); @@ -66,11 +350,7 @@ Test_DuplicateHandle(void) ok(DupHandle != NULL, "\n"); ok(!IS_HKCR(DupHandle), "\n"); - Status = NtQueryKey(DupHandle, KeyNameInformation, NameInfo, sizeof(Buffer), &ResultLength); - ok_ntstatus(Status, STATUS_SUCCESS); - RtlInitUnicodeString(&InfoName, NameInfo->Name); - InfoName.Length = NameInfo->NameLength; - ok(RtlCompareUnicodeString(&KeyName, &InfoName, TRUE) == 0, "%S\n", NameInfo->Name); + ok_key_name(DupHandle, &HKLM_ClassesPath, L"CLSID"); RegCloseKey(KeyHandle); RegCloseKey(DupHandle); @@ -78,6 +358,21 @@ Test_DuplicateHandle(void) START_TEST(HKEY_CLASSES_ROOT) { - Test_KeyInformation(); + HKEY UserKey; + LONG ErrorCode; + + /* Get HKCU real key name */ + ErrorCode = RegOpenKeyExW( + HKEY_CURRENT_USER, + L"Software\\Classes", + 0, + KEY_READ, + &UserKey); + ok_dec(ErrorCode, ERROR_SUCCESS); + GetKeyName(UserKey, &HKCU_ClassesPath); + RegCloseKey(UserKey); + + Test_CreateOpenKey(); Test_DuplicateHandle(); + Test_KeyName(); } -- 2.17.1