ReactOS  0.4.14-dev-52-g6116262
registry.c
Go to the documentation of this file.
1 /*
2  * ReactOS kernel
3  * Copyright (C) 2003 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 Setup Library
22  * FILE: base/setup/lib/registry.c
23  * PURPOSE: Registry creation functions
24  * PROGRAMMERS: ...
25  * Hermes Belusca-Maito (hermes.belusca@sfr.fr)
26  */
27 
28 /* INCLUDES *****************************************************************/
29 
30 #include "precomp.h"
31 #include "filesup.h"
32 #include "infsupp.h"
33 #include "regutil.h"
34 
35 #include "registry.h"
36 
37 #define NDEBUG
38 #include <debug.h>
39 
40 
41 // #ifdef __REACTOS__
42 #if 1 // FIXME: Disable if setupapi.h is included in the code...
43 #define FLG_ADDREG_BINVALUETYPE 0x00000001
44 #define FLG_ADDREG_NOCLOBBER 0x00000002
45 #define FLG_ADDREG_DELVAL 0x00000004
46 #define FLG_ADDREG_APPEND 0x00000008
47 #define FLG_ADDREG_KEYONLY 0x00000010
48 #define FLG_ADDREG_OVERWRITEONLY 0x00000020
49 #define FLG_ADDREG_TYPE_SZ 0x00000000
50 #define FLG_ADDREG_TYPE_MULTI_SZ 0x00010000
51 #define FLG_ADDREG_TYPE_EXPAND_SZ 0x00020000
52 #define FLG_ADDREG_TYPE_BINARY (0x00000000 | FLG_ADDREG_BINVALUETYPE)
53 #define FLG_ADDREG_TYPE_DWORD (0x00010000 | FLG_ADDREG_BINVALUETYPE)
54 #define FLG_ADDREG_TYPE_NONE (0x00020000 | FLG_ADDREG_BINVALUETYPE)
55 #define FLG_ADDREG_TYPE_MASK (0xFFFF0000 | FLG_ADDREG_BINVALUETYPE)
56 #endif
57 
58 /* GLOBALS ******************************************************************/
59 
60 #define REGISTRY_SETUP_MACHINE L"\\Registry\\Machine\\SYSTEM\\USetup_Machine\\"
61 #define REGISTRY_SETUP_USER L"\\Registry\\Machine\\SYSTEM\\USetup_User\\"
62 
63 typedef struct _ROOT_KEY
64 {
69 
71 {
72  { L"HKCR", REGISTRY_SETUP_MACHINE L"SOFTWARE\\Classes\\", NULL }, /* "\\Registry\\Machine\\SOFTWARE\\Classes\\" */ // HKEY_CLASSES_ROOT
73  { L"HKCU", REGISTRY_SETUP_USER L".DEFAULT\\" , NULL }, /* "\\Registry\\User\\.DEFAULT\\" */ // HKEY_CURRENT_USER
74  { L"HKLM", REGISTRY_SETUP_MACHINE , NULL }, /* "\\Registry\\Machine\\" */ // HKEY_LOCAL_MACHINE
75  { L"HKU" , REGISTRY_SETUP_USER , NULL }, /* "\\Registry\\User\\" */ // HKEY_USERS
76 #if 0
77  { L"HKR", NULL, NULL },
78 #endif
79 };
80 
81 /* FUNCTIONS ****************************************************************/
82 
83 #define IsPredefKey(HKey) \
84  (((ULONG_PTR)(HKey) & 0xF0000000) == 0x80000000)
85 
86 #define GetPredefKeyIndex(HKey) \
87  ((ULONG_PTR)(HKey) & 0x0FFFFFFF)
88 
89 HANDLE
92  OUT PCWSTR* RootKeyMountPoint OPTIONAL)
93 {
95 
96  if (!IsPredefKey(KeyHandle))
97  return NULL;
98  if (Index >= ARRAYSIZE(RootKeys))
99  return NULL;
100 
101  if (RootKeyMountPoint)
102  *RootKeyMountPoint = RootKeys[Index].MountPoint;
103  return RootKeys[Index].Handle;
104 }
105 
106 HANDLE
108  IN PCWSTR RootKeyName,
109  OUT PCWSTR* RootKeyMountPoint OPTIONAL)
110 {
111  UCHAR i;
112 
113  for (i = 0; i < ARRAYSIZE(RootKeys); ++i)
114  {
115  if (!_wcsicmp(RootKeyName, RootKeys[i].Name))
116  {
117  if (RootKeyMountPoint)
118  *RootKeyMountPoint = RootKeys[i].MountPoint;
119  return RootKeys[i].Handle;
120  }
121  }
122 
123  return NULL;
124 }
125 
126 
127 /***********************************************************************
128  * append_multi_sz_value
129  *
130  * Append a multisz string to a multisz registry value.
131  */
132 // NOTE: Synced with setupapi/install.c ; see also mkhive/reginf.c
133 #if 0
134 static void
136  const WCHAR *value,
137  const WCHAR *strings,
138  DWORD str_size )
139 {
140  DWORD size, type, total;
141  WCHAR *buffer, *p;
142 
143  if (RegQueryValueExW( hkey, value, NULL, &type, NULL, &size )) return;
144  if (type != REG_MULTI_SZ) return;
145 
146  if (!(buffer = HeapAlloc( GetProcessHeap(), 0, size + str_size * sizeof(WCHAR) ))) return;
147  if (RegQueryValueExW( hkey, value, NULL, NULL, (BYTE *)buffer, &size )) goto done;
148 
149  /* compare each string against all the existing ones */
150  total = size;
151  while (*strings)
152  {
153  int len = strlenW(strings) + 1;
154 
155  for (p = buffer; *p; p += strlenW(p) + 1)
156  if (!strcmpiW( p, strings )) break;
157 
158  if (!*p) /* not found, need to append it */
159  {
160  memcpy( p, strings, len * sizeof(WCHAR) );
161  p[len] = 0;
162  total += len;
163  }
164  strings += len;
165  }
166  if (total != size)
167  {
168  TRACE( "setting value %s to %s\n", debugstr_w(value), debugstr_w(buffer) );
169  RegSetValueExW( hkey, value, 0, REG_MULTI_SZ, (BYTE *)buffer, total );
170  }
171  done:
172  HeapFree( GetProcessHeap(), 0, buffer );
173 }
174 #endif
175 
176 /***********************************************************************
177  * delete_multi_sz_value
178  *
179  * Remove a string from a multisz registry value.
180  */
181 #if 0
182 static void delete_multi_sz_value( HKEY hkey, const WCHAR *value, const WCHAR *string )
183 {
184  DWORD size, type;
185  WCHAR *buffer, *src, *dst;
186 
187  if (RegQueryValueExW( hkey, value, NULL, &type, NULL, &size )) return;
188  if (type != REG_MULTI_SZ) return;
189  /* allocate double the size, one for value before and one for after */
190  if (!(buffer = HeapAlloc( GetProcessHeap(), 0, size * 2 * sizeof(WCHAR) ))) return;
191  if (RegQueryValueExW( hkey, value, NULL, NULL, (BYTE *)buffer, &size )) goto done;
192  src = buffer;
193  dst = buffer + size;
194  while (*src)
195  {
196  int len = strlenW(src) + 1;
197  if (strcmpiW( src, string ))
198  {
199  memcpy( dst, src, len * sizeof(WCHAR) );
200  dst += len;
201  }
202  src += len;
203  }
204  *dst++ = 0;
205  if (dst != buffer + 2*size) /* did we remove something? */
206  {
207  TRACE( "setting value %s to %s\n", debugstr_w(value), debugstr_w(buffer + size) );
208  RegSetValueExW( hkey, value, 0, REG_MULTI_SZ,
209  (BYTE *)(buffer + size), dst - (buffer + size) );
210  }
211  done:
212  HeapFree( GetProcessHeap(), 0, buffer );
213 }
214 #endif
215 
216 /***********************************************************************
217  * do_reg_operation
218  *
219  * Perform an add/delete registry operation depending on the flags.
220  */
221 static BOOLEAN
225  ULONG Flags)
226 {
227  WCHAR EmptyStr = 0;
228  ULONG Type;
229  ULONG Size;
230 
231  if (Flags & FLG_ADDREG_DELVAL) /* deletion */
232  {
233 #if 0
234  if (ValueName)
235  {
237  }
238  else
239  {
241  }
242 #endif
243  return TRUE;
244  }
245 
247  return TRUE;
248 
249 #if 0
251  {
252  BOOL exists = !RegQueryValueExW( hkey, ValueName, NULL, NULL, NULL, NULL );
253  if (exists && (flags & FLG_ADDREG_NOCLOBBER))
254  return TRUE;
255  if (!exists & (flags & FLG_ADDREG_OVERWRITEONLY))
256  return TRUE;
257  }
258 #endif
259 
260  switch (Flags & FLG_ADDREG_TYPE_MASK)
261  {
262  case FLG_ADDREG_TYPE_SZ:
263  Type = REG_SZ;
264  break;
265 
267  Type = REG_MULTI_SZ;
268  break;
269 
272  break;
273 
275  Type = REG_BINARY;
276  break;
277 
279  Type = REG_DWORD;
280  break;
281 
283  Type = REG_NONE;
284  break;
285 
286  default:
287  Type = Flags >> 16;
288  break;
289  }
290 
291  if (!(Flags & FLG_ADDREG_BINVALUETYPE) ||
293  {
294  PWCHAR Str = NULL;
295 
296  if (Type == REG_MULTI_SZ)
297  {
298  if (!SpInfGetMultiSzField(Context, 5, NULL, 0, &Size))
299  Size = 0;
300 
301  if (Size)
302  {
303  Str = (WCHAR*) RtlAllocateHeap(ProcessHeap, 0, Size * sizeof(WCHAR));
304  if (Str == NULL)
305  return FALSE;
306 
308  }
309 
310  if (Flags & FLG_ADDREG_APPEND)
311  {
312  if (Str == NULL)
313  return TRUE;
314 
315  DPRINT1("append_multi_sz_value '%S' commented out, WHY??\n", ValueName);
316 // append_multi_sz_value( hkey, value, str, size );
317 
318  RtlFreeHeap (ProcessHeap, 0, Str);
319  return TRUE;
320  }
321  /* else fall through to normal string handling */
322  }
323  else
324  {
325  if (!SpInfGetStringField(Context, 5, NULL, 0, &Size))
326  Size = 0;
327 
328  if (Size)
329  {
330  Str = (WCHAR*)RtlAllocateHeap(ProcessHeap, 0, Size * sizeof(WCHAR));
331  if (Str == NULL)
332  return FALSE;
333 
335  }
336  }
337 
338  if (Type == REG_DWORD)
339  {
340  ULONG dw = Str ? wcstoul (Str, NULL, 0) : 0;
341 
342  DPRINT("setting dword %wZ to %lx\n", ValueName, dw);
343 
345  ValueName,
346  0,
347  Type,
348  (PVOID)&dw,
349  sizeof(ULONG));
350  }
351  else
352  {
353  DPRINT("setting value %wZ to %S\n", ValueName, Str);
354 
355  if (Str)
356  {
358  ValueName,
359  0,
360  Type,
361  (PVOID)Str,
362  Size * sizeof(WCHAR));
363  }
364  else
365  {
367  ValueName,
368  0,
369  Type,
370  (PVOID)&EmptyStr,
371  sizeof(WCHAR));
372  }
373  }
374  RtlFreeHeap (ProcessHeap, 0, Str);
375  }
376  else /* get the binary data */
377  {
378  PUCHAR Data = NULL;
379 
380  if (!SpInfGetBinaryField(Context, 5, NULL, 0, &Size))
381  Size = 0;
382 
383  if (Size)
384  {
385  Data = (unsigned char*) RtlAllocateHeap(ProcessHeap, 0, Size);
386  if (Data == NULL)
387  return FALSE;
388 
389  DPRINT("setting binary data %wZ len %lu\n", ValueName, Size);
391  }
392 
394  ValueName,
395  0,
396  Type,
397  (PVOID)Data,
398  Size);
399 
401  }
402 
403  return TRUE;
404 }
405 
406 /***********************************************************************
407  * registry_callback
408  *
409  * Called once for each AddReg and DelReg entry in a given section.
410  */
411 static BOOLEAN
413 {
417  PUNICODE_STRING ValuePtr;
418  UINT Flags;
420 
422  PCWSTR RootKeyName;
423  HANDLE RootKeyHandle, KeyHandle;
424  BOOLEAN Ok;
425 
426  Ok = SpInfFindFirstLine(hInf, Section, NULL, &Context);
427  if (!Ok)
428  return TRUE; /* Don't fail if the section isn't present */
429 
430  for (;Ok; Ok = SpInfFindNextLine(&Context, &Context))
431  {
432  /* get root */
433  if (!SpInfGetStringField(&Context, 1, Buffer, sizeof(Buffer)/sizeof(WCHAR), NULL))
434  continue;
435  RootKeyHandle = GetRootKeyByName(Buffer, &RootKeyName);
436  if (!RootKeyHandle)
437  continue;
438 
439  /* get key */
440  if (!SpInfGetStringField(&Context, 2, Buffer, sizeof(Buffer)/sizeof(WCHAR), NULL))
441  *Buffer = 0;
442 
443  DPRINT("KeyName: <%S\\%S>\n", RootKeyName, Buffer);
444 
445  /* get flags */
446  if (!SpInfGetIntField(&Context, 4, (PINT)&Flags))
447  Flags = 0;
448 
449  DPRINT("Flags: %lx\n", Flags);
450 
453  &Name,
455  RootKeyHandle,
456  NULL);
457 
459  {
463  if (!NT_SUCCESS(Status))
464  {
465  DPRINT1("NtOpenKey(%wZ) failed (Status %lx)\n", &Name, Status);
466  continue; /* ignore if it doesn't exist */
467  }
468  }
469  else
470  {
475  if (!NT_SUCCESS(Status))
476  {
477  DPRINT1("CreateNestedKey(%wZ) failed (Status %lx)\n", &Name, Status);
478  continue;
479  }
480  }
481 
482  /* get value name */
483  if (SpInfGetStringField(&Context, 3, Buffer, sizeof(Buffer)/sizeof(WCHAR), NULL))
484  {
486  ValuePtr = &Value;
487  }
488  else
489  {
490  ValuePtr = NULL;
491  }
492 
493  /* and now do it */
494  if (!do_reg_operation(KeyHandle, ValuePtr, &Context, Flags))
495  {
497  return FALSE;
498  }
499 
501  }
502 
503  return TRUE;
504 }
505 
506 BOOLEAN
508  IN PCWSTR SourcePath,
510  IN PCWSTR Section,
511  IN LCID LocaleId,
512  IN BOOLEAN Delete)
513 {
514  HINF hInf;
515  UINT ErrorLine;
517 
518  /* Load the INF file from the installation media */
520  SourcePath, FileName);
521 
523  NULL,
525  LocaleId,
526  &ErrorLine);
527  if (hInf == INVALID_HANDLE_VALUE)
528  {
529  DPRINT1("SpInfOpenInfFile() failed\n");
530  return FALSE;
531  }
532 
533 #if 0
534  if (!registry_callback(hInf, L"DelReg", FALSE))
535  {
536  DPRINT1("registry_callback() failed\n");
537  SpInfCloseInfFile(hInf);
538  return FALSE;
539  }
540 #endif
541 
542  if (!registry_callback(hInf, L"AddReg", FALSE))
543  {
544  DPRINT1("registry_callback() failed\n");
545  SpInfCloseInfFile(hInf);
546  return FALSE;
547  }
548 
549  if (!registry_callback(hInf, L"AddReg.NT" INF_ARCH, FALSE))
550  {
551  DPRINT1("registry_callback() failed\n");
552  SpInfCloseInfFile(hInf);
553  return FALSE;
554  }
555 
556  SpInfCloseInfFile(hInf);
557  return TRUE;
558 }
559 
560 
561 typedef enum _HIVE_UPDATE_STATE
562 {
563  Create, // Create a new hive file and save possibly existing old one with a .old extension.
564  Repair, // Re-create a new hive file and save possibly existing old one with a .brk extension.
565  Update // Hive update, do not need to be recreated.
567 
568 typedef struct _HIVE_LIST_ENTRY
569 {
570  PCWSTR HiveName; // HiveFileName;
571  PCWSTR HiveRegistryPath; // HiveRegMountPoint;
575  // PUCHAR SecurityDescriptor;
576  // ULONG SecurityDescriptorLength;
578 
579 #define NUMBER_OF_STANDARD_REGISTRY_HIVES 3
580 
581 HIVE_LIST_ENTRY RegistryHives[/*NUMBER_OF_STANDARD_REGISTRY_HIVES*/] =
582 {
583  { L"SYSTEM" , L"\\Registry\\Machine\\USetup_SYSTEM" , HKEY_LOCAL_MACHINE, L"SYSTEM" , Create /* , SystemSecurity , sizeof(SystemSecurity) */ },
584  { L"SOFTWARE", L"\\Registry\\Machine\\USetup_SOFTWARE", HKEY_LOCAL_MACHINE, L"SOFTWARE", Create /* , SoftwareSecurity, sizeof(SoftwareSecurity) */ },
585  { L"DEFAULT" , L"\\Registry\\User\\USetup_DEFAULT" , HKEY_USERS , L".DEFAULT", Create /* , SystemSecurity , sizeof(SystemSecurity) */ },
586 
587 // { L"BCD" , L"\\Registry\\Machine\\USetup_BCD", HKEY_LOCAL_MACHINE, L"BCD00000000", Create /* , BcdSecurity , sizeof(BcdSecurity) */ },
588 };
590 
591 #define NUMBER_OF_SECURITY_REGISTRY_HIVES 2
592 
594 HIVE_LIST_ENTRY SecurityRegistryHives[/*NUMBER_OF_SECURITY_REGISTRY_HIVES*/] =
595 {
596  { L"SAM" , L"\\Registry\\Machine\\USetup_SAM" , HKEY_LOCAL_MACHINE, L"SAM" , Create /* , SystemSecurity , sizeof(SystemSecurity) */ },
597  { L"SECURITY", L"\\Registry\\Machine\\USetup_SECURITY", HKEY_LOCAL_MACHINE, L"SECURITY", Create /* , NULL , 0 */ },
598 };
600 
601 
602 NTSTATUS
605  OUT PBOOLEAN ShouldRepairRegistry)
606 {
608  BOOLEAN PrivilegeSet[2] = {FALSE, FALSE};
609  UINT i;
610 
611  /* Suppose first the registry hives do not have to be fully recreated */
612  *ShouldRepairRegistry = FALSE;
613 
614  /* Acquire restore privilege */
616  if (!NT_SUCCESS(Status))
617  {
618  DPRINT1("RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE) failed (Status 0x%08lx)\n", Status);
619  /* Exit prematurely here.... */
620  return Status;
621  }
622 
623  /* Acquire backup privilege */
624  Status = RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE, TRUE, FALSE, &PrivilegeSet[1]);
625  if (!NT_SUCCESS(Status))
626  {
627  DPRINT1("RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE) failed (Status 0x%08lx)\n", Status);
628  RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, PrivilegeSet[0], FALSE, &PrivilegeSet[0]);
629  /* Exit prematurely here.... */
630  return Status;
631  }
632 
633  for (i = 0; i < ARRAYSIZE(RegistryHives); ++i)
634  {
636  if (!NT_SUCCESS(Status))
637  {
638  DPRINT1("Registry hive '%S' needs repair!\n", RegistryHives[i].HiveName);
640  *ShouldRepairRegistry = TRUE;
641  }
642  else
643  {
645  }
646  }
647 
649  for (i = 0; i < ARRAYSIZE(SecurityRegistryHives); ++i)
650  {
652  if (!NT_SUCCESS(Status))
653  {
654  DPRINT1("Registry hive '%S' needs repair!\n", SecurityRegistryHives[i].HiveName);
656  /*
657  * Note that it's not the role of the 1st-stage installer to fix
658  * the security hives. This should be done at 2nd-stage installation
659  * by LSASS.
660  */
661  }
662  else
663  {
665  }
666  }
667 
668  /* Reset the status (we succeeded in checking all the hives) */
670 
671  /* Remove restore and backup privileges */
672  RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE, PrivilegeSet[1], FALSE, &PrivilegeSet[1]);
673  RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, PrivilegeSet[0], FALSE, &PrivilegeSet[0]);
674 
675  return Status;
676 }
677 
678 NTSTATUS
681 {
686  BOOLEAN PrivilegeSet[2] = {FALSE, FALSE};
688  UINT i;
689 
690  /* Acquire restore privilege */
692  if (!NT_SUCCESS(Status))
693  {
694  DPRINT1("RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE) failed (Status 0x%08lx)\n", Status);
695  /* Exit prematurely here.... */
696  return Status;
697  }
698 
699  /* Acquire backup privilege */
700  Status = RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE, TRUE, FALSE, &PrivilegeSet[1]);
701  if (!NT_SUCCESS(Status))
702  {
703  DPRINT1("RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE) failed (Status 0x%08lx)\n", Status);
704  RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, PrivilegeSet[0], FALSE, &PrivilegeSet[0]);
705  /* Exit prematurely here.... */
706  return Status;
707  }
708 
709  /*
710  * Create the template proto-hive.
711  *
712  * Use a dummy root key name:
713  * - On 2k/XP/2k3, this is "$$$PROTO.HIV"
714  * - On Vista+, this is "CMI-CreateHive{guid}"
715  * See https://github.com/libyal/winreg-kb/blob/master/documentation/Registry%20files.asciidoc
716  * for more information.
717  */
718  RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\SYSTEM\\$$$PROTO.HIV");
720  &KeyName,
722  NULL,
723  NULL);
727  0,
728  NULL,
730  NULL);
731  if (!NT_SUCCESS(Status))
732  {
733  DPRINT1("NtCreateKey() failed to create the proto-hive (Status %lx)\n", Status);
734  goto Quit;
735  }
737 
738  for (i = 0; i < ARRAYSIZE(RegistryHives); ++i)
739  {
741  continue;
742 
744  RegistryHives[i].HiveName,
745  RegistryHives[i].State != Repair, // RegistryHives[i].State == Create,
746  KeyHandle);
747  if (!NT_SUCCESS(Status))
748  {
749  DPRINT1("CreateRegistryFile(%S) failed, Status 0x%08lx\n", RegistryHives[i].HiveName, Status);
750  /* Exit prematurely here.... */
751  /* That is now done, remove the proto-hive */
754  goto Quit;
755  }
756  }
757 
758  /* That is now done, remove the proto-hive */
761 
762 
763  /*
764  * Prepare the registry root keys. Since we cannot create real registry keys
765  * inside the master keys (\Registry, \Registry\Machine or \Registry\User),
766  * we need to perform some SymLink tricks instead.
767  */
768 
769  /* Our offline HKLM '\Registry\Machine' is inside '\Registry\Machine\SYSTEM\USetup_Machine' */
772  &KeyName,
774  NULL,
775  NULL);
776  KeyHandle = NULL;
780  0,
781  NULL,
782  // FIXME: Using REG_OPTION_VOLATILE works OK on Windows,
783  // but I need to check whether it works OK on ReactOS too.
784  REG_OPTION_NON_VOLATILE, // REG_OPTION_VOLATILE,
785  &Disposition);
786  if (!NT_SUCCESS(Status))
787  {
788  DPRINT1("NtCreateKey(%wZ) failed (Status 0x%08lx)\n", &KeyName, Status);
789  // return Status;
790  }
792 
793  /* Our offline HKU '\Registry\User' is inside '\Registry\Machine\SYSTEM\USetup_User' */
796  &KeyName,
798  NULL,
799  NULL);
800  KeyHandle = NULL;
804  0,
805  NULL,
806  // FIXME: Using REG_OPTION_VOLATILE works OK on Windows,
807  // but I need to check whether it works OK on ReactOS too.
808  REG_OPTION_NON_VOLATILE, // REG_OPTION_VOLATILE,
809  &Disposition);
810  if (!NT_SUCCESS(Status))
811  {
812  DPRINT1("NtCreateKey(%wZ) failed (Status 0x%08lx)\n", &KeyName, Status);
813  // return Status;
814  }
816 
817 
818  /*
819  * Now properly mount the offline hive files
820  */
821  for (i = 0; i < ARRAYSIZE(RegistryHives); ++i)
822  {
823  // if (RegistryHives[i].State != Create && RegistryHives[i].State != Repair)
824  // continue;
825 
827  {
829  RegistryHives[i].HiveRegistryPath,
830  NtSystemRoot,
831  RegistryHives[i].HiveName
832  /* SystemSecurity, sizeof(SystemSecurity) */);
833  if (!NT_SUCCESS(Status))
834  {
835  DPRINT1("ConnectRegistry(%S) failed, Status 0x%08lx\n",
836  RegistryHives[i].HiveName, Status);
837  }
838 
839  /* Create the registry symlink to this key */
841  RegistryHives[i].RegSymLink,
842  RegistryHives[i].HiveRegistryPath);
843  if (!NT_SUCCESS(Status))
844  {
845  DPRINT1("CreateSymLinkKey(%S) failed, Status 0x%08lx\n",
846  RegistryHives[i].RegSymLink, Status);
847  }
848  }
849  else
850  {
851  /* Create *DUMMY* volatile hives just to make the update procedure working */
852 
855  &KeyName,
857  RootKeys[GetPredefKeyIndex(RegistryHives[i].PredefKeyHandle)].Handle,
858  NULL);
859  KeyHandle = NULL;
863  0,
864  NULL,
865  // FIXME: Using REG_OPTION_VOLATILE works OK on Windows,
866  // but I need to check whether it works OK on ReactOS too.
867  REG_OPTION_NON_VOLATILE, // REG_OPTION_VOLATILE,
868  &Disposition);
869  if (!NT_SUCCESS(Status))
870  {
871  DPRINT1("NtCreateKey(%wZ) failed (Status 0x%08lx)\n", &KeyName, Status);
872  // return Status;
873  }
875  }
876  }
877 
878 
879  /* HKCU is a handle to 'HKU\.DEFAULT' */
880 #if 0
881  RtlInitUnicodeString(&KeyName, L".DEFAULT");
883  &KeyName,
886  NULL);
887 #else
890  &KeyName,
892  NULL,
893  NULL);
894 #endif
895  KeyHandle = NULL;
899  if (!NT_SUCCESS(Status))
900  {
901  DPRINT1("NtOpenKey(%wZ) failed (Status %lx)\n", &KeyName, Status);
902  }
904 
905 
906  /* HKCR is a handle to 'HKLM\Software\Classes' */
907 #if 0
908  RtlInitUnicodeString(&KeyName, L"Software\\Classes");
910  &KeyName,
913  NULL);
914 #else
917  &KeyName,
919  NULL,
920  NULL);
921 #endif
922  KeyHandle = NULL;
923  /* We use NtCreateKey instead of NtOpenKey because Software\Classes doesn't exist originally */
927  0,
928  NULL,
930  &Disposition);
931  if (!NT_SUCCESS(Status))
932  {
933  DPRINT1("NtCreateKey(%wZ) failed (Status %lx)\n", &KeyName, Status);
934  }
935  else
936  {
937  DPRINT("NtCreateKey() succeeded to %s the %wZ key (Status %lx)\n",
938  Disposition == REG_CREATED_NEW_KEY ? "create" : /* REG_OPENED_EXISTING_KEY */ "open",
939  &KeyName, Status);
940  }
942 
943 
945 
946 
947  /* Create the 'HKLM\SYSTEM\ControlSet001' key */
948  // REGISTRY_SETUP_MACHINE L"SYSTEM\\ControlSet001"
949  RtlInitUnicodeString(&KeyName, L"SYSTEM\\ControlSet001");
951  &KeyName,
954  NULL);
958  0,
959  NULL,
961  &Disposition);
962  if (!NT_SUCCESS(Status))
963  {
964  DPRINT1("NtCreateKey() failed to create the ControlSet001 key (Status %lx)\n", Status);
965  // return Status;
966  }
967  else
968  {
969  DPRINT("NtCreateKey() succeeded to %s the ControlSet001 key (Status %lx)\n",
970  Disposition == REG_CREATED_NEW_KEY ? "create" : /* REG_OPENED_EXISTING_KEY */ "open",
971  Status);
972  }
974 
975  /* Create the 'HKLM\SYSTEM\CurrentControlSet' symlink */
977  L"SYSTEM\\CurrentControlSet",
978  REGISTRY_SETUP_MACHINE L"SYSTEM\\ControlSet001");
979  if (!NT_SUCCESS(Status))
980  {
981  DPRINT1("CreateSymLinkKey(CurrentControlSet) failed, Status 0x%08lx\n", Status);
982  }
983 
984 
986 
987 
988 Quit:
989  /* Remove restore and backup privileges */
990  RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE, PrivilegeSet[1], FALSE, &PrivilegeSet[1]);
991  RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, PrivilegeSet[0], FALSE, &PrivilegeSet[0]);
992 
993  return Status;
994 }
995 
996 VOID
999 {
1000  NTSTATUS Status;
1001  HANDLE KeyHandle;
1004  BOOLEAN PrivilegeSet[2] = {FALSE, FALSE};
1005  UINT i;
1006  WCHAR SrcPath[MAX_PATH];
1007  WCHAR DstPath[MAX_PATH];
1008 
1009  /* Acquire restore privilege */
1010  Status = RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, TRUE, FALSE, &PrivilegeSet[0]);
1011  if (!NT_SUCCESS(Status))
1012  {
1013  DPRINT1("RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE) failed (Status 0x%08lx)\n", Status);
1014  /* Exit prematurely here.... */
1015  return;
1016  }
1017 
1018  /* Acquire backup privilege */
1019  Status = RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE, TRUE, FALSE, &PrivilegeSet[1]);
1020  if (!NT_SUCCESS(Status))
1021  {
1022  DPRINT1("RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE) failed (Status 0x%08lx)\n", Status);
1023  RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, PrivilegeSet[0], FALSE, &PrivilegeSet[0]);
1024  /* Exit prematurely here.... */
1025  return;
1026  }
1027 
1028  /*
1029  * To keep the running system clean we need first to remove the symlinks
1030  * we have created and then unmounting the hives. Finally we delete the
1031  * master registry keys.
1032  */
1033 
1034  for (i = 0; i < ARRAYSIZE(RegistryHives); ++i)
1035  {
1037  {
1038  /* Delete the registry symlink to this key */
1040  RegistryHives[i].RegSymLink);
1041  if (!NT_SUCCESS(Status))
1042  {
1043  DPRINT1("DeleteSymLinkKey(%S) failed, Status 0x%08lx\n",
1044  RegistryHives[i].RegSymLink, Status);
1045  }
1046 
1047  /* Unmount the hive */
1049  RegistryHives[i].HiveRegistryPath,
1050  1 /* REG_FORCE_UNLOAD */);
1051  if (!NT_SUCCESS(Status))
1052  {
1053  DPRINT1("Unmounting '%S' failed\n", RegistryHives[i].HiveRegistryPath);
1054  }
1055 
1056  /* Switch the hive state to 'Update' */
1058  }
1059  else
1060  {
1061  /* Delete the *DUMMY* volatile hives created for the update procedure */
1062 
1065  &KeyName,
1067  RootKeys[GetPredefKeyIndex(RegistryHives[i].PredefKeyHandle)].Handle,
1068  NULL);
1069  KeyHandle = NULL;
1071  DELETE,
1072  &ObjectAttributes);
1073  if (!NT_SUCCESS(Status))
1074  {
1075  DPRINT1("NtOpenKey(%wZ) failed, Status 0x%08lx\n", &KeyName, Status);
1076  // return;
1077  }
1078 
1080  NtClose(KeyHandle);
1081  }
1082  }
1083 
1084  /*
1085  * FIXME: Once force-unloading keys is correctly fixed, I'll fix
1086  * this code that closes some of the registry keys that were opened
1087  * inside the hives we've just unmounted above...
1088  */
1089 
1090  /* Remove the registry root keys */
1091  for (i = 0; i < ARRAYSIZE(RootKeys); ++i)
1092  {
1093  if (RootKeys[i].Handle)
1094  {
1095  NtFlushKey(RootKeys[i].Handle); // FIXME: Why does it hang? Answer: because we have some problems in CMAPI!
1098  RootKeys[i].Handle = NULL;
1099  }
1100  }
1101 
1102  //
1103  // RegBackupRegistry()
1104  //
1105  /* Now backup the hives into .sav files */
1106  for (i = 0; i < ARRAYSIZE(RegistryHives); ++i)
1107  {
1109  continue;
1110 
1111  CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 3,
1112  NtSystemRoot->Buffer, L"System32\\config", RegistryHives[i].HiveName);
1113  RtlStringCchCopyW(DstPath, ARRAYSIZE(DstPath), SrcPath);
1114  RtlStringCchCatW(DstPath, ARRAYSIZE(DstPath), L".sav");
1115 
1116  DPRINT1("Copy hive: %S ==> %S\n", SrcPath, DstPath);
1117  Status = SetupCopyFile(SrcPath, DstPath, FALSE);
1118  if (!NT_SUCCESS(Status))
1119  {
1120  DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status);
1121  // return Status;
1122  }
1123  }
1124 
1125  /* Remove restore and backup privileges */
1126  RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE, PrivilegeSet[1], FALSE, &PrivilegeSet[1]);
1127  RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, PrivilegeSet[0], FALSE, &PrivilegeSet[0]);
1128 }
1129 
1130 /* EOF */
#define HKEY_USERS
Definition: winreg.h:13
HIVE_UPDATE_STATE State
Definition: registry.c:574
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2343
BOOLEAN ImportRegistryFile(IN PCWSTR SourcePath, IN PCWSTR FileName, IN PCWSTR Section, IN LCID LocaleId, IN BOOLEAN Delete)
Definition: registry.c:507
#define FLG_ADDREG_APPEND
Definition: registry.c:46
NTSTATUS RegInitializeRegistry(IN PUNICODE_STRING NtSystemRoot)
Definition: registry.c:679
#define GetPredefKeyIndex(HKey)
Definition: registry.c:86
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define FLG_ADDREG_OVERWRITEONLY
Definition: registry.c:48
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING KeyName
Definition: ndis.h:4711
const uint16_t * PCWSTR
Definition: typedefs.h:55
#define IN
Definition: typedefs.h:38
enum _HIVE_UPDATE_STATE HIVE_UPDATE_STATE
#define TRUE
Definition: types.h:120
NTSTATUS NTAPI NtCreateKey(OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN ULONG TitleIndex, IN PUNICODE_STRING Class OPTIONAL, IN ULONG CreateOptions, OUT PULONG Disposition OPTIONAL)
Definition: ntapi.c:240
#define FLG_ADDREG_TYPE_SZ
Definition: registry.c:49
WINE_UNICODE_INLINE unsigned int strlenW(const WCHAR *str)
Definition: unicode.h:212
UNICODE_STRING NtSystemRoot
Definition: init.c:72
#define INF_STYLE_WIN4
Definition: infsupp.h:41
Type
Definition: Type.h:6
#define FLG_ADDREG_NOCLOBBER
Definition: registry.c:44
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4711
#define REG_BINARY
Definition: nt_native.h:1496
_In_ BOOLEAN Create
Definition: pstypes.h:511
#define _countof(array)
Definition: fontsub.cpp:30
#define FLG_ADDREG_KEYONLY
Definition: registry.c:47
#define HKEY_CURRENT_USER
Definition: winreg.h:11
unsigned char * PUCHAR
Definition: retypes.h:3
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
NTSTATUS SetupCopyFile(IN PCWSTR SourceFileName, IN PCWSTR DestinationFileName, IN BOOLEAN FailIfExists)
Definition: filesup.c:240
#define SE_RESTORE_PRIVILEGE
Definition: security.c:672
PCWSTR HiveRegistryPath
Definition: registry.c:571
NTSTATUS CreateSymLinkKey(IN HANDLE RootKey OPTIONAL, IN PCWSTR LinkKeyName, IN PCWSTR TargetKeyName)
Definition: regutil.c:254
VOID RegCleanupRegistry(IN PUNICODE_STRING NtSystemRoot)
Definition: registry.c:997
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
#define FLG_ADDREG_DELVAL
Definition: registry.c:45
NTSYSAPI NTSTATUS NTAPI RtlAdjustPrivilege(_In_ ULONG Privilege, _In_ BOOLEAN NewValue, _In_ BOOLEAN ForThread, _Out_ PBOOLEAN OldValue)
GLuint buffer
Definition: glext.h:5915
#define FLG_ADDREG_TYPE_MASK
Definition: registry.c:55
NTSTATUS VerifyRegistryHives(IN PUNICODE_STRING NtSystemRoot, OUT PBOOLEAN ShouldRepairRegistry)
Definition: registry.c:603
static BOOL ConnectRegistry(IN HKEY RootKey, IN PCWSTR Path, IN PCMHIVE HiveToConnect, IN PUCHAR SecurityDescriptor, IN ULONG SecurityDescriptorLength)
Definition: registry.c:1011
static BOOLEAN registry_callback(HINF hInf, PCWSTR Section, BOOLEAN Delete)
Definition: registry.c:412
pSpInfFindFirstLine SpInfFindFirstLine
Definition: infsupp.c:87
NTSTATUS DisconnectRegistry(IN HANDLE RootKey OPTIONAL, IN PCWSTR RegMountPoint, IN ULONG Flags)
Definition: regutil.c:432
DWORD LCID
Definition: nls.h:13
PCWSTR RegSymLink
Definition: registry.c:573
uint16_t * PWCHAR
Definition: typedefs.h:54
_Check_return_ unsigned long __cdecl wcstoul(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
ROOT_KEY RootKeys[]
Definition: registry.c:70
NTSTATUS VerifyRegistryHive(IN PUNICODE_STRING NtSystemRoot, IN PCWSTR RegistryKey)
Definition: regutil.c:455
struct _ROOT_KEY * PROOT_KEY
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
_In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Reserved_ ULONG _In_opt_ PUNICODE_STRING _In_ ULONG _Out_opt_ PULONG Disposition
Definition: cmfuncs.h:50
struct _HIVE_LIST_ENTRY * PHIVE_LIST_ENTRY
LONG WINAPI RegDeleteKeyW(IN HKEY hKey, IN LPCWSTR lpSubKey)
Definition: registry.c:552
uint32_t ULONG_PTR
Definition: typedefs.h:63
_In_ PUNICODE_STRING ValueName
Definition: cmfuncs.h:264
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
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
#define FLG_ADDREG_TYPE_DWORD
Definition: registry.c:53
unsigned int BOOL
Definition: ntddk_ex.h:94
C_ASSERT(_countof(RegistryHives)==NUMBER_OF_STANDARD_REGISTRY_HIVES)
#define REG_MULTI_SZ
Definition: nt_native.h:1501
#define debugstr_w
Definition: kernel32.h:32
struct NameRec_ * Name
Definition: cdprocs.h:464
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
LONG WINAPI RegDeleteValueW(IN HKEY hKey, IN LPCWSTR lpValueName OPTIONAL)
Definition: registry.c:901
Definition: bufpool.h:45
#define REG_CREATED_NEW_KEY
Definition: nt_native.h:1084
_HIVE_UPDATE_STATE
Definition: registry.c:561
pSpInfCloseInfFile SpInfCloseInfFile
Definition: infsupp.c:86
static void append_multi_sz_value(HKEY hkey, const WCHAR *value, const WCHAR *strings, DWORD str_size)
Definition: install.c:222
#define REGISTRY_SETUP_USER
Definition: registry.c:61
pSpInfGetBinaryField SpInfGetBinaryField
Definition: infsupp.c:90
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
pSpInfGetStringField SpInfGetStringField
Definition: infsupp.c:93
_In_ HANDLE Handle
Definition: extypes.h:390
Definition: registry.c:568
int * PINT
Definition: windef.h:177
#define TRACE(s)
Definition: solgame.cpp:4
#define FLG_ADDREG_TYPE_BINARY
Definition: registry.c:52
GLsizeiptr size
Definition: glext.h:5919
#define MAX_INF_STRING_LENGTH
Definition: infsupp.h:34
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
PCWSTR HiveName
Definition: registry.c:570
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define MAX_PATH
Definition: compat.h:26
static const UCHAR Index[8]
Definition: usbohci.c:18
NTSTRSAFEAPI RtlStringCchCatW(_Inout_updates_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ NTSTRSAFE_PCWSTR pszSrc)
Definition: ntstrsafe.h:601
unsigned long DWORD
Definition: ntddk_ex.h:95
NTSTATUS DeleteSymLinkKey(IN HANDLE RootKey OPTIONAL, IN PCWSTR LinkKeyName)
Definition: regutil.c:318
REFIID LPVOID DWORD dw
Definition: atlbase.h:40
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
GLbitfield flags
Definition: glext.h:7161
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
unsigned char UCHAR
Definition: xmlstorage.h:181
char * PBOOLEAN
Definition: retypes.h:11
GLsizei const GLchar *const * strings
Definition: glext.h:7622
#define FLG_ADDREG_BINVALUETYPE
Definition: registry.c:43
static const WCHAR L[]
Definition: oid.c:1250
pSpInfOpenInfFile SpInfOpenInfFile
Definition: infsupp.c:95
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
unsigned char BYTE
Definition: mem.h:68
GLenum src
Definition: glext.h:6340
pSpInfGetFieldCount SpInfGetFieldCount
Definition: infsupp.c:89
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
HANDLE GetRootKeyByName(IN PCWSTR RootKeyName, OUT PCWSTR *RootKeyMountPoint OPTIONAL)
Definition: registry.c:107
HANDLE ProcessHeap
Definition: servman.c:15
pSpInfGetMultiSzField SpInfGetMultiSzField
Definition: infsupp.c:92
Status
Definition: gdiplustypes.h:24
NTSTATUS NTAPI NtDeleteKey(IN HANDLE KeyHandle)
Definition: ntapi.c:408
#define strcmpiW(s1, s2)
Definition: unicode.h:39
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
HANDLE PredefKeyHandle
Definition: registry.c:572
HANDLE GetRootKeyByPredefKey(IN HANDLE KeyHandle, OUT PCWSTR *RootKeyMountPoint OPTIONAL)
Definition: registry.c:90
pSpInfGetIntField SpInfGetIntField
Definition: infsupp.c:91
NTSTRSAFEAPI RtlStringCchCopyW(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ NTSTRSAFE_PCWSTR pszSrc)
Definition: ntstrsafe.h:127
PCWSTR Name
Definition: registry.c:65
struct _ROOT_KEY ROOT_KEY
#define NUMBER_OF_STANDARD_REGISTRY_HIVES
Definition: registry.c:579
PCWSTR MountPoint
Definition: registry.c:66
NTSTATUS CreateRegistryFile(IN PUNICODE_STRING NtSystemRoot, IN PCWSTR RegistryKey, IN BOOLEAN IsHiveNew, IN HANDLE ProtoKeyHandle)
Definition: regutil.c:140
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define REG_EXPAND_SZ
Definition: nt_native.h:1494
NTSTATUS NTAPI NtFlushKey(IN HANDLE KeyHandle)
Definition: ntapi.c:1065
pSpInfFindNextLine SpInfFindNextLine
Definition: infsupp.c:88
GLenum GLenum dst
Definition: glext.h:6340
unsigned int UINT
Definition: ndis.h:50
NTSYSAPI NTSTATUS NTAPI NtSetValueKey(IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName, IN ULONG TitleIndex OPTIONAL, IN ULONG Type, IN PVOID Data, IN ULONG DataSize)
Definition: ntapi.c:859
HIVE_LIST_ENTRY SecurityRegistryHives[]
Definition: registry.c:594
HIVE_LIST_ENTRY RegistryHives[]
Definition: registry.c:581
#define REGISTRY_SETUP_MACHINE
Definition: registry.c:60
#define DPRINT1
Definition: precomp.h:8
NTSYSAPI NTSTATUS NTAPI NtOpenKey(OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: ntapi.c:336
WCHAR FileNameBuffer[_MAX_PATH]
Definition: framewnd.c:239
#define OUT
Definition: typedefs.h:39
static void delete_multi_sz_value(HKEY hkey, const WCHAR *value, const WCHAR *string)
Definition: install.c:267
struct tagContext Context
Definition: acpixf.h:1024
unsigned int ULONG
Definition: retypes.h:1
#define SE_BACKUP_PRIVILEGE
Definition: security.c:671
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define NUMBER_OF_SECURITY_REGISTRY_HIVES
Definition: registry.c:591
#define FLG_ADDREG_TYPE_EXPAND_SZ
Definition: registry.c:51
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
HANDLE Handle
Definition: registry.c:67
#define HKEY_CLASSES_ROOT
Definition: winreg.h:10
#define REG_NONE
Definition: nt_native.h:1492
static BOOLEAN do_reg_operation(HANDLE KeyHandle, PUNICODE_STRING ValueName, PINFCONTEXT Context, ULONG Flags)
Definition: registry.c:222
GLfloat GLfloat p
Definition: glext.h:8902
return STATUS_SUCCESS
Definition: btrfs.c:2966
#define REG_DWORD
Definition: sdbapi.c:596
struct _HIVE_LIST_ENTRY HIVE_LIST_ENTRY
#define IsPredefKey(HKey)
Definition: registry.c:83
BOOL Delete(LPCTSTR ServiceName)
Definition: delete.c:12
NTSTATUS CombinePaths(OUT PWSTR PathBuffer, IN SIZE_T cchPathSize, IN ULONG NumberOfPathComponents, IN ...)
Definition: filesup.c:681
#define HeapFree(x, y, z)
Definition: compat.h:394
NTSTATUS CreateNestedKey(PHANDLE KeyHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, ULONG CreateOptions)
Definition: regutil.c:33
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define FLG_ADDREG_TYPE_NONE
Definition: registry.c:54
#define DELETE
Definition: nt_native.h:57
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define FLG_ADDREG_TYPE_MULTI_SZ
Definition: registry.c:50
#define REG_SZ
Definition: layer.c:22
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68