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 CmpSystemStartOptions
.Buffer
,
171 CmpSystemStartOptions
.Length
);
172 if (!NT_SUCCESS(Status
)) goto Quickie
;
174 /* Free the options now */
175 ExFreePool(CmpSystemStartOptions
.Buffer
);
177 /* Setup value name for system boot device */
178 RtlInitUnicodeString(&KeyName
, L
"SystemBootDevice");
179 RtlCreateUnicodeStringFromAsciiz(&ValueName
, LoaderBlock
->NtBootPathName
);
180 Status
= NtSetValueKey(KeyHandle
,
188 /* Free the buffers */
189 RtlFreeUnicodeString(&ValueName
);
191 /* Close the key and return */
194 /* Return the status */
200 CmpCreateControlSet(IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
202 UNICODE_STRING ConfigName
= RTL_CONSTANT_STRING(L
"Control\\IDConfigDB");
203 UNICODE_STRING SelectName
=
204 RTL_CONSTANT_STRING(L
"\\Registry\\Machine\\System\\Select");
205 UNICODE_STRING KeyName
;
206 OBJECT_ATTRIBUTES ObjectAttributes
;
207 CHAR ValueInfoBuffer
[128];
208 PKEY_VALUE_FULL_INFORMATION ValueInfo
;
210 WCHAR UnicodeBuffer
[128];
211 HANDLE SelectHandle
, KeyHandle
, ConfigHandle
= NULL
, ProfileHandle
= NULL
;
212 HANDLE ParentHandle
= NULL
;
213 ULONG ControlSet
, HwProfile
;
214 ANSI_STRING TempString
;
216 ULONG ResultLength
, Disposition
;
217 PLOADER_PARAMETER_EXTENSION LoaderExtension
;
219 if (ExpInTextModeSetup
) return STATUS_SUCCESS
;
221 /* Open the select key */
222 InitializeObjectAttributes(&ObjectAttributes
,
224 OBJ_CASE_INSENSITIVE
,
227 Status
= NtOpenKey(&SelectHandle
, KEY_READ
, &ObjectAttributes
);
228 if (!NT_SUCCESS(Status
)) return(Status
);
230 /* Open the current value */
231 RtlInitUnicodeString(&KeyName
, L
"Current");
232 Status
= NtQueryValueKey(SelectHandle
,
234 KeyValueFullInformation
,
236 sizeof(ValueInfoBuffer
),
238 NtClose(SelectHandle
);
239 if (!NT_SUCCESS(Status
)) return Status
;
241 /* Get the actual value pointer, and get the control set ID */
242 ValueInfo
= (PKEY_VALUE_FULL_INFORMATION
)ValueInfoBuffer
;
243 ControlSet
= *(PULONG
)((PUCHAR
)ValueInfo
+ ValueInfo
->DataOffset
);
245 /* Create the current control set key */
246 RtlInitUnicodeString(&KeyName
,
247 L
"\\Registry\\Machine\\System\\CurrentControlSet");
248 InitializeObjectAttributes(&ObjectAttributes
,
250 OBJ_CASE_INSENSITIVE
,
254 Status
= NtCreateKey(&KeyHandle
,
259 REG_OPTION_VOLATILE
| REG_OPTION_CREATE_LINK
,
261 if (!NT_SUCCESS(Status
)) return Status
;
264 ASSERT(Disposition
== REG_CREATED_NEW_KEY
);
266 /* Initialize the symbolic link name */
268 "\\Registry\\Machine\\System\\ControlSet%03ld",
270 RtlInitAnsiString(&TempString
, Buffer
);
272 /* Create a Unicode string out of it */
273 KeyName
.MaximumLength
= sizeof(UnicodeBuffer
);
274 KeyName
.Buffer
= UnicodeBuffer
;
275 Status
= RtlAnsiStringToUnicodeString(&KeyName
, &TempString
, FALSE
);
278 Status
= NtSetValueKey(KeyHandle
,
279 &CmSymbolicLinkValueName
,
284 if (!NT_SUCCESS(Status
)) return Status
;
286 /* Get the configuration database key */
287 InitializeObjectAttributes(&ObjectAttributes
,
289 OBJ_CASE_INSENSITIVE
,
292 Status
= NtOpenKey(&ConfigHandle
, KEY_READ
, &ObjectAttributes
);
295 /* Check if we don't have one */
296 if (!NT_SUCCESS(Status
))
298 /* Cleanup and exit */
303 /* Now get the current config */
304 RtlInitUnicodeString(&KeyName
, L
"CurrentConfig");
305 Status
= NtQueryValueKey(ConfigHandle
,
307 KeyValueFullInformation
,
309 sizeof(ValueInfoBuffer
),
312 /* Set pointer to buffer */
313 ValueInfo
= (PKEY_VALUE_FULL_INFORMATION
)ValueInfoBuffer
;
315 /* Check if we failed or got a non DWORD-value */
316 if (!(NT_SUCCESS(Status
)) || (ValueInfo
->Type
!= REG_DWORD
)) goto Cleanup
;
318 /* Get the hadware profile */
319 HwProfile
= *(PULONG
)((PUCHAR
)ValueInfo
+ ValueInfo
->DataOffset
);
321 /* Open the hardware profile key */
322 RtlInitUnicodeString(&KeyName
,
323 L
"\\Registry\\Machine\\System\\CurrentControlSet"
324 L
"\\Hardware Profiles");
325 InitializeObjectAttributes(&ObjectAttributes
,
327 OBJ_CASE_INSENSITIVE
,
330 Status
= NtOpenKey(&ParentHandle
, KEY_READ
, &ObjectAttributes
);
331 if (!NT_SUCCESS(Status
))
333 /* Exit and clean up */
338 /* Build the profile name */
339 sprintf(Buffer
, "%04ld", HwProfile
);
340 RtlInitAnsiString(&TempString
, Buffer
);
342 /* Convert it to Unicode */
343 KeyName
.MaximumLength
= sizeof(UnicodeBuffer
);
344 KeyName
.Buffer
= UnicodeBuffer
;
345 Status
= RtlAnsiStringToUnicodeString(&KeyName
,
348 ASSERT(Status
== STATUS_SUCCESS
);
350 /* Open the associated key */
351 InitializeObjectAttributes(&ObjectAttributes
,
353 OBJ_CASE_INSENSITIVE
,
356 Status
= NtOpenKey(&ProfileHandle
,
357 KEY_READ
| KEY_WRITE
,
359 if (!NT_SUCCESS (Status
))
361 /* Cleanup and exit */
366 /* Check if we have a loader block extension */
367 LoaderExtension
= LoaderBlock
->Extension
;
370 ASSERTMSG("ReactOS doesn't support NTLDR Profiles yet!\n", FALSE
);
373 /* Create the current hardware profile key */
374 RtlInitUnicodeString(&KeyName
,
375 L
"\\Registry\\Machine\\System\\CurrentControlSet\\"
376 L
"Hardware Profiles\\Current");
377 InitializeObjectAttributes(&ObjectAttributes
,
379 OBJ_CASE_INSENSITIVE
,
382 Status
= NtCreateKey(&KeyHandle
,
387 REG_OPTION_VOLATILE
| REG_OPTION_CREATE_LINK
,
389 if (NT_SUCCESS(Status
))
392 ASSERT(Disposition
== REG_CREATED_NEW_KEY
);
394 /* Create the profile name */
396 "\\Registry\\Machine\\System\\CurrentControlSet\\"
397 "Hardware Profiles\\%04ld",
399 RtlInitAnsiString(&TempString
, Buffer
);
401 /* Convert it to Unicode */
402 KeyName
.MaximumLength
= sizeof(UnicodeBuffer
);
403 KeyName
.Buffer
= UnicodeBuffer
;
404 Status
= RtlAnsiStringToUnicodeString(&KeyName
,
407 ASSERT(STATUS_SUCCESS
== Status
);
410 Status
= NtSetValueKey(KeyHandle
,
411 &CmSymbolicLinkValueName
,
419 /* Close every opened handle */
421 if (ConfigHandle
) NtClose(ConfigHandle
);
422 if (ProfileHandle
) NtClose(ProfileHandle
);
423 if (ParentHandle
) NtClose(ParentHandle
);
426 return STATUS_SUCCESS
;
431 CmpInitializeSystemHive(IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
434 ANSI_STRING LoadString
;
439 UNICODE_STRING KeyName
;
440 PEREGISTRY_HIVE SystemHive
= NULL
;
441 UNICODE_STRING HiveName
= RTL_CONSTANT_STRING(L
"SYSTEM");
442 PSECURITY_DESCRIPTOR SecurityDescriptor
;
445 /* Setup the ansi string */
446 RtlInitAnsiString(&LoadString
, LoaderBlock
->LoadOptions
);
448 /* Allocate the unicode buffer */
449 Length
= LoadString
.Length
* sizeof(WCHAR
) + sizeof(UNICODE_NULL
);
450 Buffer
= ExAllocatePoolWithTag(PagedPool
, Length
, 0);
454 KEBUGCHECKEX(BAD_SYSTEM_CONFIG_INFO
, 3, 1, (ULONG_PTR
)LoaderBlock
, 0);
457 /* Setup the unicode string */
458 RtlInitEmptyUnicodeString(&CmpLoadOptions
, Buffer
, (USHORT
)Length
);
460 /* Add the load options and null-terminate */
461 RtlAnsiStringToUnicodeString(&CmpLoadOptions
, &LoadString
, FALSE
);
462 CmpLoadOptions
.Buffer
[LoadString
.Length
] = UNICODE_NULL
;
463 CmpLoadOptions
.Length
+= sizeof(WCHAR
);
465 /* Get the System Hive base address */
466 HiveBase
= LoaderBlock
->RegistryBase
;
470 ((PHBASE_BLOCK
)HiveBase
)->Length
= LoaderBlock
->RegistryLength
;
471 Status
= CmpInitializeHive((PCMHIVE
*)&SystemHive
,
473 0, //HIVE_NOLAZYFLUSH,
481 if (!NT_SUCCESS(Status
)) return FALSE
;
482 CmPrepareHive(&SystemHive
->Hive
);
484 /* Set the hive filename */
485 RtlCreateUnicodeString(&SystemHive
->HiveFileName
, SYSTEM_REG_FILE
);
487 /* We imported, no need to create a new hive */
490 /* Manually set the hive as volatile, if in Live CD mode */
491 if (CmpShareSystemHives
) SystemHive
->Hive
.HiveFlags
= HIVE_VOLATILE
;
497 Status
= CmpInitializeHive((PCMHIVE
*)&SystemHive
,
507 if (!NT_SUCCESS(Status
)) return FALSE
;
510 /* Tell CmpLinkHiveToMaster to allocate a hive */
514 /* Save the boot type */
515 if (SystemHive
) CmpBootType
= SystemHive
->Hive
.HiveHeader
->BootType
;
517 /* Are we in self-healing mode? */
520 /* Disable self-healing internally and check if boot type wanted it */
524 /* We're disabled, so bugcheck */
525 KEBUGCHECKEX(BAD_SYSTEM_CONFIG_INFO
,
528 (ULONG_PTR
)SystemHive
,
533 /* Create the default security descriptor */
534 SecurityDescriptor
= CmpHiveRootSecurityDescriptor();
536 /* Attach it to the system key */
537 RtlInitUnicodeString(&KeyName
, REG_SYSTEM_KEY_NAME
);
538 Status
= CmpLinkHiveToMaster(&KeyName
,
544 /* Free the security descriptor */
545 ExFreePool(SecurityDescriptor
);
546 if (!NT_SUCCESS(Status
)) return FALSE
;
548 /* Add the hive to the hive list */
549 CmpMachineHiveList
[3].CmHive
= (PCMHIVE
)SystemHive
;
557 CmpCreateObjectTypes(VOID
)
559 OBJECT_TYPE_INITIALIZER ObjectTypeInitializer
;
561 GENERIC_MAPPING CmpKeyMapping
= {KEY_READ
,
567 /* Initialize the Key object type */
568 RtlZeroMemory(&ObjectTypeInitializer
, sizeof(ObjectTypeInitializer
));
569 RtlInitUnicodeString(&Name
, L
"Key");
570 ObjectTypeInitializer
.Length
= sizeof(ObjectTypeInitializer
);
571 ObjectTypeInitializer
.DefaultPagedPoolCharge
= sizeof(CM_KEY_BODY
);
572 ObjectTypeInitializer
.GenericMapping
= CmpKeyMapping
;
573 ObjectTypeInitializer
.PoolType
= PagedPool
;
574 ObjectTypeInitializer
.ValidAccessMask
= KEY_ALL_ACCESS
;
575 ObjectTypeInitializer
.UseDefaultObject
= TRUE
;
576 ObjectTypeInitializer
.DeleteProcedure
= CmpDeleteKeyObject
;
577 ObjectTypeInitializer
.ParseProcedure
= CmpParseKey
;
578 ObjectTypeInitializer
.SecurityProcedure
= CmpSecurityMethod
;
579 ObjectTypeInitializer
.QueryNameProcedure
= CmpQueryKeyName
;
580 //ObjectTypeInitializer.CloseProcedure = CmpCloseKeyObject;
581 ObjectTypeInitializer
.SecurityRequired
= TRUE
;
584 return ObCreateObjectType(&Name
, &ObjectTypeInitializer
, NULL
, &CmpKeyObjectType
);
589 CmpCreateRootNode(IN PHHIVE Hive
,
591 OUT PHCELL_INDEX Index
)
593 UNICODE_STRING KeyName
;
594 PCM_KEY_NODE KeyCell
;
595 LARGE_INTEGER SystemTime
;
598 /* Initialize the node name and allocate it */
599 RtlInitUnicodeString(&KeyName
, Name
);
600 *Index
= HvAllocateCell(Hive
,
601 FIELD_OFFSET(CM_KEY_NODE
, Name
) +
602 CmpNameSize(Hive
, &KeyName
),
603 HvStable
); // FIXME: , HCELL_NIL);
604 if (*Index
== HCELL_NIL
) return FALSE
;
606 /* Set the cell index and get the data */
607 Hive
->HiveHeader
->RootCell
= *Index
;
608 KeyCell
= (PCM_KEY_NODE
)HvGetCell(Hive
, *Index
);
609 if (!KeyCell
) return FALSE
;
612 KeyCell
->Signature
= (USHORT
)CM_KEY_NODE_SIGNATURE
;;
613 KeyCell
->Flags
= KEY_HIVE_ENTRY
| KEY_NO_DELETE
;
614 KeQuerySystemTime(&SystemTime
);
615 KeyCell
->LastWriteTime
= SystemTime
;
616 KeyCell
->Parent
= HCELL_NIL
;
617 KeyCell
->SubKeyCounts
[HvStable
] = 0;
618 KeyCell
->SubKeyCounts
[HvVolatile
] = 0;
619 KeyCell
->SubKeyLists
[HvStable
] = HCELL_NIL
;
620 KeyCell
->SubKeyLists
[HvVolatile
] = HCELL_NIL
;
621 KeyCell
->ValueList
.Count
= 0;
622 KeyCell
->ValueList
.List
= HCELL_NIL
;
623 KeyCell
->Security
= HCELL_NIL
;
624 KeyCell
->Class
= HCELL_NIL
;
625 KeyCell
->ClassLength
= 0;
626 KeyCell
->MaxNameLen
= 0;
627 KeyCell
->MaxClassLen
= 0;
628 KeyCell
->MaxValueNameLen
= 0;
629 KeyCell
->MaxValueDataLen
= 0;
631 /* Copy the name (this will also set the length) */
632 KeyCell
->NameLength
= CmpCopyName(Hive
, (PWCHAR
)KeyCell
->Name
, &KeyName
);
634 /* Check if the name was compressed */
635 if (KeyCell
->NameLength
< KeyName
.Length
)
638 KeyCell
->Flags
|= KEY_COMP_NAME
;
642 HvReleaseCell(Hive
, *Index
);
648 CmpCreateRegistryRoot(VOID
)
650 UNICODE_STRING KeyName
;
651 OBJECT_ATTRIBUTES ObjectAttributes
;
653 PCM_KEY_BODY RootKey
;
657 HCELL_INDEX RootIndex
;
659 PCM_KEY_NODE KeyCell
;
660 PSECURITY_DESCRIPTOR SecurityDescriptor
;
661 PCM_KEY_CONTROL_BLOCK Kcb
;
664 /* Setup the root node */
665 if (!CmpCreateRootNode(&CmiVolatileHive
->Hive
, L
"REGISTRY", &RootIndex
))
671 /* Create '\Registry' key. */
672 RtlInitUnicodeString(&KeyName
, L
"\\Registry");
673 SecurityDescriptor
= CmpHiveRootSecurityDescriptor();
674 InitializeObjectAttributes(&ObjectAttributes
,
676 OBJ_CASE_INSENSITIVE
,
679 Status
= ObCreateObject(KernelMode
,
688 ExFreePool(SecurityDescriptor
);
689 if (!NT_SUCCESS(Status
)) return FALSE
;
691 /* Sanity check, and get the key cell */
692 ASSERT((&CmiVolatileHive
->Hive
)->ReleaseCellRoutine
== NULL
);
693 KeyCell
= (PCM_KEY_NODE
)HvGetCell(&CmiVolatileHive
->Hive
, RootIndex
);
694 if (!KeyCell
) return FALSE
;
697 RtlInitUnicodeString(&KeyName
, L
"Registry");
698 Kcb
= CmpCreateKeyControlBlock(&CmiVolatileHive
->Hive
,
704 if (!Kcb
) return FALSE
;
706 /* Initialize the object */
708 RootKey
->Type
= TAG('k', 'v', '0', '2';
709 RootKey
->KeyControlBlock
= Kcb
;
710 RootKey
->NotifyBlock
= NULL
;
711 RootKey
->ProcessID
= PsGetCurrentProcessId();
713 RtlpCreateUnicodeString(&RootKey
->Name
, L
"Registry", NonPagedPool
);
714 RootKey
->RegistryHive
= CmiVolatileHive
;
715 RootKey
->KeyCellOffset
= RootIndex
;
716 RootKey
->KeyCell
= KeyCell
;
717 RootKey
->ParentKey
= RootKey
;
719 RootKey
->SubKeyCounts
= 0;
720 RootKey
->SubKeys
= NULL
;
721 RootKey
->SizeOfSubKeys
= 0;
724 /* Insert it into the object list head */
725 EnlistKeyBodyWithKCB(RootKey
, 0);
727 /* Insert the key into the namespace */
728 Status
= ObInsertObject(RootKey
,
733 &CmpRegistryRootHandle
);
734 if (!NT_SUCCESS(Status
)) return FALSE
;
736 /* Reference the key again so that we never lose it */
737 Status
= ObReferenceObjectByHandle(CmpRegistryRootHandle
,
743 if (!NT_SUCCESS(Status
)) return FALSE
;
745 /* Completely sucessful */
753 OBJECT_ATTRIBUTES ObjectAttributes
;
754 UNICODE_STRING KeyName
;
757 LARGE_INTEGER DueTime
;
760 PEREGISTRY_HIVE HardwareHive
;
763 PSECURITY_DESCRIPTOR SecurityDescriptor
;
766 /* Check if this is PE-boot */
769 /* Set registry to PE mode */
770 CmpMiniNTBoot
= TRUE
;
771 CmpShareSystemHives
= TRUE
;
774 /* Initialize the hive list and lock */
775 InitializeListHead(&CmpHiveListHead
);
776 ExInitializePushLock((PVOID
)&CmpHiveListHeadLock
);
777 ExInitializePushLock((PVOID
)&CmpLoadHiveLock
);
779 /* Initialize registry lock */
780 ExInitializeResourceLite(&CmpRegistryLock
);
782 /* Initialize the cache */
783 CmpInitializeCache();
785 /* Initialize allocation and delayed dereferencing */
786 CmpInitCmPrivateAlloc();
787 CmpInitCmPrivateDelayAlloc();
788 CmpInitDelayDerefKCBEngine();
790 /* Initialize callbacks */
793 /* Initialize self healing */
794 KeInitializeGuardedMutex(&CmpSelfHealQueueLock
);
795 InitializeListHead(&CmpSelfHealQueueListHead
);
797 /* Save the current process and lock the registry */
798 CmpSystemProcess
= PsGetCurrentProcess();
801 /* OLD CM: Initialize the key object list */
802 InitializeListHead(&CmiKeyObjectListHead
);
803 InitializeListHead(&CmiConnectedHiveList
);
805 /* OLD CM: Initialize the worker timer */
806 KeInitializeTimerEx(&CmiWorkerTimer
, SynchronizationTimer
);
808 /* OLD CM: Initialize the worker thread */
809 Status
= PsCreateSystemThread(&ThreadHandle
,
816 if (!NT_SUCCESS(Status
)) return FALSE
;
818 /* OLD CM: Start the timer */
819 DueTime
.QuadPart
= -1;
820 KeSetTimerEx(&CmiWorkerTimer
, DueTime
, 5000, NULL
); /* 5sec */
823 /* Create the key object types */
824 Status
= CmpCreateObjectTypes();
825 if (!NT_SUCCESS(Status
))
828 KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED
, 1, 1, Status
, 0);
831 /* Build the master hive */
832 Status
= CmpInitializeHive((PCMHIVE
*)&CmiVolatileHive
,
834 HIVE_VOLATILE
| HIVE_NO_FILE
,
842 if (!NT_SUCCESS(Status
))
845 KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED
, 1, 2, Status
, 0);
848 /* Create the \REGISTRY key node */
849 if (!CmpCreateRegistryRoot())
852 KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED
, 1, 3, 0, 0);
855 /* Create the default security descriptor */
856 SecurityDescriptor
= CmpHiveRootSecurityDescriptor();
858 /* Create '\Registry\Machine' key. */
859 RtlInitUnicodeString(&KeyName
, L
"\\REGISTRY\\MACHINE");
860 InitializeObjectAttributes(&ObjectAttributes
,
862 OBJ_CASE_INSENSITIVE
,
865 Status
= NtCreateKey(&KeyHandle
,
866 KEY_READ
| KEY_WRITE
,
872 if (!NT_SUCCESS(Status
))
875 KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED
, 1, 5, Status
, 0);
878 /* Close the handle */
881 /* Create '\Registry\User' key. */
882 RtlInitUnicodeString(&KeyName
, L
"\\REGISTRY\\USER");
883 InitializeObjectAttributes(&ObjectAttributes
,
885 OBJ_CASE_INSENSITIVE
,
888 Status
= NtCreateKey(&KeyHandle
,
889 KEY_READ
| KEY_WRITE
,
895 if (!NT_SUCCESS(Status
))
898 KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED
, 1, 6, Status
, 0);
901 /* Close the handle */
904 /* Initialize the system hive */
905 if (!CmpInitializeSystemHive(KeLoaderBlock
))
908 KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED
, 1, 7, 0, 0);
911 /* Create the 'CurrentControlSet' link. */
912 Status
= CmpCreateControlSet(KeLoaderBlock
);
913 if (!NT_SUCCESS(Status
))
916 KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED
, 1, 8, Status
, 0);
919 /* Import the hardware hive (FIXME: We should create it from scratch) */
920 BaseAddress
= CmpRosGetHardwareHive(&Length
);
921 ((PHBASE_BLOCK
)BaseAddress
)->Length
= Length
;
922 Status
= CmpInitializeHive((PCMHIVE
*)&HardwareHive
,
923 HINIT_MEMORY
, //HINIT_CREATE,
924 HIVE_NO_FILE
, //HIVE_VOLATILE,
926 BaseAddress
, // NULL,
932 CmPrepareHive(&HardwareHive
->Hive
);
933 if (!NT_SUCCESS(Status
))
936 KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED
, 1, 11, Status
, 0);
939 /* Attach it to the machine key */
940 RtlInitUnicodeString(&KeyName
, REG_HARDWARE_KEY_NAME
);
941 Status
= CmpLinkHiveToMaster(&KeyName
,
943 (PCMHIVE
)HardwareHive
,
946 if (!NT_SUCCESS(Status
))
949 KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED
, 1, 12, Status
, 0);
952 /* Fill out the Hardware key with the ARC Data from the Loader */
953 Status
= CmpInitializeHardwareConfiguration(KeLoaderBlock
);
954 if (!NT_SUCCESS(Status
))
957 KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED
, 1, 13, Status
, 0);
960 /* Initialize machine-dependent information into the registry */
961 Status
= CmpInitializeMachineDependentConfiguration(KeLoaderBlock
);
962 if (!NT_SUCCESS(Status
))
965 KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED
, 1, 14, Status
, 0);
968 /* Initialize volatile registry settings */
969 Status
= CmpSetSystemValues(KeLoaderBlock
);
970 if (!NT_SUCCESS(Status
))
973 KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED
, 1, 15, Status
, 0);
976 /* Free the load options */
977 ExFreePool(CmpLoadOptions
.Buffer
);
979 /* If we got here, all went well */