[EXPLORER] -Use WM_POPUPSYSTEMMENU to open the system menu of a window. CORE-13400
[reactos.git] / rostests / apitests / ntdll / RtlDeleteAce.c
1 /*
2 * PROJECT: ReactOS API tests
3 * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory
4 * PURPOSE: Test for RtlDeleteAce
5 * PROGRAMMERS: Thomas Faber <thomas.faber@reactos.org>
6 */
7
8 #include <apitest.h>
9 #include <ndk/mmfuncs.h>
10 #include <ndk/rtlfuncs.h>
11
12 static
13 PVOID
14 AllocateGuarded(
15 _In_ SIZE_T SizeRequested)
16 {
17 NTSTATUS Status;
18 SIZE_T Size = PAGE_ROUND_UP(SizeRequested + PAGE_SIZE);
19 PVOID VirtualMemory = NULL;
20 PCHAR StartOfBuffer;
21
22 Status = NtAllocateVirtualMemory(NtCurrentProcess(), &VirtualMemory, 0, &Size, MEM_RESERVE, PAGE_NOACCESS);
23
24 if (!NT_SUCCESS(Status))
25 return NULL;
26
27 Size -= PAGE_SIZE;
28 if (Size)
29 {
30 Status = NtAllocateVirtualMemory(NtCurrentProcess(), &VirtualMemory, 0, &Size, MEM_COMMIT, PAGE_READWRITE);
31 if (!NT_SUCCESS(Status))
32 {
33 Size = 0;
34 Status = NtFreeVirtualMemory(NtCurrentProcess(), &VirtualMemory, &Size, MEM_RELEASE);
35 ok(Status == STATUS_SUCCESS, "Status = %lx\n", Status);
36 return NULL;
37 }
38 }
39
40 StartOfBuffer = VirtualMemory;
41 StartOfBuffer += Size - SizeRequested;
42
43 return StartOfBuffer;
44 }
45
46 static
47 VOID
48 FreeGuarded(
49 _In_ PVOID Pointer)
50 {
51 NTSTATUS Status;
52 PVOID VirtualMemory = (PVOID)PAGE_ROUND_DOWN((SIZE_T)Pointer);
53 SIZE_T Size = 0;
54
55 Status = NtFreeVirtualMemory(NtCurrentProcess(), &VirtualMemory, &Size, MEM_RELEASE);
56 ok(Status == STATUS_SUCCESS, "Status = %lx\n", Status);
57 }
58
59 static
60 PACL
61 MakeAcl(
62 _In_ ULONG AceCount,
63 ...)
64 {
65 PACL Acl;
66 PACE_HEADER AceHeader;
67 ULONG AclSize;
68 ULONG AceSizes[10];
69 ULONG i;
70 va_list Args;
71
72 ASSERT(AceCount <= RTL_NUMBER_OF(AceSizes));
73 AclSize = sizeof(ACL);
74 va_start(Args, AceCount);
75 for (i = 0; i < AceCount; i++)
76 {
77 AceSizes[i] = va_arg(Args, int);
78 AclSize += AceSizes[i];
79 }
80 va_end(Args);
81
82 Acl = AllocateGuarded(AclSize);
83 if (!Acl)
84 {
85 skip("Failed to allocate %lu bytes\n", AclSize);
86 return NULL;
87 }
88
89 Acl->AclRevision = ACL_REVISION;
90 Acl->Sbz1 = 0;
91 Acl->AclSize = AclSize;
92 Acl->AceCount = AceCount;
93 Acl->Sbz2 = 0;
94
95 AceHeader = (PACE_HEADER)(Acl + 1);
96 for (i = 0; i < AceCount; i++)
97 {
98 AceHeader->AceType = 0;
99 AceHeader->AceFlags = 0;
100 AceHeader->AceSize = AceSizes[i];
101 AceHeader = (PACE_HEADER)((PCHAR)AceHeader + AceHeader->AceSize);
102 }
103
104 return Acl;
105 }
106
107 START_TEST(RtlDeleteAce)
108 {
109 PACL Acl;
110 PACCESS_ALLOWED_ACE Ace;
111 ULONG AceSize;
112 PISID Sid;
113 NTSTATUS Status;
114 int i;
115
116 Acl = MakeAcl(0);
117 if (Acl)
118 {
119 ok(RtlValidAcl(Acl), "Acl is invalid\n");
120
121 /* There is no first ACE -- should stay untouched */
122 Status = RtlDeleteAce(Acl, 0);
123 ok(Status == STATUS_INVALID_PARAMETER, "Status = %lx\n", Status);
124 ok(Acl->AclSize == sizeof(ACL), "AclSize = %u\n", Acl->AclSize);
125 ok(Acl->AceCount == 0, "AceCount = %u\n", Acl->AceCount);
126
127 /* Index -1 -- should stay untouched */
128 Status = RtlDeleteAce(Acl, 0xFFFFFFFF);
129 ok(Status == STATUS_INVALID_PARAMETER, "Status = %lx\n", Status);
130 FreeGuarded(Acl);
131 }
132
133 AceSize = FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + FIELD_OFFSET(SID, SubAuthority);
134 Acl = MakeAcl(1, (int)AceSize);
135 if (Acl)
136 {
137 Ace = (PACCESS_ALLOWED_ACE)(Acl + 1);
138 Ace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
139 Sid = (PISID)&Ace->SidStart;
140 Sid->Revision = SID_REVISION;
141 Sid->SubAuthorityCount = 0;
142 RtlZeroMemory(&Sid->IdentifierAuthority, sizeof(Sid->IdentifierAuthority));
143
144 ok(RtlValidAcl(Acl), "Acl is invalid\n");
145
146 /* Out of bounds delete -- should stay untouched */
147 Status = RtlDeleteAce(Acl, 1);
148 ok(Status == STATUS_INVALID_PARAMETER, "Status = %lx\n", Status);
149 ok(Acl->AclSize == sizeof(ACL) + AceSize, "AclSize = %u\n", Acl->AclSize);
150 ok(Acl->AceCount == 1, "AceCount = %u\n", Acl->AceCount);
151 ok(Ace->Header.AceSize == AceSize, "AceSize = %u\n", Ace->Header.AceSize);
152
153 /* Index -1 -- should stay untouched */
154 Status = RtlDeleteAce(Acl, 0xFFFFFFFF);
155 ok(Status == STATUS_INVALID_PARAMETER, "Status = %lx\n", Status);
156 ok(Acl->AclSize == sizeof(ACL) + AceSize, "AclSize = %u\n", Acl->AclSize);
157 ok(Acl->AceCount == 1, "AceCount = %u\n", Acl->AceCount);
158 ok(Ace->Header.AceSize == AceSize, "AceSize = %u\n", Ace->Header.AceSize);
159
160 /* Delete the first (and only) ACE */
161 Status = RtlDeleteAce(Acl, 0);
162 ok(Status == STATUS_SUCCESS, "Status = %lx\n", Status);
163 ok(Acl->AclSize == sizeof(ACL) + AceSize, "AclSize = %u\n", Acl->AclSize);
164 ok(Acl->AceCount == 0, "AceCount = %u\n", Acl->AceCount);
165 ok(Ace->Header.AceSize == 0, "AceSize = %u\n", Ace->Header.AceSize);
166 FreeGuarded(Acl);
167 }
168
169 AceSize = FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + FIELD_OFFSET(SID, SubAuthority[1]);
170 Acl = MakeAcl(4, (int)AceSize, (int)AceSize + 4, (int)AceSize + 8, (int)AceSize + 12);
171 if (Acl)
172 {
173 Ace = (PACCESS_ALLOWED_ACE)(Acl + 1);
174 for (i = 0; i < 4; i++)
175 {
176 Ace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
177 Sid = (PISID)&Ace->SidStart;
178 Sid->Revision = SID_REVISION;
179 Sid->SubAuthorityCount = 0;
180 RtlZeroMemory(&Sid->IdentifierAuthority, sizeof(Sid->IdentifierAuthority));
181 Ace = (PACCESS_ALLOWED_ACE)((PCHAR)Ace + Ace->Header.AceSize);
182 }
183
184 ok(RtlValidAcl(Acl), "Acl is invalid\n");
185
186 /* Out of bounds delete -- should stay untouched */
187 Status = RtlDeleteAce(Acl, 4);
188 ok(Status == STATUS_INVALID_PARAMETER, "Status = %lx\n", Status);
189 ok(Acl->AclSize == sizeof(ACL) + 4 * AceSize + 24, "AclSize = %u\n", Acl->AclSize);
190 ok(Acl->AceCount == 4, "AceCount = %u\n", Acl->AceCount);
191 Ace = (PACCESS_ALLOWED_ACE)(Acl + 1);
192 ok(Ace->Header.AceSize == AceSize, "AceSize = %u\n", Ace->Header.AceSize);
193 Ace = (PACCESS_ALLOWED_ACE)((PCHAR)Ace + Ace->Header.AceSize);
194 ok(Ace->Header.AceSize == AceSize + 4, "AceSize = %u\n", Ace->Header.AceSize);
195 Ace = (PACCESS_ALLOWED_ACE)((PCHAR)Ace + Ace->Header.AceSize);
196 ok(Ace->Header.AceSize == AceSize + 8, "AceSize = %u\n", Ace->Header.AceSize);
197 Ace = (PACCESS_ALLOWED_ACE)((PCHAR)Ace + Ace->Header.AceSize);
198 ok(Ace->Header.AceSize == AceSize + 12, "AceSize = %u\n", Ace->Header.AceSize);
199
200 /* Index -1 -- should stay untouched */
201 Status = RtlDeleteAce(Acl, 0xFFFFFFFF);
202 ok(Status == STATUS_INVALID_PARAMETER, "Status = %lx\n", Status);
203 ok(Acl->AclSize == sizeof(ACL) + 4 * AceSize + 24, "AclSize = %u\n", Acl->AclSize);
204 ok(Acl->AceCount == 4, "AceCount = %u\n", Acl->AceCount);
205 Ace = (PACCESS_ALLOWED_ACE)(Acl + 1);
206 ok(Ace->Header.AceSize == AceSize, "AceSize = %u\n", Ace->Header.AceSize);
207 Ace = (PACCESS_ALLOWED_ACE)((PCHAR)Ace + Ace->Header.AceSize);
208 ok(Ace->Header.AceSize == AceSize + 4, "AceSize = %u\n", Ace->Header.AceSize);
209 Ace = (PACCESS_ALLOWED_ACE)((PCHAR)Ace + Ace->Header.AceSize);
210 ok(Ace->Header.AceSize == AceSize + 8, "AceSize = %u\n", Ace->Header.AceSize);
211 Ace = (PACCESS_ALLOWED_ACE)((PCHAR)Ace + Ace->Header.AceSize);
212 ok(Ace->Header.AceSize == AceSize + 12, "AceSize = %u\n", Ace->Header.AceSize);
213
214 /* Delete the last ACE */
215 Status = RtlDeleteAce(Acl, 3);
216 ok(Status == STATUS_SUCCESS, "Status = %lx\n", Status);
217 ok(Acl->AclSize == sizeof(ACL) + 4 * AceSize + 24, "AclSize = %u\n", Acl->AclSize);
218 ok(Acl->AceCount == 3, "AceCount = %u\n", Acl->AceCount);
219 Ace = (PACCESS_ALLOWED_ACE)(Acl + 1);
220 ok(Ace->Header.AceSize == AceSize, "AceSize = %u\n", Ace->Header.AceSize);
221 Ace = (PACCESS_ALLOWED_ACE)((PCHAR)Ace + Ace->Header.AceSize);
222 ok(Ace->Header.AceSize == AceSize + 4, "AceSize = %u\n", Ace->Header.AceSize);
223 Ace = (PACCESS_ALLOWED_ACE)((PCHAR)Ace + Ace->Header.AceSize);
224 ok(Ace->Header.AceSize == AceSize + 8, "AceSize = %u\n", Ace->Header.AceSize);
225 Ace = (PACCESS_ALLOWED_ACE)((PCHAR)Ace + Ace->Header.AceSize);
226 ok(Ace->Header.AceSize == 0, "AceSize = %u\n", Ace->Header.AceSize);
227
228 /* Delete the second ACE */
229 Status = RtlDeleteAce(Acl, 1);
230 ok(Status == STATUS_SUCCESS, "Status = %lx\n", Status);
231 ok(Acl->AclSize == sizeof(ACL) + 4 * AceSize + 24, "AclSize = %u\n", Acl->AclSize);
232 ok(Acl->AceCount == 2, "AceCount = %u\n", Acl->AceCount);
233 Ace = (PACCESS_ALLOWED_ACE)(Acl + 1);
234 ok(Ace->Header.AceSize == AceSize, "AceSize = %u\n", Ace->Header.AceSize);
235 Ace = (PACCESS_ALLOWED_ACE)((PCHAR)Ace + Ace->Header.AceSize);
236 ok(Ace->Header.AceSize == AceSize + 8, "AceSize = %u\n", Ace->Header.AceSize);
237 Ace = (PACCESS_ALLOWED_ACE)((PCHAR)Ace + Ace->Header.AceSize);
238 ok(Ace->Header.AceSize == 0, "AceSize = %u\n", Ace->Header.AceSize);
239
240 /* Delete the first ACE */
241 Status = RtlDeleteAce(Acl, 0);
242 ok(Status == STATUS_SUCCESS, "Status = %lx\n", Status);
243 ok(Acl->AclSize == sizeof(ACL) + 4 * AceSize + 24, "AclSize = %u\n", Acl->AclSize);
244 ok(Acl->AceCount == 1, "AceCount = %u\n", Acl->AceCount);
245 Ace = (PACCESS_ALLOWED_ACE)(Acl + 1);
246 ok(Ace->Header.AceSize == AceSize + 8, "AceSize = %u\n", Ace->Header.AceSize);
247 Ace = (PACCESS_ALLOWED_ACE)((PCHAR)Ace + Ace->Header.AceSize);
248 ok(Ace->Header.AceSize == 0, "AceSize = %u\n", Ace->Header.AceSize);
249
250 /* Delete the remaining ACE */
251 Status = RtlDeleteAce(Acl, 0);
252 ok(Status == STATUS_SUCCESS, "Status = %lx\n", Status);
253 ok(Acl->AclSize == sizeof(ACL) + 4 * AceSize + 24, "AclSize = %u\n", Acl->AclSize);
254 ok(Acl->AceCount == 0, "AceCount = %u\n", Acl->AceCount);
255 Ace = (PACCESS_ALLOWED_ACE)(Acl + 1);
256 ok(Ace->Header.AceSize == 0, "AceSize = %u\n", Ace->Header.AceSize);
257
258 FreeGuarded(Acl);
259 }
260 }