00175 :
00176
00177 Initialize a hive.
00178
00179 Core HHive fields are always inited.
00180
00181
File calls WILL be
made BEFORE
this call returns.
00182
00183 Caller
is expected to create/open files and store
file handles
00184 in a way that can be derived from
the hive pointer.
00185
00186 Three kinds of initialization can be done, selected by OperationType:
00187
00188
HINIT_CREATE
00189
00190
Create a
new hive from scratch. Will have 0 storage.
00191 [Used to
do things like create HARDWARE hive and
for parts
00192 of SaveKey and RestoreKey]
00193
00194
00195
HINIT_MEMORY_INPLACE
00196
00197 Build a hive
control structure which allows read
only
00198 access to a contiguous in-memory image of a hive.
00199 No part of
the image will be copied, but a map will
00200 be
made.
00201 [Used by osloader.]
00202
00203
00204
HINIT_FLAT
00205
00206 Support very limited (read-only, no checking code) operation
00207 against a hive image.
00208
00209
00210
HINIT_MEMORY
00211
00212
Create a
new hive,
using a hive image already in memory,
00213 at address supplied by pointer HiveData. The data will
00214 be copied. Caller
is expected to free HiveData.
00215 [Used
for SYSTEM hive]
00216
00217
00218
HINIT_FILE
00219
00220
Create a hive, reading its data from a
file. Recovery processing
00221 via log
file will be done
if a log
is available. If a log
00222
is recovered, flush and clear operation will proceed.
00223
00224
00225 NOTE: The HHive
is not a completely opaque structure, because
it
00226
is really
only used by a limited set of code. Do not assume
00227 that
only this routine sets all of these values.
00228
00229
00230 Arguments:
00231
00232
Hive - supplies a pointer to hive
control structure to be initialized
00233 to describe
this hive.
00234
00235 OperationType - specifies whether to create a
new hive from scratch,
00236 from a memory image, or by reading a
file from disk.
00237
00238 HiveFlags -
HIVE_VOLATILE - Entire hive
is to be
volatile, regardless
00239 of
the types of cells allocated
00240 HIVE_NO_LAZY_FLUSH - Data in
this hive
is never written
00241 to disk except by an
explicit FlushKey
00242
00243 FileType - HFILE_TYPE_*,
HFILE_TYPE_LOG or
HFILE_TYPE_ALTERNATE set
00244 up
for logging or alternate support respectively.
00245
00246 HiveData -
if present, supplies a pointer to an in memory image of
00247 from which to init
the hive. Only useful when OperationType
00248
is set to
HINIT_MEMORY.
00249
00250 AllocateRoutine - supplies a pointer to routine called to allocate
00251 memory. WILL be called before
this routine returns.
00252
00253 FreeRoutine - supplies a pointer to routine called to free memory.
00254 CAN be called before
this routine returns.
00255
00256 FileSetSizeRoutine - supplies a pointer to a routine used to set
the
00257 size of a
file. CAN be called before
this
00258 routine returns.
00259
00260 FileWriteRoutine - supplies a pointer to routine called to write memory
00261 to a
file.
00262
00263 FileReadRoutine - supplies a pointer to routine called to read from
00264 a
file into memory. CAN be called before
this
00265 routine returns.
00266
00267 FileFlushRoutine - supplies a pointer to routine called to flush a
file.
00268
00269 Cluster - clustering factor in
HSECTOR_SIZE units. (i.e.
Size of
00270 physical sector in media /
HSECTOR_SIZE. 1
for 512 byte
00271 physical sectors (or smaller), 2
for 1024, 4
for 2048, etc.
00272 (Numbers greater than 8 won'
t work.)
00273
00274
FileName - some
path like
"...\system32\config\system", last
00275 32 or so characters will be copied into baseblock
00276 (and thus to disk) as a debugging aid. May be null.
00277
00278
00279 Return Value:
00280
00281
NTSTATUS code.
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 }