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 #define REG_MAX_PLAUSIBLE_KEY_SIZE \
00028
((FIELD_OFFSET(CM_KEY_NODE, Name)) + \
00029
(sizeof(WCHAR) * MAX_KEY_NAME_LENGTH) + 16)
00030
00031
00032
00033
00034 extern ULONG
CmpUsedStorage;
00035
00036 extern PCMHIVE CmpMasterHive;
00037
00038
00039
00040
00041
00042 ULONG
00043
CmpCheckRegistry2(
00044 HCELL_INDEX Cell,
00045 HCELL_INDEX ParentCell
00046 );
00047
00048 ULONG
00049
CmpCheckKey(
00050 HCELL_INDEX Cell,
00051 HCELL_INDEX ParentCell
00052 );
00053
00054 ULONG
00055
CmpCheckValueList(
00056
PHHIVE Hive,
00057
PCELL_DATA List,
00058 ULONG Count
00059 );
00060
00061
#ifdef ALLOC_PRAGMA
00062
#pragma alloc_text(PAGE,CmCheckRegistry)
00063
#pragma alloc_text(PAGE,CmpCheckRegistry2)
00064
#pragma alloc_text(PAGE,CmpCheckKey)
00065
#pragma alloc_text(PAGE,CmpCheckValueList)
00066
#endif
00067
00068
00069
00070
00071
00072
extern struct {
00073
PHHIVE Hive;
00074 ULONG
Status;
00075 }
CmCheckRegistryDebug;
00076
00077
extern struct {
00078
PHHIVE Hive;
00079 ULONG
Status;
00080 }
CmpCheckRegistry2Debug;
00081
00082
extern struct {
00083
PHHIVE Hive;
00084 ULONG
Status;
00085
HCELL_INDEX Cell;
00086
PCELL_DATA CellPoint;
00087 PVOID
RootPoint;
00088 ULONG
Index;
00089 }
CmpCheckKeyDebug;
00090
00091
extern struct {
00092 PHHIVE Hive;
00093 ULONG
Status;
00094 PCELL_DATA List;
00095 ULONG
Index;
00096 HCELL_INDEX Cell;
00097 PCELL_DATA CellPoint;
00098 }
CmpCheckValueListDebug;
00099
00100
00101
00102
00103 extern PHHIVE CmpCheckHive;
00104 extern BOOLEAN
CmpCheckClean;
00105
00106
00107 ULONG
00108 CmCheckRegistry(
00109
PCMHIVE CmHive,
00110 BOOLEAN Clean
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
PHHIVE Hive;
00144 ULONG rc = 0;
00145 ULONG Storage;
00146
00147
if (CmHive ==
CmpMasterHive) {
00148
return(0);
00149 }
00150
00151
CmpUsedStorage = 0;
00152
00153
CmCheckRegistryDebug.Hive = (
PHHIVE)CmHive;
00154
CmCheckRegistryDebug.Status = 0;
00155
00156
00157
00158
00159
00160
Hive = &CmHive->
Hive;
00161
00162 rc =
HvCheckHive(
Hive, &Storage);
00163
if (rc != 0) {
00164
CmCheckRegistryDebug.Status = rc;
00165
return rc;
00166 }
00167
00168
00169
00170
00171
CmpCheckHive = (
PHHIVE)CmHive;
00172
CmpCheckClean = Clean;
00173 rc =
CmpCheckRegistry2(
Hive->
BaseBlock->
RootCell,
HCELL_NIL);
00174
00175
00176
00177
00178
if (!
CmpValidateHiveSecurityDescriptors(
Hive)) {
00179 KdPrint((
"CmCheckRegistry:"));
00180 KdPrint((
" CmpValidateHiveSecurityDescriptors failed\n"));
00181 rc = 3040;
00182
CmCheckRegistryDebug.Status = rc;
00183 }
00184
00185
#if 0
00186
00187
00188
00189
if (
CmpUsedStorage != Storage) {
00190 KdPrint((
"CmCheckRegistry:"));
00191 KdPrint((
" Storage Used:%08lx Allocated:%08lx\n",
UsedStorage, Storage));
00192 rc = 3042;
00193
CmCheckRegistryDebug.Status = rc;
00194 }
00195
#endif
00196
00197
00198
00199
00200
if (rc > 0) {
00201 KdPrint((
"CmCheckRegistry Failed (%d): CmHive:%08lx\n", rc, CmHive));
00202 KdPrint((
" Hive:%08lx Root:%08lx\n",
Hive,
Hive->
BaseBlock->
RootCell));
00203 }
00204
00205
return rc;
00206 }
00207
00208
00209 ULONG
00210 CmpCheckRegistry2(
00211 HCELL_INDEX Cell,
00212 HCELL_INDEX ParentCell
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 ULONG
Index = 0;
00247
HCELL_INDEX StartCell =
Cell;
00248
HCELL_INDEX SubKey;
00249 ULONG rc = 0;
00250
PCELL_DATA pcell;
00251
00252
00253
CmpCheckRegistry2Debug.Hive =
CmpCheckHive;
00254
CmpCheckRegistry2Debug.Status = 0;
00255
00256
00257
00258
00259
00260
00261
00262 NewKey:
00263 rc =
CmpCheckKey(
Cell, ParentCell);
00264
if (rc != 0) {
00265 KdPrint((
"\tChild is list entry #%08lx\n",
Index));
00266
CmpCheckRegistry2Debug.Status = rc;
00267
return rc;
00268 }
00269
00270
00271
00272
00273 pcell =
HvGetCell(
CmpCheckHive,
Cell);
00274 pcell->
u.
KeyNode.
WorkVar =
Index;
00275
00276
for (
Index = 0;
Index<pcell->
u.
KeyNode.
SubKeyCounts[
Stable];
Index++) {
00277
00278 SubKey =
CmpFindSubKeyByNumber(
CmpCheckHive,
00279 (
PCM_KEY_NODE)
HvGetCell(
CmpCheckHive,
Cell),
00280
Index);
00281
00282
00283
00284
00285 ParentCell =
Cell;
00286
Cell = SubKey;
00287
goto NewKey;
00288
00289 ResumeKey:;
00290
00291
00292 }
00293
00294
00295
00296
00297
00298
if (
Cell == StartCell) {
00299
00300
00301
00302
00303
return 0;
00304 }
00305
00306
00307
00308
00309 pcell =
HvGetCell(
CmpCheckHive,
Cell);
00310
Index = pcell->
u.
KeyNode.
WorkVar;
00311
00312
Cell = ParentCell;
00313
00314 pcell =
HvGetCell(
CmpCheckHive,
Cell);
00315 ParentCell = pcell->
u.
KeyNode.
Parent;
00316
00317
goto ResumeKey;
00318 }
00319
00320
00321
00322 ULONG
00323 CmpCheckKey(
00324 HCELL_INDEX Cell,
00325 HCELL_INDEX ParentCell
00326 )
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
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 }
00585
00586
00587 ULONG
00588 CmpCheckValueList(
00589
PHHIVE Hive,
00590
PCELL_DATA List,
00591 ULONG Count
00592 )
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617 {
00618 ULONG i;
00619
HCELL_INDEX Cell;
00620
PCELL_DATA pcell;
00621 ULONG size;
00622 ULONG usedlen;
00623 ULONG DataLength;
00624
HCELL_INDEX Data;
00625 ULONG rc = 0;
00626
00627
CmpCheckValueListDebug.Hive =
Hive;
00628
CmpCheckValueListDebug.Status = 0;
00629
CmpCheckValueListDebug.List =
List;
00630
CmpCheckValueListDebug.Index = (ULONG)-1;
00631
CmpCheckValueListDebug.Cell = 0;
00632
CmpCheckValueListDebug.CellPoint =
NULL;
00633
00634
for (i = 0; i <
Count; i++) {
00635
00636
00637
00638
00639
Cell =
List->
u.
KeyList[i];
00640
if (
Cell ==
HCELL_NIL) {
00641 KdPrint((
"CmpCheckValueList: List:%08lx i:%08lx\n",
List, i));
00642 KdPrint((
"\tEntry is null\n"));
00643 rc = 5010;
00644
CmpCheckValueListDebug.Status = rc;
00645
CmpCheckValueListDebug.Index = i;
00646
CmpCheckValueListDebug.Cell =
Cell;
00647
return rc;
00648 }
00649
if (
HvIsCellAllocated(
Hive,
Cell) ==
FALSE) {
00650 KdPrint((
"CmpCheckValueList: List:%08lx i:%08lx\n",
List, i));
00651 KdPrint((
"\tEntry is not allocated\n"));
00652 rc = 5020;
00653
CmpCheckValueListDebug.Status = rc;
00654
CmpCheckValueListDebug.Index = i;
00655
CmpCheckValueListDebug.Cell =
Cell;
00656
return rc;
00657 }
else {
00658
SetUsed(
Hive,
Cell);
00659 }
00660
00661
00662
00663
00664 pcell =
HvGetCell(
Hive,
Cell);
00665 size =
HvGetCellSize(
Hive, pcell);
00666
if (pcell->
u.
KeyValue.
Signature !=
CM_KEY_VALUE_SIGNATURE) {
00667 KdPrint((
"CmpCheckValueList: List:%08lx i:%08lx\n",
List, i));
00668 KdPrint((
"\tCell:%08lx - invalid value signature\n",
Cell));
00669 rc = 5030;
00670
CmpCheckValueListDebug.Status = rc;
00671
CmpCheckValueListDebug.Index = i;
00672
CmpCheckValueListDebug.Cell =
Cell;
00673
CmpCheckValueListDebug.CellPoint = pcell;
00674
return rc;
00675 }
00676 usedlen = FIELD_OFFSET(
CM_KEY_VALUE,
Name) + pcell->
u.
KeyValue.
NameLength;
00677
if (usedlen > size) {
00678 KdPrint((
"CmpCheckValueList: List:%08lx i:%08lx\n",
List, i));
00679 KdPrint((
"\tCell:%08lx - value bigger than containing cell\n",
Cell));
00680 rc = 5040;
00681
CmpCheckValueListDebug.Status = rc;
00682
CmpCheckValueListDebug.Index = i;
00683
CmpCheckValueListDebug.Cell =
Cell;
00684
CmpCheckValueListDebug.CellPoint = pcell;
00685
return rc;
00686 }
00687
00688
00689
00690
00691 DataLength = pcell->
u.
KeyValue.
DataLength;
00692
if (DataLength <
CM_KEY_VALUE_SPECIAL_SIZE) {
00693 Data = pcell->
u.
KeyValue.
Data;
00694
if ((DataLength == 0) && (Data !=
HCELL_NIL)) {
00695 KdPrint((
"CmpCheckValueList: List:%08lx i:%08lx\n",
List, i));
00696 KdPrint((
"\tCell:%08lx Data:%08lx - data not null\n",
Cell, Data));
00697 rc = 5050;
00698
CmpCheckValueListDebug.Status = rc;
00699
CmpCheckValueListDebug.Index = i;
00700
CmpCheckValueListDebug.Cell =
Cell;
00701
CmpCheckValueListDebug.CellPoint = pcell;
00702
return rc;
00703 }
00704
if (DataLength > 0) {
00705
if (
HvIsCellAllocated(
Hive, Data) ==
FALSE) {
00706 KdPrint((
"CmpCheckValueList: List:%08lx i:%08lx\n",
List, i));
00707 KdPrint((
"\tCell:%08lx Data:%08lx - unallocated\n",
Cell, Data));
00708 rc = 5060;
00709
CmpCheckValueListDebug.Status = rc;
00710
CmpCheckValueListDebug.Index = i;
00711
CmpCheckValueListDebug.Cell =
Cell;
00712
CmpCheckValueListDebug.CellPoint = pcell;
00713
return rc;
00714 }
else {
00715
SetUsed(
Hive, Data);
00716 }
00717 }
00718 }
00719 }
00720
return rc;
00721 }