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 } 233