#include <ndk/ldrtypes.h>
#include <debug.h>
-// TODO: Move to .h
-void WinLdrSetupForNt(PLOADER_PARAMETER_BLOCK LoaderBlock,
- PVOID *GdtIdt,
- ULONG *PcrBasePage,
- ULONG *TssBasePage);
+DBG_DEFAULT_CHANNEL(WINDOWS);
//FIXME: Do a better way to retrieve Arc disk information
extern ULONG reactos_disk_count;
extern ARC_DISK_SIGNATURE reactos_arc_disk_info[];
-extern char reactos_arc_strings[32][256];
-extern BOOLEAN UseRealHeap;
extern ULONG LoaderPagesSpanned;
extern BOOLEAN AcpiPresent;
extern HEADLESS_LOADER_BLOCK LoaderRedirectionInformation;
extern BOOLEAN WinLdrTerminalConnected;
-
extern void WinLdrSetupEms(IN PCHAR BootOptions);
-BOOLEAN
-WinLdrCheckForLoadedDll(IN OUT PLOADER_PARAMETER_BLOCK WinLdrBlock,
- IN PCH DllName,
- OUT PLDR_DATA_TABLE_ENTRY *LoadedEntry);
+PLOADER_SYSTEM_BLOCK WinLdrSystemBlock;
// debug stuff
VOID DumpMemoryAllocMap(VOID);
-VOID WinLdrpDumpMemoryDescriptors(PLOADER_PARAMETER_BLOCK LoaderBlock);
-VOID WinLdrpDumpBootDriver(PLOADER_PARAMETER_BLOCK LoaderBlock);
-VOID WinLdrpDumpArcDisks(PLOADER_PARAMETER_BLOCK LoaderBlock);
-
// Init "phase 0"
VOID
PLOADER_PARAMETER_BLOCK LoaderBlock;
/* Allocate and zero-init the LPB */
- LoaderBlock = MmHeapAlloc(sizeof(LOADER_PARAMETER_BLOCK));
- RtlZeroMemory(LoaderBlock, sizeof(LOADER_PARAMETER_BLOCK));
+ WinLdrSystemBlock = MmAllocateMemoryWithType(sizeof(LOADER_SYSTEM_BLOCK),
+ LoaderSystemBlock);
+ if (WinLdrSystemBlock == NULL)
+ {
+ UiMessageBox("Failed to allocate memory for system block!");
+ return;
+ }
+
+ RtlZeroMemory(WinLdrSystemBlock, sizeof(LOADER_SYSTEM_BLOCK));
+
+ LoaderBlock = &WinLdrSystemBlock->LoaderBlock;
+ LoaderBlock->NlsData = &WinLdrSystemBlock->NlsDataBlock;
/* Init three critical lists, used right away */
InitializeListHead(&LoaderBlock->LoadOrderListHead);
InitializeListHead(&LoaderBlock->MemoryDescriptorListHead);
InitializeListHead(&LoaderBlock->BootDriverListHead);
- /* Alloc space for NLS (it will be converted to VA in WinLdrLoadNLS) */
- LoaderBlock->NlsData = MmHeapAlloc(sizeof(NLS_DATA_BLOCK));
- if (LoaderBlock->NlsData == NULL)
- {
- UiMessageBox("Failed to allocate memory for NLS table data!");
- return;
- }
- RtlZeroMemory(LoaderBlock->NlsData, sizeof(NLS_DATA_BLOCK));
-
*OutLoaderBlock = LoaderBlock;
}
// Init "phase 1"
VOID
WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock,
- PCHAR Options,
- PCHAR SystemRoot,
- PCHAR BootPath,
+ LPCSTR Options,
+ LPCSTR SystemRoot,
+ LPCSTR BootPath,
USHORT VersionToBoot)
{
/* Examples of correct options and paths */
//CHAR SystemRoot[] = "\\WINNT\\";
//CHAR ArcBoot[] = "multi(0)disk(0)rdisk(0)partition(1)";
- CHAR HalPath[] = "\\";
- CHAR ArcBoot[256];
- CHAR MiscFiles[256];
- ULONG i, PathSeparator;
+ LPSTR LoadOptions, NewLoadOptions;
+ CHAR HalPath[] = "\\";
+ CHAR ArcBoot[256];
+ CHAR MiscFiles[256];
+ ULONG i;
+ ULONG_PTR PathSeparator;
PLOADER_PARAMETER_EXTENSION Extension;
/* Construct SystemRoot and ArcBoot from SystemPath */
strncpy(ArcBoot, BootPath, PathSeparator);
ArcBoot[PathSeparator] = 0;
- DPRINTM(DPRINT_WINDOWS, "ArcBoot: %s\n", ArcBoot);
- DPRINTM(DPRINT_WINDOWS, "SystemRoot: %s\n", SystemRoot);
- DPRINTM(DPRINT_WINDOWS, "Options: %s\n", Options);
+ TRACE("ArcBoot: %s\n", ArcBoot);
+ TRACE("SystemRoot: %s\n", SystemRoot);
+ TRACE("Options: %s\n", Options);
/* Fill Arc BootDevice */
- LoaderBlock->ArcBootDeviceName = MmHeapAlloc(strlen(ArcBoot)+1);
- strcpy(LoaderBlock->ArcBootDeviceName, ArcBoot);
+ LoaderBlock->ArcBootDeviceName = WinLdrSystemBlock->ArcBootDeviceName;
+ strncpy(LoaderBlock->ArcBootDeviceName, ArcBoot, MAX_PATH);
LoaderBlock->ArcBootDeviceName = PaToVa(LoaderBlock->ArcBootDeviceName);
/* Fill Arc HalDevice, it matches ArcBoot path */
- LoaderBlock->ArcHalDeviceName = MmHeapAlloc(strlen(ArcBoot)+1);
- strcpy(LoaderBlock->ArcHalDeviceName, ArcBoot);
+ LoaderBlock->ArcHalDeviceName = WinLdrSystemBlock->ArcBootDeviceName;
LoaderBlock->ArcHalDeviceName = PaToVa(LoaderBlock->ArcHalDeviceName);
/* Fill SystemRoot */
- LoaderBlock->NtBootPathName = MmHeapAlloc(strlen(SystemRoot)+1);
- strcpy(LoaderBlock->NtBootPathName, SystemRoot);
+ LoaderBlock->NtBootPathName = WinLdrSystemBlock->NtBootPathName;
+ strncpy(LoaderBlock->NtBootPathName, SystemRoot, MAX_PATH);
LoaderBlock->NtBootPathName = PaToVa(LoaderBlock->NtBootPathName);
/* Fill NtHalPathName */
- LoaderBlock->NtHalPathName = MmHeapAlloc(strlen(HalPath)+1);
- strcpy(LoaderBlock->NtHalPathName, HalPath);
+ LoaderBlock->NtHalPathName = WinLdrSystemBlock->NtHalPathName;
+ strncpy(LoaderBlock->NtHalPathName, HalPath, MAX_PATH);
LoaderBlock->NtHalPathName = PaToVa(LoaderBlock->NtHalPathName);
- /* Fill load options */
- LoaderBlock->LoadOptions = MmHeapAlloc(strlen(Options)+1);
- strcpy(LoaderBlock->LoadOptions, Options);
+ /* Fill LoadOptions and strip the '/' commutator symbol in front of each option */
+ NewLoadOptions = LoadOptions = LoaderBlock->LoadOptions = WinLdrSystemBlock->LoadOptions;
+ strncpy(LoaderBlock->LoadOptions, Options, MAX_OPTIONS_LENGTH);
+
+ do
+ {
+ while (*LoadOptions == '/')
+ ++LoadOptions;
+
+ *NewLoadOptions++ = *LoadOptions;
+ } while (*LoadOptions++);
+
LoaderBlock->LoadOptions = PaToVa(LoaderBlock->LoadOptions);
/* Arc devices */
- LoaderBlock->ArcDiskInformation = (PARC_DISK_INFORMATION)MmHeapAlloc(sizeof(ARC_DISK_INFORMATION));
+ LoaderBlock->ArcDiskInformation = &WinLdrSystemBlock->ArcDiskInformation;
InitializeListHead(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead);
/* Convert ARC disk information from freeldr to a correct format */
for (i = 0; i < reactos_disk_count; i++)
{
- PARC_DISK_SIGNATURE ArcDiskInfo;
+ PARC_DISK_SIGNATURE_EX ArcDiskSig;
- /* Get the ARC structure */
- ArcDiskInfo = (PARC_DISK_SIGNATURE)MmHeapAlloc(sizeof(ARC_DISK_SIGNATURE));
- RtlZeroMemory(ArcDiskInfo, sizeof(ARC_DISK_SIGNATURE));
+ /* Allocate the ARC structure */
+ ArcDiskSig = HeapAllocate(FrLdrDefaultHeap,
+ sizeof(ARC_DISK_SIGNATURE_EX),
+ 'giSD');
/* Copy the data over */
- ArcDiskInfo->Signature = reactos_arc_disk_info[i].Signature;
- ArcDiskInfo->CheckSum = reactos_arc_disk_info[i].CheckSum;
+ ArcDiskSig->DiskSignature.Signature = reactos_arc_disk_info[i].Signature;
+ ArcDiskSig->DiskSignature.CheckSum = reactos_arc_disk_info[i].CheckSum;
/* Copy the ARC Name */
- ArcDiskInfo->ArcName = (PCHAR)MmHeapAlloc(sizeof(CHAR)*256);
- strcpy(ArcDiskInfo->ArcName, reactos_arc_disk_info[i].ArcName);
- ArcDiskInfo->ArcName = (PCHAR)PaToVa(ArcDiskInfo->ArcName);
+ strncpy(ArcDiskSig->ArcName, reactos_arc_disk_info[i].ArcName, MAX_PATH);
+ ArcDiskSig->DiskSignature.ArcName = PaToVa(ArcDiskSig->ArcName);
/* Mark partition table as valid */
- ArcDiskInfo->ValidPartitionTable = TRUE;
+ ArcDiskSig->DiskSignature.ValidPartitionTable = TRUE;
/* Insert into the list */
InsertTailList(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead,
- &ArcDiskInfo->ListEntry);
+ &ArcDiskSig->DiskSignature.ListEntry);
}
/* Convert all list's to Virtual address */
List_PaToVa(&LoaderBlock->BootDriverListHead);
/* Initialize Extension now */
- Extension = MmHeapAlloc(sizeof(LOADER_PARAMETER_EXTENSION));
- if (Extension == NULL)
- {
- UiMessageBox("Failed to allocate LPB Extension!");
- return;
- }
- RtlZeroMemory(Extension, sizeof(LOADER_PARAMETER_EXTENSION));
-
- /* Fill LPB extension */
+ Extension = &WinLdrSystemBlock->Extension;
Extension->Size = sizeof(LOADER_PARAMETER_EXTENSION);
Extension->MajorVersion = (VersionToBoot & 0xFF00) >> 8;
Extension->MinorVersion = VersionToBoot & 0xFF;
/* See KiRosFrldrLpbToNtLpb for details */
Extension->AcpiTable = (PVOID)1;
}
-
+
+#ifdef _M_IX86
/* Set headless block pointer */
if (WinLdrTerminalConnected)
{
- Extension->HeadlessLoaderBlock = MmHeapAlloc(sizeof(HEADLESS_LOADER_BLOCK));
- if (Extension->HeadlessLoaderBlock == NULL)
- {
- UiMessageBox("Failed to allocate HLB Extension!");
- while (TRUE);
- return;
- }
- RtlCopyMemory(
- Extension->HeadlessLoaderBlock,
- &LoaderRedirectionInformation,
- sizeof(HEADLESS_LOADER_BLOCK));
+ Extension->HeadlessLoaderBlock = &WinLdrSystemBlock->HeadlessLoaderBlock;
+ RtlCopyMemory(Extension->HeadlessLoaderBlock,
+ &LoaderRedirectionInformation,
+ sizeof(HEADLESS_LOADER_BLOCK));
Extension->HeadlessLoaderBlock = PaToVa(Extension->HeadlessLoaderBlock);
}
-
+#endif
/* Load drivers database */
strcpy(MiscFiles, BootPath);
strcat(MiscFiles, "AppPatch\\drvmain.sdb");
Extension->DrvDBImage = PaToVa(WinLdrLoadModule(MiscFiles,
- &Extension->DrvDBSize, LoaderRegistryData));
+ &Extension->DrvDBSize,
+ LoaderRegistryData));
/* Convert extension and setup block pointers */
LoaderBlock->Extension = PaToVa(Extension);
if (LoaderBlock->SetupLdrBlock)
LoaderBlock->SetupLdrBlock = PaToVa(LoaderBlock->SetupLdrBlock);
+ TRACE("WinLdrInitializePhase1() completed\n");
}
-BOOLEAN
-WinLdrLoadDeviceDriver(PLOADER_PARAMETER_BLOCK LoaderBlock,
- LPSTR BootPath,
+static BOOLEAN
+WinLdrLoadDeviceDriver(PLIST_ENTRY LoadOrderListHead,
+ LPCSTR BootPath,
PUNICODE_STRING FilePath,
ULONG Flags,
PLDR_DATA_TABLE_ENTRY *DriverDTE)
DriverPath[0] = 0;
}
- DPRINTM(DPRINT_WINDOWS, "DriverPath: %s, DllName: %s, LPB %p\n", DriverPath, DllName, LoaderBlock);
+ TRACE("DriverPath: %s, DllName: %s, LPB\n", DriverPath, DllName);
// Check if driver is already loaded
- Status = WinLdrCheckForLoadedDll(LoaderBlock, DllName, DriverDTE);
+ Status = WinLdrCheckForLoadedDll(LoadOrderListHead, DllName, DriverDTE);
if (Status)
{
// We've got the pointer to its DTE, just return success
return FALSE;
// Allocate a DTE for it
- Status = WinLdrAllocateDataTableEntry(LoaderBlock, DllName, DllName, DriverBase, DriverDTE);
+ Status = WinLdrAllocateDataTableEntry(LoadOrderListHead, DllName, DllName, DriverBase, DriverDTE);
if (!Status)
{
- DPRINTM(DPRINT_WINDOWS, "WinLdrAllocateDataTableEntry() failed\n");
+ ERR("WinLdrAllocateDataTableEntry() failed\n");
return FALSE;
}
// Look for any dependencies it may have, and load them too
sprintf(FullPath,"%s%s", BootPath, DriverPath);
- Status = WinLdrScanImportDescriptorTable(LoaderBlock, FullPath, *DriverDTE);
+ Status = WinLdrScanImportDescriptorTable(LoadOrderListHead, FullPath, *DriverDTE);
if (!Status)
{
- DPRINTM(DPRINT_WINDOWS, "WinLdrScanImportDescriptorTable() failed for %s\n",
- FullPath);
+ ERR("WinLdrScanImportDescriptorTable() failed for %s\n", FullPath);
return FALSE;
}
BOOLEAN
WinLdrLoadBootDrivers(PLOADER_PARAMETER_BLOCK LoaderBlock,
- LPSTR BootPath)
+ LPCSTR BootPath)
{
PLIST_ENTRY NextBd;
PBOOT_DRIVER_LIST_ENTRY BootDriver;
{
BootDriver = CONTAINING_RECORD(NextBd, BOOT_DRIVER_LIST_ENTRY, Link);
- DPRINTM(DPRINT_WINDOWS, "BootDriver %wZ DTE %08X RegPath: %wZ\n", &BootDriver->FilePath,
+ TRACE("BootDriver %wZ DTE %08X RegPath: %wZ\n", &BootDriver->FilePath,
BootDriver->LdrEntry, &BootDriver->RegistryPath);
// Paths are relative (FIXME: Are they always relative?)
// Load it
- Status = WinLdrLoadDeviceDriver(LoaderBlock, BootPath, &BootDriver->FilePath,
- 0, &BootDriver->LdrEntry);
+ Status = WinLdrLoadDeviceDriver(&LoaderBlock->LoadOrderListHead,
+ BootPath,
+ &BootDriver->FilePath,
+ 0,
+ &BootDriver->LdrEntry);
// If loading failed - cry loudly
//FIXME: Maybe remove it from the list and try to continue?
return TRUE;
}
-PVOID WinLdrLoadModule(PCSTR ModuleName, ULONG *Size,
- TYPE_OF_MEMORY MemoryType)
+PVOID
+WinLdrLoadModule(PCSTR ModuleName,
+ ULONG *Size,
+ TYPE_OF_MEMORY MemoryType)
{
ULONG FileId;
PVOID PhysicalBase;
//sprintf(ProgressString, "Loading %s...", FileName);
//UiDrawProgressBarCenter(1, 100, ProgressString);
- DPRINTM(DPRINT_WINDOWS, "Loading module %s\n", ModuleName);
+ TRACE("Loading module %s\n", ModuleName);
*Size = 0;
/* Open the image file */
return NULL;
}
- DPRINTM(DPRINT_WINDOWS, "Loaded %s at 0x%x with size 0x%x\n", ModuleName, PhysicalBase, FileSize);
+ TRACE("Loaded %s at 0x%x with size 0x%x\n", ModuleName, PhysicalBase, FileSize);
return PhysicalBase;
}
-
USHORT
WinLdrDetectVersion()
{
return _WIN32_WINNT_WS03;
}
+static
+PVOID
+LoadModule(
+ PLOADER_PARAMETER_BLOCK LoaderBlock,
+ PCCH Path,
+ PCCH File,
+ TYPE_OF_MEMORY MemoryType,
+ PLDR_DATA_TABLE_ENTRY *Dte,
+ BOOLEAN IsKdTransportDll,
+ ULONG Percentage)
+{
+ CHAR FullFileName[MAX_PATH];
+ CHAR ProgressString[256];
+ NTSTATUS Status;
+ PVOID BaseAdress;
+
+ UiDrawBackdrop();
+ sprintf(ProgressString, "Loading %s...", File);
+ UiDrawProgressBarCenter(Percentage, 100, ProgressString);
+
+ strcpy(FullFileName, Path);
+ strcat(FullFileName, "SYSTEM32\\");
+ strcat(FullFileName, File);
+
+ Status = WinLdrLoadImage(FullFileName, MemoryType, &BaseAdress);
+ TRACE("%s loaded with status %d at %p\n",
+ File, Status, BaseAdress);
+
+ strcpy(FullFileName, "WINDOWS\\SYSTEM32\\");
+ strcat(FullFileName, File);
+ /*
+ * Cheat about the base DLL name if we are loading
+ * the Kernel Debugger Transport DLL, to make the
+ * PE loader happy.
+ */
+ WinLdrAllocateDataTableEntry(&LoaderBlock->LoadOrderListHead,
+ (IsKdTransportDll ? "KDCOM.DLL" : File),
+ FullFileName,
+ BaseAdress,
+ Dte);
+
+ return BaseAdress;
+}
+
+static
+BOOLEAN
+LoadWindowsCore(IN USHORT OperatingSystemVersion,
+ IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
+ IN LPCSTR BootOptions,
+ IN LPCSTR BootPath,
+ IN OUT PLDR_DATA_TABLE_ENTRY* KernelDTE)
+{
+ BOOLEAN Status;
+ CHAR DirPath[MAX_PATH];
+ CHAR KdTransportDllName[MAX_PATH];
+ PLDR_DATA_TABLE_ENTRY HalDTE, KdComDTE = NULL;
+
+ if (!KernelDTE) return FALSE;
+
+ /* Load the Kernel */
+ LoadModule(LoaderBlock, BootPath, "NTOSKRNL.EXE", LoaderSystemCode, KernelDTE, FALSE, 30);
+
+ /* Load the HAL */
+ LoadModule(LoaderBlock, BootPath, "HAL.DLL", LoaderHalCode, &HalDTE, FALSE, 45);
+
+ /* Load the Kernel Debugger Transport DLL */
+ if (OperatingSystemVersion > _WIN32_WINNT_WIN2K)
+ {
+ /*
+ * According to http://www.nynaeve.net/?p=173 :
+ * "[...] Another enhancement that could be done Microsoft-side would be
+ * a better interface for replacing KD transport modules. Right now, due
+ * to the fact that ntoskrnl is static linked to KDCOM.DLL, the OS loader
+ * has a hardcoded hack that interprets the KD type in the OS loader options,
+ * loads one of the (hardcoded filenames) "kdcom.dll", "kd1394.dll", or
+ * "kdusb2.dll" modules, and inserts them into the loaded module list under
+ * the name "kdcom.dll". [...]"
+ */
+
+ /*
+ * This loop replaces a dumb call to strstr(..., "DEBUGPORT=").
+ * Indeed I want it to be case-insensitive to allow "debugport="
+ * or "DeBuGpOrT=" or... , and I don't want it to match malformed
+ * command-line options, such as:
+ *
+ * "...foo DEBUGPORT=xxx bar..."
+ * "...foo/DEBUGPORT=xxx bar..."
+ * "...foo/DEBUGPORT=bar..."
+ *
+ * i.e. the "DEBUGPORT=" switch must start with a slash and be separated
+ * from the rest by whitespace, unless it begins the command-line, e.g.:
+ *
+ * "/DEBUGPORT=COM1 foo...bar..."
+ * "...foo /DEBUGPORT=USB bar..."
+ * or:
+ * "...foo /DEBUGPORT= bar..."
+ * (in that case, we default the port to COM).
+ */
+ while (BootOptions)
+ {
+ /* Skip possible initial whitespace */
+ BootOptions += strspn(BootOptions, " \t");
+
+ /* Check whether a new commutator starts and it is the DEBUGPORT one */
+ if (*BootOptions != '/' || _strnicmp(++BootOptions, "DEBUGPORT=", 10) != 0)
+ {
+ /* Search for another whitespace */
+ BootOptions = strpbrk(BootOptions, " \t");
+ continue;
+ }
+ else
+ {
+ /* We found the DEBUGPORT commutator. Move to the port name. */
+ BootOptions += 10;
+ break;
+ }
+ }
+
+ if (BootOptions)
+ {
+ /*
+ * We have found the DEBUGPORT commutator. Parse the port name.
+ * Format: /DEBUGPORT=COM1 or /DEBUGPORT=FILE:\Device\HarddiskX\PartitionY\debug.log or /DEBUGPORT=FOO
+ * If we only have /DEBUGPORT= (i.e. without any port name), defaults it to "COM".
+ */
+ strcpy(KdTransportDllName, "KD");
+ if (_strnicmp(BootOptions, "COM", 3) == 0 && '0' <= BootOptions[3] && BootOptions[3] <= '9')
+ {
+ strncat(KdTransportDllName, BootOptions, 3);
+ }
+ else
+ {
+ size_t i = strcspn(BootOptions, " \t:"); /* Skip valid separators: whitespace or colon */
+ if (i == 0)
+ strcat(KdTransportDllName, "COM");
+ else
+ strncat(KdTransportDllName, BootOptions, i);
+ }
+ strcat(KdTransportDllName, ".DLL");
+ _strupr(KdTransportDllName);
+
+ /*
+ * Load the transport DLL. Specify it to LoadModule so that it can
+ * change the base DLL name of the loaded transport DLL to the default
+ * "KDCOM.DLL" name, to make the PE loader happy.
+ */
+ LoadModule(LoaderBlock, BootPath, KdTransportDllName, LoaderSystemCode, &KdComDTE, TRUE, 60);
+ }
+ }
+
+ /* Load all referenced DLLs for Kernel, HAL and Kernel Debugger Transport DLL */
+ strcpy(DirPath, BootPath);
+ strcat(DirPath, "system32\\");
+ Status = WinLdrScanImportDescriptorTable(&LoaderBlock->LoadOrderListHead, DirPath, *KernelDTE);
+ Status &= WinLdrScanImportDescriptorTable(&LoaderBlock->LoadOrderListHead, DirPath, HalDTE);
+ if (KdComDTE)
+ {
+ Status &= WinLdrScanImportDescriptorTable(&LoaderBlock->LoadOrderListHead, DirPath, KdComDTE);
+ }
+
+ return Status;
+}
VOID
-LoadAndBootWindows(PCSTR OperatingSystemName,
- PSTR SettingsValue,
- USHORT OperatingSystemVersion)
+LoadAndBootWindows(IN OperatingSystemItem* OperatingSystem,
+ IN USHORT OperatingSystemVersion)
{
+ ULONG_PTR SectionId;
+ PCSTR SectionName = OperatingSystem->SystemPartition;
+ CHAR SettingsValue[80];
BOOLEAN HasSection;
- char FullPath[MAX_PATH], SystemRoot[MAX_PATH], BootPath[MAX_PATH];
+ CHAR BootPath[MAX_PATH];
CHAR FileName[MAX_PATH];
CHAR BootOptions[256];
PCHAR File;
- PCHAR PathSeparator;
- PVOID NtosBase = NULL, HalBase = NULL, KdComBase = NULL;
BOOLEAN Status;
- ULONG_PTR SectionId;
- PLOADER_PARAMETER_BLOCK LoaderBlock, LoaderBlockVA;
- KERNEL_ENTRY_POINT KiSystemStartup;
- PLDR_DATA_TABLE_ENTRY KernelDTE, HalDTE, KdComDTE = NULL;
- // Mm-related things
- PVOID GdtIdt;
- ULONG PcrBasePage=0;
- ULONG TssBasePage=0;
+ PLOADER_PARAMETER_BLOCK LoaderBlock;
+
+ // Get OS setting value
+ SettingsValue[0] = ANSI_NULL;
+ IniOpenSection("Operating Systems", &SectionId);
+ IniReadSettingByName(SectionId, SectionName, SettingsValue, sizeof(SettingsValue));
// Open the operating system section
// specified in the .ini file
- HasSection = IniOpenSection(OperatingSystemName, &SectionId);
+ HasSection = IniOpenSection(SectionName, &SectionId);
UiDrawBackdrop();
- UiDrawStatusText("Detecting Hardware...");
UiDrawProgressBarCenter(1, 100, "Loading NT...");
/* Read the system path is set in the .ini file */
- if (!HasSection || !IniReadSettingByName(SectionId, "SystemPath", FullPath, sizeof(FullPath)))
+ if (!HasSection ||
+ !IniReadSettingByName(SectionId, "SystemPath", BootPath, sizeof(BootPath)))
{
- strcpy(FullPath, OperatingSystemName);
+ strcpy(BootPath, SectionName);
}
/* Special case for LiveCD */
- if (!_strnicmp(FullPath, "LiveCD", strlen("LiveCD")))
+ if (!_strnicmp(BootPath, "LiveCD", strlen("LiveCD")))
{
- strcpy(BootPath, FullPath + strlen("LiveCD"));
- MachDiskGetBootPath(FullPath, sizeof(FullPath));
- strcat(FullPath, BootPath);
+ strcpy(FileName, BootPath + strlen("LiveCD"));
+ MachDiskGetBootPath(BootPath, sizeof(BootPath));
+ strcat(BootPath, FileName);
}
- /* Convert FullPath to SystemRoot */
- PathSeparator = strstr(FullPath, "\\");
- strcpy(SystemRoot, PathSeparator);
- strcat(SystemRoot, "\\");
+ /* Append a backslash */
+ if ((strlen(BootPath)==0) || BootPath[strlen(BootPath)] != '\\')
+ strcat(BootPath, "\\");
/* Read booting options */
if (!HasSection || !IniReadSettingByName(SectionId, "Options", BootOptions, sizeof(BootOptions)))
{
/* Get options after the title */
- const CHAR*p = SettingsValue;
+ PCSTR p = SettingsValue;
while (*p == ' ' || *p == '"')
p++;
while (*p != '\0' && *p != '"')
p++;
strcpy(BootOptions, p);
- DPRINTM(DPRINT_WINDOWS,"BootOptions: '%s'\n", BootOptions);
+ TRACE("BootOptions: '%s'\n", BootOptions);
}
/* Append boot-time options */
AppendBootTimeOptions(BootOptions);
- //
- // Check if a ramdisk file was given
- //
+ /* Check if a ramdisk file was given */
File = strstr(BootOptions, "/RDPATH=");
if (File)
{
- //
- // Copy the file name and everything else after it
- //
+ /* Copy the file name and everything else after it */
strcpy(FileName, File + 8);
- //
- // Null-terminate
- //
+ /* Null-terminate */
*strstr(FileName, " ") = ANSI_NULL;
- //
- // Load the ramdisk
- //
+ /* Load the ramdisk */
RamDiskLoadVirtualFile(FileName);
}
/* Let user know we started loading */
- UiDrawStatusText("Loading...");
-
- /* append a backslash */
- strcpy(BootPath, FullPath);
- if ((strlen(BootPath)==0) ||
- BootPath[strlen(BootPath)] != '\\')
- strcat(BootPath, "\\");
+ //UiDrawStatusText("Loading...");
- DPRINTM(DPRINT_WINDOWS,"BootPath: '%s'\n", BootPath);
+ TRACE("BootPath: '%s'\n", BootPath);
/* Allocate and minimalistic-initialize LPB */
AllocateAndInitLPB(&LoaderBlock);
-
- /* Setup redirection support */
- WinLdrSetupEms(BootOptions);
- /* Detect hardware */
- UseRealHeap = TRUE;
- LoaderBlock->ConfigurationRoot = MachHwDetect();
+#ifdef _M_IX86
+ /* Setup redirection support */
+ WinLdrSetupEms(BootOptions);
+#endif
/* Load Hive */
+ UiDrawBackdrop();
+ UiDrawProgressBarCenter(15, 100, "Loading system hive...");
Status = WinLdrInitSystemHive(LoaderBlock, BootPath);
- DPRINTM(DPRINT_WINDOWS, "SYSTEM hive loaded with status %d\n", Status);
+ TRACE("SYSTEM hive loaded with status %d\n", Status);
- if (OperatingSystemVersion == 0)
- OperatingSystemVersion = WinLdrDetectVersion();
+ /* Load NLS data, OEM font, and prepare boot drivers list */
+ Status = WinLdrScanSystemHive(LoaderBlock, BootPath);
+ TRACE("SYSTEM hive scanned with status %d\n", Status);
+
+ /* Finish loading */
+ LoadAndBootWindowsCommon(OperatingSystemVersion,
+ LoaderBlock,
+ BootOptions,
+ BootPath,
+ 0);
+}
- /* Load kernel */
- strcpy(FileName, BootPath);
- strcat(FileName, "SYSTEM32\\NTOSKRNL.EXE");
- Status = WinLdrLoadImage(FileName, LoaderSystemCode, &NtosBase);
- DPRINTM(DPRINT_WINDOWS, "Ntos loaded with status %d at %p\n", Status, NtosBase);
+VOID
+LoadAndBootWindowsCommon(
+ USHORT OperatingSystemVersion,
+ PLOADER_PARAMETER_BLOCK LoaderBlock,
+ LPCSTR BootOptions,
+ LPCSTR BootPath,
+ BOOLEAN Setup)
+{
+ PLOADER_PARAMETER_BLOCK LoaderBlockVA;
+ BOOLEAN Status;
+ PLDR_DATA_TABLE_ENTRY KernelDTE;
+ KERNEL_ENTRY_POINT KiSystemStartup;
+ LPCSTR SystemRoot;
+ TRACE("LoadAndBootWindowsCommon()\n");
- /* Load HAL */
- strcpy(FileName, BootPath);
- strcat(FileName, "SYSTEM32\\HAL.DLL");
- Status = WinLdrLoadImage(FileName, LoaderHalCode, &HalBase);
- DPRINTM(DPRINT_WINDOWS, "HAL loaded with status %d at %p\n", Status, HalBase);
+ /* Convert BootPath to SystemRoot */
+ SystemRoot = strstr(BootPath, "\\");
- /* Load kernel-debugger support dll */
- if (OperatingSystemVersion > _WIN32_WINNT_WIN2K)
- {
- strcpy(FileName, BootPath);
- strcat(FileName, "SYSTEM32\\KDCOM.DLL");
- Status = WinLdrLoadImage(FileName, LoaderBootDriver, &KdComBase);
- DPRINTM(DPRINT_WINDOWS, "KdCom loaded with status %d at %p\n", Status, KdComBase);
- }
+ /* Detect hardware */
+ LoaderBlock->ConfigurationRoot = MachHwDetect();
- /* Allocate data table entries for above-loaded modules */
- WinLdrAllocateDataTableEntry(LoaderBlock, "ntoskrnl.exe",
- "WINDOWS\\SYSTEM32\\NTOSKRNL.EXE", NtosBase, &KernelDTE);
- WinLdrAllocateDataTableEntry(LoaderBlock, "hal.dll",
- "WINDOWS\\SYSTEM32\\HAL.DLL", HalBase, &HalDTE);
- if (OperatingSystemVersion > _WIN32_WINNT_WIN2K)
+ if (OperatingSystemVersion == 0)
+ OperatingSystemVersion = WinLdrDetectVersion();
+
+ /* Load the operating system core: the Kernel, the HAL and the Kernel Debugger Transport DLL */
+ Status = LoadWindowsCore(OperatingSystemVersion,
+ LoaderBlock,
+ BootOptions,
+ BootPath,
+ &KernelDTE);
+ if (!Status)
{
- WinLdrAllocateDataTableEntry(LoaderBlock, "kdcom.dll",
- "WINDOWS\\SYSTEM32\\KDCOM.DLL", KdComBase, &KdComDTE);
+ UiMessageBox("Error loading NTOS core.");
+ return;
}
- /* Load all referenced DLLs for kernel, HAL and kdcom.dll */
- strcpy(FileName, BootPath);
- strcat(FileName, "SYSTEM32\\");
- WinLdrScanImportDescriptorTable(LoaderBlock, FileName, KernelDTE);
- WinLdrScanImportDescriptorTable(LoaderBlock, FileName, HalDTE);
- if (KdComDTE)
- WinLdrScanImportDescriptorTable(LoaderBlock, FileName, KdComDTE);
-
- /* Load NLS data, OEM font, and prepare boot drivers list */
- Status = WinLdrScanSystemHive(LoaderBlock, BootPath);
- DPRINTM(DPRINT_WINDOWS, "SYSTEM hive scanned with status %d\n", Status);
-
/* Load boot drivers */
+ UiDrawBackdrop();
+ UiDrawProgressBarCenter(100, 100, "Loading boot drivers...");
Status = WinLdrLoadBootDrivers(LoaderBlock, BootPath);
- DPRINTM(DPRINT_WINDOWS, "Boot drivers loaded with status %d\n", Status);
-
- /* Alloc PCR, TSS, do magic things with the GDT/IDT */
- WinLdrSetupForNt(LoaderBlock, &GdtIdt, &PcrBasePage, &TssBasePage);
+ TRACE("Boot drivers loaded with status %d\n", Status);
/* Initialize Phase 1 - no drivers loading anymore */
- WinLdrInitializePhase1(LoaderBlock, BootOptions, SystemRoot, BootPath, OperatingSystemVersion);
+ WinLdrInitializePhase1(LoaderBlock,
+ BootOptions,
+ SystemRoot,
+ BootPath,
+ OperatingSystemVersion);
/* Save entry-point pointer and Loader block VAs */
KiSystemStartup = (KERNEL_ENTRY_POINT)KernelDTE->EntryPoint;
LoaderBlockVA = PaToVa(LoaderBlock);
/* "Stop all motors", change videomode */
- if (OperatingSystemVersion < _WIN32_WINNT_WIN2K)
- MachPrepareForReactOS(TRUE);
- else
- MachPrepareForReactOS(FALSE);
+ MachPrepareForReactOS(Setup);
/* Debugging... */
//DumpMemoryAllocMap();
- /* Turn on paging mode of CPU*/
- WinLdrTurnOnPaging(LoaderBlock, PcrBasePage, TssBasePage, GdtIdt);
+ /* Do the machine specific initialization */
+ WinLdrSetupMachineDependent(LoaderBlock);
+
+ /* Map pages and create memory descriptors */
+ WinLdrSetupMemoryLayout(LoaderBlock);
+
+ /* Set processor context */
+ WinLdrSetProcessorContext();
/* Save final value of LoaderPagesSpanned */
- LoaderBlockVA->Extension->LoaderPagesSpanned = LoaderPagesSpanned;
+ LoaderBlock->Extension->LoaderPagesSpanned = LoaderPagesSpanned;
+
+ TRACE("Hello from paged mode, KiSystemStartup %p, LoaderBlockVA %p!\n",
+ KiSystemStartup, LoaderBlockVA);
- DPRINTM(DPRINT_WINDOWS, "Hello from paged mode, KiSystemStartup %p, LoaderBlockVA %p!\n",
- KiSystemStartup, LoaderBlockVA);
+ // Zero KI_USER_SHARED_DATA page
+ memset((PVOID)KI_USER_SHARED_DATA, 0, MM_PAGE_SIZE);
WinLdrpDumpMemoryDescriptors(LoaderBlockVA);
WinLdrpDumpBootDriver(LoaderBlockVA);
+#ifndef _M_AMD64
WinLdrpDumpArcDisks(LoaderBlockVA);
+#endif
//FIXME: If I substitute this debugging checkpoint, GCC will "optimize away" the code below
//while (1) {};
/* Pass control */
(*KiSystemStartup)(LoaderBlockVA);
-
- return;
}
VOID
{
MemoryDescriptor = CONTAINING_RECORD(NextMd, MEMORY_ALLOCATION_DESCRIPTOR, ListEntry);
- DPRINTM(DPRINT_WINDOWS, "BP %08X PC %04X MT %d\n", MemoryDescriptor->BasePage,
+ TRACE("BP %08X PC %04X MT %d\n", MemoryDescriptor->BasePage,
MemoryDescriptor->PageCount, MemoryDescriptor->MemoryType);
NextMd = MemoryDescriptor->ListEntry.Flink;
{
BootDriver = CONTAINING_RECORD(NextBd, BOOT_DRIVER_LIST_ENTRY, Link);
- DPRINTM(DPRINT_WINDOWS, "BootDriver %wZ DTE %08X RegPath: %wZ\n", &BootDriver->FilePath,
+ TRACE("BootDriver %wZ DTE %08X RegPath: %wZ\n", &BootDriver->FilePath,
BootDriver->LdrEntry, &BootDriver->RegistryPath);
NextBd = BootDriver->Link.Flink;
{
ArcDisk = CONTAINING_RECORD(NextBd, ARC_DISK_SIGNATURE, ListEntry);
- DPRINTM(DPRINT_WINDOWS, "ArcDisk %s checksum: 0x%X, signature: 0x%X\n",
+ TRACE("ArcDisk %s checksum: 0x%X, signature: 0x%X\n",
ArcDisk->ArcName, ArcDisk->CheckSum, ArcDisk->Signature);
NextBd = ArcDisk->ListEntry.Flink;
}
}
-
-