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
VOID
00028
HvpFillFileName(
00029
PHBASE_BLOCK BaseBlock,
00030 PUNICODE_STRING FileName
00031 );
00032
00033
#ifdef ALLOC_PRAGMA
00034
#pragma alloc_text(PAGE,HvInitializeHive)
00035
#pragma alloc_text(PAGE,HvpFillFileName)
00036
#pragma alloc_text(PAGE,HvpFreeAllocatedBins)
00037
#endif
00038
00039
00040
00041
#if 0
00042
00043
VOID
00044
HvpDumpFreeDisplay(
PHHIVE Hive
00045 )
00046 {
00047 ULONG
Index;
00048 ULONG Mask;
00049
HCELL_INDEX cell;
00050
PHCELL pcell;
00051
00052 KdPrint((
"\nHvpDumpFreeDisplay:\n"));
00053
00054
for(
Index =0;
Index<
HHIVE_FREE_DISPLAY_SIZE;
Index++){
00055 Mask = 1;
00056 Mask <<=
Index;
00057 KdPrint((
"\nFreeDisplay[%lu]\n",Index));
00058
if(
Hive->Storage[
Stable].FreeSummary & Mask) {
00059
00060
00061
00062
00063 cell =
Hive->Storage[
Stable].FreeDisplay[
Index];
00064
while (cell !=
HCELL_NIL) {
00065
00066 KdPrint((
"0x%08lx ",cell));
00067 pcell =
HvpGetHCell(Hive, cell);
00068
00069
if (
USE_OLD_CELL(Hive)) {
00070 cell = pcell->
u.OldCell.u.Next;
00071 }
else {
00072 cell = pcell->
u.NewCell.u.Next;
00073 }
00074 }
00075 }
00076 }
00077 }
00078
#else
00079
00080 #define HvpDumpFreeDisplay(Hive) //nothing
00081
00082
#endif
00083
00084
VOID
00085 HvpFreeAllocatedBins(
00086
PHHIVE Hive
00087 )
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 {
00106 ULONG Length;
00107
PHBIN Bin;
00108 ULONG MapSlots;
00109 ULONG Tables;
00110
PHMAP_ENTRY Me;
00111
PHMAP_TABLE Tab;
00112 ULONG i;
00113 ULONG j;
00114
00115
00116
00117
00118 Length =
Hive->Storage[
Stable].Length;
00119 MapSlots = Length /
HBLOCK_SIZE;
00120
if( MapSlots > 0 ) {
00121 Tables = (MapSlots-1) /
HTABLE_SLOTS;
00122 }
else {
00123 Tables = 0;
00124 }
00125
00126
if(
Hive->Storage[
Stable].Map ) {
00127
00128
00129
00130
for (i = 0; i <= Tables; i++) {
00131 Tab =
Hive->Storage[
Stable].Map->Directory[i];
00132
00133
ASSERT(Tab);
00134
00135
00136
00137
00138
for(j=0;j<
HTABLE_SLOTS;j++) {
00139 Me = &(Tab->
Table[j]);
00140
00141
00142
00143
if( Me->
BinAddress ) {
00144
if( Me->
BinAddress &
HMAP_NEWALLOC ) {
00145
Bin = (
PHBIN)(Me->
BinAddress &
HMAP_BASE);
00146 (
Hive->
Free)(
Bin,
Bin->
MemAlloc);
00147 }
00148
00149 Me->
BinAddress = 0;
00150 }
00151 }
00152 }
00153 }
00154
00155 }
00156
00157
NTSTATUS
00158 HvInitializeHive(
00159
PHHIVE Hive,
00160 ULONG OperationType,
00161 ULONG HiveFlags,
00162 ULONG FileType,
00163 PVOID HiveData OPTIONAL,
00164 PALLOCATE_ROUTINE AllocateRoutine,
00165 PFREE_ROUTINE FreeRoutine,
00166 PFILE_SET_SIZE_ROUTINE FileSetSizeRoutine,
00167 PFILE_WRITE_ROUTINE FileWriteRoutine,
00168 PFILE_READ_ROUTINE FileReadRoutine,
00169 PFILE_FLUSH_ROUTINE FileFlushRoutine,
00170 ULONG Cluster,
00171 PUNICODE_STRING FileName OPTIONAL
00172 )
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284 {
00285 BOOLEAN UseForIo;
00286
PHBASE_BLOCK BaseBlock =
NULL;
00287
NTSTATUS Status;
00288
NTSTATUS Status2;
00289 PVOID Image;
00290 ULONG i;
00291
PHBIN Pbin;
00292 ULONG Alignment;
00293
00294
00295
00296
00297
HCELL_INDEX TailDisplay[
HHIVE_FREE_DISPLAY_SIZE];
00298
00299
CMLOG(
CML_MAJOR,
CMS_INIT) {
00300 KdPrint((
"HvInitializeHive:\n"));
00301 KdPrint((
"\tHive=%08lx\n",
Hive));
00302 }
00303
00304
00305
00306
00307
if ( (! ARGUMENT_PRESENT(HiveData)) &&
00308 ((OperationType ==
HINIT_MEMORY) ||
00309 (OperationType ==
HINIT_FLAT) ||
00310 (OperationType ==
HINIT_MEMORY_INPLACE))
00311 )
00312 {
00313
return STATUS_INVALID_PARAMETER;
00314 }
00315
00316
if ( ! ((OperationType ==
HINIT_CREATE) ||
00317 (OperationType ==
HINIT_MEMORY) ||
00318 (OperationType ==
HINIT_MEMORY_INPLACE) ||
00319 (OperationType ==
HINIT_FLAT) ||
00320 (OperationType ==
HINIT_FILE))
00321 )
00322 {
00323
return STATUS_INVALID_PARAMETER;
00324 }
00325
00326
00327
00328
00329
00330
Hive->
Signature =
HHIVE_SIGNATURE;
00331
00332
Hive->
Allocate = AllocateRoutine;
00333
Hive->
Free = FreeRoutine;
00334
Hive->
FileSetSize = FileSetSizeRoutine;
00335
Hive->
FileWrite = FileWriteRoutine;
00336
Hive->
FileRead = FileReadRoutine;
00337
Hive->
FileFlush = FileFlushRoutine;
00338
00339
Hive->
Log = (BOOLEAN)((FileType ==
HFILE_TYPE_LOG) ?
TRUE :
FALSE);
00340
Hive->
Alternate = (BOOLEAN)((FileType ==
HFILE_TYPE_ALTERNATE) ?
TRUE :
FALSE);
00341
00342
if ((
Hive->
Log ||
Hive->
Alternate) && (HiveFlags &
HIVE_VOLATILE)) {
00343
return STATUS_INVALID_PARAMETER;
00344 }
00345
00346
Hive->
HiveFlags = HiveFlags;
00347
00348
if ((Cluster == 0) || (Cluster >
HSECTOR_COUNT)) {
00349
return STATUS_INVALID_PARAMETER;
00350 }
00351
Hive->
Cluster = Cluster;
00352
00353
Hive->
RefreshCount = 0;
00354
00355
Hive->
StorageTypeCount =
HTYPE_COUNT;
00356
00357
00358
Hive->Storage[
Volatile].Length = 0;
00359
Hive->Storage[
Volatile].Map =
NULL;
00360
Hive->Storage[
Volatile].SmallDir =
NULL;
00361
Hive->Storage[
Volatile].Guard = (ULONG)-1;
00362
Hive->Storage[
Volatile].FreeSummary = 0;
00363 InitializeListHead(&
Hive->Storage[
Volatile].FreeBins);
00364
for (i = 0; i <
HHIVE_FREE_DISPLAY_SIZE; i++) {
00365
Hive->Storage[
Volatile].FreeDisplay[i] =
HCELL_NIL;
00366 }
00367
00368
Hive->Storage[
Stable].Length = 0;
00369
Hive->Storage[
Stable].Map =
NULL;
00370
Hive->Storage[
Stable].SmallDir =
NULL;
00371
Hive->Storage[
Stable].Guard = (ULONG)-1;
00372
Hive->Storage[
Stable].FreeSummary = 0;
00373 InitializeListHead(&
Hive->Storage[
Stable].FreeBins);
00374
for (i = 0; i <
HHIVE_FREE_DISPLAY_SIZE; i++) {
00375
Hive->Storage[
Stable].FreeDisplay[i] =
HCELL_NIL;
00376 TailDisplay[i] =
HCELL_NIL;
00377 }
00378
00379
RtlInitializeBitMap(&(
Hive->
DirtyVector),
NULL, 0);
00380
Hive->
DirtyCount = 0;
00381
Hive->
DirtyAlloc = 0;
00382
Hive->
LogSize = 0;
00383
00384
Hive->
GetCellRoutine =
HvpGetCellPaged;
00385
Hive->
Flat =
FALSE;
00386
Hive->
ReadOnly =
FALSE;
00387 UseForIo = (BOOLEAN)!(
Hive->
HiveFlags &
HIVE_VOLATILE);
00388
00389
00390
00391
00392
if (OperationType ==
HINIT_CREATE) {
00393
00394 BaseBlock = (
PHBASE_BLOCK)((
Hive->
Allocate)(
sizeof(
HBASE_BLOCK), UseForIo));
00395
if (BaseBlock ==
NULL) {
00396
return STATUS_INSUFFICIENT_RESOURCES;
00397 }
00398
00399
00400
00401
00402 Alignment = Cluster *
HSECTOR_SIZE - 1;
00403
if (((ULONG_PTR)BaseBlock & Alignment) != 0) {
00404 (
Hive->
Free)(BaseBlock,
sizeof(
HBASE_BLOCK));
00405 BaseBlock = (
PHBASE_BLOCK)((
Hive->
Allocate)(
PAGE_SIZE,
TRUE));
00406
if (BaseBlock ==
NULL) {
00407
return STATUS_INSUFFICIENT_RESOURCES;
00408 }
00409
00410
00411
00412
00413
00414
CmpReleaseGlobalQuota(
PAGE_SIZE -
sizeof(
HBASE_BLOCK));
00415 }
00416
00417 BaseBlock->
Signature =
HBASE_BLOCK_SIGNATURE;
00418 BaseBlock->
Sequence1 = 1;
00419 BaseBlock->
Sequence2 = 1;
00420 BaseBlock->
TimeStamp.HighPart = 0;
00421 BaseBlock->
TimeStamp.LowPart = 0;
00422 BaseBlock->
Major =
HSYS_MAJOR;
00423 BaseBlock->
Minor =
HSYS_MINOR;
00424 BaseBlock->
Type =
HFILE_TYPE_PRIMARY;
00425 BaseBlock->
Format =
HBASE_FORMAT_MEMORY;
00426 BaseBlock->
RootCell =
HCELL_NIL;
00427 BaseBlock->
Length = 0;
00428 BaseBlock->
Cluster = Cluster;
00429 BaseBlock->
CheckSum = 0;
00430
HvpFillFileName(BaseBlock,
FileName);
00431
Hive->
BaseBlock = BaseBlock;
00432
Hive->
Version =
HSYS_MINOR;
00433
00434
return STATUS_SUCCESS;
00435 }
00436
00437
00438
00439
00440
if (OperationType ==
HINIT_FLAT) {
00441
Hive->
BaseBlock = (
PHBASE_BLOCK)HiveData;
00442
Hive->
Version =
Hive->
BaseBlock->
Minor;
00443
Hive->
Flat =
TRUE;
00444
Hive->
ReadOnly =
TRUE;
00445
Hive->
GetCellRoutine =
HvpGetCellFlat;
00446
Hive->Storage[
Stable].Length =
Hive->
BaseBlock->
Length;
00447
Hive->
StorageTypeCount = 1;
00448
return STATUS_SUCCESS;
00449 }
00450
00451
00452
00453
00454
if (OperationType ==
HINIT_MEMORY_INPLACE) {
00455 BaseBlock = (
PHBASE_BLOCK)HiveData;
00456
00457
if ( (BaseBlock->
Signature !=
HBASE_BLOCK_SIGNATURE) ||
00458 (BaseBlock->
Type !=
HFILE_TYPE_PRIMARY) ||
00459 (BaseBlock->
Major !=
HSYS_MAJOR) ||
00460 (BaseBlock->
Minor >
HSYS_MINOR) ||
00461 (BaseBlock->
Format !=
HBASE_FORMAT_MEMORY) ||
00462 (BaseBlock->
Sequence1 != BaseBlock->
Sequence2) ||
00463 (
HvpHeaderCheckSum(BaseBlock) !=
00464 (BaseBlock->
CheckSum))
00465 )
00466 {
00467
return STATUS_REGISTRY_CORRUPT;
00468 }
00469
00470
Hive->
BaseBlock = BaseBlock;
00471
Hive->
Version = BaseBlock->
Minor;
00472
Hive->
ReadOnly =
TRUE;
00473
Hive->
StorageTypeCount = 1;
00474
00475
if (FileType ==
HFILE_TYPE_ALTERNATE) {
00476
00477
00478
00479
00480
00481
00482
00483 BaseBlock->
Type=
HFILE_TYPE_ALTERNATE;
00484
00485
00486
00487
00488 BaseBlock->
CheckSum=
HvpHeaderCheckSum(BaseBlock);
00489 }
00490
00491
if ( !
NT_SUCCESS(
HvpBuildMap(
00492
Hive,
00493 (PUCHAR)HiveData +
HBLOCK_SIZE,
00494 TailDisplay
00495 )))
00496 {
00497
return STATUS_REGISTRY_CORRUPT;
00498 }
00499
00500
00501
HvpDumpFreeDisplay(
Hive);
00502
00503
return(STATUS_SUCCESS);
00504 }
00505
00506
00507
00508
00509
if (OperationType ==
HINIT_MEMORY) {
00510 BaseBlock = (
PHBASE_BLOCK)HiveData;
00511
00512
if ( (BaseBlock->
Signature !=
HBASE_BLOCK_SIGNATURE) ||
00513 ((BaseBlock->
Type !=
HFILE_TYPE_PRIMARY) &&
00514 (BaseBlock->
Type !=
HFILE_TYPE_ALTERNATE)) ||
00515 (BaseBlock->
Format !=
HBASE_FORMAT_MEMORY) ||
00516 (BaseBlock->
Major !=
HSYS_MAJOR) ||
00517 (BaseBlock->
Minor >
HSYS_MINOR) ||
00518 (
HvpHeaderCheckSum(BaseBlock) !=
00519 (BaseBlock->
CheckSum))
00520 )
00521 {
00522
return STATUS_REGISTRY_CORRUPT;
00523 }
00524
00525
Hive->
BaseBlock = (
PHBASE_BLOCK)((
Hive->
Allocate)(
sizeof(
HBASE_BLOCK), UseForIo));
00526
if (
Hive->
BaseBlock==
NULL) {
00527
return(STATUS_INSUFFICIENT_RESOURCES);
00528 }
00529
00530
00531
00532
00533 Alignment = Cluster *
HSECTOR_SIZE - 1;
00534
if (((ULONG_PTR)
Hive->
BaseBlock & Alignment) != 0) {
00535 (
Hive->
Free)(
Hive->
BaseBlock,
sizeof(
HBASE_BLOCK));
00536
Hive->
BaseBlock = (
PHBASE_BLOCK)((
Hive->
Allocate)(
PAGE_SIZE,
TRUE));
00537
if (
Hive->
BaseBlock ==
NULL) {
00538
return (STATUS_INSUFFICIENT_RESOURCES);
00539 }
00540 }
00541 RtlCopyMemory(
Hive->
BaseBlock, BaseBlock,
HSECTOR_SIZE);
00542
00543
Hive->
Version =
Hive->
BaseBlock->
Minor;
00544
00545
if ( !
NT_SUCCESS(
HvpBuildMapAndCopy(
Hive,
00546 (PUCHAR)HiveData +
HBLOCK_SIZE,
00547 TailDisplay))) {
00548
00549 (
Hive->
Free)(
Hive->
BaseBlock,
sizeof(
HBASE_BLOCK));
00550
Hive->
BaseBlock =
NULL;
00551
return STATUS_REGISTRY_CORRUPT;
00552 }
00553
00554
if (BaseBlock->
Type ==
HFILE_TYPE_ALTERNATE) {
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
RtlSetAllBits(&(
Hive->
DirtyVector));
00568
Hive->
DirtyCount=
Hive->
DirtyVector.SizeOfBitMap;
00569
00570 }
00571
HvpFillFileName(
Hive->
BaseBlock,
FileName);
00572
00573
00574
HvpDumpFreeDisplay(
Hive);
00575
00576
return(STATUS_SUCCESS);
00577 }
00578
00579
00580
00581
00582
if (OperationType ==
HINIT_FILE) {
00583
00584
CMLOG(
CML_BIN,
CMS_BIN_MAP) {
00585 KdPrint((
"HvInitializeHive(%wZ,HINIT_FILE) :\n",
FileName));
00586 }
00587
00588
00589
00590
Status =
HvLoadHive(
Hive, TailDisplay);
00591
if ((
Status != STATUS_SUCCESS) && (
Status != STATUS_REGISTRY_RECOVERED)) {
00592
return Status;
00593 }
00594
00595
CMLOG(
CML_BIN,
CMS_BIN_MAP) {
00596 KdPrint((
"\n"));
00597 }
00598
00599
if (
Status == STATUS_REGISTRY_RECOVERED) {
00600
00601
00602
00603
00604
00605
00606
00607
00608
if ( !
HvpDoWriteHive(
Hive,
HFILE_TYPE_PRIMARY)) {
00609
00610
00611
00612
00613
HvpFreeAllocatedBins(
Hive );
00614
00615
return STATUS_REGISTRY_IO_FAILED;
00616 }
00617
00618
00619
00620
00621
00622
00623
RtlClearAllBits(&(
Hive->
DirtyVector));
00624
Hive->
DirtyCount = 0;
00625 (
Hive->
FileSetSize)(
Hive,
HFILE_TYPE_LOG, 0);
00626
Hive->
LogSize = 0;
00627 }
00628
00629
00630
00631
00632
HvpFillFileName(
Hive->
BaseBlock,
FileName);
00633
00634
00635
HvpDumpFreeDisplay(
Hive);
00636
00637
return STATUS_SUCCESS;
00638 }
00639
00640
return STATUS_INVALID_PARAMETER;
00641 }
00642
00643
00644
VOID
00645 HvpFillFileName(
00646
PHBASE_BLOCK BaseBlock,
00647 PUNICODE_STRING FileName
00648 )
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668 {
00669 ULONG offset;
00670 ULONG length;
00671 PUCHAR sptr;
00672
00673
#if 0
00674
KdPrint((
"HvpFillFileName: %wZ\n",
FileName));
00675
#endif
00676
00677 RtlZeroMemory((PVOID)&(BaseBlock->
FileName[0]),
HBASE_NAME_ALLOC);
00678
00679
if (
FileName ==
NULL) {
00680
return;
00681 }
00682
00683
if (
FileName->Length <=
HBASE_NAME_ALLOC) {
00684 offset = 0;
00685 length =
FileName->Length;
00686 }
else {
00687 offset =
FileName->Length -
HBASE_NAME_ALLOC;
00688 length =
HBASE_NAME_ALLOC;
00689 }
00690
00691 sptr = (PUCHAR)&(
FileName->Buffer[0]);
00692 RtlMoveMemory(
00693 (PVOID)&(BaseBlock->
FileName[0]),
00694 (PVOID)&(sptr[offset]),
00695 length
00696 );
00697 }