ReactOS 0.4.15-dev-8145-ga541a46
cmheal.c File Reference
#include "cmlib.h"
#include <debug.h>
Include dependency graph for cmheal.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

static VOID CmpRemoveFastIndexKeyCell (_Inout_ PCM_KEY_FAST_INDEX FastIndex, _In_ ULONG Index, _In_ BOOLEAN UpdateCount)
 Removes a cell from a fast key index.
 
static VOID CmpRemoveIndexKeyCell (_Inout_ PCM_KEY_INDEX KeyIndex, _In_ ULONG Index)
 Removes a cell from a normal key index.
 
static VOID CmpRemoveValueFromValueList (_Inout_ PCM_KEY_NODE ValueListNode, _Inout_ PCELL_DATA ValueListData, _In_ ULONG Index)
 Removes a cell from a key value list node.
 
static BOOLEAN CmpRemoveSubkeyInRoot (_In_ PHHIVE Hive, _In_ PCM_KEY_INDEX RootIndex, _In_ HCELL_INDEX TargetKey)
 Removes the offending subkey from a root index.
 
static BOOLEAN CmpRemoveSubKeyInLeaf (_In_ PHHIVE Hive, _In_ PCM_KEY_NODE KeyNode, _In_ PCM_KEY_INDEX Leaf, _In_ HCELL_INDEX TargetKey)
 Removes the offending subkey from a leaf index.
 
BOOLEAN CMAPI CmIsSelfHealEnabled (_In_ BOOLEAN FixHive)
 Checks if self healing is permitted by the kernel and/or bootloader. Self healing is also triggered if such a request was prompted by the user to fix a broken hive. Such a request tipically comes from a registry repair tool such as the ReactOS Check Registry Utility.
 
BOOLEAN CMAPI CmpRepairParentKey (_Inout_ PHHIVE Hive, _In_ HCELL_INDEX TargetKey, _In_ HCELL_INDEX ParentKey, _In_ BOOLEAN FixHive)
 Repairs the parent key from damage by removing the offending subkey cell.
 
BOOLEAN CMAPI CmpRepairParentNode (_Inout_ PHHIVE Hive, _In_ HCELL_INDEX CurrentCell, _In_ HCELL_INDEX ParentCell, _Inout_ PCELL_DATA CellData, _In_ BOOLEAN FixHive)
 Repairs the parent of the node from damage due to parent cell and parent node incosistency.
 
BOOLEAN CMAPI CmpRepairKeyNodeSignature (_Inout_ PHHIVE Hive, _In_ HCELL_INDEX CurrentCell, _Inout_ PCELL_DATA CellData, _In_ BOOLEAN FixHive)
 Repairs the key node signature from damage due to signature corruption.
 
BOOLEAN CMAPI CmpRepairClassOfNodeKey (_Inout_ PHHIVE Hive, _In_ HCELL_INDEX CurrentCell, _Inout_ PCELL_DATA CellData, _In_ BOOLEAN FixHive)
 Repairs the class from damage due to class corruption within the node key.
 
BOOLEAN CMAPI CmpRepairValueListCount (_Inout_ PHHIVE Hive, _In_ HCELL_INDEX CurrentCell, _In_ ULONG ListCountIndex, _Inout_ PCELL_DATA ValueListData, _In_ BOOLEAN FixHive)
 Repairs the value list count of key due to corruption. The process involves by removing one damaged value less from the list.
 
BOOLEAN CMAPI CmpRepairValueList (_Inout_ PHHIVE Hive, _In_ HCELL_INDEX CurrentCell, _In_ BOOLEAN FixHive)
 Repairs the value list due to corruption. The process involes by purging the whole damaged list.
 
BOOLEAN CMAPI CmpRepairSubKeyCounts (_Inout_ PHHIVE Hive, _In_ HCELL_INDEX CurrentCell, _In_ ULONG Count, _Inout_ PCELL_DATA CellData, _In_ BOOLEAN FixHive)
 Repairs the subkey list count due to corruption. The process involves by fixing the count itself with a sane count.
 
BOOLEAN CMAPI CmpRepairSubKeyList (_Inout_ PHHIVE Hive, _In_ HCELL_INDEX CurrentCell, _Inout_ PCELL_DATA CellData, _In_ BOOLEAN FixHive)
 Repairs the subkey list due to corruption. The process involves by purging the whole damaged subkeys list.
 

Variables

BOOLEAN CmpSelfHeal
 
ULONG CmpBootType
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 9 of file cmheal.c.

Function Documentation

◆ CmIsSelfHealEnabled()

BOOLEAN CMAPI CmIsSelfHealEnabled ( _In_ BOOLEAN  FixHive)

