From 9baf0933fb80603cb6d7274eb2a22c7fa5e491b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Thu, 9 Apr 2026 20:48:18 +0200 Subject: [PATCH] [FREELDR:NTLDR] Improve LoaderBlock ArcBootDeviceName determination; correctly set ArcHalDeviceName - `ArcBootDeviceName`: Given a theoretically valid ARC boot path of the form: `multi(0)disk(0)rdisk(0)partition(2)ReactOS\\weird)name` correctly determine `ArcBootDeviceName` to be: `multi(0)disk(0)rdisk(0)partition(2)` and `SystemRoot` to be what follows it: `ReactOS\\weird)name` Usual paths like: `multi(0)disk(0)rdisk(0)partition(2)\\ReactOS` are still correctly handled, of course. - The `ArcHalDeviceName` path is the ARC path to the system partition, where the firmware started the bootloader from. For historical reasons it's called Arc **HAL**, because on older (and non-x86) Windows versions the HAL was to be placed next to the OS loader in the system partition, while the rest of the OS (kernel, etc.) was placed elsewhere. So, in order to correctly set `ArcHalDeviceName`, pass the determined SystemPartition all the way down to `WinLdrInitializePhase1()`. --- boot/freeldr/freeldr/ntldr/setupldr.c | 1 + boot/freeldr/freeldr/ntldr/winldr.c | 93 +++++++++++++++------------ boot/freeldr/freeldr/ntldr/winldr.h | 18 ++---- 3 files changed, 58 insertions(+), 54 deletions(-) diff --git a/boot/freeldr/freeldr/ntldr/setupldr.c b/boot/freeldr/freeldr/ntldr/setupldr.c index 3a43fa141f6..9c8272b6306 100644 --- a/boot/freeldr/freeldr/ntldr/setupldr.c +++ b/boot/freeldr/freeldr/ntldr/setupldr.c @@ -831,5 +831,6 @@ LoadReactOSSetup( return LoadAndBootWindowsCommon(_WIN32_WINNT_WS03, LoaderBlock, BootOptions, + SystemPartition, BootPath); } diff --git a/boot/freeldr/freeldr/ntldr/winldr.c b/boot/freeldr/freeldr/ntldr/winldr.c index 7a26e19c842..9cd0f193790 100644 --- a/boot/freeldr/freeldr/ntldr/winldr.c +++ b/boot/freeldr/freeldr/ntldr/winldr.c @@ -121,39 +121,49 @@ AllocateAndInitLPB( } // Init "phase 1" -VOID -WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock, - PCSTR Options, - PCSTR SystemRoot, - PCSTR BootPath, - USHORT VersionToBoot) +static VOID +WinLdrInitializePhase1( + _In_ USHORT OperatingSystemVersion, + _In_ PLOADER_PARAMETER_BLOCK LoaderBlock, + _In_ PCSTR BootOptions, + _In_ PCSTR SystemPartition, + _In_ PCSTR BootPath) { /* * Examples of correct options and paths: - * CHAR Options[] = "DEBUGPORT=COM1 BAUDRATE=115200"; - * CHAR Options[] = "NODEBUG"; - * CHAR SystemRoot[] = "\\WINNT\\"; - * CHAR ArcBoot[] = "multi(0)disk(0)rdisk(0)partition(1)"; + * CHAR BootOptions[] = "DEBUGPORT=COM1 BAUDRATE=115200"; + * CHAR SystemPartition[] = "multi(0)disk(0)rdisk(0)partition(1)"; + * CHAR BootPath[] = "multi(0)disk(0)rdisk(0)partition(2)\\ReactOS\\"; + * --> ArcBootDevice = "multi(0)disk(0)rdisk(0)partition(2)" + * SystemRoot = "\\ReactOS\\" */ - CHAR HalPath[] = "\\"; - CHAR ArcBoot[MAX_PATH+1]; - CHAR MiscFiles[MAX_PATH+1]; + CHAR FilePath[MAX_PATH+1]; ULONG i; - ULONG_PTR PathSeparator; PLOADER_PARAMETER_EXTENSION Extension; - /* Construct SystemRoot and ArcBoot from SystemPath */ - PathSeparator = strstr(BootPath, "\\") - BootPath; - RtlStringCbCopyNA(ArcBoot, sizeof(ArcBoot), BootPath, PathSeparator); + /* Convert BootPath to SystemRoot. Attempt to handle paths like: + * "multi(0)disk(0)rdisk(0)partition(2)ReactOS\\weird)name" + * where SystemRoot would be: "ReactOS\\weird)name" */ + PCSTR SystemRoot = BootPath + strcspn(BootPath, "\\"); + PCSTR LastParen; - TRACE("ArcBoot: '%s'\n", ArcBoot); - TRACE("SystemRoot: '%s'\n", SystemRoot); - TRACE("Options: '%s'\n", Options); + CHAR Sep = *SystemRoot; + *(PSTR)SystemRoot = ANSI_NULL; + LastParen = strrchr(BootPath, ')'); + *(PSTR)SystemRoot = Sep; + if (LastParen && (LastParen < SystemRoot)) + SystemRoot = (LastParen + 1); - /* Fill ARC BootDevice */ + TRACE("SystemPartition: '%s'\n", SystemPartition); + TRACE("ArcBootDevice: '%.*s'\n", (SystemRoot - BootPath), BootPath); + TRACE("SystemRoot: '%s'\n", SystemRoot); + TRACE("BootOptions: '%s'\n", BootOptions); + + /* Fill the OS boot partition ARC device path */ LoaderBlock->ArcBootDeviceName = WinLdrSystemBlock->ArcBootDeviceName; - RtlStringCbCopyA(LoaderBlock->ArcBootDeviceName, sizeof(WinLdrSystemBlock->ArcBootDeviceName), ArcBoot); + RtlStringCbCopyNA(LoaderBlock->ArcBootDeviceName, sizeof(WinLdrSystemBlock->ArcBootDeviceName), + BootPath, (SystemRoot - BootPath) * sizeof(CHAR)); LoaderBlock->ArcBootDeviceName = PaToVa(LoaderBlock->ArcBootDeviceName); // @@ -165,7 +175,7 @@ WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock, { PSETUP_LOADER_BLOCK SetupBlock = LoaderBlock->SetupLdrBlock; - /* Adjust the ARC path in the setup block - Matches ArcBoot path */ + /* Adjust the ARC path in the setup block - Matches ArcBootDeviceName */ SetupBlock->ArcSetupDeviceName = WinLdrSystemBlock->ArcBootDeviceName; SetupBlock->ArcSetupDeviceName = PaToVa(SetupBlock->ArcSetupDeviceName); @@ -173,8 +183,9 @@ WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock, LoaderBlock->SetupLdrBlock = PaToVa(LoaderBlock->SetupLdrBlock); } - /* Fill ARC HalDevice, it matches ArcBoot path */ - LoaderBlock->ArcHalDeviceName = WinLdrSystemBlock->ArcBootDeviceName; + /* Fill the firmware system loader / "HAL" partition ARC device path */ + LoaderBlock->ArcHalDeviceName = WinLdrSystemBlock->ArcHalDeviceName; + RtlStringCbCopyA(LoaderBlock->ArcHalDeviceName, sizeof(WinLdrSystemBlock->ArcHalDeviceName), SystemPartition); LoaderBlock->ArcHalDeviceName = PaToVa(LoaderBlock->ArcHalDeviceName); /* Fill SystemRoot */ @@ -189,7 +200,7 @@ WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock, /* Fill LoadOptions */ LoaderBlock->LoadOptions = WinLdrSystemBlock->LoadOptions; - RtlStringCbCopyA(LoaderBlock->LoadOptions, sizeof(WinLdrSystemBlock->LoadOptions), Options); + RtlStringCbCopyA(LoaderBlock->LoadOptions, sizeof(WinLdrSystemBlock->LoadOptions), BootOptions); LoaderBlock->LoadOptions = PaToVa(LoaderBlock->LoadOptions); /* ARC devices */ @@ -254,7 +265,7 @@ WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock, // FIXME: Extension->AcpiTableSize; } - if (VersionToBoot >= _WIN32_WINNT_VISTA) + if (OperatingSystemVersion >= _WIN32_WINNT_VISTA) { Extension->BootViaWinload = 1; Extension->LoaderPerformanceData = PaToVa(&WinLdrSystemBlock->LoaderPerformanceData); @@ -274,9 +285,9 @@ WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock, } /* Load drivers database */ - RtlStringCbCopyA(MiscFiles, sizeof(MiscFiles), BootPath); - RtlStringCbCatA(MiscFiles, sizeof(MiscFiles), "AppPatch\\drvmain.sdb"); - Extension->DrvDBImage = PaToVa(WinLdrLoadModule(MiscFiles, + RtlStringCbCopyA(FilePath, sizeof(FilePath), BootPath); + RtlStringCbCatA(FilePath, sizeof(FilePath), "AppPatch\\drvmain.sdb"); + Extension->DrvDBImage = PaToVa(WinLdrLoadModule(FilePath, &Extension->DrvDBSize, LoaderRegistryData)); @@ -1357,21 +1368,22 @@ LoadAndBootWindows( return LoadAndBootWindowsCommon(OperatingSystemVersion, LoaderBlock, BootOptions, + SystemPartition, BootPath); } ARC_STATUS LoadAndBootWindowsCommon( - IN USHORT OperatingSystemVersion, - IN PLOADER_PARAMETER_BLOCK LoaderBlock, - IN PCSTR BootOptions, - IN PCSTR BootPath) + _In_ USHORT OperatingSystemVersion, + _In_ PLOADER_PARAMETER_BLOCK LoaderBlock, + _In_ PCSTR BootOptions, + _In_ PCSTR SystemPartition, + _In_ PCSTR BootPath) { PLOADER_PARAMETER_BLOCK LoaderBlockVA; BOOLEAN Success; PLDR_DATA_TABLE_ENTRY KernelDTE; KERNEL_ENTRY_POINT KiSystemStartup; - PCSTR SystemRoot; TRACE("LoadAndBootWindowsCommon()\n"); @@ -1380,9 +1392,6 @@ LoadAndBootWindowsCommon( /* Setup redirection support */ WinLdrSetupEms(BootOptions); - /* Convert BootPath to SystemRoot */ - SystemRoot = strstr(BootPath, "\\"); - /* Detect hardware */ UiUpdateProgressBar(20, "Detecting hardware..."); LoaderBlock->ConfigurationRoot = MachHwDetect(BootOptions); @@ -1426,11 +1435,11 @@ LoadAndBootWindowsCommon( PeLdrImportDllLoadCallback = NULL; /* Initialize Phase 1 - no drivers loading anymore */ - WinLdrInitializePhase1(LoaderBlock, + WinLdrInitializePhase1(OperatingSystemVersion, + LoaderBlock, BootOptions, - SystemRoot, - BootPath, - OperatingSystemVersion); + SystemPartition, + BootPath); UiUpdateProgressBar(100, NULL); diff --git a/boot/freeldr/freeldr/ntldr/winldr.h b/boot/freeldr/freeldr/ntldr/winldr.h index a13d916a96e..0c13396d1e7 100644 --- a/boot/freeldr/freeldr/ntldr/winldr.h +++ b/boot/freeldr/freeldr/ntldr/winldr.h @@ -52,7 +52,7 @@ typedef struct _LOADER_SYSTEM_BLOCK NLS_DATA_BLOCK NlsDataBlock; CHAR LoadOptions[MAX_OPTIONS_LENGTH+1]; CHAR ArcBootDeviceName[MAX_PATH+1]; - // CHAR ArcHalDeviceName[MAX_PATH]; + CHAR ArcHalDeviceName[MAX_PATH+1]; CHAR NtBootPathName[MAX_PATH+1]; CHAR NtHalPathName[MAX_PATH+1]; ARC_DISK_INFORMATION ArcDiskInformation; @@ -123,13 +123,6 @@ WinLdrAddDriverToList( _In_ ULONG Tag); // winldr.c -VOID -WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock, - PCSTR Options, - PCSTR SystemPath, - PCSTR BootPath, - USHORT VersionToBoot); - VOID WinLdrpDumpMemoryDescriptors(PLOADER_PARAMETER_BLOCK LoaderBlock); @@ -141,10 +134,11 @@ WinLdrpDumpArcDisks(PLOADER_PARAMETER_BLOCK LoaderBlock); ARC_STATUS LoadAndBootWindowsCommon( - IN USHORT OperatingSystemVersion, - IN PLOADER_PARAMETER_BLOCK LoaderBlock, - IN PCSTR BootOptions, - IN PCSTR BootPath); + _In_ USHORT OperatingSystemVersion, + _In_ PLOADER_PARAMETER_BLOCK LoaderBlock, + _In_ PCSTR BootOptions, + _In_ PCSTR SystemPartition, + _In_ PCSTR BootPath); VOID WinLdrSetupMachineDependent(PLOADER_PARAMETER_BLOCK LoaderBlock);