[REACTOS] Fix 64 bit build (#465)
[reactos.git] / modules / rostests / apitests / ntdll / RtlFirstFreeAce.c
1 /*
2 * PROJECT: ReactOS API tests
3 * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory
4 * PURPOSE: Test for RtlFirstFreeAce
5 * PROGRAMMERS: Thomas Faber <thomas.faber@reactos.org>
6 */
7
8 #include "precomp.h"
9
10 static
11 PVOID
12 AllocateGuarded(
13 _In_ SIZE_T SizeRequested)
14 {
15 NTSTATUS Status;
16 SIZE_T Size = PAGE_ROUND_UP(SizeRequested + PAGE_SIZE);
17 PVOID VirtualMemory = NULL;
18 PCHAR StartOfBuffer;
19
20 Status = NtAllocateVirtualMemory(NtCurrentProcess(), &VirtualMemory, 0, &Size, MEM_RESERVE, PAGE_NOACCESS);
21
22 if (!NT_SUCCESS(Status))
23 return NULL;
24
25 Size -= PAGE_SIZE;
26 if (Size)
27 {
28 Status = NtAllocateVirtualMemory(NtCurrentProcess(), &VirtualMemory, 0, &Size, MEM_COMMIT, PAGE_READWRITE);
29 if (!NT_SUCCESS(Status))
30 {
31 Size = 0;
32 Status = NtFreeVirtualMemory(NtCurrentProcess(), &VirtualMemory, &Size, MEM_RELEASE);
33 ok(Status == STATUS_SUCCESS, "Status = %lx\n", Status);
34 return NULL;
35 }
36 }
37
38 StartOfBuffer = VirtualMemory;
39 StartOfBuffer += Size - SizeRequested;
40
41 return StartOfBuffer;
42 }
43
44 static
45 VOID
46 FreeGuarded(
47 _In_ PVOID Pointer)
48 {
49 NTSTATUS Status;
50 PVOID VirtualMemory = (PVOID)PAGE_ROUND_DOWN((SIZE_T)Pointer);
51 SIZE_T Size = 0;
52
53 Status = NtFreeVirtualMemory(NtCurrentProcess(), &VirtualMemory, &Size, MEM_RELEASE);
54 ok(Status == STATUS_SUCCESS, "Status = %lx\n", Status);
55 }
56
57 static
58 PACL
59 MakeAcl(
60 _In_ ULONG AceCount,
61 ...)
62 {
63 PACL Acl;
64 PACE_HEADER AceHeader;
65 ULONG AclSize;
66 ULONG AceSizes[10];
67 ULONG i;
68 va_list Args;
69
70 ASSERT(AceCount <= RTL_NUMBER_OF(AceSizes));
71 AclSize = sizeof(ACL);
72 va_start(Args, AceCount);
73 for (i = 0; i < AceCount; i++)
74 {
75 AceSizes[i] = va_arg(Args, int);
76 AclSize += AceSizes[i];
77 }
78 va_end(Args);
79
80 Acl = AllocateGuarded(AclSize);
81 if (!Acl)
82 {
83 skip("Failed to allocate %lu bytes\n", AclSize);
84 return NULL;
85 }
86
87 Acl->AclRevision = ACL_REVISION;
88 Acl->Sbz1 = 0;
89 Acl->AclSize = AclSize;
90 Acl->AceCount = AceCount;
91 Acl->Sbz2 = 0;
92
93 AceHeader = (PACE_HEADER)(Acl + 1);
94 for (i = 0; i < AceCount; i++)
95 {
96 AceHeader->AceType = 0;
97 AceHeader->AceFlags = 0;
98 AceHeader->AceSize = AceSizes[i];
99 AceHeader = (PACE_HEADER)((PCHAR)AceHeader + AceHeader->AceSize);
100 }
101
102 return Acl;
103 }
104
105 START_TEST(RtlFirstFreeAce)
106 {
107 PACL Acl;
108 PACE FirstAce;
109 BOOLEAN Found;
110
111 Acl = MakeAcl(0);
112 if (Acl)
113 {
114 /* Simple empty ACL */
115 FirstAce = InvalidPointer;
116 Found = RtlFirstFreeAce(Acl, &FirstAce);
117 ok(Found == TRUE, "Found = %u\n", Found);
118 ok(FirstAce == (PACE)(Acl + 1), "FirstAce = %p (Acl was %p)\n", FirstAce, Acl);
119
120 /* Not enough space */
121 Acl->AclSize = sizeof(ACL) - 1;
122 FirstAce = InvalidPointer;
123 Found = RtlFirstFreeAce(Acl, &FirstAce);
124 ok(Found == TRUE, "Found = %u\n", Found);
125 ok(FirstAce == NULL, "FirstAce = %p (Acl was %p)\n", FirstAce, Acl);
126
127 /* Invalid values for all the other fields */
128 Acl->AclRevision = 76;
129 Acl->Sbz1 = 0x55;
130 Acl->AclSize = sizeof(ACL);
131 Acl->Sbz2 = 0x55;
132 FirstAce = InvalidPointer;
133 Found = RtlFirstFreeAce(Acl, &FirstAce);
134 ok(Found == TRUE, "Found = %u\n", Found);
135 ok(FirstAce == (PACE)(Acl + 1), "FirstAce = %p (Acl was %p)\n", FirstAce, Acl);
136
137 FreeGuarded(Acl);
138 }
139
140 Acl = MakeAcl(1, (int)sizeof(ACE_HEADER));
141 if (Acl)
142 {
143 /* ACL with one ACE */
144 FirstAce = InvalidPointer;
145 Found = RtlFirstFreeAce(Acl, &FirstAce);
146 ok(Found == TRUE, "Found = %u\n", Found);
147 ok(FirstAce == (PACE)((PACE_HEADER)(Acl + 1) + 1), "FirstAce = %p (Acl was %p)\n", FirstAce, Acl);
148
149 /* The one ACE doesn't actually fit */
150 Acl->AclSize = sizeof(ACL);
151 FirstAce = InvalidPointer;
152 Found = RtlFirstFreeAce(Acl, &FirstAce);
153 ok(Found == FALSE, "Found = %u\n", Found);
154 ok(FirstAce == NULL, "FirstAce = %p (Acl was %p)\n", FirstAce, Acl);
155
156 /* Only the first byte fits */
157 Acl->AclSize = sizeof(ACL) + 1;
158 FirstAce = InvalidPointer;
159 Found = RtlFirstFreeAce(Acl, &FirstAce);
160 ok(Found == TRUE, "Found = %u\n", Found);
161 ok(FirstAce == NULL, "FirstAce = %p (Acl was %p)\n", FirstAce, Acl);
162
163 /* Until we cover the whole size we get NULL */
164 Acl->AclSize = sizeof(ACL) + sizeof(ACE_HEADER) - 1;
165 FirstAce = InvalidPointer;
166 Found = RtlFirstFreeAce(Acl, &FirstAce);
167 ok(Found == TRUE, "Found = %u\n", Found);
168 ok(FirstAce == NULL, "FirstAce = %p (Acl was %p)\n", FirstAce, Acl);
169
170 FreeGuarded(Acl);
171 }
172
173 /* Same but bigger */
174 Acl = MakeAcl(1, (int)sizeof(ACE_HEADER) + 4);
175 if (Acl)
176 {
177 /* ACL with one ACE */
178 FirstAce = InvalidPointer;
179 Found = RtlFirstFreeAce(Acl, &FirstAce);
180 ok(Found == TRUE, "Found = %u\n", Found);
181 ok(FirstAce == (PACE)((PCHAR)(Acl + 1) + sizeof(ACE_HEADER) + 4), "FirstAce = %p (Acl was %p)\n", FirstAce, Acl);
182
183 /* The one ACE doesn't actually fit */
184 Acl->AclSize = sizeof(ACL);
185 FirstAce = InvalidPointer;
186 Found = RtlFirstFreeAce(Acl, &FirstAce);
187 ok(Found == FALSE, "Found = %u\n", Found);
188 ok(FirstAce == NULL, "FirstAce = %p (Acl was %p)\n", FirstAce, Acl);
189
190 /* Only the first byte fits */
191 Acl->AclSize = sizeof(ACL) + 1;
192 FirstAce = InvalidPointer;
193 Found = RtlFirstFreeAce(Acl, &FirstAce);
194 ok(Found == TRUE, "Found = %u\n", Found);
195 ok(FirstAce == NULL, "FirstAce = %p (Acl was %p)\n", FirstAce, Acl);
196
197 /* Until we cover the whole size we get NULL */
198 Acl->AclSize = sizeof(ACL) + sizeof(ACE_HEADER) - 3;
199 FirstAce = InvalidPointer;
200 Found = RtlFirstFreeAce(Acl, &FirstAce);
201 ok(Found == TRUE, "Found = %u\n", Found);
202 ok(FirstAce == NULL, "FirstAce = %p (Acl was %p)\n", FirstAce, Acl);
203
204 FreeGuarded(Acl);
205 }
206
207 Acl = MakeAcl(4, (int)sizeof(ACE_HEADER), (int)sizeof(ACE_HEADER), (int)sizeof(ACCESS_ALLOWED_ACE), (int)sizeof(ACCESS_ALLOWED_ACE));
208 if (Acl)
209 {
210 /* ACL with one ACE */
211 FirstAce = InvalidPointer;
212 Found = RtlFirstFreeAce(Acl, &FirstAce);
213 ok(Found == TRUE, "Found = %u\n", Found);
214 ok(FirstAce == (PACE)((PCHAR)(Acl + 1) + 2 * sizeof(ACE_HEADER) + 2 * sizeof(ACCESS_ALLOWED_ACE)), "FirstAce = %p (Acl was %p)\n", FirstAce, Acl);
215
216 /* One less gives us NULL */
217 Acl->AclSize = sizeof(ACL) + 2 * sizeof(ACE_HEADER) + 2 * sizeof(ACCESS_ALLOWED_ACE) - 1;
218 FirstAce = InvalidPointer;
219 Found = RtlFirstFreeAce(Acl, &FirstAce);
220 ok(Found == TRUE, "Found = %u\n", Found);
221 ok(FirstAce == NULL, "FirstAce = %p (Acl was %p)\n", FirstAce, Acl);
222
223 /* One ACE less also gives us FALSE */
224 Acl->AclSize = sizeof(ACL) + 2 * sizeof(ACE_HEADER) + sizeof(ACCESS_ALLOWED_ACE);
225 FirstAce = InvalidPointer;
226 Found = RtlFirstFreeAce(Acl, &FirstAce);
227 ok(Found == FALSE, "Found = %u\n", Found);
228 ok(FirstAce == NULL, "FirstAce = %p (Acl was %p)\n", FirstAce, Acl);
229
230 FreeGuarded(Acl);
231 }
232 }