ReactOS 0.4.15-dev-7961-gdcf9eb0
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
63typedef 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
92 OUT PCWSTR* RootKeyMountPoint OPTIONAL)
93{
95
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
106HANDLE
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
134static void
136 const WCHAR *value,
137 const WCHAR *strings,
138 DWORD str_size )
139{
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) );
170 }
171 done:
173}
174#endif
175
176/***********************************************************************
177 * delete_multi_sz_value
178 *
179 * Remove a string from a multisz registry value.
180 */
181#if 0
182static 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) );
209 (BYTE *)(buffer + size), dst - (buffer + size) );
210 }
211 done:
213}
214#endif
215
216/***********************************************************************
217 * do_reg_operation
218 *
219 * Perform an add/delete registry operation depending on the flags.
220 */
221static 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 {
263 Type = REG_SZ;
264 break;
265
268 break;
269
272 break;
273
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
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
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
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 }
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 */
411static 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
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
508 IN PCWSTR SourcePath,
510 IN PCWSTR Section,
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
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
568typedef 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
581HIVE_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
594HIVE_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
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 */
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
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 */
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,
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,
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
988Quit:
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
996VOID
999{
1004 BOOLEAN PrivilegeSet[2] = {FALSE, FALSE};
1005 UINT i;
1006 WCHAR SrcPath[MAX_PATH];
1008
1009 /* Acquire restore privilege */
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 */
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,
1073 if (!NT_SUCCESS(Status))
1074 {
1075 DPRINT1("NtOpenKey(%wZ) failed, Status 0x%08lx\n", &KeyName, Status);
1076 // return;
1077 }
1078
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);
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 */
unsigned char BOOLEAN
Type
Definition: Type.h:7
struct NameRec_ * Name
Definition: cdprocs.h:460
LONG NTSTATUS
Definition: precomp.h:26
HANDLE ProcessHeap
Definition: servman.c:15
#define DPRINT1
Definition: precomp.h:8
WCHAR FileNameBuffer[MAX_PATH]
Definition: framewnd.c:233
BOOL Delete(LPCTSTR ServiceName)
Definition: delete.c:12
BOOLEAN ImportRegistryFile(IN PCWSTR SourcePath, IN PCWSTR FileName, IN PCWSTR Section, IN LCID LocaleId, IN BOOLEAN Delete)
Definition: registry.c:507
#define FLG_ADDREG_OVERWRITEONLY
Definition: registry.c:48
static BOOLEAN registry_callback(HINF hInf, PCWSTR Section, BOOLEAN Delete)
Definition: registry.c:412
#define FLG_ADDREG_TYPE_MASK
Definition: registry.c:55
VOID RegCleanupRegistry(IN PUNICODE_STRING NtSystemRoot)
Definition: registry.c:997
enum _HIVE_UPDATE_STATE HIVE_UPDATE_STATE
ROOT_KEY RootKeys[]
Definition: registry.c:70
struct _ROOT_KEY * PROOT_KEY
#define FLG_ADDREG_TYPE_BINARY
Definition: registry.c:52
struct _ROOT_KEY ROOT_KEY
#define FLG_ADDREG_TYPE_SZ
Definition: registry.c:49
HANDLE GetRootKeyByName(IN PCWSTR RootKeyName, OUT PCWSTR *RootKeyMountPoint OPTIONAL)
Definition: registry.c:107
#define FLG_ADDREG_BINVALUETYPE
Definition: registry.c:43
HIVE_LIST_ENTRY SecurityRegistryHives[]
Definition: registry.c:594
HIVE_LIST_ENTRY RegistryHives[]
Definition: registry.c:581
#define FLG_ADDREG_APPEND
Definition: registry.c:46
#define REGISTRY_SETUP_USER
Definition: registry.c:61
HANDLE GetRootKeyByPredefKey(IN HANDLE KeyHandle, OUT PCWSTR *RootKeyMountPoint OPTIONAL)
Definition: registry.c:90
#define FLG_ADDREG_TYPE_EXPAND_SZ
Definition: registry.c:51
#define FLG_ADDREG_DELVAL
Definition: registry.c:45
#define REGISTRY_SETUP_MACHINE
Definition: registry.c:60
#define IsPredefKey(HKey)
Definition: registry.c:83
struct _HIVE_LIST_ENTRY * PHIVE_LIST_ENTRY
#define FLG_ADDREG_TYPE_MULTI_SZ
Definition: registry.c:50
#define GetPredefKeyIndex(HKey)
Definition: registry.c:86
static BOOLEAN do_reg_operation(HANDLE KeyHandle, PUNICODE_STRING ValueName, PINFCONTEXT Context, ULONG Flags)
Definition: registry.c:222
#define NUMBER_OF_STANDARD_REGISTRY_HIVES
Definition: registry.c:579
#define FLG_ADDREG_TYPE_NONE
Definition: registry.c:54
NTSTATUS RegInitializeRegistry(IN PUNICODE_STRING NtSystemRoot)
Definition: registry.c:679
_HIVE_UPDATE_STATE
Definition: registry.c:562
@ Create
Definition: registry.c:563
@ Update
Definition: registry.c:565
@ Repair
Definition: registry.c:564
#define FLG_ADDREG_KEYONLY
Definition: registry.c:47
#define FLG_ADDREG_NOCLOBBER
Definition: registry.c:44
#define FLG_ADDREG_TYPE_DWORD
Definition: registry.c:53
NTSTATUS VerifyRegistryHives(IN PUNICODE_STRING NtSystemRoot, OUT PBOOLEAN ShouldRepairRegistry)
Definition: registry.c:603
#define NUMBER_OF_SECURITY_REGISTRY_HIVES
Definition: registry.c:591
struct _HIVE_LIST_ENTRY HIVE_LIST_ENTRY
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:590
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:608
Definition: bufpool.h:45
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#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:32
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
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
#define GetProcessHeap()
Definition: compat.h:736
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define HeapAlloc
Definition: compat.h:733
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
static void append_multi_sz_value(HKEY hkey, const WCHAR *value, const WCHAR *strings, DWORD str_size)
Definition: install.c:223
static void delete_multi_sz_value(HKEY hkey, const WCHAR *value, const WCHAR *string)
Definition: install.c:268
NTSTATUS CombinePaths(OUT PWSTR PathBuffer, IN SIZE_T cchPathSize, IN ULONG NumberOfPathComponents, IN ...)
Definition: filesup.c:681
NTSTATUS SetupCopyFile(IN PCWSTR SourceFileName, IN PCWSTR DestinationFileName, IN BOOLEAN FailIfExists)
Definition: filesup.c:240
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
size_t total
ULONG Handle
Definition: gdb_input.c:15
Status
Definition: gdiplustypes.h:25
@ Ok
Definition: gdiplustypes.h:26
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLsizeiptr size
Definition: glext.h:5919
GLenum src
Definition: glext.h:6340
GLsizei const GLchar *const * strings
Definition: glext.h:7622
GLuint buffer
Definition: glext.h:5915
GLenum GLenum dst
Definition: glext.h:6340
GLbitfield flags
Definition: glext.h:7161
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
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
_Check_return_ unsigned long __cdecl wcstoul(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
REFIID LPVOID DWORD_PTR dw
Definition: atlbase.h:40
pSpInfGetBinaryField SpInfGetBinaryField
Definition: infsupp.c:90
pSpInfGetMultiSzField SpInfGetMultiSzField
Definition: infsupp.c:92
#define INF_STYLE_WIN4
Definition: infsupp.h:41
pSpInfGetStringField SpInfGetStringField
Definition: infsupp.c:93
#define MAX_INF_STRING_LENGTH
Definition: infsupp.h:34
pSpInfGetFieldCount SpInfGetFieldCount
Definition: infsupp.c:89
pSpInfFindNextLine SpInfFindNextLine
Definition: infsupp.c:88
pSpInfGetIntField SpInfGetIntField
Definition: infsupp.c:91
pSpInfFindFirstLine SpInfFindFirstLine
Definition: infsupp.c:87
pSpInfOpenInfFile SpInfOpenInfFile
Definition: infsupp.c:95
pSpInfCloseInfFile SpInfCloseInfFile
Definition: infsupp.c:86
#define C_ASSERT(e)
Definition: intsafe.h:73
#define debugstr_w
Definition: kernel32.h:32
#define REG_SZ
Definition: layer.c:22
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define SE_BACKUP_PRIVILEGE
Definition: security.c:671
#define SE_RESTORE_PRIVILEGE
Definition: security.c:672
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
unsigned int UINT
Definition: ndis.h:50
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4715
_In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Reserved_ ULONG _In_opt_ PUNICODE_STRING _In_ ULONG _Out_opt_ PULONG Disposition
Definition: cmfuncs.h:56
NTSYSAPI NTSTATUS NTAPI RtlAdjustPrivilege(_In_ ULONG Privilege, _In_ BOOLEAN NewValue, _In_ BOOLEAN ForThread, _Out_ PBOOLEAN OldValue)
NTSYSAPI NTSTATUS NTAPI NtOpenKey(OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: ntapi.c:336
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
#define REG_BINARY
Definition: nt_native.h:1496
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
#define REG_CREATED_NEW_KEY
Definition: nt_native.h:1084
#define REG_MULTI_SZ
Definition: nt_native.h:1501
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
#define DELETE
Definition: nt_native.h:57
#define REG_NONE
Definition: nt_native.h:1492
#define REG_EXPAND_SZ
Definition: nt_native.h:1494
NTSTATUS NTAPI NtDeleteKey(IN HANDLE KeyHandle)
Definition: ntapi.c:408
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
NTSTATUS NTAPI NtFlushKey(IN HANDLE KeyHandle)
Definition: ntapi.c:1085
UNICODE_STRING NtSystemRoot
Definition: init.c:76
NTSTRSAFEAPI RtlStringCchCopyW(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ NTSTRSAFE_PCWSTR pszSrc)
Definition: ntstrsafe.h:127
NTSTRSAFEAPI RtlStringCchCatW(_Inout_updates_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ NTSTRSAFE_PCWSTR pszSrc)
Definition: ntstrsafe.h:601
#define L(x)
Definition: ntvdm.h:50
#define strcmpiW(s1, s2)
Definition: unicode.h:39
#define strlenW(s)
Definition: unicode.h:28
NTSTATUS DisconnectRegistry(IN HANDLE RootKey OPTIONAL, IN PCWSTR RegMountPoint, IN ULONG Flags)
Definition: regutil.c:432
NTSTATUS VerifyRegistryHive(IN PUNICODE_STRING NtSystemRoot, IN PCWSTR RegistryKey)
Definition: regutil.c:455
NTSTATUS CreateNestedKey(PHANDLE KeyHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, ULONG CreateOptions)
Definition: regutil.c:33
NTSTATUS CreateRegistryFile(IN PUNICODE_STRING NtSystemRoot, IN PCWSTR RegistryKey, IN BOOLEAN IsHiveNew, IN HANDLE ProtoKeyHandle)
Definition: regutil.c:140
NTSTATUS CreateSymLinkKey(IN HANDLE RootKey OPTIONAL, IN PCWSTR LinkKeyName, IN PCWSTR TargetKeyName)
Definition: regutil.c:254
NTSTATUS DeleteSymLinkKey(IN HANDLE RootKey OPTIONAL, IN PCWSTR LinkKeyName)
Definition: regutil.c:318
NTSTATUS ConnectRegistry(IN HANDLE RootKey OPTIONAL, IN PCWSTR RegMountPoint, IN PUNICODE_STRING NtSystemRoot, IN PCWSTR RegistryKey)
Definition: regutil.c:391
#define REG_DWORD
Definition: sdbapi.c:596
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
DWORD LCID
Definition: nls.h:13
IN HANDLE DstPath
Definition: fsutil.h:76
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
#define _countof(array)
Definition: sndvol32.h:68
#define TRACE(s)
Definition: solgame.cpp:4
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
Definition: registry.c:569
PCWSTR HiveName
Definition: registry.c:570
HIVE_UPDATE_STATE State
Definition: registry.c:574
PCWSTR RegSymLink
Definition: registry.c:573
HANDLE PredefKeyHandle
Definition: registry.c:572
PCWSTR HiveRegistryPath
Definition: registry.c:571
HANDLE Handle
Definition: registry.c:67
PCWSTR MountPoint
Definition: registry.c:66
PCWSTR Name
Definition: registry.c:65
const uint16_t * PCWSTR
Definition: typedefs.h:57
unsigned char * PBOOLEAN
Definition: typedefs.h:53
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
uint16_t * PWCHAR
Definition: typedefs.h:56
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
Definition: pdh_main.c:94
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2699
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_ PCUNICODE_STRING _In_ PCUNICODE_STRING _In_ LCID LocaleId
Definition: wdfpdo.h:437
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:243
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
int * PINT
Definition: windef.h:177
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define HKEY_CURRENT_USER
Definition: winreg.h:11
#define HKEY_CLASSES_ROOT
Definition: winreg.h:10
#define HKEY_USERS
Definition: winreg.h:13
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
unsigned char UCHAR
Definition: xmlstorage.h:181
__wchar_t WCHAR
Definition: xmlstorage.h:180
unsigned char BYTE
Definition: xxhash.c:193