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.

381 lines
10 KiB

  1. //=============================================================================
  2. // Microsoft (R) Bloodhound (tm). Copyright (C) 1991-1992.
  3. //
  4. // MODULE: mem.c
  5. //
  6. // Modification History
  7. //
  8. // raypa 01/28/93 Created
  9. // stevehi 07/21/93 Added memory checking functionality
  10. // raypa 07/21/93 Changed to use LPTR rather than LocalLock.
  11. // Tom Laird-McConnell 08/16/93 Changed to fix no size info in functions
  12. // arth 06/16/94 Added extra debug tracing code
  13. //=============================================================================
  14. #include "switches.h"
  15. #include <windows.h>
  16. #include "mem.h"
  17. #include <memory.h>
  18. #include <stdio.h>
  19. #include "debug.h"
  20. #include "strings.h"
  21. #include <process.h>
  22. #include "utils.h"
  23. #ifdef DEBUG_MEM
  24. BOOL _rtlpheapvalidateoncall = TRUE;
  25. typedef struct _MEM_BUFFER {
  26. struct _MEM_BUFFER *Next;
  27. struct _MEM_BUFFER *Prev;
  28. ULONG Size;
  29. } MEM_BUFFER;
  30. MEM_BUFFER *MemList = NULL;
  31. ULONG AllocCount = 0;
  32. #endif
  33. //=============================================================================
  34. // Define Tags used by the following routines to stick into memory
  35. // and compare later.
  36. //=============================================================================
  37. #define AllocTagTakeStart 0x3e4b4154 //... TAK>
  38. #define AllocTagTakeStop 0x4b41543c //... <TAK
  39. #define AllocTagReAllocStart 0x3e414552 //... REA>
  40. #define AllocTagReAllocStop 0x4145523c //... <REA
  41. #define AllocTagFreeStart 0x3e455246 //... FRE>
  42. #define AllocTagFreeStop 0x4552463c //... <FRE
  43. // Just load the dynamic strings so we don't have to do it if we run out of
  44. // memory (otherwise we might not be able to load them then).
  45. void MemInit() {
  46. LPTSTR x;
  47. x = Lids(IDS_S_7);
  48. x = Lids(IDS_S_8);
  49. } // MemInit
  50. #ifdef DEBUG_MEM
  51. void DBG_MemEnum(void) {
  52. MEM_BUFFER *lpMem;
  53. ULONG TotSize = 0;
  54. ULONG i = 1;
  55. UNALIGNED LPBYTE lpByte;
  56. lpMem = MemList;
  57. dprintf(TEXT("\nMem Dump\n# Allocations: %lu\n\n"), AllocCount);
  58. while (lpMem != NULL) {
  59. TotSize += lpMem->Size;
  60. lpByte = (LPBYTE) lpMem;
  61. lpByte -= sizeof(DWORD);
  62. dprintf(TEXT("%lu %lX) Alloc Size: %lu\n"), i++, lpMem, lpMem->Size);
  63. if ( *(LPDWORD)(lpByte) != AllocTagTakeStart ) {
  64. dprintf(TEXT("AllocTagStart Corrupt\n"));
  65. dprintf(TEXT("Total Alloc Mem: %lu\n"), TotSize);
  66. DebugBreak;
  67. }
  68. lpByte += sizeof(DWORD) + sizeof(MEM_BUFFER) + lpMem->Size;
  69. if ( *(LPDWORD)(lpByte) != AllocTagTakeStop ) {
  70. dprintf(TEXT("AllocTagStop Corrupt\n"));
  71. dprintf(TEXT("Total Alloc Mem: %lu\n"), TotSize);
  72. DebugBreak;
  73. }
  74. lpMem = lpMem->Next;
  75. }
  76. dprintf(TEXT("\nTotal Alloc Mem: %lu\n"), TotSize);
  77. } // DBG_MemEnum
  78. #endif
  79. //=============================================================================
  80. // FUNCTION: AllocMemory()
  81. //
  82. // Modification History
  83. //
  84. // raypa 01/28/93 Created.
  85. // stevehi 07/21/93 Added memory checking functionality
  86. // raypa 07/21/93 Changed to use LPTR rather than LocalLock.
  87. // raypa 07/21/93 Return NULL if size is zero.
  88. //=============================================================================
  89. LPVOID WINAPI AllocMemory(DWORD size) {
  90. register LPBYTE lpByte;
  91. int ret;
  92. #ifndef DEBUG_MEM
  93. do {
  94. ret = IDOK;
  95. lpByte = LocalAlloc(LPTR, size);
  96. if ((lpByte == NULL) && (size != 0)) {
  97. MessageBeep(MB_ICONHAND);
  98. ret = MessageBox(NULL, Lids(IDS_S_7), Lids(IDS_S_8), MB_ICONHAND | MB_SYSTEMMODAL | MB_RETRYCANCEL);
  99. if (ret == IDCANCEL)
  100. exit(1);
  101. }
  102. } while (ret == IDRETRY);
  103. return (LPVOID) lpByte;
  104. #else
  105. DWORD ActualSize;
  106. MEM_BUFFER *lpMem;
  107. if ( size != 0 ) {
  108. do {
  109. ret = IDOK;
  110. // take into account 2 tags and buffer header
  111. lpByte = LocalAlloc(LPTR, size + (2 * sizeof(DWORD)) + sizeof(MEM_BUFFER));
  112. if (lpByte == NULL) {
  113. MessageBeep(MB_ICONHAND);
  114. DBG_MemEnum();
  115. ret = MessageBox(NULL, TEXT("Out of Memory"), TEXT("NwConv - Error"), MB_ICONHAND | MB_SYSTEMMODAL | MB_RETRYCANCEL);
  116. if (ret == IDCANCEL)
  117. exit(1);
  118. }
  119. } while (ret == IDRETRY);
  120. AllocCount++;
  121. ActualSize = LocalSize(lpByte) - (2 * sizeof(DWORD)) - sizeof(MEM_BUFFER);
  122. *((LPDWORD)(lpByte)) = AllocTagTakeStart;
  123. lpMem = (MEM_BUFFER *) &lpByte[sizeof(DWORD)];
  124. lpMem->Next = MemList;
  125. lpMem->Prev = NULL;
  126. if (MemList != NULL)
  127. MemList->Prev = lpMem;
  128. lpMem->Size = ActualSize;
  129. MemList = lpMem;
  130. *((LPDWORD)(lpByte + ActualSize + sizeof(DWORD) + sizeof(MEM_BUFFER))) = AllocTagTakeStop;
  131. return (LPVOID) &lpByte[sizeof(DWORD) + sizeof(MEM_BUFFER)];
  132. }
  133. return NULL;
  134. #endif
  135. } // AllocMemory
  136. //=============================================================================
  137. // FUNCTION: ReallocMemory()
  138. //
  139. // Modification History
  140. //
  141. // raypa 01/28/93 Created.
  142. // stevehi 07/21/93 Added memory checking functionality
  143. // raypa 07/21/93 Changed to use LPTR rather than LocalLock.
  144. // raypa 10/22/93 If the ptr is NULL then use AllocMemory.
  145. //=============================================================================
  146. LPVOID WINAPI ReallocMemory(LPVOID ptr, DWORD NewSize) {
  147. #ifdef DEBUG_MEM
  148. DWORD GSize;
  149. MEM_BUFFER *lpMem;
  150. MEM_BUFFER *OldMem;
  151. #endif
  152. //=========================================================================
  153. // If the ptr is NULL then use AllocMemory.
  154. //=========================================================================
  155. if ( ptr == NULL ) {
  156. return AllocMemory(NewSize);
  157. }
  158. #ifndef DEBUG_MEM
  159. return LocalReAlloc(ptr, NewSize, LHND);
  160. #else
  161. // we are reallocing... might as well check the tags here...
  162. (LPBYTE)ptr -= (sizeof(DWORD) + sizeof(MEM_BUFFER));
  163. GSize = LocalSize (ptr);
  164. if ( *(LPDWORD)(ptr) != AllocTagTakeStart )
  165. DebugBreak;
  166. // get the size and check the end tag
  167. if (GSize && ( *(LPDWORD)((LPBYTE)ptr + GSize - sizeof(DWORD))) != AllocTagTakeStop ) {
  168. DebugBreak;
  169. }
  170. // just for grins, mark the realloc part.
  171. *(LPDWORD)(ptr) = AllocTagReAllocStart;
  172. if ( GSize )
  173. *(LPDWORD)((LPBYTE)ptr + GSize - sizeof(DWORD) ) = AllocTagReAllocStop;
  174. OldMem = (MEM_BUFFER *) ((LPBYTE)ptr + sizeof(DWORD));
  175. ptr = LocalReAlloc(ptr, NewSize + sizeof(MEM_BUFFER) + (2 * sizeof(DWORD)), LHND);
  176. if (ptr == NULL ) {
  177. dprintf(TEXT("NWConv - Local Realloc failed with %ld.\r\n"), GetLastError() );
  178. DebugBreak;
  179. return NULL;
  180. }
  181. lpMem = (MEM_BUFFER *) ((LPBYTE)ptr + sizeof(DWORD));
  182. if (MemList == OldMem)
  183. MemList = lpMem;
  184. if (lpMem->Prev != NULL)
  185. lpMem->Prev->Next = lpMem;
  186. if (lpMem->Next != NULL)
  187. lpMem->Next->Prev = lpMem;
  188. lpMem->Size = NewSize;
  189. *((LPDWORD)ptr) = AllocTagTakeStart;
  190. *((LPDWORD)((LPBYTE)ptr + NewSize + sizeof(MEM_BUFFER) + sizeof(DWORD))) = AllocTagTakeStop;
  191. return (LPVOID)((LPBYTE)ptr + sizeof(DWORD) + sizeof(MEM_BUFFER));
  192. #endif
  193. } // ReAllocMemory
  194. //=============================================================================
  195. // FUNCTION: FreeMemory()
  196. //
  197. // Modification History
  198. //
  199. // raypa 01/28/93 Created.
  200. // stevehi 07/21/93 Added memory checking functionality
  201. // raypa 07/21/93 Changed to use LPTR rather than LocalLock.
  202. // raypa 07/21/93 Fixed GP-fault on NULL ptr.
  203. // raypa 11/21/93 Allow freeing of NULL pointer.
  204. //=============================================================================
  205. VOID WINAPI FreeMemory(LPBYTE ptr) {
  206. //=========================================================================
  207. // If the pointer is NULL, exit.
  208. //=========================================================================
  209. if ( ptr != NULL ) {
  210. #ifdef DEBUG_MEM
  211. register DWORD Size;
  212. register LPDWORD DwordPtr;
  213. MEM_BUFFER *lpMem;
  214. ptr -= (sizeof(DWORD) + sizeof(MEM_BUFFER));
  215. lpMem = (MEM_BUFFER *) ((LPBYTE)ptr + sizeof(DWORD));
  216. Size = LocalSize(ptr);
  217. //... Check start tag
  218. DwordPtr = (LPDWORD) &ptr[0];
  219. if ( *DwordPtr != AllocTagTakeStart ) {
  220. dprintf(TEXT("NWConv - FreeMemory: Invalid start signature: ptr = %X\r\n"), ptr);
  221. DebugBreak();
  222. }
  223. else {
  224. *DwordPtr = AllocTagFreeStart;
  225. }
  226. //... get the size and check the end tag
  227. DwordPtr = (LPDWORD) &ptr[Size - sizeof(DWORD)];
  228. if ( *DwordPtr != AllocTagTakeStop ) {
  229. dprintf(TEXT("NWConv - FreeMemory: Invalid end signature: ptr = %X\r\n"), ptr);
  230. DebugBreak();
  231. }
  232. else {
  233. *DwordPtr = AllocTagFreeStop;
  234. }
  235. AllocCount--;
  236. if (MemList == lpMem)
  237. MemList = lpMem->Next;
  238. if (lpMem->Prev != NULL)
  239. lpMem->Prev->Next = lpMem->Next;
  240. if (lpMem->Next != NULL)
  241. lpMem->Next->Prev = lpMem->Prev;
  242. #endif
  243. LocalFree(ptr);
  244. }
  245. } // FreeMemory
  246. //=============================================================================
  247. // FUNCTION: MemorySize()
  248. //
  249. // Modification History
  250. //
  251. // Tom Laird-McConnell 08/02/93 Created.
  252. // Tom Laird-McConnell 08/02/93 Changed to use local var for size...
  253. //=============================================================================
  254. DWORD_PTR WINAPI MemorySize(LPBYTE ptr) {
  255. #ifdef DEBUG_MEM
  256. register DWORD_PTR Size;
  257. if ( ptr != NULL ) {
  258. register LPDWORD DwordPtr;
  259. ptr -= (sizeof(DWORD) + sizeof(MEM_BUFFER));
  260. Size = LocalSize(ptr);
  261. DwordPtr = (LPDWORD) &ptr[0];
  262. // Check start tag
  263. if ( *DwordPtr != AllocTagTakeStart ) {
  264. dprintf(TEXT("NWConv - MemorySize: Invalid start signature!\r\n"));
  265. DebugBreak;
  266. }
  267. // get the size and check the end tag
  268. DwordPtr = (LPDWORD) &ptr[Size - sizeof(DWORD)];
  269. if ( *DwordPtr != AllocTagTakeStop ) {
  270. dprintf(TEXT("NWConv - MemorySize: Invalid end signature!\r\n"));
  271. DebugBreak;
  272. }
  273. return (Size - (2 * sizeof(DWORD)) - sizeof(MEM_BUFFER));
  274. }
  275. #endif
  276. return LocalSize(ptr);
  277. } // MemorySize