extern ULONG reactos_disk_count;
extern ARC_DISK_SIGNATURE reactos_arc_disk_info[];
-extern BOOLEAN UseRealHeap;
extern ULONG LoaderPagesSpanned;
extern BOOLEAN AcpiPresent;
AllocateAndInitLPB(PLOADER_PARAMETER_BLOCK *OutLoaderBlock)
{
PLOADER_PARAMETER_BLOCK LoaderBlock;
- ULONG SystemBlockSize;
/* Allocate and zero-init the LPB */
- SystemBlockSize = sizeof(LOADER_SYSTEM_BLOCK) +
- reactos_disk_count * sizeof(ARC_DISK_SIGNATURE_EX);
- WinLdrSystemBlock = MmAllocateMemoryWithType(SystemBlockSize,
+ WinLdrSystemBlock = MmAllocateMemoryWithType(sizeof(LOADER_SYSTEM_BLOCK),
LoaderSystemBlock);
if (WinLdrSystemBlock == NULL)
{
//CHAR SystemRoot[] = "\\WINNT\\";
//CHAR ArcBoot[] = "multi(0)disk(0)rdisk(0)partition(1)";
- CHAR HalPath[] = "\\";
- CHAR ArcBoot[256];
- CHAR MiscFiles[256];
+ LPSTR LoadOptions, NewLoadOptions;
+ CHAR HalPath[] = "\\";
+ CHAR ArcBoot[256];
+ CHAR MiscFiles[256];
ULONG i;
ULONG_PTR PathSeparator;
PLOADER_PARAMETER_EXTENSION Extension;
strncpy(LoaderBlock->NtHalPathName, HalPath, MAX_PATH);
LoaderBlock->NtHalPathName = PaToVa(LoaderBlock->NtHalPathName);
- /* Fill load options */
- LoaderBlock->LoadOptions = WinLdrSystemBlock->LoadOptions;
+ /* 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 */
/* Convert ARC disk information from freeldr to a correct format */
for (i = 0; i < reactos_disk_count; i++)
{
- PARC_DISK_SIGNATURE ArcDiskSig;
+ PARC_DISK_SIGNATURE_EX ArcDiskSig;
- /* Get the ARC structure */
- ArcDiskSig = &WinLdrSystemBlock->ArcDiskSignature[i].DiskSignature;
+ /* Allocate the ARC structure */
+ ArcDiskSig = HeapAllocate(FrLdrDefaultHeap,
+ sizeof(ARC_DISK_SIGNATURE_EX),
+ 'giSD');
/* Copy the data over */
- ArcDiskSig->Signature = reactos_arc_disk_info[i].Signature;
- ArcDiskSig->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 */
- ArcDiskSig->ArcName = WinLdrSystemBlock->ArcDiskSignature[i].ArcName;
strncpy(ArcDiskSig->ArcName, reactos_arc_disk_info[i].ArcName, MAX_PATH);
- ArcDiskSig->ArcName = PaToVa(ArcDiskSig->ArcName);
+ ArcDiskSig->DiskSignature.ArcName = PaToVa(ArcDiskSig->ArcName);
/* Mark partition table as valid */
- ArcDiskSig->ValidPartitionTable = TRUE;
+ ArcDiskSig->DiskSignature.ValidPartitionTable = TRUE;
/* Insert into the list */
InsertTailList(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead,
- &ArcDiskSig->ListEntry);
+ &ArcDiskSig->DiskSignature.ListEntry);
}
/* Convert all list's to Virtual address */
static BOOLEAN
WinLdrLoadDeviceDriver(PLIST_ENTRY LoadOrderListHead,
- LPSTR BootPath,
+ LPCSTR BootPath,
PUNICODE_STRING FilePath,
ULONG Flags,
PLDR_DATA_TABLE_ENTRY *DriverDTE)
BOOLEAN
WinLdrLoadBootDrivers(PLOADER_PARAMETER_BLOCK LoaderBlock,
- LPSTR BootPath)
+ LPCSTR BootPath)
{
PLIST_ENTRY NextBd;
PBOOT_DRIVER_LIST_ENTRY BootDriver;
// Paths are relative (FIXME: Are they always relative?)
// Load it
- Status = WinLdrLoadDeviceDriver(&LoaderBlock->LoadOrderListHead, 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;
return PhysicalBase;
}
-
USHORT
WinLdrDetectVersion()
{
PCCH File,
TYPE_OF_MEMORY MemoryType,
PLDR_DATA_TABLE_ENTRY *Dte,
+ BOOLEAN IsKdTransportDll,
ULONG Percentage)
{
CHAR FullFileName[MAX_PATH];
strcpy(FullFileName, "WINDOWS\\SYSTEM32\\");
strcat(FullFileName, File);
- WinLdrAllocateDataTableEntry(&LoaderBlock->LoadOrderListHead, File,
- FullFileName, BaseAdress, Dte);
+ /*
+ * 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 BootPath[MAX_PATH];
+ CHAR BootPath[MAX_PATH];
CHAR FileName[MAX_PATH];
CHAR BootOptions[256];
PCHAR File;
BOOLEAN Status;
- ULONG_PTR SectionId;
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();
UiDrawProgressBarCenter(1, 100, "Loading NT...");
if (!HasSection ||
!IniReadSettingByName(SectionId, "SystemPath", BootPath, sizeof(BootPath)))
{
- strcpy(BootPath, OperatingSystemName);
+ strcpy(BootPath, SectionName);
}
/* Special case for LiveCD */
strcat(BootPath, FileName);
}
- /* append a backslash */
+ /* Append a backslash */
if ((strlen(BootPath)==0) || BootPath[strlen(BootPath)] != '\\')
strcat(BootPath, "\\");
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 != '"')
AllocateAndInitLPB(&LoaderBlock);
#ifdef _M_IX86
- /* Setup redirection support */
+ /* Setup redirection support */
WinLdrSetupEms(BootOptions);
#endif
Status = WinLdrScanSystemHive(LoaderBlock, BootPath);
TRACE("SYSTEM hive scanned with status %d\n", Status);
-
+ /* Finish loading */
LoadAndBootWindowsCommon(OperatingSystemVersion,
LoaderBlock,
BootOptions,
{
PLOADER_PARAMETER_BLOCK LoaderBlockVA;
BOOLEAN Status;
- CHAR FileName[MAX_PATH];
- PLDR_DATA_TABLE_ENTRY KernelDTE, HalDTE, KdComDTE = NULL;
+ PLDR_DATA_TABLE_ENTRY KernelDTE;
KERNEL_ENTRY_POINT KiSystemStartup;
LPCSTR SystemRoot;
TRACE("LoadAndBootWindowsCommon()\n");
SystemRoot = strstr(BootPath, "\\");
/* Detect hardware */
- UseRealHeap = TRUE;
LoaderBlock->ConfigurationRoot = MachHwDetect();
if (OperatingSystemVersion == 0)
OperatingSystemVersion = WinLdrDetectVersion();
- /* Load kernel */
- LoadModule(LoaderBlock, BootPath, "NTOSKRNL.EXE", LoaderSystemCode, &KernelDTE, 30);
-
- /* Load HAL */
- LoadModule(LoaderBlock, BootPath, "HAL.DLL", LoaderHalCode, &HalDTE, 45);
-
- /* Load kernel-debugger support dll */
- if (OperatingSystemVersion > _WIN32_WINNT_WIN2K)
- {
- LoadModule(LoaderBlock, BootPath, "KDCOM.DLL", LoaderSystemCode, &KdComDTE, 60);
- }
-
- /* Load all referenced DLLs for kernel, HAL and kdcom.dll */
- strcpy(FileName, BootPath);
- strcat(FileName, "system32\\");
- Status = WinLdrScanImportDescriptorTable(&LoaderBlock->LoadOrderListHead, FileName, KernelDTE);
- Status &= WinLdrScanImportDescriptorTable(&LoaderBlock->LoadOrderListHead, FileName, HalDTE);
- if (KdComDTE)
- Status &= WinLdrScanImportDescriptorTable(&LoaderBlock->LoadOrderListHead, FileName, KdComDTE);
-
+ /* Load the operating system core: the Kernel, the HAL and the Kernel Debugger Transport DLL */
+ Status = LoadWindowsCore(OperatingSystemVersion,
+ LoaderBlock,
+ BootOptions,
+ BootPath,
+ &KernelDTE);
if (!Status)
{
- UiMessageBox("Error loading imported dll.");
+ UiMessageBox("Error loading NTOS core.");
return;
}
/* Load boot drivers */
UiDrawBackdrop();
UiDrawProgressBarCenter(100, 100, "Loading boot drivers...");
- Status = WinLdrLoadBootDrivers(LoaderBlock, (PCHAR)BootPath);
+ Status = WinLdrLoadBootDrivers(LoaderBlock, BootPath);
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;
LoaderBlock->Extension->LoaderPagesSpanned = LoaderPagesSpanned;
TRACE("Hello from paged mode, KiSystemStartup %p, LoaderBlockVA %p!\n",
- KiSystemStartup, LoaderBlockVA);
+ 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) {};
NextBd = ArcDisk->ListEntry.Flink;
}
}
-
-