2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/ex/init.c
5 * PURPOSE: Executive initalization
7 * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) - Added ExpInitializeExecutive
8 * and optimized/cleaned it.
9 * Eric Kohl (ekohl@abo.rhein-zeitung.de)
14 #include <internal/debug.h>
16 /* DATA **********************************************************************/
18 extern ULONG MmCoreDumpType
;
19 extern CHAR KiTimerSystemAuditing
;
20 extern PVOID Ki386InitialStackArray
[MAXIMUM_PROCESSORS
];
21 extern ADDRESS_RANGE KeMemoryMap
[64];
22 extern ULONG KeMemoryMapRangeCount
;
23 extern ULONG_PTR FirstKrnlPhysAddr
;
24 extern ULONG_PTR LastKrnlPhysAddr
;
25 extern ULONG_PTR LastKernelAddress
;
26 extern LOADER_MODULE KeLoaderModules
[64];
27 extern PRTL_MESSAGE_RESOURCE_DATA KiBugCodeMessages
;
28 extern LIST_ENTRY KiProfileListHead
;
29 extern LIST_ENTRY KiProfileSourceListHead
;
30 extern KSPIN_LOCK KiProfileLock
;
31 BOOLEAN SetupMode
= TRUE
;
32 BOOLEAN NoGuiBoot
= FALSE
;
34 VOID
PspPostInitSystemProcess(VOID
);
36 static VOID INIT_FUNCTION
InitSystemSharedUserPage (PCSZ ParameterLine
);
37 VOID INIT_FUNCTION
ExpDisplayNotice(VOID
);
38 INIT_FUNCTION NTSTATUS
ExpLoadInitialProcess(PHANDLE ProcessHandle
, PHANDLE ThreadHandle
);
40 #if defined (ALLOC_PRAGMA)
41 #pragma alloc_text(INIT, InitSystemSharedUserPage)
42 #pragma alloc_text(INIT, ExpDisplayNotice)
43 #pragma alloc_text(INIT, ExpLoadInitialProcess)
44 #pragma alloc_text(INIT, ExpInitializeExecutive)
45 #pragma alloc_text(INIT, ExInit2)
48 /* FUNCTIONS ****************************************************************/
53 InitSystemSharedUserPage (PCSZ ParameterLine
)
55 UNICODE_STRING ArcDeviceName
;
56 UNICODE_STRING ArcName
;
57 UNICODE_STRING BootPath
;
58 UNICODE_STRING DriveDeviceName
;
59 UNICODE_STRING DriveName
;
60 WCHAR DriveNameBuffer
[20];
66 OBJECT_ATTRIBUTES ObjectAttributes
;
69 BOOLEAN BootDriveFound
= FALSE
;
73 * The shared user page has been zeroed-out right after creation.
74 * There is NO need to do this again.
76 Ki386SetProcessorFeatures();
78 /* Set the Version Data */
79 SharedUserData
->NtProductType
= NtProductWinNt
;
80 SharedUserData
->ProductTypeIsValid
= TRUE
;
81 SharedUserData
->NtMajorVersion
= 5;
82 SharedUserData
->NtMinorVersion
= 0;
85 * Retrieve the current dos system path
86 * (e.g.: C:\reactos) from the given arc path
87 * (e.g.: multi(0)disk(0)rdisk(0)partititon(1)\reactos)
88 * Format: "<arc_name>\<path> [options...]"
91 /* Create local parameter line copy */
92 ParamBuffer
= ExAllocatePool(PagedPool
, 256);
93 strcpy (ParamBuffer
, (const char *)ParameterLine
);
94 DPRINT("%s\n", ParamBuffer
);
97 p
= strchr (ParamBuffer
, ' ');
99 DPRINT("%s\n", ParamBuffer
);
102 p
= strchr (ParamBuffer
, '\\');
105 DPRINT("Boot path: %s\n", p
);
106 RtlCreateUnicodeStringFromAsciiz (&BootPath
, p
);
111 DPRINT("Boot path: %s\n", "\\");
112 RtlCreateUnicodeStringFromAsciiz (&BootPath
, "\\");
114 DPRINT("Arc name: %s\n", ParamBuffer
);
116 /* Only ARC Name left - Build full ARC Name */
117 ArcNameBuffer
= ExAllocatePool (PagedPool
, 256 * sizeof(WCHAR
));
118 swprintf (ArcNameBuffer
, L
"\\ArcName\\%S", ParamBuffer
);
119 RtlInitUnicodeString (&ArcName
, ArcNameBuffer
);
120 DPRINT("Arc name: %wZ\n", &ArcName
);
122 /* Free ParamBuffer */
123 ExFreePool (ParamBuffer
);
125 /* Allocate ARC Device Name string */
126 ArcDeviceName
.Length
= 0;
127 ArcDeviceName
.MaximumLength
= 256 * sizeof(WCHAR
);
128 ArcDeviceName
.Buffer
= ExAllocatePool (PagedPool
, 256 * sizeof(WCHAR
));
130 /* Open the Symbolic Link */
131 InitializeObjectAttributes(&ObjectAttributes
,
136 Status
= NtOpenSymbolicLinkObject(&Handle
,
137 SYMBOLIC_LINK_ALL_ACCESS
,
140 /* Free the String */
141 ExFreePool(ArcName
.Buffer
);
143 /* Check for Success */
144 if (!NT_SUCCESS(Status
)) {
146 /* Free the Strings */
147 RtlFreeUnicodeString(&BootPath
);
148 ExFreePool(ArcDeviceName
.Buffer
);
149 CPRINT("NtOpenSymbolicLinkObject() failed (Status %x)\n", Status
);
154 Status
= NtQuerySymbolicLinkObject(Handle
,
159 /* Check for Success */
160 if (!NT_SUCCESS(Status
)) {
162 /* Free the Strings */
163 RtlFreeUnicodeString(&BootPath
);
164 ExFreePool(ArcDeviceName
.Buffer
);
165 CPRINT("NtQuerySymbolicLinkObject() failed (Status %x)\n", Status
);
168 DPRINT("Length: %lu ArcDeviceName: %wZ\n", Length
, &ArcDeviceName
);
170 /* Allocate Device Name string */
171 DriveDeviceName
.Length
= 0;
172 DriveDeviceName
.MaximumLength
= 256 * sizeof(WCHAR
);
173 DriveDeviceName
.Buffer
= ExAllocatePool (PagedPool
, 256 * sizeof(WCHAR
));
176 for (i
= 0; i
< 26; i
++) {
178 /* Setup the String */
179 swprintf (DriveNameBuffer
, L
"\\??\\%C:", 'A' + i
);
180 RtlInitUnicodeString(&DriveName
,
183 /* Open the Symbolic Link */
184 InitializeObjectAttributes(&ObjectAttributes
,
189 Status
= NtOpenSymbolicLinkObject(&Handle
,
190 SYMBOLIC_LINK_ALL_ACCESS
,
193 /* If it failed, skip to the next drive */
194 if (!NT_SUCCESS(Status
)) {
195 DPRINT("Failed to open link %wZ\n", &DriveName
);
200 Status
= NtQuerySymbolicLinkObject(Handle
,
204 /* If it failed, skip to the next drive */
205 if (!NT_SUCCESS(Status
)) {
206 DPRINT("Failed to query link %wZ\n", &DriveName
);
209 DPRINT("Opened link: %wZ ==> %wZ\n", &DriveName
, &DriveDeviceName
);
211 /* See if we've found the boot drive */
212 if (!RtlCompareUnicodeString (&ArcDeviceName
, &DriveDeviceName
, FALSE
)) {
214 DPRINT("DOS Boot path: %c:%wZ\n", 'A' + i
, &BootPath
);
215 swprintf(SharedUserData
->NtSystemRoot
, L
"%C:%wZ", 'A' + i
, &BootPath
);
216 BootDriveFound
= TRUE
;
219 /* Close this Link */
223 /* Free all the Strings we have in memory */
224 RtlFreeUnicodeString (&BootPath
);
225 ExFreePool(DriveDeviceName
.Buffer
);
226 ExFreePool(ArcDeviceName
.Buffer
);
228 /* Make sure we found the Boot Drive */
229 if (BootDriveFound
== FALSE
) {
231 DbgPrint("No system drive found!\n");
232 KEBUGCHECK (NO_BOOT_DEVICE
);
239 ExecuteRuntimeAsserts(VOID
)
242 * Fail at runtime if someone has changed various structures without
243 * updating the offsets used for the assembler code.
245 ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA
, SystemCall
) == 0x300);
246 ASSERT(FIELD_OFFSET(KTHREAD
, InitialStack
) == KTHREAD_INITIAL_STACK
);
247 ASSERT(FIELD_OFFSET(KTHREAD
, Teb
) == KTHREAD_TEB
);
248 ASSERT(FIELD_OFFSET(KTHREAD
, KernelStack
) == KTHREAD_KERNEL_STACK
);
249 ASSERT(FIELD_OFFSET(KTHREAD
, NpxState
) == KTHREAD_NPX_STATE
);
250 ASSERT(FIELD_OFFSET(KTHREAD
, ServiceTable
) == KTHREAD_SERVICE_TABLE
);
251 ASSERT(FIELD_OFFSET(KTHREAD
, PreviousMode
) == KTHREAD_PREVIOUS_MODE
);
252 ASSERT(FIELD_OFFSET(KTHREAD
, TrapFrame
) == KTHREAD_TRAP_FRAME
);
253 ASSERT(FIELD_OFFSET(KTHREAD
, CallbackStack
) == KTHREAD_CALLBACK_STACK
);
254 ASSERT(FIELD_OFFSET(KTHREAD
, ApcState
.Process
) == KTHREAD_APCSTATE_PROCESS
);
255 ASSERT(FIELD_OFFSET(KPROCESS
, DirectoryTableBase
) == KPROCESS_DIRECTORY_TABLE_BASE
);
256 ASSERT(FIELD_OFFSET(KPROCESS
, IopmOffset
) == KPROCESS_IOPM_OFFSET
);
257 ASSERT(FIELD_OFFSET(KPROCESS
, LdtDescriptor
) == KPROCESS_LDT_DESCRIPTOR0
);
258 ASSERT(FIELD_OFFSET(KV86M_TRAP_FRAME
, SavedExceptionStack
) == TF_SAVED_EXCEPTION_STACK
);
259 ASSERT(FIELD_OFFSET(KV86M_TRAP_FRAME
, regs
) == TF_REGS
);
260 ASSERT(FIELD_OFFSET(KV86M_TRAP_FRAME
, orig_ebp
) == TF_ORIG_EBP
);
261 ASSERT(FIELD_OFFSET(KPCR
, Tib
.ExceptionList
) == KPCR_EXCEPTION_LIST
);
262 ASSERT(FIELD_OFFSET(KPCR
, Self
) == KPCR_SELF
);
263 ASSERT(FIELD_OFFSET(KIPCR
, PrcbData
) + FIELD_OFFSET(KPRCB
, CurrentThread
) == KPCR_CURRENT_THREAD
);
264 ASSERT(FIELD_OFFSET(KIPCR
, PrcbData
) + FIELD_OFFSET(KPRCB
, NpxThread
) == KPCR_NPX_THREAD
);
265 ASSERT(FIELD_OFFSET(KTSS
, Esp0
) == KTSS_ESP0
);
266 ASSERT(FIELD_OFFSET(KTSS
, IoMapBase
) == KTSS_IOMAPBASE
);
267 ASSERT(sizeof(FX_SAVE_AREA
) == SIZEOF_FX_SAVE_AREA
);
273 ParseAndCacheLoadedModules(VOID
)
278 /* Loop the Module List and get the modules we want */
279 for (i
= 1; i
< KeLoaderBlock
.ModsCount
; i
++) {
281 /* Get the Name of this Module */
282 if (!(Name
= strrchr((PCHAR
)KeLoaderModules
[i
].String
, '\\'))) {
285 Name
= (PCHAR
)KeLoaderModules
[i
].String
;
293 /* Now check for any of the modules we will need later */
294 if (!_stricmp(Name
, "ansi.nls")) {
296 CachedModules
[AnsiCodepage
] = &KeLoaderModules
[i
];
298 } else if (!_stricmp(Name
, "oem.nls")) {
300 CachedModules
[OemCodepage
] = &KeLoaderModules
[i
];
302 } else if (!_stricmp(Name
, "casemap.nls")) {
304 CachedModules
[UnicodeCasemap
] = &KeLoaderModules
[i
];
306 } else if (!_stricmp(Name
, "system") || !_stricmp(Name
, "system.hiv")) {
308 CachedModules
[SystemRegistry
] = &KeLoaderModules
[i
];
311 } else if (!_stricmp(Name
, "hardware") || !_stricmp(Name
, "hardware.hiv")) {
313 CachedModules
[HardwareRegistry
] = &KeLoaderModules
[i
];
321 ParseCommandLine(PULONG MaxMem
,
324 PBOOLEAN ForceAcpiDisable
)
328 p1
= (PCHAR
)KeLoaderBlock
.CommandLine
;
329 while(*p1
&& (p2
= strchr(p1
, '/'))) {
332 if (!_strnicmp(p2
, "MAXMEM", 6)) {
335 while (isspace(*p2
)) p2
++;
341 while(isspace(*p2
)) p2
++;
344 while (isdigit(*p2
)) {
345 *MaxMem
= *MaxMem
* 10 + *p2
- '0';
351 } else if (!_strnicmp(p2
, "NOGUIBOOT", 9)) {
356 } else if (!_strnicmp(p2
, "CRASHDUMP", 9)) {
362 if (!_strnicmp(p2
, "FULL", 4)) {
364 MmCoreDumpType
= MM_CORE_DUMP_TYPE_FULL
;
368 MmCoreDumpType
= MM_CORE_DUMP_TYPE_NONE
;
371 } else if (!_strnicmp(p2
, "BOOTLOG", 7)) {
375 } else if (!_strnicmp(p2
, "NOACPI", 6)) {
378 *ForceAcpiDisable
= TRUE
;
387 ExpDisplayNotice(VOID
)
394 "\n\n\n ReactOS " KERNEL_VERSION_STR
" Setup \n");
396 " \xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD");
402 HalDisplayString("Starting ReactOS "KERNEL_VERSION_STR
" (Build "
403 KERNEL_VERSION_BUILD_STR
")\n");
404 HalDisplayString(RES_STR_LEGAL_COPYRIGHT
);
405 HalDisplayString("\n\nReactOS is free software, covered by the GNU General "
406 "Public License, and you\n");
407 HalDisplayString("are welcome to change it and/or distribute copies of it "
409 HalDisplayString("conditions. There is absolutely no warranty for "
412 /* Display number of Processors */
414 "Found %x system processor(s). [%lu MB Memory]\n",
415 (int)KeNumberProcessors
,
416 (KeLoaderBlock
.MemHigher
+ 1088)/ 1024);
417 HalDisplayString(str
);
423 ExpLoadInitialProcess(PHANDLE ProcessHandle
,
424 PHANDLE ThreadHandle
)
426 UNICODE_STRING ImagePath
= RTL_CONSTANT_STRING(L
"\\SystemRoot\\system32\\smss.exe");
427 HANDLE SystemProcessHandle
;
429 PRTL_USER_PROCESS_PARAMETERS Params
=NULL
;
430 RTL_USER_PROCESS_INFORMATION Info
;
432 /* Create a handle to the process */
433 Status
= ObpCreateHandle(PsInitialSystemProcess
,
434 PROCESS_CREATE_PROCESS
| PROCESS_CREATE_THREAD
| PROCESS_QUERY_INFORMATION
,
436 &SystemProcessHandle
);
437 if(!NT_SUCCESS(Status
))
439 DPRINT1("Failed to create a handle for the system process!\n");
443 /* Create the Parameters */
444 Status
= RtlCreateProcessParameters(&Params
,
454 if(!NT_SUCCESS(Status
))
456 DPRINT1("Failed to create ppb!\n");
457 ZwClose(SystemProcessHandle
);
461 DPRINT("Creating process\n");
462 Status
= RtlCreateUserProcess(&ImagePath
,
463 OBJ_CASE_INSENSITIVE
,
473 /* Close the handle and free the params */
474 ZwClose(SystemProcessHandle
);
475 RtlDestroyProcessParameters(Params
);
477 if (!NT_SUCCESS(Status
))
479 DPRINT1("NtCreateProcess() failed (Status %lx)\n", Status
);
484 ZwResumeThread(Info
.ThreadHandle
, NULL
);
487 *ProcessHandle
= Info
.ProcessHandle
;
488 *ThreadHandle
= Info
.ThreadHandle
;
489 DPRINT("Process created successfully\n");
490 return STATUS_SUCCESS
;
496 ExpInitializeExecutive(VOID
)
498 UNICODE_STRING EventName
;
499 HANDLE InitDoneEventHandle
;
500 OBJECT_ATTRIBUTES ObjectAttributes
;
501 BOOLEAN BootLog
= FALSE
;
503 BOOLEAN ForceAcpiDisable
= FALSE
;
504 LARGE_INTEGER Timeout
;
505 HANDLE ProcessHandle
;
509 /* Check if the structures match the ASM offset constants */
510 ExecuteRuntimeAsserts();
512 /* Sets up the Text Sections of the Kernel and HAL for debugging */
515 /* Lower the IRQL to Dispatch Level */
516 KeLowerIrql(DISPATCH_LEVEL
);
518 /* Sets up the VDM Data */
521 /* Parse Command Line Settings */
522 ParseCommandLine(&MaxMem
, &NoGuiBoot
, &BootLog
, &ForceAcpiDisable
);
524 /* Initialize Kernel Memory Address Space */
525 MmInit1(FirstKrnlPhysAddr
,
528 (PADDRESS_RANGE
)&KeMemoryMap
,
529 KeMemoryMapRangeCount
,
530 MaxMem
> 8 ? MaxMem
: 4096);
532 /* Parse the Loaded Modules (by FreeLoader) and cache the ones we'll need */
533 ParseAndCacheLoadedModules();
535 /* Initialize the Dispatcher, Clock and Bug Check Mechanisms. */
538 /* Bring back the IRQL to Passive */
539 KeLowerIrql(PASSIVE_LEVEL
);
541 /* Initialize Profiling */
542 InitializeListHead(&KiProfileListHead
);
543 InitializeListHead(&KiProfileSourceListHead
);
544 KeInitializeSpinLock(&KiProfileLock
);
546 /* Initialize resources */
547 ExpResourceInitialization();
549 /* Load basic Security for other Managers */
550 if (!SeInit1()) KEBUGCHECK(SECURITY_INITIALIZATION_FAILED
);
552 /* Create the Basic Object Manager Types to allow new Object Types */
555 /* Initialize Lookaside Lists */
556 ExpInitLookasideLists();
558 /* Set up Region Maps, Sections and the Paging File */
561 /* Initialize Tokens now that the Object Manager is ready */
562 if (!SeInit2()) KEBUGCHECK(SECURITY1_INITIALIZATION_FAILED
);
564 /* Set 1 CPU for now, we'll increment this later */
565 KeNumberProcessors
= 1;
567 /* Initalize the Process Manager */
568 PiInitProcessManager();
570 /* Break into the Debugger if requested */
571 if (KdPollBreakIn()) DbgBreakPointWithStatus (DBG_STATUS_CONTROL_C
);
573 /* Initialize all processors */
574 while (!HalAllProcessorsStarted()) {
576 PVOID ProcessorStack
;
578 /* Set up the Kernel and Process Manager for this CPU */
579 KePrepareForApplicationProcessorInit(KeNumberProcessors
);
580 KeCreateApplicationProcessorIdleThread(KeNumberProcessors
);
582 /* Allocate a stack for use when booting the processor */
583 ProcessorStack
= RVA(Ki386InitialStackArray
[((int)KeNumberProcessors
)], KERNEL_STACK_SIZE
);
585 /* Tell HAL a new CPU is being started */
586 HalStartNextProcessor(0, (ULONG
)ProcessorStack
- 2*sizeof(FX_SAVE_AREA
));
587 KeNumberProcessors
++;
590 /* Do Phase 1 HAL Initalization */
591 HalInitSystem(1, (PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
593 /* Initialize Basic System Objects and Worker Threads */
596 /* Create the system handle table, assign it to the system process, create
597 the client id table and assign a PID for the system process. This needs
598 to be done before the worker threads are initialized so the system
599 process gets the first PID (4) */
600 PspPostInitSystemProcess();
602 /* initialize the worker threads */
603 ExpInitializeWorkerThreads();
605 /* initialize callbacks */
606 ExpInitializeCallbacks();
608 /* Call KD Providers at Phase 1 */
609 KdInitSystem(1, (PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
611 /* Initialize I/O Objects, Filesystems, Error Logging and Shutdown */
615 PoInit((PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
, ForceAcpiDisable
);
617 /* Initialize the Registry (Hives are NOT yet loaded!) */
618 CmInitializeRegistry();
620 /* Unmap Low memory, initialize the Page Zeroing and the Balancer Thread */
623 /* Initialize Cache Views */
626 /* Initialize File Locking */
627 FsRtlpInitFileLockingImplementation();
629 /* Report all resources used by hal */
630 HalReportResourceUsage();
632 /* Clear the screen to blue */
633 HalInitSystem(2, (PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
635 /* Display version number and copyright/warranty message */
636 if (NoGuiBoot
) ExpDisplayNotice();
638 /* Call KD Providers at Phase 2 */
639 KdInitSystem(2, (PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
641 /* Import and create NLS Data and Sections */
644 /* Import and Load Registry Hives */
645 CmInitHives(SetupMode
);
647 /* Initialize the time zone information from the registry */
648 ExpInitTimeZoneInfo();
650 /* Enter the kernel debugger before starting up the boot drivers */
651 if (KdDebuggerEnabled
&& KdpEarlyBreak
)
654 /* Setup Drivers and Root Device Node */
657 /* Display the boot screen image if not disabled */
658 if (!NoGuiBoot
) InbvEnableBootDriver(TRUE
);
660 /* Create ARC Names, SystemRoot SymLink, Load Drivers and Assign Letters */
663 /* Load the System DLL and its Entrypoints */
666 /* Initialize the Default Locale */
667 PiInitDefaultLocale();
669 /* Initialize shared user page. Set dos system path, dos device map, etc. */
670 InitSystemSharedUserPage ((PCHAR
)KeLoaderBlock
.CommandLine
);
672 /* Create 'ReactOSInitDone' event */
673 RtlInitUnicodeString(&EventName
, L
"\\ReactOSInitDone");
674 InitializeObjectAttributes(&ObjectAttributes
,
679 Status
= ZwCreateEvent(&InitDoneEventHandle
,
682 SynchronizationEvent
,
685 /* Check for Success */
686 if (!NT_SUCCESS(Status
)) {
688 DPRINT1("Failed to create 'ReactOSInitDone' event (Status 0x%x)\n", Status
);
689 InitDoneEventHandle
= INVALID_HANDLE_VALUE
;
692 /* Launch initial process */
693 Status
= ExpLoadInitialProcess(&ProcessHandle
,
696 /* Check for success, Bugcheck if we failed */
697 if (!NT_SUCCESS(Status
)) {
699 KEBUGCHECKEX(SESSION4_INITIALIZATION_FAILED
, Status
, 0, 0, 0);
702 /* Wait on the Completion Event */
703 if (InitDoneEventHandle
!= INVALID_HANDLE_VALUE
) {
705 HANDLE Handles
[2]; /* Init event, Initial process */
707 /* Setup the Handles to wait on */
708 Handles
[0] = InitDoneEventHandle
;
709 Handles
[1] = ProcessHandle
;
711 /* Wait for the system to be initialized */
712 Timeout
.QuadPart
= (LONGLONG
)-1200000000; /* 120 second timeout */
713 Status
= ZwWaitForMultipleObjects(2,
718 if (!NT_SUCCESS(Status
)) {
720 DPRINT1("NtWaitForMultipleObjects failed with status 0x%x!\n", Status
);
722 } else if (Status
== STATUS_TIMEOUT
) {
724 DPRINT1("WARNING: System not initialized after 120 seconds.\n");
726 } else if (Status
== STATUS_WAIT_0
+ 1) {
728 /* Crash the system if the initial process was terminated. */
729 KEBUGCHECKEX(SESSION5_INITIALIZATION_FAILED
, Status
, 0, 0, 0);
734 * Disable the Boot Logo
736 if (!NoGuiBoot
) InbvEnableBootDriver(FALSE
);
738 /* Signal the Event and close the handle */
739 ZwSetEvent(InitDoneEventHandle
, NULL
);
740 ZwClose(InitDoneEventHandle
);
744 /* On failure to create 'ReactOSInitDone' event, go to text mode ASAP */
745 if (!NoGuiBoot
) InbvEnableBootDriver(FALSE
);
747 /* Crash the system if the initial process terminates within 5 seconds. */
748 Timeout
.QuadPart
= (LONGLONG
)-50000000; /* 5 second timeout */
749 Status
= ZwWaitForSingleObject(ProcessHandle
,
753 /* Check for timeout, crash if the initial process didn't initalize */
754 if (Status
!= STATUS_TIMEOUT
) KEBUGCHECKEX(SESSION5_INITIALIZATION_FAILED
, Status
, 1, 0, 0);
757 /* Enable the Clock, close remaining handles */
758 KiTimerSystemAuditing
= 1;
759 ZwClose(ThreadHandle
);
760 ZwClose(ProcessHandle
);
768 ExpInitializeEventImplementation();
769 ExpInitializeEventPairImplementation();
770 ExpInitializeMutantImplementation();
771 ExpInitializeSemaphoreImplementation();
772 ExpInitializeTimerImplementation();
774 ExpInitializeProfileImplementation();
777 ExpInitializeHandleTables();