Source code of Windows XP (NT5)
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.

306 lines
6.0 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. mem.c
  5. Abstract:
  6. This file implements memory allocation functions for fax.
  7. Author:
  8. Wesley Witt (wesw) 23-Jan-1995
  9. Environment:
  10. User Mode
  11. --*/
  12. #include "nc.h"
  13. HANDLE hHeap;
  14. DWORD HeapFlags;
  15. PMEMALLOC pMemAllocUser;
  16. PMEMFREE pMemFreeUser;
  17. #ifdef FAX_HEAP_DEBUG
  18. LIST_ENTRY HeapHeader;
  19. ULONG TotalMemory;
  20. ULONG MaxTotalMemory;
  21. ULONG MaxTotalAllocs;
  22. VOID PrintAllocations(VOID);
  23. ULONG TotalAllocs;
  24. CRITICAL_SECTION CsHeap;
  25. #endif
  26. BOOL
  27. HeapExistingInitialize(
  28. HANDLE hExistHeap
  29. )
  30. {
  31. #ifdef FAX_HEAP_DEBUG
  32. InitializeListHead( &HeapHeader );
  33. MaxTotalMemory = 0;
  34. MaxTotalAllocs = 0;
  35. InitializeCriticalSection( &CsHeap );
  36. #endif
  37. if (!hExistHeap) {
  38. return FALSE;
  39. }
  40. else {
  41. hHeap = hExistHeap;
  42. return TRUE;
  43. }
  44. }
  45. HANDLE
  46. HeapInitialize(
  47. HANDLE hHeapUser,
  48. PMEMALLOC pMemAlloc,
  49. PMEMFREE pMemFree,
  50. DWORD Flags
  51. )
  52. {
  53. #ifdef FAX_HEAP_DEBUG
  54. InitializeListHead( &HeapHeader );
  55. MaxTotalMemory = 0;
  56. MaxTotalAllocs = 0;
  57. InitializeCriticalSection( &CsHeap );
  58. #endif
  59. HeapFlags = Flags;
  60. if (pMemAlloc && pMemFree) {
  61. pMemAllocUser = pMemAlloc;
  62. pMemFreeUser = pMemFree;
  63. } else {
  64. if (hHeapUser) {
  65. hHeap = hHeapUser;
  66. } else {
  67. hHeap = HeapCreate( 0, HEAP_SIZE, 0 );
  68. }
  69. if (!hHeap) {
  70. return NULL;
  71. }
  72. }
  73. return hHeap;
  74. }
  75. BOOL
  76. HeapCleanup(
  77. VOID
  78. )
  79. {
  80. #ifdef FAX_HEAP_DEBUG
  81. PrintAllocations();
  82. #endif
  83. HeapDestroy( hHeap );
  84. return TRUE;
  85. }
  86. #ifdef FAX_HEAP_DEBUG
  87. VOID
  88. pCheckHeap(
  89. PVOID MemPtr,
  90. ULONG Line,
  91. LPSTR File
  92. )
  93. {
  94. HeapValidate( hHeap, 0, MemPtr );
  95. }
  96. #endif
  97. PVOID
  98. pMemAlloc(
  99. ULONG AllocSize
  100. #ifdef FAX_HEAP_DEBUG
  101. , ULONG Line,
  102. LPSTR File
  103. #endif
  104. )
  105. {
  106. PVOID MemPtr;
  107. #ifdef FAX_HEAP_DEBUG
  108. PHEAP_BLOCK hb;
  109. #ifdef UNICODE
  110. WCHAR fname[MAX_PATH];
  111. #endif
  112. LPWSTR p = NULL;
  113. if (pMemAllocUser) {
  114. hb = (PHEAP_BLOCK) pMemAllocUser( AllocSize + sizeof(HEAP_BLOCK) );
  115. } else {
  116. hb = (PHEAP_BLOCK) HeapAlloc( hHeap, HEAP_ZERO_MEMORY, AllocSize + sizeof(HEAP_BLOCK) );
  117. }
  118. if (hb) {
  119. TotalAllocs += 1;
  120. TotalMemory += AllocSize;
  121. if (TotalMemory > MaxTotalMemory) {
  122. MaxTotalMemory = TotalMemory;
  123. }
  124. if (TotalAllocs > MaxTotalAllocs) {
  125. MaxTotalAllocs = TotalAllocs;
  126. }
  127. EnterCriticalSection( &CsHeap );
  128. InsertTailList( &HeapHeader, &hb->ListEntry );
  129. hb->Signature = HEAP_SIG;
  130. hb->Size = AllocSize;
  131. hb->Line = Line;
  132. #ifdef UNICODE
  133. MultiByteToWideChar(
  134. CP_ACP,
  135. MB_PRECOMPOSED,
  136. File,
  137. -1,
  138. fname,
  139. sizeof(fname)/sizeof(WCHAR)
  140. );
  141. p = wcsrchr( fname, L'\\' );
  142. if (p) {
  143. wcscpy( hb->File, p+1 );
  144. }
  145. #else
  146. p = strrchr( File, '\\' );
  147. if (p) {
  148. strcpy( hb->File, p+1 );
  149. }
  150. #endif
  151. MemPtr = (PVOID) ((PUCHAR)hb + sizeof(HEAP_BLOCK));
  152. LeaveCriticalSection( &CsHeap );
  153. } else {
  154. MemPtr = NULL;
  155. }
  156. #else
  157. if (pMemAllocUser) {
  158. MemPtr = (PVOID) pMemAllocUser( AllocSize );
  159. } else {
  160. MemPtr = (PVOID) HeapAlloc( hHeap, HEAP_ZERO_MEMORY, AllocSize );
  161. }
  162. #endif
  163. if (!MemPtr) {
  164. DebugPrint(( L"MemAlloc() failed, size=%d", AllocSize ));
  165. SetLastError( ERROR_NOT_ENOUGH_MEMORY );
  166. }
  167. return MemPtr;
  168. }
  169. VOID
  170. pMemFreeForHeap(
  171. HANDLE hHeap,
  172. PVOID MemPtr
  173. #ifdef FAX_HEAP_DEBUG
  174. , ULONG Line,
  175. LPSTR File
  176. #endif
  177. )
  178. {
  179. #ifdef FAX_HEAP_DEBUG
  180. PHEAP_BLOCK hb;
  181. if (!MemPtr) {
  182. return;
  183. }
  184. hb = (PHEAP_BLOCK) ((PUCHAR)MemPtr - sizeof(HEAP_BLOCK));
  185. if (hb->Signature == HEAP_SIG) {
  186. EnterCriticalSection( &CsHeap );
  187. RemoveEntryList( &hb->ListEntry );
  188. TotalMemory -= hb->Size;
  189. TotalAllocs -= 1;
  190. } else {
  191. if (HeapFlags & HEAPINIT_NO_VALIDATION) {
  192. hb = (PHEAP_BLOCK) MemPtr;
  193. EnterCriticalSection( &CsHeap );
  194. } else {
  195. dprintf( L"MemFree(): Corrupt heap block" );
  196. PrintAllocations();
  197. __try {
  198. DebugBreak();
  199. } __except (UnhandledExceptionFilter(GetExceptionInformation())) {
  200. // Nothing to do in here.
  201. }
  202. }
  203. }
  204. if (pMemFreeUser) {
  205. pMemFreeUser( (PVOID) hb );
  206. } else {
  207. HeapFree( hHeap, 0, (PVOID) hb );
  208. }
  209. LeaveCriticalSection( &CsHeap );
  210. #else
  211. if (!MemPtr) {
  212. return;
  213. }
  214. if (pMemFreeUser) {
  215. pMemFreeUser( (PVOID) MemPtr );
  216. } else {
  217. HeapFree( hHeap, 0, (PVOID) MemPtr );
  218. }
  219. #endif
  220. }
  221. VOID
  222. pMemFree(
  223. PVOID MemPtr
  224. #ifdef FAX_HEAP_DEBUG
  225. , ULONG Line,
  226. LPSTR File
  227. #endif
  228. )
  229. {
  230. #ifdef FAX_HEAP_DEBUG
  231. pMemFreeForHeap( hHeap, MemPtr, Line, File );
  232. #else
  233. pMemFreeForHeap( hHeap, MemPtr );
  234. #endif
  235. }
  236. #ifdef FAX_HEAP_DEBUG
  237. VOID
  238. PrintAllocations(
  239. VOID
  240. )
  241. {
  242. PLIST_ENTRY Next;
  243. PHEAP_BLOCK hb;
  244. LPWSTR s;
  245. dprintf( L"-------------------------------------------------------------------------------------------------------" );
  246. dprintf( L"Memory Allocations for Heap 0x%08x, Allocs=%d, MaxAllocs=%d, TotalMem=%d, MaxTotalMem=%d",\
  247. hHeap, TotalAllocs, MaxTotalAllocs, TotalMemory, MaxTotalMemory );
  248. dprintf( L"-------------------------------------------------------------------------------------------------------" );
  249. Next = HeapHeader.Flink;
  250. if (Next == NULL || TotalAllocs == 0) {
  251. return;
  252. }
  253. while ((ULONG)Next != (ULONG)&HeapHeader) {
  254. hb = CONTAINING_RECORD( Next, HEAP_BLOCK, ListEntry );
  255. Next = hb->ListEntry.Flink;
  256. s = (LPWSTR) ((PUCHAR)hb + sizeof(HEAP_BLOCK));
  257. dprintf( L"%8d %16s @ %5d 0x%08x", hb->Size, hb->File, hb->Line, s );
  258. if (!(HeapFlags & HEAPINIT_NO_STRINGS)) {
  259. dprintf( L" \"%s\"", s );
  260. }
  261. }
  262. return;
  263. }
  264. #endif