windows-nt/Source/XPSP1/NT/sdktools/vmmreg32/regmem.c
2020-09-26 16:20:57 +08:00

203 lines
5.1 KiB
C

//
// REGMEM.C
//
// Copyright (C) Microsoft Corporation, 1995
//
// Upper-level memory management functions that discards unlocked memory blocks
// as required to fulfill allocation requests.
//
// For the ring zero version of this code, only large requests will call these
// functions. For most registry files, these requests will already be an
// integral number of pages, so it's best just to do page allocations. Small
// allocations, such as key handles, will use the heap services and not go
// through this code.
//
// For all other models of this code, all memory requests will go through this
// code and memory is allocated from the heap.
//
#include "pch.h"
DECLARE_DEBUG_COUNT(g_RgMemoryBlockCount);
// For the ring zero version, only large allocations that should be page
// aligned will pass through these functions.
#ifdef VXD
// Converts number of bytes to number of whole pages.
#define ConvertToMemoryUnits(cb) \
((((cb) + (PAGESIZE - 1)) & ~(PAGESIZE - 1)) >> PAGESHIFT)
// Generates smaller code if we don't just make this a macro...
LPVOID
INTERNAL
RgAllocMemoryUnits(
UINT nPages
)
{
return AllocPages(nPages);
}
// Generates smaller code if we don't just make this a macro...
LPVOID
INTERNAL
RgReAllocMemoryUnits(
LPVOID lpMemory,
UINT nPages
)
{
return ReAllocPages(lpMemory, nPages);
}
#define RgFreeMemoryUnits FreePages
// For non-ring zero version of the registry code, all allocations will funnel
// through these functions. All allocations are off the heap.
#else
#define ConvertToMemoryUnits(cb) (cb)
#define RgAllocMemoryUnits AllocBytes
#define RgReAllocMemoryUnits ReAllocBytes
#define RgFreeMemoryUnits FreeBytes
#endif
//
// RgAllocMemory
//
LPVOID
INTERNAL
RgAllocMemory(
UINT cbBytes
)
{
UINT MemoryUnits;
LPVOID lpMemory;
ASSERT(cbBytes > 0);
MemoryUnits = ConvertToMemoryUnits(cbBytes);
// Can we allocate from available memory?
if (!IsNullPtr((lpMemory = RgAllocMemoryUnits(MemoryUnits)))) {
INCREMENT_DEBUG_COUNT(g_RgMemoryBlockCount);
return lpMemory;
}
RgEnumFileInfos(RgSweepFileInfo);
// Can we allocate after sweeping all old memory blocks?
if (!IsNullPtr((lpMemory = RgAllocMemoryUnits(MemoryUnits)))) {
INCREMENT_DEBUG_COUNT(g_RgMemoryBlockCount);
return lpMemory;
}
// The first sweep will have cleared all the access bits of every memory
// block. This sweep will effectively discard all unlocked blocks.
RgEnumFileInfos(RgSweepFileInfo);
// Can we allocate after sweeping all unlocked and clean memory blocks?
if (!IsNullPtr((lpMemory = RgAllocMemoryUnits(MemoryUnits)))) {
INCREMENT_DEBUG_COUNT(g_RgMemoryBlockCount);
return lpMemory;
}
// Flush out every dirty memory block and sweep again.
RgEnumFileInfos(RgFlushFileInfo);
RgEnumFileInfos(RgSweepFileInfo);
// Can we allocate after sweeping all unlocked memory blocks?
if (!IsNullPtr((lpMemory = RgAllocMemoryUnits(MemoryUnits)))) {
INCREMENT_DEBUG_COUNT(g_RgMemoryBlockCount);
return lpMemory;
}
DEBUG_OUT(("RgAllocMemory failure\n"));
// Return lpMemory, which must be NULL if we're here, generates smaller
// code.
return lpMemory; // Must be NULL if we're here
}
//
// RgReAllocMemory
//
LPVOID
INTERNAL
RgReAllocMemory(
LPVOID lpOldMemory,
UINT cbBytes
)
{
UINT MemoryUnits;
LPVOID lpMemory;
ASSERT(!IsNullPtr(lpOldMemory));
ASSERT(cbBytes > 0);
MemoryUnits = ConvertToMemoryUnits(cbBytes);
// Can we allocate from available memory?
if (!IsNullPtr((lpMemory = RgReAllocMemoryUnits(lpOldMemory, MemoryUnits))))
return lpMemory;
RgEnumFileInfos(RgSweepFileInfo);
// Can we allocate after sweeping all old memory blocks?
if (!IsNullPtr((lpMemory = RgReAllocMemoryUnits(lpOldMemory, MemoryUnits))))
return lpMemory;
// The first sweep will have cleared all the access bits of every memory
// block. This sweep will effectively discard all unlocked blocks.
RgEnumFileInfos(RgSweepFileInfo);
// Can we allocate after sweeping all unlocked and clean memory blocks?
if (!IsNullPtr((lpMemory = RgReAllocMemoryUnits(lpOldMemory, MemoryUnits))))
return lpMemory;
// Flush out every dirty memory block and sweep again.
RgEnumFileInfos(RgFlushFileInfo);
RgEnumFileInfos(RgSweepFileInfo);
// Can we allocate after sweeping all unlocked memory blocks?
if (!IsNullPtr((lpMemory = RgReAllocMemoryUnits(lpOldMemory, MemoryUnits))))
return lpMemory;
DEBUG_OUT(("RgReAllocMemory failure\n"));
// Return lpMemory, which must be NULL if we're here, generates smaller
// code.
return lpMemory;
}
#ifdef DEBUG
//
// RgFreeMemory
//
VOID
INTERNAL
RgFreeMemory(
LPVOID lpMemory
)
{
ASSERT(!IsNullPtr(lpMemory));
DECREMENT_DEBUG_COUNT(g_RgMemoryBlockCount);
#ifdef ZEROONFREE
ZeroMemory(lpMemory, MemorySize(lpMemory));
#endif
RgFreeMemoryUnits(lpMemory);
}
#endif