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.
182 lines
4.0 KiB
182 lines
4.0 KiB
/*
|
|
* 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 <windows.h>
|
|
#include <caldbg.h>
|
|
|
|
#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
|