mirror of
https://github.com/reactos/reactos.git
synced 2024-10-30 03:27:31 +00:00
235 lines
7.2 KiB
C
235 lines
7.2 KiB
C
|
/*
|
||
|
* PROJECT: ReactOS API tests
|
||
|
* LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory
|
||
|
* PURPOSE: Test for RtlFirstFreeAce
|
||
|
* PROGRAMMERS: Thomas Faber <thomas.faber@reactos.org>
|
||
|
*/
|
||
|
|
||
|
#include <apitest.h>
|
||
|
#include <ndk/mmfuncs.h>
|
||
|
#include <ndk/rtlfuncs.h>
|
||
|
|
||
|
static
|
||
|
PVOID
|
||
|
AllocateGuarded(
|
||
|
_In_ SIZE_T SizeRequested)
|
||
|
{
|
||
|
NTSTATUS Status;
|
||
|
SIZE_T Size = PAGE_ROUND_UP(SizeRequested + PAGE_SIZE);
|
||
|
PVOID VirtualMemory = NULL;
|
||
|
PCHAR StartOfBuffer;
|
||
|
|
||
|
Status = NtAllocateVirtualMemory(NtCurrentProcess(), &VirtualMemory, 0, &Size, MEM_RESERVE, PAGE_NOACCESS);
|
||
|
|
||
|
if (!NT_SUCCESS(Status))
|
||
|
return NULL;
|
||
|
|
||
|
Size -= PAGE_SIZE;
|
||
|
if (Size)
|
||
|
{
|
||
|
Status = NtAllocateVirtualMemory(NtCurrentProcess(), &VirtualMemory, 0, &Size, MEM_COMMIT, PAGE_READWRITE);
|
||
|
if (!NT_SUCCESS(Status))
|
||
|
{
|
||
|
Size = 0;
|
||
|
Status = NtFreeVirtualMemory(NtCurrentProcess(), &VirtualMemory, &Size, MEM_RELEASE);
|
||
|
ok(Status == STATUS_SUCCESS, "Status = %lx\n", Status);
|
||
|
return NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
StartOfBuffer = VirtualMemory;
|
||
|
StartOfBuffer += Size - SizeRequested;
|
||
|
|
||
|
return StartOfBuffer;
|
||
|
}
|
||
|
|
||
|
static
|
||
|
VOID
|
||
|
FreeGuarded(
|
||
|
_In_ PVOID Pointer)
|
||
|
{
|
||
|
NTSTATUS Status;
|
||
|
PVOID VirtualMemory = (PVOID)PAGE_ROUND_DOWN((SIZE_T)Pointer);
|
||
|
SIZE_T Size = 0;
|
||
|
|
||
|
Status = NtFreeVirtualMemory(NtCurrentProcess(), &VirtualMemory, &Size, MEM_RELEASE);
|
||
|
ok(Status == STATUS_SUCCESS, "Status = %lx\n", Status);
|
||
|
}
|
||
|
|
||
|
static
|
||
|
PACL
|
||
|
MakeAcl(
|
||
|
_In_ ULONG AceCount,
|
||
|
...)
|
||
|
{
|
||
|
PACL Acl;
|
||
|
PACE_HEADER AceHeader;
|
||
|
ULONG AclSize;
|
||
|
ULONG AceSizes[10];
|
||
|
ULONG i;
|
||
|
va_list Args;
|
||
|
|
||
|
ASSERT(AceCount <= RTL_NUMBER_OF(AceSizes));
|
||
|
AclSize = sizeof(ACL);
|
||
|
va_start(Args, AceCount);
|
||
|
for (i = 0; i < AceCount; i++)
|
||
|
{
|
||
|
AceSizes[i] = va_arg(Args, int);
|
||
|
AclSize += AceSizes[i];
|
||
|
}
|
||
|
va_end(Args);
|
||
|
|
||
|
Acl = AllocateGuarded(AclSize);
|
||
|
if (!Acl)
|
||
|
{
|
||
|
skip("Failed to allocate %lu bytes\n", AclSize);
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
Acl->AclRevision = ACL_REVISION;
|
||
|
Acl->Sbz1 = 0;
|
||
|
Acl->AclSize = AclSize;
|
||
|
Acl->AceCount = AceCount;
|
||
|
Acl->Sbz2 = 0;
|
||
|
|
||
|
AceHeader = (PACE_HEADER)(Acl + 1);
|
||
|
for (i = 0; i < AceCount; i++)
|
||
|
{
|
||
|
AceHeader->AceType = 0;
|
||
|
AceHeader->AceFlags = 0;
|
||
|
AceHeader->AceSize = AceSizes[i];
|
||
|
AceHeader = (PACE_HEADER)((PCHAR)AceHeader + AceHeader->AceSize);
|
||
|
}
|
||
|
|
||
|
return Acl;
|
||
|
}
|
||
|
|
||
|
START_TEST(RtlFirstFreeAce)
|
||
|
{
|
||
|
PACL Acl;
|
||
|
PACE FirstAce;
|
||
|
BOOLEAN Found;
|
||
|
|
||
|
Acl = MakeAcl(0);
|
||
|
if (Acl)
|
||
|
{
|
||
|
/* Simple empty ACL */
|
||
|
FirstAce = InvalidPointer;
|
||
|
Found = RtlFirstFreeAce(Acl, &FirstAce);
|
||
|
ok(Found == TRUE, "Found = %u\n", Found);
|
||
|
ok(FirstAce == (PACE)(Acl + 1), "FirstAce = %p (Acl was %p)\n", FirstAce, Acl);
|
||
|
|
||
|
/* Not enough space */
|
||
|
Acl->AclSize = sizeof(ACL) - 1;
|
||
|
FirstAce = InvalidPointer;
|
||
|
Found = RtlFirstFreeAce(Acl, &FirstAce);
|
||
|
ok(Found == TRUE, "Found = %u\n", Found);
|
||
|
ok(FirstAce == NULL, "FirstAce = %p (Acl was %p)\n", FirstAce, Acl);
|
||
|
|
||
|
/* Invalid values for all the other fields */
|
||
|
Acl->AclRevision = 76;
|
||
|
Acl->Sbz1 = 0x55;
|
||
|
Acl->AclSize = sizeof(ACL);
|
||
|
Acl->Sbz2 = 0x55;
|
||
|
FirstAce = InvalidPointer;
|
||
|
Found = RtlFirstFreeAce(Acl, &FirstAce);
|
||
|
ok(Found == TRUE, "Found = %u\n", Found);
|
||
|
ok(FirstAce == (PACE)(Acl + 1), "FirstAce = %p (Acl was %p)\n", FirstAce, Acl);
|
||
|
|
||
|
FreeGuarded(Acl);
|
||
|
}
|
||
|
|
||
|
Acl = MakeAcl(1, (int)sizeof(ACE_HEADER));
|
||
|
if (Acl)
|
||
|
{
|
||
|
/* ACL with one ACE */
|
||
|
FirstAce = InvalidPointer;
|
||
|
Found = RtlFirstFreeAce(Acl, &FirstAce);
|
||
|
ok(Found == TRUE, "Found = %u\n", Found);
|
||
|
ok(FirstAce == (PACE)((PACE_HEADER)(Acl + 1) + 1), "FirstAce = %p (Acl was %p)\n", FirstAce, Acl);
|
||
|
|
||
|
/* The one ACE doesn't actually fit */
|
||
|
Acl->AclSize = sizeof(ACL);
|
||
|
FirstAce = InvalidPointer;
|
||
|
Found = RtlFirstFreeAce(Acl, &FirstAce);
|
||
|
ok(Found == FALSE, "Found = %u\n", Found);
|
||
|
ok(FirstAce == NULL, "FirstAce = %p (Acl was %p)\n", FirstAce, Acl);
|
||
|
|
||
|
/* Only the first byte fits */
|
||
|
Acl->AclSize = sizeof(ACL) + 1;
|
||
|
FirstAce = InvalidPointer;
|
||
|
Found = RtlFirstFreeAce(Acl, &FirstAce);
|
||
|
ok(Found == TRUE, "Found = %u\n", Found);
|
||
|
ok(FirstAce == NULL, "FirstAce = %p (Acl was %p)\n", FirstAce, Acl);
|
||
|
|
||
|
/* Until we cover the whole size we get NULL */
|
||
|
Acl->AclSize = sizeof(ACL) + sizeof(ACE_HEADER) - 1;
|
||
|
FirstAce = InvalidPointer;
|
||
|
Found = RtlFirstFreeAce(Acl, &FirstAce);
|
||
|
ok(Found == TRUE, "Found = %u\n", Found);
|
||
|
ok(FirstAce == NULL, "FirstAce = %p (Acl was %p)\n", FirstAce, Acl);
|
||
|
|
||
|
FreeGuarded(Acl);
|
||
|
}
|
||
|
|
||
|
/* Same but bigger */
|
||
|
Acl = MakeAcl(1, (int)sizeof(ACE_HEADER) + 4);
|
||
|
if (Acl)
|
||
|
{
|
||
|
/* ACL with one ACE */
|
||
|
FirstAce = InvalidPointer;
|
||
|
Found = RtlFirstFreeAce(Acl, &FirstAce);
|
||
|
ok(Found == TRUE, "Found = %u\n", Found);
|
||
|
ok(FirstAce == (PACE)((PCHAR)(Acl + 1) + sizeof(ACE_HEADER) + 4), "FirstAce = %p (Acl was %p)\n", FirstAce, Acl);
|
||
|
|
||
|
/* The one ACE doesn't actually fit */
|
||
|
Acl->AclSize = sizeof(ACL);
|
||
|
FirstAce = InvalidPointer;
|
||
|
Found = RtlFirstFreeAce(Acl, &FirstAce);
|
||
|
ok(Found == FALSE, "Found = %u\n", Found);
|
||
|
ok(FirstAce == NULL, "FirstAce = %p (Acl was %p)\n", FirstAce, Acl);
|
||
|
|
||
|
/* Only the first byte fits */
|
||
|
Acl->AclSize = sizeof(ACL) + 1;
|
||
|
FirstAce = InvalidPointer;
|
||
|
Found = RtlFirstFreeAce(Acl, &FirstAce);
|
||
|
ok(Found == TRUE, "Found = %u\n", Found);
|
||
|
ok(FirstAce == NULL, "FirstAce = %p (Acl was %p)\n", FirstAce, Acl);
|
||
|
|
||
|
/* Until we cover the whole size we get NULL */
|
||
|
Acl->AclSize = sizeof(ACL) + sizeof(ACE_HEADER) - 3;
|
||
|
FirstAce = InvalidPointer;
|
||
|
Found = RtlFirstFreeAce(Acl, &FirstAce);
|
||
|
ok(Found == TRUE, "Found = %u\n", Found);
|
||
|
ok(FirstAce == NULL, "FirstAce = %p (Acl was %p)\n", FirstAce, Acl);
|
||
|
|
||
|
FreeGuarded(Acl);
|
||
|
}
|
||
|
|
||
|
Acl = MakeAcl(4, (int)sizeof(ACE_HEADER), (int)sizeof(ACE_HEADER), (int)sizeof(ACCESS_ALLOWED_ACE), (int)sizeof(ACCESS_ALLOWED_ACE));
|
||
|
if (Acl)
|
||
|
{
|
||
|
/* ACL with one ACE */
|
||
|
FirstAce = InvalidPointer;
|
||
|
Found = RtlFirstFreeAce(Acl, &FirstAce);
|
||
|
ok(Found == TRUE, "Found = %u\n", Found);
|
||
|
ok(FirstAce == (PACE)((PCHAR)(Acl + 1) + 2 * sizeof(ACE_HEADER) + 2 * sizeof(ACCESS_ALLOWED_ACE)), "FirstAce = %p (Acl was %p)\n", FirstAce, Acl);
|
||
|
|
||
|
/* One less gives us NULL */
|
||
|
Acl->AclSize = sizeof(ACL) + 2 * sizeof(ACE_HEADER) + 2 * sizeof(ACCESS_ALLOWED_ACE) - 1;
|
||
|
FirstAce = InvalidPointer;
|
||
|
Found = RtlFirstFreeAce(Acl, &FirstAce);
|
||
|
ok(Found == TRUE, "Found = %u\n", Found);
|
||
|
ok(FirstAce == NULL, "FirstAce = %p (Acl was %p)\n", FirstAce, Acl);
|
||
|
|
||
|
/* One ACE less also gives us FALSE */
|
||
|
Acl->AclSize = sizeof(ACL) + 2 * sizeof(ACE_HEADER) + sizeof(ACCESS_ALLOWED_ACE);
|
||
|
FirstAce = InvalidPointer;
|
||
|
Found = RtlFirstFreeAce(Acl, &FirstAce);
|
||
|
ok(Found == FALSE, "Found = %u\n", Found);
|
||
|
ok(FirstAce == NULL, "FirstAce = %p (Acl was %p)\n", FirstAce, Acl);
|
||
|
|
||
|
FreeGuarded(Acl);
|
||
|
}
|
||
|
}
|