Files
admin
base
com
developer
drivers
ds
enduser
inetcore
inetsrv
loc
mergedcomponents
multimedia
net
printscan
ddk
dload
fax
activefax
admin
config
dumpqueue
exchange
faxcover
faxisapi
faxqueue
faxview
help
inc
itg
lib
perfmon
print
provider
samples
broadcast
faxapi
faxsiren
ncfsp
acctwiz.cpp
cfgtest.c
chkboxs.bmp
config.cpp
inet.bmp
inetwrld.bmp
makefile
mem.cpp
nc.h
nc.ico
nc.reg
netcntrc.cpp
netcntrc.def
netcntrc.rc
readme.txt
registry.cpp
resource.h
sources
util.cpp
world.bmp
newfsp
printsdi
simple
service
setup
shellext
test
tiff
util
web
coffbase.txt
dirs
faxsrc.inc
makefil0
placefil.txt
setenv.cmd
faxsrv
inc
lib
print
publish
scan
ui
wia
dirs
project.mk
public
published
sdktools
shell
termsrv
tools
windows
dirs
makefil0
WindowsXP/printscan/fax/samples/ncfsp/mem.cpp
2025-04-27 07:49:33 -04:00

307 lines
6.3 KiB
C++

/*++
Copyright (c) 1995 Microsoft Corporation
Module Name:
mem.c
Abstract:
This file implements memory allocation functions for fax.
Author:
Wesley Witt (wesw) 23-Jan-1995
Environment:
User Mode
--*/
#include "nc.h"
HANDLE hHeap;
DWORD HeapFlags;
PMEMALLOC pMemAllocUser;
PMEMFREE pMemFreeUser;
#ifdef FAX_HEAP_DEBUG
LIST_ENTRY HeapHeader;
ULONG TotalMemory;
ULONG MaxTotalMemory;
ULONG MaxTotalAllocs;
VOID PrintAllocations(VOID);
ULONG TotalAllocs;
CRITICAL_SECTION CsHeap;
#endif
BOOL
HeapExistingInitialize(
HANDLE hExistHeap
)
{
#ifdef FAX_HEAP_DEBUG
InitializeListHead( &HeapHeader );
MaxTotalMemory = 0;
MaxTotalAllocs = 0;
InitializeCriticalSection( &CsHeap );
#endif
if (!hExistHeap) {
return FALSE;
}
else {
hHeap = hExistHeap;
return TRUE;
}
}
HANDLE
HeapInitialize(
HANDLE hHeapUser,
PMEMALLOC pMemAlloc,
PMEMFREE pMemFree,
DWORD Flags
)
{
#ifdef FAX_HEAP_DEBUG
InitializeListHead( &HeapHeader );
MaxTotalMemory = 0;
MaxTotalAllocs = 0;
InitializeCriticalSection( &CsHeap );
#endif
HeapFlags = Flags;
if (pMemAlloc && pMemFree) {
pMemAllocUser = pMemAlloc;
pMemFreeUser = pMemFree;
} else {
if (hHeapUser) {
hHeap = hHeapUser;
} else {
hHeap = HeapCreate( 0, HEAP_SIZE, 0 );
}
if (!hHeap) {
return NULL;
}
}
return hHeap;
}
BOOL
HeapCleanup(
VOID
)
{
#ifdef FAX_HEAP_DEBUG
PrintAllocations();
#endif
HeapDestroy( hHeap );
return TRUE;
}
#ifdef FAX_HEAP_DEBUG
VOID
pCheckHeap(
PVOID MemPtr,
ULONG Line,
LPSTR File
)
{
HeapValidate( hHeap, 0, MemPtr );
}
#endif
PVOID
pMemAlloc(
ULONG AllocSize
#ifdef FAX_HEAP_DEBUG
, ULONG Line,
LPSTR File
#endif
)
{
PVOID MemPtr;
#ifdef FAX_HEAP_DEBUG
PHEAP_BLOCK hb;
#ifdef UNICODE
WCHAR fname[MAX_PATH];
#endif
LPWSTR p = NULL;
if (pMemAllocUser) {
hb = (PHEAP_BLOCK) pMemAllocUser( AllocSize + sizeof(HEAP_BLOCK) );
} else {
hb = (PHEAP_BLOCK) HeapAlloc( hHeap, HEAP_ZERO_MEMORY, AllocSize + sizeof(HEAP_BLOCK) );
}
if (hb) {
TotalAllocs += 1;
TotalMemory += AllocSize;
if (TotalMemory > MaxTotalMemory) {
MaxTotalMemory = TotalMemory;
}
if (TotalAllocs > MaxTotalAllocs) {
MaxTotalAllocs = TotalAllocs;
}
EnterCriticalSection( &CsHeap );
InsertTailList( &HeapHeader, &hb->ListEntry );
hb->Signature = HEAP_SIG;
hb->Size = AllocSize;
hb->Line = Line;
#ifdef UNICODE
MultiByteToWideChar(
CP_ACP,
MB_PRECOMPOSED,
File,
-1,
fname,
sizeof(fname)/sizeof(WCHAR)
);
p = wcsrchr( fname, L'\\' );
if (p) {
wcscpy( hb->File, p+1 );
}
#else
p = strrchr( File, '\\' );
if (p) {
strcpy( hb->File, p+1 );
}
#endif
MemPtr = (PVOID) ((PUCHAR)hb + sizeof(HEAP_BLOCK));
LeaveCriticalSection( &CsHeap );
} else {
MemPtr = NULL;
}
#else
if (pMemAllocUser) {
MemPtr = (PVOID) pMemAllocUser( AllocSize );
} else {
MemPtr = (PVOID) HeapAlloc( hHeap, HEAP_ZERO_MEMORY, AllocSize );
}
#endif
if (!MemPtr) {
DebugPrint(( L"MemAlloc() failed, size=%d", AllocSize ));
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
}
return MemPtr;
}
VOID
pMemFreeForHeap(
HANDLE hHeap,
PVOID MemPtr
#ifdef FAX_HEAP_DEBUG
, ULONG Line,
LPSTR File
#endif
)
{
#ifdef FAX_HEAP_DEBUG
PHEAP_BLOCK hb;
if (!MemPtr) {
return;
}
hb = (PHEAP_BLOCK) ((PUCHAR)MemPtr - sizeof(HEAP_BLOCK));
if (hb->Signature == HEAP_SIG) {
EnterCriticalSection( &CsHeap );
RemoveEntryList( &hb->ListEntry );
TotalMemory -= hb->Size;
TotalAllocs -= 1;
} else {
if (HeapFlags & HEAPINIT_NO_VALIDATION) {
hb = (PHEAP_BLOCK) MemPtr;
EnterCriticalSection( &CsHeap );
} else {
dprintf( L"MemFree(): Corrupt heap block" );
PrintAllocations();
__try {
DebugBreak();
} __except (UnhandledExceptionFilter(GetExceptionInformation())) {
// Nothing to do in here.
}
}
}
if (pMemFreeUser) {
pMemFreeUser( (PVOID) hb );
} else {
HeapFree( hHeap, 0, (PVOID) hb );
}
LeaveCriticalSection( &CsHeap );
#else
if (!MemPtr) {
return;
}
if (pMemFreeUser) {
pMemFreeUser( (PVOID) MemPtr );
} else {
HeapFree( hHeap, 0, (PVOID) MemPtr );
}
#endif
}
VOID
pMemFree(
PVOID MemPtr
#ifdef FAX_HEAP_DEBUG
, ULONG Line,
LPSTR File
#endif
)
{
#ifdef FAX_HEAP_DEBUG
pMemFreeForHeap( hHeap, MemPtr, Line, File );
#else
pMemFreeForHeap( hHeap, MemPtr );
#endif
}
#ifdef FAX_HEAP_DEBUG
VOID
PrintAllocations(
VOID
)
{
PLIST_ENTRY Next;
PHEAP_BLOCK hb;
LPWSTR s;
dprintf( L"-------------------------------------------------------------------------------------------------------" );
dprintf( L"Memory Allocations for Heap 0x%08x, Allocs=%d, MaxAllocs=%d, TotalMem=%d, MaxTotalMem=%d",\
hHeap, TotalAllocs, MaxTotalAllocs, TotalMemory, MaxTotalMemory );
dprintf( L"-------------------------------------------------------------------------------------------------------" );
Next = HeapHeader.Flink;
if (Next == NULL || TotalAllocs == 0) {
return;
}
while ((ULONG)Next != (ULONG)&HeapHeader) {
hb = CONTAINING_RECORD( Next, HEAP_BLOCK, ListEntry );
Next = hb->ListEntry.Flink;
s = (LPWSTR) ((PUCHAR)hb + sizeof(HEAP_BLOCK));
dprintf( L"%8d %16s @ %5d 0x%08x", hb->Size, hb->File, hb->Line, s );
if (!(HeapFlags & HEAPINIT_NO_STRINGS)) {
dprintf( L" \"%s\"", s );
}
}
return;
}
#endif