WindowsXP-SP1/ds/dns/dnslib/heapdbg.c

1442 lines
27 KiB
C
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
Copyright (c) 1995-2001 Microsoft Corporation
Module Name:
heapdbg.c
Abstract:
Domain Name System (DNS) Library
Heap debugging routines.
Author:
Jim Gilroy (jamesg) January 31, 1995
Revision History:
--*/
#include "local.h"
#include "heapdbg.h"
//
// locking
//
#define LOCK_HEAP(p) EnterCriticalSection( &p->ListCs )
#define UNLOCK_HEAP(p) LeaveCriticalSection( &p->ListCs )
//
// Heap
//
// Debug heap routines allow heap to be specified by caller of
// each routine, or by having heap global.
// If global, the heap handle may be supplied to initialization
// routine OR created internally.
//
#define HEAP_DBG_DEFAULT_CREATE_FLAGS \
( HEAP_GROWABLE | \
HEAP_GENERATE_EXCEPTIONS | \
HEAP_TAIL_CHECKING_ENABLED | \
HEAP_FREE_CHECKING_ENABLED | \
HEAP_CREATE_ALIGN_16 | \
HEAP_CLASS_1 )
//
// Dnslib using this heap
//
PHEAP_BLOB g_pDnslibHeapBlob;
HEAP_BLOB g_DnslibHeapBlob;
//
// Heap Header / Trailer Flags
//
#define HEAP_CODE 0xdddddddd
#define HEAP_CODE_ACTIVE 0xaaaaaaaa
#define HEAP_CODE_FREE 0xeeeeeeee
//
// Heap Trailer from Header
//
#define HEAP_TRAILER(_head_) \
( (PHEAP_TRAILER) ( \
(PCHAR)(_head_) \
+ (_head_)->AllocSize \
- sizeof(HEAP_TRAILER) ) )
//
// Private protos
//
VOID
DbgHeapValidateHeader(
IN PHEAP_HEADER h
);
//
// Private utilities
//
INT
DbgHeapFindAllocSize(
IN INT iRequestSize
)
/*++
Routine Description:
Determines actual size of debug alloc.
Adds in sizes of DWORD aligned header and trailer.
Arguments:
iRequestSize - requested allocation size
Return Value:
None
--*/
{
register INT imodSize;
//
// find DWORD multiple size of original alloc,
// this is required so debug trailer will be DWORD aligned
//
imodSize = iRequestSize % sizeof(DWORD);
if ( imodSize )
{
imodSize = sizeof(DWORD) - imodSize;
}
imodSize += iRequestSize + sizeof(HEAP_HEADER) + sizeof(HEAP_TRAILER);
ASSERT( ! (imodSize % sizeof(DWORD)) );
return( imodSize );
}
PVOID
DbgHeapSetHeaderAlloc(
IN OUT PHEAP_BLOB pHeap,
IN OUT PHEAP_HEADER h,
IN INT iSize,
IN LPSTR pszFile,
IN DWORD dwLine
)
/*++
Routine Description:
Sets/Resets heap globals and heap header info.
Arguments:
h - ptr to new memory block
iSize - size allocated
Return Value:
None
--*/
{
PHEAP_TRAILER t;
INT allocSize;
ASSERT( iSize > 0 );
//
// determine actual alloc
//
allocSize = DbgHeapFindAllocSize( iSize );
//
// update heap info globals
//
pHeap->AllocMem += allocSize;
pHeap->CurrentMem += allocSize;
pHeap->AllocCount++;
pHeap->CurrentCount++;
//
// fill in header
//
h->HeapCodeBegin = HEAP_CODE;
h->AllocCount = pHeap->AllocCount;
h->AllocSize = allocSize;
h->RequestSize = iSize;
h->LineNo = dwLine;
h->FileName = pszFile;
#if 0
allocSize = strlen(pszFile) - HEAP_HEADER_FILE_SIZE;
if ( allocSize > 0 )
{
pszFile = &pszFile[ allocSize ];
}
strncpy(
h->FileName,
pszFile,
HEAP_HEADER_FILE_SIZE );
#endif
h->AllocTime = GetCurrentTime();
h->CurrentMem = pHeap->CurrentMem;
h->CurrentCount = pHeap->CurrentCount;
h->HeapCodeEnd = HEAP_CODE_ACTIVE;
//
// fill in trailer
//
t = HEAP_TRAILER( h );
t->HeapCodeBegin = h->HeapCodeBegin;
t->AllocCount = h->AllocCount;
t->AllocSize = h->AllocSize;
t->HeapCodeEnd = h->HeapCodeEnd;
//
// attach to alloc list
//
LOCK_HEAP(pHeap);
InsertTailList( &pHeap->ListHead, &h->ListEntry );
UNLOCK_HEAP(pHeap);
//
// return ptr to user memory
// - first byte past header
//
return( h+1 );
}
PHEAP_HEADER
DbgHeapSetHeaderFree(
IN OUT PHEAP_BLOB pHeap,
IN OUT PVOID pMem
)
/*++
Routine Description:
Resets heap globals and heap header info for free.
Arguments:
pMem - ptr to user memory to free
Return Value:
Ptr to block to be freed.
--*/
{
register PHEAP_HEADER h;
//
// validate memory block -- get ptr to header
//
h = Dns_DbgHeapValidateMemory( pMem, TRUE );
//
// get blob if not passed in
//
if ( !pHeap )
{
pHeap = h->pHeap;
}
//
// remove from current allocs list
//
LOCK_HEAP(pHeap);
RemoveEntryList( &h->ListEntry );
UNLOCK_HEAP(pHeap);
//
// update heap info globals
//
pHeap->CurrentMem -= h->AllocSize;
pHeap->FreeMem += h->AllocSize;
pHeap->FreeCount++;
pHeap->CurrentCount--;
//
// reset header
//
h->HeapCodeEnd = HEAP_CODE_FREE;
HEAP_TRAILER(h)->HeapCodeBegin = HEAP_CODE_FREE;
//
// return ptr to block to be freed
//
return( h );
}
//
// Heap Init\Cleanup
//
VOID
Dns_HeapInitialize(
OUT PHEAP_BLOB pHeap,
IN HANDLE hHeap,
IN DWORD dwCreateFlags,
IN BOOL fUseHeaders,
IN BOOL fResetDnslib,
IN BOOL fFullHeapChecks,
IN DWORD dwException,
IN DWORD dwDefaultFlags,
IN PSTR pszDefaultFileName,
IN DWORD dwDefaultFileLine
)
/*++
Routine Description:
Initialize heap debugging.
MUST call this routine before using DbgHeapMessage routines.
Arguments:
pHeap -- heap blob to setup
hHeap -- heap to use
dwCreateFlags -- flags to RtlCreateHeap() if creating
fUseHeaders -- use headers and trailers for full debug
fResetDnslib -- reset dnslib heap to use these routines
fFullHeapChecks -- flag, TRUE for full heap checks
dwException -- exception to raise if out of heap
dwDefaultFlags -- heap flags for simple alloc\free
pszDefaultFileName -- file name for simple alloc\free
dwDefaultFileLine -- file line# for simple alloc\free
Return Value:
None.
--*/
{
DNSDBG( TRACE, (
"Dns_DbgHeapInit( %p )\n",
pHeap ));
//
// zero heap blob
//
RtlZeroMemory(
pHeap,
sizeof(*pHeap) );
// alloc list
// - alloc list head
// - critical section to protect list operations
InitializeListHead( &pHeap->ListHead );
if ( fUseHeaders )
{
InitializeCriticalSection( &pHeap->ListCs );
}
//
// heap
// can either
// - always get heap in each call
// - use heap caller supplies here
// - create a heap here
//
// to use simple dnslib compatible calls we must have
// a known heap, so must get one created here
// DCR: not sure this is TRUE, process heap may work
// g_hDnsHeap left NULL
//
if ( hHeap )
{
pHeap->hHeap = hHeap;
}
else
{
pHeap->hHeap = RtlCreateHeap(
dwCreateFlags
? dwCreateFlags
: HEAP_DBG_DEFAULT_CREATE_FLAGS,
NULL, // no base specified
0, // default reserve size
0, // default commit size
NULL, // no lock
NULL // no parameters
);
pHeap->fCreated = TRUE;
}
pHeap->Tag = HEAP_CODE_ACTIVE;
// set globals
// - full heap checks before all heap operations?
// - raise exception on alloc failure?
pHeap->fHeaders = fUseHeaders;
pHeap->fCheckAll = fFullHeapChecks;
pHeap->FailureException = dwException;
// set globals for simple allocator
pHeap->DefaultFlags = dwDefaultFlags;
pHeap->pszDefaultFile = pszDefaultFileName;
pHeap->DefaultLine = dwDefaultFileLine;
// reset dnslib heap routines to use debug heap
if ( fResetDnslib )
{
if ( fUseHeaders )
{
Dns_LibHeapReset(
Dns_DbgHeapAlloc,
Dns_DbgHeapRealloc,
Dns_DbgHeapFree );
}
else
{
Dns_LibHeapReset(
Dns_HeapAlloc,
Dns_HeapRealloc,
Dns_HeapFree );
}
g_pDnslibHeapBlob = pHeap;
}
}
VOID
Dns_HeapCleanup(
IN OUT PHEAP_BLOB pHeap
)
/*++
Routine Description:
Cleanup.
Arguments:
None.
Return Value:
None.
--*/
{
DNSDBG( TRACE, ( "Dns_HeapCleanup( %p )\n", pHeap ));
// if not initialized -- do nothing
if ( !pHeap )
{
return;
}
if ( pHeap->Tag != HEAP_CODE_ACTIVE )
{
DNS_ASSERT( pHeap->Tag == HEAP_CODE_ACTIVE );
return;
}
DNS_ASSERT( pHeap->hHeap );
// if created heap, destroy it
if ( pHeap->fCreated )
{
RtlDestroyHeap( pHeap->hHeap );
}
// cleanup critical section
if ( pHeap->fHeaders )
{
RtlDeleteCriticalSection( &pHeap->ListCs );
}
// tag as invalid
pHeap->Tag = HEAP_CODE_FREE;
}
//
// Heap Validation
//
VOID
DbgHeapValidateHeader(
IN PHEAP_HEADER h
)
/*++
Routine Description:
Validates heap header.
Arguments:
h - ptr to header of block
Return Value:
None.
--*/
{
register PHEAP_TRAILER t;
//
// extract trailer
//
t = HEAP_TRAILER( h );
//
// verify header
//
if ( h->HeapCodeBegin != HEAP_CODE
||
h->HeapCodeEnd != HEAP_CODE_ACTIVE )
{
DNSDBG( HEAPDBG, (
"Invalid memory block at %p -- invalid header.\n",
h ));
if ( h->HeapCodeEnd == HEAP_CODE_FREE )
{
DNSDBG( HEAPDBG, (
"ERROR: Previous freed memory.\n" ));
}
goto Invalid;
}
//
// match header, trailer alloc number
//
if ( h->HeapCodeBegin != t->HeapCodeBegin
||
h->AllocCount != t->AllocCount
||
h->AllocSize != t->AllocSize
||
h->HeapCodeEnd != t->HeapCodeEnd )
{
DNSDBG( HEAPDBG, (
"Invalid memory block at %p -- header / trailer mismatch.\n",
h ));
goto Invalid;
}
return;
Invalid:
DNSDBG( ANY, (
"Validation failure, in heap blob %p\n",
h->pHeap ));
Dns_DbgHeapHeaderPrint( h, t );
ASSERT( FALSE );
Dns_DbgHeapGlobalInfoPrint( h->pHeap );
Dns_DbgHeapDumpAllocList( h->pHeap );
ASSERT( FALSE );
return;
}
PHEAP_HEADER
Dns_DbgHeapValidateMemory(
IN PVOID pMem,
IN BOOL fAtHeader
)
/*++
Routine Description:
Validates users heap pointer, and returns actual.
Note: This memory MUST have been allocated by THESE MEMORY routines.
Arguments:
pMem - ptr to memory to validate
fAtHeader - TRUE if pMem is known to be immediately after a head header,
otherwise this function will search backwards through memory starting
at pMem looking for a valid heap header
Return Value:
Pointer to actual heap pointer.
--*/
{
register PHEAP_HEADER pheader;
//
// Get pointer to heap header.
//
pheader = (PHEAP_HEADER) pMem - 1;
if ( !fAtHeader )
{
int iterations = 32 * 1024;
//
// Back up from pMem a DWORD at a time looking for HEAP_CODE.
// If we don't find one, eventually we will generate an exception,
// which will be interesting. This could be handled, but for now
// this loop will just walk to past the start of valid memory.
//
while ( 1 )
{
//
// Break if we've found the heap header.
//
if ( pheader->HeapCodeBegin == HEAP_CODE &&
( pheader->HeapCodeEnd == HEAP_CODE_ACTIVE ||
pheader->HeapCodeEnd == HEAP_CODE_FREE ) )
{
break;
}
//
// Sanity check: too many iterations?
//
if ( ( --iterations ) == 0 )
{
ASSERT( iterations > 0 );
return NULL;
}
//
// Back up another DWORD.
//
pheader = ( PHEAP_HEADER ) ( ( PBYTE ) pheader - 4 );
}
}
//
// Verify header and trailer.
//
DbgHeapValidateHeader( pheader );
return pheader;
}
VOID
Dns_DbgHeapValidateAllocList(
IN OUT PHEAP_BLOB pHeap
)
/*++
Routine Description:
Dumps header information for all nodes in alloc list.
Arguments:
None
Return Value:
None
--*/
{
PLIST_ENTRY pentry;
DNSDBG( TRACE, (
"Dns_DbgHeapValidateAllocList( %p )\n",
pHeap ));
if ( !pHeap->fHeaders )
{
DNS_ASSERT( pHeap->fHeaders );
return;
}
//
// loop through all outstanding alloc's, validating each one
//
LOCK_HEAP(pHeap);
pentry = pHeap->ListHead.Flink;
while( pentry != &pHeap->ListHead )
{
DbgHeapValidateHeader( HEAP_HEADER_FROM_LIST_ENTRY(pentry) );
pentry = pentry->Flink;
}
UNLOCK_HEAP(pHeap);
}
//
// Heap Printing
//
VOID
Dns_DbgHeapGlobalInfoPrint(
IN PHEAP_BLOB pHeap
)
/*++
Routine Description:
Prints global heap info.
Arguments:
None
Return Value:
None
--*/
{
DNS_PRINT((
"Debug Heap Information:\n"
"\tHeap Blob = %p\n"
"\tHandle = %p\n"
"\tDebug headers = %d\n"
"\tDnslib redirect = %d\n"
"\tFull checks = %d\n"
"\tFlags = %08x\n"
"\tStats ---------------\n"
"\tMemory Allocated = %d\n"
"\tMemory Freed = %d\n"
"\tMemory Current = %d\n"
"\tAlloc Count = %d\n"
"\tFree Count = %d\n"
"\tCurrent Count = %d\n",
pHeap,
pHeap->hHeap,
pHeap->fHeaders,
pHeap->fDnsLib,
pHeap->fCheckAll,
pHeap->DefaultFlags,
pHeap->AllocMem,
pHeap->FreeMem,
pHeap->CurrentMem,
pHeap->AllocCount,
pHeap->FreeCount,
pHeap->CurrentCount
));
}
VOID
Dns_DbgHeapHeaderPrint(
IN PHEAP_HEADER h,
IN PHEAP_TRAILER t
)
/*++
Routine Description:
Prints heap header and trailer.
Arguments:
None
Return Value:
None
--*/
{
if ( h )
{
DNSDBG( HEAPDBG, (
"Heap Header at %p:\n"
"\tHeapCodeBegin = %08lx\n"
"\tAllocCount = %d\n"
"\tAllocSize = %d\n"
"\tRequestSize = %d\n"
"\tHeapBlob = %p\n"
//"\tFileName = %.*s\n"
"\tFileName = %s\n"
"\tLineNo = %d\n"
"\tAllocTime = %d\n"
"\tCurrentMem = %d\n"
"\tCurrentCount = %d\n"
"\tHeapCodeEnd = %08lx\n",
h,
h->HeapCodeBegin,
h->AllocCount,
h->AllocSize,
h->RequestSize,
h->pHeap,
//HEAP_HEADER_FILE_SIZE,
h->FileName,
h->LineNo,
h->AllocTime / 1000,
h->CurrentMem,
h->CurrentCount,
h->HeapCodeEnd
));
}
if ( t )
{
DNSDBG( HEAPDBG, (
"Heap Trailer at %p:\n"
"\tHeapCodeBegin = %08lx\n"
"\tAllocCount = %d\n"
"\tAllocSize = %d\n"
"\tHeapCodeEnd = %08lx\n",
t,
t->HeapCodeBegin,
t->AllocCount,
t->AllocSize,
t->HeapCodeEnd
));
}
}
VOID
Dns_DbgHeapDumpAllocList(
IN PHEAP_BLOB pHeap
)
/*++
Routine Description:
Dumps header information for all nodes in alloc list.
Arguments:
None
Return Value:
None
--*/
{
PLIST_ENTRY pentry;
PHEAP_HEADER phead;
if ( !pHeap->fHeaders )
{
DNSDBG( HEAPDBG, ( "Non-debug heap -- no alloc list!\n" ));
return;
}
//
// loop through all outstanding alloc's, dumping output
//
LOCK_HEAP(pHeap);
DNSDBG( HEAPDBG, ( "Dumping Alloc List:\n" ));
pentry = pHeap->ListHead.Flink;
while( pentry != &pHeap->ListHead )
{
phead = HEAP_HEADER_FROM_LIST_ENTRY( pentry );
Dns_DbgHeapHeaderPrint(
phead,
HEAP_TRAILER( phead )
);
pentry = pentry->Flink;
}
DNSDBG( HEAPDBG, ( "End Dump of Alloc List.\n" ));
UNLOCK_HEAP(pHeap);
}
//
// Full debug heap routines
//
PVOID
Dns_DbgHeapAllocEx(
IN OUT PHEAP_BLOB pHeap,
IN DWORD dwFlags,
IN INT iSize,
IN LPSTR pszFile,
IN DWORD dwLine
)
/*++
Routine Description:
Allocates memory.
Arguments:
iSize - number of bytes to allocate
Return Value:
Pointer to memory allocated.
NULL if allocation fails.
--*/
{
register PHEAP_HEADER h;
INT allocSize;
DNSDBG( HEAP2, (
"Dns_DbgHeapAlloc( %p, %d )\n",
pHeap, iSize ));
//
// full heap check?
//
IF_DNSDBG( HEAP_CHECK )
{
Dns_DbgHeapValidateAllocList( pHeap );
}
if ( iSize <= 0 )
{
DNSDBG( ANY, ( "Invalid alloc size = %d\n", iSize ));
DNS_ASSERT( FALSE );
return( NULL );
}
//
// allocate memory
//
// first add heap header to size
//
allocSize = DbgHeapFindAllocSize( iSize );
h = (PHEAP_HEADER) RtlAllocateHeap(
pHeap->hHeap,
dwFlags
? dwFlags
: pHeap->DefaultFlags,
allocSize );
if ( ! h )
{
Dns_DbgHeapGlobalInfoPrint( pHeap );
return NULL;
}
//
// setup header / globals for new alloc
//
// return ptr to first byte after header
//
return DbgHeapSetHeaderAlloc(
pHeap,
h,
iSize,
pszFile,
dwLine
);
}
PVOID
Dns_DbgHeapReallocEx(
IN OUT PHEAP_BLOB pHeap,
IN DWORD dwFlags,
IN OUT PVOID pMem,
IN INT iSize,
IN LPSTR pszFile,
IN DWORD dwLine
)
/*++
Routine Description:
Reallocates memory
Arguments:
pMem - ptr to existing memory to reallocated
iSize - number of bytes to reallocate
Return Value:
Pointer to memory allocated.
NULL if allocation fails.
--*/
{
register PHEAP_HEADER h;
INT previousSize;
INT allocSize;
//
// full heap check?
//
IF_DNSDBG( HEAP_CHECK )
{
Dns_DbgHeapValidateAllocList( pHeap );
}
if ( iSize <= 0 )
{
DNSDBG( HEAPDBG, ( "Invalid realloc size = %d\n", iSize ));
return( NULL );
}
//
// validate memory
//
// extract pointer to actual alloc'd block
// mark as free, and reset globals appropriately
//
h = DbgHeapSetHeaderFree( pHeap, pMem );
//
// reallocate memory
//
// first add heap header to size
//
allocSize = DbgHeapFindAllocSize( iSize );
h = (PHEAP_HEADER) RtlReAllocateHeap(
pHeap->hHeap,
dwFlags
? dwFlags
: pHeap->DefaultFlags,
h,
allocSize );
if ( ! h )
{
Dns_DbgHeapGlobalInfoPrint( pHeap );
return( NULL );
}
//
// setup header / globals for realloc
//
// return ptr to first byte after header
//
return DbgHeapSetHeaderAlloc(
pHeap,
h,
iSize,
pszFile,
dwLine
);
}
VOID
Dns_DbgHeapFreeEx(
IN OUT PHEAP_BLOB pHeap,
IN DWORD dwFlags,
IN OUT PVOID pMem
)
/*++
Routine Description:
Frees memory
Note: This memory MUST have been allocated by DbgHeap routines.
Arguments:
pMem - ptr to memory to be freed
Return Value:
None.
--*/
{
register PHEAP_HEADER h;
DNSDBG( HEAP2, (
"Dns_DbgHeapFreeEx( %p, %p )\n",
pHeap, pMem ));
//
// validate header
//
// reset heap header / globals for free
//
h = DbgHeapSetHeaderFree( pHeap, pMem );
//
// get blob
//
if ( !pHeap )
{
pHeap = h->pHeap;
}
//
// full heap check?
//
IF_DNSDBG( HEAP_CHECK )
{
Dns_DbgHeapValidateAllocList( pHeap );
}
RtlFreeHeap(
pHeap->hHeap,
dwFlags
? dwFlags
: pHeap->DefaultFlags,
h );
}
//
// Dnslib memory compatible versions
//
// Heap routines with simple function signature that matches
// the dnslib routines and allows DnsLib memory routines to
// be redirected to these routines through Dns_LibHeapReset().
//
// Note: to use these functions, must have specified at particular
// heap to use.
//
PVOID
Dns_DbgHeapAlloc(
IN INT iSize
)
{
return Dns_DbgHeapAllocEx(
g_pDnslibHeapBlob,
0,
iSize,
NULL,
0 );
}
PVOID
Dns_DbgHeapRealloc(
IN OUT PVOID pMem,
IN INT iSize
)
{
return Dns_DbgHeapReallocEx(
g_pDnslibHeapBlob,
0,
pMem,
iSize,
NULL,
0
);
}
VOID
Dns_DbgHeapFree(
IN OUT PVOID pMem
)
{
Dns_DbgHeapFreeEx(
g_pDnslibHeapBlob,
0,
pMem );
}
//
// Non debug header versions
//
// These allow you to use a private heap with some of the features
// of the debug heap
// - same initialization
// - specifying individual heap
// - redirection of dnslib (without building your own routines)
// - alloc and free counts
// but without the overhead of the headers.
//
PVOID
Dns_HeapAllocEx(
IN OUT PHEAP_BLOB pHeap,
IN DWORD dwFlags,
IN INT iSize
)
/*++
Routine Description:
Allocates memory.
Arguments:
pHeap - heap to use
dwFlags - flags
iSize - number of bytes to allocate
Return Value:
Pointer to memory allocated.
NULL if allocation fails.
--*/
{
PVOID p;
DNSDBG( HEAP2, (
"Dns_HeapAlloc( %p, %d )\n",
pHeap, iSize ));
//
// allocate memory
//
p = (PHEAP_HEADER) RtlAllocateHeap(
pHeap->hHeap,
dwFlags
? dwFlags
: pHeap->DefaultFlags,
iSize );
if ( p )
{
pHeap->AllocCount++;
pHeap->CurrentCount++;
}
return p;
}
PVOID
Dns_HeapReallocEx(
IN OUT PHEAP_BLOB pHeap,
IN DWORD dwFlags,
IN OUT PVOID pMem,
IN INT iSize
)
/*++
Routine Description:
Reallocates memory
Arguments:
pMem - ptr to existing memory to reallocated
iSize - number of bytes to reallocate
Return Value:
Pointer to memory allocated.
NULL if allocation fails.
--*/
{
PVOID p;
INT previousSize;
INT allocSize;
//
// reallocate memory
//
// first add heap header to size
//
p = RtlReAllocateHeap(
pHeap->hHeap,
dwFlags
? dwFlags
: pHeap->DefaultFlags,
pMem,
iSize );
if ( p )
{
pHeap->AllocCount++;
pHeap->FreeCount++;
}
return p;
}
VOID
Dns_HeapFreeEx(
IN OUT PHEAP_BLOB pHeap,
IN DWORD dwFlags,
IN OUT PVOID pMem
)
/*++
Routine Description:
Frees memory
Note: This memory MUST have been allocated by DbgHeap routines.
Arguments:
pMem - ptr to memory to be freed
Return Value:
None.
--*/
{
DNSDBG( HEAP2, (
"Dns_HeapFreeEx( %p, %p )\n",
pHeap, pMem ));
RtlFreeHeap(
pHeap->hHeap,
dwFlags
? dwFlags
: pHeap->DefaultFlags,
pMem );
pHeap->FreeCount++;
pHeap->CurrentCount--;
}
//
// Dnslib memory compatible versions
//
// Heap routines with simple function signature that matches
// the dnslib routines and allows DnsLib memory routines to
// be redirected to these routines through Dns_LibHeapReset().
//
// Note: to use these functions, must have specified at particular
// heap to use.
//
PVOID
Dns_HeapAlloc(
IN INT iSize
)
{
return Dns_HeapAllocEx(
g_pDnslibHeapBlob,
0,
iSize );
}
PVOID
Dns_HeapRealloc(
IN OUT PVOID pMem,
IN INT iSize
)
{
return Dns_HeapReallocEx(
g_pDnslibHeapBlob,
0,
pMem,
iSize );
}
VOID
Dns_HeapFree(
IN OUT PVOID pMem
)
{
Dns_HeapFreeEx(
g_pDnslibHeapBlob,
0,
pMem );
}
//
// End heapdbg.c
//