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.

215 lines
5.4 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Copyright (C) 1992, Microsoft Corporation.
  4. //
  5. // File: SysMem.CXX
  6. //
  7. // Contents: System Memory Management routines
  8. //
  9. // Functions: MemAlloc, MemFree, MemAllocLinked
  10. //
  11. // History: 10-Feb-92 AlexT Created
  12. // 07-May-92 MikeSe Converted to using Win32 Heap functions.
  13. // 14-Jul-92 randyd Added MemSwitchRoot, see memmgmt.doc.
  14. // 5-Oct-93 isaache Slight reorganization, conversion to 'new'
  15. // 13-Jul-94 doncl stole from ole32, put in ADs proj, deleted
  16. // MemSwitchRoot, switched to naked
  17. // Win32 CRITICAL_SECTION usage
  18. //
  19. // Notes: For additional information, see win4adm\standrds\memmgmt.doc.
  20. //
  21. // This memory management package is multithread capable - the
  22. // only place it makes a difference is in MemAllocLinked and
  23. // MemSwitchRoot, where we use a critical section t
  24. // protect adding link blocks to the list. We rely on the fact
  25. // that LocalAlloc is multi-thread safe.
  26. //
  27. //--------------------------------------------------------------------------
  28. #include "dswarn.h"
  29. #include <ADs.hxx>
  30. #if 0
  31. #include <excpt.h>
  32. #include <except.hxx>
  33. #include <dllsem.hxx>
  34. #endif
  35. CRITICAL_SECTION g_csMem;
  36. // Memory block prefix (for signature and link)
  37. typedef struct _smheader
  38. {
  39. unsigned long ulSignature;
  40. struct _smheader *psmNext;
  41. } SMHEADER, *PSMHEADER;
  42. // Memory block signatures (for strict checks)
  43. const ULONG ROOT_BLOCK = 0x726f6f74; // 'root'
  44. const ULONG LINKED_BLOCK = 0x6c696e6b; // 'link'
  45. static BOOL
  46. VerifySignature(PSMHEADER psm, ULONG ulSig )
  47. {
  48. BOOL fReturn;
  49. __try
  50. {
  51. fReturn = (ulSig == psm->ulSignature );
  52. }
  53. __except ( EXCEPTION_EXECUTE_HANDLER )
  54. {
  55. fReturn = FALSE;
  56. }
  57. return fReturn;
  58. }
  59. // This module acts as the declarer of debug support symbols for COMMNOT
  60. DECLARE_INFOLEVEL(Cn);
  61. //+-------------------------------------------------------------------------
  62. //
  63. // Function: MemAlloc
  64. //
  65. // Synopsis: allocates memory block
  66. //
  67. // Arguments: [ulSize] -- size of block in bytes
  68. // [ppv] -- output pointer
  69. //
  70. // Returns: status code
  71. //
  72. // Algorithm: call new, adding space for header
  73. //
  74. // History: 10-Feb-92 AlexT Created
  75. //
  76. //--------------------------------------------------------------------------
  77. HRESULT
  78. MemAlloc ( unsigned long ulSize, void ** ppv )
  79. {
  80. PSMHEADER psm;
  81. *ppv = NULL;
  82. psm = (PSMHEADER) LocalAlloc(LMEM_FIXED, ulSize + sizeof(SMHEADER));
  83. if ( psm != NULL )
  84. {
  85. psm->ulSignature = ROOT_BLOCK;
  86. psm->psmNext = NULL;
  87. *ppv = psm + 1;
  88. return S_OK;
  89. }
  90. return E_OUTOFMEMORY;
  91. }
  92. //+-------------------------------------------------------------------------
  93. //
  94. // Function: MemFree
  95. //
  96. // Synopsis: release system memory block
  97. //
  98. // Arguments: [pvBlockToFree] -- memory block to release
  99. //
  100. // Algorithm: Walk list of linked blocks, deleting each one
  101. //
  102. // History: 10-Feb-92 AlexT Created
  103. //
  104. //--------------------------------------------------------------------------
  105. HRESULT
  106. MemFree( void *pvBlockToFree )
  107. {
  108. PSMHEADER psm = ((PSMHEADER) pvBlockToFree) - 1;
  109. if( pvBlockToFree == NULL || psm == NULL )
  110. return S_OK;
  111. if( !VerifySignature( psm, ROOT_BLOCK ) )
  112. {
  113. Win4Assert( !"MemFree -- not a root block!\n" );
  114. return MEM_E_INVALID_ROOT;
  115. }
  116. do {
  117. PSMHEADER psmNext = psm->psmNext;
  118. psm->ulSignature = 0;
  119. LocalFree(psm);
  120. psm = psmNext;
  121. if( psm && !VerifySignature( psm, LINKED_BLOCK ) )
  122. {
  123. Win4Assert( !"MemFree -- invalid linked block!\n" );
  124. return MEM_E_INVALID_LINK;
  125. }
  126. } while( psm != NULL );
  127. return S_OK;
  128. }
  129. //+-------------------------------------------------------------------------
  130. //
  131. // Function: MemAllocLinked
  132. //
  133. // Synopsis: allocates linked memory block
  134. //
  135. //
  136. // Arguments: [pvRootBlock] -- root memory block
  137. // [ulSize] -- size of new memory block
  138. // [ppv] -- output pointer
  139. //
  140. // Returns: status code
  141. //
  142. //
  143. // History: 10-Feb-92 AlexT Created
  144. //
  145. // Notes: pvRootBlock can specify either a root block, or another
  146. // linked block.
  147. //
  148. //--------------------------------------------------------------------------
  149. HRESULT
  150. MemAllocLinked ( void *pvRootBlock, unsigned long ulSize, void ** ppv )
  151. {
  152. PSMHEADER psm = NULL;
  153. PSMHEADER psmRoot = ((PSMHEADER) pvRootBlock) - 1;
  154. *ppv = NULL;
  155. if ( pvRootBlock == NULL || psmRoot == NULL )
  156. {
  157. Win4Assert( !"MemAllocLinked - null root block\n" );
  158. return MEM_E_INVALID_ROOT;
  159. }
  160. if ( !VerifySignature(psmRoot, ROOT_BLOCK)
  161. && !VerifySignature(psmRoot,LINKED_BLOCK) )
  162. {
  163. Win4Assert( !"MemAllocLinked - invalid root block\n" );
  164. return MEM_E_INVALID_ROOT;
  165. }
  166. psm = (PSMHEADER) LocalAlloc(LMEM_FIXED, ulSize + sizeof(SMHEADER));
  167. if ( psm == NULL )
  168. return E_OUTOFMEMORY;
  169. psm->ulSignature = LINKED_BLOCK;
  170. EnterCriticalSection(&g_csMem);
  171. psm->psmNext = psmRoot->psmNext;
  172. psmRoot->psmNext = psm;
  173. LeaveCriticalSection(&g_csMem);
  174. // move psm past header
  175. *ppv = psm+1;
  176. return S_OK;
  177. }