00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
#include "cmp.h"
00026
00027
#ifdef ALLOC_PRAGMA
00028
#pragma alloc_text(PAGE,HvFreeHive)
00029
#pragma alloc_text(PAGE,HvFreeHivePartial)
00030
#endif
00031
00032
00033
VOID
00034 HvFreeHive(
00035
PHHIVE Hive
00036 )
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 {
00055
PHMAP_DIRECTORY Dir;
00056
PHMAP_ENTRY Me;
00057
HCELL_INDEX Address;
00058 ULONG Type;
00059 ULONG Length;
00060
PHBIN Bin;
00061 ULONG Tables;
00062
PFREE_HBIN FreeBin;
00063
00064
ASSERT(
Hive->
Flat ==
FALSE);
00065
ASSERT(
Hive->
ReadOnly ==
FALSE);
00066
ASSERT(
Stable == 0);
00067
ASSERT(
Volatile == 1);
00068
00069
CMLOG(
CML_BIN,
CMS_BIN_MAP) {
00070 KdPrint((
"HvFreeHive(%ws) :\n",
Hive->
BaseBlock->
FileName));
00071 }
00072
00073
00074
00075
for (Type = 0; Type <=
Volatile; Type++) {
00076
00077 Address =
HCELL_TYPE_MASK * Type;
00078 Length =
Hive->Storage[Type].Length + (
HCELL_TYPE_MASK * Type);
00079
00080
if (Length > (
HCELL_TYPE_MASK * Type)) {
00081
00082
00083
00084
00085
do {
00086 Me =
HvpGetCellMap(
Hive, Address);
00087
VALIDATE_CELL_MAP(__LINE__,Me,
Hive,Address);
00088
if (Me->
BinAddress &
HMAP_DISCARDABLE) {
00089
00090
00091
00092 FreeBin = (
PFREE_HBIN)Me->
BlockAddress;
00093 Address += FreeBin->
Size;
00094
if (FreeBin->
Flags &
FREE_HBIN_DISCARDABLE) {
00095
CmpFree((
PHBIN)(Me->
BinAddress &
HMAP_BASE), FreeBin->
Size);
00096 }
00097
CmpFree(FreeBin,
sizeof(
FREE_HBIN));
00098 }
else {
00099
Bin = (
PHBIN)(Me->
BinAddress &
HMAP_BASE);
00100 Address +=
Bin->
MemAlloc;
00101
#if DBG
00102
00103
00104
00105
00106
if (Address < Length) {
00107 Me =
HvpGetCellMap(
Hive, Address);
00108
VALIDATE_CELL_MAP(__LINE__,Me,
Hive,Address);
00109
ASSERT(Me->
BinAddress &
HMAP_NEWALLOC);
00110 }
00111
#endif
00112
00113
CMLOG(
CML_BIN,
CMS_BIN_MAP) {
00114
if( Type ==
Stable ) {
00115 KdPrint((
"HvFreeHive: BinAddress = 0x%08lx\t Size = 0x%lx\n",
Bin,
Bin->
MemAlloc));
00116 }
00117 }
00118
00119
CmpFree(
Bin,
Bin->
MemAlloc);
00120 }
00121
00122 }
while (Address < Length);
00123
00124
00125
00126
00127
ASSERT(
Hive->Storage[Type].Length != (
HCELL_TYPE_MASK * Type));
00128 Tables = (((
Hive->Storage[Type].Length) /
HBLOCK_SIZE)-1) /
HTABLE_SLOTS;
00129 Dir =
Hive->Storage[Type].Map;
00130
HvpFreeMap(
Hive, Dir, 0, Tables);
00131
00132
if (Tables > 0) {
00133
CmpFree(
Hive->Storage[Type].Map,
sizeof(
HMAP_DIRECTORY));
00134 }
00135 }
00136
Hive->Storage[Type].Length = 0;
00137 }
00138
00139
CMLOG(
CML_BIN,
CMS_BIN_MAP) {
00140 KdPrint((
"\n"));
00141 }
00142
00143
00144
00145 (
Hive->
Free)(
Hive->
BaseBlock,
sizeof(
HBASE_BLOCK));
00146
Hive->
BaseBlock =
NULL;
00147
00148
00149
00150
00151
if (
Hive->
DirtyVector.Buffer !=
NULL) {
00152
CmpFree((PVOID)(
Hive->
DirtyVector.Buffer),
Hive->
DirtyAlloc);
00153 }
00154
00155
return;
00156 }
00157
00158
00159
VOID
00160 HvFreeHivePartial(
00161
PHHIVE Hive,
00162 HCELL_INDEX Start,
00163 HSTORAGE_TYPE Type
00164 )
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187 {
00188
PHMAP_DIRECTORY Dir;
00189
PHMAP_ENTRY Me;
00190
HCELL_INDEX Address;
00191 ULONG StartTable;
00192 ULONG Length;
00193
PHBIN Bin;
00194 ULONG Tables;
00195 ULONG FirstBit;
00196 ULONG LastBit;
00197
PFREE_HBIN FreeBin;
00198
00199
ASSERT(
Hive->
Flat ==
FALSE);
00200
ASSERT(
Hive->
ReadOnly ==
FALSE);
00201
00202 Address =
Start;
00203 Length =
Hive->Storage[Type].Length;
00204
ASSERT(Address <= Length);
00205
00206
if (Address == Length) {
00207
return;
00208 }
00209
00210
00211
00212
00213
do {
00214 Me =
HvpGetCellMap(
Hive, Address + (Type*
HCELL_TYPE_MASK));
00215
VALIDATE_CELL_MAP(__LINE__,Me,
Hive,Address + (Type*
HCELL_TYPE_MASK));
00216
if (Me->
BinAddress &
HMAP_DISCARDABLE) {
00217 FreeBin = (
PFREE_HBIN)Me->
BlockAddress;
00218
if (FreeBin->
Flags &
FREE_HBIN_DISCARDABLE) {
00219
CmpFree((PVOID)(Me->
BinAddress &
HMAP_BASE), FreeBin->
Size);
00220 }
else {
00221
00222
00223
00224
00225
00226
CmpReleaseGlobalQuota(FreeBin->
Size);
00227 }
00228 RemoveEntryList(&FreeBin->
ListEntry);
00229 Address += FreeBin->
Size;
00230
CmpFree(FreeBin,
sizeof(
FREE_HBIN));
00231
00232 }
else {
00233
Bin = (
PHBIN)(Me->
BinAddress &
HMAP_BASE);
00234
00235 Address +=
Bin->
MemAlloc;
00236
CmpFree(
Bin,
Bin->
MemAlloc);
00237 }
00238 }
while (Address < Length);
00239
00240
00241
00242
00243 Tables = (((
Hive->Storage[Type].Length) /
HBLOCK_SIZE) - 1) /
HTABLE_SLOTS;
00244 Dir =
Hive->Storage[Type].Map;
00245
if (
Start > 0) {
00246 StartTable = ((
Start-1) /
HBLOCK_SIZE) /
HTABLE_SLOTS;
00247 }
else {
00248 StartTable = (ULONG)-1;
00249 }
00250
HvpFreeMap(
Hive, Dir, StartTable+1, Tables);
00251
00252
Hive->Storage[Type].Length =
Start;
00253
00254
if (Type==
Stable) {
00255
00256
00257
00258 FirstBit =
Start /
HSECTOR_SIZE;
00259 LastBit =
Hive->
DirtyVector.SizeOfBitMap;
00260
ASSERT(
Hive->
DirtyCount ==
RtlNumberOfSetBits(&
Hive->
DirtyVector));
00261
RtlClearBits(&
Hive->
DirtyVector, FirstBit, LastBit-FirstBit);
00262
Hive->
DirtyCount =
RtlNumberOfSetBits(&
Hive->
DirtyVector);
00263 }
00264
00265
return;
00266 }