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.

268 lines
6.1 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: N C M E M . C P P
  7. //
  8. // Contents: Common memory management routines.
  9. //
  10. // Notes:
  11. //
  12. // Author: shaunco 24 Mar 1997
  13. // deonb 2 Jan 2002
  14. //
  15. //
  16. // Our memory allocations rules are:
  17. // * Most of our memory allocators do NOT throw exceptions but instead return NULL.
  18. // This includes MemAlloc, operator new, operator new[], calloc & malloc.
  19. // * Anything explicitly allocated using: p = new(throwonfail) CClass(), will raise a bad_alloc on failure.
  20. // * STL:
  21. // #ifdef (USE_CUSTOM_STL_ALLOCATOR)
  22. // The STL memory allocator will raise a bad_alloc C++ exception on low memory.
  23. // (Note, not an SEH exception!).
  24. // #else
  25. // STL will raise an access violation exception after out-of-memory occurred and
  26. // it tries to use the memory.
  27. // #endif
  28. // * Currently USE_CUSTOM_STL_ALLOCATOR is defined in our makefile.inc
  29. //
  30. //----------------------------------------------------------------------------
  31. #include <pch.h>
  32. #pragma hdrstop
  33. #include "ncdebug.h"
  34. #include "ncmem.h"
  35. // Debug limit for single memory allocation (16 MB)
  36. #define MAX_DEBUG_ALLOC 16 * 1048576
  37. // This global heap handle will be set to the process heap when the
  38. // first request to allocate memory through MemAlloc is made.
  39. //
  40. HANDLE g_hHeap = NULL;
  41. //+---------------------------------------------------------------------------
  42. //
  43. // Function: MemAlloc
  44. //
  45. // Purpose: NetConfig's memory allocator
  46. //
  47. // Arguments:
  48. // cb [in] Count of bytes to allocate.
  49. //
  50. // Returns: Pointer to allocated memory, or NULL if failed.
  51. //
  52. // Author: deonb 2 Jan 2002
  53. //
  54. // Notes: Free the returned buffer with MemFree.
  55. // Will ASSERT in debug if attempt to allocate more than MAX_DEBUG_ALLOC (Currently 16 MB)
  56. //
  57. // We COULD extend this to include a primitive buffer overrun check, but it would require us
  58. // to put the size of the allocated block in the beginning of the buffer, and would make things like
  59. // allocating with MemAlloc but freeing it with HeapFree fail.
  60. // PageHeap / AVRF is better suited for this purpose since it works directly with the RTL allocator.
  61. //
  62. VOID*
  63. MemAlloc (
  64. size_t cb) throw()
  65. {
  66. AssertSz(cb < MAX_DEBUG_ALLOC, "Suspicious request for a lot of memory");
  67. if (!g_hHeap)
  68. {
  69. // Don't trace in this part of the function. It will likely recurse.
  70. g_hHeap = GetProcessHeap();
  71. if (!g_hHeap)
  72. {
  73. AssertSz(FALSE, "MemAlloc could not get the process heap.");
  74. return NULL;
  75. }
  76. }
  77. LPVOID lpAlloc = HeapAlloc (g_hHeap, 0, cb);
  78. if (!lpAlloc)
  79. {
  80. TraceTag(ttidError, "MemAlloc failed request for %d bytes from:", cb);
  81. TraceStack(ttidError);
  82. }
  83. return lpAlloc;
  84. }
  85. //+---------------------------------------------------------------------------
  86. //
  87. // Function: MemFree
  88. //
  89. // Purpose: NetConfig's memory de-allocator
  90. //
  91. // Arguments:
  92. // pv [in] Pointer to previously allocated memory
  93. //
  94. // Returns: none
  95. //
  96. // Author: deonb 2 Jan 2002
  97. //
  98. // Notes: Free the returned buffer from MemAlloc.
  99. // Don't trace in this function. It will recurse.
  100. VOID
  101. MemFree (
  102. VOID* pv) throw()
  103. {
  104. if (pv)
  105. {
  106. if (!g_hHeap)
  107. {
  108. AssertSz(FALSE, "Suspicious call to MemFree before MemAlloc");
  109. g_hHeap = GetProcessHeap();
  110. if (!g_hHeap)
  111. {
  112. return;
  113. }
  114. }
  115. HeapFree (g_hHeap, 0, pv);
  116. }
  117. }
  118. //+---------------------------------------------------------------------------
  119. //
  120. // Function: HrMalloc
  121. //
  122. // Purpose: HRESULT returning version of malloc.
  123. //
  124. // Arguments:
  125. // cb [in] Count of bytes to allocate.
  126. // ppv [out] Address of returned allocation.
  127. //
  128. // Returns: S_OK or E_OUTOFMEMORY;
  129. //
  130. // Author: shaunco 31 Mar 1998
  131. //
  132. // Notes: Free the returned buffer with free.
  133. //
  134. HRESULT
  135. HrMalloc (
  136. size_t cb,
  137. PVOID* ppv) throw()
  138. {
  139. Assert (ppv);
  140. HRESULT hr = S_OK;
  141. *ppv = MemAlloc (cb);
  142. if (!*ppv)
  143. {
  144. hr = E_OUTOFMEMORY;
  145. TraceHr (ttidError, FAL, hr, FALSE, "HrMalloc failed request for %d bytes from:", cb);
  146. TraceStack(ttidError);
  147. }
  148. return hr;
  149. }
  150. namespace std
  151. {
  152. // report a length_error
  153. void __cdecl _Xlen()
  154. {
  155. _THROW(length_error, "string too long");
  156. }
  157. // report an out_of_range error
  158. void __cdecl _Xran()
  159. {
  160. _THROW(out_of_range, "invalid string position");
  161. }
  162. }
  163. //+---------------------------------------------------------------------------
  164. // CRT memory function overloads
  165. //
  166. const throwonfail_t throwonfail;
  167. VOID*
  168. __cdecl
  169. operator new (
  170. size_t cb,
  171. const throwonfail_t&
  172. ) throw (std::bad_alloc)
  173. {
  174. LPVOID pv = MemAlloc (cb);
  175. if (!pv)
  176. {
  177. throw std::bad_alloc();
  178. }
  179. return pv;
  180. }
  181. VOID
  182. __cdecl
  183. operator delete (
  184. void* pv,
  185. const throwonfail_t&) throw ()
  186. {
  187. MemFree (pv);
  188. }
  189. const extrabytes_t extrabytes;
  190. VOID*
  191. __cdecl
  192. operator new (
  193. size_t cb,
  194. const extrabytes_t&,
  195. size_t cbExtra) throw()
  196. {
  197. return MemAlloc (cb + cbExtra);
  198. }
  199. VOID
  200. __cdecl
  201. operator delete(
  202. void* pv,
  203. const extrabytes_t&,
  204. size_t cbExtra) throw()
  205. {
  206. MemFree (pv);
  207. }
  208. VOID*
  209. __cdecl
  210. operator new (
  211. size_t cb) throw()
  212. {
  213. return MemAlloc (cb);
  214. }
  215. VOID*
  216. __cdecl
  217. operator new (
  218. size_t cb,
  219. std::nothrow_t const &) throw()
  220. {
  221. return MemAlloc (cb);
  222. }
  223. VOID*
  224. __cdecl
  225. operator new[] (
  226. size_t cb) throw()
  227. {
  228. return MemAlloc (cb);
  229. }
  230. VOID
  231. __cdecl
  232. operator delete (
  233. VOID* pv) throw()
  234. {
  235. MemFree (pv);
  236. }
  237. VOID
  238. __cdecl
  239. operator delete[] (
  240. VOID* pv) throw()
  241. {
  242. MemFree (pv);
  243. }