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 ****************************************************************/
53 LARGE_INTEGER SectionSize
;
56 PVOID SectionBase
= NULL
;
58 LARGE_INTEGER SectionOffset
= {{0}};
60 /* Set the section size */
61 SectionSize
.QuadPart
= ExpNlsTableSize
;
63 /* Create the NLS Section */
64 Status
= ZwCreateSection(&NlsSection
,
71 if (!NT_SUCCESS(Status
))
74 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED
, Status
, 1, 0, 0);
77 /* Get a pointer to the section */
78 Status
= ObReferenceObjectByHandle(NlsSection
,
82 &ExpNlsSectionPointer
,
85 if (!NT_SUCCESS(Status
))
88 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED
, Status
, 2, 0, 0);
91 /* Map the NLS Section in system space */
92 Status
= MmMapViewInSystemSpace(ExpNlsSectionPointer
,
95 if (!NT_SUCCESS(Status
))
98 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED
, Status
, 3, 0, 0);
101 /* Copy the codepage data in its new location. */
102 RtlMoveMemory(SectionBase
, ExpNlsTableBase
, ExpNlsTableSize
);
104 /* Free the previously allocated buffer and set the new location */
105 ExFreePool(ExpNlsTableBase
);
106 ExpNlsTableBase
= SectionBase
;
108 /* Initialize the NLS Tables */
109 RtlInitNlsTables((PVOID
)((ULONG_PTR
)ExpNlsTableBase
+
110 ExpAnsiCodePageDataOffset
),
111 (PVOID
)((ULONG_PTR
)ExpNlsTableBase
+
112 ExpOemCodePageDataOffset
),
113 (PVOID
)((ULONG_PTR
)ExpNlsTableBase
+
114 ExpUnicodeCaseTableDataOffset
),
116 RtlResetRtlTranslations(&ExpNlsTableInfo
);
118 /* Reset the base to 0 */
121 /* Map the section in the system process */
122 Status
= MmMapViewOfSection(ExpNlsSectionPointer
,
123 PsGetCurrentProcess(),
132 if (!NT_SUCCESS(Status
))
135 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED
, Status
, 5, 0, 0);
138 /* Copy the table into the system process and set this as the base */
139 RtlMoveMemory(SectionBase
, ExpNlsTableBase
, ExpNlsTableSize
);
140 ExpNlsTableBase
= SectionBase
;
146 InitSystemSharedUserPage (IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
148 UNICODE_STRING ArcDeviceName
;
149 UNICODE_STRING ArcName
;
150 UNICODE_STRING BootPath
;
151 UNICODE_STRING DriveDeviceName
;
152 UNICODE_STRING DriveName
;
153 WCHAR DriveNameBuffer
[20];
154 PWCHAR ArcNameBuffer
;
157 OBJECT_ATTRIBUTES ObjectAttributes
;
160 BOOLEAN BootDriveFound
= FALSE
;
162 /* Set the Product Type */
163 SharedUserData
->NtProductType
= NtProductWinNt
;
164 SharedUserData
->ProductTypeIsValid
= TRUE
;
167 * Retrieve the current dos system path
168 * (e.g.: C:\reactos) from the given arc path
169 * (e.g.: multi(0)disk(0)rdisk(0)partititon(1)\reactos)
170 * Format: "<arc_name>\<path> [options...]"
173 RtlCreateUnicodeStringFromAsciiz(&BootPath
, LoaderBlock
->NtBootPathName
);
175 /* Remove the trailing backslash */
176 BootPath
.Length
-= sizeof(WCHAR
);
177 BootPath
.MaximumLength
-= sizeof(WCHAR
);
179 /* Only ARC Name left - Build full ARC Name */
180 ArcNameBuffer
= ExAllocatePool (PagedPool
, 256 * sizeof(WCHAR
));
181 swprintf (ArcNameBuffer
, L
"\\ArcName\\%S", LoaderBlock
->ArcBootDeviceName
);
182 RtlInitUnicodeString (&ArcName
, ArcNameBuffer
);
184 /* Allocate ARC Device Name string */
185 ArcDeviceName
.Length
= 0;
186 ArcDeviceName
.MaximumLength
= 256 * sizeof(WCHAR
);
187 ArcDeviceName
.Buffer
= ExAllocatePool (PagedPool
, 256 * sizeof(WCHAR
));
189 /* Open the Symbolic Link */
190 InitializeObjectAttributes(&ObjectAttributes
,
195 Status
= NtOpenSymbolicLinkObject(&Handle
,
196 SYMBOLIC_LINK_ALL_ACCESS
,
199 /* Free the String */
200 ExFreePool(ArcName
.Buffer
);
202 /* Check for Success */
203 if (!NT_SUCCESS(Status
)) {
205 /* Free the Strings */
206 RtlFreeUnicodeString(&BootPath
);
207 ExFreePool(ArcDeviceName
.Buffer
);
208 CPRINT("NtOpenSymbolicLinkObject() failed (Status %x)\n", Status
);
213 Status
= NtQuerySymbolicLinkObject(Handle
,
218 /* Check for Success */
219 if (!NT_SUCCESS(Status
)) {
221 /* Free the Strings */
222 RtlFreeUnicodeString(&BootPath
);
223 ExFreePool(ArcDeviceName
.Buffer
);
224 CPRINT("NtQuerySymbolicLinkObject() failed (Status %x)\n", Status
);
228 /* Allocate Device Name string */
229 DriveDeviceName
.Length
= 0;
230 DriveDeviceName
.MaximumLength
= 256 * sizeof(WCHAR
);
231 DriveDeviceName
.Buffer
= ExAllocatePool (PagedPool
, 256 * sizeof(WCHAR
));
234 for (i
= 0; i
< 26; i
++) {
236 /* Setup the String */
237 swprintf (DriveNameBuffer
, L
"\\??\\%C:", 'A' + i
);
238 RtlInitUnicodeString(&DriveName
,
241 /* Open the Symbolic Link */
242 InitializeObjectAttributes(&ObjectAttributes
,
247 Status
= NtOpenSymbolicLinkObject(&Handle
,
248 SYMBOLIC_LINK_ALL_ACCESS
,
251 /* If it failed, skip to the next drive */
252 if (!NT_SUCCESS(Status
)) {
253 DPRINT("Failed to open link %wZ\n", &DriveName
);
258 Status
= NtQuerySymbolicLinkObject(Handle
,
262 /* If it failed, skip to the next drive */
263 if (!NT_SUCCESS(Status
)) {
264 DPRINT("Failed to query link %wZ\n", &DriveName
);
267 DPRINT("Opened link: %wZ ==> %wZ\n", &DriveName
, &DriveDeviceName
);
269 /* See if we've found the boot drive */
270 if (!RtlCompareUnicodeString (&ArcDeviceName
, &DriveDeviceName
, FALSE
)) {
272 DPRINT("DOS Boot path: %c:%wZ\n", 'A' + i
, &BootPath
);
273 swprintf(SharedUserData
->NtSystemRoot
, L
"%C:%wZ", 'A' + i
, &BootPath
);
274 BootDriveFound
= TRUE
;
277 /* Close this Link */
281 /* Free all the Strings we have in memory */
282 RtlFreeUnicodeString (&BootPath
);
283 ExFreePool(DriveDeviceName
.Buffer
);
284 ExFreePool(ArcDeviceName
.Buffer
);
286 /* Make sure we found the Boot Drive */
287 if (BootDriveFound
== FALSE
) {
289 DbgPrint("No system drive found!\n");
290 KEBUGCHECK (NO_BOOT_DEVICE
);
296 ExpDisplayNotice(VOID
)
300 if (ExpInTextModeSetup
)
303 "\n\n\n ReactOS " KERNEL_VERSION_STR
" Setup \n");
305 " \xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD");
311 HalDisplayString("Starting ReactOS "KERNEL_VERSION_STR
" (Build "
312 KERNEL_VERSION_BUILD_STR
")\n");
313 HalDisplayString(RES_STR_LEGAL_COPYRIGHT
);
314 HalDisplayString("\n\nReactOS is free software, covered by the GNU General "
315 "Public License, and you\n");
316 HalDisplayString("are welcome to change it and/or distribute copies of it "
318 HalDisplayString("conditions. There is absolutely no warranty for "
321 /* Display number of Processors */
323 "Found %x system processor(s). [%lu MB Memory]\n",
324 (int)KeNumberProcessors
,
325 (MmFreeLdrMemHigher
+ 1088)/ 1024);
326 HalDisplayString(str
);
332 ExpLoadInitialProcess(IN PHANDLE ProcessHandle
,
333 IN PHANDLE ThreadHandle
)
335 PRTL_USER_PROCESS_PARAMETERS ProcessParameters
= NULL
;
338 RTL_USER_PROCESS_INFORMATION ProcessInformation
;
340 UNICODE_STRING NullString
= RTL_CONSTANT_STRING(L
"");
341 UNICODE_STRING SmssName
, Environment
, SystemDriveString
;
343 /* Allocate memory for the process parameters */
344 Size
= sizeof(RTL_USER_PROCESS_PARAMETERS
) +
345 ((MAX_PATH
* 4) * sizeof(WCHAR
));
346 Status
= ZwAllocateVirtualMemory(NtCurrentProcess(),
347 (PVOID
)&ProcessParameters
,
352 if (!NT_SUCCESS(Status
))
355 KeBugCheckEx(SESSION1_INITIALIZATION_FAILED
, Status
, 0, 0, 0);
358 /* Setup the basic header, and give the process the low 1MB to itself */
359 ProcessParameters
->Length
= Size
;
360 ProcessParameters
->MaximumLength
= Size
;
361 ProcessParameters
->Flags
= RTL_USER_PROCESS_PARAMETERS_NORMALIZED
|
362 RTL_USER_PROCESS_PARAMETERS_RESERVE_1MB
;
364 /* Allocate a page for the environment */
366 Status
= ZwAllocateVirtualMemory(NtCurrentProcess(),
367 (PVOID
)&ProcessParameters
->Environment
,
373 if (!NT_SUCCESS(Status
))
376 KeBugCheckEx(SESSION2_INITIALIZATION_FAILED
, Status
, 0, 0, 0);
379 /* Make a buffer for the DOS path */
380 p
= (PWSTR
)(ProcessParameters
+ 1);
381 ProcessParameters
->CurrentDirectory
.DosPath
.Buffer
= p
;
383 CurrentDirectory
.DosPath
.MaximumLength
= MAX_PATH
* sizeof(WCHAR
);
385 /* Copy the DOS path */
386 RtlCopyUnicodeString(&ProcessParameters
->CurrentDirectory
.DosPath
,
389 /* Make a buffer for the DLL Path */
390 p
= (PWSTR
)((PCHAR
)ProcessParameters
->CurrentDirectory
.DosPath
.Buffer
+
391 ProcessParameters
->CurrentDirectory
.DosPath
.MaximumLength
);
392 ProcessParameters
->DllPath
.Buffer
= p
;
393 ProcessParameters
->DllPath
.MaximumLength
= MAX_PATH
* sizeof(WCHAR
);
395 /* Copy the DLL path and append the system32 directory */
396 RtlCopyUnicodeString(&ProcessParameters
->DllPath
,
397 &ProcessParameters
->CurrentDirectory
.DosPath
);
398 RtlAppendUnicodeToString(&ProcessParameters
->DllPath
, L
"\\System32");
400 /* Make a buffer for the image name */
401 p
= (PWSTR
)((PCHAR
)ProcessParameters
->DllPath
.Buffer
+
402 ProcessParameters
->DllPath
.MaximumLength
);
403 ProcessParameters
->ImagePathName
.Buffer
= p
;
404 ProcessParameters
->ImagePathName
.MaximumLength
= MAX_PATH
* sizeof(WCHAR
);
406 /* Append the system path and session manager name */
407 RtlAppendUnicodeToString(&ProcessParameters
->ImagePathName
,
408 L
"\\SystemRoot\\System32");
409 RtlAppendUnicodeToString(&ProcessParameters
->ImagePathName
,
412 /* Create the environment string */
413 RtlInitEmptyUnicodeString(&Environment
,
414 ProcessParameters
->Environment
,
417 /* Append the DLL path to it */
418 RtlAppendUnicodeToString(&Environment
, L
"Path=" );
419 RtlAppendUnicodeStringToString(&Environment
, &ProcessParameters
->DllPath
);
420 RtlAppendUnicodeStringToString(&Environment
, &NullString
);
422 /* Create the system drive string */
423 SystemDriveString
= NtSystemRoot
;
424 SystemDriveString
.Length
= 2 * sizeof(WCHAR
);
426 /* Append it to the environment */
427 RtlAppendUnicodeToString(&Environment
, L
"SystemDrive=");
428 RtlAppendUnicodeStringToString(&Environment
, &SystemDriveString
);
429 RtlAppendUnicodeStringToString(&Environment
, &NullString
);
431 /* Append the system root to the environment */
432 RtlAppendUnicodeToString(&Environment
, L
"SystemRoot=");
433 RtlAppendUnicodeStringToString(&Environment
, &NtSystemRoot
);
434 RtlAppendUnicodeStringToString(&Environment
, &NullString
);
436 /* Get and set the command line equal to the image path */
437 ProcessParameters
->CommandLine
= ProcessParameters
->ImagePathName
;
438 SmssName
= ProcessParameters
->ImagePathName
;
440 /* Create SMSS process */
441 Status
= RtlCreateUserProcess(&SmssName
,
442 OBJ_CASE_INSENSITIVE
,
443 RtlDeNormalizeProcessParams(
451 &ProcessInformation
);
452 if (!NT_SUCCESS(Status
))
455 KeBugCheckEx(SESSION3_INITIALIZATION_FAILED
, Status
, 0, 0, 0);
458 /* Resume the thread */
459 Status
= ZwResumeThread(ProcessInformation
.ThreadHandle
, NULL
);
460 if (!NT_SUCCESS(Status
))
463 KeBugCheckEx(SESSION4_INITIALIZATION_FAILED
, Status
, 0, 0, 0);
467 *ProcessHandle
= ProcessInformation
.ProcessHandle
;
468 *ThreadHandle
= ProcessInformation
.ThreadHandle
;
469 return STATUS_SUCCESS
;
474 ExComputeTickCountMultiplier(IN ULONG ClockIncrement
)
476 ULONG MsRemainder
= 0, MsIncrement
;
477 ULONG IncrementRemainder
;
480 /* Count the number of milliseconds for each clock interrupt */
481 MsIncrement
= ClockIncrement
/ (10 * 1000);
483 /* Count the remainder from the division above, with 24-bit precision */
484 IncrementRemainder
= ClockIncrement
- (MsIncrement
* (10 * 1000));
485 for (i
= 0; i
< 24; i
++)
487 /* Shift the remainders */
489 IncrementRemainder
<<= 1;
491 /* Check if we've went past 1 ms */
492 if (IncrementRemainder
>= (10 * 1000))
494 /* Increase the remainder by one, and substract from increment */
495 IncrementRemainder
-= (10 * 1000);
500 /* Return the increment */
501 return (MsIncrement
<< 24) | MsRemainder
;
506 ExpInitSystemPhase0(VOID
)
508 /* Initialize EXRESOURCE Support */
509 ExpResourceInitialization();
511 /* Initialize the environment lock */
512 ExInitializeFastMutex(&ExpEnvironmentLock
);
514 /* Initialize the lookaside lists and locks */
515 ExpInitLookasideLists();
517 /* Initialize the Firmware Table resource and listhead */
518 InitializeListHead(&ExpFirmwareTableProviderListHead
);
519 ExInitializeResourceLite(&ExpFirmwareTableResource
);
521 /* Set the suite mask to maximum and return */
522 ExSuiteMask
= 0xFFFFFFFF;
528 ExpInitSystemPhase1(VOID
)
530 /* Initialize worker threads */
531 ExpInitializeWorkerThreads();
533 /* Initialize pushlocks */
534 ExpInitializePushLocks();
536 /* Initialize events and event pairs */
537 ExpInitializeEventImplementation();
538 ExpInitializeEventPairImplementation();
540 /* Initialize callbacks */
541 ExpInitializeCallbacks();
543 /* Initialize mutants */
544 ExpInitializeMutantImplementation();
546 /* Initialize semaphores */
547 ExpInitializeSemaphoreImplementation();
549 /* Initialize timers */
550 ExpInitializeTimerImplementation();
552 /* Initialize profiling */
553 ExpInitializeProfileImplementation();
555 /* Initialize UUIDs */
558 /* Initialize Win32K */
567 /* Check the initialization phase */
568 switch (ExpInitializationPhase
)
573 return ExpInitSystemPhase0();
578 return ExpInitSystemPhase1();
582 /* Don't know any other phase! Bugcheck! */
583 KeBugCheck(UNEXPECTED_INITIALIZATION_CALL
);
590 ExpIsLoaderValid(IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
592 PLOADER_PARAMETER_EXTENSION Extension
;
594 /* Get the loader extension */
595 Extension
= LoaderBlock
->Extension
;
597 /* Validate the size (larger structures are OK, we'll just ignore them) */
598 if (Extension
->Size
< sizeof(LOADER_PARAMETER_EXTENSION
)) return FALSE
;
600 /* Don't validate upper versions */
601 if (Extension
->MajorVersion
> 5) return TRUE
;
603 /* Fail if this is NT 4 */
604 if (Extension
->MajorVersion
< 5) return FALSE
;
606 /* Fail if this is XP */
607 if (Extension
->MinorVersion
< 2) return FALSE
;
609 /* This is 2003 or newer, aprove it */
615 ExpInitializeExecutive(IN ULONG Cpu
,
616 IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
618 PNLS_DATA_BLOCK NlsData
;
620 ANSI_STRING AnsiPath
;
622 PLIST_ENTRY NextEntry
, ListHead
;
623 PMEMORY_ALLOCATION_DESCRIPTOR MdBlock
;
625 /* Validate Loader */
626 if (!ExpIsLoaderValid(LoaderBlock
))
628 /* Invalid loader version */
629 KeBugCheckEx(MISMATCHED_HAL
,
631 LoaderBlock
->Extension
->Size
,
632 LoaderBlock
->Extension
->MajorVersion
,
633 LoaderBlock
->Extension
->MinorVersion
);
636 /* Initialize PRCB pool lookaside pointers */
637 ExInitPoolLookasidePointers();
639 /* Check if this is an application CPU */
642 /* Then simply initialize it with HAL */
643 if (!HalInitSystem(ExpInitializationPhase
, LoaderBlock
))
645 /* Initialization failed */
646 KEBUGCHECK(HAL_INITIALIZATION_FAILED
);
653 /* Assume no text-mode or remote boot */
654 ExpInTextModeSetup
= FALSE
;
655 IoRemoteBootClient
= FALSE
;
657 /* Check if we have a setup loader block */
658 if (LoaderBlock
->SetupLdrBlock
)
660 /* Check if this is text-mode setup */
661 if (LoaderBlock
->SetupLdrBlock
->Flags
& 1) ExpInTextModeSetup
= TRUE
;
663 /* Check if this is network boot */
664 if (LoaderBlock
->SetupLdrBlock
->Flags
& 2)
667 IoRemoteBootClient
= TRUE
;
669 /* Make sure we're actually booting off the network */
670 ASSERT(!_memicmp(LoaderBlock
->ArcBootDeviceName
, "net(0)", 6));
675 ExpInitializationPhase
= 0;
677 /* Setup NLS Base and offsets */
678 NlsData
= LoaderBlock
->NlsData
;
679 ExpNlsTableBase
= NlsData
->AnsiCodePageData
;
680 ExpAnsiCodePageDataOffset
= 0;
681 ExpOemCodePageDataOffset
= ((ULONG_PTR
)NlsData
->OemCodePageData
-
682 (ULONG_PTR
)NlsData
->AnsiCodePageData
);
683 ExpUnicodeCaseTableDataOffset
= ((ULONG_PTR
)NlsData
->UnicodeCodePageData
-
684 (ULONG_PTR
)NlsData
->AnsiCodePageData
);
686 /* Initialize the NLS Tables */
687 RtlInitNlsTables((PVOID
)((ULONG_PTR
)ExpNlsTableBase
+
688 ExpAnsiCodePageDataOffset
),
689 (PVOID
)((ULONG_PTR
)ExpNlsTableBase
+
690 ExpOemCodePageDataOffset
),
691 (PVOID
)((ULONG_PTR
)ExpNlsTableBase
+
692 ExpUnicodeCaseTableDataOffset
),
694 RtlResetRtlTranslations(&ExpNlsTableInfo
);
696 /* Now initialize the HAL */
697 if (!HalInitSystem(ExpInitializationPhase
, LoaderBlock
))
699 /* HAL failed to initialize, bugcheck */
700 KeBugCheck(HAL_INITIALIZATION_FAILED
);
703 /* Make sure interrupts are active now */
706 /* Clear the crypto exponent */
707 SharedUserData
->CryptoExponent
= 0;
709 /* Set global flags for the checked build */
711 NtGlobalFlag
|= FLG_ENABLE_CLOSE_EXCEPTIONS
|
712 FLG_ENABLE_KDEBUG_SYMBOL_LOAD
;
715 /* Setup NT System Root Path */
716 sprintf(Buffer
, "C:%s", LoaderBlock
->NtBootPathName
);
718 /* Convert to ANSI_STRING and null-terminate it */
719 RtlInitString(&AnsiPath
, Buffer
);
720 Buffer
[--AnsiPath
.Length
] = UNICODE_NULL
;
722 /* Get the string from KUSER_SHARED_DATA's buffer */
723 NtSystemRoot
.Buffer
= SharedUserData
->NtSystemRoot
;
724 NtSystemRoot
.MaximumLength
= sizeof(SharedUserData
->NtSystemRoot
) / sizeof(WCHAR
);
725 NtSystemRoot
.Length
= 0;
728 Status
= RtlAnsiStringToUnicodeString(&NtSystemRoot
, &AnsiPath
, FALSE
);
729 if (!NT_SUCCESS(Status
)) KEBUGCHECK(SESSION3_INITIALIZATION_FAILED
);
731 /* Setup bugcheck messages */
732 KiInitializeBugCheck();
734 /* Setup system time */
735 KiInitializeSystemClock();
737 /* Initialize the executive at phase 0 */
738 if (!ExInitSystem()) KEBUGCHECK(PHASE0_INITIALIZATION_FAILED
);
740 /* Break into the Debugger if requested */
741 if (KdPollBreakIn()) DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C
);
743 /* Set system ranges */
744 SharedUserData
->Reserved1
= (ULONG_PTR
)MmHighestUserAddress
;
745 SharedUserData
->Reserved3
= (ULONG_PTR
)MmSystemRangeStart
;
747 /* Loop the memory descriptors */
748 ListHead
= &LoaderBlock
->MemoryDescriptorListHead
;
749 NextEntry
= ListHead
->Flink
;
750 while (NextEntry
!= ListHead
)
752 /* Get the current block */
753 MdBlock
= CONTAINING_RECORD(NextEntry
,
754 MEMORY_ALLOCATION_DESCRIPTOR
,
757 /* Check if this is an NLS block */
758 if (MdBlock
->MemoryType
== LoaderNlsData
)
760 /* Increase the table size */
761 ExpNlsTableSize
+= MdBlock
->PageCount
* PAGE_SIZE
;
764 /* Go to the next block */
765 NextEntry
= MdBlock
->ListEntry
.Flink
;
769 * In NT, the memory blocks are contiguous, but in ReactOS they are not,
770 * so unless someone fixes FreeLdr, we'll have to use this icky hack.
772 ExpNlsTableSize
+= 2 * PAGE_SIZE
; // BIAS FOR FREELDR. HACK!
774 /* Allocate the NLS buffer in the pool since loader memory will be freed */
775 ExpNlsTableBase
= ExAllocatePoolWithTag(NonPagedPool
,
777 TAG('R', 't', 'l', 'i'));
778 if (!ExpNlsTableBase
) KeBugCheck(PHASE0_INITIALIZATION_FAILED
);
780 /* Copy the codepage data in its new location. */
781 RtlMoveMemory(ExpNlsTableBase
,
782 LoaderBlock
->NlsData
->AnsiCodePageData
,
785 /* Initialize and reset the NLS TAbles */
786 RtlInitNlsTables((PVOID
)((ULONG_PTR
)ExpNlsTableBase
+
787 ExpAnsiCodePageDataOffset
),
788 (PVOID
)((ULONG_PTR
)ExpNlsTableBase
+
789 ExpOemCodePageDataOffset
),
790 (PVOID
)((ULONG_PTR
)ExpNlsTableBase
+
791 ExpUnicodeCaseTableDataOffset
),
793 RtlResetRtlTranslations(&ExpNlsTableInfo
);
795 /* Initialize the Handle Table */
796 ExpInitializeHandleTables();
799 /* On checked builds, allocate the system call count table */
800 KeServiceDescriptorTable
[0].Count
=
801 ExAllocatePoolWithTag(NonPagedPool
,
802 KiServiceLimit
* sizeof(ULONG
),
803 TAG('C', 'a', 'l', 'l'));
805 /* Use it for the shadow table too */
806 KeServiceDescriptorTableShadow
[0].Count
= KeServiceDescriptorTable
[0].Count
;
808 /* Make sure allocation succeeded */
809 if (KeServiceDescriptorTable
[0].Count
)
811 /* Zero the call counts to 0 */
812 RtlZeroMemory(KeServiceDescriptorTable
[0].Count
,
813 KiServiceLimit
* sizeof(ULONG
));
817 /* Create the Basic Object Manager Types to allow new Object Types */
818 if (!ObInit()) KEBUGCHECK(OBJECT_INITIALIZATION_FAILED
);
820 /* Load basic Security for other Managers */
821 if (!SeInit()) KEBUGCHECK(SECURITY_INITIALIZATION_FAILED
);
823 /* Set up Region Maps, Sections and the Paging File */
826 /* Call OB initialization again */
827 if (!ObInit()) KEBUGCHECK(OBJECT_INITIALIZATION_FAILED
);
829 /* Initialize the Process Manager */
830 if (!PsInitSystem()) KEBUGCHECK(PROCESS_INITIALIZATION_FAILED
);
832 /* Calculate the tick count multiplier */
833 ExpTickCountMultiplier
= ExComputeTickCountMultiplier(KeMaximumIncrement
);
834 SharedUserData
->TickCountMultiplier
= ExpTickCountMultiplier
;
836 /* Set the OS Version */
837 SharedUserData
->NtMajorVersion
= NtMajorVersion
;
838 SharedUserData
->NtMinorVersion
= NtMinorVersion
;
840 /* Set the machine type */
842 SharedUserData
->ImageNumberLow
= IMAGE_FILE_MACHINE_I386
;
843 SharedUserData
->ImageNumberHigh
= IMAGE_FILE_MACHINE_I386
;
844 #elif defined(_PPC_) // <3 Arty
845 SharedUserData
->ImageNumberLow
= IMAGE_FILE_MACHINE_POWERPC
;
846 SharedUserData
->ImageNumberHigh
= IMAGE_FILE_MACHINE_POWERPC
;
848 #error "Unsupported ReactOS Target"
854 ExPhase2Init(PVOID Context
)
856 LARGE_INTEGER Timeout
;
857 HANDLE ProcessHandle
;
862 ExpInitializationPhase
= 1;
864 /* Set us at maximum priority */
865 KeSetPriorityThread(KeGetCurrentThread(), HIGH_PRIORITY
);
867 /* Initialize the later stages of the kernel */
870 /* Initialize all processors */
871 HalAllProcessorsStarted();
873 /* Do Phase 1 HAL Initialization */
874 HalInitSystem(1, KeLoaderBlock
);
876 /* Initialize Basic System Objects and Worker Threads */
879 /* Call KD Providers at Phase 1 */
880 KdInitSystem(1, KeLoaderBlock
);
882 /* Initialize I/O Objects, Filesystems, Error Logging and Shutdown */
886 PoInit(AcpiTableDetected
, KeLoaderBlock
);
888 /* Initialize the Registry (Hives are NOT yet loaded!) */
889 CmInitializeRegistry();
891 /* Unmap Low memory, initialize the Page Zeroing and the Balancer Thread */
894 /* Initialize Cache Views */
897 /* Initialize File Locking */
898 FsRtlpInitFileLockingImplementation();
900 /* Report all resources used by hal */
901 HalReportResourceUsage();
903 /* Clear the screen to blue */
904 HalInitSystem(2, KeLoaderBlock
);
906 /* Check if GUI Boot is enabled */
907 if (strstr(KeLoaderBlock
->LoadOptions
, "NOGUIBOOT")) NoGuiBoot
= TRUE
;
909 /* Display version number and copyright/warranty message */
910 if (NoGuiBoot
) ExpDisplayNotice();
912 /* Call KD Providers at Phase 2 */
913 KdInitSystem(2, KeLoaderBlock
);
915 /* Create NLS section */
921 /* Import and Load Registry Hives */
922 CmInitHives(ExpInTextModeSetup
);
924 /* Initialize VDM support */
925 KeI386VdmInitialize();
927 /* Initialize the time zone information from the registry */
928 ExpInitTimeZoneInfo();
930 /* Enter the kernel debugger before starting up the boot drivers */
931 if (KdDebuggerEnabled
&& KdpEarlyBreak
)
934 /* Setup Drivers and Root Device Node */
937 /* Display the boot screen image if not disabled */
938 if (!NoGuiBoot
) InbvEnableBootDriver(TRUE
);
940 /* Create ARC Names, SystemRoot SymLink, Load Drivers and Assign Letters */
943 /* Load the System DLL and its Entrypoints */
946 /* Initialize shared user page. Set dos system path, dos device map, etc. */
947 InitSystemSharedUserPage(KeLoaderBlock
);
949 /* Launch initial process */
950 Status
= ExpLoadInitialProcess(&ProcessHandle
,
953 /* Wait 5 seconds for it to initialize */
954 Timeout
.QuadPart
= Int32x32To64(5, -10000000);
955 Status
= ZwWaitForSingleObject(ProcessHandle
, FALSE
, &Timeout
);
956 if (Status
== STATUS_SUCCESS
)
958 /* Bugcheck the system if SMSS couldn't initialize */
959 KeBugCheck(SESSION5_INITIALIZATION_FAILED
);
963 /* Close process handles */
964 ZwClose(ThreadHandle
);
965 ZwClose(ProcessHandle
);
969 * Disable the Boot Logo
971 if (!NoGuiBoot
) InbvEnableBootDriver(FALSE
);
973 /* FIXME: We should free the initial process' memory!*/
975 /* Increase init phase */
976 ExpInitializationPhase
+= 1;
978 /* Jump into zero page thread */
979 MmZeroPageThreadMain(NULL
);