ReactOS 0.4.16-dev-197-g92996da
RegCreateKeyEx.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS api tests
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: Tests for RegCreateKeyExW.
5 * COPYRIGHT: Copyright 2023 Doug Lyons <douglyons@douglyons.com>
6 */
7
8/*
9 * Idea based loosely on code from the following:
10 * https://learn.microsoft.com/en-us/windows/win32/secauthz/creating-a-security-descriptor-for-a-new-object-in-c--
11 */
12
13#include <apitest.h>
14#include <stdio.h>
15
16#define WIN32_NO_STATUS
17#define _INC_WINDOWS
18#define COM_NO_WINDOWS_H
19#include <windef.h>
20#include <aclapi.h>
21
22
24{
26 DWORD dwRes, dwDisposition;
27 PACL pACL = NULL;
29 PSID pEveryoneSID = NULL, pAdminSID = NULL;
32 EXPLICIT_ACCESSW ea[2];
33 SECURITY_ATTRIBUTES sa = { 0 };
34 LONG lRes;
35 BOOL bRes;
36 LONG ErrorCode = 0;
37 HKEY hkSub = NULL;
38
39 // If any of the test keys already exist, delete them to ensure proper testing
41 {
46 {
47 skip("'HKCU\\mykey' cannot be deleted. Terminating test\n");
48 goto Cleanup;
49 }
50 }
51
53 {
58 {
59 skip("'HKCU\\mykey1' cannot be deleted. Terminating test\n");
60 goto Cleanup;
61 }
62 }
63
65 {
70 {
71 skip("'HKCU\\mykey2' cannot be deleted. Terminating test\n");
72 goto Cleanup;
73 }
74 }
75
76 // Setup GetLastError to known value for tests
77 SetLastError(0xdeadbeef);
78
79 // Create a well-known SID for the Everyone group.
80 bRes = AllocateAndInitializeSid(&SIDAuthWorld, 1,
82 0, 0, 0, 0, 0, 0, 0,
83 &pEveryoneSID);
84 ok(bRes, "AllocateAndInitializeSid Error %ld\n", GetLastError());
85 if (!bRes)
86 {
87 skip("EveryoneSID not initialized. Terminating test\n");
88 goto Cleanup;
89 }
90
91 // Initialize an EXPLICIT_ACCESS structure for an ACE.
92 // The ACE will allow Everyone read access to the key.
93 ZeroMemory(&ea, sizeof(ea));
99 ea[0].Trustee.ptstrName = pEveryoneSID;
100
101 // Create a SID for the BUILTIN\Administrators group.
102 bRes = AllocateAndInitializeSid(&SIDAuthNT, 2,
105 0, 0, 0, 0, 0, 0,
106 &pAdminSID);
107 ok(bRes, "AllocateAndInitializeSid Error %ld\n", GetLastError());
108 if (!bRes)
109 {
110 skip("AdminSID not initialized. Terminating test\n");
111 goto Cleanup;
112 }
113
114 // Initialize an EXPLICIT_ACCESS structure for an ACE.
115 // The ACE will allow the Administrators group full access to the key.
121 ea[1].Trustee.ptstrName = pAdminSID;
122
123 // Create a new ACL that contains the new ACEs.
124 dwRes = SetEntriesInAclW(_countof(ea), ea, NULL, &pACL);
125 ok(dwRes == ERROR_SUCCESS, "SetEntriesInAcl Error %ld\n", GetLastError());
126 if (dwRes != ERROR_SUCCESS)
127 goto Cleanup;
128
129 // Initialize a security descriptor.
131 ok(pSD != NULL, "LocalAlloc Error %ld\n", GetLastError());
132 if (pSD == NULL)
133 goto Cleanup;
134
136 ok(bRes, "InitializeSecurityDescriptor Error %ld\n", GetLastError());
137 if (!bRes)
138 goto Cleanup;
139
140 // Add the ACL to the security descriptor.
141 bRes = SetSecurityDescriptorDacl(pSD,
142 TRUE, // bDaclPresent flag
143 pACL,
144 FALSE); // not a default DACL
145 ok(bRes, "SetSecurityDescriptorDacl Error %ld\n", GetLastError());
146 if (!bRes)
147 goto Cleanup;
148
149 // Initialize a security attributes structure.
150 sa.lpSecurityDescriptor = pSD;
151 sa.bInheritHandle = FALSE;
152
153 // Use the security attributes to set the security descriptor
154 // with an nlength that is 0.
155 sa.nLength = 0;
156 lRes = RegCreateKeyExW(HKEY_CURRENT_USER, L"mykey", 0, L"", 0,
157 KEY_READ | KEY_WRITE, &sa, &hkSub, &dwDisposition);
158 ok(lRes == ERROR_SUCCESS, "RegCreateKeyExW returned '%ld', expected 0", lRes);
159 ok(dwDisposition == REG_CREATED_NEW_KEY, "Should have created NEW key\n");
160 if (dwDisposition != REG_CREATED_NEW_KEY)
161 goto Cleanup;
162
163 // Test the -A function
164 lRes = RegCreateKeyExA(HKEY_CURRENT_USER, "mykey", 0, "", 0,
165 KEY_READ | KEY_WRITE, &sa, &hkSub, &dwDisposition);
166 ok(lRes == ERROR_SUCCESS, "RegCreateKeyExA returned '%ld', expected 0", lRes);
167 ok(dwDisposition == REG_OPENED_EXISTING_KEY, "Should have opened EXISTING key\n");
168 if (dwDisposition != REG_OPENED_EXISTING_KEY)
169 goto Cleanup;
170
171 // Use the security attributes to set the security descriptor
172 // with an nlength that is too short, but not 0.
173 sa.nLength = sizeof(SECURITY_ATTRIBUTES) / 2;
174 lRes = RegCreateKeyExW(HKEY_CURRENT_USER, L"mykey1", 0, L"", 0,
175 KEY_READ | KEY_WRITE, &sa, &hkSub, &dwDisposition);
176 ok(lRes == ERROR_SUCCESS, "RegCreateKeyExW returned '%ld', expected 0", lRes);
177 ok(dwDisposition == REG_CREATED_NEW_KEY, "Should have created NEW key\n");
178 if (dwDisposition != REG_CREATED_NEW_KEY)
179 goto Cleanup;
180
181 // Test the -A function
182 lRes = RegCreateKeyExA(HKEY_CURRENT_USER, "mykey1", 0, "", 0,
183 KEY_READ | KEY_WRITE, &sa, &hkSub, &dwDisposition);
184 ok(lRes == ERROR_SUCCESS, "RegCreateKeyExA returned '%ld', expected 0", lRes);
185 ok(dwDisposition == REG_OPENED_EXISTING_KEY, "Should have opened EXISTING key\n");
186 if (dwDisposition != REG_OPENED_EXISTING_KEY)
187 goto Cleanup;
188
189 // Use the security attributes to set the security descriptor
190 // with an nlength that is too long.
191 sa.nLength = sizeof(SECURITY_ATTRIBUTES) + 10;
192 lRes = RegCreateKeyExW(HKEY_CURRENT_USER, L"mykey2", 0, L"", 0,
193 KEY_READ | KEY_WRITE, &sa, &hkSub, &dwDisposition);
194 ok(lRes == ERROR_SUCCESS, "RegCreateKeyExW returned '%ld', expected 0", lRes);
195 ok(dwDisposition == REG_CREATED_NEW_KEY, "Should have created NEW key\n");
196 if (dwDisposition != REG_CREATED_NEW_KEY)
197 goto Cleanup;
198
199 // Test the -A function
200 lRes = RegCreateKeyExA(HKEY_CURRENT_USER, "mykey2", 0, "", 0,
201 KEY_READ | KEY_WRITE, &sa, &hkSub, &dwDisposition);
202 ok(lRes == ERROR_SUCCESS, "RegCreateKeyExA returned '%ld', expected 0", lRes);
203 ok(dwDisposition == REG_OPENED_EXISTING_KEY, "Should have opened EXISTING key\n");
204 if (dwDisposition != REG_OPENED_EXISTING_KEY)
205 goto Cleanup;
206
207Cleanup:
208
209 if (pEveryoneSID)
210 FreeSid(pEveryoneSID);
211 if (pAdminSID)
212 FreeSid(pAdminSID);
213 if (pACL)
214 LocalFree(pACL);
215 if (pSD)
216 LocalFree(pSD);
217 if (hkSub)
218 RegCloseKey(hkSub);
219
220 // Delete the subkeys created for testing
223
226
229}
230
DWORD WINAPI SetEntriesInAclW(ULONG cCountOfExplicitEntries, PEXPLICIT_ACCESS_W pListOfExplicitEntries, PACL OldAcl, PACL *NewAcl)
Definition: ac.c:199
@ TRUSTEE_IS_SID
Definition: accctrl.h:189
@ TRUSTEE_IS_WELL_KNOWN_GROUP
Definition: accctrl.h:181
@ TRUSTEE_IS_GROUP
Definition: accctrl.h:178
#define NO_INHERITANCE
Definition: accctrl.h:103
@ SET_ACCESS
Definition: accctrl.h:150
static struct sockaddr_in sa
Definition: adnsresfilter.c:69
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define ok_dec(expression, result)
Definition: atltest.h:101
#define START_TEST(x)
Definition: atltest.h:75
#define RegCloseKey(hKey)
Definition: registry.h:49
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
LONG WINAPI RegCreateKeyExW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey, _In_ DWORD Reserved, _In_opt_ LPWSTR lpClass, _In_ DWORD dwOptions, _In_ REGSAM samDesired, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _Out_ PHKEY phkResult, _Out_opt_ LPDWORD lpdwDisposition)
Definition: reg.c:1096
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3333
LONG WINAPI RegDeleteKeyW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey)
Definition: reg.c:1239
LONG WINAPI RegCreateKeyExA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey, _In_ DWORD Reserved, _In_ LPSTR lpClass, _In_ DWORD dwOptions, _In_ REGSAM samDesired, _In_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _Out_ PHKEY phkResult, _Out_ LPDWORD lpdwDisposition)
Definition: reg.c:1034
BOOL WINAPI AllocateAndInitializeSid(PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority, BYTE nSubAuthorityCount, DWORD nSubAuthority0, DWORD nSubAuthority1, DWORD nSubAuthority2, DWORD nSubAuthority3, DWORD nSubAuthority4, DWORD nSubAuthority5, DWORD nSubAuthority6, DWORD nSubAuthority7, PSID *pSid)
Definition: security.c:674
BOOL WINAPI InitializeSecurityDescriptor(PSECURITY_DESCRIPTOR pSecurityDescriptor, DWORD dwRevision)
Definition: security.c:929
PVOID WINAPI FreeSid(PSID pSid)
Definition: security.c:698
struct _SECURITY_ATTRIBUTES SECURITY_ATTRIBUTES
#define SetLastError(x)
Definition: compat.h:752
static const WCHAR Cleanup[]
Definition: register.c:80
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
HLOCAL NTAPI LocalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:1390
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1594
static HKEY hkey_main
Definition: registry.c:37
_In_ NDIS_ERROR_CODE ErrorCode
Definition: ndis.h:4436
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define KEY_READ
Definition: nt_native.h:1023
#define REG_CREATED_NEW_KEY
Definition: nt_native.h:1084
#define KEY_WRITE
Definition: nt_native.h:1031
#define REG_OPENED_EXISTING_KEY
Definition: nt_native.h:1085
#define L(x)
Definition: ntvdm.h:50
long LONG
Definition: pedump.c:60
BOOL WINAPI SetSecurityDescriptorDacl(PSECURITY_DESCRIPTOR pSecurityDescriptor, BOOL bDaclPresent, PACL pDacl, BOOL bDaclDefaulted)
Definition: sec.c:262
#define _countof(array)
Definition: sndvol32.h:70
DWORD grfAccessPermissions
Definition: accctrl.h:340
DWORD grfInheritance
Definition: accctrl.h:342
TRUSTEE_W Trustee
Definition: accctrl.h:343
ACCESS_MODE grfAccessMode
Definition: accctrl.h:341
LPWSTR ptstrName
Definition: accctrl.h:217
TRUSTEE_TYPE TrusteeType
Definition: accctrl.h:216
TRUSTEE_FORM TrusteeForm
Definition: accctrl.h:215
#define ZeroMemory
Definition: winbase.h:1736
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define LPTR
Definition: winbase.h:406
#define HKEY_CURRENT_USER
Definition: winreg.h:11
#define RegCreateKeyEx
Definition: winreg.h:501
#define SECURITY_BUILTIN_DOMAIN_RID
Definition: setypes.h:581
#define SECURITY_WORLD_SID_AUTHORITY
Definition: setypes.h:527
#define SECURITY_WORLD_RID
Definition: setypes.h:541
#define SECURITY_NT_AUTHORITY
Definition: setypes.h:554
#define SECURITY_DESCRIPTOR_REVISION
Definition: setypes.h:58
#define SECURITY_DESCRIPTOR_MIN_LENGTH
Definition: setypes.h:815
#define DOMAIN_ALIAS_RID_ADMINS
Definition: setypes.h:652