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.

300 lines
7.8 KiB

  1. #ifndef CDEBUG
  2. #ifndef WIN32
  3. #define WIN32
  4. #endif
  5. #endif
  6. /*++
  7. Copyright (c) 1991-92 Microsoft Corporation
  8. Module Name:
  9. MemAlloc.c
  10. Abstract:
  11. Memory allocation routines for per-process use.
  12. Note that the semantics of these routines are intended to be 100%
  13. compatible with the ANSI C routines malloc(), free(), and realloc().
  14. (That way, an implementation which can actually use the ANSI routines
  15. would just #define NetpMemoryAllocate as malloc.)
  16. Author:
  17. John Rogers (JohnRo) 15-Mar-1991
  18. Environment:
  19. Only runs under NT, although the interface is portable (Win/32).
  20. Requires ANSI C extensions: slash-slash comments, long external names.
  21. Revision History:
  22. 15-Mar-91 JohnRo
  23. Created.
  24. 16-Apr-1991 JohnRo
  25. Include <lmcons.h> for <netlib.h>. Got rid of tabs in source file.
  26. 13-Oct-1991 JohnRo
  27. Fix memory realloc problems.
  28. 18-Nov-1991 JohnRo
  29. Make sure output areas are aligned for worst case use.
  30. 12-Jan-1992 JohnRo
  31. Workaround a LocalReAlloc() bug where 2nd realloc messes up.
  32. (See WIN32_WORKAROUND code below.)
  33. Added NETLIB_LOCAL_ALLOCATION_FLAGS to make clearer what we're doing.
  34. 10-May-1992 JohnRo
  35. Add some debug output.
  36. --*/
  37. // These must be included first:
  38. #include <nt.h> // Rtl routines, etc. (Must be first.)
  39. #include <windef.h>
  40. #ifdef WIN32
  41. #include <ntrtl.h> // Needed for nturtl/winbase.h
  42. #include <nturtl.h> // Needed for winbase.h????
  43. #include <winbase.h> // LocalAlloc(), LMEM_ flags, etc.
  44. #endif
  45. #include <lmcons.h> // NET_API_STATUS.
  46. // These may be included in any order:
  47. #include <align.h> // ROUND_UP_POINTER(), ALIGN_WORST.
  48. #include <debuglib.h> // IF_DEBUG().
  49. #include <netdebug.h> // NetpAssert(), NetpKdPrint(()), FORMAT_ equates.
  50. #include <netlib.h> // My prototypes, NetpMoveMemory().
  51. #include <prefix.h> // PREFIX_ equates.
  52. #ifdef CDEBUG
  53. #include <stdlib.h> // free(), malloc(), realloc().
  54. #endif // def CDEBUG
  55. // Define memory alloc/realloc flags. We are NOT using movable or zeroed
  56. // on allocation here.
  57. #define NETLIB_LOCAL_ALLOCATION_FLAGS LMEM_FIXED
  58. LPVOID
  59. NetpMemoryAllocate(
  60. IN DWORD Size
  61. )
  62. /*++
  63. Routine Description:
  64. NetpMemoryAllocate will allocate memory, or return NULL if not available.
  65. Arguments:
  66. Size - Supplies number of bytes of memory to allocate.
  67. Return Value:
  68. LPVOID - pointer to allocated memory.
  69. NULL - no memory is available.
  70. --*/
  71. {
  72. LPVOID NewAddress;
  73. if (Size == 0) {
  74. return (NULL);
  75. }
  76. #ifdef WIN32
  77. {
  78. HANDLE hMem;
  79. hMem = LocalAlloc(
  80. NETLIB_LOCAL_ALLOCATION_FLAGS,
  81. Size); // size in bytes
  82. NewAddress = (LPVOID) hMem;
  83. }
  84. #else // ndef WIN32
  85. #ifndef CDEBUG
  86. NewAddress = RtlAllocateHeap(
  87. RtlProcessHeap( ), 0, // heap handle
  88. Size )); // bytes wanted
  89. #else // def CDEBUG
  90. NetpAssert( Size == (DWORD) (size_t) Size );
  91. NewAddress = malloc( (size_t) Size ));
  92. #endif // def CDEBUG
  93. #endif // ndef WIN32
  94. NetpAssert( ROUND_UP_POINTER( NewAddress, ALIGN_WORST) == NewAddress);
  95. return (NewAddress);
  96. } // NetpMemoryAllocate
  97. VOID
  98. NetpMemoryFree(
  99. IN LPVOID Address OPTIONAL
  100. )
  101. /*++
  102. Routine Description:
  103. Free memory at Address (must have been gotten from NetpMemoryAllocate or
  104. NetpMemoryReallocate). (Address may be NULL.)
  105. Arguments:
  106. Address - points to an area allocated by NetpMemoryAllocate (or
  107. NetpMemoryReallocate).
  108. Return Value:
  109. None.
  110. --*/
  111. {
  112. NetpAssert( ROUND_UP_POINTER( Address, ALIGN_WORST) == Address);
  113. #ifdef WIN32
  114. if (Address == NULL) {
  115. return;
  116. }
  117. if (LocalFree(Address) != NULL) {
  118. NetpAssert(FALSE);
  119. }
  120. #else // ndef WIN32
  121. #ifndef CDEBUG
  122. if (Address == NULL) {
  123. return;
  124. }
  125. RtlFreeHeap(
  126. RtlProcessHeap( ), 0, // heap handle
  127. Address); // addr of alloc'ed space.
  128. #else // def CDEBUG
  129. free( Address );
  130. #endif // def CDEBUG
  131. #endif // ndef WIN32
  132. } // NetpMemoryFree
  133. LPVOID
  134. NetpMemoryReallocate(
  135. IN LPVOID OldAddress OPTIONAL,
  136. IN DWORD NewSize
  137. )
  138. /*++
  139. Routine Description:
  140. NetpMemoryReallocate reallocates a block of memory to a different size.
  141. Contents of the block are copied if necessary. Returns NULL if unable to
  142. allocate additional storage.
  143. Arguments:
  144. OldAddress - Optionally gives address of a block which was allocated by
  145. NetpMemoryAllocate or NetpMemoryReallocate.
  146. NewSize - Gives the new size in bytes.
  147. Return Value:
  148. LPVOID - Pointer to new (possibly moved) block of memory. (Pointer may
  149. be NULL, in which case the old block is still allocated.)
  150. --*/
  151. {
  152. LPVOID NewAddress; // may be NULL.
  153. NetpAssert( ROUND_UP_POINTER( OldAddress, ALIGN_WORST) == OldAddress);
  154. IF_DEBUG( MEMALLOC ) {
  155. NetpKdPrint(( PREFIX_NETLIB "NetpMemoryReallocate: called with ptr "
  156. FORMAT_LPVOID " and size " FORMAT_DWORD ".\n",
  157. (LPVOID) OldAddress, NewSize ));
  158. }
  159. // Special cases: something into nothing, or nothing into something.
  160. if (OldAddress == NULL) {
  161. NewAddress = NetpMemoryAllocate(NewSize);
  162. } else if (NewSize == 0) {
  163. NetpMemoryFree(OldAddress);
  164. NewAddress = NULL;
  165. } else { // must be realloc of something to something else.
  166. #if defined(WIN32)
  167. HANDLE hNewMem; // handle for new (may = old handle)
  168. HANDLE hOldMem;
  169. #ifdef notdef // LocalHandle returns 0 for LMEM_FIXED block
  170. hOldMem = LocalHandle( (LPSTR) OldAddress);
  171. #else
  172. hOldMem = (HANDLE) OldAddress;
  173. #endif // notdef
  174. NetpAssert(hOldMem != NULL);
  175. hNewMem = LocalReAlloc(
  176. hOldMem, // old handle
  177. NewSize, // new size in bytes
  178. LMEM_MOVEABLE); // OK if new block is in new location
  179. if (hNewMem == NULL) {
  180. return (NULL);
  181. }
  182. NewAddress = (LPVOID) hNewMem;
  183. #elif !defined(CDEBUG) // not WIN32 or CDEBUG, must be NT
  184. DWORD OldSize;
  185. // Need size of old area to continue...
  186. OldSize = RtlSizeHeap(
  187. RtlProcessHeap( ), 0, // heap handle
  188. OldAddress); // "base" address
  189. if (OldSize == NewSize) {
  190. NewAddress = OldAddress; // Another special case.
  191. } else {
  192. // Normal case (something into something else). Alloc new area.
  193. NewAddress = NetpMemoryAllocate(NewSize);
  194. if (NewAddress != NULL) {
  195. // Copy lesser of old and new sizes.
  196. NetpMoveMemory(
  197. NewAddress, // dest
  198. OldAddress, // src
  199. (NewSize < OldSize) ? NewSize : OldSize); // len
  200. NetpMemoryFree(OldAddress);
  201. }
  202. }
  203. #else // must be CDEBUG
  204. NetpAssert(NewSize == (DWORD)(size_t)NewSize);
  205. NewAddress = realloc( OldAddress, NewSize );
  206. #endif // CDEBUG
  207. } // must be realloc of something to something else
  208. IF_DEBUG( MEMALLOC ) {
  209. NetpKdPrint(( PREFIX_NETLIB "NetpMemoryReallocate: new address is "
  210. FORMAT_LPVOID ".\n", (LPVOID) OldAddress ));
  211. }
  212. NetpAssert( ROUND_UP_POINTER( NewAddress, ALIGN_WORST) == NewAddress);
  213. return (NewAddress);
  214. } // NetpMemoryReallocate