Checks if self healing is permitted by the kernel and/or bootloader. Self healing is also triggered if such a request was prompted by the user to fix a broken hive. Such a request tipically comes from a registry repair tool such as the ReactOS Check Registry Utility.

Parameters
[in]FixHiveIf set to TRUE, self heal is triggered and the target hive will be fixed. Otherwise the hive will not be fixed.
Returns
Returns TRUE if self healing is possible, FALSE otherwise.

Definition at line 369 of file cmheal.c.

371{
372 PAGED_CODE();
373
374 if (FixHive)
375 return TRUE;
376
377#if !defined(CMLIB_HOST) && !defined(_BLDR_)
379 return TRUE;
380#endif
381
382 return FALSE;
383}
#define PAGED_CODE()
ULONG CmpBootType
Definition: cmdata.c:62
BOOLEAN CmpSelfHeal
Definition: cmdata.c:64
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define HBOOT_TYPE_SELF_HEAL
Definition: hivedata.h:89

Referenced by CmpRepairClassOfNodeKey(), CmpRepairKeyNodeSignature(), CmpRepairParentKey(), CmpRepairParentNode(), CmpRepairSubKeyCounts(), CmpRepairSubKeyList(), CmpRepairValueList(), CmpRepairValueListCount(), HvpInitializeMemoryHive(), HvpRecoverDataFromLog(), and HvpRecoverHeaderFromLog().

◆ CmpRemoveFastIndexKeyCell()

static VOID CmpRemoveFastIndexKeyCell ( _Inout_ PCM_KEY_FAST_INDEX  FastIndex,
_In_ ULONG  Index,
_In_ BOOLEAN  UpdateCount 
)
static

Removes a cell from a fast key index.

Parameters
[in,out]FastIndexThe fast key index where a cell has to be removed.
[in]IndexThe index which points to the location of the cell that is to be removed.
[in]UpdateCountIf set to TRUE, the function will update the fast index count accordingly by one value less. If set to FALSE, the count won't be updated. See Remarks for further information.
Remarks
In case where the fast index count is not updated is when the key index is not a root but a leaf. In such scenario such leaf is the actual key index itself so updating the fast index count is not necessary (aka UpdateCount is set to FALSE).

Definition at line 47 of file cmheal.c.

51{
52 ULONG MoveCount;
53 ASSERT(Index < FastIndex->Count);
54
55 /* Calculate the number of trailing cells */
56 MoveCount = FastIndex->Count - Index - 1;
57 if (MoveCount != 0)
58 {
59 /* Remove the cell now by moving one location ahead */
60 RtlMoveMemory(&FastIndex->List[Index],
61 &FastIndex->List[Index + 1],
62 MoveCount * sizeof(CM_INDEX));
63 }
64
65 /* Update the fast index count if asked */
66 if (UpdateCount)
67 FastIndex->Count--;
68}
#define ASSERT(a)
Definition: mode.c:44
int Count
Definition: noreturn.cpp:7
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
uint32_t ULONG
Definition: typedefs.h:59
_In_ WDFCOLLECTION _In_ ULONG Index

Referenced by CmpRemoveSubKeyInLeaf(), and CmpRemoveSubkeyInRoot().

◆ CmpRemoveIndexKeyCell()

static VOID CmpRemoveIndexKeyCell ( _Inout_ PCM_KEY_INDEX  KeyIndex,
_In_ ULONG  Index 
)
static

Removes a cell from a normal key index.

Parameters
[in,out]KeyIndexThe key index where a cell has to be removed.
[in]IndexThe index which points to the location of the cell that is to be removed.

Definition at line 83 of file cmheal.c.

86{
87 ULONG MoveCount;
88 ASSERT(Index < KeyIndex->Count);
89
90 /* Calculate the number of trailing cells */
91 MoveCount = KeyIndex->Count - Index - 1;
92 if (MoveCount != 0)
93 {
94 /* Remove the cell now by moving one location ahead */
95 RtlMoveMemory(&KeyIndex->List[Index],
96 &KeyIndex->List[Index + 1],
97 MoveCount * sizeof(HCELL_INDEX));
98 }
99
100 /* Update the key index count */
101 KeyIndex->Count--;
102}
ULONG HCELL_INDEX
Definition: hivedata.h:105

Referenced by CmpRemoveSubKeyInLeaf(), and CmpRemoveSubkeyInRoot().

◆ CmpRemoveSubKeyInLeaf()

static BOOLEAN CmpRemoveSubKeyInLeaf ( _In_ PHHIVE  Hive,
_In_ PCM_KEY_NODE  KeyNode,
_In_ PCM_KEY_INDEX  Leaf,
_In_ HCELL_INDEX  TargetKey 
)
static

Removes the offending subkey from a leaf index.

