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.

306 lines
8.9 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. hivefree.c
  5. Abstract:
  6. Hive free code
  7. Author:
  8. Bryan M. Willman (bryanwi) 30-Mar-92
  9. Environment:
  10. Revision History:
  11. Dragos C. Sambotin (dragoss) 25-Jan-99
  12. Implementation of bin-size chunk loading of hives.
  13. --*/
  14. #include "cmp.h"
  15. #ifdef ALLOC_PRAGMA
  16. #pragma alloc_text(PAGE,HvFreeHive)
  17. #pragma alloc_text(PAGE,HvFreeHivePartial)
  18. #endif
  19. // Dragos: Modified functions
  20. VOID
  21. HvFreeHive(
  22. PHHIVE Hive
  23. )
  24. /*++
  25. Routine Description:
  26. Free all of the pieces of a hive.
  27. Arguments:
  28. Hive - supplies a pointer to hive control structure for hive to free.
  29. this structure itself will NOT be freed, but everything it
  30. points to will.
  31. Return Value:
  32. NONE.
  33. --*/
  34. {
  35. PHMAP_DIRECTORY Dir;
  36. PHMAP_ENTRY Me;
  37. PHMAP_ENTRY TempMe;
  38. HCELL_INDEX Address;
  39. ULONG Type;
  40. ULONG Length;
  41. PHBIN Bin;
  42. ULONG Tables;
  43. PFREE_HBIN FreeBin;
  44. ASSERT(Hive->Flat == FALSE);
  45. ASSERT(Hive->ReadOnly == FALSE);
  46. ASSERT(Stable == 0);
  47. ASSERT(Volatile == 1);
  48. CmKdPrintEx((DPFLTR_CONFIG_ID,CML_BIN_MAP,"HvFreeHive(%ws) :\n", Hive->BaseBlock->FileName));
  49. //
  50. // Iterate through both types of storage
  51. //
  52. for (Type = 0; Type <= Volatile; Type++) {
  53. Address = HCELL_TYPE_MASK * Type;
  54. Length = Hive->Storage[Type].Length + (HCELL_TYPE_MASK * Type);
  55. if (Length > (HCELL_TYPE_MASK * Type)) {
  56. //
  57. // Sweep through bin set
  58. //
  59. do {
  60. Me = HvpGetCellMap(Hive, Address);
  61. VALIDATE_CELL_MAP(__LINE__,Me,Hive,Address);
  62. if (Me->BinAddress & HMAP_DISCARDABLE) {
  63. //
  64. // hbin is either discarded or discardable, check the tombstone
  65. //
  66. FreeBin = (PFREE_HBIN)Me->BlockAddress;
  67. Address += FreeBin->Size;
  68. if (FreeBin->Flags & FREE_HBIN_DISCARDABLE) {
  69. CmpFree((PHBIN)HBIN_BASE(Me->BinAddress), FreeBin->Size);
  70. } else if(Me->BinAddress & HMAP_INPAGEDPOOL) {
  71. //
  72. // The bin has been freed, but quota is still charged.
  73. // Since the hive is being freed, the quota must be
  74. // returned here.
  75. //
  76. CmpReleaseGlobalQuota(FreeBin->Size);
  77. }
  78. CmpFree(FreeBin, sizeof(FREE_HBIN));
  79. } else {
  80. if( Me->BinAddress & HMAP_INPAGEDPOOL ) {
  81. ASSERT( Me->BinAddress & HMAP_INPAGEDPOOL );
  82. Bin = (PHBIN)HBIN_BASE(Me->BinAddress);
  83. Address += HvpGetBinMemAlloc(Hive,Bin,Type);
  84. #if 0
  85. //
  86. // Make sure that the next bin in the list is
  87. // actually the start of an alloc before freeing it
  88. //
  89. if (Address < Length) {
  90. TempMe = HvpGetCellMap(Hive, Address);
  91. VALIDATE_CELL_MAP(__LINE__,TempMe,Hive,Address);
  92. ASSERT(TempMe->BinAddress & HMAP_NEWALLOC);
  93. }
  94. #endif
  95. #if DBG
  96. if( Type == Stable ) {
  97. CmKdPrintEx((DPFLTR_CONFIG_ID,CML_BIN_MAP,"HvFreeHive: BinAddress = 0x%p\t Size = 0x%lx\n", Bin, HvpGetBinMemAlloc(Hive,Bin,Type)));
  98. }
  99. #endif
  100. //
  101. // free the actual bin only if it is allocated from paged pool
  102. //
  103. if(HvpGetBinMemAlloc(Hive,Bin,Type)) {
  104. CmpFree(Bin, HvpGetBinMemAlloc(Hive,Bin,Type));
  105. }
  106. } else {
  107. //
  108. // bin was mapped into view; advance carefully
  109. //
  110. Address += HBLOCK_SIZE;
  111. }
  112. }
  113. } while (Address < Length);
  114. //
  115. // Free map table storage
  116. //
  117. ASSERT(Hive->Storage[Type].Length != (HCELL_TYPE_MASK * Type));
  118. Tables = (((Hive->Storage[Type].Length) / HBLOCK_SIZE)-1) / HTABLE_SLOTS;
  119. Dir = Hive->Storage[Type].Map;
  120. HvpFreeMap(Hive, Dir, 0, Tables);
  121. if (Tables > 0) {
  122. CmpFree(Hive->Storage[Type].Map, sizeof(HMAP_DIRECTORY)); // free dir if it exists
  123. }
  124. }
  125. Hive->Storage[Type].Length = 0;
  126. }
  127. CmKdPrintEx((DPFLTR_CONFIG_ID,CML_BIN_MAP,"\n"));
  128. //
  129. // Free the base block
  130. //
  131. (Hive->Free)(Hive->BaseBlock, sizeof(HBASE_BLOCK));
  132. Hive->BaseBlock = NULL;
  133. //
  134. // Free the dirty vector
  135. //
  136. if (Hive->DirtyVector.Buffer != NULL) {
  137. CmpFree((PVOID)(Hive->DirtyVector.Buffer), Hive->DirtyAlloc);
  138. }
  139. HvpFreeHiveFreeDisplay(Hive);
  140. return;
  141. }
  142. VOID
  143. HvFreeHivePartial(
  144. PHHIVE Hive,
  145. HCELL_INDEX Start,
  146. HSTORAGE_TYPE Type
  147. )
  148. /*++
  149. Routine Description:
  150. Free the memory and associated maps for the end of a hive
  151. starting at Start. The baseblock, hive, etc will not be touched.
  152. Arguments:
  153. Hive - supplies a pointer to hive control structure for hive to
  154. partially free.
  155. Start - HCELL_INDEX of first bin to free, will free from this
  156. bin (inclusive) to the end of the hives stable storage.
  157. Type - Type of storage (Stable or Volatile) to be freed.
  158. Return Value:
  159. NONE.
  160. --*/
  161. {
  162. PHMAP_DIRECTORY Dir;
  163. PHMAP_ENTRY Me;
  164. HCELL_INDEX Address;
  165. ULONG StartTable;
  166. ULONG Length;
  167. PHBIN Bin;
  168. ULONG Tables;
  169. ULONG FirstBit;
  170. ULONG LastBit;
  171. PFREE_HBIN FreeBin;
  172. ASSERT(Hive->Flat == FALSE);
  173. ASSERT(Hive->ReadOnly == FALSE);
  174. Address = Start;
  175. Length = Hive->Storage[Type].Length;
  176. ASSERT(Address <= Length);
  177. if (Address == Length) {
  178. return;
  179. }
  180. //
  181. // Sweep through bin set
  182. //
  183. do {
  184. Me = HvpGetCellMap(Hive, Address + (Type*HCELL_TYPE_MASK));
  185. VALIDATE_CELL_MAP(__LINE__,Me,Hive,Address + (Type*HCELL_TYPE_MASK));
  186. if (Me->BinAddress & HMAP_DISCARDABLE) {
  187. FreeBin = (PFREE_HBIN)Me->BlockAddress;
  188. if (FreeBin->Flags & FREE_HBIN_DISCARDABLE) {
  189. CmpFree((PVOID)HBIN_BASE(Me->BinAddress), FreeBin->Size);
  190. } else {
  191. //
  192. // The bin has been freed, but quota is still charged.
  193. // Since the file will now shrink, the quota must be
  194. // returned here.
  195. //
  196. if( Me->BinAddress & HMAP_INPAGEDPOOL) {
  197. //
  198. // we charge quota only for bins in paged-pool
  199. //
  200. CmpReleaseGlobalQuota(FreeBin->Size);
  201. }
  202. }
  203. RemoveEntryList(&FreeBin->ListEntry);
  204. Address += FreeBin->Size;
  205. CmpFree(FreeBin, sizeof(FREE_HBIN));
  206. } else {
  207. Bin = (PHBIN)HBIN_BASE(Me->BinAddress);
  208. Address += HvpGetBinMemAlloc(Hive,Bin,Type);
  209. if( Me->BinAddress & HMAP_INPAGEDPOOL && HvpGetBinMemAlloc(Hive,Bin,Type) ) {
  210. //
  211. // free the bin only if it is allocated from paged pool
  212. //
  213. CmpFree(Bin, HvpGetBinMemAlloc(Hive,Bin,Type));
  214. }
  215. }
  216. } while (Address < Length);
  217. //
  218. // Free map table storage
  219. //
  220. Tables = (((Hive->Storage[Type].Length) / HBLOCK_SIZE) - 1) / HTABLE_SLOTS;
  221. Dir = Hive->Storage[Type].Map;
  222. if (Start > 0) {
  223. StartTable = ((Start-1) / HBLOCK_SIZE) / HTABLE_SLOTS;
  224. } else {
  225. StartTable = (ULONG)-1;
  226. }
  227. HvpFreeMap(Hive, Dir, StartTable+1, Tables);
  228. //
  229. // update hysteresis (eventually queue work item)
  230. //
  231. if( Type == Stable) {
  232. CmpUpdateSystemHiveHysteresis(Hive,(Start&(~HCELL_TYPE_MASK)),Hive->Storage[Type].Length);
  233. }
  234. Hive->Storage[Type].Length = (Start&(~HCELL_TYPE_MASK));
  235. if (Type==Stable) {
  236. //
  237. // Clear dirty vector for data past Hive->Storage[Stable].Length
  238. //
  239. FirstBit = Start / HSECTOR_SIZE;
  240. LastBit = Hive->DirtyVector.SizeOfBitMap;
  241. ASSERT(Hive->DirtyCount == RtlNumberOfSetBits(&Hive->DirtyVector));
  242. RtlClearBits(&Hive->DirtyVector, FirstBit, LastBit-FirstBit);
  243. Hive->DirtyCount = RtlNumberOfSetBits(&Hive->DirtyVector);
  244. }
  245. HvpAdjustHiveFreeDisplay(Hive,Hive->Storage[Type].Length,Type);
  246. return;
  247. }