1c2c66affSColin Finck /*
2c2c66affSColin Finck  * PROJECT:         ReactOS API tests
3c2c66affSColin Finck  * LICENSE:         LGPLv2.1+ - See COPYING.LIB in the top level directory
4c2c66affSColin Finck  * PURPOSE:         Test for RtlFirstFreeAce
5c2c66affSColin Finck  * PROGRAMMERS:     Thomas Faber <thomas.faber@reactos.org>
6c2c66affSColin Finck  */
7c2c66affSColin Finck 
8*283bbe73SAmine Khaldi #include "precomp.h"
9c2c66affSColin Finck 
10c2c66affSColin Finck static
11c2c66affSColin Finck PACL
MakeAcl(_In_ ULONG AceCount,...)12c2c66affSColin Finck MakeAcl(
13c2c66affSColin Finck     _In_ ULONG AceCount,
14c2c66affSColin Finck     ...)
15c2c66affSColin Finck {
16c2c66affSColin Finck     PACL Acl;
17c2c66affSColin Finck     PACE_HEADER AceHeader;
18c2c66affSColin Finck     ULONG AclSize;
19c2c66affSColin Finck     ULONG AceSizes[10];
20c2c66affSColin Finck     ULONG i;
21c2c66affSColin Finck     va_list Args;
22c2c66affSColin Finck 
23c2c66affSColin Finck     ASSERT(AceCount <= RTL_NUMBER_OF(AceSizes));
24c2c66affSColin Finck     AclSize = sizeof(ACL);
25c2c66affSColin Finck     va_start(Args, AceCount);
26c2c66affSColin Finck     for (i = 0; i < AceCount; i++)
27c2c66affSColin Finck     {
28c2c66affSColin Finck         AceSizes[i] = va_arg(Args, int);
29c2c66affSColin Finck         AclSize += AceSizes[i];
30c2c66affSColin Finck     }
31c2c66affSColin Finck     va_end(Args);
32c2c66affSColin Finck 
33c2c66affSColin Finck     Acl = AllocateGuarded(AclSize);
34c2c66affSColin Finck     if (!Acl)
35c2c66affSColin Finck     {
36c2c66affSColin Finck         skip("Failed to allocate %lu bytes\n", AclSize);
37c2c66affSColin Finck         return NULL;
38c2c66affSColin Finck     }
39c2c66affSColin Finck 
40c2c66affSColin Finck     Acl->AclRevision = ACL_REVISION;
41c2c66affSColin Finck     Acl->Sbz1 = 0;
42c2c66affSColin Finck     Acl->AclSize = AclSize;
43c2c66affSColin Finck     Acl->AceCount = AceCount;
44c2c66affSColin Finck     Acl->Sbz2 = 0;
45c2c66affSColin Finck 
46c2c66affSColin Finck     AceHeader = (PACE_HEADER)(Acl + 1);
47c2c66affSColin Finck     for (i = 0; i < AceCount; i++)
48c2c66affSColin Finck     {
49c2c66affSColin Finck         AceHeader->AceType = 0;
50c2c66affSColin Finck         AceHeader->AceFlags = 0;
51c2c66affSColin Finck         AceHeader->AceSize = AceSizes[i];
52c2c66affSColin Finck         AceHeader = (PACE_HEADER)((PCHAR)AceHeader + AceHeader->AceSize);
53c2c66affSColin Finck     }
54c2c66affSColin Finck 
55c2c66affSColin Finck     return Acl;
56c2c66affSColin Finck }
57c2c66affSColin Finck 
START_TEST(RtlFirstFreeAce)58c2c66affSColin Finck START_TEST(RtlFirstFreeAce)
59c2c66affSColin Finck {
60c2c66affSColin Finck     PACL Acl;
61c2c66affSColin Finck     PACE FirstAce;
62c2c66affSColin Finck     BOOLEAN Found;
63c2c66affSColin Finck 
64c2c66affSColin Finck     Acl = MakeAcl(0);
65c2c66affSColin Finck     if (Acl)
66c2c66affSColin Finck     {
67c2c66affSColin Finck         /* Simple empty ACL */
68c2c66affSColin Finck         FirstAce = InvalidPointer;
69c2c66affSColin Finck         Found = RtlFirstFreeAce(Acl, &FirstAce);
70c2c66affSColin Finck         ok(Found == TRUE, "Found = %u\n", Found);
71c2c66affSColin Finck         ok(FirstAce == (PACE)(Acl + 1), "FirstAce = %p (Acl was %p)\n", FirstAce, Acl);
72c2c66affSColin Finck 
73c2c66affSColin Finck         /* Not enough space */
74c2c66affSColin Finck         Acl->AclSize = sizeof(ACL) - 1;
75c2c66affSColin Finck         FirstAce = InvalidPointer;
76c2c66affSColin Finck         Found = RtlFirstFreeAce(Acl, &FirstAce);
77c2c66affSColin Finck         ok(Found == TRUE, "Found = %u\n", Found);
78c2c66affSColin Finck         ok(FirstAce == NULL, "FirstAce = %p (Acl was %p)\n", FirstAce, Acl);
79c2c66affSColin Finck 
80c2c66affSColin Finck         /* Invalid values for all the other fields */
81c2c66affSColin Finck         Acl->AclRevision = 76;
82c2c66affSColin Finck         Acl->Sbz1 = 0x55;
83c2c66affSColin Finck         Acl->AclSize = sizeof(ACL);
84c2c66affSColin Finck         Acl->Sbz2 = 0x55;
85c2c66affSColin Finck         FirstAce = InvalidPointer;
86c2c66affSColin Finck         Found = RtlFirstFreeAce(Acl, &FirstAce);
87c2c66affSColin Finck         ok(Found == TRUE, "Found = %u\n", Found);
88c2c66affSColin Finck         ok(FirstAce == (PACE)(Acl + 1), "FirstAce = %p (Acl was %p)\n", FirstAce, Acl);
89c2c66affSColin Finck 
90c2c66affSColin Finck         FreeGuarded(Acl);
91c2c66affSColin Finck     }
92c2c66affSColin Finck 
93c2c66affSColin Finck     Acl = MakeAcl(1, (int)sizeof(ACE_HEADER));
94c2c66affSColin Finck     if (Acl)
95c2c66affSColin Finck     {
96c2c66affSColin Finck         /* ACL with one ACE */
97c2c66affSColin Finck         FirstAce = InvalidPointer;
98c2c66affSColin Finck         Found = RtlFirstFreeAce(Acl, &FirstAce);
99c2c66affSColin Finck         ok(Found == TRUE, "Found = %u\n", Found);
100c2c66affSColin Finck         ok(FirstAce == (PACE)((PACE_HEADER)(Acl + 1) + 1), "FirstAce = %p (Acl was %p)\n", FirstAce, Acl);
101c2c66affSColin Finck 
102c2c66affSColin Finck         /* The one ACE doesn't actually fit */
103c2c66affSColin Finck         Acl->AclSize = sizeof(ACL);
104c2c66affSColin Finck         FirstAce = InvalidPointer;
105c2c66affSColin Finck         Found = RtlFirstFreeAce(Acl, &FirstAce);
106c2c66affSColin Finck         ok(Found == FALSE, "Found = %u\n", Found);
107c2c66affSColin Finck         ok(FirstAce == NULL, "FirstAce = %p (Acl was %p)\n", FirstAce, Acl);
108c2c66affSColin Finck 
109c2c66affSColin Finck         /* Only the first byte fits */
110c2c66affSColin Finck         Acl->AclSize = sizeof(ACL) + 1;
111c2c66affSColin Finck         FirstAce = InvalidPointer;
112c2c66affSColin Finck         Found = RtlFirstFreeAce(Acl, &FirstAce);
113c2c66affSColin Finck         ok(Found == TRUE, "Found = %u\n", Found);
114c2c66affSColin Finck         ok(FirstAce == NULL, "FirstAce = %p (Acl was %p)\n", FirstAce, Acl);
115c2c66affSColin Finck 
116c2c66affSColin Finck         /* Until we cover the whole size we get NULL */
117c2c66affSColin Finck         Acl->AclSize = sizeof(ACL) + sizeof(ACE_HEADER) - 1;
118c2c66affSColin Finck         FirstAce = InvalidPointer;
119c2c66affSColin Finck         Found = RtlFirstFreeAce(Acl, &FirstAce);
120c2c66affSColin Finck         ok(Found == TRUE, "Found = %u\n", Found);
121c2c66affSColin Finck         ok(FirstAce == NULL, "FirstAce = %p (Acl was %p)\n", FirstAce, Acl);
122c2c66affSColin Finck 
123c2c66affSColin Finck         FreeGuarded(Acl);
124c2c66affSColin Finck     }
125c2c66affSColin Finck 
126c2c66affSColin Finck     /* Same but bigger */
127c2c66affSColin Finck     Acl = MakeAcl(1, (int)sizeof(ACE_HEADER) + 4);
128c2c66affSColin Finck     if (Acl)
129c2c66affSColin Finck     {
130c2c66affSColin Finck         /* ACL with one ACE */
131c2c66affSColin Finck         FirstAce = InvalidPointer;
132c2c66affSColin Finck         Found = RtlFirstFreeAce(Acl, &FirstAce);
133c2c66affSColin Finck         ok(Found == TRUE, "Found = %u\n", Found);
134c2c66affSColin Finck         ok(FirstAce == (PACE)((PCHAR)(Acl + 1) + sizeof(ACE_HEADER) + 4), "FirstAce = %p (Acl was %p)\n", FirstAce, Acl);
135c2c66affSColin Finck 
136c2c66affSColin Finck         /* The one ACE doesn't actually fit */
137c2c66affSColin Finck         Acl->AclSize = sizeof(ACL);
138c2c66affSColin Finck         FirstAce = InvalidPointer;
139c2c66affSColin Finck         Found = RtlFirstFreeAce(Acl, &FirstAce);
140c2c66affSColin Finck         ok(Found == FALSE, "Found = %u\n", Found);
141c2c66affSColin Finck         ok(FirstAce == NULL, "FirstAce = %p (Acl was %p)\n", FirstAce, Acl);
142c2c66affSColin Finck 
143c2c66affSColin Finck         /* Only the first byte fits */
144c2c66affSColin Finck         Acl->AclSize = sizeof(ACL) + 1;
145c2c66affSColin Finck         FirstAce = InvalidPointer;
146c2c66affSColin Finck         Found = RtlFirstFreeAce(Acl, &FirstAce);
147c2c66affSColin Finck         ok(Found == TRUE, "Found = %u\n", Found);
148c2c66affSColin Finck         ok(FirstAce == NULL, "FirstAce = %p (Acl was %p)\n", FirstAce, Acl);
149c2c66affSColin Finck 
150c2c66affSColin Finck         /* Until we cover the whole size we get NULL */
151c2c66affSColin Finck         Acl->AclSize = sizeof(ACL) + sizeof(ACE_HEADER) - 3;
152c2c66affSColin Finck         FirstAce = InvalidPointer;
153c2c66affSColin Finck         Found = RtlFirstFreeAce(Acl, &FirstAce);
154c2c66affSColin Finck         ok(Found == TRUE, "Found = %u\n", Found);
155c2c66affSColin Finck         ok(FirstAce == NULL, "FirstAce = %p (Acl was %p)\n", FirstAce, Acl);
156c2c66affSColin Finck 
157c2c66affSColin Finck         FreeGuarded(Acl);
158c2c66affSColin Finck     }
159c2c66affSColin Finck 
160c2c66affSColin Finck     Acl = MakeAcl(4, (int)sizeof(ACE_HEADER), (int)sizeof(ACE_HEADER), (int)sizeof(ACCESS_ALLOWED_ACE), (int)sizeof(ACCESS_ALLOWED_ACE));
161c2c66affSColin Finck     if (Acl)
162c2c66affSColin Finck     {
163c2c66affSColin Finck         /* ACL with one ACE */
164c2c66affSColin Finck         FirstAce = InvalidPointer;
165c2c66affSColin Finck         Found = RtlFirstFreeAce(Acl, &FirstAce);
166c2c66affSColin Finck         ok(Found == TRUE, "Found = %u\n", Found);
167c2c66affSColin Finck         ok(FirstAce == (PACE)((PCHAR)(Acl + 1) + 2 * sizeof(ACE_HEADER) + 2 * sizeof(ACCESS_ALLOWED_ACE)), "FirstAce = %p (Acl was %p)\n", FirstAce, Acl);
168c2c66affSColin Finck 
169c2c66affSColin Finck         /* One less gives us NULL */
170c2c66affSColin Finck         Acl->AclSize = sizeof(ACL) + 2 * sizeof(ACE_HEADER) + 2 * sizeof(ACCESS_ALLOWED_ACE) - 1;
171c2c66affSColin Finck         FirstAce = InvalidPointer;
172c2c66affSColin Finck         Found = RtlFirstFreeAce(Acl, &FirstAce);
173c2c66affSColin Finck         ok(Found == TRUE, "Found = %u\n", Found);
174c2c66affSColin Finck         ok(FirstAce == NULL, "FirstAce = %p (Acl was %p)\n", FirstAce, Acl);
175c2c66affSColin Finck 
176c2c66affSColin Finck         /* One ACE less also gives us FALSE */
177c2c66affSColin Finck         Acl->AclSize = sizeof(ACL) + 2 * sizeof(ACE_HEADER) + sizeof(ACCESS_ALLOWED_ACE);
178c2c66affSColin Finck         FirstAce = InvalidPointer;
179c2c66affSColin Finck         Found = RtlFirstFreeAce(Acl, &FirstAce);
180c2c66affSColin Finck         ok(Found == FALSE, "Found = %u\n", Found);
181c2c66affSColin Finck         ok(FirstAce == NULL, "FirstAce = %p (Acl was %p)\n", FirstAce, Acl);
182c2c66affSColin Finck 
183c2c66affSColin Finck         FreeGuarded(Acl);
184c2c66affSColin Finck     }
185c2c66affSColin Finck }
186