https://git.reactos.org/?p=reactos.git;a=commitdiff;h=40233a364435882d9c361…
commit 40233a364435882d9c361b9065c0ab2dc5380157
Author: Doug Lyons <douglyons(a)douglyons.com>
AuthorDate: Thu Jun 29 14:33:44 2023 -0500
Commit: GitHub <noreply(a)github.com>
CommitDate: Thu Jun 29 21:33:44 2023 +0200
[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
---
modules/rostests/apitests/advapi32/CMakeLists.txt | 1 +
.../rostests/apitests/advapi32/RegCreateKeyEx.c | 230 +++++++++++++++++++++
modules/rostests/apitests/advapi32/testlist.c | 2 +
3 files changed, 233 insertions(+)
diff --git a/modules/rostests/apitests/advapi32/CMakeLists.txt
b/modules/rostests/apitests/advapi32/CMakeLists.txt
index c5bccc3b0d0..8a9bab7abd6 100644
--- a/modules/rostests/apitests/advapi32/CMakeLists.txt
+++ b/modules/rostests/apitests/advapi32/CMakeLists.txt
@@ -7,6 +7,7 @@ list(APPEND SOURCE
IsTextUnicode.c
LockServiceDatabase.c
QueryServiceConfig2.c
+ RegCreateKeyEx.c
RegEnumKey.c
RegEnumValueW.c
RegOpenKeyExW.c
diff --git a/modules/rostests/apitests/advapi32/RegCreateKeyEx.c
b/modules/rostests/apitests/advapi32/RegCreateKeyEx.c
new file mode 100644
index 00000000000..18ffd88c779
--- /dev/null
+++ b/modules/rostests/apitests/advapi32/RegCreateKeyEx.c
@@ -0,0 +1,230 @@
+/*
+ * 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(a)douglyons.com>
+ */
+
+/*
+ * Idea based loosely on code from the following:
+ *
https://learn.microsoft.com/en-us/windows/win32/secauthz/creating-a-securit…
+ */
+
+#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);
+}
+
diff --git a/modules/rostests/apitests/advapi32/testlist.c
b/modules/rostests/apitests/advapi32/testlist.c
index dadd2f6ac18..67764a03204 100644
--- a/modules/rostests/apitests/advapi32/testlist.c
+++ b/modules/rostests/apitests/advapi32/testlist.c
@@ -10,6 +10,7 @@ extern void func_HKEY_CLASSES_ROOT(void);
extern void func_IsTextUnicode(void);
extern void func_LockServiceDatabase(void);
extern void func_QueryServiceConfig2(void);
+extern void func_RegCreateKeyEx(void);
extern void func_RegEnumKey(void);
extern void func_RegEnumValueW(void);
extern void func_RegOpenKeyExW(void);
@@ -30,6 +31,7 @@ const struct test winetest_testlist[] =
{ "IsTextUnicode" , func_IsTextUnicode },
{ "LockServiceDatabase" , func_LockServiceDatabase },
{ "QueryServiceConfig2", func_QueryServiceConfig2 },
+ { "RegCreateKeyEx", func_RegCreateKeyEx },
{ "RegEnumKey", func_RegEnumKey },
{ "RegEnumValueW", func_RegEnumValueW },
{ "RegQueryInfoKey", func_RegQueryInfoKey },