2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: ntoskrnl/config/cmkeydel.c
5 * PURPOSE: Configuration Manager - Key Body Deletion
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
9 /* INCLUDES ******************************************************************/
15 /* FUNCTIONS *****************************************************************/
19 CmpMarkKeyDirty(IN PHHIVE Hive
,
21 IN BOOLEAN CheckNoSubkeys
)
23 PCELL_DATA CellData
, ListData
, SecurityData
, ValueData
;
26 /* Get the cell data for our target */
27 CellData
= HvGetCell(Hive
, Cell
);
28 if (!CellData
) return FALSE
;
30 /* Check if sanity checks requested */
34 ASSERT(CellData
->u
.KeyNode
.SubKeyCounts
[Stable
] == 0);
35 ASSERT(CellData
->u
.KeyNode
.SubKeyCounts
[Volatile
] == 0);
38 /* If this is an exit hive, there's nothing to do */
39 if (CellData
->u
.KeyNode
.Flags
& KEY_HIVE_EXIT
)
41 /* Release the cell and get out */
42 HvReleaseCell(Hive
, Cell
);
46 /* Otherwise, mark it dirty and release it */
47 HvMarkCellDirty(Hive
, Cell
, FALSE
);
48 HvReleaseCell(Hive
, Cell
);
50 /* Check if we have a class */
51 if (CellData
->u
.KeyNode
.Class
!= HCELL_NIL
)
54 HvMarkCellDirty(Hive
, CellData
->u
.KeyNode
.Class
, FALSE
);
57 /* Check if we have security */
58 if (CellData
->u
.KeyNode
.Security
!= HCELL_NIL
)
61 HvMarkCellDirty(Hive
, CellData
->u
.KeyNode
.Security
, FALSE
);
63 /* Get the security data and release it */
64 SecurityData
= HvGetCell(Hive
, CellData
->u
.KeyNode
.Security
);
65 if (!SecurityData
) ASSERT(FALSE
);
66 HvReleaseCell(Hive
, CellData
->u
.KeyNode
.Security
);
68 /* Mark the security links dirty too */
69 HvMarkCellDirty(Hive
, SecurityData
->u
.KeySecurity
.Flink
, FALSE
);
70 HvMarkCellDirty(Hive
, SecurityData
->u
.KeySecurity
.Blink
, FALSE
);
73 /* Check if we have any values */
74 if (CellData
->u
.KeyNode
.ValueList
.Count
> 0)
76 /* Dirty the value list */
77 HvMarkCellDirty(Hive
, CellData
->u
.KeyNode
.ValueList
.List
, FALSE
);
79 /* Get the list data itself, and release it */
80 ListData
= HvGetCell(Hive
, CellData
->u
.KeyNode
.ValueList
.List
);
81 if (!ListData
) ASSERT(FALSE
);
82 HvReleaseCell(Hive
, CellData
->u
.KeyNode
.ValueList
.List
);
85 for (i
= 0; i
< CellData
->u
.KeyNode
.ValueList
.Count
; i
++)
87 /* Dirty each value */
88 HvMarkCellDirty(Hive
, ListData
->u
.KeyList
[i
], FALSE
);
90 /* Get the value data and release it */
91 ValueData
= HvGetCell(Hive
, ListData
->u
.KeyList
[i
]);
93 HvReleaseCell(Hive
,ListData
->u
.KeyList
[i
]);
95 /* Mark the value data dirty too */
96 if (!CmpMarkValueDataDirty(Hive
, &ValueData
->u
.KeyValue
))
104 /* If this is an entry hive, we're done */
105 if (CellData
->u
.KeyNode
.Flags
& KEY_HIVE_ENTRY
) return TRUE
;
107 /* Otherwise mark the index dirty too */
108 if (!CmpMarkIndexDirty(Hive
, CellData
->u
.KeyNode
.Parent
, Cell
))
114 /* Finally, mark the parent dirty */
115 HvMarkCellDirty(Hive
, CellData
->u
.KeyNode
.Parent
, FALSE
);
121 CmpFreeKeyBody(IN PHHIVE Hive
,
126 /* Get the key node */
127 CellData
= HvGetCell(Hive
, Cell
);
128 if (!CellData
) ASSERT(FALSE
);
130 /* Check if we can delete the child cells */
131 if (!(CellData
->u
.KeyNode
.Flags
& KEY_HIVE_EXIT
))
133 /* Check if we have a security cell */
134 if (CellData
->u
.KeyNode
.Security
!= HCELL_NIL
)
136 /* Free the security cell */
137 HvFreeCell(Hive
, CellData
->u
.KeyNode
.Security
);
140 /* Check if we have a class */
141 if (CellData
->u
.KeyNode
.ClassLength
> 0)
144 HvFreeCell(Hive
, CellData
->u
.KeyNode
.Class
);
148 /* Release and free the cell */
149 HvReleaseCell(Hive
, Cell
);
150 HvFreeCell(Hive
, Cell
);
156 CmpFreeKeyByCell(IN PHHIVE Hive
,
160 PCELL_DATA CellData
, ParentData
, ListData
;
164 /* Mark the entire key dirty */
165 CmpMarkKeyDirty(Hive
, Cell
,TRUE
);
167 /* Get the target node and release it */
168 CellData
= HvGetCell(Hive
, Cell
);
169 if (!CellData
) ASSERT(FALSE
);
170 HvReleaseCell(Hive
, Cell
);
172 /* Make sure we don't have subkeys */
173 ASSERT((CellData
->u
.KeyNode
.SubKeyCounts
[Stable
] +
174 CellData
->u
.KeyNode
.SubKeyCounts
[Volatile
]) == 0);
176 /* Check if we have to unlink */
179 /* Remove the subkey */
180 Result
= CmpRemoveSubKey(Hive
, CellData
->u
.KeyNode
.Parent
, Cell
);
181 if (!Result
) return STATUS_INSUFFICIENT_RESOURCES
;
183 /* Get the parent node and release it */
184 ParentData
= HvGetCell(Hive
, CellData
->u
.KeyNode
.Parent
);
185 if (!ParentData
) ASSERT(FALSE
);
186 HvReleaseCell(Hive
, CellData
->u
.KeyNode
.Parent
);
188 /* Check if the parent node has no more subkeys */
189 if (!(ParentData
->u
.KeyNode
.SubKeyCounts
[Stable
] +
190 ParentData
->u
.KeyNode
.SubKeyCounts
[Volatile
]))
192 /* Then free the cached name/class lengths */
193 ParentData
->u
.KeyNode
.MaxNameLen
= 0;
194 ParentData
->u
.KeyNode
.MaxClassLen
= 0;
198 /* Check if we have any values */
199 if (CellData
->u
.KeyNode
.ValueList
.Count
> 0)
201 /* Get the value list and release it */
202 ListData
= HvGetCell(Hive
, CellData
->u
.KeyNode
.ValueList
.List
);
203 if (!ListData
) ASSERT(FALSE
);
204 HvReleaseCell(Hive
, CellData
->u
.KeyNode
.ValueList
.List
);
206 /* Loop every value */
207 for (i
= 0; i
< CellData
->u
.KeyNode
.ValueList
.Count
; i
++)
210 if (!CmpFreeValue(Hive
, ListData
->u
.KeyList
[i
])) ASSERT(FALSE
);
213 /* Free the value list */
214 HvFreeCell(Hive
, CellData
->u
.KeyNode
.ValueList
.List
);
217 /* Free the key body itself, and then return our status */
218 if (!CmpFreeKeyBody(Hive
, Cell
)) return STATUS_INSUFFICIENT_RESOURCES
;
219 return STATUS_SUCCESS
;