windows-nt/Source/XPSP1/NT/base/fs/rdr2/rxce/daytona/rxcemm.c

270 lines
6.5 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++
Copyright (c) 1989 Microsoft Corporation
Module Name:
rxcemm.c
Abstract:
This module contains the NT implementation of memory management for RxCe.
Notes:
--*/
#include "precomp.h"
#pragma hdrstop
#include "rxtdip.h"
//
// The debug trace level
//
#define Dbg (DEBUG_TRACE_RXCEPOOL)
#define RXCE_ZONE_ALLOCATION 0x80
//
// Pool debugging data structures.
//
LIST_ENTRY s_RxMdlList;
// MDL debugging structures.
typedef struct _WRAPPED_RX_MDL {
LIST_ENTRY Next;
PUCHAR File;
int Line;
PMDL pMdl;
} WRAPPED_RX_MDL, *PWRAPPED_RX_MDL;
//
// Pool header data structure. Ensure it is 8 byte aligned, no
// matter what members are added to the pool header
//
typedef struct _RX_POOL_HEADER {
union {
struct _RXH {
BYTE Signature[ 16 ];
ULONG Size;
ULONG Type;
PSZ AFileName;
ULONG ALineNumber;
PSZ FFileName;
ULONG FLineNumber;
};
UCHAR _pad[ (sizeof( struct _RXH ) + 7) & (~7) ];
};
} RX_POOL_HEADER, *PRX_POOL_HEADER;
//
// Number of trailer bytes after a pool allocation with a known signature
//
#define TRAIL_BYTES 16
#ifdef RX_POOL_WRAPPER
PVOID
_RxAllocatePoolWithTag(
ULONG Type,
ULONG Size,
ULONG Tag,
PSZ FileName,
ULONG LineNumber
)
/*++
Routine Description:
This routine allocates the desired pool and sets up the debugging header and trailer
to catch most instances of memory trashing
Arguments:
Type - type of pool to be allocated
Size - size of the allocation
Return Value:
a valid pointer if successful, otherwise FALSE.
--*/
{
#if 0
PCHAR pBuffer;
PRX_POOL_HEADER pPoolHeader;
ASSERT( Size != 0 );
ASSERT(
Type == PagedPool ||
Type == (PagedPool | POOL_COLD_ALLOCATION) ||
Type == NonPagedPool);
ASSERT( (sizeof(RX_POOL_HEADER)&7) == 0 );
pPoolHeader = ExAllocatePoolWithTagPriority(
Type,
sizeof( *pPoolHeader ) + Size + TRAIL_BYTES,
Tag,
LowPoolPriority);
if ( pPoolHeader == NULL ) {
RxLog(("RA:NULL %d %d %s\n", Type, LineNumber, &FileName[24]));
return( NULL );
}
//
// Fill the head so we can verify valid free's
//
RtlFillMemory( pPoolHeader->Signature, sizeof( pPoolHeader->Signature ), 'H' );
pPoolHeader->Size = Size;
pPoolHeader->Type = Type;
pPoolHeader->AFileName = FileName;
pPoolHeader->ALineNumber = LineNumber;
pPoolHeader->FFileName = NULL;
pPoolHeader->FLineNumber = 0;
pBuffer = (PCHAR)(pPoolHeader + 1);
//
// Fill the memory to catch uninitialized structures, etc
//
RtlFillMemory( pBuffer, Size, '*' );
//
// Fill the tail to catch overruns
//
RtlFillMemory( pBuffer + Size, TRAIL_BYTES, 'T' );
//
// Make sure we're starting out valid
//
RxCheckMemoryBlock( pBuffer );
return( pBuffer );
#endif
return ExAllocatePoolWithTagPriority(
Type,Size,Tag,LowPoolPriority);
}
VOID
_RxFreePool( PVOID pBuffer, PSZ FileName, ULONG LineNumber )
{
#if 0
if( _RxCheckMemoryBlock( pBuffer, FileName, LineNumber ) ) {
PRX_POOL_HEADER pPoolHeader = ((PRX_POOL_HEADER)pBuffer) - 1;
//
// Zap the block, to catch cases where we are using freed blocks
//
RtlFillMemory( pPoolHeader->Signature,
sizeof( pPoolHeader->Signature ),
'F' );
pPoolHeader->FFileName = FileName;
pPoolHeader->FLineNumber = LineNumber;
RtlFillMemory( pPoolHeader+1,
pPoolHeader->Size + TRAIL_BYTES,
'F' );
ExFreePool( pPoolHeader );
}
#endif
ExFreePool(pBuffer);
}
BOOLEAN
_RxCheckMemoryBlock(
PVOID pBuffer,
PSZ FileName,
ULONG LineNumber
)
/*++
Routine Description:
This routine frees up the pool allocated through RxAllocate
Arguments:
pv - the block to be freed
--*/
{
PRX_POOL_HEADER pPoolHeader = ((PRX_POOL_HEADER)pBuffer) - 1;
PCHAR pTail;
ULONG i;
if( pBuffer == NULL ) {
DbgPrint( "RxCheckMemoryBlock( NULL ) at %s %d\n",
FileName, LineNumber );
DbgBreakPoint();
return FALSE;
}
//
// Make sure we have a valid block
//
for( i=0; i < sizeof( pPoolHeader->Signature ); i++ ) {
if( pPoolHeader->Signature[i] != 'H' ) {
if( pPoolHeader->Signature[i] == 'F' && i == 0 ) {
DbgPrint( "RxFreePool: Likely double free on block at %X\n", pPoolHeader );
}
DbgPrint( "RxCheckMemoryBlock: Invalid header signature for block %X\n", pPoolHeader );
DbgPrint( " Called from %s %d\n", FileName, LineNumber );
DbgPrint( " Originally Freed at %s %d\n",pPoolHeader->FFileName,pPoolHeader->FLineNumber);
DbgPrint( " Size is x%X, user part at %X\n", pPoolHeader->Size, pPoolHeader + 1 );
DbgBreakPoint();
return FALSE;
}
}
if( pPoolHeader->Type != PagedPool &&
pPoolHeader->Type != (PagedPool | POOL_COLD_ALLOCATION) &&
pPoolHeader->Type != NonPagedPool) {
DbgPrint( "RxCheckMemoryBlock:\n" );
DbgPrint( " Invalid PoolHeader->Type for block %X\n", pPoolHeader );
DbgPrint( " Called from %s %d\n", FileName, LineNumber );
DbgBreakPoint();
return FALSE;
}
if( pPoolHeader->Size == 0 ) {
DbgPrint( "RxCheckMemoryBlock:\n" );
DbgPrint( " Size is 0 for block %X\n", pPoolHeader );
DbgPrint( " Called from %s %d\n", FileName, LineNumber );
DbgBreakPoint();
return FALSE;
}
//
// Look to see if the buffer has been overrun
//
pTail = (PCHAR)pBuffer + pPoolHeader->Size;
for( i=0; i < TRAIL_BYTES; i++ ) {
if( *pTail++ != 'T' ) {
DbgPrint( "RxCheckMemoryBlock: Overrun memory block at %X\n", pPoolHeader );
DbgPrint( " RxCheckMemoryBlock called from %s line %d\n", FileName, LineNumber );
DbgPrint( " Allocated at %s line %d\n", pPoolHeader->AFileName, pPoolHeader->ALineNumber );
DbgPrint( " Size is x%X, user part at %X\n", pPoolHeader->Size, pPoolHeader + 1 );
DbgPrint( " Overrun begins at %X\n", pTail-1 );
DbgBreakPoint();
return FALSE;
}
}
return TRUE;
}
#endif