Parameters
[in]HiveA pointer to a hive descriptor containing faulty data.
[in]KeyNodeA pointer to a key node of the parent. This node is used by the function to mark the whole subkeys list of the parent dirty.
[in]LeafA pointer to a leaf key index of which the offending subkey is to be removed from.
[in]TargetKeyThe offending target subkey to remove.
Returns
Returns TRUE if the function successfully removed the target key, FALSE otherwise.

Definition at line 281 of file cmheal.c.

286{
287 PCM_KEY_FAST_INDEX FastIndex;
288 ULONG LeafIndex;
289
290 /* Loop the leaf index */
291 for (LeafIndex = 0; LeafIndex < Leaf->Count; LeafIndex++)
292 {
293 /*
294 * Check if the main leaf is a fast
295 * leaf or a hash one.
296 */
297 if ((Leaf->Signature == CM_KEY_FAST_LEAF) ||
298 (Leaf->Signature == CM_KEY_HASH_LEAF))
299 {
300 /* It is one of the two, get the fast index */
301 FastIndex = (PCM_KEY_FAST_INDEX)Leaf;
302
303 /*
304 * Is the subkey cell from the fast
305 * index the one we're actually
306 * searching?
307 */
308 if (FastIndex->List[LeafIndex].Cell == TargetKey)
309 {
310 HvMarkCellDirty(Hive, KeyNode->SubKeyLists[Stable], FALSE);
311 CmpRemoveFastIndexKeyCell(FastIndex, LeafIndex, FALSE);
312
313 /*
314 * Since this fast index actually came from the
315 * actual leaf index itself, just update its count
316 * rather than that of the fast index.
317 */
318 Leaf->Count--;
319 DPRINT1("The offending key cell has BEEN FOUND in fast index (fast index 0x%p, leaf index %lu)\n",
320 FastIndex, LeafIndex);
321 return TRUE;
322 }
323 }
324 else
325 {
326 /*
327 * The leaf is neither of the two. The offending
328 * cell must come directly from the normal leaf
329 * at this point.
330 */
331 if (Leaf->List[LeafIndex] == TargetKey)
332 {
333 HvMarkCellDirty(Hive, KeyNode->SubKeyLists[Stable], FALSE);
334 CmpRemoveIndexKeyCell(Leaf, LeafIndex);
335 DPRINT1("The offending key cell has BEEN FOUND in leaf (leaf 0x%p, index %lu)\n",
336 Leaf, LeafIndex);
337 return TRUE;
338 }
339 }
340 }
341
342 /*
343 * We have searched everywhere but we couldn't
344 * hunt the offending target key cell.
345 */
346 DPRINT1("No target key has been found to remove\n");
347 return FALSE;
348}
#define DPRINT1
Definition: precomp.h:8
struct _CM_KEY_FAST_INDEX * PCM_KEY_FAST_INDEX
#define CM_KEY_FAST_LEAF
Definition: cmdata.h:15
#define CM_KEY_HASH_LEAF
Definition: cmdata.h:16
static VOID CmpRemoveFastIndexKeyCell(_Inout_ PCM_KEY_FAST_INDEX FastIndex, _In_ ULONG Index, _In_ BOOLEAN UpdateCount)
Removes a cell from a fast key index.
Definition: cmheal.c:47
static VOID CmpRemoveIndexKeyCell(_Inout_ PCM_KEY_INDEX KeyIndex, _In_ ULONG Index)
Removes a cell from a normal key index.
Definition: cmheal.c:83
BOOLEAN CMAPI HvMarkCellDirty(PHHIVE RegistryHive, HCELL_INDEX CellOffset, BOOLEAN HoldingLock)
Definition: hivecell.c:109
@ Stable
Definition: hivedata.h:127
HCELL_INDEX Cell
Definition: cmdata.h:165
CM_INDEX List[ANYSIZE_ARRAY]
Definition: cmdata.h:190

Referenced by CmpRepairParentKey().

◆ CmpRemoveSubkeyInRoot()

static BOOLEAN CmpRemoveSubkeyInRoot ( _In_ PHHIVE  Hive,
_In_ PCM_KEY_INDEX  RootIndex,
_In_ HCELL_INDEX  TargetKey 
)
static

Removes the offending subkey from a root index.

Parameters
[in]HiveA pointer to a hive descriptor containing faulty data.
[in]RootIndexThe root index where a leaf is obtained from. Such leaf is used to check deep down the leaf for the offending subkey.
[in]TargetKeyThe offending target subkey to be removed.
Returns
Returns TRUE if the function successfully removed the target key, FALSE otherwise.

Definition at line 164 of file cmheal.c.

