Leaked source code of windows server 2003
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.

269 lines
6.8 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. rxcemm.c
  5. Abstract:
  6. This module contains the NT implementation of memory management for RxCe.
  7. Notes:
  8. --*/
  9. #include "precomp.h"
  10. #pragma hdrstop
  11. #include "rxtdip.h"
  12. //
  13. // The debug trace level
  14. //
  15. #define Dbg (DEBUG_TRACE_RXCEPOOL)
  16. #define RXCE_ZONE_ALLOCATION 0x80
  17. //
  18. // Pool debugging data structures.
  19. //
  20. LIST_ENTRY s_RxMdlList;
  21. // MDL debugging structures.
  22. typedef struct _WRAPPED_RX_MDL {
  23. LIST_ENTRY Next;
  24. PUCHAR File;
  25. int Line;
  26. PMDL pMdl;
  27. } WRAPPED_RX_MDL, *PWRAPPED_RX_MDL;
  28. //
  29. // Pool header data structure. Ensure it is 8 byte aligned, no
  30. // matter what members are added to the pool header
  31. //
  32. typedef struct _RX_POOL_HEADER {
  33. union {
  34. struct _RXH {
  35. BYTE Signature[ 16 ];
  36. ULONG Size;
  37. ULONG Type;
  38. PSZ AFileName;
  39. ULONG ALineNumber;
  40. PSZ FFileName;
  41. ULONG FLineNumber;
  42. };
  43. UCHAR _pad[ (sizeof( struct _RXH ) + 7) & (~7) ];
  44. };
  45. } RX_POOL_HEADER, *PRX_POOL_HEADER;
  46. //
  47. // Number of trailer bytes after a pool allocation with a known signature
  48. //
  49. #define TRAIL_BYTES 16
  50. #ifdef RX_POOL_WRAPPER
  51. PVOID
  52. _RxAllocatePoolWithTag(
  53. ULONG Type,
  54. ULONG Size,
  55. ULONG Tag,
  56. PSZ FileName,
  57. ULONG LineNumber
  58. )
  59. /*++
  60. Routine Description:
  61. This routine allocates the desired pool and sets up the debugging header and trailer
  62. to catch most instances of memory trashing
  63. Arguments:
  64. Type - type of pool to be allocated
  65. Size - size of the allocation
  66. Return Value:
  67. a valid pointer if successful, otherwise FALSE.
  68. --*/
  69. {
  70. #if 0
  71. PCHAR pBuffer;
  72. PRX_POOL_HEADER pPoolHeader;
  73. ASSERT( Size != 0 );
  74. ASSERT(
  75. Type == PagedPool ||
  76. Type == (PagedPool | POOL_COLD_ALLOCATION) ||
  77. Type == NonPagedPool);
  78. ASSERT( (sizeof(RX_POOL_HEADER)&7) == 0 );
  79. pPoolHeader = ExAllocatePoolWithTagPriority(
  80. Type,
  81. sizeof( *pPoolHeader ) + Size + TRAIL_BYTES,
  82. Tag,
  83. LowPoolPriority);
  84. if ( pPoolHeader == NULL ) {
  85. RxLog(("RA:NULL %d %d %s\n", Type, LineNumber, &FileName[24]));
  86. return( NULL );
  87. }
  88. //
  89. // Fill the head so we can verify valid free's
  90. //
  91. RtlFillMemory( pPoolHeader->Signature, sizeof( pPoolHeader->Signature ), 'H' );
  92. pPoolHeader->Size = Size;
  93. pPoolHeader->Type = Type;
  94. pPoolHeader->AFileName = FileName;
  95. pPoolHeader->ALineNumber = LineNumber;
  96. pPoolHeader->FFileName = NULL;
  97. pPoolHeader->FLineNumber = 0;
  98. pBuffer = (PCHAR)(pPoolHeader + 1);
  99. //
  100. // Fill the memory to catch uninitialized structures, etc
  101. //
  102. RtlFillMemory( pBuffer, Size, '*' );
  103. //
  104. // Fill the tail to catch overruns
  105. //
  106. RtlFillMemory( pBuffer + Size, TRAIL_BYTES, 'T' );
  107. //
  108. // Make sure we're starting out valid
  109. //
  110. RxCheckMemoryBlock( pBuffer );
  111. return( pBuffer );
  112. #endif
  113. return ExAllocatePoolWithTagPriority(
  114. Type,Size,Tag,LowPoolPriority);
  115. }
  116. VOID
  117. _RxFreePool( PVOID pBuffer, PSZ FileName, ULONG LineNumber )
  118. {
  119. #if 0
  120. if( _RxCheckMemoryBlock( pBuffer, FileName, LineNumber ) ) {
  121. PRX_POOL_HEADER pPoolHeader = ((PRX_POOL_HEADER)pBuffer) - 1;
  122. //
  123. // Zap the block, to catch cases where we are using freed blocks
  124. //
  125. RtlFillMemory( pPoolHeader->Signature,
  126. sizeof( pPoolHeader->Signature ),
  127. 'F' );
  128. pPoolHeader->FFileName = FileName;
  129. pPoolHeader->FLineNumber = LineNumber;
  130. RtlFillMemory( pPoolHeader+1,
  131. pPoolHeader->Size + TRAIL_BYTES,
  132. 'F' );
  133. ExFreePool( pPoolHeader );
  134. }
  135. #endif
  136. ExFreePool(pBuffer);
  137. }
  138. BOOLEAN
  139. _RxCheckMemoryBlock(
  140. PVOID pBuffer,
  141. PSZ FileName,
  142. ULONG LineNumber
  143. )
  144. /*++
  145. Routine Description:
  146. This routine frees up the pool allocated through RxAllocate
  147. Arguments:
  148. pv - the block to be freed
  149. --*/
  150. {
  151. PRX_POOL_HEADER pPoolHeader = ((PRX_POOL_HEADER)pBuffer) - 1;
  152. PCHAR pTail;
  153. ULONG i;
  154. if( pBuffer == NULL ) {
  155. DbgPrint( "RxCheckMemoryBlock( NULL ) at %s %d\n",
  156. FileName, LineNumber );
  157. DbgBreakPoint();
  158. return FALSE;
  159. }
  160. //
  161. // Make sure we have a valid block
  162. //
  163. for( i=0; i < sizeof( pPoolHeader->Signature ); i++ ) {
  164. if( pPoolHeader->Signature[i] != 'H' ) {
  165. if( pPoolHeader->Signature[i] == 'F' && i == 0 ) {
  166. DbgPrint( "RxFreePool: Likely double free on block at %X\n", pPoolHeader );
  167. }
  168. DbgPrint( "RxCheckMemoryBlock: Invalid header signature for block %X\n", pPoolHeader );
  169. DbgPrint( " Called from %s %d\n", FileName, LineNumber );
  170. DbgPrint( " Originally Freed at %s %d\n",pPoolHeader->FFileName,pPoolHeader->FLineNumber);
  171. DbgPrint( " Size is x%X, user part at %X\n", pPoolHeader->Size, pPoolHeader + 1 );
  172. DbgBreakPoint();
  173. return FALSE;
  174. }
  175. }
  176. if( pPoolHeader->Type != PagedPool &&
  177. pPoolHeader->Type != (PagedPool | POOL_COLD_ALLOCATION) &&
  178. pPoolHeader->Type != NonPagedPool) {
  179. DbgPrint( "RxCheckMemoryBlock:\n" );
  180. DbgPrint( " Invalid PoolHeader->Type for block %X\n", pPoolHeader );
  181. DbgPrint( " Called from %s %d\n", FileName, LineNumber );
  182. DbgBreakPoint();
  183. return FALSE;
  184. }
  185. if( pPoolHeader->Size == 0 ) {
  186. DbgPrint( "RxCheckMemoryBlock:\n" );
  187. DbgPrint( " Size is 0 for block %X\n", pPoolHeader );
  188. DbgPrint( " Called from %s %d\n", FileName, LineNumber );
  189. DbgBreakPoint();
  190. return FALSE;
  191. }
  192. //
  193. // Look to see if the buffer has been overrun
  194. //
  195. pTail = (PCHAR)pBuffer + pPoolHeader->Size;
  196. for( i=0; i < TRAIL_BYTES; i++ ) {
  197. if( *pTail++ != 'T' ) {
  198. DbgPrint( "RxCheckMemoryBlock: Overrun memory block at %X\n", pPoolHeader );
  199. DbgPrint( " RxCheckMemoryBlock called from %s line %d\n", FileName, LineNumber );
  200. DbgPrint( " Allocated at %s line %d\n", pPoolHeader->AFileName, pPoolHeader->ALineNumber );
  201. DbgPrint( " Size is x%X, user part at %X\n", pPoolHeader->Size, pPoolHeader + 1 );
  202. DbgPrint( " Overrun begins at %X\n", pTail-1 );
  203. DbgBreakPoint();
  204. return FALSE;
  205. }
  206. }
  207. return TRUE;
  208. }
  209. #endif
  210.