windows-nt/Source/XPSP1/NT/base/mvdm/suballoc/tsa.c

879 lines
15 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include <malloc.h>
#include <stdio.h>
#include <suballoc.h>
typedef struct _MemTrack *PMEMTRACK;
typedef struct _MemTrack {
PMEMTRACK Next;
ULONG Address;
ULONG Size;
} MEMTRACK;
VOID
SimpleTest1(
PVOID SA
);
VOID
SimpleTest2(
PVOID SA
);
VOID
SimpleTest3(
PVOID SA
);
VOID
SimpleTest4(
PVOID
);
VOID
SimpleTest5(
PVOID
);
VOID
SimpleTest6(
PVOID
);
NTSTATUS
DecommitMem(
ULONG BaseAddress,
ULONG Size
);
NTSTATUS
CommitMem(
ULONG BaseAddress,
ULONG Size
);
VOID
MoveMem(
ULONG Destination,
ULONG Source,
ULONG Size
);
main(argv, argc)
char **argv;
int argc;
{
NTSTATUS Status;
PVOID BaseAddress, SA;
ULONG Size;
ULONG TotalFree, LargestFree;
ULONG i,j;
BOOL Success;
//
// Allocate a region of memory for SA to manage
//
BaseAddress = NULL;
Size = 15*1024*1024 - 64 * 1024;
Status = NtAllocateVirtualMemory(
NtCurrentProcess(),
&BaseAddress,
0,
&Size,
MEM_RESERVE,
PAGE_READWRITE
);
if (!NT_SUCCESS(Status)) {
printf("Couldn't allocate memory, %lx\n", Status);
return(0);
}
//
// Initialize the suballocation stuff
//
SA = SAInitialize(
(ULONG)BaseAddress,
Size,
CommitMem,
DecommitMem,
MoveMem
);
if (SA == NULL) {
printf("SAInitialize Failed\n");
}
//
// Find out how much free memory we have
//
Success = SAQueryFree(
SA,
&TotalFree,
&LargestFree
);
if (!Success) {
printf("Could not query free\n");
return;
}
//
// Run some tests
//
SimpleTest1(SA);
//
// Allocate blocks spanning two commit blocks
//
SimpleTest2(SA);
//
// Allocate and free all of memory (twice)
//
SimpleTest3(SA);
//
// More complex alloc and free test
//
SimpleTest4(SA);
//
// Test realloc
//
SimpleTest5(SA);
//
// Test Queryfree
//
SimpleTest6(SA);
//
// Make sure we didn't leak
//
Success = SAQueryFree(
SA,
&i,
&j
);
if (!Success){
printf("Couldn't requery free\n");
return;
}
if ((i != TotalFree) || (j != LargestFree)) {
printf("We leaked\n");
}
}
VOID
SimpleTest1(
PVOID SA
)
{
ULONG Address;
BOOL Success;
Success = SAAllocate(
SA,
50,
&Address
);
if (!Success) {
printf("SimpleTest1: Failed to allocate\n");
return;
}
try {
*((PULONG)(Address + 4)) = 1;
} except (EXCEPTION_EXECUTE_HANDLER) {
printf("SimpleTest1: Faulted accessing memory\n");
return;
}
Success = SAFree(
SA,
50,
Address
);
if (!Success) {
printf("SimpleTest1: Failed to free\n");
return;
}
Success = TRUE;
try {
*((PULONG)Address + 4) = 1;
} except (EXCEPTION_EXECUTE_HANDLER) {
Success = FALSE;
}
if (Success) {
printf("SimpleTest1: memory not decommited\n");
}
}
VOID
SimpleTest2(
PVOID SA
)
{
ULONG SmallAddress, LargeAddress;
BOOL Success;
Success = SAAllocate(
SA,
50,
&SmallAddress
);
if (!Success) {
printf("SimpleTest2: Could not alloc small block\n");
return;
}
try {
*((PULONG)(SmallAddress + 4)) = 1;
} except (EXCEPTION_EXECUTE_HANDLER) {
printf("SimpleTest2: small block not committed\n");
return;
}
Success = SAAllocate(
SA,
COMMIT_GRANULARITY + 50,
&LargeAddress
);
if (!Success) {
printf("SimpleTest2: Could not alloc large block\n");
return;
}
try {
*((PULONG)(LargeAddress + 4)) = 1;
*((PULONG)(LargeAddress + COMMIT_GRANULARITY)) = 1;
} except (EXCEPTION_EXECUTE_HANDLER) {
printf("SimpleTest2: Large block not committed\n");
return;
}
Success = SAFree(
SA,
50,
SmallAddress
);
if (!Success) {
printf("SimpleTest2: failed to free small block\n");
return;
}
try {
*((PULONG)(LargeAddress + 4)) = 1;
} except (EXCEPTION_EXECUTE_HANDLER) {
printf("SimpleTest2: LargeBlock decommited!!\n");
return;
}
Success = SAFree(
SA,
COMMIT_GRANULARITY + 50,
LargeAddress
);
if (!Success) {
printf("SimpleTest2: failed to free Large block\n");
return;
}
Success = FALSE;
try {
*((PULONG)(LargeAddress + 4)) = 1;
} except (EXCEPTION_EXECUTE_HANDLER) {
Success = TRUE;
}
if (!Success) {
printf("SimpleTest2: First block not decommited\n");
}
Success = FALSE;
try {
*((PULONG)(LargeAddress + COMMIT_GRANULARITY + 4)) = 1;
} except (EXCEPTION_EXECUTE_HANDLER) {
Success = TRUE;
}
if (!Success) {
printf("SimpleTest2: Last block not decommited\n");
}
}
VOID
SimpleTest3(
PVOID SA
)
{
ULONG BlockCount, i, Address;
PMEMTRACK p, Head, f;
BOOL Success;
Head = NULL;
BlockCount = 0;
do {
Success = SAAllocate(
SA,
3072,
&Address
);
if (Success) {
p = malloc(sizeof(MEMTRACK));
if (p == NULL) {
printf("SimpleTest3: malloc error\n");
return;
}
p->Next = Head;
p->Size = 3072;
p->Address = Address;
Head = p;
BlockCount++;
}
} while (Success);
try {
p = Head;
while (p != NULL) {
*((PULONG)(p->Address + 100)) = 1;
p = p->Next;
}
} except (EXCEPTION_EXECUTE_HANDLER) {
printf("SimpleTest3: failed first access test\n");
return;
}
p = Head;
while (p != NULL) {
Success = SAFree(
SA,
3072,
p->Address
);
if (!Success) {
printf("SimpleTest3: Failed first free test\n");
return;
}
f = p;
p = p->Next;
free(f);
}
Head = NULL;
for (i = 0; i < BlockCount; i++) {
Success = SAAllocate(
SA,
3072,
&Address
);
if (!Success) {
printf("SimpleTest3: Failed second alloc test\n");
return;
}
p = malloc(sizeof(MEMTRACK));
if (p == NULL) {
printf("SimpleTest3: malloc error\n");
return;
}
p->Next = Head;
p->Size = 3072;
p->Address = Address;
Head = p;
}
try {
p = Head;
while (p != NULL) {
*((PULONG)(p->Address + 100)) = 1;
p = p->Next;
}
} except (EXCEPTION_EXECUTE_HANDLER) {
printf("SimpleTest3: failed second access test\n");
return;
}
p = Head;
while (p != NULL) {
Success = SAFree(
SA,
3072,
p->Address
);
if (!Success) {
printf("SimpleTest3: Failed second free test\n");
return;
}
f = p;
p = p->Next;
free(f);
}
}
VOID
SimpleTest4(
PVOID SA
)
{
ULONG i, Address;
PMEMTRACK p, Head, f;
BOOL Success;
Head = NULL;
do {
Success = SAAllocate(
SA,
3072,
&Address
);
if (Success) {
p = malloc(sizeof(MEMTRACK));
if (p == NULL) {
printf("SimpleTest4: malloc error\n");
return;
}
p->Next = Head;
p->Size = 3072;
p->Address = Address;
Head = p;
}
} while (Success);
p = Head;
p = p->Next;
p = p->Next;
Success = SAFree(
SA,
3072,
p->Next->Address
);
if (!Success) {
printf("SimpleTest4: could not free\n");
return;
}
f = p->Next;
p->Next = p->Next->Next;
free (f);
p = p->Next;
p = p->Next;
Success = SAFree(
SA,
3072,
p->Next->Address
);
if (!Success) {
printf("SimpleTest4: could not free\n");
return;
}
f = p->Next;
p->Next = p->Next->Next;
free (f);
Success = SAFree(
SA,
3072,
p->Next->Address
);
if (!Success) {
printf("SimpleTest4: could not free\n");
return;
}
f = p->Next;
p->Next = p->Next->Next;
free (f);
Success = SAAllocate(
SA,
3072,
&Address
);
try {
*((PULONG)(Address + 4)) = 1;
} except (EXCEPTION_EXECUTE_HANDLER) {
printf("SimpleTest4: failed to access\n");
return;
}
if (!Success) {
printf("SimpleTest4: could not allocate\n");
return;
}
p = malloc(sizeof(MEMTRACK));
if (!p) {
printf("SimpleTest4: could not malloc\n");
return;
}
p->Next = Head;
p->Size = 3072;
p->Address = Address;
Head = p;
Success = SAAllocate(
SA,
3072,
&Address
);
try {
*((PULONG)(Address + 4)) = 1;
} except (EXCEPTION_EXECUTE_HANDLER) {
printf("SimpleTest4: failed to access\n");
return;
}
if (!Success) {
printf("SimpleTest4: could not allocate\n");
return;
}
p = malloc(sizeof(MEMTRACK));
if (!p) {
printf("SimpleTest4: could not malloc\n");
return;
}
p->Next = Head;
p->Size = 3072;
p->Address = Address;
Head = p;
p = Head;
while (p != NULL) {
Success = SAFree(
SA,
3072,
p->Address
);
if (!Success) {
printf("SimpleTest3: Failed second free test\n");
return;
}
f = p;
p = p->Next;
free(f);
}
}
VOID
SimpleTest5(
PVOID SA
)
{
ULONG Address, NewAddress;
ULONG Address1, Address2, Address3;
ULONG Size1, Size2, Size3;
BOOL Success;
Success = SAAllocate(
SA,
3072,
&Address
);
if (!Success) {
printf("SimpleTest5: failed to allocate\n");
return;
}
Success = SAReallocate(
SA,
3072,
Address,
3000,
&NewAddress
);
if (!Success) {
printf("SimpleTest5: failed to reallocate\n");
return;
}
if (NewAddress != Address) {
printf("SimpleTest5: Realloc in place failed\n");
}
Success = SAReallocate(
SA,
3072,
Address,
200,
&NewAddress
);
if (!Success) {
printf("SimpleTest5: failed to reallocate\n");
return;
}
if (NewAddress != Address) {
printf("SimpleTest5: Realloc in place failed\n");
return;
}
Success = SAReallocate(
SA,
200,
Address,
6000,
&NewAddress
);
if (!Success) {
printf("SimpleTest5: failed to reallocate\n");
return;
}
if (NewAddress != Address) {
printf("SimpleTest5: realloc in place failed\n");
return;
}
Success = SAAllocate(
SA,
1500,
&Address
);
if (!Success) {
printf("SimpleTest5: failed to allocate\n");
return;
}
Address1 = NewAddress;
Size1 = 6000;
Address2 = Address;
Size2 = 1500;
Success = SAReallocate(
SA,
Size1,
Address1,
3000,
&NewAddress
);
if (!Success) {
printf("SimpleTest5: failed to reallocate\n");
return;
}
if (Address1 != NewAddress) {
printf("SimpleTest5: realloc in place failed\n");
return;
}
Size1= 3000;
Success = SAAllocate(
SA,
2000,
&Address
);
if (!Success) {
printf("SimpleTest5: failed to allocate\n");
return;
}
Address3 = Address;
Size3 = 2000;
Success = SAFree(
SA,
Size1,
Address1
);
if (!Success) {
printf("SimpleTest5: failed to free\n");
return;
}
Success = SAReallocate(
SA,
Size3,
Address3,
5000,
&Address
);
if (!Success) {
printf("SimpleTest5: failed to reallocate\n");
return;
}
Address3 = Address;
Size3 = 5000;
Success = SAReallocate(
SA,
Size3,
Address3,
10000,
&Address
);
if (!Success) {
printf("SimpleTest5: failed to reallocate\n");
return;
}
Address3 = Address;
Size3 = 10000;
Success = SAFree(
SA,
Size2,
Address2
);
if (!Success) {
printf("SimpleTest5: failed to free\n");
return;
}
Success = SAFree(
SA,
Size3,
Address3
);
if (!Success) {
printf("SimpleTest5: failed to free\n");
return;
}
}
VOID
SimpleTest6(
PVOID SA
)
{
ULONG LargestFree, TotalFree;
BOOL Success;
Success = SAQueryFree(
SA,
&TotalFree,
&LargestFree
);
}
NTSTATUS
CommitMem(
ULONG BaseAddress,
ULONG Size
)
{
NTSTATUS Status;
PVOID Address;
ULONG size;
Address = (PVOID)BaseAddress;
size = Size;
Status = NtAllocateVirtualMemory(
NtCurrentProcess(),
&Address,
0L,
&size,
MEM_COMMIT,
PAGE_READWRITE
);
if (!NT_SUCCESS(Status)) {
printf(
"CommitMem failed to commit %lx, %lx, error %lx\n",
Address,
size,
Status
);
}
return Status;
}
NTSTATUS
DecommitMem(
ULONG BaseAddress,
ULONG Size
)
{
NTSTATUS Status;
PVOID Address;
ULONG size;
Address = (PVOID)BaseAddress;
size = Size;
Status = NtFreeVirtualMemory(
NtCurrentProcess(),
&Address,
&size,
MEM_DECOMMIT
);
if (!NT_SUCCESS(Status)) {
printf(
"DecommitMem failed to decommit %lx, %lx, error %lx\n",
Address,
size,
Status
);
}
return Status;
}
VOID
MoveMem(
ULONG Destination,
ULONG Source,
ULONG Size
)
{
RtlMoveMemory(
(PVOID)Destination,
(PVOID)Source,
Size
);
}