168{
169 PCM_KEY_INDEX Leaf;
170 PCM_KEY_FAST_INDEX FastIndex;
171 HCELL_INDEX LeafCell;
172 ULONG RootCountIndex;
173 ULONG LeafCountIndex;
174
175 PAGED_CODE();
176
177 ASSERT(RootIndex);
178
179 /* Loop the root index */
180 for (RootCountIndex = 0; RootCountIndex < RootIndex->Count; RootCountIndex++)
181 {
182 /*
183 * Release the leaf cell from previous iteration
184 * of the loop. Make sure what we're releasing is
185 * valid to begin with.
186 */
187 if (RootCountIndex)
188 {
189 ASSERT(Leaf);
190 ASSERT(LeafCell == RootIndex->List[RootCountIndex - 1]);
191 HvReleaseCell(Hive, LeafCell);
192 }
193
194 /* Get the leaf cell and the leaf for this index */
195 LeafCell = RootIndex->List[RootCountIndex];
196 Leaf = (PCM_KEY_INDEX)HvGetCell(Hive, LeafCell);
197 if (!Leaf)
198 {
199 DPRINT1("Couldn't get the leaf from cell\n");
200 return FALSE;
201 }
202
203 /* Start looping the leaf */
204 for (LeafCountIndex = 0; LeafCountIndex < Leaf->Count; LeafCountIndex++)
205 {
206 /* Is the leaf a fast leaf or a hash one? */
207 if ((Leaf->Signature == CM_KEY_FAST_LEAF) ||
208 (Leaf->Signature == CM_KEY_HASH_LEAF))
209 {
210 /* It is one of the two, get the fast index */
211 FastIndex = (PCM_KEY_FAST_INDEX)Leaf;
212
213 /*
214 * Is the subkey cell from the fast
215 * index the one we one we're actually
216 * searching?
217 */
218 if (FastIndex->List[LeafCountIndex].Cell == TargetKey)
219 {
220 HvReleaseCell(Hive, LeafCell);
221 HvMarkCellDirty(Hive, LeafCell, FALSE);
222 CmpRemoveFastIndexKeyCell(FastIndex, LeafCountIndex, TRUE);
223 DPRINT1("The offending key cell has BEEN FOUND in fast index (fast index 0x%p, index %lu)\n",
224 FastIndex, LeafCountIndex);
225 return TRUE;
226 }
227 }
228 else
229 {
230 /*
231 * The leaf is neither of the two. Check if
232 * the target offending cell is inside the leaf
233 * itself.
234 */
235 if (Leaf->List[LeafCountIndex] == TargetKey)
236 {
237 HvReleaseCell(Hive, LeafCell);
238 HvMarkCellDirty(Hive, LeafCell, FALSE);
239 CmpRemoveIndexKeyCell(Leaf, LeafCountIndex);
240 DPRINT1("The offending key cell has BEEN FOUND in leaf (leaf 0x%p, index %lu)\n",
241 Leaf, LeafCountIndex);
242 return TRUE;
243 }
244 }
245 }
246 }
247
248 /*
249 * We have searched everywhere but we couldn't
250 * hunt the offending target key cell.
251 */
252 DPRINT1("No target key has been found to remove\n");
253 return FALSE;
254}
struct _CM_KEY_INDEX * PCM_KEY_INDEX
#define HvReleaseCell(Hive, Cell)
Definition: cmlib.h:460
#define HvGetCell(Hive, Cell)
Definition: cmlib.h:457
USHORT Signature
Definition: cmdata.h:178
USHORT Count
Definition: cmdata.h:179
HCELL_INDEX List[ANYSIZE_ARRAY]
Definition: cmdata.h:180

Referenced by CmpRepairParentKey().

◆ CmpRemoveValueFromValueList()

static VOID CmpRemoveValueFromValueList ( _Inout_ PCM_KEY_NODE  ValueListNode,
_Inout_ PCELL_DATA  ValueListData,
_In_ ULONG  Index 
)
static

Removes a cell from a key value list node.

Parameters
[in,out]ValueListNodeThe value list node which is used by the function to update the value list count.
[in,out]ValueListDataThe value list data of which a cell has to be removed.
[in]IndexThe index which points to the location of the cell that is to be removed.

Definition at line 121 of file cmheal.c.

125{
126 ULONG MoveCount;
127 ASSERT(Index < ValueListNode->ValueList.Count);
128
129 /* Calculate the number of trailing values */
130 MoveCount = ValueListNode->ValueList.Count - Index - 1;
131 if (MoveCount != 0)
132 {
133 /* Remove the value now by moving one location ahead */
134 RtlMoveMemory(&ValueListData->u.KeyList[Index],
135 &ValueListData->u.KeyList[Index + 1],
136 MoveCount * sizeof(HCELL_INDEX));
137 }
138
139 /* Update the value list count */
140 ValueListNode->ValueList.Count--;
141}

Referenced by CmpRepairValueListCount().

◆ CmpRepairClassOfNodeKey()

