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 /* Init flags and settings */
29 ULONG ExpInitializationPhase
;
30 BOOLEAN ExpInTextModeSetup
;
31 BOOLEAN IoRemoteBootClient
;
32 ULONG InitSafeBootMode
;
34 BOOLEAN NoGuiBoot
= FALSE
;
37 UNICODE_STRING NtSystemRoot
;
39 /* Boot NLS information */
40 PVOID ExpNlsTableBase
;
41 ULONG ExpAnsiCodePageDataOffset
, ExpOemCodePageDataOffset
;
42 ULONG ExpUnicodeCaseTableDataOffset
;
43 NLSTABLEINFO ExpNlsTableInfo
;
44 ULONG ExpNlsTableSize
;
45 PVOID ExpNlsSectionPointer
;
47 /* FUNCTIONS ****************************************************************/
51 ExpInitNls(IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
53 LARGE_INTEGER SectionSize
;
56 PVOID SectionBase
= NULL
;
58 LARGE_INTEGER SectionOffset
= {{0}};
59 PLIST_ENTRY ListHead
, NextEntry
;
60 PMEMORY_ALLOCATION_DESCRIPTOR MdBlock
;
62 /* Check if this is boot-time phase 0 initialization */
63 if (!ExpInitializationPhase
)
65 /* Loop the memory descriptors */
66 ListHead
= &LoaderBlock
->MemoryDescriptorListHead
;
67 NextEntry
= ListHead
->Flink
;
68 while (NextEntry
!= ListHead
)
70 /* Get the current block */
71 MdBlock
= CONTAINING_RECORD(NextEntry
,
72 MEMORY_ALLOCATION_DESCRIPTOR
,
75 /* Check if this is an NLS block */
76 if (MdBlock
->MemoryType
== LoaderNlsData
)
78 /* Increase the table size */
79 ExpNlsTableSize
+= MdBlock
->PageCount
* PAGE_SIZE
;
82 /* Go to the next block */
83 NextEntry
= MdBlock
->ListEntry
.Flink
;
87 * In NT, the memory blocks are contiguous, but in ReactOS they aren't,
88 * so unless someone fixes FreeLdr, we'll have to use this icky hack.
90 ExpNlsTableSize
+= 2 * PAGE_SIZE
; // BIAS FOR FREELDR. HACK!
92 /* Allocate the a new buffer since loader memory will be freed */
93 ExpNlsTableBase
= ExAllocatePoolWithTag(NonPagedPool
,
95 TAG('R', 't', 'l', 'i'));
96 if (!ExpNlsTableBase
) KeBugCheck(PHASE0_INITIALIZATION_FAILED
);
98 /* Copy the codepage data in its new location. */
99 RtlMoveMemory(ExpNlsTableBase
,
100 LoaderBlock
->NlsData
->AnsiCodePageData
,
103 /* Initialize and reset the NLS TAbles */
104 RtlInitNlsTables((PVOID
)((ULONG_PTR
)ExpNlsTableBase
+
105 ExpAnsiCodePageDataOffset
),
106 (PVOID
)((ULONG_PTR
)ExpNlsTableBase
+
107 ExpOemCodePageDataOffset
),
108 (PVOID
)((ULONG_PTR
)ExpNlsTableBase
+
109 ExpUnicodeCaseTableDataOffset
),
111 RtlResetRtlTranslations(&ExpNlsTableInfo
);
115 /* Set the section size */
116 SectionSize
.QuadPart
= ExpNlsTableSize
;
118 /* Create the NLS Section */
119 Status
= ZwCreateSection(&NlsSection
,
126 if (!NT_SUCCESS(Status
))
129 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED
, Status
, 1, 0, 0);
132 /* Get a pointer to the section */
133 Status
= ObReferenceObjectByHandle(NlsSection
,
137 &ExpNlsSectionPointer
,
140 if (!NT_SUCCESS(Status
))
143 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED
, Status
, 2, 0, 0);
146 /* Map the NLS Section in system space */
147 Status
= MmMapViewInSystemSpace(ExpNlsSectionPointer
,
150 if (!NT_SUCCESS(Status
))
153 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED
, Status
, 3, 0, 0);
156 /* Copy the codepage data in its new location. */
157 RtlMoveMemory(SectionBase
, ExpNlsTableBase
, ExpNlsTableSize
);
159 /* Free the previously allocated buffer and set the new location */
160 ExFreePool(ExpNlsTableBase
);
161 ExpNlsTableBase
= SectionBase
;
163 /* Initialize the NLS Tables */
164 RtlInitNlsTables((PVOID
)((ULONG_PTR
)ExpNlsTableBase
+
165 ExpAnsiCodePageDataOffset
),
166 (PVOID
)((ULONG_PTR
)ExpNlsTableBase
+
167 ExpOemCodePageDataOffset
),
168 (PVOID
)((ULONG_PTR
)ExpNlsTableBase
+
169 ExpUnicodeCaseTableDataOffset
),
171 RtlResetRtlTranslations(&ExpNlsTableInfo
);
173 /* Reset the base to 0 */
176 /* Map the section in the system process */
177 Status
= MmMapViewOfSection(ExpNlsSectionPointer
,
178 PsGetCurrentProcess(),
187 if (!NT_SUCCESS(Status
))
190 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED
, Status
, 5, 0, 0);
193 /* Copy the table into the system process and set this as the base */
194 RtlMoveMemory(SectionBase
, ExpNlsTableBase
, ExpNlsTableSize
);
195 ExpNlsTableBase
= SectionBase
;
201 InitSystemSharedUserPage (IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
203 UNICODE_STRING ArcDeviceName
;
204 UNICODE_STRING ArcName
;
205 UNICODE_STRING BootPath
;
206 UNICODE_STRING DriveDeviceName
;
207 UNICODE_STRING DriveName
;
208 WCHAR DriveNameBuffer
[20];
209 PWCHAR ArcNameBuffer
;
212 OBJECT_ATTRIBUTES ObjectAttributes
;
215 BOOLEAN BootDriveFound
= FALSE
;
217 /* Set the Product Type */
218 SharedUserData
->NtProductType
= NtProductWinNt
;
219 SharedUserData
->ProductTypeIsValid
= TRUE
;
222 * Retrieve the current dos system path
223 * (e.g.: C:\reactos) from the given arc path
224 * (e.g.: multi(0)disk(0)rdisk(0)partititon(1)\reactos)
225 * Format: "<arc_name>\<path> [options...]"
228 RtlCreateUnicodeStringFromAsciiz(&BootPath
, LoaderBlock
->NtBootPathName
);
230 /* Remove the trailing backslash */
231 BootPath
.Length
-= sizeof(WCHAR
);
232 BootPath
.MaximumLength
-= sizeof(WCHAR
);
234 /* Only ARC Name left - Build full ARC Name */
235 ArcNameBuffer
= ExAllocatePool (PagedPool
, 256 * sizeof(WCHAR
));
236 swprintf (ArcNameBuffer
, L
"\\ArcName\\%S", LoaderBlock
->ArcBootDeviceName
);
237 RtlInitUnicodeString (&ArcName
, ArcNameBuffer
);
239 /* Allocate ARC Device Name string */
240 ArcDeviceName
.Length
= 0;
241 ArcDeviceName
.MaximumLength
= 256 * sizeof(WCHAR
);
242 ArcDeviceName
.Buffer
= ExAllocatePool (PagedPool
, 256 * sizeof(WCHAR
));
244 /* Open the Symbolic Link */
245 InitializeObjectAttributes(&ObjectAttributes
,
250 Status
= NtOpenSymbolicLinkObject(&Handle
,
251 SYMBOLIC_LINK_ALL_ACCESS
,
254 /* Free the String */
255 ExFreePool(ArcName
.Buffer
);
257 /* Check for Success */
258 if (!NT_SUCCESS(Status
)) {
260 /* Free the Strings */
261 RtlFreeUnicodeString(&BootPath
);
262 ExFreePool(ArcDeviceName
.Buffer
);
263 CPRINT("NtOpenSymbolicLinkObject() failed (Status %x)\n", Status
);
268 Status
= NtQuerySymbolicLinkObject(Handle
,
273 /* Check for Success */
274 if (!NT_SUCCESS(Status
)) {
276 /* Free the Strings */
277 RtlFreeUnicodeString(&BootPath
);
278 ExFreePool(ArcDeviceName
.Buffer
);
279 CPRINT("NtQuerySymbolicLinkObject() failed (Status %x)\n", Status
);
283 /* Allocate Device Name string */
284 DriveDeviceName
.Length
= 0;
285 DriveDeviceName
.MaximumLength
= 256 * sizeof(WCHAR
);
286 DriveDeviceName
.Buffer
= ExAllocatePool (PagedPool
, 256 * sizeof(WCHAR
));
289 for (i
= 0; i
< 26; i
++) {
291 /* Setup the String */
292 swprintf (DriveNameBuffer
, L
"\\??\\%C:", 'A' + i
);
293 RtlInitUnicodeString(&DriveName
,
296 /* Open the Symbolic Link */
297 InitializeObjectAttributes(&ObjectAttributes
,
302 Status
= NtOpenSymbolicLinkObject(&Handle
,
303 SYMBOLIC_LINK_ALL_ACCESS
,
306 /* If it failed, skip to the next drive */
307 if (!NT_SUCCESS(Status
)) {
308 DPRINT("Failed to open link %wZ\n", &DriveName
);
313 Status
= NtQuerySymbolicLinkObject(Handle
,
317 /* If it failed, skip to the next drive */
318 if (!NT_SUCCESS(Status
)) {
319 DPRINT("Failed to query link %wZ\n", &DriveName
);
322 DPRINT("Opened link: %wZ ==> %wZ\n", &DriveName
, &DriveDeviceName
);
324 /* See if we've found the boot drive */
325 if (!RtlCompareUnicodeString (&ArcDeviceName
, &DriveDeviceName
, FALSE
)) {
327 DPRINT("DOS Boot path: %c:%wZ\n", 'A' + i
, &BootPath
);
328 swprintf(SharedUserData
->NtSystemRoot
, L
"%C:%wZ", 'A' + i
, &BootPath
);
329 BootDriveFound
= TRUE
;
332 /* Close this Link */
336 /* Free all the Strings we have in memory */
337 RtlFreeUnicodeString (&BootPath
);
338 ExFreePool(DriveDeviceName
.Buffer
);
339 ExFreePool(ArcDeviceName
.Buffer
);
341 /* Make sure we found the Boot Drive */
342 if (BootDriveFound
== FALSE
) {
344 DbgPrint("No system drive found!\n");
345 KEBUGCHECK (NO_BOOT_DEVICE
);
351 ExpDisplayNotice(VOID
)
355 if (ExpInTextModeSetup
)
358 "\n\n\n ReactOS " KERNEL_VERSION_STR
" Setup \n");
360 " \xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD");
366 HalDisplayString("Starting ReactOS "KERNEL_VERSION_STR
" (Build "
367 KERNEL_VERSION_BUILD_STR
")\n");
368 HalDisplayString(RES_STR_LEGAL_COPYRIGHT
);
369 HalDisplayString("\n\nReactOS is free software, covered by the GNU General "
370 "Public License, and you\n");
371 HalDisplayString("are welcome to change it and/or distribute copies of it "
373 HalDisplayString("conditions. There is absolutely no warranty for "
376 /* Display number of Processors */
378 "Found %x system processor(s). [%lu MB Memory]\n",
379 (int)KeNumberProcessors
,
380 (MmFreeLdrMemHigher
+ 1088)/ 1024);
381 HalDisplayString(str
);
387 ExpLoadInitialProcess(IN PHANDLE ProcessHandle
,
388 IN PHANDLE ThreadHandle
)
390 PRTL_USER_PROCESS_PARAMETERS ProcessParameters
= NULL
;
393 RTL_USER_PROCESS_INFORMATION ProcessInformation
;
395 UNICODE_STRING NullString
= RTL_CONSTANT_STRING(L
"");
396 UNICODE_STRING SmssName
, Environment
, SystemDriveString
;
398 /* Allocate memory for the process parameters */
399 Size
= sizeof(RTL_USER_PROCESS_PARAMETERS
) +
400 ((MAX_PATH
* 4) * sizeof(WCHAR
));
401 Status
= ZwAllocateVirtualMemory(NtCurrentProcess(),
402 (PVOID
)&ProcessParameters
,
407 if (!NT_SUCCESS(Status
))
410 KeBugCheckEx(SESSION1_INITIALIZATION_FAILED
, Status
, 0, 0, 0);
413 /* Setup the basic header, and give the process the low 1MB to itself */
414 ProcessParameters
->Length
= Size
;
415 ProcessParameters
->MaximumLength
= Size
;
416 ProcessParameters
->Flags
= RTL_USER_PROCESS_PARAMETERS_NORMALIZED
|
417 RTL_USER_PROCESS_PARAMETERS_RESERVE_1MB
;
419 /* Allocate a page for the environment */
421 Status
= ZwAllocateVirtualMemory(NtCurrentProcess(),
422 (PVOID
)&ProcessParameters
->Environment
,
428 if (!NT_SUCCESS(Status
))
431 KeBugCheckEx(SESSION2_INITIALIZATION_FAILED
, Status
, 0, 0, 0);
434 /* Make a buffer for the DOS path */
435 p
= (PWSTR
)(ProcessParameters
+ 1);
436 ProcessParameters
->CurrentDirectory
.DosPath
.Buffer
= p
;
438 CurrentDirectory
.DosPath
.MaximumLength
= MAX_PATH
* sizeof(WCHAR
);
440 /* Copy the DOS path */
441 RtlCopyUnicodeString(&ProcessParameters
->CurrentDirectory
.DosPath
,
444 /* Make a buffer for the DLL Path */
445 p
= (PWSTR
)((PCHAR
)ProcessParameters
->CurrentDirectory
.DosPath
.Buffer
+
446 ProcessParameters
->CurrentDirectory
.DosPath
.MaximumLength
);
447 ProcessParameters
->DllPath
.Buffer
= p
;
448 ProcessParameters
->DllPath
.MaximumLength
= MAX_PATH
* sizeof(WCHAR
);
450 /* Copy the DLL path and append the system32 directory */
451 RtlCopyUnicodeString(&ProcessParameters
->DllPath
,
452 &ProcessParameters
->CurrentDirectory
.DosPath
);
453 RtlAppendUnicodeToString(&ProcessParameters
->DllPath
, L
"\\System32");
455 /* Make a buffer for the image name */
456 p
= (PWSTR
)((PCHAR
)ProcessParameters
->DllPath
.Buffer
+
457 ProcessParameters
->DllPath
.MaximumLength
);
458 ProcessParameters
->ImagePathName
.Buffer
= p
;
459 ProcessParameters
->ImagePathName
.MaximumLength
= MAX_PATH
* sizeof(WCHAR
);
461 /* Append the system path and session manager name */
462 RtlAppendUnicodeToString(&ProcessParameters
->ImagePathName
,
463 L
"\\SystemRoot\\System32");
464 RtlAppendUnicodeToString(&ProcessParameters
->ImagePathName
,
467 /* Create the environment string */
468 RtlInitEmptyUnicodeString(&Environment
,
469 ProcessParameters
->Environment
,
472 /* Append the DLL path to it */
473 RtlAppendUnicodeToString(&Environment
, L
"Path=" );
474 RtlAppendUnicodeStringToString(&Environment
, &ProcessParameters
->DllPath
);
475 RtlAppendUnicodeStringToString(&Environment
, &NullString
);
477 /* Create the system drive string */
478 SystemDriveString
= NtSystemRoot
;
479 SystemDriveString
.Length
= 2 * sizeof(WCHAR
);
481 /* Append it to the environment */
482 RtlAppendUnicodeToString(&Environment
, L
"SystemDrive=");
483 RtlAppendUnicodeStringToString(&Environment
, &SystemDriveString
);
484 RtlAppendUnicodeStringToString(&Environment
, &NullString
);
486 /* Append the system root to the environment */
487 RtlAppendUnicodeToString(&Environment
, L
"SystemRoot=");
488 RtlAppendUnicodeStringToString(&Environment
, &NtSystemRoot
);
489 RtlAppendUnicodeStringToString(&Environment
, &NullString
);
491 /* Get and set the command line equal to the image path */
492 ProcessParameters
->CommandLine
= ProcessParameters
->ImagePathName
;
493 SmssName
= ProcessParameters
->ImagePathName
;
495 /* Create SMSS process */
496 Status
= RtlCreateUserProcess(&SmssName
,
497 OBJ_CASE_INSENSITIVE
,
498 RtlDeNormalizeProcessParams(
506 &ProcessInformation
);
507 if (!NT_SUCCESS(Status
))
510 KeBugCheckEx(SESSION3_INITIALIZATION_FAILED
, Status
, 0, 0, 0);
513 /* Resume the thread */
514 Status
= ZwResumeThread(ProcessInformation
.ThreadHandle
, NULL
);
515 if (!NT_SUCCESS(Status
))
518 KeBugCheckEx(SESSION4_INITIALIZATION_FAILED
, Status
, 0, 0, 0);
522 *ProcessHandle
= ProcessInformation
.ProcessHandle
;
523 *ThreadHandle
= ProcessInformation
.ThreadHandle
;
524 return STATUS_SUCCESS
;
529 ExComputeTickCountMultiplier(IN ULONG ClockIncrement
)
531 ULONG MsRemainder
= 0, MsIncrement
;
532 ULONG IncrementRemainder
;
535 /* Count the number of milliseconds for each clock interrupt */
536 MsIncrement
= ClockIncrement
/ (10 * 1000);
538 /* Count the remainder from the division above, with 24-bit precision */
539 IncrementRemainder
= ClockIncrement
- (MsIncrement
* (10 * 1000));
540 for (i
= 0; i
< 24; i
++)
542 /* Shift the remainders */
544 IncrementRemainder
<<= 1;
546 /* Check if we've went past 1 ms */
547 if (IncrementRemainder
>= (10 * 1000))
549 /* Increase the remainder by one, and substract from increment */
550 IncrementRemainder
-= (10 * 1000);
555 /* Return the increment */
556 return (MsIncrement
<< 24) | MsRemainder
;
561 ExpInitSystemPhase0(VOID
)
563 /* Initialize EXRESOURCE Support */
564 ExpResourceInitialization();
566 /* Initialize the environment lock */
567 ExInitializeFastMutex(&ExpEnvironmentLock
);
569 /* Initialize the lookaside lists and locks */
570 ExpInitLookasideLists();
572 /* Initialize the Firmware Table resource and listhead */
573 InitializeListHead(&ExpFirmwareTableProviderListHead
);
574 ExInitializeResourceLite(&ExpFirmwareTableResource
);
576 /* Set the suite mask to maximum and return */
577 ExSuiteMask
= 0xFFFFFFFF;
583 ExpInitSystemPhase1(VOID
)
585 /* Initialize worker threads */
586 ExpInitializeWorkerThreads();
588 /* Initialize pushlocks */
589 ExpInitializePushLocks();
591 /* Initialize events and event pairs */
592 ExpInitializeEventImplementation();
593 ExpInitializeEventPairImplementation();
595 /* Initialize callbacks */
596 ExpInitializeCallbacks();
598 /* Initialize mutants */
599 ExpInitializeMutantImplementation();
601 /* Initialize semaphores */
602 ExpInitializeSemaphoreImplementation();
604 /* Initialize timers */
605 ExpInitializeTimerImplementation();
607 /* Initialize profiling */
608 ExpInitializeProfileImplementation();
610 /* Initialize UUIDs */
613 /* Initialize Win32K */
622 /* Check the initialization phase */
623 switch (ExpInitializationPhase
)
628 return ExpInitSystemPhase0();
633 return ExpInitSystemPhase1();
637 /* Don't know any other phase! Bugcheck! */
638 KeBugCheck(UNEXPECTED_INITIALIZATION_CALL
);
645 ExpIsLoaderValid(IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
647 PLOADER_PARAMETER_EXTENSION Extension
;
649 /* Get the loader extension */
650 Extension
= LoaderBlock
->Extension
;
652 /* Validate the size (larger structures are OK, we'll just ignore them) */
653 if (Extension
->Size
< sizeof(LOADER_PARAMETER_EXTENSION
)) return FALSE
;
655 /* Don't validate upper versions */
656 if (Extension
->MajorVersion
> 5) return TRUE
;
658 /* Fail if this is NT 4 */
659 if (Extension
->MajorVersion
< 5) return FALSE
;
661 /* Fail if this is XP */
662 if (Extension
->MinorVersion
< 2) return FALSE
;
664 /* This is 2003 or newer, aprove it */
670 ExpInitializeExecutive(IN ULONG Cpu
,
671 IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
673 PNLS_DATA_BLOCK NlsData
;
675 ANSI_STRING AnsiPath
;
678 /* Validate Loader */
679 if (!ExpIsLoaderValid(LoaderBlock
))
681 /* Invalid loader version */
682 KeBugCheckEx(MISMATCHED_HAL
,
684 LoaderBlock
->Extension
->Size
,
685 LoaderBlock
->Extension
->MajorVersion
,
686 LoaderBlock
->Extension
->MinorVersion
);
689 /* Initialize PRCB pool lookaside pointers */
690 ExInitPoolLookasidePointers();
692 /* Check if this is an application CPU */
695 /* Then simply initialize it with HAL */
696 if (!HalInitSystem(ExpInitializationPhase
, LoaderBlock
))
698 /* Initialization failed */
699 KEBUGCHECK(HAL_INITIALIZATION_FAILED
);
706 /* Assume no text-mode or remote boot */
707 ExpInTextModeSetup
= FALSE
;
708 IoRemoteBootClient
= FALSE
;
710 /* Check if we have a setup loader block */
711 if (LoaderBlock
->SetupLdrBlock
)
713 /* Check if this is text-mode setup */
714 if (LoaderBlock
->SetupLdrBlock
->Flags
& 1) ExpInTextModeSetup
= TRUE
;
716 /* Check if this is network boot */
717 if (LoaderBlock
->SetupLdrBlock
->Flags
& 2)
720 IoRemoteBootClient
= TRUE
;
722 /* Make sure we're actually booting off the network */
723 ASSERT(!_memicmp(LoaderBlock
->ArcBootDeviceName
, "net(0)", 6));
728 ExpInitializationPhase
= 0;
730 /* Setup NLS Base and offsets */
731 NlsData
= LoaderBlock
->NlsData
;
732 ExpNlsTableBase
= NlsData
->AnsiCodePageData
;
733 ExpAnsiCodePageDataOffset
= 0;
734 ExpOemCodePageDataOffset
= ((ULONG_PTR
)NlsData
->OemCodePageData
-
735 (ULONG_PTR
)NlsData
->AnsiCodePageData
);
736 ExpUnicodeCaseTableDataOffset
= ((ULONG_PTR
)NlsData
->UnicodeCodePageData
-
737 (ULONG_PTR
)NlsData
->AnsiCodePageData
);
739 /* Initialize the NLS Tables */
740 RtlInitNlsTables((PVOID
)((ULONG_PTR
)ExpNlsTableBase
+
741 ExpAnsiCodePageDataOffset
),
742 (PVOID
)((ULONG_PTR
)ExpNlsTableBase
+
743 ExpOemCodePageDataOffset
),
744 (PVOID
)((ULONG_PTR
)ExpNlsTableBase
+
745 ExpUnicodeCaseTableDataOffset
),
747 RtlResetRtlTranslations(&ExpNlsTableInfo
);
749 /* Now initialize the HAL */
750 if (!HalInitSystem(ExpInitializationPhase
, LoaderBlock
))
752 /* HAL failed to initialize, bugcheck */
753 KeBugCheck(HAL_INITIALIZATION_FAILED
);
756 /* Make sure interrupts are active now */
759 /* Clear the crypto exponent */
760 SharedUserData
->CryptoExponent
= 0;
762 /* Set global flags for the checked build */
764 NtGlobalFlag
|= FLG_ENABLE_CLOSE_EXCEPTIONS
|
765 FLG_ENABLE_KDEBUG_SYMBOL_LOAD
;
768 /* Setup NT System Root Path */
769 sprintf(Buffer
, "C:%s", LoaderBlock
->NtBootPathName
);
771 /* Convert to ANSI_STRING and null-terminate it */
772 RtlInitString(&AnsiPath
, Buffer
);
773 Buffer
[--AnsiPath
.Length
] = UNICODE_NULL
;
775 /* Get the string from KUSER_SHARED_DATA's buffer */
776 NtSystemRoot
.Buffer
= SharedUserData
->NtSystemRoot
;
777 NtSystemRoot
.MaximumLength
= sizeof(SharedUserData
->NtSystemRoot
) / sizeof(WCHAR
);
778 NtSystemRoot
.Length
= 0;
781 Status
= RtlAnsiStringToUnicodeString(&NtSystemRoot
, &AnsiPath
, FALSE
);
782 if (!NT_SUCCESS(Status
)) KEBUGCHECK(SESSION3_INITIALIZATION_FAILED
);
784 /* Setup bugcheck messages */
785 KiInitializeBugCheck();
787 /* Initialize the executive at phase 0 */
788 if (!ExInitSystem()) KEBUGCHECK(PHASE0_INITIALIZATION_FAILED
);
790 /* Break into the Debugger if requested */
791 if (KdPollBreakIn()) DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C
);
793 /* Set system ranges */
794 SharedUserData
->Reserved1
= (ULONG_PTR
)MmHighestUserAddress
;
795 SharedUserData
->Reserved3
= (ULONG_PTR
)MmSystemRangeStart
;
797 /* Make a copy of the NLS Tables */
798 ExpInitNls(LoaderBlock
);
800 /* Initialize the Handle Table */
801 ExpInitializeHandleTables();
804 /* On checked builds, allocate the system call count table */
805 KeServiceDescriptorTable
[0].Count
=
806 ExAllocatePoolWithTag(NonPagedPool
,
807 KiServiceLimit
* sizeof(ULONG
),
808 TAG('C', 'a', 'l', 'l'));
810 /* Use it for the shadow table too */
811 KeServiceDescriptorTableShadow
[0].Count
= KeServiceDescriptorTable
[0].Count
;
813 /* Make sure allocation succeeded */
814 if (KeServiceDescriptorTable
[0].Count
)
816 /* Zero the call counts to 0 */
817 RtlZeroMemory(KeServiceDescriptorTable
[0].Count
,
818 KiServiceLimit
* sizeof(ULONG
));
822 /* Create the Basic Object Manager Types to allow new Object Types */
823 if (!ObInit()) KEBUGCHECK(OBJECT_INITIALIZATION_FAILED
);
825 /* Load basic Security for other Managers */
826 if (!SeInit()) KEBUGCHECK(SECURITY_INITIALIZATION_FAILED
);
828 /* Set up Region Maps, Sections and the Paging File */
831 /* Initialize the Process Manager */
832 if (!PsInitSystem()) KEBUGCHECK(PROCESS_INITIALIZATION_FAILED
);
834 /* Calculate the tick count multiplier */
835 ExpTickCountMultiplier
= ExComputeTickCountMultiplier(KeMaximumIncrement
);
836 SharedUserData
->TickCountMultiplier
= ExpTickCountMultiplier
;
838 /* Set the OS Version */
839 SharedUserData
->NtMajorVersion
= NtMajorVersion
;
840 SharedUserData
->NtMinorVersion
= NtMinorVersion
;
842 /* Set the machine type */
844 SharedUserData
->ImageNumberLow
= IMAGE_FILE_MACHINE_I386
;
845 SharedUserData
->ImageNumberHigh
= IMAGE_FILE_MACHINE_I386
;
846 #elif defined(_PPC_) // <3 Arty
847 SharedUserData
->ImageNumberLow
= IMAGE_FILE_MACHINE_POWERPC
;
848 SharedUserData
->ImageNumberHigh
= IMAGE_FILE_MACHINE_POWERPC
;
850 #error "Unsupported ReactOS Target"
856 ExPhase2Init(PVOID Context
)
858 LARGE_INTEGER Timeout
;
859 HANDLE ProcessHandle
;
864 ExpInitializationPhase
= 1;
866 /* Set us at maximum priority */
867 KeSetPriorityThread(KeGetCurrentThread(), HIGH_PRIORITY
);
869 /* Do Phase 1 HAL Initialization */
870 HalInitSystem(1, KeLoaderBlock
);
872 /* Setup system time */
873 KiInitializeSystemClock();
875 /* Initialize all processors */
876 HalAllProcessorsStarted();
878 /* Call OB initialization again */
879 if (!ObInit()) KEBUGCHECK(OBJECT1_INITIALIZATION_FAILED
);
881 /* Initialize Basic System Objects and Worker Threads */
882 if (!ExInitSystem()) KEBUGCHECK(PHASE1_INITIALIZATION_FAILED
);
884 /* Initialize the later stages of the kernel */
885 if (!KeInitSystem()) KEBUGCHECK(PHASE1_INITIALIZATION_FAILED
);
887 /* Create NLS section */
888 ExpInitNls(KeLoaderBlock
);
890 /* Call KD Providers at Phase 1 */
891 KdInitSystem(1, KeLoaderBlock
);
893 /* Initialize I/O Objects, Filesystems, Error Logging and Shutdown */
897 PoInit(AcpiTableDetected
, KeLoaderBlock
);
899 /* Initialize the Registry (Hives are NOT yet loaded!) */
900 CmInitializeRegistry();
902 /* Unmap Low memory, and initialize the MPW and Balancer Thread */
905 /* Initialize Cache Views */
908 /* Initialize File Locking */
909 FsRtlpInitFileLockingImplementation();
911 /* Report all resources used by hal */
912 HalReportResourceUsage();
914 /* Clear the screen to blue */
915 HalInitSystem(2, KeLoaderBlock
);
917 /* Check if GUI Boot is enabled */
918 if (strstr(KeLoaderBlock
->LoadOptions
, "NOGUIBOOT")) NoGuiBoot
= TRUE
;
920 /* Display version number and copyright/warranty message */
921 if (NoGuiBoot
) ExpDisplayNotice();
923 /* Call KD Providers at Phase 2 */
924 KdInitSystem(2, KeLoaderBlock
);
929 /* Import and Load Registry Hives */
930 CmInitHives(ExpInTextModeSetup
);
932 /* Initialize VDM support */
933 KeI386VdmInitialize();
935 /* Initialize the time zone information from the registry */
936 ExpInitTimeZoneInfo();
938 /* Enter the kernel debugger before starting up the boot drivers */
939 if (KdDebuggerEnabled
&& KdpEarlyBreak
)
942 /* Setup Drivers and Root Device Node */
945 /* Display the boot screen image if not disabled */
946 if (!NoGuiBoot
) InbvEnableBootDriver(TRUE
);
948 /* Create ARC Names, SystemRoot SymLink, Load Drivers and Assign Letters */
951 /* Load the System DLL and its Entrypoints */
954 /* Initialize shared user page. Set dos system path, dos device map, etc. */
955 InitSystemSharedUserPage(KeLoaderBlock
);
957 /* Launch initial process */
958 Status
= ExpLoadInitialProcess(&ProcessHandle
,
961 /* Wait 5 seconds for it to initialize */
962 Timeout
.QuadPart
= Int32x32To64(5, -10000000);
963 Status
= ZwWaitForSingleObject(ProcessHandle
, FALSE
, &Timeout
);
964 if (Status
== STATUS_SUCCESS
)
966 /* Bugcheck the system if SMSS couldn't initialize */
967 KeBugCheck(SESSION5_INITIALIZATION_FAILED
);
971 /* Close process handles */
972 ZwClose(ThreadHandle
);
973 ZwClose(ProcessHandle
);
977 * Disable the Boot Logo
979 if (!NoGuiBoot
) InbvEnableBootDriver(FALSE
);
981 /* FIXME: We should free the initial process' memory!*/
983 /* Increase init phase */
984 ExpInitializationPhase
+= 1;
986 /* Jump into zero page thread */
987 MmZeroPageThreadMain(NULL
);