Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231/* * 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);}