reactos/modules/rostests/apitests/advapi32/RegCreateKeyEx.c
Doug Lyons 40233a3644
[ADVAPI32_APITEST] Add new RegCreateKeyEx tests (#5234)
* [ADVAPI32_APITEST] Add new RegCreateKeyEx tests
* Remove trailing spaces.
* Initialize SECURITY_ATTRIBUTES sa with zeroes.

Add a set of tests for RegCreateKeyExW and -A.
Created to prove the correctness of the already merged PR (#5230)

JIRA issue: CORE-15471
2023-06-29 21:33:44 +02:00

230 lines
8.2 KiB
C

/*
* PROJECT: ReactOS api tests
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
* PURPOSE: Tests for RegCreateKeyExW.
* COPYRIGHT: Copyright 2023 Doug Lyons <douglyons@douglyons.com>
*/
/*
* Idea based loosely on code from the following:
* https://learn.microsoft.com/en-us/windows/win32/secauthz/creating-a-security-descriptor-for-a-new-object-in-c--
*/
#include <apitest.h>
#include <stdio.h>
#define WIN32_NO_STATUS
#define _INC_WINDOWS
#define COM_NO_WINDOWS_H
#include <windef.h>
#include <aclapi.h>
START_TEST(RegCreateKeyEx)
{
HKEY hkey_main;
DWORD dwRes, dwDisposition;
PACL pACL = NULL;
PSECURITY_DESCRIPTOR pSD = NULL;
PSID pEveryoneSID = NULL, pAdminSID = NULL;
SID_IDENTIFIER_AUTHORITY SIDAuthWorld = {SECURITY_WORLD_SID_AUTHORITY};
SID_IDENTIFIER_AUTHORITY SIDAuthNT = {SECURITY_NT_AUTHORITY};
EXPLICIT_ACCESSW ea[2];
SECURITY_ATTRIBUTES sa = { 0 };
LONG lRes;
BOOL bRes;
LONG ErrorCode = 0;
HKEY hkSub = NULL;
// If any of the test keys already exist, delete them to ensure proper testing
if (RegOpenKeyExW(HKEY_CURRENT_USER, L"mykey", 0, KEY_ALL_ACCESS, &hkey_main) == ERROR_SUCCESS)
{
RegCloseKey(hkey_main);
ErrorCode = RegDeleteKeyW(HKEY_CURRENT_USER, L"mykey");
ok_dec(ErrorCode, ERROR_SUCCESS);
if (ErrorCode != ERROR_SUCCESS)
{
skip("'HKCU\\mykey' cannot be deleted. Terminating test\n");
goto Cleanup;
}
}
if (RegOpenKeyExW(HKEY_CURRENT_USER, L"mykey1", 0, KEY_ALL_ACCESS, &hkey_main) == ERROR_SUCCESS)
{
RegCloseKey(hkey_main);
ErrorCode = RegDeleteKeyW(HKEY_CURRENT_USER, L"mykey1");
ok_dec(ErrorCode, ERROR_SUCCESS);
if (ErrorCode != ERROR_SUCCESS)
{
skip("'HKCU\\mykey1' cannot be deleted. Terminating test\n");
goto Cleanup;
}
}
if (RegOpenKeyExW(HKEY_CURRENT_USER, L"mykey2", 0, KEY_ALL_ACCESS, &hkey_main) == ERROR_SUCCESS)
{
RegCloseKey(hkey_main);
ErrorCode = RegDeleteKeyW(HKEY_CURRENT_USER, L"mykey2");
ok_dec(ErrorCode, ERROR_SUCCESS);
if (ErrorCode != ERROR_SUCCESS)
{
skip("'HKCU\\mykey2' cannot be deleted. Terminating test\n");
goto Cleanup;
}
}
// Setup GetLastError to known value for tests
SetLastError(0xdeadbeef);
// Create a well-known SID for the Everyone group.
bRes = AllocateAndInitializeSid(&SIDAuthWorld, 1,
SECURITY_WORLD_RID,
0, 0, 0, 0, 0, 0, 0,
&pEveryoneSID);
ok(bRes, "AllocateAndInitializeSid Error %ld\n", GetLastError());
if (!bRes)
{
skip("EveryoneSID not initialized. Terminating test\n");
goto Cleanup;
}
// Initialize an EXPLICIT_ACCESS structure for an ACE.
// The ACE will allow Everyone read access to the key.
ZeroMemory(&ea, sizeof(ea));
ea[0].grfAccessPermissions = KEY_READ;
ea[0].grfAccessMode = SET_ACCESS;
ea[0].grfInheritance= NO_INHERITANCE;
ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
ea[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
ea[0].Trustee.ptstrName = pEveryoneSID;
// Create a SID for the BUILTIN\Administrators group.
bRes = AllocateAndInitializeSid(&SIDAuthNT, 2,
SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS,
0, 0, 0, 0, 0, 0,
&pAdminSID);
ok(bRes, "AllocateAndInitializeSid Error %ld\n", GetLastError());
if (!bRes)
{
skip("AdminSID not initialized. Terminating test\n");
goto Cleanup;
}
// Initialize an EXPLICIT_ACCESS structure for an ACE.
// The ACE will allow the Administrators group full access to the key.
ea[1].grfAccessPermissions = KEY_ALL_ACCESS;
ea[1].grfAccessMode = SET_ACCESS;
ea[1].grfInheritance= NO_INHERITANCE;
ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
ea[1].Trustee.TrusteeType = TRUSTEE_IS_GROUP;
ea[1].Trustee.ptstrName = pAdminSID;
// Create a new ACL that contains the new ACEs.
dwRes = SetEntriesInAclW(_countof(ea), ea, NULL, &pACL);
ok(dwRes == ERROR_SUCCESS, "SetEntriesInAcl Error %ld\n", GetLastError());
if (dwRes != ERROR_SUCCESS)
goto Cleanup;
// Initialize a security descriptor.
pSD = LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
ok(pSD != NULL, "LocalAlloc Error %ld\n", GetLastError());
if (pSD == NULL)
goto Cleanup;
bRes = InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
ok(bRes, "InitializeSecurityDescriptor Error %ld\n", GetLastError());
if (!bRes)
goto Cleanup;
// Add the ACL to the security descriptor.
bRes = SetSecurityDescriptorDacl(pSD,
TRUE, // bDaclPresent flag
pACL,
FALSE); // not a default DACL
ok(bRes, "SetSecurityDescriptorDacl Error %ld\n", GetLastError());
if (!bRes)
goto Cleanup;
// Initialize a security attributes structure.
sa.lpSecurityDescriptor = pSD;
sa.bInheritHandle = FALSE;
// Use the security attributes to set the security descriptor
// with an nlength that is 0.
sa.nLength = 0;
lRes = RegCreateKeyExW(HKEY_CURRENT_USER, L"mykey", 0, L"", 0,
KEY_READ | KEY_WRITE, &sa, &hkSub, &dwDisposition);
ok(lRes == ERROR_SUCCESS, "RegCreateKeyExW returned '%ld', expected 0", lRes);
ok(dwDisposition == REG_CREATED_NEW_KEY, "Should have created NEW key\n");
if (dwDisposition != REG_CREATED_NEW_KEY)
goto Cleanup;
// Test the -A function
lRes = RegCreateKeyExA(HKEY_CURRENT_USER, "mykey", 0, "", 0,
KEY_READ | KEY_WRITE, &sa, &hkSub, &dwDisposition);
ok(lRes == ERROR_SUCCESS, "RegCreateKeyExA returned '%ld', expected 0", lRes);
ok(dwDisposition == REG_OPENED_EXISTING_KEY, "Should have opened EXISTING key\n");
if (dwDisposition != REG_OPENED_EXISTING_KEY)
goto Cleanup;
// Use the security attributes to set the security descriptor
// with an nlength that is too short, but not 0.
sa.nLength = sizeof(SECURITY_ATTRIBUTES) / 2;
lRes = RegCreateKeyExW(HKEY_CURRENT_USER, L"mykey1", 0, L"", 0,
KEY_READ | KEY_WRITE, &sa, &hkSub, &dwDisposition);
ok(lRes == ERROR_SUCCESS, "RegCreateKeyExW returned '%ld', expected 0", lRes);
ok(dwDisposition == REG_CREATED_NEW_KEY, "Should have created NEW key\n");
if (dwDisposition != REG_CREATED_NEW_KEY)
goto Cleanup;
// Test the -A function
lRes = RegCreateKeyExA(HKEY_CURRENT_USER, "mykey1", 0, "", 0,
KEY_READ | KEY_WRITE, &sa, &hkSub, &dwDisposition);
ok(lRes == ERROR_SUCCESS, "RegCreateKeyExA returned '%ld', expected 0", lRes);
ok(dwDisposition == REG_OPENED_EXISTING_KEY, "Should have opened EXISTING key\n");
if (dwDisposition != REG_OPENED_EXISTING_KEY)
goto Cleanup;
// Use the security attributes to set the security descriptor
// with an nlength that is too long.
sa.nLength = sizeof(SECURITY_ATTRIBUTES) + 10;
lRes = RegCreateKeyExW(HKEY_CURRENT_USER, L"mykey2", 0, L"", 0,
KEY_READ | KEY_WRITE, &sa, &hkSub, &dwDisposition);
ok(lRes == ERROR_SUCCESS, "RegCreateKeyExW returned '%ld', expected 0", lRes);
ok(dwDisposition == REG_CREATED_NEW_KEY, "Should have created NEW key\n");
if (dwDisposition != REG_CREATED_NEW_KEY)
goto Cleanup;
// Test the -A function
lRes = RegCreateKeyExA(HKEY_CURRENT_USER, "mykey2", 0, "", 0,
KEY_READ | KEY_WRITE, &sa, &hkSub, &dwDisposition);
ok(lRes == ERROR_SUCCESS, "RegCreateKeyExA returned '%ld', expected 0", lRes);
ok(dwDisposition == REG_OPENED_EXISTING_KEY, "Should have opened EXISTING key\n");
if (dwDisposition != REG_OPENED_EXISTING_KEY)
goto Cleanup;
Cleanup:
if (pEveryoneSID)
FreeSid(pEveryoneSID);
if (pAdminSID)
FreeSid(pAdminSID);
if (pACL)
LocalFree(pACL);
if (pSD)
LocalFree(pSD);
if (hkSub)
RegCloseKey(hkSub);
// Delete the subkeys created for testing
ErrorCode = RegDeleteKeyW(HKEY_CURRENT_USER, L"mykey");
ok_dec(ErrorCode, ERROR_SUCCESS);
ErrorCode = RegDeleteKeyW(HKEY_CURRENT_USER, L"mykey1");
ok_dec(ErrorCode, ERROR_SUCCESS);
ErrorCode = RegDeleteKeyW(HKEY_CURRENT_USER, L"mykey2");
ok_dec(ErrorCode, ERROR_SUCCESS);
}