00854 :
00855
00856 Apply
the corrections in
the log
file to
the hive memory image.
00857
00858 ALGORITHM:
00859
00860 compute size of dirty vector
00861 read in dirty vector
00862
if (i/o error)
00863
return Fail
00864
00865 skip first cluster of data (already processed as log)
00866 sweep vector, looking
for runs of bits
00867 address of first bit
is used to compute memory offset
00868 length of run
is length of block to read
00869 assert always a cluster multiple
00870
file offset kept by running counter
00871 read
00872
if (i/o error)
00873
return fail
00874
00875
return success
00876
00877 NOTE: It
is assumed that
the data part of
the Hive has been
00878 read into a single contiguous block, at Image.
00879
00880 Arguments:
00881
00882
Hive - supplies a pointer to
the hive
control structure
for the
00883 hive of interest
00884
00885 ReadOnly - by
the time
this function
is called,
the hive
is forced to
the
00886 ready-
only state. At
the end,
if recovery goes OK, we restore
the
00887 hive at
it's original state, and enlist all free cells.
00888
00889 TailDisplay - array containing
the tail ends of
the free cell lists - optional
00890
00891 Return Value:
00892
00893
RESULT
00894
00895 --*/
00896 {
00897 ULONG Cluster;
00898 ULONG ClusterSize;
00899 ULONG VectorSize;
00900 PULONG Vector;
00901 ULONG FileOffset;
00902 BOOLEAN rc;
00903 ULONG Current;
00904 ULONG
Start;
00905 ULONG
End;
00906 ULONG Address;
00907 PUCHAR MemoryBlock;
00908 RTL_BITMAP
BitMap;
00909 ULONG Length;
00910 ULONG DirtyVectorSignature = 0;
00911 ULONG i;
00912
PHMAP_ENTRY Me;
00913
PHBIN Bin;
00914
PHBIN NewBin;
00915 PUCHAR SectorImage;
00916 PUCHAR Source;
00917
PHBIN SourceBin;
00918 ULONG SectorOffsetInBin;
00919 ULONG SectorOffsetInBlock;
00920 ULONG BlockOffsetInBin;
00921 ULONG NumberOfSectors;
00922
00923
00924
00925
00926 Cluster =
Hive->
Cluster;
00927 ClusterSize = Cluster *
HSECTOR_SIZE;
00928 Length =
Hive->
BaseBlock->
Length;
00929 VectorSize = (Length /
HSECTOR_SIZE) / 8;
00930 FileOffset = ClusterSize;
00931
00932
00933
00934
00935 rc = (
Hive->
FileRead)(
00936
Hive,
00937
HFILE_TYPE_LOG,
00938 &FileOffset,
00939 (PVOID)&DirtyVectorSignature,
00940
sizeof(DirtyVectorSignature)
00941 );
00942
if (rc ==
FALSE) {
00943
return Fail;
00944 }
00945
00946
if (DirtyVectorSignature !=
HLOG_DV_SIGNATURE) {
00947
return Fail;
00948 }
00949
00950
00951
00952
00953 Vector = (PULONG)((
Hive->
Allocate)(
ROUND_UP(VectorSize,
sizeof(ULONG)),
TRUE));
00954
if (Vector ==
NULL) {
00955
return NoMemory;
00956 }
00957 rc = (
Hive->
FileRead)(
00958
Hive,
00959
HFILE_TYPE_LOG,
00960 &FileOffset,
00961 (PVOID)Vector,
00962 VectorSize
00963 );
00964
if (rc ==
FALSE) {
00965 (
Hive->
Free)(Vector, VectorSize);
00966
return Fail;
00967 }
00968 FileOffset =
ROUND_UP(FileOffset, ClusterSize);
00969
00970
00971
00972
00973
00974 Current = 0;
00975 VectorSize = VectorSize * 8;
00976
00977
RtlInitializeBitMap(&BitMap, Vector, VectorSize);
00978
00979
while (Current < VectorSize) {
00980
00981
00982
00983
00984
for (i = Current; i < VectorSize; i++) {
00985
if (RtlCheckBit(&BitMap, i) == 1) {
00986
break;
00987 }
00988 }
00989
Start = i;
00990
00991
for ( ; i < VectorSize; i++) {
00992
if (RtlCheckBit(&BitMap, i) == 0) {
00993
break;
00994 }
00995 }
00996
End = i;
00997 Current =
End;
00998
00999
01000
01001
01002 Length = (
End -
Start) *
HSECTOR_SIZE;
01003
01004
if( 0 == Length ) {
01005
01006
break;
01007 }
01008
01009
01010
01011
01012 MemoryBlock = (PUCHAR)
ExAllocatePoolWithTag(PagedPool, Length, CM_POOL_TAG);
01013
if( MemoryBlock ==
NULL ) {
01014
goto ErrorExit;
01015 }
01016
01017 rc = (
Hive->
FileRead)(
01018
Hive,
01019
HFILE_TYPE_LOG,
01020 &FileOffset,
01021 (PVOID)MemoryBlock,
01022 Length
01023 );
01024
01025
ASSERT((FileOffset % ClusterSize) == 0);
01026
if (rc ==
FALSE) {
01027
ExFreePool(MemoryBlock);
01028
goto ErrorExit;
01029 }
01030
01031 Source = MemoryBlock;
01032
01033
01034
01035
while(
Start <
End ) {
01036 Address =
Start *
HSECTOR_SIZE;
01037
01038 Me =
HvpGetCellMap(Hive, Address);
01039
VALIDATE_CELL_MAP(__LINE__,Me,Hive,Address);
01040
01041
Bin = (
PHBIN)(Me->
BinAddress &
HMAP_BASE);
01042
01043
01044
01045 SectorOffsetInBin = Address -
Bin->
FileOffset;
01046
01047
if( ( SectorOffsetInBin == 0 ) && ( ((
PHBIN)Source)->Size >
Bin->
Size ) ){
01048
01049
01050
01051
01052
ASSERT( Me->
BinAddress & HMAP_NEWALLOC );
01053
01054 SourceBin = (
PHBIN)Source;
01055
01056
01057
01058
01059
ASSERT( Address == SourceBin->
FileOffset );
01060
ASSERT( SourceBin->
Signature == HBIN_SIGNATURE );
01061
01062
01063
01064
ASSERT( (SourceBin->
FileOffset + SourceBin->
Size) <= End * HSECTOR_SIZE );
01065
01066
01067
01068
01069 NewBin = (
PHBIN)(
Hive->
Allocate)(SourceBin->
Size,
TRUE);
01070
if (NewBin ==
NULL) {
01071
goto ErrorExit;
01072 }
01073
01074
01075
01076
01077
while(
Bin->
FileOffset < (Address + SourceBin->
Size)) {
01078
01079 RtlCopyMemory((PUCHAR)NewBin + (
Bin->
FileOffset - Address),Bin,
Bin->
Size);
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
if( (
Bin->
FileOffset +
Bin->
Size) <
Hive->
BaseBlock->
Length ) {
01090 Me =
HvpGetCellMap(Hive,
Bin->
FileOffset +
Bin->
Size);
01091
VALIDATE_CELL_MAP(__LINE__,Me,Hive,
Bin->
FileOffset +
Bin->
Size);
01092
01093
01094
01095
01096 (
Hive->
Free)(
Bin,
Bin->
Size);
01097
01098
01099
01100
01101
ASSERT( Me->
BinAddress & HMAP_NEWALLOC );
01102
01103
Bin = (
PHBIN)(Me->
BinAddress &
HMAP_BASE);
01104 }
else {
01105
01106
01107
01108
ASSERT( (Address + SourceBin->
Size) ==
Hive->
BaseBlock->
Length );
01109
ASSERT( (
Bin->
FileOffset +
Bin->
Size) ==
Hive->
BaseBlock->
Length );
01110
01111
01112
01113
01114 (
Hive->
Free)(
Bin,
Bin->
Size);
01115
01116
01117
01118
01119
ASSERT( (Bin = NULL) == NULL );
01120
01121
01122
break;
01123 }
01124
01125 }
01126
01127
#if DBG
01128
01129
01130
01131
01132
if(
Bin !=
NULL ) {
01133
ASSERT(
Bin->
FileOffset == (Address + SourceBin->
Size));
01134 }
01135
#endif
01136
01137
01138
01139
01140
01141
while( (Address < (SourceBin->
FileOffset + SourceBin->
Size)) && (
Start <
End) ) {
01142 RtlCopyMemory((PUCHAR)NewBin + (Address - SourceBin->
FileOffset),Source, HSECTOR_SIZE);
01143
01144
01145
01146
01147
Start++;
01148 Source +=
HSECTOR_SIZE;
01149 Address +=
HSECTOR_SIZE;
01150 }
01151
01152
01153
01154
01155
ASSERT(NewBin->
FileOffset == SourceBin->
FileOffset);
01156
ASSERT(NewBin->
Size == SourceBin->
Size);
01157
01158 }
else {
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
ASSERT( SectorOffsetInBin < Bin->Size );
01173
01174 BlockOffsetInBin = (ULONG)((PUCHAR)Me->
BlockAddress - (PUCHAR)
Bin);
01175 SectorOffsetInBlock = SectorOffsetInBin - BlockOffsetInBin;
01176
01177
01178
01179
01180
ASSERT(((PUCHAR)Me->
BlockAddress + SectorOffsetInBlock) == ((PUCHAR)Bin + SectorOffsetInBin));
01181
01182 SectorImage = (PUCHAR)((PUCHAR)Me->
BlockAddress + SectorOffsetInBlock);
01183
01184
01185
01186
01187
ASSERT( SectorImage < ((PUCHAR)Bin + Bin->Size) );
01188
ASSERT( Source < (MemoryBlock + Length) );
01189
01190 NumberOfSectors = 0;
01191
while( ( (SectorImage + (NumberOfSectors *
HSECTOR_SIZE)) < (PUCHAR)((PUCHAR)
Bin +
Bin->
Size) ) &&
01192 ( (
Start + NumberOfSectors ) <
End ) ) {
01193
01194
01195
01196
01197 NumberOfSectors++;
01198 }
01199
01200
01201
01202
01203 RtlCopyMemory(SectorImage,Source, NumberOfSectors * HSECTOR_SIZE);
01204
01205 NewBin =
Bin;
01206
01207
01208
01209
01210
Start += NumberOfSectors;
01211 Source += NumberOfSectors *
HSECTOR_SIZE;
01212
01213 }
01214
01215
01216
01217
01218
if( !
NT_SUCCESS(
HvpEnlistBinInMap(Hive, Length, NewBin, NewBin->
FileOffset, TailDisplay)) ) {
01219
goto ErrorExit;
01220 }
01221 }
01222
01223
01224
01225
01226
ExFreePool(MemoryBlock);
01227 }
01228
01229
01230
01231
01232
01233
Hive->
ReadOnly = ReadOnly;
01234
01235
if( ReadOnly ==
FALSE ) {
01236
01237
01238
01239 Address = 0;
01240
while( Address <
Hive->
BaseBlock->
Length ) {
01241 Me =
HvpGetCellMap(Hive, Address);
01242
VALIDATE_CELL_MAP(__LINE__,Me,Hive,Address);
01243
Bin = (
PHBIN)(Me->
BinAddress &
HMAP_BASE);
01244
01245
ASSERT(
Bin->
FileOffset == Address );
01246
ASSERT(
Bin->
Signature == HBIN_SIGNATURE );
01247
01248
01249
01250
01251
if ( !
HvpEnlistFreeCells(Hive, Bin, Address,TailDisplay)) {
01252
HvCheckHiveDebug.Hive =
Hive;
01253
HvCheckHiveDebug.Status = 0xA004;
01254
HvCheckHiveDebug.Space =
Bin->
Size;
01255
HvCheckHiveDebug.MapPoint = Address;
01256
HvCheckHiveDebug.BinPoint =
Bin;
01257
goto ErrorExit;
01258 }
01259
01260 Address +=
Bin->
Size;
01261 }
01262 }
01263
01264
01265
01266
01267
01268
RtlInitializeBitMap(&(
Hive->
DirtyVector), Vector, VectorSize);
01269
Hive->
DirtyCount =
RtlNumberOfSetBits(&
Hive->
DirtyVector);
01270
Hive->
DirtyAlloc = VectorSize * 8;
01271
HvMarkDirty(Hive, 0,
sizeof(
HBIN));
01272
return HiveSuccess;
01273
01274
ErrorExit:
01275
01276
01277
01278 (
Hive->
Free)(Vector, VectorSize);
01279
return Fail;
01280 }