Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

153 lines
4.4 KiB

/**********************************************************************/
/** Microsoft Windows/NT **/
/** Copyright(c) Microsoft Corporation, 1997 - 2002 **/
/**********************************************************************/
#include "stdafx.h"
#include "util.h"
PVOID __fastcall MyVirtualAlloc(ULONG Size)
{
return VirtualAlloc( NULL, Size, MEM_COMMIT, PAGE_READWRITE );
}
VOID __fastcall MyVirtualFree(PVOID Allocation)
{
VirtualFree( Allocation, 0, MEM_RELEASE );
}
HANDLE CreateSubAllocator(IN ULONG InitialCommitSize, IN ULONG GrowthCommitSize)
{
PSUBALLOCATOR SubAllocator;
ULONG InitialSize;
ULONG GrowthSize;
InitialSize = ROUNDUP2( InitialCommitSize, MINIMUM_VM_ALLOCATION );
GrowthSize = ROUNDUP2( GrowthCommitSize, MINIMUM_VM_ALLOCATION );
SubAllocator = (PSUBALLOCATOR)MyVirtualAlloc( InitialSize );
//
// If can't allocate entire initial size, back off to minimum size.
// Very large initial requests sometimes cannot be allocated simply
// because there is not enough contiguous address space.
//
if ( SubAllocator == NULL )
{
SubAllocator = (PSUBALLOCATOR)MyVirtualAlloc( GrowthSize );
}
if ( SubAllocator == NULL )
{
SubAllocator = (PSUBALLOCATOR)MyVirtualAlloc( MINIMUM_VM_ALLOCATION );
}
if ( SubAllocator != NULL )
{
SubAllocator->NextAvailable = (PCHAR)SubAllocator + ROUNDUP2( sizeof( SUBALLOCATOR ), SUBALLOCATOR_ALIGNMENT );
SubAllocator->LastAvailable = (PCHAR)SubAllocator + InitialSize;
SubAllocator->VirtualList = (PVOID*)SubAllocator;
SubAllocator->GrowSize = GrowthSize;
}
return (HANDLE) SubAllocator;
}
PVOID __fastcall SubAllocate(IN HANDLE hAllocator, IN ULONG Size)
{
PSUBALLOCATOR SubAllocator = (PSUBALLOCATOR) hAllocator;
PCHAR NewVirtual;
PCHAR Allocation;
ULONG AllocSize;
ULONG_PTR Available;
ULONG GrowSize;
ASSERT( Size < (ULONG)( ~(( SUBALLOCATOR_ALIGNMENT * 2 ) - 1 )));
AllocSize = ROUNDUP2( Size, SUBALLOCATOR_ALIGNMENT );
Available = SubAllocator->LastAvailable - SubAllocator->NextAvailable;
if ( AllocSize <= Available )
{
Allocation = SubAllocator->NextAvailable;
SubAllocator->NextAvailable = Allocation + AllocSize;
return Allocation;
}
//
// Insufficient VM, so grow it. Make sure we grow it enough to satisfy
// the allocation request in case the request is larger than the grow
// size specified in CreateSubAllocator.
//
GrowSize = SubAllocator->GrowSize;
if ( GrowSize < ( AllocSize + SUBALLOCATOR_ALIGNMENT ))
{
GrowSize = ROUNDUP2(( AllocSize + SUBALLOCATOR_ALIGNMENT ), MINIMUM_VM_ALLOCATION );
}
NewVirtual = (PCHAR)MyVirtualAlloc( GrowSize );
// If failed to alloc GrowSize VM, and the allocation could be satisfied
// with a minimum VM allocation, try allocating minimum VM to satisfy
// this request.
//
if (( NewVirtual == NULL ) && ( AllocSize <= ( MINIMUM_VM_ALLOCATION - SUBALLOCATOR_ALIGNMENT )))
{
GrowSize = MINIMUM_VM_ALLOCATION;
NewVirtual = (PCHAR)MyVirtualAlloc( GrowSize );
}
if ( NewVirtual != NULL )
{
// Set LastAvailable to end of new VM block.
SubAllocator->LastAvailable = NewVirtual + GrowSize;
// Link new VM into list of VM allocations.
*(PVOID*)NewVirtual = SubAllocator->VirtualList;
SubAllocator->VirtualList = (PVOID*)NewVirtual;
// Requested allocation comes next.
Allocation = NewVirtual + SUBALLOCATOR_ALIGNMENT;
// Then set the NextAvailable for what's remaining.
SubAllocator->NextAvailable = Allocation + AllocSize;
// And return the allocation.
return Allocation;
}
// Could not allocate enough VM to satisfy request.
return NULL;
}
VOID DestroySubAllocator(IN HANDLE hAllocator)
{
PSUBALLOCATOR SubAllocator = (PSUBALLOCATOR) hAllocator;
PVOID VirtualBlock = SubAllocator->VirtualList;
PVOID NextVirtualBlock;
do
{
NextVirtualBlock = *(PVOID*)VirtualBlock;
MyVirtualFree( VirtualBlock );
VirtualBlock = NextVirtualBlock;
}while (VirtualBlock != NULL);
}