BOOLEAN CMAPI CmpRepairClassOfNodeKey ( _Inout_ PHHIVE  Hive,
_In_ HCELL_INDEX  CurrentCell,
_Inout_ PCELL_DATA  CellData,
_In_ BOOLEAN  FixHive 
)

Repairs the class from damage due to class corruption within the node key.

Parameters
[in,out]HiveA pointer to a hive descriptor containing faulty data.
[in]CurrentCellThe current cell to be marked as dirty.
[in,out]CellDataThe cell data of the current cell of which its class is to be repaired.
[in]FixHiveIf set to TRUE, self heal is triggered and the target hive will be fixed. Otherwise the hive will not be fixed.
Returns
Returns TRUE if the function successfully healed the class of node key, FALSE otherwise.

Definition at line 637 of file cmheal.c.

642{
643 PAGED_CODE();
644
645 /* Is self healing possible? */
646 if (!CmIsSelfHealEnabled(FixHive))
647 {
648 DPRINT1("Self healing not possible\n");
649 return FALSE;
650 }
651
652 /*
653 * Mark the cell where we got the actual
654 * cell data as dirty and fix the class field
655 * of key node.
656 */
657 HvMarkCellDirty(Hive, CurrentCell, FALSE);
658 CellData->u.KeyNode.Class = HCELL_NIL;
659 CellData->u.KeyNode.ClassLength = 0;
660
661 /* Mark the hive as in self healing mode since we repaired it */
662 Hive->BaseBlock->BootType |= HBOOT_TYPE_SELF_HEAL;
663 return TRUE;
664}
BOOLEAN CMAPI CmIsSelfHealEnabled(_In_ BOOLEAN FixHive)
Checks if self healing is permitted by the kernel and/or bootloader. Self healing is also triggered i...
Definition: cmheal.c:369
#define HCELL_NIL
Definition: hivedata.h:110

Referenced by CmpValidateKey().

◆ CmpRepairKeyNodeSignature()

BOOLEAN CMAPI CmpRepairKeyNodeSignature ( _Inout_ PHHIVE  Hive,
_In_ HCELL_INDEX  CurrentCell,
_Inout_ PCELL_DATA  CellData,
_In_ BOOLEAN  FixHive 
)

Repairs the key node signature from damage due to signature corruption.

Parameters
[in,out]HiveA pointer to a hive descriptor containing faulty data.
[in]CurrentCellThe current cell to be marked as dirty.
[in,out]CellDataThe cell data of the current cell of which its signature is to be repaired.
[in]FixHiveIf set to TRUE, self heal is triggered and the target hive will be fixed. Otherwise the hive will not be fixed.
Returns
Returns TRUE if the function successfully healed the key node signature, FALSE otherwise.

Definition at line 585 of file cmheal.c.

590{
591 PAGED_CODE();
592
593 /* Is self healing possible? */
594 if (!CmIsSelfHealEnabled(FixHive))
595 {
596 DPRINT1("Self healing not possible\n");
597 return FALSE;
598 }
599
600 /*
601 * Mark the cell where we got the actual
602 * cell data as dirty and fix the key signature.
603 */
604 HvMarkCellDirty(Hive, CurrentCell, FALSE);
605 CellData->u.KeyNode.Signature = CM_KEY_NODE_SIGNATURE;
606
607 /* Mark the hive as in self healing mode since we repaired it */
608 Hive->BaseBlock->BootType |= HBOOT_TYPE_SELF_HEAL;
609 return TRUE;
610}
#define CM_KEY_NODE_SIGNATURE
Definition: cmdata.h:21

Referenced by CmpValidateKey().

◆ CmpRepairParentKey()

BOOLEAN CMAPI CmpRepairParentKey ( _Inout_ PHHIVE  Hive,
_In_ HCELL_INDEX  TargetKey,
_In_ HCELL_INDEX  ParentKey,
_In_ BOOLEAN  FixHive 
)

Repairs the parent key from damage by removing the offending subkey cell.

Parameters
[in,out]HiveA pointer to a hive descriptor containing faulty data.
[in]TargetKeyThe offending target cell to remove from the parent.
[in]ParentKeyThe damaged parent key cell to heal.
[in]FixHiveIf set to TRUE, self heal is triggered and the target hive will be fixed. Otherwise the hive will not be fixed.
Returns
Returns TRUE if the function successfully healed the parent key, FALSE otherwise.

Definition at line 409 of file cmheal.c.

