ReactOS  0.4.12-dev-934-g9a4676f
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 
35 typedef struct _REPARSE_POINT
36 {
43 
44 typedef struct _MEMKEY
45 {
46  /* Information on hard disk structure */
49 } MEMKEY, *PMEMKEY;
50 
51 #define HKEY_TO_MEMKEY(hKey) ((PMEMKEY)(hKey))
52 #define MEMKEY_TO_HKEY(memKey) ((HKEY)(memKey))
53 
56 
57 static CMHIVE SystemHive; /* \Registry\Machine\SYSTEM */
58 static CMHIVE SoftwareHive; /* \Registry\Machine\SOFTWARE */
59 static CMHIVE DefaultHive; /* \Registry\User\.DEFAULT */
60 static CMHIVE SamHive; /* \Registry\Machine\SAM */
61 static CMHIVE SecurityHive; /* \Registry\Machine\SECURITY */
62 static 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 //
75 static UCHAR BcdSecurity[] =
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 
351 HIVE_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 
369 static 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 
388 static LONG
390  IN HKEY hParentKey,
391  IN PCWSTR KeyName,
392  IN BOOL AllowCreation,
393  IN BOOL Volatile,
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 
511 LONG WINAPI
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 
523 LONG WINAPI
525  IN HKEY hKey,
526  IN LPCWSTR lpSubKey,
527  OUT PHKEY phkResult)
528 {
529  return RegpCreateOrOpenKey(hKey, lpSubKey, TRUE, FALSE, phkResult);
530 }
531 
532 LONG WINAPI
534  IN HKEY hKey,
535  IN LPCWSTR lpSubKey,
536  IN DWORD Reserved,
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 {
544  return RegpCreateOrOpenKey(hKey,
545  lpSubKey,
546  TRUE,
548  phkResult);
549 }
550 
551 LONG WINAPI
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 
639 Quit:
640  if (lpSubKey)
641  RegCloseKey(hTargetKey);
642 
643  return rc;
644 }
645 
646 LONG WINAPI
648  IN HKEY hKey,
649  IN LPCWSTR lpSubKey,
650  OUT PHKEY phkResult)
651 {
652  return RegpCreateOrOpenKey(hKey, lpSubKey, FALSE, FALSE, phkResult);
653 }
654 
655 LONG WINAPI
657  IN HKEY hKey,
658  IN LPCWSTR lpValueName OPTIONAL,
659  IN ULONG Reserved,
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 = 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 */
815  KeQuerySystemTime(&KeyNode->LastWriteTime);
816 
817  return ERROR_SUCCESS;
818 }
819 
820 
821 // Synced with freeldr/ntldr/registry.c
822 static
823 VOID
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,
852  min(*DataSize, DataLength));
853  }
854 
855  /* Return the actual data length */
856  *DataSize = DataLength;
857  }
858 }
859 
860 // Similar to RegQueryValue in freeldr/ntldr/registry.c
861 LONG WINAPI
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 {
870  PMEMKEY ParentKey = HKEY_TO_MEMKEY(hKey);
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 = 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 
900 LONG WINAPI
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 */
977  KeQuerySystemTime(&KeyNode->LastWriteTime);
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 
993 Quit:
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 
1010 static BOOL
1012  IN HKEY RootKey,
1013  IN PCWSTR Path,
1014  IN PCMHIVE HiveToConnect,
1017 {
1018  NTSTATUS Status;
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 */
1054  rc = RegCreateKeyExW(RootKey,
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;
1075  InsertTailList(&CmiReparsePointsHead, &ReparsePoint->ListEntry);
1076 
1077  return TRUE;
1078 }
1079 
1080 static 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;
1128  InsertTailList(&CmiReparsePointsHead, &ReparsePoint->ListEntry);
1129 
1130  return TRUE;
1131 }
1132 
1133 VOID
1135  IN PCSTR HiveList)
1136 {
1137  NTSTATUS Status;
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,
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 
1192 VOID
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 */
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
LIST_ENTRY CmiReparsePointsHead
Definition: registry.c:386
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
LONG WINAPI RegCloseKey(IN HKEY hKey)
Definition: registry.c:512
DWORD dwOptions
Definition: solitaire.cpp:23
NTSTATUS RegInitializeRegistry(IN PUNICODE_STRING NtSystemRoot)
Definition: registry.c:679
BOOLEAN CMAPI HvIsCellDirty(IN PHHIVE Hive, IN HCELL_INDEX Cell)
Definition: hivecell.c:126
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING KeyName
Definition: ndis.h:4693
HCELL_INDEX Data
Definition: cmdata.h:127
const uint16_t * PCWSTR
Definition: typedefs.h:55
#define IN
Definition: typedefs.h:38
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
IN PLARGE_INTEGER IN PLARGE_INTEGER PEPROCESS ULONG Key
Definition: fatprocs.h:2697
HCELL_INDEX List
Definition: cmdata.h:75
static PMEMKEY RootKey
Definition: registry.c:55
Type
Definition: Type.h:6
#define ERROR_SUCCESS
Definition: deptool.c:10
struct _Entry Entry
Definition: kefuncs.h:640
static CMHIVE SamHive
Definition: registry.c:60
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
LONG WINAPI RegCreateKeyExW(IN HKEY hKey, IN LPCWSTR lpSubKey, IN DWORD Reserved, IN LPWSTR lpClass OPTIONAL, IN DWORD dwOptions, IN REGSAM samDesired, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes OPTIONAL, OUT PHKEY phkResult, OUT LPDWORD lpdwDisposition OPTIONAL)
Definition: registry.c:533
USHORT MaximumLength
Definition: env_spec_w32.h:370
LIST_ENTRY CmiHiveListHead
Definition: registry.c:385
#define ERROR_INVALID_FUNCTION
Definition: dderror.h:6
_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:182
static UCHAR SoftwareSecurity[]
Definition: registry.c:137
uint16_t * PWSTR
Definition: typedefs.h:54
WINE_UNICODE_INLINE WCHAR * strchrW(const WCHAR *str, WCHAR ch)
Definition: unicode.h:248
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
ULONG MaxValueNameLen
Definition: cmdata.h:111
#define _countof(array)
Definition: fontsub.cpp:30
PHBASE_BLOCK BaseBlock
Definition: hivedata.h:303
#define CM_KEY_NODE_SIGNATURE
Definition: cmdata.h:21
HCELL_INDEX DestinationKeyCellOffset
Definition: registry.c:41
unsigned char * PUCHAR
Definition: retypes.h:3
#define MAX_NUMBER_OF_REGISTRY_HIVES
Definition: registry.h:19
#define free
Definition: debug_ros.c:5
static CMHIVE DefaultHive
Definition: registry.c:59
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
#define HvReleaseCell(h, c)
Definition: cmlib.h:390
LONG NTSTATUS
Definition: precomp.h:26
#define HCELL_NIL
Definition: hivedata.h:85
LONG WINAPI RegCreateKeyW(IN HKEY hKey, IN LPCWSTR lpSubKey, OUT PHKEY phkResult)
Definition: registry.c:524
#define VERIFY_KEY_CELL(key)
Definition: cmi.h:29
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
static PVOID
Definition: registry.c:44
BOOLEAN NTAPI CmpFindNameInList(IN PHHIVE Hive, IN PCHILD_LIST ChildList, IN PUNICODE_STRING Name, OUT PULONG ChildIndex OPTIONAL, OUT PHCELL_INDEX CellIndex)
Definition: cmname.c:149
static BOOL ConnectRegistry(IN HKEY RootKey, IN PCWSTR Path, IN PCMHIVE HiveToConnect, IN PUCHAR SecurityDescriptor, IN ULONG SecurityDescriptorLength)
Definition: registry.c:1011
HCELL_INDEX CMAPI HvAllocateCell(PHHIVE RegistryHive, ULONG Size, HSTORAGE_TYPE Storage, IN HCELL_INDEX Vicinity)
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn BOOLEAN Physical 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:716
#define CM_KEY_VALUE_SPECIAL_SIZE
Definition: cm.h:73
#define InsertTailList(ListHead, Entry)
_In_ ULONG SecurityDescriptorLength
Definition: rtlfuncs.h:1674
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
LONG WINAPI RegSetValueExW(IN HKEY hKey, IN LPCWSTR lpValueName OPTIONAL, IN ULONG Reserved, IN ULONG dwType, IN const UCHAR *lpData, IN ULONG cbData)
Definition: registry.c:656
#define ERROR_NO_SYSTEM_RESOURCES
Definition: winerror.h:931
NTSTATUS NTAPI CmpRemoveValueFromList(IN PHHIVE Hive, IN ULONG Index, IN OUT PCHILD_LIST ChildList)
Definition: cmvalue.c:320
HCELL_INDEX SourceKeyCellOffset
Definition: registry.c:39
LONG WINAPI RegDeleteKeyW(IN HKEY hKey, IN LPCWSTR lpSubKey)
Definition: registry.c:552
uint32_t ULONG_PTR
Definition: typedefs.h:63
HCELL_INDEX KeyCellOffset
Definition: registry.c:47
ULONG DataLength
Definition: cmdata.h:126
static CMHIVE SoftwareHive
Definition: registry.c:58
#define BlockOffset(V, L)
Definition: cdprocs.h:1660
BOOLEAN NTAPI CmpFreeValue(IN PHHIVE Hive, IN HCELL_INDEX Cell)
Definition: cmvalue.c:73
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
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
#define ERROR_ACCESS_DENIED
Definition: compat.h:87
NTSTATUS CmiCreateSecurityKey(IN PHHIVE Hive, IN HCELL_INDEX Cell, IN PUCHAR Descriptor, IN ULONG DescriptorLength)
Definition: cmi.c:157
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
static CMHIVE BcdHive
Definition: registry.c:62
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
C_ASSERT(_countof(RegistryHives)==NUMBER_OF_STANDARD_REGISTRY_HIVES)
PVOID CMAPI HvGetCell(PHHIVE RegistryHive, HCELL_INDEX CellOffset)
Definition: hivecell.c:67
static VOID RepGetValueData(IN PHHIVE Hive, IN PCM_KEY_VALUE ValueCell, OUT PULONG Type OPTIONAL, OUT PUCHAR Data OPTIONAL, IN OUT PULONG DataSize OPTIONAL)
Definition: registry.c:824
VOID RegShutdownRegistry(VOID)
Definition: registry.c:1193
static CMHIVE RootHive
Definition: registry.c:54
smooth NULL
Definition: ftsmooth.c:416
struct _CM_KEY_NODE * PCM_KEY_NODE
HHIVE Hive
Definition: cm.h:393
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
void DPRINT(...)
Definition: polytest.cpp:61
LONG WINAPI RegDeleteValueW(IN HKEY hKey, IN LPCWSTR lpValueName OPTIONAL)
Definition: registry.c:901
_Reserved_ PVOID Reserved
Definition: winddi.h:3974
struct _REPARSE_POINT * PREPARSE_POINT
LONG WINAPI RegOpenKeyW(IN HKEY hKey, IN LPCWSTR lpSubKey, OUT PHKEY phkResult)
Definition: registry.c:647
#define ERROR_NO_LOG_SPACE
Definition: winerror.h:598
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
CHILD_LIST ValueList
Definition: cmdata.h:103
static CMHIVE SecurityHive
Definition: registry.c:61
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
static UCHAR BcdSecurity[]
Definition: registry.c:75
PCELL_DATA NTAPI CmpValueToData(IN PHHIVE Hive, IN PCM_KEY_VALUE Value, OUT PULONG Length)
Definition: cmvalue.c:167
#define REG_LINK
Definition: nt_native.h:1500
Definition: registry.c:568
LIST_ENTRY ListEntry
Definition: registry.c:37
HCELL_INDEX NTAPI CmpFindValueByName(IN PHHIVE Hive, IN PCM_KEY_NODE KeyNode, IN PUNICODE_STRING Name)
Definition: cmvalue.c:99
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
HCELL_INDEX Parent
Definition: cmdata.h:96
ULONG HCELL_INDEX
Definition: hivedata.h:80
ULONG SubKeyCounts[HTYPE_COUNT]
Definition: cmdata.h:97
USHORT Signature
Definition: cmdata.h:92
PCMHIVE DestinationHive
Definition: registry.c:40
PCMHIVE RegistryHive
Definition: registry.c:48
#define WINAPI
Definition: msvc.h:8
PCMHIVE SourceHive
Definition: registry.c:38
unsigned long DWORD
Definition: ntddk_ex.h:95
BOOLEAN CMAPI HvMarkCellDirty(PHHIVE RegistryHive, HCELL_INDEX CellOffset, BOOLEAN HoldingLock)
Definition: hivecell.c:100
static PMEMKEY CreateInMemoryStructure(IN PCMHIVE RegistryHive, IN HCELL_INDEX KeyCellOffset)
Definition: registry.c:370
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
VOID CMAPI HvFreeCell(PHHIVE RegistryHive, HCELL_INDEX CellOffset)
Definition: hivecell.c:441
unsigned char UCHAR
Definition: xmlstorage.h:181
LONG CMAPI HvGetCellSize(PHHIVE RegistryHive, PVOID Cell)
struct _MEMKEY MEMKEY
static const WCHAR L[]
Definition: oid.c:1250
static UCHAR SystemSecurity[]
Definition: registry.c:253
LARGE_INTEGER LastWriteTime
Definition: cmdata.h:94
Definition: typedefs.h:117
#define KEY_NO_DELETE
Definition: cmdata.h:33
HCELL_INDEX RootCell
Definition: hivedata.h:143
ULONG Count
Definition: cmdata.h:74
Status
Definition: gdiplustypes.h:24
LONG WINAPI RegQueryValueExW(IN HKEY hKey, IN LPCWSTR lpValueName, IN PULONG lpReserved, OUT PULONG lpType OPTIONAL, OUT PUCHAR lpData OPTIONAL, IN OUT PULONG lpcbData OPTIONAL)
Definition: registry.c:862
PRTL_UNICODE_STRING_BUFFER Path
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
unsigned short USHORT
Definition: pedump.c:61
struct _CM_KEY_VALUE * PCM_KEY_VALUE
ULONG Type
Definition: cmdata.h:128
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
static PCMHIVE CmHive
Definition: registry.c:28
ACCESS_MASK REGSAM
Definition: winreg.h:69
unsigned int * PULONG
Definition: retypes.h:1
#define min(a, b)
Definition: monoChain.cc:55
unsigned int UINT
Definition: ndis.h:50
NTSTATUS CmiInitializeHive(IN OUT PCMHIVE Hive, IN PCWSTR Name)
Definition: cmi.c:114
NTSTATUS NTAPI CmpFreeKeyByCell(IN PHHIVE Hive, IN HCELL_INDEX Cell, IN BOOLEAN Unlink)
Definition: cmkeydel.c:159
HIVE_LIST_ENTRY RegistryHives[]
Definition: registry.c:581
ULONG MaxValueDataLen
Definition: cmdata.h:112
static CMHIVE SystemHive
Definition: registry.c:57
#define DPRINT1
Definition: precomp.h:8
#define OUT
Definition: typedefs.h:39
uint32_t * LPDWORD
Definition: typedefs.h:57
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define ULONG_PTR
Definition: config.h:101
struct _REPARSE_POINT REPARSE_POINT
#define malloc
Definition: debug_ros.c:4
#define MEMKEY_TO_HKEY(memKey)
Definition: registry.c:52
const char * PCSTR
Definition: typedefs.h:51
#define REG_OPTION_VOLATILE
Definition: nt_native.h:1060
#define ERROR_GEN_FAILURE
Definition: winerror.h:134
WCHAR * LPWSTR
Definition: xmlstorage.h:184
_Must_inspect_result_ _Out_writes_to_ DataLength PHIDP_DATA _Inout_ PULONG DataLength
Definition: hidpi.h:333
return STATUS_SUCCESS
Definition: btrfs.c:2725
BOOLEAN NTAPI CmpLinkKeyToHive(_In_z_ PCWSTR LinkKeyName, _In_z_ PCWSTR TargetKeyName)
Definition: cmsysini.c:42
HCELL_INDEX NTAPI CmpFindSubKeyByName(IN PHHIVE Hive, IN PCM_KEY_NODE Parent, IN PCUNICODE_STRING SearchName)
Definition: cmindex.c:683
struct _MEMKEY * PMEMKEY
NTSTATUS CmiAddSubKey(IN PCMHIVE RegistryHive, IN HCELL_INDEX ParentKeyCellOffset, IN PCUNICODE_STRING SubKeyName, IN BOOLEAN VolatileKey, OUT HCELL_INDEX *pBlockOffset)
Definition: cmi.c:297
static LONG RegpCreateOrOpenKey(IN HKEY hParentKey, IN PCWSTR KeyName, IN BOOL AllowCreation, IN BOOL Volatile, OUT PHKEY Key)
Definition: registry.c:389
_In_ NDIS_STATUS _In_ ULONG _In_ USHORT _In_opt_ PVOID _In_ ULONG DataSize
Definition: ndis.h:4733
base of all file and directory entries
Definition: entries.h:82
Definition: cm.h:391
USHORT Flags
Definition: cmdata.h:93
#define HKEY_TO_MEMKEY(hKey)
Definition: registry.c:51
BOOLEAN NTAPI CmpMarkValueDataDirty(IN PHHIVE Hive, IN PCM_KEY_VALUE Value)
Definition: cmvalue.c:19
static BOOL CreateSymLink(IN PCWSTR LinkKeyPath OPTIONAL, IN OUT PHKEY LinkKeyHandle OPTIONAL, IN HKEY TargetKeyHandle)
Definition: registry.c:1081
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68