/* * V M E M . C * * Virtual Memory Utilities * * Copyright 1993-1997 Microsoft Corporation. All Rights Reserved. */ #pragma warning(disable:4206) /* empty source file */ #if defined(DBG) && defined(_X86_) #pragma warning(disable:4001) /* single line comments */ #pragma warning(disable:4001) /* single line comments */ #pragma warning(disable:4050) /* different code attributes */ #pragma warning(disable:4100) /* unreferenced formal parameter */ #pragma warning(disable:4115) /* named type definition in parentheses */ #pragma warning(disable:4115) /* named type definition in parentheses */ #pragma warning(disable:4127) /* conditional expression is constant */ #pragma warning(disable:4201) /* nameless struct/union */ #pragma warning(disable:4206) /* translation unit is empty */ #pragma warning(disable:4209) /* benign typedef redefinition */ #pragma warning(disable:4214) /* bit field types other than int */ #pragma warning(disable:4514) /* unreferenced inline function */ #include #include #define PAGE_SIZE 4096 #define PvToVMBase(pv) ((void *)((ULONG)pv & 0xFFFF0000)) static BOOL VMValidatePvEx(VOID *pv, ULONG cbCluster) { VOID * pvBase; BYTE * pb; pvBase = PvToVMBase(pv); pb = (BYTE *)pvBase + sizeof(ULONG); while (pb < (BYTE *)pv) { if (*pb++ != 0xAD) { TrapSz("VMValidatePvEx: Block leader overwrite"); return(FALSE); } } if (cbCluster != 1) { ULONG cb = *((ULONG *)pvBase); ULONG cbPad = 0; if (cb % cbCluster) cbPad = (cbCluster - (cb % cbCluster)); if (cbPad) { BYTE *pbMac; pb = (BYTE *)pv + cb; pbMac = pb + cbPad; while (pb < pbMac) { if (*pb++ != 0xBC) { TrapSz("VMValidatePvEx: Block trailer overwrite"); return(FALSE); } } } } return(TRUE); } VOID * EXPORTDBG __cdecl VMAlloc(ULONG cb) { return VMAllocEx(cb, 1); } VOID * EXPORTDBG __cdecl VMAllocEx(ULONG cb, ULONG cbCluster) { ULONG cbAlloc; VOID * pvR; VOID * pvC; ULONG cbPad = 0; // a cluster size of 0 means don't use the virtual allocator. AssertSz(cbCluster != 0, "Cluster size is zero."); if (cb > 0x100000) return(0); if (cb % cbCluster) /*lint !e414*/ cbPad = (cbCluster - (cb % cbCluster)); cbAlloc = sizeof(ULONG) + cb + cbPad + PAGE_SIZE - 1; cbAlloc -= cbAlloc % PAGE_SIZE; cbAlloc += PAGE_SIZE; pvR = VirtualAlloc(0, cbAlloc, MEM_RESERVE, PAGE_NOACCESS); if (pvR == 0) return(0); pvC = VirtualAlloc(pvR, cbAlloc - PAGE_SIZE, MEM_COMMIT, PAGE_READWRITE); if (pvC != pvR) { VirtualFree(pvR, 0, MEM_RELEASE); /*lint !e534*/ return(0); } *(ULONG *)pvC = cb; memset((BYTE *)pvC + sizeof(ULONG), 0xAD, (UINT) cbAlloc - cb - cbPad - sizeof(ULONG) - PAGE_SIZE); if (cbPad) memset((BYTE *)pvC + cbAlloc - PAGE_SIZE - cbPad, 0xBC, (UINT) cbPad); return((BYTE *)pvC + (cbAlloc - cb - cbPad - PAGE_SIZE)); } VOID EXPORTDBG __cdecl VMFree(VOID *pv) { VMFreeEx(pv, 1); } VOID EXPORTDBG __cdecl VMFreeEx(VOID *pv, ULONG cbCluster) { /*lint -save -e534*/ VMValidatePvEx(pv, cbCluster); /*lint -restore*/ if (!VirtualFree(PvToVMBase(pv), 0, MEM_RELEASE)) { TrapSz("VMFreeEx: VirtualFree failed"); GetLastError(); } } VOID * EXPORTDBG __cdecl VMRealloc(VOID *pv, ULONG cb) { return VMReallocEx(pv, cb, 1); } VOID * EXPORTDBG __cdecl VMReallocEx(VOID *pv, ULONG cb, ULONG cbCluster) { VOID * pvNew = 0; ULONG cbCopy; /*lint -save -e534*/ VMValidatePvEx(pv, cbCluster); /*lint -restore*/ cbCopy = *(ULONG *)PvToVMBase(pv); if (cbCopy > cb) cbCopy = cb; pvNew = VMAllocEx(cb, cbCluster); if (pvNew) { memcpy(pvNew, pv, cbCopy); VMFreeEx(pv, cbCluster); } return(pvNew); } ULONG EXPORTDBG __cdecl VMGetSize(VOID *pv) { return VMGetSizeEx(pv, 1); } /*lint -save -e715*/ ULONG EXPORTDBG __cdecl VMGetSizeEx(VOID *pv, ULONG cbCluster) { return (*(ULONG *)PvToVMBase(pv)); } /*lint -restore*/ #endif