414{
415 PCM_KEY_INDEX KeyIndex;
416 PCM_KEY_NODE KeyNode;
417 BOOLEAN ParentRepaired;
418
419 PAGED_CODE();
420
421 /* The target key must NEVER be NIL! */
422 ASSERT(TargetKey != HCELL_NIL);
423
424 /* Assume the parent hasn't been repaired yet */
425 ParentRepaired = FALSE;
426
427 /* Is self healing possible? */
428 if (!CmIsSelfHealEnabled(FixHive))
429 {
430 DPRINT1("Self healing not possible\n");
431 return ParentRepaired;
432 }
433
434 /* Obtain a node from the parent */
435 KeyNode = (PCM_KEY_NODE)HvGetCell(Hive, ParentKey);
436 if (!KeyNode)
437 {
438 DPRINT1("Couldn't get the parent key node\n");
439 return ParentRepaired;
440 }
441
442 /* Obtain the index as well since we got the parent node */
443 KeyIndex = (PCM_KEY_INDEX)HvGetCell(Hive, KeyNode->SubKeyLists[Stable]);
444 if (!KeyIndex)
445 {
446 DPRINT1("Couldn't get the key index from parent node\n");
448 return ParentRepaired;
449 }
450
451 /* Check if this is a root */
452 if (KeyIndex->Signature == CM_KEY_INDEX_ROOT)
453 {
454 /* It is, call the specific helper to discard the damaged key down the root */
455 ParentRepaired = CmpRemoveSubkeyInRoot(Hive,
456 KeyIndex,
457 TargetKey);
458 }
459 else if ((KeyIndex->Signature == CM_KEY_INDEX_LEAF) ||
460 (KeyIndex->Signature == CM_KEY_FAST_LEAF) ||
461 (KeyIndex->Signature == CM_KEY_HASH_LEAF))
462 {
463 /* Otherwise call the leaf helper */
464 ParentRepaired = CmpRemoveSubKeyInLeaf(Hive,
465 KeyNode,
466 KeyIndex,
467 TargetKey);
468 }
469 else
470 {
471 /*
472 * Generally CmCheckRegistry detects if a key index
473 * in the subkeys list is totally broken (we understand
474 * that if its signature is not root or leaf) and it will
475 * purge the whole subkeys list in such cases. With that
476 * being said, we should never reach this code path. But
477 * if for whatever reason we reach here then something
478 * is seriously wrong.
479 */
480 DPRINT1("The key index signature is invalid (KeyIndex->Signature == %lu)", KeyIndex->Signature);
481 ASSERT(FALSE);
482 }
483
484 /*
485 * If we successfully removed the offending key
486 * cell mark down the parent as dirty and punt down
487 * the subkey count as well. Mark the hive as in
488 * self heal mode as well.
489 */
490 if (ParentRepaired)
491 {
493 KeyNode->SubKeyCounts[Stable]--;
494 Hive->BaseBlock->BootType |= HBOOT_TYPE_SELF_HEAL;
495 DPRINT1("The subkey has been removed, the parent is now repaired\n");
496 }
497
498 HvReleaseCell(Hive, KeyNode->SubKeyLists[Stable]);
500 return ParentRepaired;
501}
unsigned char BOOLEAN
struct _CM_KEY_NODE * PCM_KEY_NODE
#define CM_KEY_INDEX_LEAF
Definition: cmdata.h:14
#define CM_KEY_INDEX_ROOT
Definition: cmdata.h:13
static BOOLEAN CmpRemoveSubKeyInLeaf(_In_ PHHIVE Hive, _In_ PCM_KEY_NODE KeyNode, _In_ PCM_KEY_INDEX Leaf, _In_ HCELL_INDEX TargetKey)
Removes the offending subkey from a leaf index.
Definition: cmheal.c:281
static BOOLEAN CmpRemoveSubkeyInRoot(_In_ PHHIVE Hive, _In_ PCM_KEY_INDEX RootIndex, _In_ HCELL_INDEX TargetKey)
Removes the offending subkey from a root index.
Definition: cmheal.c:164
HCELL_INDEX SubKeyLists[HTYPE_COUNT]
Definition: cmdata.h:102
ULONG SubKeyCounts[HTYPE_COUNT]
Definition: cmdata.h:97
_Must_inspect_result_ _In_opt_ WDFKEY ParentKey
Definition: wdfregistry.h:69

Referenced by CmpValidateRegistryInternal().

◆ CmpRepairParentNode()

BOOLEAN CMAPI CmpRepairParentNode ( _Inout_ PHHIVE  Hive,
_In_ HCELL_INDEX  CurrentCell,
_In_ HCELL_INDEX  ParentCell,
_Inout_ PCELL_DATA  CellData,
_In_ BOOLEAN  FixHive 
)

Repairs the parent of the node from damage due to parent cell and parent node incosistency.

Parameters
[in,out]HiveA pointer to a hive descriptor containing faulty data.
[in]CurrentCellThe current cell to be marked as dirty.
[in]ParentCellThe sane parent cell which is used by the function for new parent node assignment.
[in,out]CellDataThe cell data of the current cell of which its parent node is to be repaired.
[in]FixHiveIf set to TRUE, self heal is triggered and the target hive will be fixed. Otherwise the hive will not be fixed.
Returns
Returns TRUE if the function successfully healed the parent node, FALSE otherwise.

