[CRT] spawn: define a unicode environment when needed
[reactos.git] / sdk / lib / cmlib / cmkeydel.c
1 /*
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)
7 */
8
9 /* INCLUDES ******************************************************************/
10
11 #include "cmlib.h"
12 #define NDEBUG
13 #include <debug.h>
14
15 /* FUNCTIONS *****************************************************************/
16
17 BOOLEAN
18 NTAPI
19 CmpMarkKeyDirty(IN PHHIVE Hive,
20 IN HCELL_INDEX Cell,
21 IN BOOLEAN CheckNoSubkeys)
22 {
23 PCM_KEY_NODE CellData;
24 PCM_KEY_SECURITY SecurityData;
25 PCELL_DATA ListData, ValueData;
26 ULONG i;
27
28 /* Get the cell data for our target */
29 CellData = HvGetCell(Hive, Cell);
30 if (!CellData) return FALSE;
31
32 /* Check if sanity checks requested */
33 if (CheckNoSubkeys)
34 {
35 /* Do them */
36 ASSERT(CellData->SubKeyCounts[Stable] == 0);
37 ASSERT(CellData->SubKeyCounts[Volatile] == 0);
38 }
39
40 /* If this is an exit node, there's nothing to do */
41 if (CellData->Flags & KEY_HIVE_EXIT)
42 {
43 /* Release the cell and get out */
44 HvReleaseCell(Hive, Cell);
45 return TRUE;
46 }
47
48 /* Otherwise, mark it dirty and release it */
49 HvMarkCellDirty(Hive, Cell, FALSE);
50 HvReleaseCell(Hive, Cell);
51
52 /* Check if we have a class */
53 if (CellData->Class != HCELL_NIL)
54 {
55 /* Mark it dirty */
56 HvMarkCellDirty(Hive, CellData->Class, FALSE);
57 }
58
59 /* Check if we have security */
60 if (CellData->Security != HCELL_NIL)
61 {
62 /* Mark it dirty */
63 HvMarkCellDirty(Hive, CellData->Security, FALSE);
64
65 /* Get the security data and release it */
66 SecurityData = HvGetCell(Hive, CellData->Security);
67 if (!SecurityData) ASSERT(FALSE);
68 HvReleaseCell(Hive, CellData->Security);
69
70 /* Mark the security links dirty too */
71 HvMarkCellDirty(Hive, SecurityData->Flink, FALSE);
72 HvMarkCellDirty(Hive, SecurityData->Blink, FALSE);
73 }
74
75 // TODO: Handle predefined keys (Flags: KEY_PREDEF_HANDLE)
76 /* Check if we have any values */
77 if (CellData->ValueList.Count > 0)
78 {
79 /* Dirty the value list */
80 HvMarkCellDirty(Hive, CellData->ValueList.List, FALSE);
81
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);
86
87 /* Loop all values */
88 for (i = 0; i < CellData->ValueList.Count; i++)
89 {
90 /* Dirty each value */
91 HvMarkCellDirty(Hive, ListData->u.KeyList[i], FALSE);
92
93 /* Get the value data and release it */
94 ValueData = HvGetCell(Hive, ListData->u.KeyList[i]);
95 ASSERT(ValueData);
96 HvReleaseCell(Hive,ListData->u.KeyList[i]);
97
98 /* Mark the value data dirty too */
99 if (!CmpMarkValueDataDirty(Hive, &ValueData->u.KeyValue))
100 {
101 /* Failure */
102 return FALSE;
103 }
104 }
105 }
106
107 /* If this is an entry node, we're done */
108 if (CellData->Flags & KEY_HIVE_ENTRY) return TRUE;
109
110 /* Otherwise mark the index dirty too */
111 if (!CmpMarkIndexDirty(Hive, CellData->Parent, Cell))
112 {
113 /* Failure */
114 return FALSE;
115 }
116
117 /* Finally, mark the parent dirty */
118 HvMarkCellDirty(Hive, CellData->Parent, FALSE);
119 return TRUE;
120 }
121
122 BOOLEAN
123 NTAPI
124 CmpFreeKeyBody(IN PHHIVE Hive,
125 IN HCELL_INDEX Cell)
126 {
127 PCM_KEY_NODE CellData;
128
129 /* Get the key node */
130 CellData = HvGetCell(Hive, Cell);
131 if (!CellData) ASSERT(FALSE);
132
133 /* Check if we can delete the child cells */
134 if (!(CellData->Flags & KEY_HIVE_EXIT))
135 {
136 /* Check if we have a security cell */
137 if (CellData->Security != HCELL_NIL)
138 {
139 /* Free the security cell */
140 HvFreeCell(Hive, CellData->Security);
141 }
142
143 /* Check if we have a class */
144 if (CellData->ClassLength > 0)
145 {
146 /* Free it */
147 HvFreeCell(Hive, CellData->Class);
148 }
149 }
150
151 /* Release and free the cell */
152 HvReleaseCell(Hive, Cell);
153 HvFreeCell(Hive, Cell);
154 return TRUE;
155 }
156
157 NTSTATUS
158 NTAPI
159 CmpFreeKeyByCell(IN PHHIVE Hive,
160 IN HCELL_INDEX Cell,
161 IN BOOLEAN Unlink)
162 {
163 PCM_KEY_NODE CellData, ParentData;
164 PCELL_DATA ListData;
165 ULONG i;
166 BOOLEAN Result;
167
168 /* Mark the entire key dirty */
169 CmpMarkKeyDirty(Hive, Cell, TRUE);
170
171 /* Get the target node and release it */
172 CellData = HvGetCell(Hive, Cell);
173 if (!CellData) ASSERT(FALSE);
174 HvReleaseCell(Hive, Cell);
175
176 /* Make sure we don't have subkeys */
177 ASSERT(CellData->SubKeyCounts[Stable] + CellData->SubKeyCounts[Volatile] == 0);
178
179 /* Check if we have to unlink */
180 if (Unlink)
181 {
182 /* Remove the subkey */
183 Result = CmpRemoveSubKey(Hive, CellData->Parent, Cell);
184 if (!Result) return STATUS_INSUFFICIENT_RESOURCES;
185
186 /* Get the parent node and release it */
187 ParentData = HvGetCell(Hive, CellData->Parent);
188 if (!ParentData) ASSERT(FALSE);
189 HvReleaseCell(Hive, CellData->Parent);
190
191 /* Check if the parent node has no more subkeys */
192 if (ParentData->SubKeyCounts[Stable] + ParentData->SubKeyCounts[Volatile] == 0)
193 {
194 /* Then free the cached name/class lengths */
195 ParentData->MaxNameLen = 0;
196 ParentData->MaxClassLen = 0;
197 }
198 }
199
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))
203 {
204 /* Check if we have any values */
205 if (CellData->ValueList.Count > 0)
206 {
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);
211
212 /* Loop every value */
213 for (i = 0; i < CellData->ValueList.Count; i++)
214 {
215 /* Free it */
216 if (!CmpFreeValue(Hive, ListData->u.KeyList[i])) ASSERT(FALSE);
217 }
218
219 /* Free the value list */
220 HvFreeCell(Hive, CellData->ValueList.List);
221 }
222
223 /* Free the key security descriptor */
224 CmpFreeSecurityDescriptor(Hive, Cell);
225 }
226
227 /* Free the key body itself, and then return our status */
228 if (!CmpFreeKeyBody(Hive, Cell)) return STATUS_INSUFFICIENT_RESOURCES;
229 return STATUS_SUCCESS;
230 }