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.

291 lines
4.9 KiB

  1. //=======================================================================
  2. //
  3. // Copyright (c) 1998-2000 Microsoft Corporation. All Rights Reserved.
  4. //
  5. // File: MemUtil.CPP
  6. // Author: Charles Ma, 10/13/2000
  7. //
  8. // Revision History:
  9. //
  10. //
  11. //
  12. //
  13. // Description:
  14. //
  15. // Implement IU memory utility library
  16. //
  17. //=======================================================================
  18. #include <windows.h>
  19. #include <MemUtil.h>
  20. // *******************************************************************************
  21. //
  22. // Implementation of class CSmartHeapMem
  23. //
  24. // *******************************************************************************
  25. const size_t ArrayGrowChunk = 4;
  26. //
  27. // constructor
  28. //
  29. CSmartHeapMem::CSmartHeapMem()
  30. {
  31. m_ArraySize = 0;
  32. m_lppMems = NULL;
  33. m_Heap = GetProcessHeap();
  34. }
  35. //
  36. // desctructor
  37. //
  38. CSmartHeapMem::~CSmartHeapMem()
  39. {
  40. if (NULL != m_Heap)
  41. {
  42. for (size_t i = 0; i < m_ArraySize; i++)
  43. {
  44. if (NULL != m_lppMems[i])
  45. HeapFree(m_Heap, 0, m_lppMems[i]);
  46. }
  47. HeapFree(m_Heap, 0, m_lppMems);
  48. }
  49. }
  50. //
  51. // allocate mem
  52. //
  53. LPVOID CSmartHeapMem::Alloc(size_t nBytes, DWORD dwFlags /*= HEAP_ZERO_MEMORY*/)
  54. {
  55. int iNdx;
  56. LPVOID pMem = NULL;
  57. DWORD dwBytes = (DWORD) nBytes;
  58. DWORD dwCurrentFlag = dwFlags & (~HEAP_GENERATE_EXCEPTIONS |
  59. ~HEAP_NO_SERIALIZE);
  60. if (NULL == m_Heap || 0x0 == dwBytes)
  61. {
  62. return NULL;
  63. }
  64. iNdx = GetUnusedArraySlot();
  65. if (iNdx < 0 || NULL == m_Heap)
  66. {
  67. //
  68. // out of mem
  69. //
  70. return NULL;
  71. }
  72. pMem = m_lppMems[iNdx] = HeapAlloc(m_Heap, dwCurrentFlag, dwBytes);
  73. return pMem;
  74. }
  75. //
  76. // reallocate mem
  77. //
  78. LPVOID CSmartHeapMem::ReAlloc(LPVOID lpMem, size_t nBytes, DWORD dwFlags)
  79. {
  80. LPVOID pMem = NULL;
  81. DWORD dwBytes = (DWORD) nBytes;
  82. DWORD dwCurrentFlag = dwFlags & (~HEAP_GENERATE_EXCEPTIONS |
  83. ~HEAP_NO_SERIALIZE);
  84. int n;
  85. if (0x0 == dwBytes || NULL == m_Heap)
  86. {
  87. return NULL;
  88. }
  89. n = FindIndex(lpMem);
  90. if (n < 0)
  91. {
  92. return NULL;
  93. }
  94. pMem = HeapReAlloc(m_Heap, dwCurrentFlag, lpMem, dwBytes);
  95. if (NULL != pMem)
  96. {
  97. m_lppMems[n] = pMem;
  98. }
  99. return pMem;
  100. }
  101. //
  102. // return the size allocated
  103. //
  104. size_t CSmartHeapMem::Size(LPVOID lpMem)
  105. {
  106. if (NULL == m_Heap) return 0;
  107. return HeapSize(m_Heap, 0, lpMem);
  108. }
  109. void CSmartHeapMem::FreeAllocatedMem(LPVOID lpMem)
  110. {
  111. int n = FindIndex(lpMem);
  112. if (n < 0 || NULL == m_Heap)
  113. {
  114. return;
  115. }
  116. HeapFree(m_Heap, 0, lpMem);
  117. m_lppMems[n] = NULL;
  118. }
  119. //
  120. // get first empty slot from mem pointer array
  121. // expand array if needed
  122. //
  123. int CSmartHeapMem::GetUnusedArraySlot()
  124. {
  125. int iNdx = -1;
  126. UINT i;
  127. LPVOID lpCurrent;
  128. LPVOID lpTemp;
  129. if (0 == m_ArraySize)
  130. {
  131. if (NULL == (m_lppMems = (LPVOID*)HeapAlloc(
  132. m_Heap,
  133. HEAP_ZERO_MEMORY,
  134. ArrayGrowChunk * sizeof(LPVOID))))
  135. {
  136. return -1;
  137. }
  138. m_ArraySize = ArrayGrowChunk;
  139. }
  140. while (true)
  141. {
  142. for (i = 0; i < m_ArraySize; i++)
  143. {
  144. if (NULL == m_lppMems[i])
  145. {
  146. return i;
  147. }
  148. }
  149. //
  150. // if come to here, we didn't find an empty slot
  151. //
  152. if (NULL == (lpTemp = HeapReAlloc(
  153. m_Heap,
  154. HEAP_ZERO_MEMORY,
  155. m_lppMems,
  156. (m_ArraySize + ArrayGrowChunk) * sizeof(LPVOID))))
  157. {
  158. //
  159. // when fail, original mem buffer pointed by m_lppMems untouched,
  160. // we we simply return -1 to signal caller that no more free slots.
  161. //
  162. return -1;
  163. }
  164. //
  165. // when success, the mem pointers previously stored in m_lppMems already
  166. // been copied to lpTemp, and lppMems was freed.
  167. //
  168. //
  169. // assign the newly allocated mems to m_lppMems in success case
  170. //
  171. m_lppMems = (LPVOID *) lpTemp;
  172. m_ArraySize += ArrayGrowChunk;
  173. //
  174. // go back to loop again
  175. //
  176. }
  177. }
  178. //
  179. // based on mem pointer, find index
  180. //
  181. int CSmartHeapMem::FindIndex(LPVOID pMem)
  182. {
  183. if (NULL == pMem) return -1;
  184. for (size_t i = 0; i < m_ArraySize; i++)
  185. {
  186. if (pMem == m_lppMems[i]) return (int)i;
  187. }
  188. return -1;
  189. }
  190. // *******************************************************************************
  191. //
  192. // Other memory related functions
  193. //
  194. // *******************************************************************************
  195. //
  196. // implemenation of CRT memcpy() function
  197. //
  198. LPVOID MyMemCpy(LPVOID dest, const LPVOID src, size_t nBytes)
  199. {
  200. LPBYTE lpDest = (LPBYTE)dest;
  201. LPBYTE lpSrc = (LPBYTE)src;
  202. if (NULL == src || NULL == dest || src == dest)
  203. {
  204. return dest;
  205. }
  206. while (nBytes-- > 0)
  207. {
  208. *lpDest++ = *lpSrc++;
  209. }
  210. return dest;
  211. }
  212. //
  213. // allocate heap mem and copy
  214. //
  215. LPVOID HeapAllocCopy(LPVOID src, size_t nBytes)
  216. {
  217. LPVOID pBuffer;
  218. if (0 == nBytes)
  219. {
  220. return NULL;
  221. }
  222. pBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nBytes);
  223. if (NULL != pBuffer)
  224. {
  225. MyMemCpy(pBuffer, src, nBytes);
  226. }
  227. return pBuffer;
  228. }