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
00026
00027
00028
00029
00030
00031
00032
#include "cmp.h"
00033
00034 #define IO_BUFFER_SIZE 0x10000 //64K
00035
00036 typedef enum _RESULT {
00037
NotHive,
00038
Fail,
00039
NoMemory,
00040
HiveSuccess,
00041
RecoverHeader,
00042
RecoverData
00043 }
RESULT;
00044
00045
RESULT
00046
HvpGetHiveHeader(
00047
PHHIVE Hive,
00048
PHBASE_BLOCK *BaseBlock,
00049 PLARGE_INTEGER TimeStamp
00050 );
00051
00052
RESULT
00053
HvpGetLogHeader(
00054
PHHIVE Hive,
00055
PHBASE_BLOCK *BaseBlock,
00056 PLARGE_INTEGER TimeStamp
00057 );
00058
00059
RESULT
00060
HvpRecoverData(
00061
PHHIVE Hive,
00062 BOOLEAN ReadOnly,
00063 PHCELL_INDEX TailDisplay OPTIONAL
00064 );
00065
00066
NTSTATUS
00067
HvpReadFileImageAndBuildMap(
00068
PHHIVE Hive,
00069 ULONG Length,
00070 PHCELL_INDEX TailDisplay OPTIONAL
00071 );
00072
00073
VOID
00074
HvpDelistBinFreeCells(
00075
PHHIVE Hive,
00076
PHBIN Bin,
00077 HSTORAGE_TYPE Type,
00078 PHCELL_INDEX TailDisplay OPTIONAL
00079 );
00080
00081
#ifdef ALLOC_PRAGMA
00082
#pragma alloc_text(PAGE,HvLoadHive)
00083
#pragma alloc_text(PAGE,HvpGetHiveHeader)
00084
#pragma alloc_text(PAGE,HvpGetLogHeader)
00085
#pragma alloc_text(PAGE,HvpRecoverData)
00086
#pragma alloc_text(PAGE,HvpReadFileImageAndBuildMap)
00087
#endif
00088
00089
00090
extern struct {
00091 PHHIVE Hive;
00092 ULONG
Status;
00093 ULONG
Space;
00094 HCELL_INDEX MapPoint;
00095 PHBIN BinPoint;
00096 }
HvCheckHiveDebug;
00097
00098
00099
NTSTATUS
00100 HvLoadHive(
00101
PHHIVE Hive,
00102 PHCELL_INDEX TailDisplay OPTIONAL
00103 )
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174 {
00175
PHBASE_BLOCK BaseBlock;
00176 ULONG result1;
00177 ULONG result2;
00178
NTSTATUS status;
00179 LARGE_INTEGER TimeStamp;
00180 ULONG FileOffset;
00181
PHBIN pbin;
00182 BOOLEAN ReadOnlyFlagCopy;
00183
00184
ASSERT(
Hive->
Signature ==
HHIVE_SIGNATURE);
00185
00186 BaseBlock =
NULL;
00187 result1 =
HvpGetHiveHeader(
Hive, &BaseBlock, &TimeStamp);
00188
00189
00190
00191
00192
if (result1 ==
NoMemory) {
00193 status = STATUS_INSUFFICIENT_RESOURCES;
00194
goto Exit1;
00195 }
00196
if (result1 ==
NotHive) {
00197 status = STATUS_NOT_REGISTRY_FILE;
00198
goto Exit1;
00199 }
00200
00201
00202 ReadOnlyFlagCopy =
Hive->
ReadOnly;
00203
00204
00205
00206
if ( ((result1 ==
RecoverData) ||
00207 (result1 ==
RecoverHeader)) )
00208 {
00209
00210
00211
00212
if(
Hive->
Log ==
FALSE)
00213 {
00214
00215
00216
00217 status = STATUS_REGISTRY_CORRUPT;
00218
goto Exit1;
00219 }
else {
00220
00221
00222
00223
00224
00225
00226
Hive->
ReadOnly =
TRUE;
00227 }
00228 }
00229
00230
00231
00232
00233
if (result1 ==
RecoverHeader) {
00234 result2 =
HvpGetLogHeader(
Hive, &BaseBlock, &TimeStamp);
00235
if (result2 ==
NoMemory) {
00236 status = STATUS_INSUFFICIENT_RESOURCES;
00237
goto Exit1;
00238 }
00239
if (result2 ==
Fail) {
00240 status = STATUS_REGISTRY_CORRUPT;
00241
goto Exit1;
00242 }
00243 BaseBlock->
Type =
HFILE_TYPE_PRIMARY;
00244 }
00245
Hive->
BaseBlock = BaseBlock;
00246
Hive->
Version =
Hive->
BaseBlock->
Minor;
00247
00248
00249
00250
00251
00252 status =
HvpReadFileImageAndBuildMap(
Hive,BaseBlock->
Length,TailDisplay);
00253
00254
00255
00256
00257
00258
if( !
NT_SUCCESS(status) && ((status != STATUS_REGISTRY_CORRUPT) || (result1 !=
RecoverData)) ) {
00259
goto Exit2;
00260 }
00261
00262
00263
00264
00265 status = STATUS_SUCCESS;
00266
if ( (result1 ==
RecoverHeader) ||
00267 (result1 ==
RecoverData) )
00268 {
00269
00270
00271
00272
00273 result2 =
HvpRecoverData(
Hive,ReadOnlyFlagCopy,TailDisplay);
00274
if (result2 ==
NoMemory) {
00275 status = STATUS_INSUFFICIENT_RESOURCES;
00276
goto Exit2;
00277 }
00278
if (result2 ==
Fail) {
00279 status = STATUS_REGISTRY_CORRUPT;
00280
goto Exit2;
00281 }
00282 status = STATUS_REGISTRY_RECOVERED;
00283 }
00284
00285 BaseBlock->
Sequence2 = BaseBlock->
Sequence1;
00286
return status;
00287
00288
00289 Exit2:
00290
00291
00292
00293
HvpFreeAllocatedBins(
Hive );
00294
00295
00296
00297
00298
HvpCleanMap(
Hive );
00299
00300 Exit1:
00301
if (BaseBlock !=
NULL) {
00302 (
Hive->
Free)(BaseBlock,
sizeof(
HBASE_BLOCK));
00303 }
00304
00305
Hive->
BaseBlock =
NULL;
00306
Hive->
DirtyCount = 0;
00307
return status;
00308 }
00309
00310
NTSTATUS
00311 HvpReadFileImageAndBuildMap(
00312
PHHIVE Hive,
00313 ULONG Length,
00314 PHCELL_INDEX TailDisplay OPTIONAL
00315 )
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347 {
00348 ULONG FileOffset;
00349
NTSTATUS Status = STATUS_SUCCESS;
00350
PHBIN Bin;
00351 ULONG BinSize;
00352 ULONG BinOffset;
00353 ULONG BinFileOffset;
00354 ULONG BinDataInBuffer;
00355 ULONG BinDataNeeded;
00356 PUCHAR IOBuffer;
00357 ULONG IOBufferSize;
00358 ULONG IOBufferOffset;
00359
00360
00361
00362
00363
Status =
HvpInitMap(
Hive);
00364
00365
if( !
NT_SUCCESS(
Status) ) {
00366
00367
00368
00369
return Status;
00370 }
00371
00372
00373
00374
00375
00376 IOBuffer = (PUCHAR)
ExAllocatePool(
PagedPool,
IO_BUFFER_SIZE);
00377
if (IOBuffer ==
NULL) {
00378
Status = STATUS_INSUFFICIENT_RESOURCES;
00379
HvpCleanMap(
Hive );
00380
return Status;
00381 }
00382
00383
00384
00385
00386 FileOffset =
HBLOCK_SIZE;
00387 BinFileOffset = FileOffset;
00388
Bin =
NULL;
00389
00390
00391
00392
00393
while( FileOffset < (Length +
HBLOCK_SIZE) ) {
00394
00395
00396
00397 IOBufferOffset = 0;
00398
00399
00400
00401
00402
00403 IOBufferSize = Length +
HBLOCK_SIZE - FileOffset;
00404 IOBufferSize = ( IOBufferSize >
IO_BUFFER_SIZE ) ?
IO_BUFFER_SIZE : IOBufferSize;
00405
00406
ASSERT( (IOBufferSize %
HBLOCK_SIZE) == 0 );
00407
00408
00409
00410
00411
if ( ! (
Hive->
FileRead)(
00412
Hive,
00413
HFILE_TYPE_PRIMARY,
00414 &FileOffset,
00415 (PVOID)IOBuffer,
00416 IOBufferSize
00417 )
00418 )
00419 {
00420
Status = STATUS_REGISTRY_IO_FAILED;
00421
goto ErrorExit;
00422 }
00423
00424
00425
00426
00427
while( IOBufferOffset < IOBufferSize ) {
00428
00429
if(
Bin ==
NULL ) {
00430
00431
00432
00433
00434
00435
Bin = (
PHBIN)(IOBuffer + IOBufferOffset);
00436
00437
00438
00439 BinSize =
Bin->
Size;
00440
if ( (BinSize > Length) ||
00441 (BinSize <
HBLOCK_SIZE) ||
00442 (
Bin->
Signature !=
HBIN_SIGNATURE) ||
00443 (
Bin->
FileOffset != (BinFileOffset -
HBLOCK_SIZE) )) {
00444
00445
00446
00447
Bin = (
PHBIN)(
Hive->
Allocate)(
HBLOCK_SIZE,
TRUE);
00448
if (
Bin ==
NULL) {
00449
Status = STATUS_INSUFFICIENT_RESOURCES;
00450
goto ErrorExit;
00451 }
00452
00453
00454
00455 RtlCopyMemory(
Bin,(IOBuffer + IOBufferOffset),
HBLOCK_SIZE);
00456
00457
Status = STATUS_REGISTRY_CORRUPT;
00458
HvCheckHiveDebug.Hive =
Hive;
00459
HvCheckHiveDebug.Status = 0xA001;
00460
HvCheckHiveDebug.Space = Length;
00461
HvCheckHiveDebug.MapPoint = BinFileOffset;
00462
HvCheckHiveDebug.BinPoint =
Bin;
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
Bin->
Signature = 0;
00473 BinSize =
Bin->
Size =
HBLOCK_SIZE;
00474
Bin->
FileOffset = BinFileOffset -
HBLOCK_SIZE;
00475
00476
00477
00478
00479 ((
PHCELL)((PUCHAR)
Bin +
sizeof(
HBIN)))->Size =
sizeof(
HBIN) - BinSize;
00480
00481
00482
00483
Status =
HvpEnlistBinInMap(
Hive, Length,
Bin, BinFileOffset -
HBLOCK_SIZE, TailDisplay);
00484
00485
if( !
NT_SUCCESS(
Status) ) {
00486
goto ErrorExit;
00487 }
00488
00489
00490
00491
00492 BinFileOffset +=
Bin->
Size;
00493 IOBufferOffset +=
Bin->
Size;
00494
00495
00496
00497
00498
Bin =
NULL;
00499 }
else {
00500
00501
00502
00503
Bin = (
PHBIN)(
Hive->
Allocate)(BinSize,
TRUE);
00504
if (
Bin ==
NULL) {
00505
Status = STATUS_INSUFFICIENT_RESOURCES;
00506
goto ErrorExit;
00507 }
00508
00509
00510
00511
00512
00513 BinOffset = 0;
00514 }
00515 }
else {
00516
00517
00518
00519
00520
00521
ASSERT(
Bin !=
NULL );
00522 BinDataInBuffer = (IOBufferSize - IOBufferOffset);
00523 BinDataNeeded = (BinSize - BinOffset);
00524
00525
if( BinDataInBuffer >= BinDataNeeded ) {
00526
00527
00528
00529 RtlCopyMemory(((PUCHAR)
Bin + BinOffset),(IOBuffer + IOBufferOffset), BinDataNeeded);
00530
00531
00532
00533
Status =
HvpEnlistBinInMap(
Hive, Length,
Bin, BinFileOffset -
HBLOCK_SIZE, TailDisplay);
00534
00535
if( !
NT_SUCCESS(
Status) ) {
00536
goto ErrorExit;
00537 }
00538
00539
00540
00541 BinFileOffset += BinSize;
00542 IOBufferOffset += BinDataNeeded;
00543
00544
00545
00546
Bin =
NULL;
00547 }
else {
00548
00549
00550
00551
00552 RtlCopyMemory(((PUCHAR)
Bin + BinOffset),(IOBuffer + IOBufferOffset), BinDataInBuffer);
00553
00554
00555
00556
00557 BinOffset += BinDataInBuffer;
00558 IOBufferOffset += BinDataInBuffer;
00559
00560
00561
00562
00563
ASSERT( IOBufferOffset == IOBufferSize );
00564 }
00565 }
00566 }
00567 }
00568
00569
00570
00571
00572
ASSERT(
Bin ==
NULL );
00573
00574
00575
00576
00577
ExFreePool(IOBuffer);
00578
00579
return Status;
00580
00581
ErrorExit:
00582
00583
00584
00585
ExFreePool(IOBuffer);
00586
00587
return Status;
00588 }
00589
00590
00591
RESULT
00592 HvpGetHiveHeader(
00593
PHHIVE Hive,
00594
PHBASE_BLOCK *BaseBlock,
00595 PLARGE_INTEGER TimeStamp
00596 )
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653 {
00654
PHBASE_BLOCK buffer;
00655 BOOLEAN rc;
00656 ULONG FileOffset;
00657 ULONG Alignment;
00658
00659
ASSERT(
sizeof(
HBASE_BLOCK) >= (
HSECTOR_SIZE *
Hive->
Cluster));
00660
00661
00662
00663
00664 *BaseBlock =
NULL;
00665 buffer = (
PHBASE_BLOCK)((
Hive->
Allocate)(
sizeof(
HBASE_BLOCK),
TRUE));
00666
if (buffer ==
NULL) {
00667
return NoMemory;
00668 }
00669
00670
00671
00672
00673 Alignment =
Hive->
Cluster *
HSECTOR_SIZE - 1;
00674
if (((ULONG_PTR)buffer & Alignment) != 0) {
00675 (
Hive->
Free)(buffer,
sizeof(
HBASE_BLOCK));
00676 buffer = (
PHBASE_BLOCK)((
Hive->
Allocate)(
PAGE_SIZE,
TRUE));
00677
if (buffer ==
NULL) {
00678
return NoMemory;
00679 }
00680 }
00681 RtlZeroMemory((PVOID)buffer,
sizeof(
HBASE_BLOCK));
00682
00683
00684
00685
00686 FileOffset = 0;
00687 rc = (
Hive->
FileRead)(
Hive,
00688
HFILE_TYPE_PRIMARY,
00689 &FileOffset,
00690 (PVOID)buffer,
00691
HSECTOR_SIZE *
Hive->
Cluster);
00692
00693
if ( (rc ==
FALSE) ||
00694 (
HvpHeaderCheckSum(buffer) != buffer->CheckSum)) {
00695
00696
00697
00698 FileOffset =
HBLOCK_SIZE;
00699 rc = (
Hive->
FileRead)(
Hive,
00700
HFILE_TYPE_PRIMARY,
00701 &FileOffset,
00702 (PVOID)buffer,
00703
HSECTOR_SIZE *
Hive->
Cluster);
00704
00705
if ( (rc ==
FALSE) ||
00706 ( ((
PHBIN)buffer)->Signature !=
HBIN_SIGNATURE) ||
00707 ( ((
PHBIN)buffer)->FileOffset != 0)
00708 )
00709 {
00710
00711
00712
00713 (
Hive->
Free)(buffer,
sizeof(
HBASE_BLOCK));
00714
return NotHive;
00715 }
00716
00717
00718
00719
00720
00721 *TimeStamp = ((
PHBIN)buffer)->TimeStamp;
00722 (
Hive->
Free)(buffer,
sizeof(
HBASE_BLOCK));
00723
return RecoverHeader;
00724 }
00725
00726
00727
00728
00729
if ( (buffer->Signature !=
HBASE_BLOCK_SIGNATURE) ||
00730 (buffer->Type !=
HFILE_TYPE_PRIMARY) ||
00731 (buffer->Major !=
HSYS_MAJOR) ||
00732 (buffer->Minor >
HSYS_MINOR) ||
00733 ((buffer->Major == 1) && (buffer->Minor == 0)) ||
00734 (buffer->Format !=
HBASE_FORMAT_MEMORY)
00735 )
00736 {
00737
00738
00739
00740 (
Hive->
Free)(buffer,
sizeof(
HBASE_BLOCK));
00741
return NotHive;
00742 }
00743
00744
00745
00746
00747 *BaseBlock = buffer;
00748 *TimeStamp = buffer->
TimeStamp;
00749
if ( (buffer->Sequence1 != buffer->Sequence2) ) {
00750
return RecoverData;
00751 }
00752
00753
return HiveSuccess;
00754 }
00755
00756
00757
RESULT
00758 HvpGetLogHeader(
00759
PHHIVE Hive,
00760
PHBASE_BLOCK *BaseBlock,
00761 PLARGE_INTEGER TimeStamp
00762 )
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799 {
00800
PHBASE_BLOCK buffer;
00801 BOOLEAN rc;
00802 ULONG FileOffset;
00803
00804
ASSERT(
sizeof(
HBASE_BLOCK) ==
HBLOCK_SIZE);
00805
ASSERT(
sizeof(
HBASE_BLOCK) >= (
HSECTOR_SIZE *
Hive->
Cluster));
00806
00807
00808
00809
00810 *BaseBlock =
NULL;
00811 buffer = (
PHBASE_BLOCK)((
Hive->
Allocate)(
sizeof(
HBASE_BLOCK),
TRUE));
00812
if (buffer ==
NULL) {
00813
return NoMemory;
00814 }
00815 RtlZeroMemory((PVOID)buffer,
HSECTOR_SIZE);
00816
00817
00818
00819
00820 FileOffset = 0;
00821 rc = (
Hive->
FileRead)(
Hive,
00822
HFILE_TYPE_LOG,
00823 &FileOffset,
00824 (PVOID)buffer,
00825
HSECTOR_SIZE *
Hive->
Cluster);
00826
00827
if ( (rc ==
FALSE) ||
00828 (buffer->Signature !=
HBASE_BLOCK_SIGNATURE) ||
00829 (buffer->Type !=
HFILE_TYPE_LOG) ||
00830 (buffer->Sequence1 != buffer->Sequence2) ||
00831 (
HvpHeaderCheckSum(buffer) != buffer->CheckSum) ||
00832 (TimeStamp->LowPart != buffer->TimeStamp.LowPart) ||
00833 (TimeStamp->HighPart != buffer->TimeStamp.HighPart)) {
00834
00835
00836
00837 (
Hive->
Free)(buffer,
sizeof(
HBASE_BLOCK));
00838
return Fail;
00839 }
00840
00841 *BaseBlock = buffer;
00842
return HiveSuccess;
00843 }
00844
00845
00846
RESULT
00847 HvpRecoverData(
00848
PHHIVE Hive,
00849 BOOLEAN ReadOnly,
00850 PHCELL_INDEX TailDisplay OPTIONAL
00851 )
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
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 }
01281