307 lines
9.6 KiB
C
307 lines
9.6 KiB
C
/*++
|
|
|
|
Copyright (c) 1989 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
theap.c
|
|
|
|
Abstract:
|
|
|
|
Test program for the Heap Procedures
|
|
|
|
Author:
|
|
|
|
Steven R. Wood [stevewo]
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#define THEAP
|
|
#include "..\heap.c"
|
|
#include "..\heapdll.c"
|
|
#include "..\heapdbg.c"
|
|
#include "..\heappage.c"
|
|
#include <windows.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
ULONG NtGlobalFlag = FLG_HEAP_ENABLE_TAIL_CHECK |
|
|
FLG_HEAP_ENABLE_FREE_CHECK |
|
|
FLG_HEAP_VALIDATE_PARAMETERS |
|
|
FLG_HEAP_VALIDATE_ALL |
|
|
FLG_HEAP_ENABLE_TAGGING;
|
|
|
|
BOOLEAN
|
|
NtdllOkayToLockRoutine(
|
|
IN PVOID Lock
|
|
)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
PRTL_INITIALIZE_LOCK_ROUTINE RtlInitializeLockRoutine =
|
|
(PRTL_INITIALIZE_LOCK_ROUTINE)RtlInitializeCriticalSection;
|
|
PRTL_ACQUIRE_LOCK_ROUTINE RtlAcquireLockRoutine =
|
|
(PRTL_ACQUIRE_LOCK_ROUTINE)RtlEnterCriticalSection;
|
|
PRTL_RELEASE_LOCK_ROUTINE RtlReleaseLockRoutine =
|
|
(PRTL_RELEASE_LOCK_ROUTINE)RtlLeaveCriticalSection;
|
|
PRTL_DELETE_LOCK_ROUTINE RtlDeleteLockRoutine =
|
|
(PRTL_DELETE_LOCK_ROUTINE)RtlDeleteCriticalSection;
|
|
PRTL_OKAY_TO_LOCK_ROUTINE RtlOkayToLockRoutine =
|
|
(PRTL_OKAY_TO_LOCK_ROUTINE)NtdllOkayToLockRoutine;
|
|
|
|
RTL_HEAP_PARAMETERS HeapParameters;
|
|
|
|
ULONG RtlpHeapValidateOnCall;
|
|
ULONG RtlpHeapStopOnFree;
|
|
ULONG RtlpHeapStopOnReAlloc;
|
|
|
|
|
|
typedef struct _TEST_HEAP_ENTRY {
|
|
PVOID AllocatedBlock;
|
|
ULONG Size;
|
|
} TEST_HEAP_ENTRY, *PTEST_HEAP_ENTRY;
|
|
|
|
ULONG NumberOfHeapEntries;
|
|
PTEST_HEAP_ENTRY HeapEntries;
|
|
|
|
ULONG Seed = 14623;
|
|
|
|
#define MAX_HEAP_ALLOC 0x120000
|
|
#define REASONABLE_HEAP_ALLOC 0x200
|
|
|
|
int
|
|
_cdecl
|
|
main(
|
|
int argc,
|
|
char *argv[]
|
|
)
|
|
{
|
|
PVOID Heap, AllocatedBlock;
|
|
ULONG i, n;
|
|
PTEST_HEAP_ENTRY p;
|
|
BOOLEAN Result;
|
|
NTSTATUS Status;
|
|
RTL_HEAP_USAGE Usage;
|
|
PRTL_HEAP_USAGE_ENTRY pEntries;
|
|
ULONG TagBaseIndex, Tag;
|
|
ULONG TotalAllocated;
|
|
|
|
RtlInitializeHeapManager();
|
|
memset( &Usage, 0, sizeof( Usage ) );
|
|
|
|
#if 0
|
|
HeapParameters.Length = sizeof( HeapParameters );
|
|
HeapParameters.DeCommitFreeBlockThreshold = 0x1000;
|
|
HeapParameters.DeCommitTotalFreeThreshold = 0x4000;
|
|
Heap = RtlCreateHeap( HEAP_GROWABLE | HEAP_NO_SERIALIZE,
|
|
NULL,
|
|
256 * 4096,
|
|
4096,
|
|
NULL,
|
|
&HeapParameters
|
|
);
|
|
#endif
|
|
Heap = RtlCreateHeap( HEAP_GROWABLE | HEAP_NO_SERIALIZE | HEAP_CLASS_3,
|
|
NULL,
|
|
0x100000,
|
|
0x1000,
|
|
NULL,
|
|
NULL
|
|
);
|
|
if (Heap == NULL) {
|
|
fprintf( stderr, "THEAP: Unable to create heap.\n" );
|
|
exit( 1 );
|
|
}
|
|
fprintf( stderr, "THEAP: Created heap at %x\n", Heap );
|
|
DebugBreak();
|
|
TagBaseIndex = RtlCreateTagHeap( Heap, 0, L"THEAP!",
|
|
L"!HeapName\0"
|
|
L"Tag1\0"
|
|
L"Tag2\0"
|
|
L"Tag3\0"
|
|
L"Tag4\0"
|
|
L"Tag5\0"
|
|
L"Tag6\0"
|
|
L"Tag7\0"
|
|
L"Tag8\0"
|
|
L"Tag9\0"
|
|
L"Tag10\0"
|
|
L"Tag11\0"
|
|
L"Tag12\0"
|
|
L"Tag13\0"
|
|
L"Tag14\0"
|
|
L"Tag15\0"
|
|
L"Tag16\0"
|
|
L"Tag17\0"
|
|
L"Tag18\0"
|
|
L"Tag19\0"
|
|
L"Tag20\0"
|
|
L"Tag21\0"
|
|
L"Tag22\0"
|
|
L"Tag23\0"
|
|
L"Tag24\0"
|
|
L"Tag25\0"
|
|
L"Tag26\0"
|
|
L"Tag27\0"
|
|
L"Tag28\0"
|
|
L"Tag29\0"
|
|
L"Tag30\0"
|
|
L"Tag31\0"
|
|
L"Tag32\0"
|
|
L"Tag33\0"
|
|
L"Tag34\0"
|
|
L"Tag35\0"
|
|
L"Tag36\0"
|
|
L"Tag37\0"
|
|
L"Tag38\0"
|
|
L"Tag39\0"
|
|
L"Tag40\0"
|
|
L"Tag41\0"
|
|
L"Tag42\0"
|
|
L"Tag43\0"
|
|
L"Tag44\0"
|
|
L"Tag45\0"
|
|
L"Tag46\0"
|
|
L"Tag47\0"
|
|
L"Tag48\0"
|
|
L"Tag49\0"
|
|
L"Tag50\0"
|
|
L"Tag51\0"
|
|
L"Tag52\0"
|
|
L"Tag53\0"
|
|
L"Tag54\0"
|
|
L"Tag55\0"
|
|
L"Tag56\0"
|
|
L"Tag57\0"
|
|
L"Tag58\0"
|
|
L"Tag59\0"
|
|
L"Tag60\0"
|
|
);
|
|
|
|
NumberOfHeapEntries = 1000;
|
|
HeapEntries = VirtualAlloc( NULL,
|
|
NumberOfHeapEntries * sizeof( *HeapEntries ),
|
|
MEM_COMMIT,
|
|
PAGE_READWRITE
|
|
);
|
|
if (HeapEntries == NULL) {
|
|
fprintf( stderr, "THEAP: Unable to allocate space.\n" );
|
|
exit( 1 );
|
|
}
|
|
|
|
RtlpHeapValidateOnCall=TRUE;
|
|
// RtlpHeapStopOnAllocate=0x350f88;
|
|
// RtlpHeapStopOnReAlloc=0x710040;
|
|
|
|
TotalAllocated = 0;
|
|
while (TotalAllocated < (2 * 1024 * 1024)) {
|
|
i = RtlUniform( &Seed ) % NumberOfHeapEntries;
|
|
if (RtlUniform( &Seed ) % 100) {
|
|
n = RtlUniform( &Seed ) % REASONABLE_HEAP_ALLOC;
|
|
}
|
|
else {
|
|
n = RtlUniform( &Seed ) % MAX_HEAP_ALLOC;
|
|
}
|
|
|
|
#if 0
|
|
Usage.Length = sizeof( Usage );
|
|
Status = RtlUsageHeap( Heap, HEAP_USAGE_ALLOCATED_BLOCKS , &Usage );
|
|
if (NT_SUCCESS( Status )) {
|
|
if (Status == STATUS_MORE_ENTRIES) {
|
|
pEntries = Usage.AddedEntries;
|
|
while (pEntries) {
|
|
fprintf( stderr,
|
|
"Added: %08x %06x\n",
|
|
pEntries->Address,
|
|
pEntries->Size
|
|
);
|
|
pEntries = pEntries->Next;
|
|
}
|
|
|
|
pEntries = Usage.RemovedEntries;
|
|
while (pEntries) {
|
|
fprintf( stderr,
|
|
"Freed: %08x %06x\n",
|
|
pEntries->Address,
|
|
pEntries->Size
|
|
);
|
|
pEntries = pEntries->Next;
|
|
}
|
|
}
|
|
|
|
fprintf( stderr, "%08x %08x %08x %08x ",
|
|
Usage.BytesAllocated, Usage.BytesCommitted,
|
|
Usage.BytesReserved, Usage.BytesReservedMaximum
|
|
);
|
|
}
|
|
else {
|
|
fprintf( stderr, "RtlUsageHeap failed with status %x\n", Status );
|
|
DebugBreak();
|
|
}
|
|
|
|
if (i < 60) {
|
|
Tag = (TagBaseIndex + i + 1) << 16;
|
|
}
|
|
else {
|
|
Tag = 0;
|
|
}
|
|
#endif
|
|
Tag = 0;
|
|
p = &HeapEntries[ i ];
|
|
if (p->AllocatedBlock == NULL) {
|
|
TotalAllocated += n;
|
|
p->AllocatedBlock = RtlAllocateHeap( Heap, Tag, n );
|
|
fprintf( stderr, "Allocated %06x bytes at %08x\n", n, p->AllocatedBlock );
|
|
if (p->AllocatedBlock != NULL) {
|
|
p->Size = n;
|
|
}
|
|
else {
|
|
DebugBreak();
|
|
}
|
|
}
|
|
else
|
|
if (RtlUniform( &Seed ) & 1) {
|
|
TotalAllocated -= p->Size;
|
|
TotalAllocated += n;
|
|
AllocatedBlock = RtlReAllocateHeap( Heap, Tag, p->AllocatedBlock, n );
|
|
fprintf( stderr, "ReAlloced %06x bytes at %08x to %06x bytes at %08x\n",
|
|
p->Size,
|
|
p->AllocatedBlock,
|
|
n,
|
|
AllocatedBlock
|
|
);
|
|
if (AllocatedBlock != NULL) {
|
|
p->AllocatedBlock = AllocatedBlock;
|
|
p->Size = n;
|
|
}
|
|
else {
|
|
DebugBreak();
|
|
}
|
|
}
|
|
else {
|
|
TotalAllocated -= p->Size;
|
|
Result = RtlFreeHeap( Heap, 0, p->AllocatedBlock );
|
|
fprintf( stderr, "Freed %06x bytes at %08x\n",
|
|
p->Size,
|
|
p->AllocatedBlock
|
|
);
|
|
if (Result) {
|
|
p->AllocatedBlock = NULL;
|
|
p->Size = 0;
|
|
}
|
|
else {
|
|
DebugBreak();
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
RtlResetHeap( Heap, 0 );
|
|
RtlValidateHeap( Heap, 0, NULL );
|
|
|
|
return 0;
|
|
}
|