ReactOS 0.4.16-dev-250-g3ecd236
registry.c
Go to the documentation of this file.
1/*
2 * ReactOS kernel
3 * Copyright (C) 2006 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19/*
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS hive maker
22 * FILE: tools/mkhive/registry.c
23 * PURPOSE: Registry code
24 * PROGRAMMERS: Hervé Poussineau
25 * Hermès Bélusca-Maïto
26 */
27
28/* INCLUDES *****************************************************************/
29
30#define NDEBUG
31#include "mkhive.h"
32
33/* DATA *********************************************************************/
34
35typedef struct _REPARSE_POINT
36{
43
44typedef struct _MEMKEY
45{
46 /* Information on hard disk structure */
50
51#define HKEY_TO_MEMKEY(hKey) ((PMEMKEY)(hKey))
52#define MEMKEY_TO_HKEY(memKey) ((HKEY)(memKey))
53
56
57static CMHIVE SystemHive; /* \Registry\Machine\SYSTEM */
58static CMHIVE SoftwareHive; /* \Registry\Machine\SOFTWARE */
59static CMHIVE DefaultHive; /* \Registry\User\.DEFAULT */
60static CMHIVE SamHive; /* \Registry\Machine\SAM */
61static CMHIVE SecurityHive; /* \Registry\Machine\SECURITY */
62static CMHIVE BcdHive; /* \Registry\Machine\BCD00000000 */
63
64//
65// TODO: Write these values in a more human-readable form.
66// See http://amnesia.gtisc.gatech.edu/~moyix/suzibandit.ltd.uk/MSc/Registry%20Structure%20-%20Appendices%20V4.pdf
67// Appendix 12 "The Registry NT Security Descriptor" for more information.
68//
69// These SECURITY_DESCRIPTORs were obtained by dumping the security block "sk"
70// of registry hives created by setting their permissions to be the same as
71// the ones of the BCD, SOFTWARE, or SYSTEM, SAM and .DEFAULT system hives.
72// A cross-check was subsequently done with the system hives to verify that
73// the security descriptors were the same.
74//
76{
77 // SECURITY_DESCRIPTOR_RELATIVE
78 0x01, // Revision
79 0x00, // Sbz1
80 0x04, 0x94, // Control: SE_SELF_RELATIVE (0x8000) |
81 // SE_DACL_PROTECTED (0x1000) |
82 // SE_DACL_AUTO_INHERITED (0x0400) |
83 // SE_DACL_PRESENT (0x0004)
84 0x48, 0x00, 0x00, 0x00, // Owner
85 0x58, 0x00, 0x00, 0x00, // Group
86 0x00, 0x00, 0x00, 0x00, // Sacl (None)
87 0x14, 0x00, 0x00, 0x00, // Dacl
88
89 // DACL
90 0x02, // AclRevision
91 0x00, // Sbz1
92 0x34, 0x00, // AclSize
93 0x02, 0x00, // AceCount
94 0x00, 0x00, // Sbz2
95
96 // (1st ACE)
97 0x00, // AceType : ACCESS_ALLOWED_ACE_TYPE
98 0x02, // AceFlags: CONTAINER_INHERIT_ACE
99 0x18, 0x00, // AceSize
100 0x19, 0x00, 0x06, 0x00, // ACCESS_MASK: "Write DAC" (0x00040000) |
101 // "Read Control" (0x00020000) |
102 // "Notify" (0x00000010) |
103 // "Enumerate Subkeys" (0x00000008) |
104 // "Query Value" (0x00000001)
105 // (SidStart: S-1-5-32-544 "Administrators")
106 0x01, 0x02, 0x00, 0x00,
107 0x00, 0x00, 0x00, 0x05,
108 0x20, 0x00, 0x00, 0x00,
109 0x20, 0x02, 0x00, 0x00,
110
111 // (2nd ACE)
112 0x00, // AceType : ACCESS_ALLOWED_ACE_TYPE
113 0x02, // AceFlags: CONTAINER_INHERIT_ACE
114 0x14, 0x00, // AceSize
115 0x3F, 0x00, 0x0F, 0x00, // ACCESS_MASK: "Full Control" (0x000F003F)
116 // (SidStart: S-1-5-18 "Local System")
117 0x01, 0x01, 0x00, 0x00,
118 0x00, 0x00, 0x00, 0x05,
119 0x12, 0x00, 0x00, 0x00,
120
121 // Owner SID (S-1-5-32-544 "Administrators")
122 0x01, 0x02, 0x00, 0x00,
123 0x00, 0x00, 0x00, 0x05,
124 0x20, 0x00, 0x00, 0x00,
125 0x20, 0x02, 0x00, 0x00,
126
127 // Group SID (S-1-5-21-domain-513 "Domain Users")
128 0x01, 0x05, 0x00, 0x00,
129 0x00, 0x00, 0x00, 0x05,
130 0x15, 0x00, 0x00, 0x00,
131 0xAC, 0xD0, 0x49, 0xCB,
132 0xE6, 0x52, 0x47, 0x9C,
133 0xE4, 0x31, 0xDB, 0x5C,
134 0x01, 0x02, 0x00, 0x00
135};
136
138{
139 // SECURITY_DESCRIPTOR_RELATIVE
140 0x01, // Revision
141 0x00, // Sbz1
142 0x04, 0x94, // Control: SE_SELF_RELATIVE (0x8000) |
143 // SE_DACL_PROTECTED (0x1000) |
144 // SE_DACL_AUTO_INHERITED (0x0400) |
145 // SE_DACL_PRESENT (0x0004)
146 0xA0, 0x00, 0x00, 0x00, // Owner
147 0xB0, 0x00, 0x00, 0x00, // Group
148 0x00, 0x00, 0x00, 0x00, // Sacl (None)
149 0x14, 0x00, 0x00, 0x00, // Dacl
150
151 // DACL
152 0x02, // AclRevision
153 0x00, // Sbz1
154 0x8C, 0x00, // AclSize
155 0x06, 0x00, // AceCount
156 0x00, 0x00, // Sbz2
157
158 // (1st ACE)
159 0x00, // AceType : ACCESS_ALLOWED_ACE_TYPE
160 0x02, // AceFlags: CONTAINER_INHERIT_ACE
161 0x18, 0x00, // AceSize
162 0x3F, 0x00, 0x0F, 0x00, // ACCESS_MASK: "Full Control" (0x000F003F)
163 // (SidStart: S-1-5-32-544 "Administrators")
164 0x01, 0x02, 0x00, 0x00,
165 0x00, 0x00, 0x00, 0x05,
166 0x20, 0x00, 0x00, 0x00,
167 0x20, 0x02, 0x00, 0x00,
168
169 // (2nd ACE)
170 0x00, // AceType : ACCESS_ALLOWED_ACE_TYPE
171 0x0A, // AceFlags: INHERIT_ONLY_ACE | CONTAINER_INHERIT_ACE
172 0x14, 0x00, // AceSize
173 0x3F, 0x00, 0x0F, 0x00, // ACCESS_MASK: "Full Control" (0x000F003F)
174 // (SidStart: S-1-3-0 "Creator Owner")
175 0x01, 0x01, 0x00, 0x00,
176 0x00, 0x00, 0x00, 0x03,
177 0x00, 0x00, 0x00, 0x00,
178
179 // (3rd ACE)
180 0x00, // AceType : ACCESS_ALLOWED_ACE_TYPE
181 0x02, // AceFlags: CONTAINER_INHERIT_ACE
182 0x14, 0x00, // AceSize
183 0x3F, 0x00, 0x0F, 0x00, // ACCESS_MASK: "Full Control" (0x000F003F)
184 // (SidStart: S-1-5-18 "Local System")
185 0x01, 0x01, 0x00, 0x00,
186 0x00, 0x00, 0x00, 0x05,
187 0x12, 0x00, 0x00, 0x00,
188
189 // (4th ACE)
190 0x00, // AceType : ACCESS_ALLOWED_ACE_TYPE
191 0x02, // AceFlags: CONTAINER_INHERIT_ACE
192 0x14, 0x00, // AceSize
193 0x1F, 0x00, 0x03, 0x00, // ACCESS_MASK: "Read Control" (0x00020000) |
194 // "Delete" (0x00010000) |
195 // "Notify" (0x00000010) |
196 // "Enumerate Subkeys" (0x00000008) |
197 // "Create Subkey" (0x00000004) |
198 // "Set Value" (0x00000002) |
199 // "Query Value" (0x00000001)
200 // (SidStart: S-1-5-13 "Terminal Server Users")
201 0x01, 0x01, 0x00, 0x00,
202 0x00, 0x00, 0x00, 0x05,
203 0x0D, 0x00, 0x00, 0x00,
204
205 // (5th ACE)
206 0x00, // AceType : ACCESS_ALLOWED_ACE_TYPE
207 0x02, // AceFlags: CONTAINER_INHERIT_ACE
208 0x18, 0x00, // AceSize
209 0x19, 0x00, 0x02, 0x00, // ACCESS_MASK: "Read Control" (0x00020000) |
210 // "Notify" (0x00000010) |
211 // "Enumerate Subkeys" (0x00000008) |
212 // "Query Value" (0x00000001)
213 // (SidStart: S-1-5-32-545 "Users")
214 0x01, 0x02, 0x00, 0x00,
215 0x00, 0x00, 0x00, 0x05,
216 0x20, 0x00, 0x00, 0x00,
217 0x21, 0x02, 0x00, 0x00,
218
219 // (6th ACE)
220 0x00, // AceType : ACCESS_ALLOWED_ACE_TYPE
221 0x02, // AceFlags: CONTAINER_INHERIT_ACE
222 0x18, 0x00, // AceSize
223 0x1F, 0x00, 0x03, 0x00, // ACCESS_MASK: "Read Control" (0x00020000) |
224 // "Delete" (0x00010000) |
225 // "Notify" (0x00000010) |
226 // "Enumerate Subkeys" (0x00000008) |
227 // "Create Subkey" (0x00000004) |
228 // "Set Value" (0x00000002) |
229 // "Query Value" (0x00000001)
230 // (SidStart: S-1-5-32-547 "Power Users")
231 0x01, 0x02, 0x00, 0x00,
232 0x00, 0x00, 0x00, 0x05,
233 0x20, 0x00, 0x00, 0x00,
234 0x23, 0x02, 0x00, 0x00,
235
236 // Owner SID (S-1-5-32-544 "Administrators")
237 0x01, 0x02, 0x00, 0x00,
238 0x00, 0x00, 0x00, 0x05,
239 0x20, 0x00, 0x00, 0x00,
240 0x20, 0x02, 0x00, 0x00,
241
242 // Group SID (S-1-5-21-domain-513 "Domain Users")
243 0x01, 0x05, 0x00, 0x00,
244 0x00, 0x00, 0x00, 0x05,
245 0x15, 0x00, 0x00, 0x00,
246 0xAC, 0xD0, 0x49, 0xCB,
247 0xE6, 0x52, 0x47, 0x9C,
248 0xE4, 0x31, 0xDB, 0x5C,
249 0x01, 0x02, 0x00, 0x00
250};
251
252// Same security for SYSTEM, SAM and .DEFAULT
254{
255 // SECURITY_DESCRIPTOR_RELATIVE
256 0x01, // Revision
257 0x00, // Sbz1
258 0x04, 0x94, // Control: SE_SELF_RELATIVE (0x8000) |
259 // SE_DACL_PROTECTED (0x1000) |
260 // SE_DACL_AUTO_INHERITED (0x0400) |
261 // SE_DACL_PRESENT (0x0004)
262 0x8C, 0x00, 0x00, 0x00, // Owner
263 0x9C, 0x00, 0x00, 0x00, // Group
264 0x00, 0x00, 0x00, 0x00, // Sacl (None)
265 0x14, 0x00, 0x00, 0x00, // Dacl
266
267 // DACL
268 0x02, // AclRevision
269 0x00, // Sbz1
270 0x78, 0x00, // AclSize
271 0x05, 0x00, // AceCount
272 0x00, 0x00, // Sbz2
273
274 // (1st ACE)
275 0x00, // AceType : ACCESS_ALLOWED_ACE_TYPE
276 0x02, // AceFlags: CONTAINER_INHERIT_ACE
277 0x18, 0x00, // AceSize
278 0x3F, 0x00, 0x0F, 0x00, // ACCESS_MASK: "Full Control" (0x000F003F)
279 // (SidStart: S-1-5-32-544 "Administrators")
280 0x01, 0x02, 0x00, 0x00,
281 0x00, 0x00, 0x00, 0x05,
282 0x20, 0x00, 0x00, 0x00,
283 0x20, 0x02, 0x00, 0x00,
284
285 // (2nd ACE)
286 0x00, // AceType : ACCESS_ALLOWED_ACE_TYPE
287 0x0A, // AceFlags: INHERIT_ONLY_ACE | CONTAINER_INHERIT_ACE
288 0x14, 0x00, // AceSize
289 0x3F, 0x00, 0x0F, 0x00, // ACCESS_MASK: "Full Control" (0x000F003F)
290 // (SidStart: S-1-3-0 "Creator Owner")
291 0x01, 0x01, 0x00, 0x00,
292 0x00, 0x00, 0x00, 0x03,
293 0x00, 0x00, 0x00, 0x00,
294
295 // (3rd ACE)
296 0x00, // AceType : ACCESS_ALLOWED_ACE_TYPE
297 0x02, // AceFlags: CONTAINER_INHERIT_ACE
298 0x14, 0x00, // AceSize
299 0x3F, 0x00, 0x0F, 0x00, // ACCESS_MASK: "Full Control" (0x000F003F)
300 // (SidStart: S-1-5-18 "Local System")
301 0x01, 0x01, 0x00, 0x00,
302 0x00, 0x00, 0x00, 0x05,
303 0x12, 0x00, 0x00, 0x00,
304
305 // (4th ACE)
306 0x00, // AceType : ACCESS_ALLOWED_ACE_TYPE
307 0x02, // AceFlags: CONTAINER_INHERIT_ACE
308 0x18, 0x00, // AceSize
309 0x19, 0x00, 0x02, 0x00, // ACCESS_MASK: "Read Control" (0x00020000) |
310 // "Notify" (0x00000010) |
311 // "Enumerate Subkeys" (0x00000008) |
312 // "Query Value" (0x00000001)
313 // (SidStart: S-1-5-32-545 "Users")
314 0x01, 0x02, 0x00, 0x00,
315 0x00, 0x00, 0x00, 0x05,
316 0x20, 0x00, 0x00, 0x00,
317 0x21, 0x02, 0x00, 0x00,
318
319 // (5th ACE)
320 0x00, // AceType : ACCESS_ALLOWED_ACE_TYPE
321 0x02, // AceFlags: CONTAINER_INHERIT_ACE
322 0x18, 0x00, // AceSize
323 0x19, 0x00, 0x02, 0x00, // ACCESS_MASK: "Read Control" (0x00020000) |
324 // "Notify" (0x00000010) |
325 // "Enumerate Subkeys" (0x00000008) |
326 // "Query Value" (0x00000001)
327 // (SidStart: S-1-5-32-547 "Power Users")
328 0x01, 0x02, 0x00, 0x00,
329 0x00, 0x00, 0x00, 0x05,
330 0x20, 0x00, 0x00, 0x00,
331 0x23, 0x02, 0x00, 0x00,
332
333 // Owner SID (S-1-5-32-544 "Administrators")
334 0x01, 0x02, 0x00, 0x00,
335 0x00, 0x00, 0x00, 0x05,
336 0x20, 0x00, 0x00, 0x00,
337 0x20, 0x02, 0x00, 0x00,
338
339 // Group SID (S-1-5-21-domain-513 "Domain Users")
340 0x01, 0x05, 0x00, 0x00,
341 0x00, 0x00, 0x00, 0x05,
342 0x15, 0x00, 0x00, 0x00,
343 0xAC, 0xD0, 0x49, 0xCB,
344 0xE6, 0x52, 0x47, 0x9C,
345 0xE4, 0x31, 0xDB, 0x5C,
346 0x01, 0x02, 0x00, 0x00
347};
348
349/* GLOBALS ******************************************************************/
350
351HIVE_LIST_ENTRY RegistryHives[/*MAX_NUMBER_OF_REGISTRY_HIVES*/] =
352{
353 /* Special Setup system registry hive */
354 // WARNING: Please *keep* it in first position!
355 { "SETUPREG", L"Registry\\Machine\\SYSTEM" , &SystemHive , SystemSecurity , sizeof(SystemSecurity) },
356
357 /* Regular registry hives */
358 { "SYSTEM" , L"Registry\\Machine\\SYSTEM" , &SystemHive , SystemSecurity , sizeof(SystemSecurity) },
359 { "SOFTWARE", L"Registry\\Machine\\SOFTWARE" , &SoftwareHive, SoftwareSecurity, sizeof(SoftwareSecurity) },
360 { "DEFAULT" , L"Registry\\User\\.DEFAULT" , &DefaultHive , SystemSecurity , sizeof(SystemSecurity) },
361 { "SAM" , L"Registry\\Machine\\SAM" , &SamHive , SystemSecurity , sizeof(SystemSecurity) },
362 { "SECURITY", L"Registry\\Machine\\SECURITY" , &SecurityHive, NULL , 0 },
363 { "BCD" , L"Registry\\Machine\\BCD00000000", &BcdHive , BcdSecurity , sizeof(BcdSecurity) },
364};
366
367/* FUNCTIONS ****************************************************************/
368
369static PMEMKEY
371 IN PCMHIVE RegistryHive,
372 IN HCELL_INDEX KeyCellOffset)
373{
374 PMEMKEY Key;
375
376 Key = (PMEMKEY)malloc(sizeof(MEMKEY));
377 if (!Key)
378 return NULL;
379
380 Key->RegistryHive = RegistryHive;
381 Key->KeyCellOffset = KeyCellOffset;
382 return Key;
383}
384
387
388static LONG
390 IN HKEY hParentKey,
392 IN BOOL AllowCreation,
394 OUT PHKEY Key)
395{
397 PWSTR LocalKeyName;
398 PWSTR End;
399 UNICODE_STRING KeyString;
400 PREPARSE_POINT CurrentReparsePoint;
401 PMEMKEY CurrentKey;
402 PCMHIVE ParentRegistryHive;
403 HCELL_INDEX ParentCellOffset;
404 PCM_KEY_NODE ParentKeyCell;
407
408 DPRINT("RegpCreateOrOpenKey('%S')\n", KeyName);
409
411 {
412 KeyName++;
413 ParentRegistryHive = RootKey->RegistryHive;
414 ParentCellOffset = RootKey->KeyCellOffset;
415 }
416 else if (hParentKey == NULL)
417 {
418 ParentRegistryHive = RootKey->RegistryHive;
419 ParentCellOffset = RootKey->KeyCellOffset;
420 }
421 else
422 {
423 ParentRegistryHive = HKEY_TO_MEMKEY(hParentKey)->RegistryHive;
424 ParentCellOffset = HKEY_TO_MEMKEY(hParentKey)->KeyCellOffset;
425 }
426
427 LocalKeyName = (PWSTR)KeyName;
428 for (;;)
429 {
430 End = (PWSTR)strchrW(LocalKeyName, OBJ_NAME_PATH_SEPARATOR);
431 if (End)
432 {
433 KeyString.Buffer = LocalKeyName;
434 KeyString.Length = KeyString.MaximumLength =
435 (USHORT)((ULONG_PTR)End - (ULONG_PTR)LocalKeyName);
436 }
437 else
438 {
439 RtlInitUnicodeString(&KeyString, LocalKeyName);
440 if (KeyString.Length == 0)
441 {
442 /* Trailing path separator: we're done */
443 break;
444 }
445 }
446
447 ParentKeyCell = (PCM_KEY_NODE)HvGetCell(&ParentRegistryHive->Hive, ParentCellOffset);
448 if (!ParentKeyCell)
449 return ERROR_GEN_FAILURE; // STATUS_UNSUCCESSFUL;
450
451 VERIFY_KEY_CELL(ParentKeyCell);
452
453 BlockOffset = CmpFindSubKeyByName(&ParentRegistryHive->Hive, ParentKeyCell, &KeyString);
454 if (BlockOffset != HCELL_NIL)
455 {
457
458 /* Search for a possible reparse point */
460 while (Ptr != &CmiReparsePointsHead)
461 {
462 CurrentReparsePoint = CONTAINING_RECORD(Ptr, REPARSE_POINT, ListEntry);
463 if (CurrentReparsePoint->SourceHive == ParentRegistryHive &&
464 CurrentReparsePoint->SourceKeyCellOffset == BlockOffset)
465 {
466 ParentRegistryHive = CurrentReparsePoint->DestinationHive;
467 BlockOffset = CurrentReparsePoint->DestinationKeyCellOffset;
468 break;
469 }
470 Ptr = Ptr->Flink;
471 }
472 }
473 else if (AllowCreation) // && (BlockOffset == HCELL_NIL)
474 {
475 Status = CmiAddSubKey(ParentRegistryHive,
476 ParentCellOffset,
477 &KeyString,
478 Volatile,
479 &BlockOffset);
480 }
481 else // if (BlockOffset == HCELL_NIL)
482 {
484 }
485
486 HvReleaseCell(&ParentRegistryHive->Hive, ParentCellOffset);
487
488 if (!NT_SUCCESS(Status))
489 {
490 DPRINT("RegpCreateOrOpenKey('%S'): Could not create or open subkey '%.*S', Status 0x%08x\n",
491 KeyName, (int)(KeyString.Length / sizeof(WCHAR)), KeyString.Buffer, Status);
492 return ERROR_GEN_FAILURE; // STATUS_UNSUCCESSFUL;
493 }
494
495 ParentCellOffset = BlockOffset;
496 if (End)
497 LocalKeyName = End + 1;
498 else
499 break;
500 }
501
502 CurrentKey = CreateInMemoryStructure(ParentRegistryHive, ParentCellOffset);
503 if (!CurrentKey)
504 return ERROR_NOT_ENOUGH_MEMORY; // STATUS_NO_MEMORY;
505
506 *Key = MEMKEY_TO_HKEY(CurrentKey);
507
508 return ERROR_SUCCESS;
509}
510
513 IN HKEY hKey)
514{
515 PMEMKEY Key = HKEY_TO_MEMKEY(hKey); // ParentKey
516
517 /* Free the object */
518 free(Key);
519
520 return ERROR_SUCCESS;
521}
522
525 IN HKEY hKey,
526 IN LPCWSTR lpSubKey,
527 OUT PHKEY phkResult)
528{
529 return RegpCreateOrOpenKey(hKey, lpSubKey, TRUE, FALSE, phkResult);
530}
531
534 IN HKEY hKey,
535 IN LPCWSTR lpSubKey,
537 IN LPWSTR lpClass OPTIONAL,
539 IN REGSAM samDesired,
540 IN LPSECURITY_ATTRIBUTES lpSecurityAttributes OPTIONAL,
541 OUT PHKEY phkResult,
542 OUT LPDWORD lpdwDisposition OPTIONAL)
543{
545 lpSubKey,
546 TRUE,
548 phkResult);
549}
550
553 IN HKEY hKey,
554 IN LPCWSTR lpSubKey)
555{
556 LONG rc;
558 HKEY hTargetKey;
559 PMEMKEY Key; // ParentKey
560 PHHIVE Hive;
561 PCM_KEY_NODE KeyNode; // ParentNode
563 HCELL_INDEX ParentCell;
564
565 if (lpSubKey)
566 {
567 rc = RegOpenKeyW(hKey, lpSubKey, &hTargetKey);
568 if (rc != ERROR_SUCCESS)
569 return rc;
570 }
571 else
572 {
573 hTargetKey = hKey;
574 rc = ERROR_SUCCESS;
575 }
576
577 /* Don't allow deleting the root */
578 if (hTargetKey == RootKey)
579 {
580 /* Fail */
581 rc = ERROR_ACCESS_DENIED; // STATUS_CANNOT_DELETE;
582 goto Quit;
583 }
584
585 /* Get the hive and node */
586 Key = HKEY_TO_MEMKEY(hTargetKey);
587 Hive = &Key->RegistryHive->Hive;
588
589 /* Get the key node */
590 KeyNode = (PCM_KEY_NODE)HvGetCell(Hive, Key->KeyCellOffset);
591 if (!KeyNode)
592 {
593 rc = ERROR_GEN_FAILURE; // STATUS_UNSUCCESSFUL;
594 goto Quit;
595 }
596
598
599 /* Check if we don't have any children */
600 if (!(KeyNode->SubKeyCounts[Stable] + KeyNode->SubKeyCounts[Volatile]) &&
601 !(KeyNode->Flags & KEY_NO_DELETE))
602 {
603 /* Get the parent and free the cell */
604 ParentCell = KeyNode->Parent;
605 Status = CmpFreeKeyByCell(Hive, Key->KeyCellOffset, TRUE);
606 if (NT_SUCCESS(Status))
607 {
608 /* Get the parent node */
609 Parent = (PCM_KEY_NODE)HvGetCell(Hive, ParentCell);
610 if (Parent)
611 {
612 /* Make sure we're dirty */
613 ASSERT(HvIsCellDirty(Hive, ParentCell));
614
615 /* Update the write time */
616 KeQuerySystemTime(&Parent->LastWriteTime);
617
618 /* Release the cell */
619 HvReleaseCell(Hive, ParentCell);
620 }
621
622 rc = ERROR_SUCCESS;
623 }
624 else
625 {
626 /* Fail */
627 rc = ERROR_GEN_FAILURE; // STATUS_UNSUCCESSFUL;
628 }
629 }
630 else
631 {
632 /* Fail */
633 rc = ERROR_ACCESS_DENIED; // STATUS_CANNOT_DELETE;
634 }
635
636 /* Release the cell */
637 HvReleaseCell(Hive, Key->KeyCellOffset);
638
639Quit:
640 if (lpSubKey)
641 RegCloseKey(hTargetKey);
642
643 return rc;
644}
645
648 IN HKEY hKey,
649 IN LPCWSTR lpSubKey,
650 OUT PHKEY phkResult)
651{
652 return RegpCreateOrOpenKey(hKey, lpSubKey, FALSE, FALSE, phkResult);
653}
654
657 IN HKEY hKey,
658 IN LPCWSTR lpValueName OPTIONAL,
660 IN ULONG dwType,
661 IN const UCHAR* lpData,
662 IN ULONG cbData)
663{
664 PMEMKEY Key = HKEY_TO_MEMKEY(hKey); // ParentKey
665 PHHIVE Hive;
666 PCM_KEY_NODE KeyNode; // ParentNode
667 PCM_KEY_VALUE ValueCell;
668 ULONG ChildIndex;
669 HCELL_INDEX CellIndex;
670 UNICODE_STRING ValueNameString;
671
672 PVOID DataCell;
673 ULONG DataCellSize;
675
676 if (dwType == REG_LINK)
677 {
678 PMEMKEY DestKey;
679
680 /* Special handling of registry links */
681 if (cbData != sizeof(PVOID))
682 return ERROR_INVALID_PARAMETER; // STATUS_INVALID_PARAMETER;
683
684 DestKey = HKEY_TO_MEMKEY(*(PHKEY)lpData);
685
686 // FIXME: Add additional checks for the validity of DestKey
687
688 /* Create the link in registry hive (if applicable) */
689 if (Key->RegistryHive != DestKey->RegistryHive)
690 return ERROR_SUCCESS;
691
692 DPRINT1("Save link to registry\n");
693 return ERROR_INVALID_FUNCTION; // STATUS_NOT_IMPLEMENTED;
694 }
695
696 if ((cbData & ~CM_KEY_VALUE_SPECIAL_SIZE) != cbData)
697 return ERROR_GEN_FAILURE; // STATUS_UNSUCCESSFUL;
698
699 Hive = &Key->RegistryHive->Hive;
700
701 KeyNode = (PCM_KEY_NODE)HvGetCell(Hive, Key->KeyCellOffset);
702 if (!KeyNode)
703 return ERROR_GEN_FAILURE; // STATUS_UNSUCCESSFUL;
704
706
707 /* Mark the parent as dirty since we are going to create a new value in it */
708 HvMarkCellDirty(Hive, Key->KeyCellOffset, FALSE);
709
710 /* Initialize value name string */
711 RtlInitUnicodeString(&ValueNameString, lpValueName);
712 if (!CmpFindNameInList(Hive,
713 &KeyNode->ValueList,
714 &ValueNameString,
715 &ChildIndex,
716 &CellIndex))
717 {
718 /* Sanity check */
719 ASSERT(CellIndex == HCELL_NIL);
720 /* Fail */
722 }
723 if (CellIndex == HCELL_NIL)
724 {
725 /* The value doesn't exist, create a new one */
726 Status = CmiAddValueKey(Key->RegistryHive,
727 KeyNode,
728 ChildIndex,
729 &ValueNameString,
730 &ValueCell,
731 &CellIndex);
732 }
733 else
734 {
735 /* The value already exists, use it. Get the value cell. */
736 ValueCell = (PCM_KEY_VALUE)HvGetCell(&Key->RegistryHive->Hive, CellIndex);
737 ASSERT(ValueCell != NULL);
739 }
740
741 // /**/HvReleaseCell(Hive, CellIndex);/**/
742
743 if (!NT_SUCCESS(Status))
744 return ERROR_GEN_FAILURE; // STATUS_UNSUCCESSFUL;
745
746 /* Get size of the allocated cell (if any) */
747 if (!(ValueCell->DataLength & CM_KEY_VALUE_SPECIAL_SIZE) &&
748 (ValueCell->DataLength & ~CM_KEY_VALUE_SPECIAL_SIZE) != 0)
749 {
750 DataCell = HvGetCell(Hive, ValueCell->Data);
751 if (!DataCell)
752 return ERROR_GEN_FAILURE; // STATUS_UNSUCCESSFUL;
753
754 DataCellSize = (ULONG)(-HvGetCellSize(Hive, DataCell));
755 }
756 else
757 {
758 DataCell = NULL;
759 DataCellSize = 0;
760 }
761
762 if (cbData <= sizeof(HCELL_INDEX))
763 {
764 /* If data size <= sizeof(HCELL_INDEX) then store data in the data offset */
765 DPRINT("ValueCell->DataLength %u\n", ValueCell->DataLength);
766 if (DataCell)
767 HvFreeCell(Hive, ValueCell->Data);
768
769 RtlCopyMemory(&ValueCell->Data, lpData, cbData);
770 ValueCell->DataLength = (cbData | CM_KEY_VALUE_SPECIAL_SIZE);
771 ValueCell->Type = dwType;
772 }
773 else
774 {
775 if (cbData > DataCellSize)
776 {
777 /* New data size is larger than the current, destroy current
778 * data block and allocate a new one. */
779 HCELL_INDEX NewOffset;
780
781 DPRINT("ValueCell->DataLength %u\n", ValueCell->DataLength);
782
783 NewOffset = HvAllocateCell(Hive, cbData, Stable, HCELL_NIL);
784 if (NewOffset == HCELL_NIL)
785 {
786 DPRINT("HvAllocateCell() has failed!\n");
787 return ERROR_GEN_FAILURE; // STATUS_UNSUCCESSFUL;
788 }
789
790 if (DataCell)
791 HvFreeCell(Hive, ValueCell->Data);
792
793 ValueCell->Data = NewOffset;
794 DataCell = (PVOID)HvGetCell(Hive, NewOffset);
795 }
796
797 /* Copy new contents to cell */
798 RtlCopyMemory(DataCell, lpData, cbData);
799 ValueCell->DataLength = (cbData & ~CM_KEY_VALUE_SPECIAL_SIZE);
800 ValueCell->Type = dwType;
801 HvMarkCellDirty(Hive, ValueCell->Data, FALSE);
802 }
803
804 HvMarkCellDirty(Hive, CellIndex, FALSE);
805
806 /* Check if the maximum value name length changed, update it if so */
807 if (KeyNode->MaxValueNameLen < ValueNameString.Length)
808 KeyNode->MaxValueNameLen = ValueNameString.Length;
809
810 /* Check if the maximum data length changed, update it if so */
811 if (KeyNode->MaxValueDataLen < cbData)
812 KeyNode->MaxValueDataLen = cbData;
813
814 /* Save the write time */
816
817 return ERROR_SUCCESS;
818}
819
820
821// Synced with freeldr/ntldr/registry.c
822static
823VOID
825 IN PHHIVE Hive,
826 IN PCM_KEY_VALUE ValueCell,
830{
832 PVOID DataCell;
833
834 /* Does the caller want the type? */
835 if (Type != NULL)
836 *Type = ValueCell->Type;
837
838 /* Does the caller provide DataSize? */
839 if (DataSize != NULL)
840 {
841 // NOTE: CmpValueToData doesn't support big data (the function will
842 // bugcheck if so), FreeLdr is not supposed to read such data.
843 // If big data is needed, use instead CmpGetValueData.
844 // CmpGetValueData(Hive, ValueCell, DataSize, &DataCell, ...);
845 DataCell = CmpValueToData(Hive, ValueCell, &DataLength);
846
847 /* Does the caller want the data? */
848 if ((Data != NULL) && (*DataSize != 0))
849 {
851 DataCell,
853 }
854
855 /* Return the actual data length */
857 }
858}
859
860// Similar to RegQueryValue in freeldr/ntldr/registry.c
863 IN HKEY hKey,
864 IN LPCWSTR lpValueName,
865 IN PULONG lpReserved,
866 OUT PULONG lpType OPTIONAL,
867 OUT PUCHAR lpData OPTIONAL,
868 IN OUT PULONG lpcbData OPTIONAL)
869{
871 PHHIVE Hive = &ParentKey->RegistryHive->Hive;
872 PCM_KEY_NODE KeyNode;
873 PCM_KEY_VALUE ValueCell;
874 HCELL_INDEX CellIndex;
875 UNICODE_STRING ValueNameString;
876
877 KeyNode = (PCM_KEY_NODE)HvGetCell(Hive, ParentKey->KeyCellOffset);
878 if (!KeyNode)
879 return ERROR_GEN_FAILURE; // STATUS_UNSUCCESSFUL;
880
882
883 /* Initialize value name string */
884 RtlInitUnicodeString(&ValueNameString, lpValueName);
885 CellIndex = CmpFindValueByName(Hive, KeyNode, &ValueNameString);
886 if (CellIndex == HCELL_NIL)
887 return ERROR_FILE_NOT_FOUND; // STATUS_OBJECT_NAME_NOT_FOUND;
888
889 /* Get the value cell */
890 ValueCell = (PCM_KEY_VALUE)HvGetCell(Hive, CellIndex);
891 ASSERT(ValueCell != NULL);
892
893 RepGetValueData(Hive, ValueCell, lpType, lpData, lpcbData);
894
895 HvReleaseCell(Hive, CellIndex);
896
897 return ERROR_SUCCESS;
898}
899
902 IN HKEY hKey,
903 IN LPCWSTR lpValueName OPTIONAL)
904{
905 LONG rc;
907 PMEMKEY Key = HKEY_TO_MEMKEY(hKey); // ParentKey
908 PHHIVE Hive = &Key->RegistryHive->Hive;
909 PCM_KEY_NODE KeyNode; // ParentNode
910 PCM_KEY_VALUE ValueCell;
911 HCELL_INDEX CellIndex;
912 ULONG ChildIndex;
913 UNICODE_STRING ValueNameString;
914
915 KeyNode = (PCM_KEY_NODE)HvGetCell(Hive, Key->KeyCellOffset);
916 if (!KeyNode)
917 return ERROR_GEN_FAILURE; // STATUS_UNSUCCESSFUL;
918
920
921 /* Initialize value name string */
922 RtlInitUnicodeString(&ValueNameString, lpValueName);
923 if (!CmpFindNameInList(Hive,
924 &KeyNode->ValueList,
925 &ValueNameString,
926 &ChildIndex,
927 &CellIndex))
928 {
929 /* Sanity check */
930 ASSERT(CellIndex == HCELL_NIL);
931 }
932 if (CellIndex == HCELL_NIL)
933 {
934 rc = ERROR_FILE_NOT_FOUND; // STATUS_OBJECT_NAME_NOT_FOUND;
935 goto Quit;
936 }
937
938 /* We found the value, mark all relevant cells dirty */
939 HvMarkCellDirty(Hive, Key->KeyCellOffset, FALSE);
940 HvMarkCellDirty(Hive, KeyNode->ValueList.List, FALSE);
941 HvMarkCellDirty(Hive, CellIndex, FALSE);
942
943 /* Get the key value */
944 ValueCell = (PCM_KEY_VALUE)HvGetCell(Hive, CellIndex);
945 ASSERT(ValueCell);
946
947 /* Mark it and all related data as dirty */
948 if (!CmpMarkValueDataDirty(Hive, ValueCell))
949 {
950 /* Not enough log space, fail */
951 rc = ERROR_NO_LOG_SPACE; // STATUS_NO_LOG_SPACE;
952 goto Quit;
953 }
954
955 /* Sanity checks */
956 ASSERT(HvIsCellDirty(Hive, KeyNode->ValueList.List));
957 ASSERT(HvIsCellDirty(Hive, CellIndex));
958
959 /* Remove the value from the child list */
960 Status = CmpRemoveValueFromList(Hive, ChildIndex, &KeyNode->ValueList);
961 if (!NT_SUCCESS(Status))
962 {
963 /* Set known error */
964 rc = ERROR_NO_SYSTEM_RESOURCES; // STATUS_INSUFFICIENT_RESOURCES;
965 goto Quit;
966 }
967
968 /* Remove the value and its data itself */
969 if (!CmpFreeValue(Hive, CellIndex))
970 {
971 /* Failed to free the value, fail */
972 rc = ERROR_NO_SYSTEM_RESOURCES; // STATUS_INSUFFICIENT_RESOURCES;
973 goto Quit;
974 }
975
976 /* Set the last write time */
978
979 /* Sanity check */
980 ASSERT(HvIsCellDirty(Hive, Key->KeyCellOffset));
981
982 /* Check if the value list is empty now */
983 if (!KeyNode->ValueList.Count)
984 {
985 /* Then clear key node data */
986 KeyNode->MaxValueNameLen = 0;
987 KeyNode->MaxValueDataLen = 0;
988 }
989
990 /* Change default Status to success */
991 rc = ERROR_SUCCESS;
992
993Quit:
994 /* Check if we had a value */
995 if (ValueCell)
996 {
997 /* Release the child cell */
998 ASSERT(CellIndex != HCELL_NIL);
999 HvReleaseCell(Hive, CellIndex);
1000 }
1001
1002 /* Release the parent cell, if any */
1003 if (KeyNode)
1004 HvReleaseCell(Hive, Key->KeyCellOffset);
1005
1006 return rc;
1007}
1008
1009
1010static BOOL
1012 IN HKEY RootKey,
1013 IN PCWSTR Path,
1014 IN PCMHIVE HiveToConnect,
1017{
1019 LONG rc;
1020 PREPARSE_POINT ReparsePoint;
1021 PMEMKEY NewKey;
1022
1023 ReparsePoint = (PREPARSE_POINT)malloc(sizeof(*ReparsePoint));
1024 if (!ReparsePoint)
1025 return FALSE;
1026
1027 /*
1028 * Use a dummy root key name:
1029 * - On 2k/XP/2k3, this is "$$$PROTO.HIV"
1030 * - On Vista+, this is "CMI-CreateHive{guid}"
1031 * See https://github.com/libyal/winreg-kb/blob/master/documentation/Registry%20files.asciidoc
1032 * for more information.
1033 */
1034 Status = CmiInitializeHive(HiveToConnect, L"$$$PROTO.HIV");
1035 if (!NT_SUCCESS(Status))
1036 {
1037 DPRINT1("CmiInitializeHive() failed with status 0x%08x\n", Status);
1038 free(ReparsePoint);
1039 return FALSE;
1040 }
1041
1042 /*
1043 * Add security to the root key.
1044 * NOTE: One can implement this using the lpSecurityAttributes
1045 * parameter of RegCreateKeyExW.
1046 */
1047 Status = CmiCreateSecurityKey(&HiveToConnect->Hive,
1048 HiveToConnect->Hive.BaseBlock->RootCell,
1050 if (!NT_SUCCESS(Status))
1051 DPRINT1("Failed to add security for root key '%S'\n", Path);
1052
1053 /* Create the key */
1055 Path,
1056 0,
1057 NULL,
1059 0,
1060 NULL,
1061 (PHKEY)&NewKey,
1062 NULL);
1063 if (rc != ERROR_SUCCESS)
1064 {
1065 free(ReparsePoint);
1066 return FALSE;
1067 }
1068
1069 ReparsePoint->SourceHive = NewKey->RegistryHive;
1070 ReparsePoint->SourceKeyCellOffset = NewKey->KeyCellOffset;
1071 NewKey->RegistryHive = HiveToConnect;
1072 NewKey->KeyCellOffset = HiveToConnect->Hive.BaseBlock->RootCell;
1073 ReparsePoint->DestinationHive = NewKey->RegistryHive;
1074 ReparsePoint->DestinationKeyCellOffset = NewKey->KeyCellOffset;
1076
1077 return TRUE;
1078}
1079
1080static BOOL
1082 IN PCWSTR LinkKeyPath OPTIONAL,
1083 IN OUT PHKEY LinkKeyHandle OPTIONAL,
1084 // IN PCWSTR TargetKeyPath OPTIONAL,
1085 IN HKEY TargetKeyHandle)
1086{
1087 LONG rc;
1088 PMEMKEY LinkKey, TargetKey;
1089 PREPARSE_POINT ReparsePoint;
1090
1091 ReparsePoint = (PREPARSE_POINT)malloc(sizeof(*ReparsePoint));
1092 if (!ReparsePoint)
1093 return FALSE;
1094
1095 if (LinkKeyPath && !(LinkKeyHandle && *LinkKeyHandle))
1096 {
1097 /* Create the link key */
1098 rc = RegCreateKeyExW(NULL,
1099 LinkKeyPath,
1100 0,
1101 NULL,
1103 0,
1104 NULL,
1105 (PHKEY)&LinkKey,
1106 NULL);
1107 if (rc != ERROR_SUCCESS)
1108 {
1109 free(ReparsePoint);
1110 return FALSE;
1111 }
1112 }
1113 else if (LinkKeyHandle)
1114 {
1115 /* Use the user-provided link key handle */
1116 LinkKey = HKEY_TO_MEMKEY(*LinkKeyHandle);
1117 }
1118
1119 if (LinkKeyHandle)
1120 *LinkKeyHandle = MEMKEY_TO_HKEY(LinkKey);
1121
1122 TargetKey = HKEY_TO_MEMKEY(TargetKeyHandle);
1123
1124 ReparsePoint->SourceHive = LinkKey->RegistryHive;
1125 ReparsePoint->SourceKeyCellOffset = LinkKey->KeyCellOffset;
1126 ReparsePoint->DestinationHive = TargetKey->RegistryHive;
1127 ReparsePoint->DestinationKeyCellOffset = TargetKey->KeyCellOffset;
1129
1130 return TRUE;
1131}
1132
1133VOID
1135 IN PCSTR HiveList)
1136{
1138 UINT i;
1139 HKEY ControlSetKey;
1140
1143
1145 if (!NT_SUCCESS(Status))
1146 {
1147 DPRINT1("CmiInitializeHive() failed with status 0x%08x\n", Status);
1148 return;
1149 }
1150
1153
1154 for (i = 0; i < _countof(RegistryHives); ++i)
1155 {
1156 /* Skip this registry hive if it's not in the list */
1157 if (!strstr(HiveList, RegistryHives[i].HiveName))
1158 continue;
1159
1160 /* Create the registry key */
1162 RegistryHives[i].HiveRegistryPath,
1163 RegistryHives[i].CmHive,
1166
1167 /* If we happen to deal with the special setup registry hive, stop there */
1168 // if (strcmp(RegistryHives[i].HiveName, "SETUPREG") == 0)
1169 if (i == 0)
1170 break;
1171 }
1172
1173 /* Create the 'ControlSet001' key */
1175 L"Registry\\Machine\\SYSTEM\\ControlSet001",
1176 &ControlSetKey);
1177
1178 /* Create the 'CurrentControlSet' key as a symlink to 'ControlSet001' */
1179 CreateSymLink(L"Registry\\Machine\\SYSTEM\\CurrentControlSet",
1180 NULL, ControlSetKey);
1181
1182 RegCloseKey(ControlSetKey);
1183
1184#if 0
1185 /* Link SECURITY to SAM */
1186 CmpLinkKeyToHive(L"\\Registry\\Machine\\Security\\SAM", L"\\Registry\\Machine\\SAM\\SAM");
1187 /* Link S-1-5-18 to .Default */
1188 CmpLinkKeyToHive(L"\\Registry\\User\\S-1-5-18", L"\\Registry\\User\\.Default");
1189#endif
1190}
1191
1192VOID
1194{
1196 PREPARSE_POINT ReparsePoint;
1197
1198 /* Clean up the reparse points list */
1200 {
1202 ReparsePoint = CONTAINING_RECORD(Entry, REPARSE_POINT, ListEntry);
1203 free(ReparsePoint);
1204 }
1205
1206 /* FIXME: clean up the complete hive */
1207
1208 free(RootKey);
1209}
1210
1211/* EOF */
PRTL_UNICODE_STRING_BUFFER Path
Type
Definition: Type.h:7
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn UINT32 *TableIdx UINT32 ACPI_TABLE_HEADER *OutTableHeader ACPI_TABLE_HEADER **OutTable ACPI_HANDLE UINT32 ACPI_WALK_CALLBACK ACPI_WALK_CALLBACK void void **ReturnValue UINT32 ACPI_BUFFER *RetPathPtr ACPI_OBJECT_HANDLER void *Data ACPI_OBJECT_HANDLER void **Data ACPI_STRING ACPI_OBJECT_LIST ACPI_BUFFER *ReturnObjectBuffer ACPI_DEVICE_INFO **ReturnBuffer ACPI_HANDLE Parent
Definition: acpixf.h:732
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
HIVE_LIST_ENTRY RegistryHives[]
Definition: registry.c:581
NTSTATUS RegInitializeRegistry(IN PUNICODE_STRING NtSystemRoot)
Definition: registry.c:679
static VOID RepGetValueData(_In_ PHHIVE Hive, _In_ PCM_KEY_VALUE ValueCell, _Out_opt_ PULONG Type, _Out_opt_ PUCHAR Data, _Inout_opt_ PULONG DataSize)
Definition: registry.c:794
PHHIVE SystemHive
Definition: registry.c:33
#define RegCloseKey(hKey)
Definition: registry.h:49
#define BlockOffset(V, L)
Definition: cdprocs.h:1650
_In_ ULONG _In_opt_ WDFREQUEST _In_opt_ PVOID _In_ size_t _In_ PVOID _In_ size_t _Out_ size_t * DataLength
Definition: cdrom.h:1444
struct _CM_KEY_NODE * PCM_KEY_NODE
struct _CM_KEY_VALUE * PCM_KEY_VALUE
#define KEY_NO_DELETE
Definition: cmdata.h:33
#define CM_KEY_VALUE_SPECIAL_SIZE
Definition: cmdata.h:51
#define CM_KEY_NODE_SIGNATURE
Definition: cmdata.h:21
NTSTATUS CmiAddValueKey(IN PCMHIVE RegistryHive, IN PCM_KEY_NODE Parent, IN ULONG ChildIndex, IN PCUNICODE_STRING ValueName, OUT PCM_KEY_VALUE *pValueCell, OUT HCELL_INDEX *pValueCellOffset)
Definition: cmi.c:348
NTSTATUS CmiCreateSecurityKey(IN PHHIVE Hive, IN HCELL_INDEX Cell, IN PUCHAR Descriptor, IN ULONG DescriptorLength)
Definition: cmi.c:157
NTSTATUS CmiAddSubKey(IN PCMHIVE RegistryHive, IN HCELL_INDEX ParentKeyCellOffset, IN PCUNICODE_STRING SubKeyName, IN BOOLEAN VolatileKey, OUT HCELL_INDEX *pBlockOffset)
Definition: cmi.c:297
NTSTATUS CmiInitializeHive(IN OUT PCMHIVE Hive, IN PCWSTR Name)
Definition: cmi.c:114
#define VERIFY_KEY_CELL(key)
Definition: cmi.h:29
HCELL_INDEX NTAPI CmpFindSubKeyByName(IN PHHIVE Hive, IN PCM_KEY_NODE Parent, IN PCUNICODE_STRING SearchName)
Definition: cmindex.c:683
NTSTATUS NTAPI CmpFreeKeyByCell(IN PHHIVE Hive, IN HCELL_INDEX Cell, IN BOOLEAN Unlink)
Definition: cmkeydel.c:159
#define HvReleaseCell(Hive, Cell)
Definition: cmlib.h:460
BOOLEAN NTAPI CmpMarkValueDataDirty(IN PHHIVE Hive, IN PCM_KEY_VALUE Value)
Definition: cmvalue.c:19
BOOLEAN NTAPI CmpFreeValue(IN PHHIVE Hive, IN HCELL_INDEX Cell)
Definition: cmvalue.c:73
NTSTATUS NTAPI CmpRemoveValueFromList(IN PHHIVE Hive, IN ULONG Index, IN OUT PCHILD_LIST ChildList)
Definition: cmvalue.c:320
BOOLEAN CMAPI HvIsCellDirty(IN PHHIVE Hive, IN HCELL_INDEX Cell)
Definition: hivecell.c:153
HCELL_INDEX NTAPI CmpFindValueByName(IN PHHIVE Hive, IN PCM_KEY_NODE KeyNode, IN PCUNICODE_STRING Name)
Definition: cmvalue.c:99
PCELL_DATA NTAPI CmpValueToData(IN PHHIVE Hive, IN PCM_KEY_VALUE Value, OUT PULONG Length)
Definition: cmvalue.c:167
VOID CMAPI HvFreeCell(PHHIVE RegistryHive, HCELL_INDEX CellOffset)
Definition: hivecell.c:468
LONG CMAPI HvGetCellSize(PHHIVE RegistryHive, PVOID Cell)
BOOLEAN CMAPI HvMarkCellDirty(PHHIVE RegistryHive, HCELL_INDEX CellOffset, BOOLEAN HoldingLock)
Definition: hivecell.c:109
#define HvGetCell(Hive, Cell)
Definition: cmlib.h:457
HCELL_INDEX CMAPI HvAllocateCell(PHHIVE RegistryHive, ULONG Size, HSTORAGE_TYPE Storage, IN HCELL_INDEX Vicinity)
BOOLEAN NTAPI CmpFindNameInList(IN PHHIVE Hive, IN PCHILD_LIST ChildList, IN PCUNICODE_STRING Name, OUT PULONG ChildIndex OPTIONAL, OUT PHCELL_INDEX CellIndex)
Definition: cmname.c:149
BOOLEAN NTAPI CmpLinkKeyToHive(_In_z_ PCWSTR LinkKeyName, _In_z_ PCWSTR TargetKeyName)
Definition: cmsysini.c:45
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define ERROR_INVALID_FUNCTION
Definition: dderror.h:6
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
LONG WINAPI RegCreateKeyExW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey, _In_ DWORD Reserved, _In_opt_ LPWSTR lpClass, _In_ DWORD dwOptions, _In_ REGSAM samDesired, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _Out_ PHKEY phkResult, _Out_opt_ LPDWORD lpdwDisposition)
Definition: reg.c:1096
LONG WINAPI RegOpenKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3268
LONG WINAPI RegSetValueExW(_In_ HKEY hKey, _In_ LPCWSTR lpValueName, _In_ DWORD Reserved, _In_ DWORD dwType, _In_ CONST BYTE *lpData, _In_ DWORD cbData)
Definition: reg.c:4882
LONG WINAPI RegDeleteKeyW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey)
Definition: reg.c:1239
LONG WINAPI RegDeleteValueW(HKEY hKey, LPCWSTR lpValueName)
Definition: reg.c:2330
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4103
LONG WINAPI RegCreateKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:1201
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
#define ULONG_PTR
Definition: config.h:101
#define InsertTailList(ListHead, Entry)
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
FxAutoRegKey hKey
Status
Definition: gdiplustypes.h:25
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
@ Volatile
Definition: hivedata.h:128
@ Stable
Definition: hivedata.h:127
#define HCELL_NIL
Definition: hivedata.h:110
ULONG HCELL_INDEX
Definition: hivedata.h:105
#define C_ASSERT(e)
Definition: intsafe.h:73
#define ASSERT(a)
Definition: mode.c:44
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
#define min(a, b)
Definition: monoChain.cc:55
_In_ NDIS_STATUS _In_ ULONG _In_ USHORT _In_opt_ PVOID _In_ ULONG DataSize
Definition: ndis.h:4755
unsigned int UINT
Definition: ndis.h:50
_In_ ULONG SecurityDescriptorLength
Definition: rtlfuncs.h:1726
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define REG_LINK
Definition: nt_native.h:1500
#define REG_OPTION_VOLATILE
Definition: nt_native.h:1060
#define L(x)
Definition: ntvdm.h:50
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
#define strchrW(s, c)
Definition: unicode.h:40
NTSTATUS ConnectRegistry(IN HANDLE RootKey OPTIONAL, IN PCWSTR RegMountPoint, IN PUNICODE_STRING NtSystemRoot, IN PCWSTR RegistryKey)
Definition: regutil.c:391
LIST_ENTRY CmiHiveListHead
Definition: registry.c:385
static CMHIVE SamHive
Definition: registry.c:60
struct _MEMKEY MEMKEY
struct _REPARSE_POINT REPARSE_POINT
static PMEMKEY RootKey
Definition: registry.c:55
struct _MEMKEY * PMEMKEY
static CMHIVE BcdHive
Definition: registry.c:62
static CMHIVE RootHive
Definition: registry.c:54
static CMHIVE DefaultHive
Definition: registry.c:59
static UCHAR SystemSecurity[]
Definition: registry.c:253
LIST_ENTRY CmiReparsePointsHead
Definition: registry.c:386
struct _REPARSE_POINT * PREPARSE_POINT
static UCHAR BcdSecurity[]
Definition: registry.c:75
#define HKEY_TO_MEMKEY(hKey)
Definition: registry.c:51
VOID RegShutdownRegistry(VOID)
Definition: registry.c:1193
#define MEMKEY_TO_HKEY(memKey)
Definition: registry.c:52
static LONG RegpCreateOrOpenKey(IN HKEY hParentKey, IN PCWSTR KeyName, IN BOOL AllowCreation, IN BOOL Volatile, OUT PHKEY Key)
Definition: registry.c:389
static UCHAR SoftwareSecurity[]
Definition: registry.c:137
static BOOL CreateSymLink(IN PCWSTR LinkKeyPath OPTIONAL, IN OUT PHKEY LinkKeyHandle OPTIONAL, IN HKEY TargetKeyHandle)
Definition: registry.c:1081
static CMHIVE SecurityHive
Definition: registry.c:61
static CMHIVE SoftwareHive
Definition: registry.c:58
static PMEMKEY CreateInMemoryStructure(IN PCMHIVE RegistryHive, IN HCELL_INDEX KeyCellOffset)
Definition: registry.c:370
#define MAX_NUMBER_OF_REGISTRY_HIVES
Definition: registry.h:19
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:73
#define _countof(array)
Definition: sndvol32.h:70
DWORD dwOptions
Definition: solitaire.cpp:25
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
base of all file and directory entries
Definition: entries.h:83
HCELL_INDEX List
Definition: cmdata.h:75
ULONG Count
Definition: cmdata.h:74
Definition: cmlib.h:316
HHIVE Hive
Definition: cmlib.h:317
USHORT Signature
Definition: cmdata.h:92
HCELL_INDEX Parent
Definition: cmdata.h:96
ULONG MaxValueNameLen
Definition: cmdata.h:111
ULONG SubKeyCounts[HTYPE_COUNT]
Definition: cmdata.h:97
ULONG MaxValueDataLen
Definition: cmdata.h:112
CHILD_LIST ValueList
Definition: cmdata.h:103
USHORT Flags
Definition: cmdata.h:93
LARGE_INTEGER LastWriteTime
Definition: cmdata.h:94
ULONG Type
Definition: cmdata.h:128
HCELL_INDEX Data
Definition: cmdata.h:127
ULONG DataLength
Definition: cmdata.h:126
HCELL_INDEX RootCell
Definition: hivedata.h:168
PHBASE_BLOCK BaseBlock
Definition: hivedata.h:328
Definition: registry.c:569
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
HCELL_INDEX KeyCellOffset
Definition: registry.c:47
PCMHIVE RegistryHive
Definition: registry.c:48
HCELL_INDEX SourceKeyCellOffset
Definition: registry.c:39
HCELL_INDEX DestinationKeyCellOffset
Definition: registry.c:41
PCMHIVE DestinationHive
Definition: registry.c:40
LIST_ENTRY ListEntry
Definition: registry.c:37
PCMHIVE SourceHive
Definition: registry.c:38
USHORT MaximumLength
Definition: env_spec_w32.h:370
uint16_t * PWSTR
Definition: typedefs.h:56
uint32_t * PULONG
Definition: typedefs.h:59
const uint16_t * PCWSTR
Definition: typedefs.h:57
void * PVOID
Definition: typedefs.h:50
uint32_t * LPDWORD
Definition: typedefs.h:59
const char * PCSTR
Definition: typedefs.h:52
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2699
_Must_inspect_result_ _In_opt_ WDFKEY ParentKey
Definition: wdfregistry.h:69
_Reserved_ PVOID Reserved
Definition: winddi.h:3974
#define WINAPI
Definition: msvc.h:6
#define ERROR_GEN_FAILURE
Definition: winerror.h:134
#define ERROR_NO_SYSTEM_RESOURCES
Definition: winerror.h:931
#define ERROR_NO_LOG_SPACE
Definition: winerror.h:598
ACCESS_MASK REGSAM
Definition: winreg.h:69
_In_ USHORT _In_ ULONG _In_ PSOCKADDR _In_ PSOCKADDR _Reserved_ ULONG _In_opt_ PVOID _In_opt_ const WSK_CLIENT_CONNECTION_DISPATCH _In_opt_ PEPROCESS _In_opt_ PETHREAD _In_opt_ PSECURITY_DESCRIPTOR SecurityDescriptor
Definition: wsk.h:191
unsigned char UCHAR
Definition: xmlstorage.h:181
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185