/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
+ * PROJECT: ReactOS Kernel
+ * LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/ex/init.c
- * PURPOSE: Executive initalization
- *
- * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) - Added ExpInitializeExecutive
- * and optimized/cleaned it.
- * Eric Kohl (ekohl@abo.rhein-zeitung.de)
+ * PURPOSE: Executive Initialization Code
+ * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
+ * Eric Kohl (ekohl@rz-online.de)
*/
+/* INCLUDES ******************************************************************/
+
#include <ntoskrnl.h>
#define NDEBUG
#include <internal/debug.h>
/* DATA **********************************************************************/
+/* HACK */
+extern BOOLEAN KiClockSetupComplete;
+
#define BUILD_OSCSDVERSION(major, minor) (((major & 0xFF) << 8) | (minor & 0xFF))
/* NT Version Info */
ULONG NtGlobalFlag;
ULONG ExSuiteMask;
-extern LOADER_MODULE KeLoaderModules[64];
-extern ULONG KeLoaderModuleCount;
-extern ULONG KiServiceLimit;
-BOOLEAN NoGuiBoot = FALSE;
-
/* Init flags and settings */
ULONG ExpInitializationPhase;
BOOLEAN ExpInTextModeSetup;
BOOLEAN IoRemoteBootClient;
ULONG InitSafeBootMode;
+BOOLEAN NoGuiBoot = FALSE;
+
/* NT Boot Path */
UNICODE_STRING NtSystemRoot;
ULONG ExpUnicodeCaseTableDataOffset;
NLSTABLEINFO ExpNlsTableInfo;
ULONG ExpNlsTableSize;
+PVOID ExpNlsSectionPointer;
/* FUNCTIONS ****************************************************************/
-static
-VOID
-INIT_FUNCTION
-InitSystemSharedUserPage (IN PLOADER_PARAMETER_BLOCK LoaderBlock)
+NTSTATUS
+NTAPI
+ExpCreateSystemRootLink(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
- UNICODE_STRING ArcDeviceName;
- UNICODE_STRING ArcName;
- UNICODE_STRING BootPath;
- UNICODE_STRING DriveDeviceName;
- UNICODE_STRING DriveName;
- WCHAR DriveNameBuffer[20];
- PWCHAR ArcNameBuffer;
- NTSTATUS Status;
- ULONG Length;
+ UNICODE_STRING LinkName;
OBJECT_ATTRIBUTES ObjectAttributes;
- HANDLE Handle;
- ULONG i;
- BOOLEAN BootDriveFound = FALSE;
+ HANDLE LinkHandle;
+ NTSTATUS Status;
+ ANSI_STRING AnsiName;
+ CHAR Buffer[256];
+ ANSI_STRING TargetString;
+ UNICODE_STRING TargetName;
- /* Set the Product Type */
- SharedUserData->NtProductType = NtProductWinNt;
- SharedUserData->ProductTypeIsValid = TRUE;
+ /* Initialize the ArcName tree */
+ RtlInitUnicodeString(&LinkName, L"\\ArcName");
+ InitializeObjectAttributes(&ObjectAttributes,
+ &LinkName,
+ OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
+ NULL,
+ SePublicDefaultSd);
- /*
- * Retrieve the current dos system path
- * (e.g.: C:\reactos) from the given arc path
- * (e.g.: multi(0)disk(0)rdisk(0)partititon(1)\reactos)
- * Format: "<arc_name>\<path> [options...]"
- */
+ /* Create it */
+ Status = NtCreateDirectoryObject(&LinkHandle,
+ DIRECTORY_ALL_ACCESS,
+ &ObjectAttributes);
+ if (!NT_SUCCESS(Status))
+ {
+ KeBugCheckEx(SYMBOLIC_INITIALIZATION_FAILED, Status, 1, 0, 0);
+ }
- RtlCreateUnicodeStringFromAsciiz(&BootPath, LoaderBlock->NtBootPathName);
+ /* Close the LinkHandle */
+ NtClose(LinkHandle);
+
+ /* Initialize the Device tree */
+ RtlInitUnicodeString(&LinkName, L"\\Device");
+ InitializeObjectAttributes(&ObjectAttributes,
+ &LinkName,
+ OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
+ NULL,
+ SePublicDefaultSd);
- /* Remove the trailing backslash */
- BootPath.Length -= sizeof(WCHAR);
- BootPath.MaximumLength -= sizeof(WCHAR);
+ /* Create it */
+ Status = NtCreateDirectoryObject(&LinkHandle,
+ DIRECTORY_ALL_ACCESS,
+ &ObjectAttributes);
+ if (!NT_SUCCESS(Status))
+ {
+ KeBugCheckEx(SYMBOLIC_INITIALIZATION_FAILED, Status, 2, 0, 0);
+ }
- /* Only ARC Name left - Build full ARC Name */
- ArcNameBuffer = ExAllocatePool (PagedPool, 256 * sizeof(WCHAR));
- swprintf (ArcNameBuffer, L"\\ArcName\\%S", LoaderBlock->ArcBootDeviceName);
- RtlInitUnicodeString (&ArcName, ArcNameBuffer);
+ /* Close the LinkHandle */
+ ObCloseHandle(LinkHandle, KernelMode);
- /* Allocate ARC Device Name string */
- ArcDeviceName.Length = 0;
- ArcDeviceName.MaximumLength = 256 * sizeof(WCHAR);
- ArcDeviceName.Buffer = ExAllocatePool (PagedPool, 256 * sizeof(WCHAR));
+ /* Create the system root symlink name */
+ RtlInitAnsiString(&AnsiName, "\\SystemRoot");
+ Status = RtlAnsiStringToUnicodeString(&LinkName, &AnsiName, TRUE);
+ if (!NT_SUCCESS(Status))
+ {
+ KeBugCheckEx(SYMBOLIC_INITIALIZATION_FAILED, Status, 3, 0, 0);
+ }
- /* Open the Symbolic Link */
+ /* Initialize the attributes for the link */
InitializeObjectAttributes(&ObjectAttributes,
- &ArcName,
- OBJ_OPENLINK,
+ &LinkName,
+ OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
NULL,
- NULL);
- Status = NtOpenSymbolicLinkObject(&Handle,
- SYMBOLIC_LINK_ALL_ACCESS,
- &ObjectAttributes);
-
- /* Free the String */
- ExFreePool(ArcName.Buffer);
-
- /* Check for Success */
- if (!NT_SUCCESS(Status)) {
-
- /* Free the Strings */
- RtlFreeUnicodeString(&BootPath);
- ExFreePool(ArcDeviceName.Buffer);
- CPRINT("NtOpenSymbolicLinkObject() failed (Status %x)\n", Status);
- KEBUGCHECK(0);
+ SePublicDefaultSd);
+
+ /* Build the ARC name */
+ sprintf(Buffer,
+ "\\ArcName\\%s%s",
+ LoaderBlock->ArcBootDeviceName,
+ LoaderBlock->NtBootPathName);
+ Buffer[strlen(Buffer) - 1] = ANSI_NULL;
+
+ /* Convert it to Unicode */
+ RtlInitString(&TargetString, Buffer);
+ Status = RtlAnsiStringToUnicodeString(&TargetName,
+ &TargetString,
+ TRUE);
+ if (!NT_SUCCESS(Status))
+ {
+ /* We failed, bugcheck */
+ KeBugCheckEx(SYMBOLIC_INITIALIZATION_FAILED, Status, 4, 0, 0);
}
- /* Query the Link */
- Status = NtQuerySymbolicLinkObject(Handle,
- &ArcDeviceName,
- &Length);
- NtClose (Handle);
+ /* Create it */
+ Status = NtCreateSymbolicLinkObject(&LinkHandle,
+ SYMBOLIC_LINK_ALL_ACCESS,
+ &ObjectAttributes,
+ &TargetName);
- /* Check for Success */
- if (!NT_SUCCESS(Status)) {
+ /* Free the strings */
+ RtlFreeUnicodeString(&LinkName);
+ RtlFreeUnicodeString(&TargetName);
- /* Free the Strings */
- RtlFreeUnicodeString(&BootPath);
- ExFreePool(ArcDeviceName.Buffer);
- CPRINT("NtQuerySymbolicLinkObject() failed (Status %x)\n", Status);
- KEBUGCHECK(0);
+ /* Check if creating the link failed */
+ if (!NT_SUCCESS(Status))
+ {
+ KeBugCheckEx(SYMBOLIC_INITIALIZATION_FAILED, Status, 5, 0, 0);
}
- /* Allocate Device Name string */
- DriveDeviceName.Length = 0;
- DriveDeviceName.MaximumLength = 256 * sizeof(WCHAR);
- DriveDeviceName.Buffer = ExAllocatePool (PagedPool, 256 * sizeof(WCHAR));
-
- /* Loop Drives */
- for (i = 0; i < 26; i++) {
-
- /* Setup the String */
- swprintf (DriveNameBuffer, L"\\??\\%C:", 'A' + i);
- RtlInitUnicodeString(&DriveName,
- DriveNameBuffer);
-
- /* Open the Symbolic Link */
- InitializeObjectAttributes(&ObjectAttributes,
- &DriveName,
- OBJ_OPENLINK,
- NULL,
- NULL);
- Status = NtOpenSymbolicLinkObject(&Handle,
- SYMBOLIC_LINK_ALL_ACCESS,
- &ObjectAttributes);
-
- /* If it failed, skip to the next drive */
- if (!NT_SUCCESS(Status)) {
- DPRINT("Failed to open link %wZ\n", &DriveName);
- continue;
- }
+ /* Close the handle and return success */
+ ObCloseHandle(LinkHandle, KernelMode);
+ return STATUS_SUCCESS;
+}
- /* Query it */
- Status = NtQuerySymbolicLinkObject(Handle,
- &DriveDeviceName,
- &Length);
+VOID
+NTAPI
+ExpInitNls(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
+{
+ LARGE_INTEGER SectionSize;
+ NTSTATUS Status;
+ HANDLE NlsSection;
+ PVOID SectionBase = NULL;
+ ULONG ViewSize = 0;
+ LARGE_INTEGER SectionOffset = {{0}};
+ PLIST_ENTRY ListHead, NextEntry;
+ PMEMORY_ALLOCATION_DESCRIPTOR MdBlock;
- /* If it failed, skip to the next drive */
- if (!NT_SUCCESS(Status)) {
- DPRINT("Failed to query link %wZ\n", &DriveName);
- continue;
+ /* Check if this is boot-time phase 0 initialization */
+ if (!ExpInitializationPhase)
+ {
+ /* Loop the memory descriptors */
+ ListHead = &LoaderBlock->MemoryDescriptorListHead;
+ NextEntry = ListHead->Flink;
+ while (NextEntry != ListHead)
+ {
+ /* Get the current block */
+ MdBlock = CONTAINING_RECORD(NextEntry,
+ MEMORY_ALLOCATION_DESCRIPTOR,
+ ListEntry);
+
+ /* Check if this is an NLS block */
+ if (MdBlock->MemoryType == LoaderNlsData)
+ {
+ /* Increase the table size */
+ ExpNlsTableSize += MdBlock->PageCount * PAGE_SIZE;
+ }
+
+ /* Go to the next block */
+ NextEntry = MdBlock->ListEntry.Flink;
}
- DPRINT("Opened link: %wZ ==> %wZ\n", &DriveName, &DriveDeviceName);
- /* See if we've found the boot drive */
- if (!RtlCompareUnicodeString (&ArcDeviceName, &DriveDeviceName, FALSE)) {
+ /*
+ * In NT, the memory blocks are contiguous, but in ReactOS they aren't,
+ * so unless someone fixes FreeLdr, we'll have to use this icky hack.
+ */
+ ExpNlsTableSize += 2 * PAGE_SIZE; // BIAS FOR FREELDR. HACK!
+
+ /* Allocate the a new buffer since loader memory will be freed */
+ ExpNlsTableBase = ExAllocatePoolWithTag(NonPagedPool,
+ ExpNlsTableSize,
+ TAG('R', 't', 'l', 'i'));
+ if (!ExpNlsTableBase) KeBugCheck(PHASE0_INITIALIZATION_FAILED);
+
+ /* Copy the codepage data in its new location. */
+ RtlCopyMemory(ExpNlsTableBase,
+ LoaderBlock->NlsData->AnsiCodePageData,
+ ExpNlsTableSize);
+
+ /* Initialize and reset the NLS TAbles */
+ RtlInitNlsTables((PVOID)((ULONG_PTR)ExpNlsTableBase +
+ ExpAnsiCodePageDataOffset),
+ (PVOID)((ULONG_PTR)ExpNlsTableBase +
+ ExpOemCodePageDataOffset),
+ (PVOID)((ULONG_PTR)ExpNlsTableBase +
+ ExpUnicodeCaseTableDataOffset),
+ &ExpNlsTableInfo);
+ RtlResetRtlTranslations(&ExpNlsTableInfo);
+ return;
+ }
- DPRINT("DOS Boot path: %c:%wZ\n", 'A' + i, &BootPath);
- swprintf(SharedUserData->NtSystemRoot, L"%C:%wZ", 'A' + i, &BootPath);
- BootDriveFound = TRUE;
- }
+ /* Set the section size */
+ SectionSize.QuadPart = ExpNlsTableSize;
+
+ /* Create the NLS Section */
+ Status = ZwCreateSection(&NlsSection,
+ SECTION_ALL_ACCESS,
+ NULL,
+ &SectionSize,
+ PAGE_READWRITE,
+ SEC_COMMIT,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ /* Failed */
+ KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 1, 0, 0);
+ }
- /* Close this Link */
- NtClose (Handle);
+ /* Get a pointer to the section */
+ Status = ObReferenceObjectByHandle(NlsSection,
+ SECTION_ALL_ACCESS,
+ MmSectionObjectType,
+ KernelMode,
+ &ExpNlsSectionPointer,
+ NULL);
+ ZwClose(NlsSection);
+ if (!NT_SUCCESS(Status))
+ {
+ /* Failed */
+ KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 2, 0, 0);
}
- /* Free all the Strings we have in memory */
- RtlFreeUnicodeString (&BootPath);
- ExFreePool(DriveDeviceName.Buffer);
- ExFreePool(ArcDeviceName.Buffer);
+ /* Map the NLS Section in system space */
+ Status = MmMapViewInSystemSpace(ExpNlsSectionPointer,
+ &SectionBase,
+ &ExpNlsTableSize);
+ if (!NT_SUCCESS(Status))
+ {
+ /* Failed */
+ KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 3, 0, 0);
+ }
- /* Make sure we found the Boot Drive */
- if (BootDriveFound == FALSE) {
+ /* Copy the codepage data in its new location. */
+ RtlCopyMemory(SectionBase, ExpNlsTableBase, ExpNlsTableSize);
- DbgPrint("No system drive found!\n");
- KEBUGCHECK (NO_BOOT_DEVICE);
- }
-}
+ /* Free the previously allocated buffer and set the new location */
+ ExFreePool(ExpNlsTableBase);
+ ExpNlsTableBase = SectionBase;
-VOID
-FORCEINLINE
-ParseAndCacheLoadedModules(VOID)
-{
- ULONG i;
- PCHAR Name;
+ /* Initialize the NLS Tables */
+ RtlInitNlsTables((PVOID)((ULONG_PTR)ExpNlsTableBase +
+ ExpAnsiCodePageDataOffset),
+ (PVOID)((ULONG_PTR)ExpNlsTableBase +
+ ExpOemCodePageDataOffset),
+ (PVOID)((ULONG_PTR)ExpNlsTableBase +
+ ExpUnicodeCaseTableDataOffset),
+ &ExpNlsTableInfo);
+ RtlResetRtlTranslations(&ExpNlsTableInfo);
- /* Loop the Module List and get the modules we want */
- for (i = 1; i < KeLoaderModuleCount; i++)
+ /* Reset the base to 0 */
+ SectionBase = NULL;
+
+ /* Map the section in the system process */
+ Status = MmMapViewOfSection(ExpNlsSectionPointer,
+ PsGetCurrentProcess(),
+ &SectionBase,
+ 0L,
+ 0L,
+ &SectionOffset,
+ &ViewSize,
+ ViewShare,
+ 0L,
+ PAGE_READWRITE);
+ if (!NT_SUCCESS(Status))
{
- /* Get the Name of this Module */
- if (!(Name = strrchr((PCHAR)KeLoaderModules[i].String, '\\')))
- {
- /* Save the name */
- Name = (PCHAR)KeLoaderModules[i].String;
- }
- else
- {
- /* No name, skip */
- Name++;
- }
-
- /* Now check for any of the modules we will need later */
- if (!_stricmp(Name, "ansi.nls"))
- {
- CachedModules[AnsiCodepage] = &KeLoaderModules[i];
- }
- else if (!_stricmp(Name, "oem.nls"))
- {
- CachedModules[OemCodepage] = &KeLoaderModules[i];
- }
- else if (!_stricmp(Name, "casemap.nls"))
- {
- CachedModules[UnicodeCasemap] = &KeLoaderModules[i];
- }
- else if (!_stricmp(Name, "system") || !_stricmp(Name, "system.hiv"))
- {
- CachedModules[SystemRegistry] = &KeLoaderModules[i];
- }
- else if (!_stricmp(Name, "hardware") || !_stricmp(Name, "hardware.hiv"))
- {
- CachedModules[HardwareRegistry] = &KeLoaderModules[i];
- }
+ /* Failed */
+ KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 5, 0, 0);
}
+
+ /* Copy the table into the system process and set this as the base */
+ RtlCopyMemory(SectionBase, ExpNlsTableBase, ExpNlsTableSize);
+ ExpNlsTableBase = SectionBase;
}
VOID
}
-INIT_FUNCTION
NTSTATUS
-ExpLoadInitialProcess(PHANDLE ProcessHandle,
- PHANDLE ThreadHandle)
+NTAPI
+ExpLoadInitialProcess(IN PHANDLE ProcessHandle,
+ IN PHANDLE ThreadHandle)
{
- UNICODE_STRING CurrentDirectory;
- UNICODE_STRING ImagePath = RTL_CONSTANT_STRING(L"\\SystemRoot\\system32\\smss.exe");
+ PRTL_USER_PROCESS_PARAMETERS ProcessParameters = NULL;
NTSTATUS Status;
- PRTL_USER_PROCESS_PARAMETERS Params=NULL;
- RTL_USER_PROCESS_INFORMATION Info;
-
- RtlInitUnicodeString(&CurrentDirectory,
- SharedUserData->NtSystemRoot);
-
- /* Create the Parameters */
- Status = RtlCreateProcessParameters(&Params,
- &ImagePath,
- NULL,
- &CurrentDirectory,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL);
- if(!NT_SUCCESS(Status))
+ ULONG Size;
+ RTL_USER_PROCESS_INFORMATION ProcessInformation;
+ PWSTR p;
+ UNICODE_STRING NullString = RTL_CONSTANT_STRING(L"");
+ UNICODE_STRING SmssName, Environment, SystemDriveString;
+
+ /* Allocate memory for the process parameters */
+ Size = sizeof(RTL_USER_PROCESS_PARAMETERS) +
+ ((MAX_PATH * 4) * sizeof(WCHAR));
+ Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
+ (PVOID)&ProcessParameters,
+ 0,
+ &Size,
+ MEM_COMMIT,
+ PAGE_READWRITE);
+ if (!NT_SUCCESS(Status))
+ {
+ /* Failed */
+ KeBugCheckEx(SESSION1_INITIALIZATION_FAILED, Status, 0, 0, 0);
+ }
+
+ /* Setup the basic header, and give the process the low 1MB to itself */
+ ProcessParameters->Length = Size;
+ ProcessParameters->MaximumLength = Size;
+ ProcessParameters->Flags = RTL_USER_PROCESS_PARAMETERS_NORMALIZED |
+ RTL_USER_PROCESS_PARAMETERS_RESERVE_1MB;
+
+ /* Allocate a page for the environment */
+ Size = PAGE_SIZE;
+ Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
+ (PVOID)&ProcessParameters->Environment,
+ 0,
+ &Size,
+ MEM_COMMIT,
+ PAGE_READWRITE);
+ if (!NT_SUCCESS(Status))
{
- DPRINT1("Failed to create ppb!\n");
- return Status;
+ /* Failed */
+ KeBugCheckEx(SESSION2_INITIALIZATION_FAILED, Status, 0, 0, 0);
}
- DPRINT("Creating process\n");
- Status = RtlCreateUserProcess(&ImagePath,
+ /* Make a buffer for the DOS path */
+ p = (PWSTR)(ProcessParameters + 1);
+ ProcessParameters->CurrentDirectory.DosPath.Buffer = p;
+ ProcessParameters->
+ CurrentDirectory.DosPath.MaximumLength = MAX_PATH * sizeof(WCHAR);
+
+ /* Copy the DOS path */
+ RtlCopyUnicodeString(&ProcessParameters->CurrentDirectory.DosPath,
+ &NtSystemRoot);
+
+ /* Make a buffer for the DLL Path */
+ p = (PWSTR)((PCHAR)ProcessParameters->CurrentDirectory.DosPath.Buffer +
+ ProcessParameters->CurrentDirectory.DosPath.MaximumLength);
+ ProcessParameters->DllPath.Buffer = p;
+ ProcessParameters->DllPath.MaximumLength = MAX_PATH * sizeof(WCHAR);
+
+ /* Copy the DLL path and append the system32 directory */
+ RtlCopyUnicodeString(&ProcessParameters->DllPath,
+ &ProcessParameters->CurrentDirectory.DosPath);
+ RtlAppendUnicodeToString(&ProcessParameters->DllPath, L"\\System32");
+
+ /* Make a buffer for the image name */
+ p = (PWSTR)((PCHAR)ProcessParameters->DllPath.Buffer +
+ ProcessParameters->DllPath.MaximumLength);
+ ProcessParameters->ImagePathName.Buffer = p;
+ ProcessParameters->ImagePathName.MaximumLength = MAX_PATH * sizeof(WCHAR);
+
+ /* Append the system path and session manager name */
+ RtlAppendUnicodeToString(&ProcessParameters->ImagePathName,
+ L"\\SystemRoot\\System32");
+ RtlAppendUnicodeToString(&ProcessParameters->ImagePathName,
+ L"\\smss.exe");
+
+ /* Create the environment string */
+ RtlInitEmptyUnicodeString(&Environment,
+ ProcessParameters->Environment,
+ (USHORT)Size);
+
+ /* Append the DLL path to it */
+ RtlAppendUnicodeToString(&Environment, L"Path=" );
+ RtlAppendUnicodeStringToString(&Environment, &ProcessParameters->DllPath);
+ RtlAppendUnicodeStringToString(&Environment, &NullString );
+
+ /* Create the system drive string */
+ SystemDriveString = NtSystemRoot;
+ SystemDriveString.Length = 2 * sizeof(WCHAR);
+
+ /* Append it to the environment */
+ RtlAppendUnicodeToString(&Environment, L"SystemDrive=");
+ RtlAppendUnicodeStringToString(&Environment, &SystemDriveString);
+ RtlAppendUnicodeStringToString(&Environment, &NullString);
+
+ /* Append the system root to the environment */
+ RtlAppendUnicodeToString(&Environment, L"SystemRoot=");
+ RtlAppendUnicodeStringToString(&Environment, &NtSystemRoot);
+ RtlAppendUnicodeStringToString(&Environment, &NullString);
+
+ /* Get and set the command line equal to the image path */
+ ProcessParameters->CommandLine = ProcessParameters->ImagePathName;
+ SmssName = ProcessParameters->ImagePathName;
+
+ /* Create SMSS process */
+ Status = RtlCreateUserProcess(&SmssName,
OBJ_CASE_INSENSITIVE,
- Params,
+ RtlDeNormalizeProcessParams(
+ ProcessParameters),
NULL,
NULL,
NULL,
FALSE,
NULL,
NULL,
- &Info);
-
- /* Close the handle and free the params */
- RtlDestroyProcessParameters(Params);
-
+ &ProcessInformation);
if (!NT_SUCCESS(Status))
{
- DPRINT1("NtCreateProcess() failed (Status %lx)\n", Status);
- return(Status);
+ /* Failed */
+ KeBugCheckEx(SESSION3_INITIALIZATION_FAILED, Status, 0, 0, 0);
}
- /* Start it up */
- ZwResumeThread(Info.ThreadHandle, NULL);
+ /* Resume the thread */
+ Status = ZwResumeThread(ProcessInformation.ThreadHandle, NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ /* Failed */
+ KeBugCheckEx(SESSION4_INITIALIZATION_FAILED, Status, 0, 0, 0);
+ }
/* Return Handles */
- *ProcessHandle = Info.ProcessHandle;
- *ThreadHandle = Info.ThreadHandle;
- DPRINT("Process created successfully\n");
+ *ProcessHandle = ProcessInformation.ProcessHandle;
+ *ThreadHandle = ProcessInformation.ThreadHandle;
return STATUS_SUCCESS;
}
-VOID
-NTAPI
-ExInit3(VOID)
-{
- ExpInitializeEventImplementation();
- ExpInitializeEventPairImplementation();
- ExpInitializeMutantImplementation();
- ExpInitializeSemaphoreImplementation();
- ExpInitializeTimerImplementation();
- LpcpInitSystem();
- ExpInitializeProfileImplementation();
- ExpWin32kInit();
- ExpInitUuids();
-}
-
ULONG
NTAPI
ExComputeTickCountMultiplier(IN ULONG ClockIncrement)
NTAPI
ExpInitSystemPhase1(VOID)
{
- /* Not yet done */
- return FALSE;
+ /* Initialize worker threads */
+ ExpInitializeWorkerThreads();
+
+ /* Initialize pushlocks */
+ ExpInitializePushLocks();
+
+ /* Initialize events and event pairs */
+ ExpInitializeEventImplementation();
+ ExpInitializeEventPairImplementation();
+
+ /* Initialize callbacks */
+ ExpInitializeCallbacks();
+
+ /* Initialize mutants */
+ ExpInitializeMutantImplementation();
+
+ /* Initialize semaphores */
+ ExpInitializeSemaphoreImplementation();
+
+ /* Initialize timers */
+ ExpInitializeTimerImplementation();
+
+ /* Initialize profiling */
+ ExpInitializeProfileImplementation();
+
+ /* Initialize UUIDs */
+ ExpInitUuids();
+
+ /* Initialize Win32K */
+ ExpWin32kInit();
+ return TRUE;
}
BOOLEAN
/* Fail if this is XP */
if (Extension->MinorVersion < 2) return FALSE;
- /* This is 2003 or newer, aprove it */
+ /* This is 2003 or newer, approve it */
return TRUE;
}
CHAR Buffer[256];
ANSI_STRING AnsiPath;
NTSTATUS Status;
- PLIST_ENTRY NextEntry, ListHead;
- PMEMORY_ALLOCATION_DESCRIPTOR MdBlock;
-
- /* FIXME: Deprecate soon */
- ParseAndCacheLoadedModules();
/* Validate Loader */
if (!ExpIsLoaderValid(LoaderBlock))
if (!HalInitSystem(ExpInitializationPhase, LoaderBlock))
{
/* Initialization failed */
- KEBUGCHECK(HAL_INITIALIZATION_FAILED);
+ KeBugCheck(HAL_INITIALIZATION_FAILED);
}
/* We're done */
/* Convert to ANSI_STRING and null-terminate it */
RtlInitString(&AnsiPath, Buffer );
- Buffer[--AnsiPath.Length] = UNICODE_NULL;
+ Buffer[--AnsiPath.Length] = ANSI_NULL;
/* Get the string from KUSER_SHARED_DATA's buffer */
NtSystemRoot.Buffer = SharedUserData->NtSystemRoot;
/* Setup bugcheck messages */
KiInitializeBugCheck();
- /* Setup system time */
- KiInitializeSystemClock();
-
/* Initialize the executive at phase 0 */
if (!ExInitSystem()) KEBUGCHECK(PHASE0_INITIALIZATION_FAILED);
SharedUserData->Reserved1 = (ULONG_PTR)MmHighestUserAddress;
SharedUserData->Reserved3 = (ULONG_PTR)MmSystemRangeStart;
- /* Loop the memory descriptors */
- ListHead = &LoaderBlock->MemoryDescriptorListHead;
- NextEntry = ListHead->Flink;
- while (NextEntry != ListHead)
- {
- /* Get the current block */
- MdBlock = CONTAINING_RECORD(NextEntry,
- MEMORY_ALLOCATION_DESCRIPTOR,
- ListEntry);
-
- /* Check if this is an NLS block */
- if (MdBlock->MemoryType == LoaderNlsData)
- {
- /* Increase the table size */
- ExpNlsTableSize += MdBlock->PageCount * PAGE_SIZE;
- }
-
- /* Go to the next block */
- NextEntry = MdBlock->ListEntry.Flink;
- }
-
- /*
- * In NT, the memory blocks are contiguous, but in ReactOS they are not,
- * so unless someone fixes FreeLdr, we'll have to use this icky hack.
- */
- ExpNlsTableSize += 2 * PAGE_SIZE; // BIAS FOR FREELDR. HACK!
-
- /* Allocate the NLS buffer in the pool since loader memory will be freed */
- ExpNlsTableBase = ExAllocatePoolWithTag(NonPagedPool,
- ExpNlsTableSize,
- TAG('R', 't', 'l', 'i'));
- if (!ExpNlsTableBase) KeBugCheck(PHASE0_INITIALIZATION_FAILED);
-
- /* Copy the codepage data in its new location. */
- RtlMoveMemory(ExpNlsTableBase,
- LoaderBlock->NlsData->AnsiCodePageData,
- ExpNlsTableSize);
-
- /* Initialize and reset the NLS TAbles */
- RtlInitNlsTables((PVOID)((ULONG_PTR)ExpNlsTableBase +
- ExpAnsiCodePageDataOffset),
- (PVOID)((ULONG_PTR)ExpNlsTableBase +
- ExpOemCodePageDataOffset),
- (PVOID)((ULONG_PTR)ExpNlsTableBase +
- ExpUnicodeCaseTableDataOffset),
- &ExpNlsTableInfo);
- RtlResetRtlTranslations(&ExpNlsTableInfo);
+ /* Make a copy of the NLS Tables */
+ ExpInitNls(LoaderBlock);
/* Initialize the Handle Table */
ExpInitializeHandleTables();
/* Set up Region Maps, Sections and the Paging File */
MmInit2();
- /* Call OB initialization again */
- if (!ObInit()) KEBUGCHECK(OBJECT_INITIALIZATION_FAILED);
+ /* Initialize the boot video. */
+ InbvDisplayInitialize();
/* Initialize the Process Manager */
if (!PsInitSystem()) KEBUGCHECK(PROCESS_INITIALIZATION_FAILED);
+ /* Initialize the User-Mode Debugging Subsystem */
+ DbgkInitialize();
+
/* Calculate the tick count multiplier */
ExpTickCountMultiplier = ExComputeTickCountMultiplier(KeMaximumIncrement);
SharedUserData->TickCountMultiplier = ExpTickCountMultiplier;
NTAPI
ExPhase2Init(PVOID Context)
{
- UNICODE_STRING EventName;
- HANDLE InitDoneEventHandle;
- OBJECT_ATTRIBUTES ObjectAttributes;
LARGE_INTEGER Timeout;
HANDLE ProcessHandle;
HANDLE ThreadHandle;
NTSTATUS Status;
+ TIME_FIELDS TimeFields;
+ LARGE_INTEGER SystemBootTime, UniversalBootTime;
+
+ /* Set to phase 1 */
+ ExpInitializationPhase = 1;
/* Set us at maximum priority */
KeSetPriorityThread(KeGetCurrentThread(), HIGH_PRIORITY);
- /* Initialize the later stages of the kernel */
- KeInitSystem();
-
- /* Initialize all processors */
- HalAllProcessorsStarted();
-
/* Do Phase 1 HAL Initialization */
HalInitSystem(1, KeLoaderBlock);
- /* Initialize Basic System Objects and Worker Threads */
- ExInit3();
-
- /* initialize the worker threads */
- ExpInitializeWorkerThreads();
-
- /* initialize callbacks */
- ExpInitializeCallbacks();
-
- /* Call KD Providers at Phase 1 */
- KdInitSystem(1, KeLoaderBlock);
-
- /* Initialize I/O Objects, Filesystems, Error Logging and Shutdown */
- IoInit();
-
- /* TBD */
- PoInit(AcpiTableDetected, KeLoaderBlock);
-
- /* Initialize the Registry (Hives are NOT yet loaded!) */
- CmInitializeRegistry();
-
- /* Unmap Low memory, initialize the Page Zeroing and the Balancer Thread */
- MmInit3();
-
- /* Initialize Cache Views */
- CcInit();
-
- /* Initialize File Locking */
- FsRtlpInitFileLockingImplementation();
-
- /* Report all resources used by hal */
- HalReportResourceUsage();
-
- /* Clear the screen to blue */
- HalInitSystem(2, KeLoaderBlock);
-
/* Check if GUI Boot is enabled */
if (strstr(KeLoaderBlock->LoadOptions, "NOGUIBOOT")) NoGuiBoot = TRUE;
- /* Display version number and copyright/warranty message */
- if (NoGuiBoot) ExpDisplayNotice();
+ /* Display the boot screen image if not disabled */
+ if (!ExpInTextModeSetup) InbvDisplayInitialize2(NoGuiBoot);
+ if (!NoGuiBoot) InbvDisplayBootLogo();
- /* Call KD Providers at Phase 2 */
+ /* Clear the screen to blue and display the boot notice and debug status */
+ if (NoGuiBoot) ExpDisplayNotice();
KdInitSystem(2, KeLoaderBlock);
- /* Import and create NLS Data and Sections */
- RtlpInitNls();
-
- /* Import and Load Registry Hives */
- CmInitHives(ExpInTextModeSetup);
+ /* Initialize Power Subsystem in Phase 0 */
+ PoInit(0, AcpiTableDetected);
- /* Initialize VDM support */
- KeI386VdmInitialize();
-
- /* Initialize the time zone information from the registry */
- ExpInitTimeZoneInfo();
+ /* Query the clock */
+ if (HalQueryRealTimeClock(&TimeFields))
+ {
+ /* Convert to time fields */
+ RtlTimeFieldsToTime(&TimeFields, &SystemBootTime);
+ UniversalBootTime = SystemBootTime;
+
+#if 0 // FIXME: Won't work until we can read registry data here
+ /* FIXME: This assumes that the RTC is not already in GMT */
+ ExpTimeZoneBias.QuadPart = Int32x32To64(ExpLastTimeZoneBias * 60,
+ 10000000);
+
+ /* Set the boot time-zone bias */
+ SharedUserData->TimeZoneBias.High2Time = ExpTimeZoneBias.HighPart;
+ SharedUserData->TimeZoneBias.LowPart = ExpTimeZoneBias.LowPart;
+ SharedUserData->TimeZoneBias.High1Time = ExpTimeZoneBias.HighPart;
+
+ /* Convert the boot time to local time, and set it */
+ UniversalBootTime.QuadPart = SystemBootTime.QuadPart +
+ ExpTimeZoneBias.QuadPart;
+#endif
+ KiSetSystemTime(&UniversalBootTime);
- /* Enter the kernel debugger before starting up the boot drivers */
- if (KdDebuggerEnabled && KdpEarlyBreak)
- DbgBreakPoint();
+ /* Remember this as the boot time */
+ KeBootTime = UniversalBootTime;
+ }
- /* Setup Drivers and Root Device Node */
- IoInit2(FALSE);
+ /* The clock is ready now (FIXME: HACK FOR OLD HAL) */
+ KiClockSetupComplete = TRUE;
- /* Display the boot screen image if not disabled */
- if (!NoGuiBoot) InbvEnableBootDriver(TRUE);
+ /* Initialize all processors */
+ HalAllProcessorsStarted();
- /* Create ARC Names, SystemRoot SymLink, Load Drivers and Assign Letters */
- IoInit3();
+ /* Call OB initialization again */
+ if (!ObInit()) KeBugCheck(OBJECT1_INITIALIZATION_FAILED);
- /* Load the System DLL and its Entrypoints */
- PsLocateSystemDll();
+ /* Initialize Basic System Objects and Worker Threads */
+ if (!ExInitSystem()) KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, 1, 0, 0, 0);
- /* Initialize shared user page. Set dos system path, dos device map, etc. */
- InitSystemSharedUserPage(KeLoaderBlock);
+ /* Initialize the later stages of the kernel */
+ if (!KeInitSystem()) KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, 2, 0, 0, 0);
- /* Create 'ReactOSInitDone' event */
- RtlInitUnicodeString(&EventName, L"\\ReactOSInitDone");
- InitializeObjectAttributes(&ObjectAttributes,
- &EventName,
- 0,
- NULL,
- NULL);
- Status = ZwCreateEvent(&InitDoneEventHandle,
- EVENT_ALL_ACCESS,
- &ObjectAttributes,
- SynchronizationEvent,
- FALSE);
-
- /* Check for Success */
- if (!NT_SUCCESS(Status)) {
-
- DPRINT1("Failed to create 'ReactOSInitDone' event (Status 0x%x)\n", Status);
- InitDoneEventHandle = INVALID_HANDLE_VALUE;
+ /* Call KD Providers at Phase 1 */
+ if (!KdInitSystem(ExpInitializationPhase, KeLoaderBlock))
+ {
+ /* Failed, bugcheck */
+ KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, 3, 0, 0, 0);
}
- /* Launch initial process */
- Status = ExpLoadInitialProcess(&ProcessHandle,
- &ThreadHandle);
-
- /* Check for success, Bugcheck if we failed */
- if (!NT_SUCCESS(Status)) {
-
- KEBUGCHECKEX(SESSION4_INITIALIZATION_FAILED, Status, 0, 0, 0);
+ /* Create SystemRoot Link */
+ Status = ExpCreateSystemRootLink(KeLoaderBlock);
+ if (!NT_SUCCESS(Status))
+ {
+ KeBugCheckEx(SYMBOLIC_INITIALIZATION_FAILED, Status, 0, 0, 0);
}
- /* Wait on the Completion Event */
- if (InitDoneEventHandle != INVALID_HANDLE_VALUE) {
+ /* Create NLS section */
+ ExpInitNls(KeLoaderBlock);
- HANDLE Handles[2]; /* Init event, Initial process */
+ /* Initialize Cache Views */
+ CcInitializeCacheManager();
- /* Setup the Handles to wait on */
- Handles[0] = InitDoneEventHandle;
- Handles[1] = ProcessHandle;
+ /* Initialize the Registry */
+ if (!CmInitSystem1()) KeBugCheck(CONFIG_INITIALIZATION_FAILED);
- /* Wait for the system to be initialized */
- Timeout.QuadPart = (LONGLONG)-1200000000; /* 120 second timeout */
- Status = ZwWaitForMultipleObjects(2,
- Handles,
- WaitAny,
- FALSE,
- &Timeout);
- if (!NT_SUCCESS(Status)) {
+ /* Update timezone information */
+ ExRefreshTimeZoneInformation(&SystemBootTime);
- DPRINT1("NtWaitForMultipleObjects failed with status 0x%x!\n", Status);
+ /* Initialize the File System Runtime Library */
+ FsRtlInitSystem();
- } else if (Status == STATUS_TIMEOUT) {
+ /* Report all resources used by HAL */
+ HalReportResourceUsage();
- DPRINT1("WARNING: System not initialized after 120 seconds.\n");
+ /* Initialize LPC */
+ LpcpInitSystem();
- } else if (Status == STATUS_WAIT_0 + 1) {
+ /* Enter the kernel debugger before starting up the boot drivers */
+ if (KdDebuggerEnabled && KdpEarlyBreak) DbgBreakPoint();
- /* Crash the system if the initial process was terminated. */
- KEBUGCHECKEX(SESSION5_INITIALIZATION_FAILED, Status, 0, 0, 0);
- }
+ /* Initialize the I/O Subsystem */
+ if (!IoInitSystem(KeLoaderBlock)) KeBugCheck(IO1_INITIALIZATION_FAILED);
- /*
- * FIXME: FILIP!
- * Disable the Boot Logo
- */
- if (!NoGuiBoot) InbvEnableBootDriver(FALSE);
+ /* Unmap Low memory, and initialize the MPW and Balancer Thread */
+ MmInit3();
+#if DBG
+ extern ULONG Guard;
+#endif
+ ASSERT(Guard == 0xCACA1234);
- /* Signal the Event and close the handle */
- ZwSetEvent(InitDoneEventHandle, NULL);
- ZwClose(InitDoneEventHandle);
+ /* Initialize VDM support */
+ KeI386VdmInitialize();
- } else {
+ /* Initialize Power Subsystem in Phase 1*/
+ PoInit(1, AcpiTableDetected);
- /* On failure to create 'ReactOSInitDone' event, go to text mode ASAP */
- if (!NoGuiBoot) InbvEnableBootDriver(FALSE);
+ /* Initialize the Process Manager at Phase 1 */
+ if (!PsInitSystem()) KeBugCheck(PROCESS1_INITIALIZATION_FAILED);
- /* Crash the system if the initial process terminates within 5 seconds. */
- Timeout.QuadPart = (LONGLONG)-50000000; /* 5 second timeout */
- Status = ZwWaitForSingleObject(ProcessHandle,
- FALSE,
- &Timeout);
+ /* Launch initial process */
+ Status = ExpLoadInitialProcess(&ProcessHandle, &ThreadHandle);
- /* Check for timeout, crash if the initial process didn't initalize */
- if (Status != STATUS_TIMEOUT) KEBUGCHECKEX(SESSION5_INITIALIZATION_FAILED, Status, 1, 0, 0);
+ /* Wait 5 seconds for it to initialize */
+ Timeout.QuadPart = Int32x32To64(5, -10000000);
+ Status = ZwWaitForSingleObject(ProcessHandle, FALSE, &Timeout);
+ if (!NoGuiBoot) InbvFinalizeBootLogo();
+ if (Status == STATUS_SUCCESS)
+ {
+ /* Bugcheck the system if SMSS couldn't initialize */
+ KeBugCheck(SESSION5_INITIALIZATION_FAILED);
}
-
- /* Enable the Clock, close remaining handles */
- ZwClose(ThreadHandle);
- ZwClose(ProcessHandle);
-
- DPRINT1("System initialization complete\n");
+ else
{
- /* FIXME: We should instead jump to zero-page thread */
- /* Free initial kernel memory */
- MiFreeInitMemory();
+ /* Close process handles */
+ ZwClose(ThreadHandle);
+ ZwClose(ProcessHandle);
- /* Set our priority to 0 */
- KeGetCurrentThread()->BasePriority = 0;
- KeSetPriorityThread(KeGetCurrentThread(), 0);
+ /* FIXME: We should free the initial process' memory!*/
- /* Wait ad-infinitum */
- for (;;)
- {
- LARGE_INTEGER Timeout;
- Timeout.QuadPart = 0x7fffffffffffffffLL;
- KeDelayExecutionThread(KernelMode, FALSE, &Timeout);
- }
+ /* Increase init phase */
+ ExpInitializationPhase += 1;
+
+ /* Jump into zero page thread */
+ MmZeroPageThreadMain(NULL);
}
}
-
/* EOF */