/*
- * 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>
/* FUNCTIONS ****************************************************************/
+NTSTATUS
+NTAPI
+ExpCreateSystemRootLink(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
+{
+ UNICODE_STRING LinkName;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ HANDLE LinkHandle;
+ NTSTATUS Status;
+ ANSI_STRING AnsiName;
+ CHAR Buffer[256];
+ ANSI_STRING TargetString;
+ UNICODE_STRING TargetName;
+
+ /* Initialize the ArcName tree */
+ RtlInitUnicodeString(&LinkName, L"\\ArcName");
+ InitializeObjectAttributes(&ObjectAttributes,
+ &LinkName,
+ OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
+ NULL,
+ SePublicDefaultSd);
+
+ /* Create it */
+ Status = NtCreateDirectoryObject(&LinkHandle,
+ DIRECTORY_ALL_ACCESS,
+ &ObjectAttributes);
+ if (!NT_SUCCESS(Status))
+ {
+ KeBugCheckEx(SYMBOLIC_INITIALIZATION_FAILED, Status, 1, 0, 0);
+ }
+
+ /* Close the LinkHandle */
+ NtClose(LinkHandle);
+
+ /* Initialize the Device tree */
+ RtlInitUnicodeString(&LinkName, L"\\Device");
+ InitializeObjectAttributes(&ObjectAttributes,
+ &LinkName,
+ OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
+ NULL,
+ SePublicDefaultSd);
+
+ /* Create it */
+ Status = NtCreateDirectoryObject(&LinkHandle,
+ DIRECTORY_ALL_ACCESS,
+ &ObjectAttributes);
+ if (!NT_SUCCESS(Status))
+ {
+ KeBugCheckEx(SYMBOLIC_INITIALIZATION_FAILED, Status, 2, 0, 0);
+ }
+
+ /* Close the LinkHandle */
+ ObCloseHandle(LinkHandle, KernelMode);
+
+ /* 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);
+ }
+
+ /* Initialize the attributes for the link */
+ InitializeObjectAttributes(&ObjectAttributes,
+ &LinkName,
+ OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
+ NULL,
+ 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);
+ }
+
+ /* Create it */
+ Status = NtCreateSymbolicLinkObject(&LinkHandle,
+ SYMBOLIC_LINK_ALL_ACCESS,
+ &ObjectAttributes,
+ &TargetName);
+
+ /* Free the strings */
+ RtlFreeUnicodeString(&LinkName);
+ RtlFreeUnicodeString(&TargetName);
+
+ /* Check if creating the link failed */
+ if (!NT_SUCCESS(Status))
+ {
+ KeBugCheckEx(SYMBOLIC_INITIALIZATION_FAILED, Status, 5, 0, 0);
+ }
+
+ /* Close the handle and return success */
+ ObCloseHandle(LinkHandle, KernelMode);
+ return STATUS_SUCCESS;
+}
+
VOID
NTAPI
ExpInitNls(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
if (!ExpNlsTableBase) KeBugCheck(PHASE0_INITIALIZATION_FAILED);
/* Copy the codepage data in its new location. */
- RtlMoveMemory(ExpNlsTableBase,
+ RtlCopyMemory(ExpNlsTableBase,
LoaderBlock->NlsData->AnsiCodePageData,
ExpNlsTableSize);
}
/* Copy the codepage data in its new location. */
- RtlMoveMemory(SectionBase, ExpNlsTableBase, ExpNlsTableSize);
+ RtlCopyMemory(SectionBase, ExpNlsTableBase, ExpNlsTableSize);
/* Free the previously allocated buffer and set the new location */
ExFreePool(ExpNlsTableBase);
}
/* Copy the table into the system process and set this as the base */
- RtlMoveMemory(SectionBase, ExpNlsTableBase, ExpNlsTableSize);
+ RtlCopyMemory(SectionBase, ExpNlsTableBase, ExpNlsTableSize);
ExpNlsTableBase = SectionBase;
}
-static
-VOID
-INIT_FUNCTION
-InitSystemSharedUserPage (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;
- OBJECT_ATTRIBUTES ObjectAttributes;
- HANDLE Handle;
- ULONG i;
- BOOLEAN BootDriveFound = FALSE;
-
- /* Set the Product Type */
- SharedUserData->NtProductType = NtProductWinNt;
- SharedUserData->ProductTypeIsValid = TRUE;
-
- /*
- * 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...]"
- */
-
- RtlCreateUnicodeStringFromAsciiz(&BootPath, LoaderBlock->NtBootPathName);
-
- /* Remove the trailing backslash */
- BootPath.Length -= sizeof(WCHAR);
- BootPath.MaximumLength -= sizeof(WCHAR);
-
- /* Only ARC Name left - Build full ARC Name */
- ArcNameBuffer = ExAllocatePool (PagedPool, 256 * sizeof(WCHAR));
- swprintf (ArcNameBuffer, L"\\ArcName\\%S", LoaderBlock->ArcBootDeviceName);
- RtlInitUnicodeString (&ArcName, ArcNameBuffer);
-
- /* Allocate ARC Device Name string */
- ArcDeviceName.Length = 0;
- ArcDeviceName.MaximumLength = 256 * sizeof(WCHAR);
- ArcDeviceName.Buffer = ExAllocatePool (PagedPool, 256 * sizeof(WCHAR));
-
- /* Open the Symbolic Link */
- InitializeObjectAttributes(&ObjectAttributes,
- &ArcName,
- OBJ_OPENLINK,
- 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);
- }
-
- /* Query the Link */
- Status = NtQuerySymbolicLinkObject(Handle,
- &ArcDeviceName,
- &Length);
- NtClose (Handle);
-
- /* Check for Success */
- if (!NT_SUCCESS(Status)) {
-
- /* Free the Strings */
- RtlFreeUnicodeString(&BootPath);
- ExFreePool(ArcDeviceName.Buffer);
- CPRINT("NtQuerySymbolicLinkObject() failed (Status %x)\n", Status);
- KEBUGCHECK(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;
- }
-
- /* Query it */
- Status = NtQuerySymbolicLinkObject(Handle,
- &DriveDeviceName,
- &Length);
-
- /* If it failed, skip to the next drive */
- if (!NT_SUCCESS(Status)) {
- DPRINT("Failed to query link %wZ\n", &DriveName);
- continue;
- }
- DPRINT("Opened link: %wZ ==> %wZ\n", &DriveName, &DriveDeviceName);
-
- /* See if we've found the boot drive */
- if (!RtlCompareUnicodeString (&ArcDeviceName, &DriveDeviceName, FALSE)) {
-
- DPRINT("DOS Boot path: %c:%wZ\n", 'A' + i, &BootPath);
- swprintf(SharedUserData->NtSystemRoot, L"%C:%wZ", 'A' + i, &BootPath);
- BootDriveFound = TRUE;
- }
-
- /* Close this Link */
- NtClose (Handle);
- }
-
- /* Free all the Strings we have in memory */
- RtlFreeUnicodeString (&BootPath);
- ExFreePool(DriveDeviceName.Buffer);
- ExFreePool(ArcDeviceName.Buffer);
-
- /* Make sure we found the Boot Drive */
- if (BootDriveFound == FALSE) {
-
- DbgPrint("No system drive found!\n");
- KEBUGCHECK (NO_BOOT_DEVICE);
- }
-}
-
VOID
INIT_FUNCTION
ExpDisplayNotice(VOID)
/* Create the environment string */
RtlInitEmptyUnicodeString(&Environment,
ProcessParameters->Environment,
- Size);
+ (USHORT)Size);
/* Append the DLL path to it */
RtlAppendUnicodeToString(&Environment, L"Path=" );
/* 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;
}
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;
/* Set up Region Maps, Sections and the Paging File */
MmInit2();
+ /* 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;
/* Check if GUI Boot is enabled */
if (strstr(KeLoaderBlock->LoadOptions, "NOGUIBOOT")) NoGuiBoot = TRUE;
+ /* Display the boot screen image if not disabled */
+ if (!ExpInTextModeSetup) InbvDisplayInitialize2(NoGuiBoot);
+ if (!NoGuiBoot) InbvDisplayBootLogo();
+
/* Clear the screen to blue and display the boot notice and debug status */
- HalInitSystem(2, KeLoaderBlock);
if (NoGuiBoot) ExpDisplayNotice();
KdInitSystem(2, KeLoaderBlock);
}
/* Create SystemRoot Link */
+ Status = ExpCreateSystemRootLink(KeLoaderBlock);
+ if (!NT_SUCCESS(Status))
+ {
+ KeBugCheckEx(SYMBOLIC_INITIALIZATION_FAILED, Status, 0, 0, 0);
+ }
/* Create NLS section */
ExpInitNls(KeLoaderBlock);
/* Initialize Cache Views */
CcInitializeCacheManager();
- /* Initialize the Registry (Hives are NOT yet loaded!) */
- CmInitSystem1();
+ /* Initialize the Registry */
+ if (!CmInitSystem1()) KeBugCheck(CONFIG_INITIALIZATION_FAILED);
/* Update timezone information */
ExRefreshTimeZoneInformation(&SystemBootTime);
/* Initialize LPC */
LpcpInitSystem();
- /* Initialize I/O Objects, Filesystems, Error Logging and Shutdown */
- IoInit();
-
- /* Unmap Low memory, and initialize the MPW and Balancer Thread */
- MmInit3();
-
- /* Import and Load Registry Hives */
- CmInitHives(ExpInTextModeSetup);
-
/* Enter the kernel debugger before starting up the boot drivers */
if (KdDebuggerEnabled && KdpEarlyBreak) DbgBreakPoint();
- /* Setup Drivers and Root Device Node */
- IoInit2(FALSE);
-
- /* Display the boot screen image if not disabled */
- if (!NoGuiBoot) InbvEnableBootDriver(TRUE);
-
- /* Create ARC Names, SystemRoot SymLink, Load Drivers and Assign Letters */
- IoInit3();
-
- /* Load the System DLL and its Entrypoints */
- PsLocateSystemDll();
+ /* Initialize the I/O Subsystem */
+ if (!IoInitSystem(KeLoaderBlock)) KeBugCheck(IO1_INITIALIZATION_FAILED);
- /* Initialize shared user page. Set dos system path, dos device map, etc. */
- InitSystemSharedUserPage(KeLoaderBlock);
+ /* Unmap Low memory, and initialize the MPW and Balancer Thread */
+ MmInit3();
+#if DBG
+ extern ULONG Guard;
+#endif
+ ASSERT(Guard == 0xCACA1234);
/* Initialize VDM support */
KeI386VdmInitialize();
/* 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 */
ZwClose(ThreadHandle);
ZwClose(ProcessHandle);
- /*
- * FIXME: FILIP!
- * Disable the Boot Logo
- */
- if (!NoGuiBoot) InbvEnableBootDriver(FALSE);
-
/* FIXME: We should free the initial process' memory!*/
/* Increase init phase */