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.

341 lines
7.8 KiB

  1. /*****************************************************************************\
  2. * MODULE: genmem.c
  3. *
  4. * This module contains memory-management wrapper routines. These provide
  5. * debugging checks if needed.
  6. *
  7. * The blocks allocated with these routines include two DWORD entrys for
  8. * marking the head and tail of the allocation block. This is structured as
  9. * follows:
  10. *
  11. * DWORD cbSize DWORD
  12. * -------------------------------------------------
  13. * | Block Size | ...Alocated Memory... | DEADBEEF |
  14. * -------------------------------------------------
  15. * ^
  16. * |
  17. * Allocations return this pointer.
  18. *
  19. * routines
  20. * --------
  21. * genGAlloc
  22. * genGFree
  23. * genGRealloc
  24. * genGAllocStr
  25. * genGCopy
  26. * genGSize
  27. *
  28. *
  29. *
  30. * Copyright (C) 1996-1997 Microsoft Corporation
  31. * Copyright (C) 1996-1997 Hewlett Packard
  32. *
  33. * history:
  34. * 22-Nov-1996 <chriswil> created.
  35. *
  36. \*****************************************************************************/
  37. #include "pch.h"
  38. #ifdef DEBUG
  39. /*****************************************************************************\
  40. * mem_validate
  41. *
  42. * Checks the block of memory for any overwrites or size mismatches.
  43. *
  44. \*****************************************************************************/
  45. LPVOID gen_validate(
  46. PDWORD_PTR lpMem,
  47. DWORD cbSize)
  48. {
  49. DWORD cbNew;
  50. PDWORD_PTR lpTail;
  51. PDWORD_PTR lpHead;
  52. LPVOID lpRet = NULL;
  53. // Bad thing if a null-pointer is passed in.
  54. //
  55. if (lpMem != NULL) {
  56. // Reset the block to the true position.
  57. //
  58. lpHead = --lpMem;
  59. // Calculate the "real" size of our allocated block and round it
  60. // up to an even number of DWORD_PTR s.
  61. //
  62. cbNew = cbSize + (2 * sizeof(DWORD_PTR));
  63. if (cbNew & 7)
  64. cbNew += sizeof(DWORD_PTR) - (cbNew & 7);
  65. // Get the tail location.
  66. //
  67. lpTail = (DWORD_PTR)((LPBYTE)lpHead + cbNew - sizeof(DWORD_PTR));
  68. // Compare the values that memAlloc stored at the beginning
  69. // and end of the block
  70. //
  71. SPLASSERT(*lpHead == cbSize);
  72. SPLASSERT(*lpTail == DEADBEEF);
  73. lpRet = (LPVOID)lpHead;
  74. } else {
  75. DBGMSG(DBG_ERROR, ("gen_validate: Bad Pointer"));
  76. }
  77. return lpRet;
  78. }
  79. #else
  80. /*****************************************************************************\
  81. * gen_validate (Non-Debug)
  82. *
  83. * On non-debug builds, we will just return the head ptr.
  84. *
  85. \*****************************************************************************/
  86. _inline LPVOID gen_validate(
  87. PDWORD_PTR lpMem,
  88. DWORD cbSize)
  89. {
  90. if (lpMem) {
  91. lpMem--;
  92. return (LPVOID)lpMem;
  93. }
  94. return NULL;
  95. }
  96. #endif
  97. /*****************************************************************************\
  98. * genGAlloc
  99. *
  100. * Allocates a global-memory block. This allocation also includes a header
  101. * block which contains block-information. This allows for the tracking
  102. * of overwrites.
  103. *
  104. \*****************************************************************************/
  105. LPVOID genGAlloc(
  106. DWORD cbSize)
  107. {
  108. PDWORD_PTR lpMem;
  109. DWORD cbNew;
  110. // Give us a little room for debugging info and make sure that our
  111. // size in bytes results in a whole number of DWORDs.
  112. //
  113. cbNew = cbSize + (2 * sizeof(DWORD_PTR));
  114. // DWORD_PTR align the memory so that we can track the correct amount
  115. // of dword-allocations.
  116. //
  117. if (cbNew & 7)
  118. cbNew += sizeof(DWORD_PTR) - (cbNew & 7);
  119. // Attempt to allocate the memory.
  120. //
  121. if ((lpMem = (PDWORD_PTR)GlobalAlloc(GPTR, cbNew)) == NULL) {
  122. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  123. return NULL;
  124. }
  125. // Set up extra tracking information -- region size at the front
  126. // and an easily distinguishable constant at the back to help
  127. // us detect overwrites.
  128. //
  129. *lpMem = cbSize;
  130. *(PDWORD_PTR)((LPBYTE)lpMem + cbNew - sizeof(DWORD_PTR)) = DEADBEEF;
  131. return (LPVOID)(lpMem + 1);
  132. }
  133. /*****************************************************************************\
  134. * genGFree
  135. *
  136. * Free the memory allocated from genGAlloc. Validate the memory to see
  137. * if any bad-overwrites occured.
  138. *
  139. \*****************************************************************************/
  140. BOOL genGFree(
  141. LPVOID lpMem,
  142. DWORD cbSize)
  143. {
  144. LPVOID lpHead;
  145. BOOL bRet = FALSE;
  146. // Try to at least make sure it's our memory and that no pointers have
  147. // gone astray in it.
  148. //
  149. if (lpHead = gen_validate((PDWORD_PTR)lpMem, cbSize))
  150. bRet = (GlobalFree(lpHead) == NULL);
  151. return bRet;
  152. }
  153. /*****************************************************************************\
  154. * genGRealloc
  155. *
  156. * Reallocate the memory block. This allocates a new block, then copies
  157. * the information to the new-memory. The old one is freed.
  158. *
  159. \*****************************************************************************/
  160. PVOID genGRealloc(
  161. LPVOID lpMem,
  162. DWORD cbOldSize,
  163. DWORD cbNewSize)
  164. {
  165. LPVOID lpNew;
  166. if (lpNew = (LPVOID)genGAlloc(cbNewSize)) {
  167. memcpy(lpNew, lpMem, cbOldSize);
  168. genGFree(lpMem, cbOldSize);
  169. }
  170. return lpNew;
  171. }
  172. /*****************************************************************************\
  173. * genGAllocWStr
  174. *
  175. * Allocate and store a UNICODE string.
  176. *
  177. \*****************************************************************************/
  178. LPWSTR genGAllocWStr(
  179. LPCWSTR lpwszStr)
  180. {
  181. LPWSTR lpwszMem;
  182. DWORD len;
  183. if (lpwszStr == NULL)
  184. return NULL;
  185. len = lstrlen(lpwszStr) + 1;
  186. if (lpwszMem = (LPWSTR)genGAlloc(len * sizeof(WCHAR)))
  187. StringCchCopyW(lpwszMem, len, lpwszStr);
  188. return lpwszMem;
  189. }
  190. /*****************************************************************************\
  191. * genGAllocStr
  192. *
  193. * Allocate and store a string.
  194. *
  195. \*****************************************************************************/
  196. LPTSTR genGAllocStr(
  197. LPCTSTR lpszStr)
  198. {
  199. LPTSTR lpszMem;
  200. DWORD len;
  201. if (lpszStr == NULL)
  202. return NULL;
  203. len = lstrlen(lpszStr) + 1;
  204. if (lpszMem = (LPTSTR)genGAlloc(len * sizeof(TCHAR)))
  205. StringCchCopy(lpszMem, len, lpszStr);
  206. return lpszMem;
  207. }
  208. /*****************************************************************************\
  209. * genGCopy
  210. *
  211. * Makes a copy of the memory pointed to by (lpSrc), and returns a new
  212. * allocated block.
  213. *
  214. \*****************************************************************************/
  215. LPVOID genGCopy(
  216. LPVOID lpSrc)
  217. {
  218. DWORD cbSize;
  219. LPVOID lpCpy = NULL;
  220. if ((lpSrc != NULL) && (cbSize = genGSize(lpSrc))) {
  221. if (lpCpy = genGAlloc(cbSize))
  222. memcpy(lpCpy, lpSrc, cbSize);
  223. }
  224. return lpCpy;
  225. }
  226. /*****************************************************************************\
  227. * genGSize
  228. *
  229. * Returns the size of the block alloced by genGAlloc().
  230. *
  231. \*****************************************************************************/
  232. DWORD genGSize(
  233. LPVOID lpMem)
  234. {
  235. PDWORD_PTR lpHead;
  236. if (lpHead = (PDWORD_PTR)lpMem)
  237. return (DWORD) *(--lpHead);
  238. return 0;
  239. }
  240. /*****************************************************************************\
  241. *
  242. * These function are for linking with spllib.
  243. *
  244. \*****************************************************************************/
  245. EXTERN_C
  246. LPVOID
  247. DllAllocSplMem(
  248. DWORD cb
  249. )
  250. {
  251. return LocalAlloc(LPTR, cb);
  252. }
  253. EXTERN_C
  254. BOOL
  255. DllFreeSplMem(
  256. LPVOID pMem
  257. )
  258. {
  259. LocalFree(pMem);
  260. return TRUE;
  261. }
  262. EXTERN_C
  263. BOOL
  264. DllFreeSplStr(
  265. LPWSTR lpStr
  266. )
  267. {
  268. LocalFree(lpStr);
  269. return TRUE;
  270. }