reactos/modules/rostests/apitests/advapi32/HKEY_CLASSES_ROOT.c
2018-08-04 14:39:13 +02:00

626 lines
17 KiB
C

/*
* PROJECT: ReactOS api tests
* LICENSE: GPLv2+ - See COPYING in the top level directory
* PURPOSE: Test for the HKEY_CLASSES_ROOT key
* PROGRAMMER: Jérôme Gardou <jerome.gardou@reactos.org>
*/
#include "precomp.h"
#include <ndk/cmfuncs.h>
#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
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);
InfoName.Buffer = NameInformation->Name;
InfoName.Length = NameInformation->NameLength;
InfoName.MaximumLength = InfoName.Length;
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, MachineSubKey;
HKEY UserKey, UserSubKey;
HKEY ClassesRootKey, ClassesRootSubKey;
DWORD ErrorCode;
DWORD Disposition;
/* First create a subkey in HKLM */
ErrorCode = RegCreateKeyExW(
HKEY_LOCAL_MACHINE,
L"Software\\Classes\\Apitest_HKLM",
0,
NULL,
0,
MAXIMUM_ALLOWED,
NULL,
&MachineKey,
NULL);
if (ErrorCode == ERROR_ACCESS_DENIED)
{
win_skip("Please run those tests with Administrator rights\n");
return;
}
ok_dec(ErrorCode, ERROR_SUCCESS);
ok(!IS_HKCR(MachineKey), "\n");
/* Open it in HKCR */
ErrorCode = RegOpenKeyExW(
HKEY_CLASSES_ROOT,
L"Apitest_HKLM",
0,
MAXIMUM_ALLOWED,
&ClassesRootKey);
ok_dec(ErrorCode, ERROR_SUCCESS);
ok(IS_HKCR(ClassesRootKey), "\n");
ok_key_name(ClassesRootKey, &HKLM_ClassesPath, L"Apitest_HKLM");
/* Try opening it in HKCU */
UserKey = (HKEY)(ULONG_PTR)0xCAFEF00DCAFEF00DULL;
ErrorCode = RegOpenKeyExW(
HKEY_CURRENT_USER,
L"Software\\Classes\\Apitest_HKLM",
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");
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)(ULONG_PTR)0xCAFEF00DCAFEF00DULL;
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)(ULONG_PTR)0xCAFEF00DCAFEF00DULL;
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)(ULONG_PTR)0xCAFEF00DCAFEF00DULL;
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");
/* Try the same thing, but this time with RegCreateKeyEx API */
RegCloseKey(ClassesRootKey);
ErrorCode = RegCreateKeyExW(
HKEY_CLASSES_ROOT,
L"Apitest_HKLM_HKCU",
0,
NULL,
0,
MAXIMUM_ALLOWED,
NULL,
&ClassesRootKey,
&Disposition);
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");
ok_hex(Disposition, REG_OPENED_EXISTING_KEY);
/* 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);
/* See what happens with subkeys */
ErrorCode = RegCreateKeyExW(
HKEY_LOCAL_MACHINE,
L"Software\\Classes\\Apitest_HKLM",
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",
0,
MAXIMUM_ALLOWED,
&ClassesRootKey);
ok_dec(ErrorCode, ERROR_SUCCESS);
ok(IS_HKCR(ClassesRootKey), "\n");
ok_key_name(ClassesRootKey, &HKLM_ClassesPath, L"Apitest_HKLM");
/* Create a corresponding subkey in HKCU */
ErrorCode = RegCreateKeyExW(
HKEY_CURRENT_USER,
L"Software\\Classes\\Apitest_HKLM\\HKCU_Subkey",
0,
NULL,
0,
MAXIMUM_ALLOWED,
NULL,
&UserSubKey,
NULL);
ok_dec(ErrorCode, ERROR_SUCCESS);
ok(!IS_HKCR(UserSubKey), "\n");
/* Open it as an HKCR subkey */
ErrorCode = RegOpenKeyExW(
ClassesRootKey,
L"HKCU_Subkey",
0,
MAXIMUM_ALLOWED,
&ClassesRootSubKey);
ok_dec(ErrorCode, ERROR_SUCCESS);
ok(IS_HKCR(ClassesRootSubKey), "\n");
ok_key_name(ClassesRootSubKey, &HKCU_ClassesPath, L"Apitest_HKLM\\HKCU_Subkey");
/* Try the same thing, but this time with RegCreateKeyEx API */
RegCloseKey(ClassesRootSubKey);
ErrorCode = RegCreateKeyExW(
ClassesRootKey,
L"HKCU_Subkey",
0,
NULL,
0,
MAXIMUM_ALLOWED,
NULL,
&ClassesRootSubKey,
&Disposition);
ok_dec(ErrorCode, ERROR_SUCCESS);
ok(IS_HKCR(ClassesRootSubKey), "\n");
/* Verify it has opened the HKCU one */
ok_key_name(ClassesRootSubKey, &HKCU_ClassesPath, L"Apitest_HKLM\\HKCU_Subkey");
ok_hex(Disposition, REG_OPENED_EXISTING_KEY);
/* This one now exists */
ErrorCode = RegOpenKeyExW(
HKEY_CURRENT_USER,
L"Software\\Classes\\Apitest_HKLM",
0,
MAXIMUM_ALLOWED,
&UserKey);
ok_dec(ErrorCode, ERROR_SUCCESS);
ok(!IS_HKCR(UserKey), "\n");
/* Delete */
ErrorCode = RegDeleteKeyW(UserKey, L"HKCU_Subkey");
ok_dec(ErrorCode, ERROR_SUCCESS);
ok_key_deleted(UserSubKey);
ok_key_deleted(ClassesRootSubKey);
RegCloseKey(UserSubKey);
RegCloseKey(ClassesRootSubKey);
/* See what this deletes */
RegDeleteKeyW(HKEY_CLASSES_ROOT, L"Apitest_HKLM");
ok_key_deleted(UserKey);
RegCloseKey(UserKey);
ok_key_not_deleted(ClassesRootKey);
ok_key_not_deleted(MachineKey);
/* Once again */
RegDeleteKeyW(HKEY_CLASSES_ROOT, L"Apitest_HKLM");
ok_key_deleted(ClassesRootKey);
ok_key_deleted(MachineKey);
RegCloseKey(ClassesRootKey);
RegCloseKey(MachineKey);
/* Same, but with HKCU first */
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");
/* Open 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");
/* Try creating a subkey with this HKCR handle, which points to a subkey in HKCU. */
ErrorCode = RegCreateKeyExW(
ClassesRootKey,
L"HKCR_Subkey",
0,
NULL,
0,
MAXIMUM_ALLOWED,
NULL,
&ClassesRootSubKey,
NULL);
ok_dec(ErrorCode, ERROR_SUCCESS);
ok(IS_HKCR(ClassesRootSubKey), "\n");
/* It is in fact created in HKLM */
ok_key_name(ClassesRootSubKey, &HKLM_ClassesPath, L"Apitest_HKCU\\HKCR_Subkey");
/* Let's see if we can delete it */
RegDeleteKeyW(ClassesRootKey, L"HKCR_Subkey");
ok_key_deleted(ClassesRootSubKey);
RegCloseKey(ClassesRootSubKey);
/* Create a corresponding subkey in HKLM */
ErrorCode = RegCreateKeyExW(
HKEY_LOCAL_MACHINE,
L"Software\\Classes\\Apitest_HKCU\\HKLM_Subkey",
0,
NULL,
0,
MAXIMUM_ALLOWED,
NULL,
&MachineSubKey,
NULL);
ok_dec(ErrorCode, ERROR_SUCCESS);
ok(!IS_HKCR(MachineSubKey), "\n");
/* Open it from the HKCR handle (which is still pointing to HKCU) */
ok_key_name(ClassesRootKey, &HKCU_ClassesPath, L"Apitest_HKCU");
ErrorCode = RegOpenKeyExW(
ClassesRootKey,
L"HKLM_Subkey",
0,
MAXIMUM_ALLOWED,
&ClassesRootSubKey);
ok_dec(ErrorCode, ERROR_SUCCESS);
ok(IS_HKCR(ClassesRootSubKey), "\n");
ok_key_name(ClassesRootSubKey, &HKLM_ClassesPath, L"Apitest_HKCU\\HKLM_Subkey");
/* This one now exists */
ErrorCode = RegOpenKeyExW(
HKEY_LOCAL_MACHINE,
L"Software\\Classes\\Apitest_HKCU",
0,
MAXIMUM_ALLOWED,
&MachineKey);
ok_dec(ErrorCode, ERROR_SUCCESS);
ok(!IS_HKCR(MachineKey), "\n");
/* Delete this subkey */
ErrorCode = RegDeleteKeyW(MachineKey, L"HKLM_Subkey");
ok_dec(ErrorCode, ERROR_SUCCESS);
ok_key_deleted(MachineSubKey);
ok_key_deleted(ClassesRootSubKey);
/* Create another subkey, this time from HKCU */
ErrorCode = RegCreateKeyExW(
HKEY_CURRENT_USER,
L"Software\\Classes\\Apitest_HKCU\\HKCU_Subkey",
0,
NULL,
0,
MAXIMUM_ALLOWED,
NULL,
&UserSubKey,
NULL);
ok_dec(ErrorCode, ERROR_SUCCESS);
ok(!IS_HKCR(UserSubKey), "\n");
/* And try creating it again as a subkey of this HKCR handle (which points to HKCU). */
ok_key_name(ClassesRootKey, &HKCU_ClassesPath, L"Apitest_HKCU");
ErrorCode = RegCreateKeyExW(
ClassesRootKey,
L"HKCU_Subkey",
0,
NULL,
0,
MAXIMUM_ALLOWED,
NULL,
&ClassesRootSubKey,
&Disposition);
ok_dec(ErrorCode, ERROR_SUCCESS);
ok(IS_HKCR(ClassesRootSubKey), "\n");
/* This time the one in HKCU is opened */
ok_key_name(ClassesRootSubKey, &HKCU_ClassesPath, L"Apitest_HKCU\\HKCU_Subkey");
ok_hex(Disposition, REG_OPENED_EXISTING_KEY);
/* Let's see if we can delete it */
RegDeleteKeyW(ClassesRootKey, L"HKCU_Subkey");
ok_key_deleted(ClassesRootSubKey);
RegCloseKey(ClassesRootSubKey);
ok_key_deleted(UserSubKey);
RegCloseKey(UserSubKey);
RegCloseKey(MachineSubKey);
RegCloseKey(ClassesRootSubKey);
/* See what this deletes */
RegDeleteKeyW(HKEY_CLASSES_ROOT, L"Apitest_HKCU");
ok_key_deleted(UserKey);
RegCloseKey(UserKey);
ok_key_deleted(ClassesRootKey);
RegCloseKey(UserKey);
ok_key_not_deleted(MachineKey);
/* Once again */
RegDeleteKeyW(HKEY_CLASSES_ROOT, L"Apitest_HKCU");
ok_key_deleted(MachineKey);
RegCloseKey(MachineKey);
}
static
void
Test_DuplicateHandle(void)
{
HKEY KeyHandle, DupHandle;
DWORD ErrorCode;
BOOL Duplicated;
ErrorCode = RegOpenKeyExW(HKEY_CLASSES_ROOT, L"CLSID", 0, KEY_READ, &KeyHandle);
ok_dec(ErrorCode, ERROR_SUCCESS);
ok(IS_HKCR(KeyHandle), "\n");
Duplicated = DuplicateHandle(GetCurrentProcess(), KeyHandle, GetCurrentProcess(), (PHANDLE)&DupHandle, 0, 0, DUPLICATE_SAME_ACCESS);
ok(Duplicated, "\n");
ok(DupHandle != NULL, "\n");
ok(!IS_HKCR(DupHandle), "\n");
RegCloseKey(KeyHandle);
RegCloseKey(DupHandle);
}
START_TEST(HKEY_CLASSES_ROOT)
{
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();
}