ReactOS 0.4.16-dev-1067-ge98bba2
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:64
BOOLEAN CmpSelfHeal
Definition: cmdata.c:66
#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 %u)\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 %u)\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 %u)\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 %u)\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 638 of file cmheal.c.

643{
644 PAGED_CODE();
645
646 /* Is self healing possible? */
647 if (!CmIsSelfHealEnabled(FixHive))
648 {
649 DPRINT1("Self healing not possible\n");
650 return FALSE;
651 }
652
653 /*
654 * Mark the cell where we got the actual
655 * cell data as dirty and fix the class field
656 * of key node.
657 */
658 HvMarkCellDirty(Hive, CurrentCell, FALSE);
659 CellData->u.KeyNode.Class = HCELL_NIL;
660 CellData->u.KeyNode.ClassLength = 0;
661
662 /* Mark the hive as in self healing mode since we repaired it */
663 Hive->BaseBlock->BootType |= HBOOT_TYPE_SELF_HEAL;
664 return TRUE;
665}
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 586 of file cmheal.c.

591{
592 PAGED_CODE();
593
594 /* Is self healing possible? */
595 if (!CmIsSelfHealEnabled(FixHive))
596 {
597 DPRINT1("Self healing not possible\n");
598 return FALSE;
599 }
600
601 /*
602 * Mark the cell where we got the actual
603 * cell data as dirty and fix the key signature.
604 */
605 HvMarkCellDirty(Hive, CurrentCell, FALSE);
606 CellData->u.KeyNode.Signature = CM_KEY_NODE_SIGNATURE;
607
608 /* Mark the hive as in self healing mode since we repaired it */
609 Hive->BaseBlock->BootType |= HBOOT_TYPE_SELF_HEAL;
610 return TRUE;
611}
#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 == %u)",
481 KeyIndex->Signature);
482 ASSERT(FALSE);
483 }
484
485 /*
486 * If we successfully removed the offending key
487 * cell mark down the parent as dirty and punt down
488 * the subkey count as well. Mark the hive as in
489 * self heal mode as well.
490 */
491 if (ParentRepaired)
492 {
494 KeyNode->SubKeyCounts[Stable]--;
495 Hive->BaseBlock->BootType |= HBOOT_TYPE_SELF_HEAL;
496 DPRINT1("The subkey has been removed, the parent is now repaired\n");
497 }
498
499 HvReleaseCell(Hive, KeyNode->SubKeyLists[Stable]);
501 return ParentRepaired;
502}
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 533 of file cmheal.c.

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

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 830 of file cmheal.c.

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

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 884 of file cmheal.c.

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

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 766 of file cmheal.c.

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

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

Referenced by CmIsSelfHealEnabled(), and CmpInitializeSystemHive().

◆ CmpSelfHeal

BOOLEAN CmpSelfHeal
extern

Definition at line 66 of file cmdata.c.

Referenced by CmIsSelfHealEnabled(), and CmpInitializeSystemHive().