Definition at line 532 of file cmheal.c.

538{
539 PAGED_CODE();
540
541 /* Is self healing possible? */
542 if (!CmIsSelfHealEnabled(FixHive))
543 {
544 DPRINT1("Self healing not possible\n");
545 return FALSE;
546 }
547
548 /*
549 * Mark the cell where we got the actual
550 * cell data as dirty and fix the node.
551 */
552 HvMarkCellDirty(Hive, CurrentCell, FALSE);
553 CellData->u.KeyNode.Parent = ParentCell;
554
555 /* Mark the hive as in self healing mode since we repaired it */
556 Hive->BaseBlock->BootType |= HBOOT_TYPE_SELF_HEAL;
557 return TRUE;
558}

Referenced by CmpValidateKey().

◆ CmpRepairSubKeyCounts()

BOOLEAN CMAPI CmpRepairSubKeyCounts ( _Inout_ PHHIVE  Hive,
_In_ HCELL_INDEX  CurrentCell,
_In_ ULONG  Count,
_Inout_ PCELL_DATA  CellData,
_In_ BOOLEAN  FixHive 
)

Repairs the subkey list count due to corruption. The process involves by fixing the count itself with a sane count.

Parameters
[in,out]HiveA pointer to a hive descriptor containing faulty data.
[in]CurrentCellThe current cell to be marked as dirty.
[in]CountThe healthy count which is used by the function to fix the subkeys list count.
[in,out]CellDataThe cell data of the current cell of which its subkeys list is to be fixed.
[in]FixHiveIf set to TRUE, self heal is triggered and the target hive will be fixed. Otherwise the hive will not be fixed.
Returns
Returns TRUE if the function successfully healed the subkeys list count, FALSE otherwise.

Definition at line 829 of file cmheal.c.

835{
836 PAGED_CODE();
837
838 /* Is self healing possible? */
839 if (!CmIsSelfHealEnabled(FixHive))
840 {
841 DPRINT1("Self healing not possible\n");
842 return FALSE;
843 }
844
845 /*
846 * Mark the cell where we got the actual
847 * cell data as dirty and fix the subkey
848 * counts.
849 */
850 HvMarkCellDirty(Hive, CurrentCell, FALSE);
851 CellData->u.KeyNode.SubKeyCounts[Stable] = Count;
852
853 /* Mark the hive as in self healing mode since we repaired it */
854 Hive->BaseBlock->BootType |= HBOOT_TYPE_SELF_HEAL;
855 return TRUE;
856}

Referenced by CmpValidateSubKeyList().

◆ CmpRepairSubKeyList()

BOOLEAN CMAPI CmpRepairSubKeyList ( _Inout_ PHHIVE  Hive,
_In_ HCELL_INDEX  CurrentCell,
_Inout_ PCELL_DATA  CellData,
_In_ BOOLEAN  FixHive 
)

Repairs the subkey list due to corruption. The process involves by purging the whole damaged subkeys list.

Parameters
[in,out]HiveA pointer to a hive descriptor containing faulty data.
[in]CurrentCellThe current cell to be marked as dirty.
[in,out]CellDataThe cell data of the current cell of which its subkeys list is to be fixed.
[in]FixHiveIf set to TRUE, self heal is triggered and the target hive will be fixed. Otherwise the hive will not be fixed.
Returns
Returns TRUE if the function successfully healed the subkeys list, FALSE otherwise.

Definition at line 883 of file cmheal.c.

888{
889 PAGED_CODE();
890
891 /* Is self healing possible? */
892 if (!CmIsSelfHealEnabled(FixHive))
893 {
894 DPRINT1("Self healing not possible\n");
895 return FALSE;
896 }
897
898 /*
899 * Mark the cell where we got the actual
900 * cell data as dirty and fix the subkey
901 * list.
902 */
903 HvMarkCellDirty(Hive, CurrentCell, FALSE);
904 CellData->u.KeyNode.SubKeyLists[Stable] = HCELL_NIL;
905 CellData->u.KeyNode.SubKeyCounts[Stable] = 0;
906
907 /* Mark the hive as in self healing mode since we repaired it */
908 Hive->BaseBlock->BootType |= HBOOT_TYPE_SELF_HEAL;
909 return TRUE;
910}

Referenced by CmpValidateKey().

◆ CmpRepairValueList()

BOOLEAN CMAPI CmpRepairValueList ( _Inout_ PHHIVE  Hive,
_In_ HCELL_INDEX  CurrentCell,
_In_ BOOLEAN  FixHive 
)

