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 "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(RtlDeleteAce) 106 { 107 PACL Acl; 108 PACCESS_ALLOWED_ACE Ace; 109 ULONG AceSize; 110 PISID Sid; 111 NTSTATUS Status; 112 int i; 113 114 Acl = MakeAcl(0); 115 if (Acl) 116 { 117 ok(RtlValidAcl(Acl), "Acl is invalid\n"); 118 119 /* There is no first ACE -- should stay untouched */ 120 Status = RtlDeleteAce(Acl, 0); 121 ok(Status == STATUS_INVALID_PARAMETER, "Status = %lx\n", Status); 122 ok(Acl->AclSize == sizeof(ACL), "AclSize = %u\n", Acl->AclSize); 123 ok(Acl->AceCount == 0, "AceCount = %u\n", Acl->AceCount); 124 125 /* Index -1 -- should stay untouched */ 126 Status = RtlDeleteAce(Acl, 0xFFFFFFFF); 127 ok(Status == STATUS_INVALID_PARAMETER, "Status = %lx\n", Status); 128 FreeGuarded(Acl); 129 } 130 131 AceSize = FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + FIELD_OFFSET(SID, SubAuthority); 132 Acl = MakeAcl(1, (int)AceSize); 133 if (Acl) 134 { 135 Ace = (PACCESS_ALLOWED_ACE)(Acl + 1); 136 Ace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE; 137 Sid = (PISID)&Ace->SidStart; 138 Sid->Revision = SID_REVISION; 139 Sid->SubAuthorityCount = 0; 140 RtlZeroMemory(&Sid->IdentifierAuthority, sizeof(Sid->IdentifierAuthority)); 141 142 ok(RtlValidAcl(Acl), "Acl is invalid\n"); 143 144 /* Out of bounds delete -- should stay untouched */ 145 Status = RtlDeleteAce(Acl, 1); 146 ok(Status == STATUS_INVALID_PARAMETER, "Status = %lx\n", Status); 147 ok(Acl->AclSize == sizeof(ACL) + AceSize, "AclSize = %u\n", Acl->AclSize); 148 ok(Acl->AceCount == 1, "AceCount = %u\n", Acl->AceCount); 149 ok(Ace->Header.AceSize == AceSize, "AceSize = %u\n", Ace->Header.AceSize); 150 151 /* Index -1 -- should stay untouched */ 152 Status = RtlDeleteAce(Acl, 0xFFFFFFFF); 153 ok(Status == STATUS_INVALID_PARAMETER, "Status = %lx\n", Status); 154 ok(Acl->AclSize == sizeof(ACL) + AceSize, "AclSize = %u\n", Acl->AclSize); 155 ok(Acl->AceCount == 1, "AceCount = %u\n", Acl->AceCount); 156 ok(Ace->Header.AceSize == AceSize, "AceSize = %u\n", Ace->Header.AceSize); 157 158 /* Delete the first (and only) ACE */ 159 Status = RtlDeleteAce(Acl, 0); 160 ok(Status == STATUS_SUCCESS, "Status = %lx\n", Status); 161 ok(Acl->AclSize == sizeof(ACL) + AceSize, "AclSize = %u\n", Acl->AclSize); 162 ok(Acl->AceCount == 0, "AceCount = %u\n", Acl->AceCount); 163 ok(Ace->Header.AceSize == 0, "AceSize = %u\n", Ace->Header.AceSize); 164 FreeGuarded(Acl); 165 } 166 167 AceSize = FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + FIELD_OFFSET(SID, SubAuthority[1]); 168 Acl = MakeAcl(4, (int)AceSize, (int)AceSize + 4, (int)AceSize + 8, (int)AceSize + 12); 169 if (Acl) 170 { 171 Ace = (PACCESS_ALLOWED_ACE)(Acl + 1); 172 for (i = 0; i < 4; i++) 173 { 174 Ace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE; 175 Sid = (PISID)&Ace->SidStart; 176 Sid->Revision = SID_REVISION; 177 Sid->SubAuthorityCount = 0; 178 RtlZeroMemory(&Sid->IdentifierAuthority, sizeof(Sid->IdentifierAuthority)); 179 Ace = (PACCESS_ALLOWED_ACE)((PCHAR)Ace + Ace->Header.AceSize); 180 } 181 182 ok(RtlValidAcl(Acl), "Acl is invalid\n"); 183 184 /* Out of bounds delete -- should stay untouched */ 185 Status = RtlDeleteAce(Acl, 4); 186 ok(Status == STATUS_INVALID_PARAMETER, "Status = %lx\n", Status); 187 ok(Acl->AclSize == sizeof(ACL) + 4 * AceSize + 24, "AclSize = %u\n", Acl->AclSize); 188 ok(Acl->AceCount == 4, "AceCount = %u\n", Acl->AceCount); 189 Ace = (PACCESS_ALLOWED_ACE)(Acl + 1); 190 ok(Ace->Header.AceSize == AceSize, "AceSize = %u\n", Ace->Header.AceSize); 191 Ace = (PACCESS_ALLOWED_ACE)((PCHAR)Ace + Ace->Header.AceSize); 192 ok(Ace->Header.AceSize == AceSize + 4, "AceSize = %u\n", Ace->Header.AceSize); 193 Ace = (PACCESS_ALLOWED_ACE)((PCHAR)Ace + Ace->Header.AceSize); 194 ok(Ace->Header.AceSize == AceSize + 8, "AceSize = %u\n", Ace->Header.AceSize); 195 Ace = (PACCESS_ALLOWED_ACE)((PCHAR)Ace + Ace->Header.AceSize); 196 ok(Ace->Header.AceSize == AceSize + 12, "AceSize = %u\n", Ace->Header.AceSize); 197 198 /* Index -1 -- should stay untouched */ 199 Status = RtlDeleteAce(Acl, 0xFFFFFFFF); 200 ok(Status == STATUS_INVALID_PARAMETER, "Status = %lx\n", Status); 201 ok(Acl->AclSize == sizeof(ACL) + 4 * AceSize + 24, "AclSize = %u\n", Acl->AclSize); 202 ok(Acl->AceCount == 4, "AceCount = %u\n", Acl->AceCount); 203 Ace = (PACCESS_ALLOWED_ACE)(Acl + 1); 204 ok(Ace->Header.AceSize == AceSize, "AceSize = %u\n", Ace->Header.AceSize); 205 Ace = (PACCESS_ALLOWED_ACE)((PCHAR)Ace + Ace->Header.AceSize); 206 ok(Ace->Header.AceSize == AceSize + 4, "AceSize = %u\n", Ace->Header.AceSize); 207 Ace = (PACCESS_ALLOWED_ACE)((PCHAR)Ace + Ace->Header.AceSize); 208 ok(Ace->Header.AceSize == AceSize + 8, "AceSize = %u\n", Ace->Header.AceSize); 209 Ace = (PACCESS_ALLOWED_ACE)((PCHAR)Ace + Ace->Header.AceSize); 210 ok(Ace->Header.AceSize == AceSize + 12, "AceSize = %u\n", Ace->Header.AceSize); 211 212 /* Delete the last ACE */ 213 Status = RtlDeleteAce(Acl, 3); 214 ok(Status == STATUS_SUCCESS, "Status = %lx\n", Status); 215 ok(Acl->AclSize == sizeof(ACL) + 4 * AceSize + 24, "AclSize = %u\n", Acl->AclSize); 216 ok(Acl->AceCount == 3, "AceCount = %u\n", Acl->AceCount); 217 Ace = (PACCESS_ALLOWED_ACE)(Acl + 1); 218 ok(Ace->Header.AceSize == AceSize, "AceSize = %u\n", Ace->Header.AceSize); 219 Ace = (PACCESS_ALLOWED_ACE)((PCHAR)Ace + Ace->Header.AceSize); 220 ok(Ace->Header.AceSize == AceSize + 4, "AceSize = %u\n", Ace->Header.AceSize); 221 Ace = (PACCESS_ALLOWED_ACE)((PCHAR)Ace + Ace->Header.AceSize); 222 ok(Ace->Header.AceSize == AceSize + 8, "AceSize = %u\n", Ace->Header.AceSize); 223 Ace = (PACCESS_ALLOWED_ACE)((PCHAR)Ace + Ace->Header.AceSize); 224 ok(Ace->Header.AceSize == 0, "AceSize = %u\n", Ace->Header.AceSize); 225 226 /* Delete the second ACE */ 227 Status = RtlDeleteAce(Acl, 1); 228 ok(Status == STATUS_SUCCESS, "Status = %lx\n", Status); 229 ok(Acl->AclSize == sizeof(ACL) + 4 * AceSize + 24, "AclSize = %u\n", Acl->AclSize); 230 ok(Acl->AceCount == 2, "AceCount = %u\n", Acl->AceCount); 231 Ace = (PACCESS_ALLOWED_ACE)(Acl + 1); 232 ok(Ace->Header.AceSize == AceSize, "AceSize = %u\n", Ace->Header.AceSize); 233 Ace = (PACCESS_ALLOWED_ACE)((PCHAR)Ace + Ace->Header.AceSize); 234 ok(Ace->Header.AceSize == AceSize + 8, "AceSize = %u\n", Ace->Header.AceSize); 235 Ace = (PACCESS_ALLOWED_ACE)((PCHAR)Ace + Ace->Header.AceSize); 236 ok(Ace->Header.AceSize == 0, "AceSize = %u\n", Ace->Header.AceSize); 237 238 /* Delete the first ACE */ 239 Status = RtlDeleteAce(Acl, 0); 240 ok(Status == STATUS_SUCCESS, "Status = %lx\n", Status); 241 ok(Acl->AclSize == sizeof(ACL) + 4 * AceSize + 24, "AclSize = %u\n", Acl->AclSize); 242 ok(Acl->AceCount == 1, "AceCount = %u\n", Acl->AceCount); 243 Ace = (PACCESS_ALLOWED_ACE)(Acl + 1); 244 ok(Ace->Header.AceSize == AceSize + 8, "AceSize = %u\n", Ace->Header.AceSize); 245 Ace = (PACCESS_ALLOWED_ACE)((PCHAR)Ace + Ace->Header.AceSize); 246 ok(Ace->Header.AceSize == 0, "AceSize = %u\n", Ace->Header.AceSize); 247 248 /* Delete the remaining ACE */ 249 Status = RtlDeleteAce(Acl, 0); 250 ok(Status == STATUS_SUCCESS, "Status = %lx\n", Status); 251 ok(Acl->AclSize == sizeof(ACL) + 4 * AceSize + 24, "AclSize = %u\n", Acl->AclSize); 252 ok(Acl->AceCount == 0, "AceCount = %u\n", Acl->AceCount); 253 Ace = (PACCESS_ALLOWED_ACE)(Acl + 1); 254 ok(Ace->Header.AceSize == 0, "AceSize = %u\n", Ace->Header.AceSize); 255 256 FreeGuarded(Acl); 257 } 258 } 259