2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: lib/cmlib/cmkeydel.c
5 * PURPOSE: Configuration Manager Library - 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 PCM_KEY_NODE CellData
;
24 PCM_KEY_SECURITY SecurityData
;
25 PCELL_DATA ListData
, ValueData
;
28 /* Get the cell data for our target */
29 CellData
= HvGetCell(Hive
, Cell
);
30 if (!CellData
) return FALSE
;
32 /* Check if sanity checks requested */
36 ASSERT(CellData
->SubKeyCounts
[Stable
] == 0);
37 ASSERT(CellData
->SubKeyCounts
[Volatile
] == 0);
40 /* If this is an exit node, there's nothing to do */
41 if (CellData
->Flags
& KEY_HIVE_EXIT
)
43 /* Release the cell and get out */
44 HvReleaseCell(Hive
, Cell
);
48 /* Otherwise, mark it dirty and release it */
49 HvMarkCellDirty(Hive
, Cell
, FALSE
);
50 HvReleaseCell(Hive
, Cell
);
52 /* Check if we have a class */
53 if (CellData
->Class
!= HCELL_NIL
)
56 HvMarkCellDirty(Hive
, CellData
->Class
, FALSE
);
59 /* Check if we have security */
60 if (CellData
->Security
!= HCELL_NIL
)
63 HvMarkCellDirty(Hive
, CellData
->Security
, FALSE
);
65 /* Get the security data and release it */
66 SecurityData
= HvGetCell(Hive
, CellData
->Security
);
67 if (!SecurityData
) ASSERT(FALSE
);
68 HvReleaseCell(Hive
, CellData
->Security
);
70 /* Mark the security links dirty too */
71 HvMarkCellDirty(Hive
, SecurityData
->Flink
, FALSE
);
72 HvMarkCellDirty(Hive
, SecurityData
->Blink
, FALSE
);
75 // TODO: Handle predefined keys (Flags: KEY_PREDEF_HANDLE)
76 /* Check if we have any values */
77 if (CellData
->ValueList
.Count
> 0)
79 /* Dirty the value list */
80 HvMarkCellDirty(Hive
, CellData
->ValueList
.List
, FALSE
);
82 /* Get the list data itself, and release it */
83 ListData
= HvGetCell(Hive
, CellData
->ValueList
.List
);
84 if (!ListData
) ASSERT(FALSE
);
85 HvReleaseCell(Hive
, CellData
->ValueList
.List
);
88 for (i
= 0; i
< CellData
->ValueList
.Count
; i
++)
90 /* Dirty each value */
91 HvMarkCellDirty(Hive
, ListData
->u
.KeyList
[i
], FALSE
);
93 /* Get the value data and release it */
94 ValueData
= HvGetCell(Hive
, ListData
->u
.KeyList
[i
]);
96 HvReleaseCell(Hive
,ListData
->u
.KeyList
[i
]);
98 /* Mark the value data dirty too */
99 if (!CmpMarkValueDataDirty(Hive
, &ValueData
->u
.KeyValue
))
107 /* If this is an entry node, we're done */
108 if (CellData
->Flags
& KEY_HIVE_ENTRY
) return TRUE
;
110 /* Otherwise mark the index dirty too */
111 if (!CmpMarkIndexDirty(Hive
, CellData
->Parent
, Cell
))
117 /* Finally, mark the parent dirty */
118 HvMarkCellDirty(Hive
, CellData
->Parent
, FALSE
);
124 CmpFreeKeyBody(IN PHHIVE Hive
,
127 PCM_KEY_NODE CellData
;
129 /* Get the key node */
130 CellData
= HvGetCell(Hive
, Cell
);
131 if (!CellData
) ASSERT(FALSE
);
133 /* Check if we can delete the child cells */
134 if (!(CellData
->Flags
& KEY_HIVE_EXIT
))
136 /* Check if we have a security cell */
137 if (CellData
->Security
!= HCELL_NIL
)
139 /* Free the security cell */
140 HvFreeCell(Hive
, CellData
->Security
);
143 /* Check if we have a class */
144 if (CellData
->ClassLength
> 0)
147 HvFreeCell(Hive
, CellData
->Class
);
151 /* Release and free the cell */
152 HvReleaseCell(Hive
, Cell
);
153 HvFreeCell(Hive
, Cell
);
159 CmpFreeKeyByCell(IN PHHIVE Hive
,
163 PCM_KEY_NODE CellData
, ParentData
;
168 /* Mark the entire key dirty */
169 CmpMarkKeyDirty(Hive
, Cell
, TRUE
);
171 /* Get the target node and release it */
172 CellData
= HvGetCell(Hive
, Cell
);
173 if (!CellData
) ASSERT(FALSE
);
174 HvReleaseCell(Hive
, Cell
);
176 /* Make sure we don't have subkeys */
177 ASSERT(CellData
->SubKeyCounts
[Stable
] + CellData
->SubKeyCounts
[Volatile
] == 0);
179 /* Check if we have to unlink */
182 /* Remove the subkey */
183 Result
= CmpRemoveSubKey(Hive
, CellData
->Parent
, Cell
);
184 if (!Result
) return STATUS_INSUFFICIENT_RESOURCES
;
186 /* Get the parent node and release it */
187 ParentData
= HvGetCell(Hive
, CellData
->Parent
);
188 if (!ParentData
) ASSERT(FALSE
);
189 HvReleaseCell(Hive
, CellData
->Parent
);
191 /* Check if the parent node has no more subkeys */
192 if (ParentData
->SubKeyCounts
[Stable
] + ParentData
->SubKeyCounts
[Volatile
] == 0)
194 /* Then free the cached name/class lengths */
195 ParentData
->MaxNameLen
= 0;
196 ParentData
->MaxClassLen
= 0;
200 // TODO: Handle predefined keys (Flags: KEY_PREDEF_HANDLE)
201 /* If this is an exit node, we don't have values */
202 if (!(CellData
->Flags
& KEY_HIVE_EXIT
))
204 /* Check if we have any values */
205 if (CellData
->ValueList
.Count
> 0)
207 /* Get the value list and release it */
208 ListData
= HvGetCell(Hive
, CellData
->ValueList
.List
);
209 if (!ListData
) ASSERT(FALSE
);
210 HvReleaseCell(Hive
, CellData
->ValueList
.List
);
212 /* Loop every value */
213 for (i
= 0; i
< CellData
->ValueList
.Count
; i
++)
216 if (!CmpFreeValue(Hive
, ListData
->u
.KeyList
[i
])) ASSERT(FALSE
);
219 /* Free the value list */
220 HvFreeCell(Hive
, CellData
->ValueList
.List
);
223 /* Free the key security descriptor */
224 CmpFreeSecurityDescriptor(Hive
, Cell
);
227 /* Free the key body itself, and then return our status */
228 if (!CmpFreeKeyBody(Hive
, Cell
)) return STATUS_INSUFFICIENT_RESOURCES
;
229 return STATUS_SUCCESS
;