00329 :
00330
00331 Check consistency of
the registry,
for a particular cell
00332
00333 . Check that
the cell's value list, child key list,
class,
00334 security are OK.
00335 . Check that each value entry IN
the list
is OK.
00336
00337 Globals:
00338
00339
CmpCheckHive - hive we're working on
00340
00341
CmpCheckClean - flag
TRUE -> clean off volatiles,
FALSE -> don'
t
00342
00343 Arguments:
00344
00345
Cell -
HCELL_INDEX of subkey to work on.
00346
00347 ParentCell - expected value of parent cell
for Cell, unless
00348
HCELL_NIL, in which
case ignore.
00349
00350 Return Value:
00351
00352 0
if Hive is OK.
Error return indicator
if not.
00353
00354 RANGE: 4000 - 4999
00355
00356 --*/
00357 {
00358
PCELL_DATA pcell;
00359 ULONG size;
00360 ULONG usedlen;
00361 ULONG ClassLength;
00362
HCELL_INDEX Class;
00363 ULONG ValueCount;
00364
HCELL_INDEX ValueList;
00365
HCELL_INDEX Security;
00366 ULONG rc = 0;
00367 ULONG nrc = 0;
00368 ULONG i;
00369
PCM_KEY_INDEX Root;
00370
PCM_KEY_INDEX Leaf;
00371 ULONG SubCount;
00372
00373
CmpCheckKeyDebug.Hive =
CmpCheckHive;
00374
CmpCheckKeyDebug.Status = 0;
00375
CmpCheckKeyDebug.Cell =
Cell;
00376
CmpCheckKeyDebug.CellPoint =
NULL;
00377
CmpCheckKeyDebug.RootPoint =
NULL;
00378
CmpCheckKeyDebug.Index = (ULONG)-1;
00379
00380
00381
00382
00383
if (!
HvIsCellAllocated(CmpCheckHive, Cell)) {
00384 KdPrint((
"CmpCheckKey: CmpCheckHive:%08lx Cell:%08lx\n", CmpCheckHive, Cell));
00385 KdPrint((
"\tNot allocated\n"));
00386 rc = 4010;
00387
CmpCheckKeyDebug.Status = rc;
00388
return rc;
00389 }
00390 pcell =
HvGetCell(CmpCheckHive, Cell);
00391
SetUsed(CmpCheckHive, Cell);
00392
00393
CmpCheckKeyDebug.CellPoint = pcell;
00394
00395 size =
HvGetCellSize(CmpCheckHive, pcell);
00396
if (size >
REG_MAX_PLAUSIBLE_KEY_SIZE) {
00397 KdPrint((
"CmpCheckKey: CmpCheckHive:%08lx Cell:%08lx\n", CmpCheckHive, Cell));
00398 KdPrint((
"\tImplausible size %lx\n", size));
00399 rc = 4020;
00400
CmpCheckKeyDebug.Status = rc;
00401
return rc;
00402 }
00403 usedlen = FIELD_OFFSET(
CM_KEY_NODE, Name) + pcell->
u.
KeyNode.
NameLength;
00404
if (usedlen > size) {
00405 KdPrint((
"CmpCheckKey: CmpCheckHive:%08lx Cell:%08lx\n", CmpCheckHive, Cell));
00406 KdPrint((
"\tKey is bigger than containing cell.\n"));
00407 rc = 4030;
00408
CmpCheckKeyDebug.Status = rc;
00409
return rc;
00410 }
00411
if (pcell->
u.
KeyNode.
Signature !=
CM_KEY_NODE_SIGNATURE) {
00412 KdPrint((
"CmpCheckKey: CmpCheckHive:%08lx Cell:%08lx\n", CmpCheckHive, Cell));
00413 KdPrint((
"\tNo key signature\n"));
00414 rc = 4040;
00415
CmpCheckKeyDebug.Status = rc;
00416
return rc;
00417 }
00418
if (ParentCell !=
HCELL_NIL) {
00419
if (pcell->
u.
KeyNode.
Parent != ParentCell) {
00420 KdPrint((
"CmpCheckKey: CmpCheckHive:%08lx Cell:%08lx\n", CmpCheckHive, Cell));
00421 KdPrint((
"\tWrong parent value.\n"));
00422 rc = 4045;
00423
CmpCheckKeyDebug.Status = rc;
00424
return rc;
00425 }
00426 }
00427 ClassLength = pcell->
u.
KeyNode.
ClassLength;
00428 Class = pcell->
u.
KeyNode.
Class;
00429 ValueCount = pcell->
u.
KeyNode.
ValueList.
Count;
00430 ValueList = pcell->
u.
KeyNode.
ValueList.
List;
00431 Security = pcell->
u.
KeyNode.
Security;
00432
00433
00434
00435
00436
if (ClassLength > 0) {
00437
if( Class ==
HCELL_NIL ) {
00438 pcell->
u.
KeyNode.
ClassLength = 0;
00439
HvMarkCellDirty(CmpCheckHive, Cell);
00440 KdPrint((
"CmpCheckKey: CmpCheckHive:%08lx Cell:%08lx has ClassLength = %lu and Class == HCELL_NIL\n", CmpCheckHive, Cell,ClassLength));
00441 }
else {
00442
if (
HvIsCellAllocated(CmpCheckHive, Class) ==
FALSE) {
00443 KdPrint((
"CmpCheckKey: CmpCheckHive:%08lx Cell:%08lx\n", CmpCheckHive, Cell));
00444 KdPrint((
"\tClass:%08lx - unallocated class\n", Class));
00445 rc = 4080;
00446
CmpCheckKeyDebug.Status = rc;
00447
return rc;
00448 }
else {
00449
SetUsed(CmpCheckHive, Class);
00450 }
00451 }
00452 }
00453
00454
if (Security !=
HCELL_NIL) {
00455
if (
HvIsCellAllocated(CmpCheckHive, Security) ==
FALSE) {
00456 KdPrint((
"CmpCheckKey: CmpCheckHive:%08lx Cell:%08lx\n", CmpCheckHive, Cell));
00457 KdPrint((
"\tSecurity:%08lx - unallocated security\n", Security));
00458 rc = 4090;
00459
CmpCheckKeyDebug.Status = rc;
00460
return rc;
00461 }
else if (
HvGetCellType(Security) ==
Volatile) {
00462
SetUsed(CmpCheckHive, Security);
00463 }
00464
00465
00466
00467 }
00468
00469
00470
00471
00472
if (ValueCount > 0) {
00473
if (
HvIsCellAllocated(CmpCheckHive, ValueList) ==
FALSE) {
00474 KdPrint((
"CmpCheckKey: CmpCheckHive:%08lx Cell:%08lx\n", CmpCheckHive, Cell));
00475 KdPrint((
"\tValueList:%08lx - unallocated valuelist\n", ValueList));
00476 rc = 4100;
00477
CmpCheckKeyDebug.Status = rc;
00478
return rc;
00479 }
else {
00480
SetUsed(CmpCheckHive, ValueList);
00481 pcell =
HvGetCell(CmpCheckHive, ValueList);
00482 nrc =
CmpCheckValueList(CmpCheckHive, pcell, ValueCount);
00483
if (nrc != 0) {
00484 KdPrint((
"List was for CmpCheckHive:%08lx Cell:%08lx\n", CmpCheckHive, Cell));
00485 rc = nrc;
00486
CmpCheckKeyDebug.CellPoint = pcell;
00487
CmpCheckKeyDebug.Status = rc;
00488
return rc;
00489 }
00490 }
00491 }
00492
00493
00494
00495
00496
00497
00498 pcell =
HvGetCell(CmpCheckHive, Cell);
00499
CmpCheckKeyDebug.CellPoint = pcell;
00500
if ((
HvGetCellType(Cell) ==
Volatile) &&
00501 (pcell->
u.
KeyNode.
SubKeyCounts[
Stable] != 0))
00502 {
00503 KdPrint((
"CmpCheckKey: CmpCheckHive:%08lx Cell:%08lx\n", CmpCheckHive, Cell));
00504 KdPrint((
"\tVolatile Cell has Stable children\n"));
00505 rc = 4108;
00506
CmpCheckKeyDebug.Status = rc;
00507
return rc;
00508 }
else if (pcell->
u.
KeyNode.
SubKeyCounts[
Stable] > 0) {
00509
if (!
HvIsCellAllocated(CmpCheckHive, pcell->
u.
KeyNode.
SubKeyLists[Stable])) {
00510 KdPrint((
"CmpCheckKey: CmpCheckHive:%08lx Cell:%08lx\n", CmpCheckHive, Cell));
00511 KdPrint((
"\tStableKeyList:%08lx - unallocated\n", pcell->
u.
KeyNode.
SubKeyLists[Stable]));
00512 rc = 4110;
00513
CmpCheckKeyDebug.Status = rc;
00514
return rc;
00515 }
else {
00516
SetUsed(CmpCheckHive, pcell->
u.
KeyNode.
SubKeyLists[Stable]);
00517
00518
00519
00520
00521 Root = (
PCM_KEY_INDEX)
HvGetCell(
00522 CmpCheckHive,
00523 pcell->
u.
KeyNode.
SubKeyLists[Stable]
00524 );
00525
CmpCheckKeyDebug.RootPoint = Root;
00526
if ((Root->
Signature ==
CM_KEY_INDEX_LEAF) ||
00527 (Root->
Signature ==
CM_KEY_FAST_LEAF)) {
00528
if ((ULONG)Root->
Count != pcell->
u.
KeyNode.
SubKeyCounts[
Stable]) {
00529 KdPrint((
"CmpCheckKey: CmpCheckHive:%08lx Cell:%08lx\n", CmpCheckHive, Cell));
00530 KdPrint((
"\tBad Index count @%08lx\n", Root));
00531 rc = 4120;
00532
CmpCheckKeyDebug.Status = rc;
00533
return rc;
00534 }
00535 }
else if (Root->
Signature ==
CM_KEY_INDEX_ROOT) {
00536 SubCount = 0;
00537
for (i = 0; i < Root->
Count; i++) {
00538
CmpCheckKeyDebug.Index = i;
00539
if (!
HvIsCellAllocated(CmpCheckHive, Root->
List[i])) {
00540 KdPrint((
"CmpCheckKey: Hive:%08lx Cell:%08lx\n", CmpCheckHive, Cell));
00541 KdPrint((
"\tBad Leaf Cell %08lx Root@%08lx\n", Root->
List[i], Root));
00542 rc = 4130;
00543
CmpCheckKeyDebug.Status = rc;
00544
return rc;
00545 }
00546 Leaf = (
PCM_KEY_INDEX)
HvGetCell(CmpCheckHive,
00547 Root->
List[i]);
00548
if ((Leaf->
Signature !=
CM_KEY_INDEX_LEAF) &&
00549 (Leaf->
Signature !=
CM_KEY_FAST_LEAF)) {
00550 KdPrint((
"CmpCheckKey: CmpCheckHive:%08lx Cell:%08lx\n", CmpCheckHive, Cell));
00551 KdPrint((
"\tBad Leaf Index @%08lx Root@%08lx\n", Leaf, Root));
00552 rc = 4140;
00553
CmpCheckKeyDebug.Status = rc;
00554
return rc;
00555 }
00556
SetUsed(CmpCheckHive, Root->
List[i]);
00557 SubCount += Leaf->
Count;
00558 }
00559
if (pcell->
u.
KeyNode.
SubKeyCounts[
Stable] != SubCount) {
00560 KdPrint((
"CmpCheckKey: CmpCheckHive:%08lx Cell:%08lx\n", CmpCheckHive, Cell));
00561 KdPrint((
"\tBad count in index, SubCount=%08lx\n", SubCount));
00562 rc = 4150;
00563
CmpCheckKeyDebug.Status = rc;
00564
return rc;
00565 }
00566 }
else {
00567 KdPrint((
"CmpCheckKey: CmpCheckHive:%08lx Cell:%08lx\n", CmpCheckHive, Cell));
00568 KdPrint((
"\tBad Root index signature @%08lx\n", Root));
00569 rc = 4120;
00570
CmpCheckKeyDebug.Status = rc;
00571
return rc;
00572 }
00573 }
00574 }
00575
00576
00577
00578
if (
CmpCheckClean ==
TRUE) {
00579 pcell->
u.
KeyNode.
SubKeyCounts[
Volatile] = 0;
00580 pcell->
u.
KeyNode.
SubKeyLists[
Volatile] =
HCELL_NIL;
00581 }
00582
00583
return rc;
00584 }