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 PUNICODE_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
.HiveHeader
->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
),
600 HvStable
); // FIXME: , HCELL_NIL);
601 if (*Index
== HCELL_NIL
) return FALSE
;
603 /* Set the cell index and get the data */
604 Hive
->HiveHeader
->RootCell
= *Index
;
605 KeyCell
= (PCM_KEY_NODE
)HvGetCell(Hive
, *Index
);
606 if (!KeyCell
) return FALSE
;
609 KeyCell
->Signature
= (USHORT
)CM_KEY_NODE_SIGNATURE
;;
610 KeyCell
->Flags
= KEY_HIVE_ENTRY
| KEY_NO_DELETE
;
611 KeQuerySystemTime(&SystemTime
);
612 KeyCell
->LastWriteTime
= SystemTime
;
613 KeyCell
->Parent
= HCELL_NIL
;
614 KeyCell
->SubKeyCounts
[HvStable
] = 0;
615 KeyCell
->SubKeyCounts
[HvVolatile
] = 0;
616 KeyCell
->SubKeyLists
[HvStable
] = HCELL_NIL
;
617 KeyCell
->SubKeyLists
[HvVolatile
] = HCELL_NIL
;
618 KeyCell
->ValueList
.Count
= 0;
619 KeyCell
->ValueList
.List
= HCELL_NIL
;
620 KeyCell
->Security
= HCELL_NIL
;
621 KeyCell
->Class
= HCELL_NIL
;
622 KeyCell
->ClassLength
= 0;
623 KeyCell
->MaxNameLen
= 0;
624 KeyCell
->MaxClassLen
= 0;
625 KeyCell
->MaxValueNameLen
= 0;
626 KeyCell
->MaxValueDataLen
= 0;
628 /* Copy the name (this will also set the length) */
629 KeyCell
->NameLength
= CmpCopyName(Hive
, (PWCHAR
)KeyCell
->Name
, &KeyName
);
631 /* Check if the name was compressed */
632 if (KeyCell
->NameLength
< KeyName
.Length
)
635 KeyCell
->Flags
|= KEY_COMP_NAME
;
639 HvReleaseCell(Hive
, *Index
);
645 CmpCreateRegistryRoot(VOID
)
647 UNICODE_STRING KeyName
;
648 OBJECT_ATTRIBUTES ObjectAttributes
;
650 PCM_KEY_BODY RootKey
;
654 HCELL_INDEX RootIndex
;
656 PCM_KEY_NODE KeyCell
;
657 PSECURITY_DESCRIPTOR SecurityDescriptor
;
658 PCM_KEY_CONTROL_BLOCK Kcb
;
661 /* Setup the root node */
662 if (!CmpCreateRootNode(&CmiVolatileHive
->Hive
, L
"REGISTRY", &RootIndex
))
668 /* Create '\Registry' key. */
669 RtlInitUnicodeString(&KeyName
, L
"\\Registry");
670 SecurityDescriptor
= CmpHiveRootSecurityDescriptor();
671 InitializeObjectAttributes(&ObjectAttributes
,
673 OBJ_CASE_INSENSITIVE
,
676 Status
= ObCreateObject(KernelMode
,
685 ExFreePool(SecurityDescriptor
);
686 if (!NT_SUCCESS(Status
)) return FALSE
;
688 /* Sanity check, and get the key cell */
689 ASSERT((&CmiVolatileHive
->Hive
)->ReleaseCellRoutine
== NULL
);
690 KeyCell
= (PCM_KEY_NODE
)HvGetCell(&CmiVolatileHive
->Hive
, RootIndex
);
691 if (!KeyCell
) return FALSE
;
694 RtlInitUnicodeString(&KeyName
, L
"Registry");
695 Kcb
= CmpCreateKeyControlBlock(&CmiVolatileHive
->Hive
,
701 if (!Kcb
) return FALSE
;
703 /* Initialize the object */
705 RootKey
->Type
= TAG('k', 'v', '0', '2';
706 RootKey
->KeyControlBlock
= Kcb
;
707 RootKey
->NotifyBlock
= NULL
;
708 RootKey
->ProcessID
= PsGetCurrentProcessId();
710 RtlpCreateUnicodeString(&RootKey
->Name
, L
"Registry", NonPagedPool
);
711 RootKey
->RegistryHive
= CmiVolatileHive
;
712 RootKey
->KeyCellOffset
= RootIndex
;
713 RootKey
->KeyCell
= KeyCell
;
714 RootKey
->ParentKey
= RootKey
;
716 RootKey
->SubKeyCounts
= 0;
717 RootKey
->SubKeys
= NULL
;
718 RootKey
->SizeOfSubKeys
= 0;
721 /* Insert it into the object list head */
722 EnlistKeyBodyWithKCB(RootKey
, 0);
724 /* Insert the key into the namespace */
725 Status
= ObInsertObject(RootKey
,
730 &CmpRegistryRootHandle
);
731 if (!NT_SUCCESS(Status
)) return FALSE
;
733 /* Reference the key again so that we never lose it */
734 Status
= ObReferenceObjectByHandle(CmpRegistryRootHandle
,
740 if (!NT_SUCCESS(Status
)) return FALSE
;
742 /* Completely sucessful */
750 OBJECT_ATTRIBUTES ObjectAttributes
;
751 UNICODE_STRING KeyName
;
754 LARGE_INTEGER DueTime
;
757 PEREGISTRY_HIVE HardwareHive
;
760 PSECURITY_DESCRIPTOR SecurityDescriptor
;
763 /* Check if this is PE-boot */
766 /* Set registry to PE mode */
767 CmpMiniNTBoot
= TRUE
;
768 CmpShareSystemHives
= TRUE
;
771 /* Initialize the hive list and lock */
772 InitializeListHead(&CmpHiveListHead
);
773 ExInitializePushLock((PVOID
)&CmpHiveListHeadLock
);
774 ExInitializePushLock((PVOID
)&CmpLoadHiveLock
);
776 /* Initialize registry lock */
777 ExInitializeResourceLite(&CmpRegistryLock
);
779 /* Initialize the cache */
780 CmpInitializeCache();
782 /* Initialize allocation and delayed dereferencing */
783 CmpInitCmPrivateAlloc();
784 CmpInitCmPrivateDelayAlloc();
785 CmpInitDelayDerefKCBEngine();
787 /* Initialize callbacks */
790 /* Initialize self healing */
791 KeInitializeGuardedMutex(&CmpSelfHealQueueLock
);
792 InitializeListHead(&CmpSelfHealQueueListHead
);
794 /* Save the current process and lock the registry */
795 CmpSystemProcess
= PsGetCurrentProcess();
798 /* OLD CM: Initialize the key object list */
799 InitializeListHead(&CmiKeyObjectListHead
);
800 InitializeListHead(&CmiConnectedHiveList
);
802 /* OLD CM: Initialize the worker timer */
803 KeInitializeTimerEx(&CmiWorkerTimer
, SynchronizationTimer
);
805 /* OLD CM: Initialize the worker thread */
806 Status
= PsCreateSystemThread(&ThreadHandle
,
813 if (!NT_SUCCESS(Status
)) return FALSE
;
815 /* OLD CM: Start the timer */
816 DueTime
.QuadPart
= -1;
817 KeSetTimerEx(&CmiWorkerTimer
, DueTime
, 5000, NULL
); /* 5sec */
820 /* Create the key object types */
821 Status
= CmpCreateObjectTypes();
822 if (!NT_SUCCESS(Status
))
825 KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED
, 1, 1, Status
, 0);
828 /* Build the master hive */
829 Status
= CmpInitializeHive((PCMHIVE
*)&CmiVolatileHive
,
831 HIVE_VOLATILE
| HIVE_NO_FILE
,
839 if (!NT_SUCCESS(Status
))
842 KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED
, 1, 2, Status
, 0);
845 /* Create the \REGISTRY key node */
846 if (!CmpCreateRegistryRoot())
849 KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED
, 1, 3, 0, 0);
852 /* Create the default security descriptor */
853 SecurityDescriptor
= CmpHiveRootSecurityDescriptor();
855 /* Create '\Registry\Machine' key. */
856 RtlInitUnicodeString(&KeyName
, L
"\\REGISTRY\\MACHINE");
857 InitializeObjectAttributes(&ObjectAttributes
,
859 OBJ_CASE_INSENSITIVE
,
862 Status
= NtCreateKey(&KeyHandle
,
863 KEY_READ
| KEY_WRITE
,
869 if (!NT_SUCCESS(Status
))
872 KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED
, 1, 5, Status
, 0);
875 /* Close the handle */
878 /* Create '\Registry\User' key. */
879 RtlInitUnicodeString(&KeyName
, L
"\\REGISTRY\\USER");
880 InitializeObjectAttributes(&ObjectAttributes
,
882 OBJ_CASE_INSENSITIVE
,
885 Status
= NtCreateKey(&KeyHandle
,
886 KEY_READ
| KEY_WRITE
,
892 if (!NT_SUCCESS(Status
))
895 KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED
, 1, 6, Status
, 0);
898 /* Close the handle */
901 /* Initialize the system hive */
902 if (!CmpInitializeSystemHive(KeLoaderBlock
))
905 KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED
, 1, 7, 0, 0);
908 /* Create the 'CurrentControlSet' link. */
909 Status
= CmpCreateControlSet(KeLoaderBlock
);
910 if (!NT_SUCCESS(Status
))
913 KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED
, 1, 8, Status
, 0);
916 /* Import the hardware hive (FIXME: We should create it from scratch) */
917 BaseAddress
= CmpRosGetHardwareHive(&Length
);
918 ((PHBASE_BLOCK
)BaseAddress
)->Length
= Length
;
919 Status
= CmpInitializeHive((PCMHIVE
*)&HardwareHive
,
920 HINIT_MEMORY
, //HINIT_CREATE,
921 HIVE_NO_FILE
, //HIVE_VOLATILE,
923 BaseAddress
, // NULL,
929 CmPrepareHive(&HardwareHive
->Hive
);
930 if (!NT_SUCCESS(Status
))
933 KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED
, 1, 11, Status
, 0);
936 /* Attach it to the machine key */
937 RtlInitUnicodeString(&KeyName
, REG_HARDWARE_KEY_NAME
);
938 Status
= CmpLinkHiveToMaster(&KeyName
,
940 (PCMHIVE
)HardwareHive
,
943 if (!NT_SUCCESS(Status
))
946 KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED
, 1, 12, Status
, 0);
949 /* Fill out the Hardware key with the ARC Data from the Loader */
950 Status
= CmpInitializeHardwareConfiguration(KeLoaderBlock
);
951 if (!NT_SUCCESS(Status
))
954 KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED
, 1, 13, Status
, 0);
957 /* Initialize machine-dependent information into the registry */
958 Status
= CmpInitializeMachineDependentConfiguration(KeLoaderBlock
);
959 if (!NT_SUCCESS(Status
))
962 KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED
, 1, 14, Status
, 0);
965 /* Initialize volatile registry settings */
966 Status
= CmpSetSystemValues(KeLoaderBlock
);
967 if (!NT_SUCCESS(Status
))
970 KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED
, 1, 15, Status
, 0);
973 /* Free the load options */
974 ExFreePool(CmpLoadOptions
.Buffer
);
976 /* If we got here, all went well */