Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

cmchek.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1991 Microsoft Corporation 00004 00005 Module Name: 00006 00007 cmchek.c 00008 00009 Abstract: 00010 00011 This module implements consistency checking for the registry. 00012 This module can be linked standalone, cmchek2.c cannot. 00013 00014 Author: 00015 00016 Bryan M. Willman (bryanwi) 27-Jan-92 00017 00018 Environment: 00019 00020 00021 Revision History: 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 // Global data used to support checkout 00033 // 00034 extern ULONG CmpUsedStorage; 00035 00036 extern PCMHIVE CmpMasterHive; 00037 00038 // 00039 // Private prototypes 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 // debug structures 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 // globals private to check code 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 Routine Description: 00115 00116 Check consistency of the registry within a given hive. Start from 00117 root, and check that: 00118 . Each child key points back to its parent. 00119 . All allocated cells are refered to exactly once 00120 (requires looking inside the hive structure...) 00121 [This also detects space leaks.] 00122 . All allocated cells are reachable from the root. 00123 00124 NOTE: Exactly 1 ref rule may change with security. 00125 00126 Arguments: 00127 00128 CmHive - supplies a pointer to the CM hive control structure for the 00129 hive of interest. 00130 00131 Clean - if TRUE, references to volatile cells will be zapped 00132 (done at startup only to avoid groveling hives twice.) 00133 if FALSE, nothing will be changed. 00134 00135 Return Value: 00136 00137 0 if Hive is OK. Error return indicator if not. 00138 00139 RANGE: 3000 - 3999 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 // check the underlying hive and get storage use 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 // Call recursive helper to check out the values and subkeys 00170 // 00171 CmpCheckHive = (PHHIVE)CmHive; 00172 CmpCheckClean = Clean; 00173 rc = CmpCheckRegistry2(Hive->BaseBlock->RootCell, HCELL_NIL); 00174 00175 // 00176 // Validate all the security descriptors in the hive 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 // Check allocated storage against used storage 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 // Print a bit of a summary (make sure this data avail in all error cases) 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 Routine Description: 00217 00218 Check consistency of the registry, from a particular cell on down. 00219 00220 . Check that the cell's value list, child key list, class, 00221 security are OK. 00222 . Check that each value entry IN the list is OK. 00223 . Apply self to each child key list. 00224 00225 Globals: 00226 00227 CmpCheckHive - hive we're working on 00228 00229 CmpCheckClean - flag TRUE -> clean off volatiles, FALSE -> don't 00230 00231 Arguments: 00232 00233 Cell - HCELL_INDEX of subkey to work on. 00234 00235 ParentCell - expected value of parent cell for Cell, unless 00236 HCELL_NIL, in which case ignore. 00237 00238 Return Value: 00239 00240 0 if Hive is OK. Error return indicator if not. 00241 00242 RANGE: 4000 - 4999 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 // A jump to NewKey amounts to a virtual call to check the 00258 // next child cell. (a descent into the tree) 00259 // 00260 // Cell, ParentCell, Index, and globals are defined 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 // save Index and check out children 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 // "recurse" onto child 00284 // 00285 ParentCell = Cell; 00286 Cell = SubKey; 00287 goto NewKey; 00288 00289 ResumeKey:; // A jump here is a virtual return 00290 // Cell, ParentCell and Index 00291 // must be defined 00292 } 00293 00294 // 00295 // since we're here, we've checked out all the children 00296 // of the current cell. 00297 // 00298 if (Cell == StartCell) { 00299 00300 // 00301 // we are done 00302 // 00303 return 0; 00304 } 00305 00306 // 00307 // "return" to "parent instance" 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 Routine Description: 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 // Check key itself 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 // Check simple non-empty cases 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 // Else CmpValidateHiveSecurityDescriptors must do computation 00466 // 00467 } 00468 00469 // 00470 // Check value list case 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 // Check subkey list case 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 // Prove that the index is OK 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 // force volatiles to be empty, if this is a load operation 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 Routine Description: 00596 00597 Check consistency of a value list. 00598 . Each element allocated? 00599 . Each element have valid signature? 00600 . Data properly allocated? 00601 00602 Arguments: 00603 00604 Hive - containing Hive. 00605 00606 List - pointer to an array of HCELL_INDEX entries. 00607 00608 Count - number of entries in list. 00609 00610 Return Value: 00611 00612 0 if Hive is OK. Error return indicator if not. 00613 00614 RANGE: 5000 - 5999 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; // NOT HCELL_NIL 00632 CmpCheckValueListDebug.CellPoint = NULL; 00633 00634 for (i = 0; i < Count; i++) { 00635 00636 // 00637 // Check out value entry's refs. 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 // Check out the value entry itself 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 // Check out value entry's data 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 }

Generated on Sat May 15 19:39:26 2004 for test by doxygen 1.3.7