Repairs the value list due to corruption. The process involes by purging the whole damaged list.

Parameters
[in,out]HiveA pointer to a hive descriptor containing faulty data.
[in]CurrentCellThe current cell to be marked as dirty.
[in]FixHiveIf set to TRUE, self heal is triggered and the target hive will be fixed. Otherwise the hive will not be fixed.
Returns
Returns TRUE if the function successfully healed the value list, FALSE otherwise.

Definition at line 765 of file cmheal.c.

769{
770 PCM_KEY_NODE ValueListNode;
771
772 PAGED_CODE();
773
774 /* Is self healing possible? */
775 if (!CmIsSelfHealEnabled(FixHive))
776 {
777 DPRINT1("Self healing not possible\n");
778 return FALSE;
779 }
780
781 /* Obtain a node */
782 ValueListNode = (PCM_KEY_NODE)HvGetCell(Hive, CurrentCell);
783 if (!ValueListNode)
784 {
785 DPRINT1("Could not get a node from the current cell\n");
786 return FALSE;
787 }
788
789 /* Purge out the whole list */
790 HvMarkCellDirty(Hive, CurrentCell, FALSE);
791 ValueListNode->ValueList.List = HCELL_NIL;
792 ValueListNode->ValueList.Count = 0;
793
794 Hive->BaseBlock->BootType |= HBOOT_TYPE_SELF_HEAL;
795 HvReleaseCell(Hive, CurrentCell);
796 return TRUE;
797}
HCELL_INDEX List
Definition: cmdata.h:75
ULONG Count
Definition: cmdata.h:74
CHILD_LIST ValueList
Definition: cmdata.h:103

Referenced by CmpValidateKey().

◆ CmpRepairValueListCount()

BOOLEAN CMAPI CmpRepairValueListCount ( _Inout_ PHHIVE  Hive,
_In_ HCELL_INDEX  CurrentCell,
_In_ ULONG  ListCountIndex,
_Inout_ PCELL_DATA  ValueListData,
_In_ BOOLEAN  FixHive 
)

Repairs the value list count of key due to corruption. The process involves by removing one damaged value less from the list.

Parameters
[in,out]HiveA pointer to a hive descriptor containing faulty data.
[in]CurrentCellThe current cell to be marked as dirty.
[in]ListCountIndexThe value count index which points to the actual value in the list to be removed.
[in,out]ValueListDataThe value list cell data containing the actual list of which the damaged is to be removed from.
[in]FixHiveIf set to TRUE, self heal is triggered and the target hive will be fixed. Otherwise the hive will not be fixed.
Returns
Returns TRUE if the function successfully healed the value list count, FALSE otherwise.

Definition at line 696 of file cmheal.c.

702{
703 PCM_KEY_NODE ValueListNode;
704
705 PAGED_CODE();
706
707 /* Is self healing possible? */
708 if (!CmIsSelfHealEnabled(FixHive))
709 {
710 DPRINT1("Self healing not possible\n");
711 return FALSE;
712 }
713
714 /*
715 * Obtain a node from the cell that we mark it as dirty.
716 * The node is that of the current cell of which its
717 * value list is being validated.
718 */
719 ValueListNode = (PCM_KEY_NODE)HvGetCell(Hive, CurrentCell);
720 if (!ValueListNode)
721 {
722 DPRINT1("Could not get a node from the current cell\n");
723 return FALSE;
724 }
725
726 /*
727 * Mark the current cell and value list as dirty
728 * as we will be making changes onto them.
729 */
730 HvMarkCellDirty(Hive, CurrentCell, FALSE);
731 HvMarkCellDirty(Hive, ValueListNode->ValueList.List, FALSE);
732
733 /*
734 * Now remove the value from the list and mark the
735 * hive as in self healing mode.
736 */
737 CmpRemoveValueFromValueList(ValueListNode, ValueListData, ListCountIndex);
738 Hive->BaseBlock->BootType |= HBOOT_TYPE_SELF_HEAL;
739 HvReleaseCell(Hive, CurrentCell);
740 return TRUE;
741}
static VOID CmpRemoveValueFromValueList(_Inout_ PCM_KEY_NODE ValueListNode, _Inout_ PCELL_DATA ValueListData, _In_ ULONG Index)
Removes a cell from a key value list node.
Definition: cmheal.c:121

Referenced by CmpValidateValueListByCount().

Variable Documentation

◆ CmpBootType

ULONG CmpBootType
extern

Definition at line 62 of file cmdata.c.

Referenced by CmIsSelfHealEnabled(), and CmpInitializeSystemHive().

◆ CmpSelfHeal

BOOLEAN CmpSelfHeal
extern

Definition at line 64 of file cmdata.c.

Referenced by CmIsSelfHealEnabled(), and CmpInitializeSystemHive().