ReactOS 0.4.15-dev-8222-g9164419
cmheal.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: Configuration Manager Library - Registry Self-Heal Routines
5 * COPYRIGHT: Copyright 2022 George Bișoc <george.bisoc@reactos.org>
6 */
7
8#include "cmlib.h"
9#define NDEBUG
10#include <debug.h>
11
12/* GLOBALS ********************************************************************/
13
14#if !defined(CMLIB_HOST) && !defined(_BLDR_)
15extern BOOLEAN CmpSelfHeal;
16extern ULONG CmpBootType;
17#endif
18
19/* PRIVATE FUNCTIONS **********************************************************/
20
45static
46VOID
50 _In_ BOOLEAN UpdateCount)
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}
69
81static
82VOID
84 _Inout_ PCM_KEY_INDEX KeyIndex,
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}
103
119static
120VOID
122 _Inout_ PCM_KEY_NODE ValueListNode,
123 _Inout_ PCELL_DATA ValueListData,
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}
142
162static
165 _In_ PHHIVE Hive,
166 _In_ PCM_KEY_INDEX RootIndex,
167 _In_ HCELL_INDEX TargetKey)
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}
255
279static
282 _In_ PHHIVE Hive,
283 _In_ PCM_KEY_NODE KeyNode,
284 _In_ PCM_KEY_INDEX Leaf,
285 _In_ HCELL_INDEX TargetKey)
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}
349
350/* PUBLIC FUNCTIONS ***********************************************************/
351
368CMAPI
370 _In_ BOOLEAN FixHive)
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}
384
408CMAPI
410 _Inout_ PHHIVE Hive,
411 _In_ HCELL_INDEX TargetKey,
413 _In_ BOOLEAN FixHive)
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}
502
531CMAPI
533 _Inout_ PHHIVE Hive,
534 _In_ HCELL_INDEX CurrentCell,
535 _In_ HCELL_INDEX ParentCell,
536 _Inout_ PCELL_DATA CellData,
537 _In_ BOOLEAN FixHive)
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}
559
584CMAPI
586 _Inout_ PHHIVE Hive,
587 _In_ HCELL_INDEX CurrentCell,
588 _Inout_ PCELL_DATA CellData,
589 _In_ BOOLEAN FixHive)
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}
611
636CMAPI
638 _Inout_ PHHIVE Hive,
639 _In_ HCELL_INDEX CurrentCell,
640 _Inout_ PCELL_DATA CellData,
641 _In_ BOOLEAN FixHive)
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}
665
695CMAPI
697 _Inout_ PHHIVE Hive,
698 _In_ HCELL_INDEX CurrentCell,
699 _In_ ULONG ListCountIndex,
700 _Inout_ PCELL_DATA ValueListData,
701 _In_ BOOLEAN FixHive)
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}
742
764CMAPI
766 _Inout_ PHHIVE Hive,
767 _In_ HCELL_INDEX CurrentCell,
768 _In_ BOOLEAN FixHive)
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}
798
828CMAPI
830 _Inout_ PHHIVE Hive,
831 _In_ HCELL_INDEX CurrentCell,
833 _Inout_ PCELL_DATA CellData,
834 _In_ BOOLEAN FixHive)
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}
857
882CMAPI
884 _Inout_ PHHIVE Hive,
885 _In_ HCELL_INDEX CurrentCell,
886 _Inout_ PCELL_DATA CellData,
887 _In_ BOOLEAN FixHive)
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}
911
912/* EOF */
#define PAGED_CODE()
unsigned char BOOLEAN
#define DPRINT1
Definition: precomp.h:8
#define CMAPI
Definition: cfgmgr32.h:41
struct _CM_KEY_NODE * PCM_KEY_NODE
#define CM_KEY_INDEX_LEAF
Definition: cmdata.h:14
#define CM_KEY_NODE_SIGNATURE
Definition: cmdata.h:21
#define CM_KEY_INDEX_ROOT
Definition: cmdata.h:13
struct _CM_KEY_FAST_INDEX * PCM_KEY_FAST_INDEX
#define CM_KEY_FAST_LEAF
Definition: cmdata.h:15
struct _CM_KEY_INDEX * PCM_KEY_INDEX
#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 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
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.
Definition: cmheal.c:765
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 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
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.
Definition: cmheal.c:637
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
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
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.
Definition: cmheal.c:532
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 v...
Definition: cmheal.c:696
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.
Definition: cmheal.c:585
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...
Definition: cmheal.c:829
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 ...
Definition: cmheal.c:883
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.
Definition: cmheal.c:409
ULONG CmpBootType
Definition: cmdata.c:62
BOOLEAN CmpSelfHeal
Definition: cmdata.c:64
#define HvReleaseCell(Hive, Cell)
Definition: cmlib.h:460
BOOLEAN CMAPI HvMarkCellDirty(PHHIVE RegistryHive, HCELL_INDEX CellOffset, BOOLEAN HoldingLock)
Definition: hivecell.c:109
#define HvGetCell(Hive, Cell)
Definition: cmlib.h:457
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
@ Stable
Definition: hivedata.h:127
#define HCELL_NIL
Definition: hivedata.h:110
ULONG HCELL_INDEX
Definition: hivedata.h:105
#define HBOOT_TYPE_SELF_HEAL
Definition: hivedata.h:89
#define ASSERT(a)
Definition: mode.c:44
#define _Inout_
Definition: ms_sal.h:378
#define _In_
Definition: ms_sal.h:308
int Count
Definition: noreturn.cpp:7
HCELL_INDEX List
Definition: cmdata.h:75
ULONG Count
Definition: cmdata.h:74
HCELL_INDEX Cell
Definition: cmdata.h:165
CM_INDEX List[ANYSIZE_ARRAY]
Definition: cmdata.h:190
USHORT Signature
Definition: cmdata.h:178
USHORT Count
Definition: cmdata.h:179
HCELL_INDEX List[ANYSIZE_ARRAY]
Definition: cmdata.h:180
HCELL_INDEX SubKeyLists[HTYPE_COUNT]
Definition: cmdata.h:102
ULONG SubKeyCounts[HTYPE_COUNT]
Definition: cmdata.h:97
CHILD_LIST ValueList
Definition: cmdata.h:103
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
uint32_t ULONG
Definition: typedefs.h:59
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ _In_opt_ WDFKEY ParentKey
Definition: wdfregistry.h:69