2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: ntoskrnl/config/cmsysini.c
5 * PURPOSE: Configuration Manager - System Initialization Code
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
9 /* INCLUDES ******************************************************************/
16 KGUARDED_MUTEX CmpSelfHealQueueLock
;
17 LIST_ENTRY CmpSelfHealQueueListHead
;
18 PEPROCESS CmpSystemProcess
;
19 BOOLEAN HvShutdownComplete
;
21 /* FUNCTIONS *****************************************************************/
25 CmpInitHiveFromFile(IN PCUNICODE_STRING HiveName
,
31 ULONG HiveDisposition
, LogDisposition
;
32 HANDLE FileHandle
= NULL
, LogHandle
= NULL
;
34 ULONG Operation
, FileType
;
35 PEREGISTRY_HIVE NewHive
;
41 /* Open or create the hive files */
42 Status
= CmpOpenHiveFiles(HiveName
,
52 if (!NT_SUCCESS(Status
)) return Status
;
54 /* Check if we have a log handle */
55 FileType
= (LogHandle
) ? HFILE_TYPE_LOG
: HFILE_TYPE_PRIMARY
;
57 /* Check if we created or opened the hive */
58 if (HiveDisposition
== FILE_CREATED
)
60 /* Do a create operation */
61 Operation
= HINIT_CREATE
;
66 /* Open it as a file */
67 Operation
= HINIT_FILE
;
71 /* Check if we're sharing hives */
72 if (CmpShareSystemHives
)
74 /* Then force using the primary hive */
75 FileType
= HFILE_TYPE_PRIMARY
;
78 /* Get rid of the log handle */
84 /* Check if we're too late */
85 if (HvShutdownComplete
)
89 if (LogHandle
) ZwClose(LogHandle
);
90 return STATUS_TOO_LATE
;
93 /* Initialize the hive */
94 Status
= CmpInitializeHive((PCMHIVE
*)&NewHive
,
104 if (!NT_SUCCESS(Status
))
108 if (LogHandle
) ZwClose(LogHandle
);
112 /* Success, return hive */
113 *Hive
= (PCMHIVE
)NewHive
;
115 /* ROS: Init root key cell and prepare the hive */
116 if (Operation
== HINIT_CREATE
) CmCreateRootNode(&NewHive
->Hive
, L
"");
117 CmPrepareHive(&NewHive
->Hive
);
119 /* Duplicate the hive name */
120 NewHive
->HiveFileName
.Buffer
= ExAllocatePoolWithTag(PagedPool
,
123 if (NewHive
->HiveFileName
.Buffer
)
125 /* Copy the string */
126 RtlCopyMemory(NewHive
->HiveFileName
.Buffer
,
129 NewHive
->HiveFileName
.Length
= HiveName
->Length
;
130 NewHive
->HiveFileName
.MaximumLength
= HiveName
->MaximumLength
;
133 /* ROS: Close the hive files */
135 if (LogHandle
) ZwClose(LogHandle
);
138 return STATUS_SUCCESS
;
143 CmpSetSystemValues(IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
145 OBJECT_ATTRIBUTES ObjectAttributes
;
146 UNICODE_STRING KeyName
, ValueName
;
149 ASSERT(LoaderBlock
!= NULL
);
150 if (ExpInTextModeSetup
) return STATUS_SUCCESS
;
152 /* Setup attributes for loader options */
153 RtlInitUnicodeString(&KeyName
,
154 L
"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\"
156 InitializeObjectAttributes(&ObjectAttributes
,
158 OBJ_CASE_INSENSITIVE
,
161 Status
= NtOpenKey(&KeyHandle
, KEY_WRITE
, &ObjectAttributes
);
162 if (!NT_SUCCESS(Status
)) goto Quickie
;
164 /* Key opened, now write to the key */
165 RtlInitUnicodeString(&KeyName
, L
"SystemStartOptions");
166 Status
= NtSetValueKey(KeyHandle
,
170 CmpLoadOptions
.Buffer
,
171 CmpLoadOptions
.Length
);
172 if (!NT_SUCCESS(Status
)) goto Quickie
;
174 /* Setup value name for system boot device */
175 RtlInitUnicodeString(&KeyName
, L
"SystemBootDevice");
176 RtlCreateUnicodeStringFromAsciiz(&ValueName
, LoaderBlock
->NtBootPathName
);
177 Status
= NtSetValueKey(KeyHandle
,
185 /* Free the buffers */
186 RtlFreeUnicodeString(&ValueName
);
188 /* Close the key and return */
191 /* Return the status */
197 CmpCreateControlSet(IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
199 UNICODE_STRING ConfigName
= RTL_CONSTANT_STRING(L
"Control\\IDConfigDB");
200 UNICODE_STRING SelectName
=
201 RTL_CONSTANT_STRING(L
"\\Registry\\Machine\\System\\Select");
202 UNICODE_STRING KeyName
;
203 OBJECT_ATTRIBUTES ObjectAttributes
;
204 CHAR ValueInfoBuffer
[128];
205 PKEY_VALUE_FULL_INFORMATION ValueInfo
;
207 WCHAR UnicodeBuffer
[128];
208 HANDLE SelectHandle
, KeyHandle
, ConfigHandle
= NULL
, ProfileHandle
= NULL
;
209 HANDLE ParentHandle
= NULL
;
210 ULONG ControlSet
, HwProfile
;
211 ANSI_STRING TempString
;
213 ULONG ResultLength
, Disposition
;
214 PLOADER_PARAMETER_EXTENSION LoaderExtension
;
216 if (ExpInTextModeSetup
) return STATUS_SUCCESS
;
218 /* Open the select key */
219 InitializeObjectAttributes(&ObjectAttributes
,
221 OBJ_CASE_INSENSITIVE
,
224 Status
= NtOpenKey(&SelectHandle
, KEY_READ
, &ObjectAttributes
);
225 if (!NT_SUCCESS(Status
)) return(Status
);
227 /* Open the current value */
228 RtlInitUnicodeString(&KeyName
, L
"Current");
229 Status
= NtQueryValueKey(SelectHandle
,
231 KeyValueFullInformation
,
233 sizeof(ValueInfoBuffer
),
235 NtClose(SelectHandle
);
236 if (!NT_SUCCESS(Status
)) return Status
;
238 /* Get the actual value pointer, and get the control set ID */
239 ValueInfo
= (PKEY_VALUE_FULL_INFORMATION
)ValueInfoBuffer
;
240 ControlSet
= *(PULONG
)((PUCHAR
)ValueInfo
+ ValueInfo
->DataOffset
);
242 /* Create the current control set key */
243 RtlInitUnicodeString(&KeyName
,
244 L
"\\Registry\\Machine\\System\\CurrentControlSet");
245 InitializeObjectAttributes(&ObjectAttributes
,
247 OBJ_CASE_INSENSITIVE
,
251 Status
= NtCreateKey(&KeyHandle
,
256 REG_OPTION_VOLATILE
| REG_OPTION_CREATE_LINK
,
258 if (!NT_SUCCESS(Status
)) return Status
;
261 ASSERT(Disposition
== REG_CREATED_NEW_KEY
);
263 /* Initialize the symbolic link name */
265 "\\Registry\\Machine\\System\\ControlSet%03ld",
267 RtlInitAnsiString(&TempString
, Buffer
);
269 /* Create a Unicode string out of it */
270 KeyName
.MaximumLength
= sizeof(UnicodeBuffer
);
271 KeyName
.Buffer
= UnicodeBuffer
;
272 Status
= RtlAnsiStringToUnicodeString(&KeyName
, &TempString
, FALSE
);
275 Status
= NtSetValueKey(KeyHandle
,
276 &CmSymbolicLinkValueName
,
281 if (!NT_SUCCESS(Status
)) return Status
;
283 /* Get the configuration database key */
284 InitializeObjectAttributes(&ObjectAttributes
,
286 OBJ_CASE_INSENSITIVE
,
289 Status
= NtOpenKey(&ConfigHandle
, KEY_READ
, &ObjectAttributes
);
292 /* Check if we don't have one */
293 if (!NT_SUCCESS(Status
))
295 /* Cleanup and exit */
300 /* Now get the current config */
301 RtlInitUnicodeString(&KeyName
, L
"CurrentConfig");
302 Status
= NtQueryValueKey(ConfigHandle
,
304 KeyValueFullInformation
,
306 sizeof(ValueInfoBuffer
),
309 /* Set pointer to buffer */
310 ValueInfo
= (PKEY_VALUE_FULL_INFORMATION
)ValueInfoBuffer
;
312 /* Check if we failed or got a non DWORD-value */
313 if (!(NT_SUCCESS(Status
)) || (ValueInfo
->Type
!= REG_DWORD
)) goto Cleanup
;
315 /* Get the hadware profile */
316 HwProfile
= *(PULONG
)((PUCHAR
)ValueInfo
+ ValueInfo
->DataOffset
);
318 /* Open the hardware profile key */
319 RtlInitUnicodeString(&KeyName
,
320 L
"\\Registry\\Machine\\System\\CurrentControlSet"
321 L
"\\Hardware Profiles");
322 InitializeObjectAttributes(&ObjectAttributes
,
324 OBJ_CASE_INSENSITIVE
,
327 Status
= NtOpenKey(&ParentHandle
, KEY_READ
, &ObjectAttributes
);
328 if (!NT_SUCCESS(Status
))
330 /* Exit and clean up */
335 /* Build the profile name */
336 sprintf(Buffer
, "%04ld", HwProfile
);
337 RtlInitAnsiString(&TempString
, Buffer
);
339 /* Convert it to Unicode */
340 KeyName
.MaximumLength
= sizeof(UnicodeBuffer
);
341 KeyName
.Buffer
= UnicodeBuffer
;
342 Status
= RtlAnsiStringToUnicodeString(&KeyName
,
345 ASSERT(Status
== STATUS_SUCCESS
);
347 /* Open the associated key */
348 InitializeObjectAttributes(&ObjectAttributes
,
350 OBJ_CASE_INSENSITIVE
,
353 Status
= NtOpenKey(&ProfileHandle
,
354 KEY_READ
| KEY_WRITE
,
356 if (!NT_SUCCESS (Status
))
358 /* Cleanup and exit */
363 /* Check if we have a loader block extension */
364 LoaderExtension
= LoaderBlock
->Extension
;
367 ASSERTMSG("ReactOS doesn't support NTLDR Profiles yet!\n", FALSE
);
370 /* Create the current hardware profile key */
371 RtlInitUnicodeString(&KeyName
,
372 L
"\\Registry\\Machine\\System\\CurrentControlSet\\"
373 L
"Hardware Profiles\\Current");
374 InitializeObjectAttributes(&ObjectAttributes
,
376 OBJ_CASE_INSENSITIVE
,
379 Status
= NtCreateKey(&KeyHandle
,
384 REG_OPTION_VOLATILE
| REG_OPTION_CREATE_LINK
,
386 if (NT_SUCCESS(Status
))
389 ASSERT(Disposition
== REG_CREATED_NEW_KEY
);
391 /* Create the profile name */
393 "\\Registry\\Machine\\System\\CurrentControlSet\\"
394 "Hardware Profiles\\%04ld",
396 RtlInitAnsiString(&TempString
, Buffer
);
398 /* Convert it to Unicode */
399 KeyName
.MaximumLength
= sizeof(UnicodeBuffer
);
400 KeyName
.Buffer
= UnicodeBuffer
;
401 Status
= RtlAnsiStringToUnicodeString(&KeyName
,
404 ASSERT(STATUS_SUCCESS
== Status
);
407 Status
= NtSetValueKey(KeyHandle
,
408 &CmSymbolicLinkValueName
,
416 /* Close every opened handle */
418 if (ConfigHandle
) NtClose(ConfigHandle
);
419 if (ProfileHandle
) NtClose(ProfileHandle
);
420 if (ParentHandle
) NtClose(ParentHandle
);
423 return STATUS_SUCCESS
;
428 CmpInitializeSystemHive(IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
431 ANSI_STRING LoadString
;
436 UNICODE_STRING KeyName
;
437 PEREGISTRY_HIVE SystemHive
= NULL
;
438 UNICODE_STRING HiveName
= RTL_CONSTANT_STRING(L
"SYSTEM");
439 PSECURITY_DESCRIPTOR SecurityDescriptor
;
442 /* Setup the ansi string */
443 RtlInitAnsiString(&LoadString
, LoaderBlock
->LoadOptions
);
445 /* Allocate the unicode buffer */
446 Length
= LoadString
.Length
* sizeof(WCHAR
) + sizeof(UNICODE_NULL
);
447 Buffer
= ExAllocatePoolWithTag(PagedPool
, Length
, TAG_CM
);
451 KEBUGCHECKEX(BAD_SYSTEM_CONFIG_INFO
, 3, 1, (ULONG_PTR
)LoaderBlock
, 0);
454 /* Setup the unicode string */
455 RtlInitEmptyUnicodeString(&CmpLoadOptions
, Buffer
, (USHORT
)Length
);
457 /* Add the load options and null-terminate */
458 RtlAnsiStringToUnicodeString(&CmpLoadOptions
, &LoadString
, FALSE
);
459 CmpLoadOptions
.Buffer
[LoadString
.Length
] = UNICODE_NULL
;
460 CmpLoadOptions
.Length
+= sizeof(WCHAR
);
462 /* Get the System Hive base address */
463 HiveBase
= LoaderBlock
->RegistryBase
;
467 ((PHBASE_BLOCK
)HiveBase
)->Length
= LoaderBlock
->RegistryLength
;
468 Status
= CmpInitializeHive((PCMHIVE
*)&SystemHive
,
470 0, //HIVE_NOLAZYFLUSH,
478 if (!NT_SUCCESS(Status
)) return FALSE
;
479 CmPrepareHive(&SystemHive
->Hive
);
481 /* Set the hive filename */
482 RtlCreateUnicodeString(&SystemHive
->HiveFileName
, SYSTEM_REG_FILE
);
484 /* We imported, no need to create a new hive */
487 /* Manually set the hive as volatile, if in Live CD mode */
488 if (CmpShareSystemHives
) SystemHive
->Hive
.HiveFlags
= HIVE_VOLATILE
;
494 Status
= CmpInitializeHive((PCMHIVE
*)&SystemHive
,
504 if (!NT_SUCCESS(Status
)) return FALSE
;
507 /* Tell CmpLinkHiveToMaster to allocate a hive */
511 /* Save the boot type */
512 if (SystemHive
) CmpBootType
= SystemHive
->Hive
.BaseBlock
->BootType
;
514 /* Are we in self-healing mode? */
517 /* Disable self-healing internally and check if boot type wanted it */
521 /* We're disabled, so bugcheck */
522 KEBUGCHECKEX(BAD_SYSTEM_CONFIG_INFO
,
525 (ULONG_PTR
)SystemHive
,
530 /* Create the default security descriptor */
531 SecurityDescriptor
= CmpHiveRootSecurityDescriptor();
533 /* Attach it to the system key */
534 RtlInitUnicodeString(&KeyName
, REG_SYSTEM_KEY_NAME
);
535 Status
= CmpLinkHiveToMaster(&KeyName
,
541 /* Free the security descriptor */
542 ExFreePool(SecurityDescriptor
);
543 if (!NT_SUCCESS(Status
)) return FALSE
;
545 /* Add the hive to the hive list */
546 CmpMachineHiveList
[3].CmHive
= (PCMHIVE
)SystemHive
;
554 CmpCreateObjectTypes(VOID
)
556 OBJECT_TYPE_INITIALIZER ObjectTypeInitializer
;
558 GENERIC_MAPPING CmpKeyMapping
= {KEY_READ
,
564 /* Initialize the Key object type */
565 RtlZeroMemory(&ObjectTypeInitializer
, sizeof(ObjectTypeInitializer
));
566 RtlInitUnicodeString(&Name
, L
"Key");
567 ObjectTypeInitializer
.Length
= sizeof(ObjectTypeInitializer
);
568 ObjectTypeInitializer
.DefaultPagedPoolCharge
= sizeof(CM_KEY_BODY
);
569 ObjectTypeInitializer
.GenericMapping
= CmpKeyMapping
;
570 ObjectTypeInitializer
.PoolType
= PagedPool
;
571 ObjectTypeInitializer
.ValidAccessMask
= KEY_ALL_ACCESS
;
572 ObjectTypeInitializer
.UseDefaultObject
= TRUE
;
573 ObjectTypeInitializer
.DeleteProcedure
= CmpDeleteKeyObject
;
574 ObjectTypeInitializer
.ParseProcedure
= CmpParseKey
;
575 ObjectTypeInitializer
.SecurityProcedure
= CmpSecurityMethod
;
576 ObjectTypeInitializer
.QueryNameProcedure
= CmpQueryKeyName
;
577 //ObjectTypeInitializer.CloseProcedure = CmpCloseKeyObject;
578 ObjectTypeInitializer
.SecurityRequired
= TRUE
;
581 return ObCreateObjectType(&Name
, &ObjectTypeInitializer
, NULL
, &CmpKeyObjectType
);
586 CmpCreateRootNode(IN PHHIVE Hive
,
588 OUT PHCELL_INDEX Index
)
590 UNICODE_STRING KeyName
;
591 PCM_KEY_NODE KeyCell
;
592 LARGE_INTEGER SystemTime
;
595 /* Initialize the node name and allocate it */
596 RtlInitUnicodeString(&KeyName
, Name
);
597 *Index
= HvAllocateCell(Hive
,
598 FIELD_OFFSET(CM_KEY_NODE
, Name
) +
599 CmpNameSize(Hive
, &KeyName
),
602 if (*Index
== HCELL_NIL
) return FALSE
;
604 /* Set the cell index and get the data */
605 Hive
->BaseBlock
->RootCell
= *Index
;
606 KeyCell
= (PCM_KEY_NODE
)HvGetCell(Hive
, *Index
);
607 if (!KeyCell
) return FALSE
;
610 KeyCell
->Signature
= (USHORT
)CM_KEY_NODE_SIGNATURE
;;
611 KeyCell
->Flags
= KEY_HIVE_ENTRY
| KEY_NO_DELETE
;
612 KeQuerySystemTime(&SystemTime
);
613 KeyCell
->LastWriteTime
= SystemTime
;
614 KeyCell
->Parent
= HCELL_NIL
;
615 KeyCell
->SubKeyCounts
[Stable
] = 0;
616 KeyCell
->SubKeyCounts
[Volatile
] = 0;
617 KeyCell
->SubKeyLists
[Stable
] = HCELL_NIL
;
618 KeyCell
->SubKeyLists
[Volatile
] = HCELL_NIL
;
619 KeyCell
->ValueList
.Count
= 0;
620 KeyCell
->ValueList
.List
= HCELL_NIL
;
621 KeyCell
->Security
= HCELL_NIL
;
622 KeyCell
->Class
= HCELL_NIL
;
623 KeyCell
->ClassLength
= 0;
624 KeyCell
->MaxNameLen
= 0;
625 KeyCell
->MaxClassLen
= 0;
626 KeyCell
->MaxValueNameLen
= 0;
627 KeyCell
->MaxValueDataLen
= 0;
629 /* Copy the name (this will also set the length) */
630 KeyCell
->NameLength
= CmpCopyName(Hive
, (PWCHAR
)KeyCell
->Name
, &KeyName
);
632 /* Check if the name was compressed */
633 if (KeyCell
->NameLength
< KeyName
.Length
)
636 KeyCell
->Flags
|= KEY_COMP_NAME
;
640 HvReleaseCell(Hive
, *Index
);
646 CmpCreateRegistryRoot(VOID
)
648 UNICODE_STRING KeyName
;
649 OBJECT_ATTRIBUTES ObjectAttributes
;
651 PCM_KEY_BODY RootKey
;
655 HCELL_INDEX RootIndex
;
657 PCM_KEY_NODE KeyCell
;
658 PSECURITY_DESCRIPTOR SecurityDescriptor
;
659 PCM_KEY_CONTROL_BLOCK Kcb
;
662 /* Setup the root node */
663 if (!CmpCreateRootNode(&CmiVolatileHive
->Hive
, L
"REGISTRY", &RootIndex
))
670 /* Create '\Registry' key. */
671 RtlInitUnicodeString(&KeyName
, L
"\\Registry");
672 SecurityDescriptor
= CmpHiveRootSecurityDescriptor();
673 InitializeObjectAttributes(&ObjectAttributes
,
675 OBJ_CASE_INSENSITIVE
,
678 Status
= ObCreateObject(KernelMode
,
687 ExFreePool(SecurityDescriptor
);
688 if (!NT_SUCCESS(Status
)) return FALSE
;
690 /* Sanity check, and get the key cell */
691 ASSERT((&CmiVolatileHive
->Hive
)->ReleaseCellRoutine
== NULL
);
692 KeyCell
= (PCM_KEY_NODE
)HvGetCell(&CmiVolatileHive
->Hive
, RootIndex
);
693 if (!KeyCell
) return FALSE
;
696 RtlInitUnicodeString(&KeyName
, L
"Registry");
697 Kcb
= CmpCreateKeyControlBlock(&CmiVolatileHive
->Hive
,
703 if (!Kcb
) return FALSE
;
705 /* Initialize the object */
707 RootKey
->Type
= TAG('k', 'v', '0', '2';
708 RootKey
->KeyControlBlock
= Kcb
;
709 RootKey
->NotifyBlock
= NULL
;
710 RootKey
->ProcessID
= PsGetCurrentProcessId();
712 RtlpCreateUnicodeString(&RootKey
->Name
, L
"Registry", NonPagedPool
);
713 RootKey
->RegistryHive
= CmiVolatileHive
;
714 RootKey
->KeyCellOffset
= RootIndex
;
715 RootKey
->KeyCell
= KeyCell
;
716 RootKey
->ParentKey
= RootKey
;
718 RootKey
->SubKeyCounts
= 0;
719 RootKey
->SubKeys
= NULL
;
720 RootKey
->SizeOfSubKeys
= 0;
723 /* Insert it into the object list head */
724 EnlistKeyBodyWithKCB(RootKey
, 0);
726 /* Insert the key into the namespace */
727 Status
= ObInsertObject(RootKey
,
732 &CmpRegistryRootHandle
);
733 if (!NT_SUCCESS(Status
)) return FALSE
;
735 /* Reference the key again so that we never lose it */
736 Status
= ObReferenceObjectByHandle(CmpRegistryRootHandle
,
742 if (!NT_SUCCESS(Status
)) return FALSE
;
744 /* Completely sucessful */
752 OBJECT_ATTRIBUTES ObjectAttributes
;
753 UNICODE_STRING KeyName
;
756 LARGE_INTEGER DueTime
;
759 PEREGISTRY_HIVE HardwareHive
;
762 PSECURITY_DESCRIPTOR SecurityDescriptor
;
765 /* Check if this is PE-boot */
768 /* Set registry to PE mode */
769 CmpMiniNTBoot
= TRUE
;
770 CmpShareSystemHives
= TRUE
;
773 /* Initialize the hive list and lock */
774 InitializeListHead(&CmpHiveListHead
);
775 ExInitializePushLock((PVOID
)&CmpHiveListHeadLock
);
776 ExInitializePushLock((PVOID
)&CmpLoadHiveLock
);
778 /* Initialize registry lock */
779 ExInitializeResourceLite(&CmpRegistryLock
);
781 /* Initialize the cache */
782 CmpInitializeCache();
784 /* Initialize allocation and delayed dereferencing */
785 CmpInitCmPrivateAlloc();
786 CmpInitCmPrivateDelayAlloc();
787 CmpInitDelayDerefKCBEngine();
789 /* Initialize callbacks */
792 /* Initialize self healing */
793 KeInitializeGuardedMutex(&CmpSelfHealQueueLock
);
794 InitializeListHead(&CmpSelfHealQueueListHead
);
796 /* Save the current process and lock the registry */
797 CmpSystemProcess
= PsGetCurrentProcess();
800 /* OLD CM: Initialize the key object list */
801 InitializeListHead(&CmiKeyObjectListHead
);
802 InitializeListHead(&CmiConnectedHiveList
);
804 /* OLD CM: Initialize the worker timer */
805 KeInitializeTimerEx(&CmiWorkerTimer
, SynchronizationTimer
);
807 /* OLD CM: Initialize the worker thread */
808 Status
= PsCreateSystemThread(&ThreadHandle
,
815 if (!NT_SUCCESS(Status
)) return FALSE
;
817 /* OLD CM: Start the timer */
818 DueTime
.QuadPart
= -1;
819 KeSetTimerEx(&CmiWorkerTimer
, DueTime
, 5000, NULL
); /* 5sec */
822 /* Create the key object types */
823 Status
= CmpCreateObjectTypes();
824 if (!NT_SUCCESS(Status
))
827 KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED
, 1, 1, Status
, 0);
830 /* Build the master hive */
831 Status
= CmpInitializeHive((PCMHIVE
*)&CmiVolatileHive
,
833 HIVE_VOLATILE
| HIVE_NO_FILE
,
841 if (!NT_SUCCESS(Status
))
844 KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED
, 1, 2, Status
, 0);
847 /* Create the \REGISTRY key node */
848 if (!CmpCreateRegistryRoot())
851 KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED
, 1, 3, 0, 0);
854 /* Create the default security descriptor */
855 SecurityDescriptor
= CmpHiveRootSecurityDescriptor();
857 /* Create '\Registry\Machine' key. */
858 RtlInitUnicodeString(&KeyName
, L
"\\REGISTRY\\MACHINE");
859 InitializeObjectAttributes(&ObjectAttributes
,
861 OBJ_CASE_INSENSITIVE
,
864 Status
= NtCreateKey(&KeyHandle
,
865 KEY_READ
| KEY_WRITE
,
871 if (!NT_SUCCESS(Status
))
874 KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED
, 1, 5, Status
, 0);
877 /* Close the handle */
880 /* Create '\Registry\User' key. */
881 RtlInitUnicodeString(&KeyName
, L
"\\REGISTRY\\USER");
882 InitializeObjectAttributes(&ObjectAttributes
,
884 OBJ_CASE_INSENSITIVE
,
887 Status
= NtCreateKey(&KeyHandle
,
888 KEY_READ
| KEY_WRITE
,
894 if (!NT_SUCCESS(Status
))
897 KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED
, 1, 6, Status
, 0);
900 /* Close the handle */
903 /* Initialize the system hive */
904 if (!CmpInitializeSystemHive(KeLoaderBlock
))
907 KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED
, 1, 7, 0, 0);
910 /* Create the 'CurrentControlSet' link. */
911 Status
= CmpCreateControlSet(KeLoaderBlock
);
912 if (!NT_SUCCESS(Status
))
915 KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED
, 1, 8, Status
, 0);
918 /* Import the hardware hive (FIXME: We should create it from scratch) */
919 BaseAddress
= CmpRosGetHardwareHive(&Length
);
920 ((PHBASE_BLOCK
)BaseAddress
)->Length
= Length
;
921 Status
= CmpInitializeHive((PCMHIVE
*)&HardwareHive
,
922 HINIT_MEMORY
, //HINIT_CREATE,
923 HIVE_NO_FILE
, //HIVE_VOLATILE,
925 BaseAddress
, // NULL,
931 CmPrepareHive(&HardwareHive
->Hive
);
932 if (!NT_SUCCESS(Status
))
935 KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED
, 1, 11, Status
, 0);
938 /* Attach it to the machine key */
939 RtlInitUnicodeString(&KeyName
, REG_HARDWARE_KEY_NAME
);
940 Status
= CmpLinkHiveToMaster(&KeyName
,
942 (PCMHIVE
)HardwareHive
,
945 if (!NT_SUCCESS(Status
))
948 KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED
, 1, 12, Status
, 0);
951 /* Fill out the Hardware key with the ARC Data from the Loader */
952 Status
= CmpInitializeHardwareConfiguration(KeLoaderBlock
);
953 if (!NT_SUCCESS(Status
))
956 KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED
, 1, 13, Status
, 0);
959 /* Initialize machine-dependent information into the registry */
960 Status
= CmpInitializeMachineDependentConfiguration(KeLoaderBlock
);
961 if (!NT_SUCCESS(Status
))
964 KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED
, 1, 14, Status
, 0);
967 /* Initialize volatile registry settings */
968 Status
= CmpSetSystemValues(KeLoaderBlock
);
969 if (!NT_SUCCESS(Status
))
972 KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED
, 1, 15, Status
, 0);
975 /* Free the load options */
976 ExFreePool(CmpLoadOptions
.Buffer
);
978 /* If we got here, all went well */