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.
|
|
/**********************************************************************/ /** 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); }
|