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 #define BUILD_OSCSDVERSION(major, minor) (((major & 0xFF) << 8) | (minor & 0xFF))
21 ULONG NtMajorVersion
= 5;
22 ULONG NtMinorVersion
= 0;
23 ULONG NtOSCSDVersion
= BUILD_OSCSDVERSION(4, 0);
24 ULONG NtBuildNumber
= KERNEL_VERSION_BUILD
;
28 extern LOADER_MODULE KeLoaderModules
[64];
29 extern ULONG KeLoaderModuleCount
;
30 extern ULONG KiServiceLimit
;
31 BOOLEAN NoGuiBoot
= FALSE
;
33 /* Init flags and settings */
34 ULONG ExpInitializationPhase
;
35 BOOLEAN ExpInTextModeSetup
;
36 BOOLEAN IoRemoteBootClient
;
37 ULONG InitSafeBootMode
;
40 UNICODE_STRING NtSystemRoot
;
42 /* Boot NLS information */
43 PVOID ExpNlsTableBase
;
44 ULONG ExpAnsiCodePageDataOffset
, ExpOemCodePageDataOffset
;
45 ULONG ExpUnicodeCaseTableDataOffset
;
46 NLSTABLEINFO ExpNlsTableInfo
;
47 ULONG ExpNlsTableSize
;
48 PVOID ExpNlsSectionPointer
;
50 /* FUNCTIONS ****************************************************************/
56 LARGE_INTEGER SectionSize
;
59 PVOID SectionBase
= NULL
;
61 LARGE_INTEGER SectionOffset
= {{0}};
63 /* Set the section size */
64 SectionSize
.QuadPart
= ExpNlsTableSize
;
66 /* Create the NLS Section */
67 Status
= ZwCreateSection(&NlsSection
,
74 if (!NT_SUCCESS(Status
))
77 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED
, Status
, 1, 0, 0);
80 /* Get a pointer to the section */
81 Status
= ObReferenceObjectByHandle(NlsSection
,
85 &ExpNlsSectionPointer
,
88 if (!NT_SUCCESS(Status
))
91 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED
, Status
, 2, 0, 0);
94 /* Map the NLS Section in system space */
95 Status
= MmMapViewInSystemSpace(ExpNlsSectionPointer
,
98 if (!NT_SUCCESS(Status
))
101 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED
, Status
, 3, 0, 0);
104 /* Copy the codepage data in its new location. */
105 RtlMoveMemory(SectionBase
, ExpNlsTableBase
, ExpNlsTableSize
);
107 /* Free the previously allocated buffer and set the new location */
108 ExFreePool(ExpNlsTableBase
);
109 ExpNlsTableBase
= SectionBase
;
111 /* Initialize the NLS Tables */
112 RtlInitNlsTables((PVOID
)((ULONG_PTR
)ExpNlsTableBase
+
113 ExpAnsiCodePageDataOffset
),
114 (PVOID
)((ULONG_PTR
)ExpNlsTableBase
+
115 ExpOemCodePageDataOffset
),
116 (PVOID
)((ULONG_PTR
)ExpNlsTableBase
+
117 ExpUnicodeCaseTableDataOffset
),
119 RtlResetRtlTranslations(&ExpNlsTableInfo
);
121 /* Reset the base to 0 */
124 /* Map the section in the system process */
125 Status
= MmMapViewOfSection(ExpNlsSectionPointer
,
126 PsGetCurrentProcess(),
135 if (!NT_SUCCESS(Status
))
138 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED
, Status
, 5, 0, 0);
141 /* Copy the table into the system process and set this as the base */
142 RtlMoveMemory(SectionBase
, ExpNlsTableBase
, ExpNlsTableSize
);
143 ExpNlsTableBase
= SectionBase
;
149 InitSystemSharedUserPage (IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
151 UNICODE_STRING ArcDeviceName
;
152 UNICODE_STRING ArcName
;
153 UNICODE_STRING BootPath
;
154 UNICODE_STRING DriveDeviceName
;
155 UNICODE_STRING DriveName
;
156 WCHAR DriveNameBuffer
[20];
157 PWCHAR ArcNameBuffer
;
160 OBJECT_ATTRIBUTES ObjectAttributes
;
163 BOOLEAN BootDriveFound
= FALSE
;
165 /* Set the Product Type */
166 SharedUserData
->NtProductType
= NtProductWinNt
;
167 SharedUserData
->ProductTypeIsValid
= TRUE
;
170 * Retrieve the current dos system path
171 * (e.g.: C:\reactos) from the given arc path
172 * (e.g.: multi(0)disk(0)rdisk(0)partititon(1)\reactos)
173 * Format: "<arc_name>\<path> [options...]"
176 RtlCreateUnicodeStringFromAsciiz(&BootPath
, LoaderBlock
->NtBootPathName
);
178 /* Remove the trailing backslash */
179 BootPath
.Length
-= sizeof(WCHAR
);
180 BootPath
.MaximumLength
-= sizeof(WCHAR
);
182 /* Only ARC Name left - Build full ARC Name */
183 ArcNameBuffer
= ExAllocatePool (PagedPool
, 256 * sizeof(WCHAR
));
184 swprintf (ArcNameBuffer
, L
"\\ArcName\\%S", LoaderBlock
->ArcBootDeviceName
);
185 RtlInitUnicodeString (&ArcName
, ArcNameBuffer
);
187 /* Allocate ARC Device Name string */
188 ArcDeviceName
.Length
= 0;
189 ArcDeviceName
.MaximumLength
= 256 * sizeof(WCHAR
);
190 ArcDeviceName
.Buffer
= ExAllocatePool (PagedPool
, 256 * sizeof(WCHAR
));
192 /* Open the Symbolic Link */
193 InitializeObjectAttributes(&ObjectAttributes
,
198 Status
= NtOpenSymbolicLinkObject(&Handle
,
199 SYMBOLIC_LINK_ALL_ACCESS
,
202 /* Free the String */
203 ExFreePool(ArcName
.Buffer
);
205 /* Check for Success */
206 if (!NT_SUCCESS(Status
)) {
208 /* Free the Strings */
209 RtlFreeUnicodeString(&BootPath
);
210 ExFreePool(ArcDeviceName
.Buffer
);
211 CPRINT("NtOpenSymbolicLinkObject() failed (Status %x)\n", Status
);
216 Status
= NtQuerySymbolicLinkObject(Handle
,
221 /* Check for Success */
222 if (!NT_SUCCESS(Status
)) {
224 /* Free the Strings */
225 RtlFreeUnicodeString(&BootPath
);
226 ExFreePool(ArcDeviceName
.Buffer
);
227 CPRINT("NtQuerySymbolicLinkObject() failed (Status %x)\n", Status
);
231 /* Allocate Device Name string */
232 DriveDeviceName
.Length
= 0;
233 DriveDeviceName
.MaximumLength
= 256 * sizeof(WCHAR
);
234 DriveDeviceName
.Buffer
= ExAllocatePool (PagedPool
, 256 * sizeof(WCHAR
));
237 for (i
= 0; i
< 26; i
++) {
239 /* Setup the String */
240 swprintf (DriveNameBuffer
, L
"\\??\\%C:", 'A' + i
);
241 RtlInitUnicodeString(&DriveName
,
244 /* Open the Symbolic Link */
245 InitializeObjectAttributes(&ObjectAttributes
,
250 Status
= NtOpenSymbolicLinkObject(&Handle
,
251 SYMBOLIC_LINK_ALL_ACCESS
,
254 /* If it failed, skip to the next drive */
255 if (!NT_SUCCESS(Status
)) {
256 DPRINT("Failed to open link %wZ\n", &DriveName
);
261 Status
= NtQuerySymbolicLinkObject(Handle
,
265 /* If it failed, skip to the next drive */
266 if (!NT_SUCCESS(Status
)) {
267 DPRINT("Failed to query link %wZ\n", &DriveName
);
270 DPRINT("Opened link: %wZ ==> %wZ\n", &DriveName
, &DriveDeviceName
);
272 /* See if we've found the boot drive */
273 if (!RtlCompareUnicodeString (&ArcDeviceName
, &DriveDeviceName
, FALSE
)) {
275 DPRINT("DOS Boot path: %c:%wZ\n", 'A' + i
, &BootPath
);
276 swprintf(SharedUserData
->NtSystemRoot
, L
"%C:%wZ", 'A' + i
, &BootPath
);
277 BootDriveFound
= TRUE
;
280 /* Close this Link */
284 /* Free all the Strings we have in memory */
285 RtlFreeUnicodeString (&BootPath
);
286 ExFreePool(DriveDeviceName
.Buffer
);
287 ExFreePool(ArcDeviceName
.Buffer
);
289 /* Make sure we found the Boot Drive */
290 if (BootDriveFound
== FALSE
) {
292 DbgPrint("No system drive found!\n");
293 KEBUGCHECK (NO_BOOT_DEVICE
);
299 ParseAndCacheLoadedModules(VOID
)
304 /* Loop the Module List and get the modules we want */
305 for (i
= 1; i
< KeLoaderModuleCount
; i
++)
307 /* Get the Name of this Module */
308 if (!(Name
= strrchr((PCHAR
)KeLoaderModules
[i
].String
, '\\')))
311 Name
= (PCHAR
)KeLoaderModules
[i
].String
;
319 /* Now check for any of the modules we will need later */
320 if (!_stricmp(Name
, "ansi.nls"))
322 CachedModules
[AnsiCodepage
] = &KeLoaderModules
[i
];
324 else if (!_stricmp(Name
, "oem.nls"))
326 CachedModules
[OemCodepage
] = &KeLoaderModules
[i
];
328 else if (!_stricmp(Name
, "casemap.nls"))
330 CachedModules
[UnicodeCasemap
] = &KeLoaderModules
[i
];
332 else if (!_stricmp(Name
, "system") || !_stricmp(Name
, "system.hiv"))
334 CachedModules
[SystemRegistry
] = &KeLoaderModules
[i
];
336 else if (!_stricmp(Name
, "hardware") || !_stricmp(Name
, "hardware.hiv"))
338 CachedModules
[HardwareRegistry
] = &KeLoaderModules
[i
];
345 ExpDisplayNotice(VOID
)
349 if (ExpInTextModeSetup
)
352 "\n\n\n ReactOS " KERNEL_VERSION_STR
" Setup \n");
354 " \xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD");
360 HalDisplayString("Starting ReactOS "KERNEL_VERSION_STR
" (Build "
361 KERNEL_VERSION_BUILD_STR
")\n");
362 HalDisplayString(RES_STR_LEGAL_COPYRIGHT
);
363 HalDisplayString("\n\nReactOS is free software, covered by the GNU General "
364 "Public License, and you\n");
365 HalDisplayString("are welcome to change it and/or distribute copies of it "
367 HalDisplayString("conditions. There is absolutely no warranty for "
370 /* Display number of Processors */
372 "Found %x system processor(s). [%lu MB Memory]\n",
373 (int)KeNumberProcessors
,
374 (MmFreeLdrMemHigher
+ 1088)/ 1024);
375 HalDisplayString(str
);
381 ExpLoadInitialProcess(PHANDLE ProcessHandle
,
382 PHANDLE ThreadHandle
)
384 UNICODE_STRING CurrentDirectory
;
385 UNICODE_STRING ImagePath
= RTL_CONSTANT_STRING(L
"\\SystemRoot\\system32\\smss.exe");
387 PRTL_USER_PROCESS_PARAMETERS Params
=NULL
;
388 RTL_USER_PROCESS_INFORMATION Info
;
390 RtlInitUnicodeString(&CurrentDirectory
,
391 SharedUserData
->NtSystemRoot
);
393 /* Create the Parameters */
394 Status
= RtlCreateProcessParameters(&Params
,
404 if(!NT_SUCCESS(Status
))
406 DPRINT1("Failed to create ppb!\n");
410 DPRINT("Creating process\n");
411 Status
= RtlCreateUserProcess(&ImagePath
,
412 OBJ_CASE_INSENSITIVE
,
422 /* Close the handle and free the params */
423 RtlDestroyProcessParameters(Params
);
425 if (!NT_SUCCESS(Status
))
427 DPRINT1("NtCreateProcess() failed (Status %lx)\n", Status
);
432 ZwResumeThread(Info
.ThreadHandle
, NULL
);
435 *ProcessHandle
= Info
.ProcessHandle
;
436 *ThreadHandle
= Info
.ThreadHandle
;
437 DPRINT("Process created successfully\n");
438 return STATUS_SUCCESS
;
445 ExpInitializeEventImplementation();
446 ExpInitializeEventPairImplementation();
447 ExpInitializeMutantImplementation();
448 ExpInitializeSemaphoreImplementation();
449 ExpInitializeTimerImplementation();
451 ExpInitializeProfileImplementation();
458 ExComputeTickCountMultiplier(IN ULONG ClockIncrement
)
460 ULONG MsRemainder
= 0, MsIncrement
;
461 ULONG IncrementRemainder
;
464 /* Count the number of milliseconds for each clock interrupt */
465 MsIncrement
= ClockIncrement
/ (10 * 1000);
467 /* Count the remainder from the division above, with 24-bit precision */
468 IncrementRemainder
= ClockIncrement
- (MsIncrement
* (10 * 1000));
469 for (i
= 0; i
< 24; i
++)
471 /* Shift the remainders */
473 IncrementRemainder
<<= 1;
475 /* Check if we've went past 1 ms */
476 if (IncrementRemainder
>= (10 * 1000))
478 /* Increase the remainder by one, and substract from increment */
479 IncrementRemainder
-= (10 * 1000);
484 /* Return the increment */
485 return (MsIncrement
<< 24) | MsRemainder
;
490 ExpInitSystemPhase0(VOID
)
492 /* Initialize EXRESOURCE Support */
493 ExpResourceInitialization();
495 /* Initialize the environment lock */
496 ExInitializeFastMutex(&ExpEnvironmentLock
);
498 /* Initialize the lookaside lists and locks */
499 ExpInitLookasideLists();
501 /* Initialize the Firmware Table resource and listhead */
502 InitializeListHead(&ExpFirmwareTableProviderListHead
);
503 ExInitializeResourceLite(&ExpFirmwareTableResource
);
505 /* Set the suite mask to maximum and return */
506 ExSuiteMask
= 0xFFFFFFFF;
512 ExpInitSystemPhase1(VOID
)
522 /* Check the initialization phase */
523 switch (ExpInitializationPhase
)
528 return ExpInitSystemPhase0();
533 return ExpInitSystemPhase1();
537 /* Don't know any other phase! Bugcheck! */
538 KeBugCheck(UNEXPECTED_INITIALIZATION_CALL
);
545 ExpIsLoaderValid(IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
547 PLOADER_PARAMETER_EXTENSION Extension
;
549 /* Get the loader extension */
550 Extension
= LoaderBlock
->Extension
;
552 /* Validate the size (larger structures are OK, we'll just ignore them) */
553 if (Extension
->Size
< sizeof(LOADER_PARAMETER_EXTENSION
)) return FALSE
;
555 /* Don't validate upper versions */
556 if (Extension
->MajorVersion
> 5) return TRUE
;
558 /* Fail if this is NT 4 */
559 if (Extension
->MajorVersion
< 5) return FALSE
;
561 /* Fail if this is XP */
562 if (Extension
->MinorVersion
< 2) return FALSE
;
564 /* This is 2003 or newer, aprove it */
570 ExpInitializeExecutive(IN ULONG Cpu
,
571 IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
573 PNLS_DATA_BLOCK NlsData
;
575 ANSI_STRING AnsiPath
;
577 PLIST_ENTRY NextEntry
, ListHead
;
578 PMEMORY_ALLOCATION_DESCRIPTOR MdBlock
;
580 /* FIXME: Deprecate soon */
581 ParseAndCacheLoadedModules();
583 /* Validate Loader */
584 if (!ExpIsLoaderValid(LoaderBlock
))
586 /* Invalid loader version */
587 KeBugCheckEx(MISMATCHED_HAL
,
589 LoaderBlock
->Extension
->Size
,
590 LoaderBlock
->Extension
->MajorVersion
,
591 LoaderBlock
->Extension
->MinorVersion
);
594 /* Initialize PRCB pool lookaside pointers */
595 ExInitPoolLookasidePointers();
597 /* Check if this is an application CPU */
600 /* Then simply initialize it with HAL */
601 if (!HalInitSystem(ExpInitializationPhase
, LoaderBlock
))
603 /* Initialization failed */
604 KEBUGCHECK(HAL_INITIALIZATION_FAILED
);
611 /* Assume no text-mode or remote boot */
612 ExpInTextModeSetup
= FALSE
;
613 IoRemoteBootClient
= FALSE
;
615 /* Check if we have a setup loader block */
616 if (LoaderBlock
->SetupLdrBlock
)
618 /* Check if this is text-mode setup */
619 if (LoaderBlock
->SetupLdrBlock
->Flags
& 1) ExpInTextModeSetup
= TRUE
;
621 /* Check if this is network boot */
622 if (LoaderBlock
->SetupLdrBlock
->Flags
& 2)
625 IoRemoteBootClient
= TRUE
;
627 /* Make sure we're actually booting off the network */
628 ASSERT(!_memicmp(LoaderBlock
->ArcBootDeviceName
, "net(0)", 6));
633 ExpInitializationPhase
= 0;
635 /* Setup NLS Base and offsets */
636 NlsData
= LoaderBlock
->NlsData
;
637 ExpNlsTableBase
= NlsData
->AnsiCodePageData
;
638 ExpAnsiCodePageDataOffset
= 0;
639 ExpOemCodePageDataOffset
= ((ULONG_PTR
)NlsData
->OemCodePageData
-
640 (ULONG_PTR
)NlsData
->AnsiCodePageData
);
641 ExpUnicodeCaseTableDataOffset
= ((ULONG_PTR
)NlsData
->UnicodeCodePageData
-
642 (ULONG_PTR
)NlsData
->AnsiCodePageData
);
644 /* Initialize the NLS Tables */
645 RtlInitNlsTables((PVOID
)((ULONG_PTR
)ExpNlsTableBase
+
646 ExpAnsiCodePageDataOffset
),
647 (PVOID
)((ULONG_PTR
)ExpNlsTableBase
+
648 ExpOemCodePageDataOffset
),
649 (PVOID
)((ULONG_PTR
)ExpNlsTableBase
+
650 ExpUnicodeCaseTableDataOffset
),
652 RtlResetRtlTranslations(&ExpNlsTableInfo
);
654 /* Now initialize the HAL */
655 if (!HalInitSystem(ExpInitializationPhase
, LoaderBlock
))
657 /* HAL failed to initialize, bugcheck */
658 KeBugCheck(HAL_INITIALIZATION_FAILED
);
661 /* Make sure interrupts are active now */
664 /* Clear the crypto exponent */
665 SharedUserData
->CryptoExponent
= 0;
667 /* Set global flags for the checked build */
669 NtGlobalFlag
|= FLG_ENABLE_CLOSE_EXCEPTIONS
|
670 FLG_ENABLE_KDEBUG_SYMBOL_LOAD
;
673 /* Setup NT System Root Path */
674 sprintf(Buffer
, "C:%s", LoaderBlock
->NtBootPathName
);
676 /* Convert to ANSI_STRING and null-terminate it */
677 RtlInitString(&AnsiPath
, Buffer
);
678 Buffer
[--AnsiPath
.Length
] = UNICODE_NULL
;
680 /* Get the string from KUSER_SHARED_DATA's buffer */
681 NtSystemRoot
.Buffer
= SharedUserData
->NtSystemRoot
;
682 NtSystemRoot
.MaximumLength
= sizeof(SharedUserData
->NtSystemRoot
) / sizeof(WCHAR
);
683 NtSystemRoot
.Length
= 0;
686 Status
= RtlAnsiStringToUnicodeString(&NtSystemRoot
, &AnsiPath
, FALSE
);
687 if (!NT_SUCCESS(Status
)) KEBUGCHECK(SESSION3_INITIALIZATION_FAILED
);
689 /* Setup bugcheck messages */
690 KiInitializeBugCheck();
692 /* Setup system time */
693 KiInitializeSystemClock();
695 /* Initialize the executive at phase 0 */
696 if (!ExInitSystem()) KEBUGCHECK(PHASE0_INITIALIZATION_FAILED
);
698 /* Break into the Debugger if requested */
699 if (KdPollBreakIn()) DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C
);
701 /* Set system ranges */
702 SharedUserData
->Reserved1
= (ULONG_PTR
)MmHighestUserAddress
;
703 SharedUserData
->Reserved3
= (ULONG_PTR
)MmSystemRangeStart
;
705 /* Loop the memory descriptors */
706 ListHead
= &LoaderBlock
->MemoryDescriptorListHead
;
707 NextEntry
= ListHead
->Flink
;
708 while (NextEntry
!= ListHead
)
710 /* Get the current block */
711 MdBlock
= CONTAINING_RECORD(NextEntry
,
712 MEMORY_ALLOCATION_DESCRIPTOR
,
715 /* Check if this is an NLS block */
716 if (MdBlock
->MemoryType
== LoaderNlsData
)
718 /* Increase the table size */
719 ExpNlsTableSize
+= MdBlock
->PageCount
* PAGE_SIZE
;
722 /* Go to the next block */
723 NextEntry
= MdBlock
->ListEntry
.Flink
;
727 * In NT, the memory blocks are contiguous, but in ReactOS they are not,
728 * so unless someone fixes FreeLdr, we'll have to use this icky hack.
730 ExpNlsTableSize
+= 2 * PAGE_SIZE
; // BIAS FOR FREELDR. HACK!
732 /* Allocate the NLS buffer in the pool since loader memory will be freed */
733 ExpNlsTableBase
= ExAllocatePoolWithTag(NonPagedPool
,
735 TAG('R', 't', 'l', 'i'));
736 if (!ExpNlsTableBase
) KeBugCheck(PHASE0_INITIALIZATION_FAILED
);
738 /* Copy the codepage data in its new location. */
739 RtlMoveMemory(ExpNlsTableBase
,
740 LoaderBlock
->NlsData
->AnsiCodePageData
,
743 /* Initialize and reset the NLS TAbles */
744 RtlInitNlsTables((PVOID
)((ULONG_PTR
)ExpNlsTableBase
+
745 ExpAnsiCodePageDataOffset
),
746 (PVOID
)((ULONG_PTR
)ExpNlsTableBase
+
747 ExpOemCodePageDataOffset
),
748 (PVOID
)((ULONG_PTR
)ExpNlsTableBase
+
749 ExpUnicodeCaseTableDataOffset
),
751 RtlResetRtlTranslations(&ExpNlsTableInfo
);
753 /* Initialize the Handle Table */
754 ExpInitializeHandleTables();
757 /* On checked builds, allocate the system call count table */
758 KeServiceDescriptorTable
[0].Count
=
759 ExAllocatePoolWithTag(NonPagedPool
,
760 KiServiceLimit
* sizeof(ULONG
),
761 TAG('C', 'a', 'l', 'l'));
763 /* Use it for the shadow table too */
764 KeServiceDescriptorTableShadow
[0].Count
= KeServiceDescriptorTable
[0].Count
;
766 /* Make sure allocation succeeded */
767 if (KeServiceDescriptorTable
[0].Count
)
769 /* Zero the call counts to 0 */
770 RtlZeroMemory(KeServiceDescriptorTable
[0].Count
,
771 KiServiceLimit
* sizeof(ULONG
));
775 /* Create the Basic Object Manager Types to allow new Object Types */
776 if (!ObInit()) KEBUGCHECK(OBJECT_INITIALIZATION_FAILED
);
778 /* Load basic Security for other Managers */
779 if (!SeInit()) KEBUGCHECK(SECURITY_INITIALIZATION_FAILED
);
781 /* Set up Region Maps, Sections and the Paging File */
784 /* Call OB initialization again */
785 if (!ObInit()) KEBUGCHECK(OBJECT_INITIALIZATION_FAILED
);
787 /* Initialize the Process Manager */
788 if (!PsInitSystem()) KEBUGCHECK(PROCESS_INITIALIZATION_FAILED
);
790 /* Calculate the tick count multiplier */
791 ExpTickCountMultiplier
= ExComputeTickCountMultiplier(KeMaximumIncrement
);
792 SharedUserData
->TickCountMultiplier
= ExpTickCountMultiplier
;
794 /* Set the OS Version */
795 SharedUserData
->NtMajorVersion
= NtMajorVersion
;
796 SharedUserData
->NtMinorVersion
= NtMinorVersion
;
798 /* Set the machine type */
800 SharedUserData
->ImageNumberLow
= IMAGE_FILE_MACHINE_I386
;
801 SharedUserData
->ImageNumberHigh
= IMAGE_FILE_MACHINE_I386
;
802 #elif defined(_PPC_) // <3 Arty
803 SharedUserData
->ImageNumberLow
= IMAGE_FILE_MACHINE_POWERPC
;
804 SharedUserData
->ImageNumberHigh
= IMAGE_FILE_MACHINE_POWERPC
;
806 #error "Unsupported ReactOS Target"
812 ExPhase2Init(PVOID Context
)
814 UNICODE_STRING EventName
;
815 HANDLE InitDoneEventHandle
;
816 OBJECT_ATTRIBUTES ObjectAttributes
;
817 LARGE_INTEGER Timeout
;
818 HANDLE ProcessHandle
;
822 /* Set us at maximum priority */
823 KeSetPriorityThread(KeGetCurrentThread(), HIGH_PRIORITY
);
825 /* Initialize the later stages of the kernel */
828 /* Initialize all processors */
829 HalAllProcessorsStarted();
831 /* Do Phase 1 HAL Initialization */
832 HalInitSystem(1, KeLoaderBlock
);
834 /* Initialize Basic System Objects and Worker Threads */
837 /* initialize the worker threads */
838 ExpInitializeWorkerThreads();
840 /* initialize callbacks */
841 ExpInitializeCallbacks();
843 /* Call KD Providers at Phase 1 */
844 KdInitSystem(1, KeLoaderBlock
);
846 /* Initialize I/O Objects, Filesystems, Error Logging and Shutdown */
850 PoInit(AcpiTableDetected
, KeLoaderBlock
);
852 /* Initialize the Registry (Hives are NOT yet loaded!) */
853 CmInitializeRegistry();
855 /* Unmap Low memory, initialize the Page Zeroing and the Balancer Thread */
858 /* Initialize Cache Views */
861 /* Initialize File Locking */
862 FsRtlpInitFileLockingImplementation();
864 /* Report all resources used by hal */
865 HalReportResourceUsage();
867 /* Clear the screen to blue */
868 HalInitSystem(2, KeLoaderBlock
);
870 /* Check if GUI Boot is enabled */
871 if (strstr(KeLoaderBlock
->LoadOptions
, "NOGUIBOOT")) NoGuiBoot
= TRUE
;
873 /* Display version number and copyright/warranty message */
874 if (NoGuiBoot
) ExpDisplayNotice();
876 /* Call KD Providers at Phase 2 */
877 KdInitSystem(2, KeLoaderBlock
);
879 /* Create NLS section */
882 /* Import and Load Registry Hives */
883 CmInitHives(ExpInTextModeSetup
);
885 /* Initialize VDM support */
886 KeI386VdmInitialize();
888 /* Initialize the time zone information from the registry */
889 ExpInitTimeZoneInfo();
891 /* Enter the kernel debugger before starting up the boot drivers */
892 if (KdDebuggerEnabled
&& KdpEarlyBreak
)
895 /* Setup Drivers and Root Device Node */
898 /* Display the boot screen image if not disabled */
899 if (!NoGuiBoot
) InbvEnableBootDriver(TRUE
);
901 /* Create ARC Names, SystemRoot SymLink, Load Drivers and Assign Letters */
904 /* Load the System DLL and its Entrypoints */
907 /* Initialize shared user page. Set dos system path, dos device map, etc. */
908 InitSystemSharedUserPage(KeLoaderBlock
);
910 /* Create 'ReactOSInitDone' event */
911 RtlInitUnicodeString(&EventName
, L
"\\ReactOSInitDone");
912 InitializeObjectAttributes(&ObjectAttributes
,
917 Status
= ZwCreateEvent(&InitDoneEventHandle
,
920 SynchronizationEvent
,
923 /* Check for Success */
924 if (!NT_SUCCESS(Status
)) {
926 DPRINT1("Failed to create 'ReactOSInitDone' event (Status 0x%x)\n", Status
);
927 InitDoneEventHandle
= INVALID_HANDLE_VALUE
;
930 /* Launch initial process */
931 Status
= ExpLoadInitialProcess(&ProcessHandle
,
934 /* Check for success, Bugcheck if we failed */
935 if (!NT_SUCCESS(Status
)) {
937 KEBUGCHECKEX(SESSION4_INITIALIZATION_FAILED
, Status
, 0, 0, 0);
940 /* Wait on the Completion Event */
941 if (InitDoneEventHandle
!= INVALID_HANDLE_VALUE
) {
943 HANDLE Handles
[2]; /* Init event, Initial process */
945 /* Setup the Handles to wait on */
946 Handles
[0] = InitDoneEventHandle
;
947 Handles
[1] = ProcessHandle
;
949 /* Wait for the system to be initialized */
950 Timeout
.QuadPart
= (LONGLONG
)-1200000000; /* 120 second timeout */
951 Status
= ZwWaitForMultipleObjects(2,
956 if (!NT_SUCCESS(Status
)) {
958 DPRINT1("NtWaitForMultipleObjects failed with status 0x%x!\n", Status
);
960 } else if (Status
== STATUS_TIMEOUT
) {
962 DPRINT1("WARNING: System not initialized after 120 seconds.\n");
964 } else if (Status
== STATUS_WAIT_0
+ 1) {
966 /* Crash the system if the initial process was terminated. */
967 KEBUGCHECKEX(SESSION5_INITIALIZATION_FAILED
, Status
, 0, 0, 0);
972 * Disable the Boot Logo
974 if (!NoGuiBoot
) InbvEnableBootDriver(FALSE
);
976 /* Signal the Event and close the handle */
977 ZwSetEvent(InitDoneEventHandle
, NULL
);
978 ZwClose(InitDoneEventHandle
);
982 /* On failure to create 'ReactOSInitDone' event, go to text mode ASAP */
983 if (!NoGuiBoot
) InbvEnableBootDriver(FALSE
);
985 /* Crash the system if the initial process terminates within 5 seconds. */
986 Timeout
.QuadPart
= (LONGLONG
)-50000000; /* 5 second timeout */
987 Status
= ZwWaitForSingleObject(ProcessHandle
,
991 /* Check for timeout, crash if the initial process didn't initalize */
992 if (Status
!= STATUS_TIMEOUT
) KEBUGCHECKEX(SESSION5_INITIALIZATION_FAILED
, Status
, 1, 0, 0);
995 /* Enable the Clock, close remaining handles */
996 ZwClose(ThreadHandle
);
997 ZwClose(ProcessHandle
);
999 DPRINT1("System initialization complete\n");
1001 /* FIXME: We should instead jump to zero-page thread */
1002 /* Free initial kernel memory */
1005 /* Set our priority to 0 */
1006 KeGetCurrentThread()->BasePriority
= 0;
1007 KeSetPriorityThread(KeGetCurrentThread(), 0);
1009 /* Wait ad-infinitum */
1012 LARGE_INTEGER Timeout
;
1013 Timeout
.QuadPart
= 0x7fffffffffffffffLL
;
1014 KeDelayExecutionThread(KernelMode
, FALSE
, &Timeout
);