From bac97c58e25262ccf53dfd7d0de4bed638b65491 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Thu, 23 Apr 2026 23:28:00 +0200 Subject: [PATCH] [FREELDR] Rework the contents of the FreeLoader setup, custom-boot, and NT advanced boot options menus - Make the menu contents more dynamic; inspired by PR #8871 by Ahmed Arif. - advopts.c: Double-relicense ntldropts.c/h to GPL-2.0-or-later or MIT, as most of the code in this file has been rewritten for years now. - options.c (FreeLoader setup options menu): Double-relicense options.c/h to GPL-2.0-or-later or MIT, as most of the code in this file has been rewritten since commit 9ff4e4b9ef. --- boot/freeldr/freeldr/custom.c | 32 +-- boot/freeldr/freeldr/include/custom.h | 8 - boot/freeldr/freeldr/include/freeldr.h | 2 +- boot/freeldr/freeldr/include/ntldr/winldr.h | 14 +- boot/freeldr/freeldr/include/options.h | 9 +- boot/freeldr/freeldr/ntldr/advopts.c | 262 +++++++++++++++----- boot/freeldr/freeldr/ntldr/setupldr.c | 4 +- boot/freeldr/freeldr/ntldr/winldr.c | 4 +- boot/freeldr/freeldr/options.c | 87 +++++-- 9 files changed, 295 insertions(+), 127 deletions(-) diff --git a/boot/freeldr/freeldr/custom.c b/boot/freeldr/freeldr/custom.c index 7519d2d7fa5..845a5fb1d1b 100644 --- a/boot/freeldr/freeldr/custom.c +++ b/boot/freeldr/freeldr/custom.c @@ -114,14 +114,21 @@ static const PCSTR CustomBootPrompt = VOID OptionMenuCustomBoot(VOID) { - PCSTR CustomBootMenuList[] = { + static PCSTR CustomBootMenuList[] = { #if defined(_M_IX86) || defined(_M_AMD64) "Boot Sector (Disk/Partition/File)", "Linux", #endif "ReactOS", "ReactOS Setup" - }; + }; + static ULONG MenuActionsMap[RTL_NUMBER_OF(CustomBootMenuList)] = { +#if defined(_M_IX86) || defined(_M_AMD64) + 0, 1, +#endif + 2, 3 + }; + ULONG SelectedMenuItem; OperatingSystemItem OperatingSystem; @@ -139,7 +146,7 @@ VOID OptionMenuCustomBoot(VOID) /* Initialize a new custom OS entry */ OperatingSystem.SectionId = 0; - switch (SelectedMenuItem) + switch (MenuActionsMap[SelectedMenuItem]) { #if defined(_M_IX86) || defined(_M_AMD64) case 0: // Boot Sector (Disk/Partition/File) @@ -148,20 +155,13 @@ VOID OptionMenuCustomBoot(VOID) case 1: // Linux EditCustomBootLinux(&OperatingSystem); break; +#endif /* _M_IX86 || _M_AMD64 */ case 2: // ReactOS EditCustomBootReactOS(&OperatingSystem, FALSE); break; case 3: // ReactOS Setup EditCustomBootReactOS(&OperatingSystem, TRUE); break; -#else - case 0: // ReactOS - EditCustomBootReactOS(&OperatingSystem, FALSE); - break; - case 1: // ReactOS Setup - EditCustomBootReactOS(&OperatingSystem, TRUE); - break; -#endif /* _M_IX86 || _M_AMD64 */ } /* And boot it */ @@ -568,13 +568,3 @@ EditCustomBootReactOS( OperatingSystem->SectionId = SectionId; OperatingSystem->LoadIdentifier = NULL; } - -#ifdef HAS_OPTION_MENU_REBOOT - -VOID OptionMenuReboot(VOID) -{ - UiMessageBox("The system will now reboot."); - Reboot(); -} - -#endif // HAS_OPTION_MENU_REBOOT diff --git a/boot/freeldr/freeldr/include/custom.h b/boot/freeldr/freeldr/include/custom.h index 53263546d46..6f420dd374c 100644 --- a/boot/freeldr/freeldr/include/custom.h +++ b/boot/freeldr/freeldr/include/custom.h @@ -19,10 +19,6 @@ #pragma once -#define HAS_OPTION_MENU_EDIT_CMDLINE -#define HAS_OPTION_MENU_CUSTOM_BOOT -#define HAS_OPTION_MENU_REBOOT - #ifdef HAS_OPTION_MENU_CUSTOM_BOOT VOID OptionMenuCustomBoot(VOID); #endif @@ -43,7 +39,3 @@ VOID EditCustomBootReactOS( IN OUT OperatingSystemItem* OperatingSystem, IN BOOLEAN IsSetup); - -#ifdef HAS_OPTION_MENU_REBOOT -VOID OptionMenuReboot(VOID); -#endif diff --git a/boot/freeldr/freeldr/include/freeldr.h b/boot/freeldr/freeldr/include/freeldr.h index 05e5dc57e6e..a8c737f9582 100644 --- a/boot/freeldr/freeldr/include/freeldr.h +++ b/boot/freeldr/freeldr/include/freeldr.h @@ -75,12 +75,12 @@ #include #include #include +#include #include #include #include #include #include -#include #include #include #include diff --git a/boot/freeldr/freeldr/include/ntldr/winldr.h b/boot/freeldr/freeldr/include/ntldr/winldr.h index 5db5aeb472e..c406ae42705 100644 --- a/boot/freeldr/freeldr/include/ntldr/winldr.h +++ b/boot/freeldr/freeldr/include/ntldr/winldr.h @@ -44,7 +44,7 @@ typedef struct _ARC_DISK_SIGNATURE_EX //////////////////////////////////////////////////////////////////////////////// /* The boot options are mutually exclusive */ -enum BootOption +enum SAFEBOOT_MODE { NO_OPTION = 0, @@ -53,14 +53,20 @@ enum BootOption SAFEBOOT_ALTSHELL, SAFEBOOT_DSREPAIR, - LKG_CONFIG, + LKG_CONFIG, // TODO: Make it exclusive? Or allow it to be combined with SafeBoot? }; +extern enum SAFEBOOT_MODE BootOptionChoice; + +#if DBG && defined(_M_IX86) // x86 *ONLY*: HAL/Kernel auto-detection override +#define BOOT_AUTODETECT 0 +#define BOOT_ACPI_APIC 1 +#define BOOT_ACPI_SMP 2 +extern UCHAR HALAutoDetectMode; +#endif #define BOOT_LOGGING (1 << 0) #define BOOT_VGA_MODE (1 << 1) #define BOOT_DEBUGGING (1 << 2) - -extern enum BootOption BootOptionChoice; extern LOGICAL BootFlags; VOID diff --git a/boot/freeldr/freeldr/include/options.h b/boot/freeldr/freeldr/include/options.h index 00eef427647..4a884e41f84 100644 --- a/boot/freeldr/freeldr/include/options.h +++ b/boot/freeldr/freeldr/include/options.h @@ -1,12 +1,17 @@ /* * PROJECT: FreeLoader - * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * LICENSE: Dual-licensed: + * GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * MIT (https://spdx.org/licenses/MIT) * PURPOSE: FreeLoader Setup and Configuration F2 menu. * COPYRIGHT: Copyright 2022-2026 Hermès Bélusca-Maïto */ #pragma once +#define HAS_OPTION_MENU_EDIT_CMDLINE +#define HAS_OPTION_MENU_CUSTOM_BOOT + VOID FreeLdrSetupMenu( _In_opt_ OperatingSystemItem* OperatingSystem); @@ -14,3 +19,5 @@ FreeLdrSetupMenu( VOID DisplayBootTimeOptions( _In_ OperatingSystemItem* OperatingSystem); + +VOID OptionMenuReboot(VOID); diff --git a/boot/freeldr/freeldr/ntldr/advopts.c b/boot/freeldr/freeldr/ntldr/advopts.c index 3a16054a9eb..adfefcd5426 100644 --- a/boot/freeldr/freeldr/ntldr/advopts.c +++ b/boot/freeldr/freeldr/ntldr/advopts.c @@ -1,6 +1,8 @@ /* * PROJECT: NT-compatible ReactOS/Windows OS Loader - * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * LICENSE: Dual-licensed: + * GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * MIT (https://spdx.org/licenses/MIT) * PURPOSE: Advanced Boot Options F8 menu. * COPYRIGHT: Copyright 1998-2003 Brian Palmer * Copyright 2010 Cameron Gutman @@ -14,33 +16,73 @@ /* GLOBALS ********************************************************************/ -static PCSTR OptionsMenuList[] = +/* Named menu IDs */ +typedef enum _ADVOPTS_ACTION { - "Safe Mode", - "Safe Mode with Networking", - "Safe Mode with Command Prompt", - - NULL, - - "Enable Boot Logging", - "Enable VGA Mode", - "Last Known Good Configuration", - "Directory Services Restore Mode", - "Debugging Mode", - - NULL, - - "Start ReactOS normally", + ActionSeparator = -1, + ActionSafeBoot, + ActionSafeBootNetwork, + ActionSafeBootAltShell, + ActionSafeBootDSRepair, + ActionBootLog, + ActionVGAMode, + ActionLKGConfig, + ActionDebugMode, +#if DBG && defined(_M_IX86) // x86 *ONLY*: HAL/Kernel auto-detection override + ActionBootAcpiApic, + ActionBootAcpiSmp, +#endif #ifdef HAS_OPTION_MENU_EDIT_CMDLINE - "Edit Boot Command Line (F10)", + ActionEditBootCmdLine, #endif -#ifdef HAS_OPTION_MENU_REBOOT - "Reboot", + ActionStartNormally, + ActionReboot, + ActionBackToPrevMenu, +} ADVOPTS_ACTION; + +typedef struct _ADVBOOT_OPTIONS +{ + ULONG Id; + PCSTR Item; +} ADVBOOT_OPTIONS; + +static ADVBOOT_OPTIONS AdvBootOptions[] = // OptionsMenuList +{ + {ActionSafeBoot, "Safe Mode"}, + {ActionSafeBootNetwork, "Safe Mode with Networking"}, + {ActionSafeBootAltShell, "Safe Mode with Command Prompt"}, + + {ActionSeparator, NULL}, + + {ActionBootLog, "Enable Boot Logging"}, + {ActionVGAMode, "Enable VGA Mode"}, + {ActionLKGConfig, "Last Known Good Configuration"}, + {ActionSafeBootDSRepair, "Directory Services Restore Mode"}, // "(ReactOS domain controllers only)" + {ActionDebugMode, "Debugging Mode"}, + +#if DBG && defined(_M_IX86) + /* For x86 *ONLY*, allow the user to override HAL/Kernel auto-detection. + * NOTE: This can always be done by manually editing the command-line if wanted. */ + {ActionBootAcpiApic, NULL}, + {ActionBootAcpiApic, "Boot with ACPI APIC"}, + {ActionBootAcpiSmp, "Boot with ACPI Multiprocessor"}, #endif + + {ActionSeparator, NULL}, + +#ifdef HAS_OPTION_MENU_EDIT_CMDLINE + {ActionEditBootCmdLine, "Edit Boot Command Line (F10)"}, +#endif + {ActionStartNormally, "Start ReactOS normally"}, + {ActionReboot, "Reboot"}, + {ActionBackToPrevMenu, "Return to OS Choices menu"}, }; /* Advanced NT boot options */ -enum BootOption BootOptionChoice = NO_OPTION; +enum SAFEBOOT_MODE BootOptionChoice = NO_OPTION; +#if DBG && defined(_M_IX86) // x86 *ONLY*: HAL/Kernel auto-detection override +UCHAR HALAutoDetectMode = BOOT_AUTODETECT; +#endif LOGICAL BootFlags = 0; /* FUNCTIONS ******************************************************************/ @@ -51,16 +93,16 @@ GetBootOptionsDescription( PSTR BootOptsDesc, _In_ SIZE_T BootOptsDescSize) { - /* NOTE: Keep in sync with the 'enum BootOption' - * in winldr.h and the OptionsMenuList above. */ + /* NOTE: Keep in sync with the 'enum SAFEBOOT_MODE' + * in winldr.h and the AdvBootOptions above. */ static const PCSTR* OptionNames[] = { /* NO_OPTION */ NULL, - /* SAFEBOOT */ &OptionsMenuList[0], - /* SAFEBOOT_NETWORK */ &OptionsMenuList[1], - /* SAFEBOOT_ALTSHELL */ &OptionsMenuList[2], - /* SAFEBOOT_DSREPAIR */ &OptionsMenuList[7], - /* LKG_CONFIG */ &OptionsMenuList[6], + /* SAFEBOOT */ &AdvBootOptions[0].Item, + /* SAFEBOOT_NETWORK */ &AdvBootOptions[1].Item, + /* SAFEBOOT_ALTSHELL */ &AdvBootOptions[2].Item, + /* SAFEBOOT_DSREPAIR */ &AdvBootOptions[7].Item, + /* LKG_CONFIG */ &AdvBootOptions[6].Item, }; if (BootOptsDescSize < sizeof(CHAR)) @@ -68,9 +110,21 @@ GetBootOptionsDescription( *BootOptsDesc = ANSI_NULL; +#if DBG && defined(_M_IX86) // x86 *ONLY*: HAL/Kernel auto-detection override + if ((HALAutoDetectMode != BOOT_AUTODETECT) && (HALAutoDetectMode <= BOOT_ACPI_SMP)) + { + static const PCSTR AutoDetectNames[] = {"", "ACPI APIC", "ACPI Multiprocessor"}; + RtlStringCbCatA(BootOptsDesc, BootOptsDescSize, AutoDetectNames[HALAutoDetectMode]); + } +#endif + ASSERT(BootOptionChoice < RTL_NUMBER_OF(OptionNames)); if (BootOptionChoice != NO_OPTION) // && BootOptionChoice < RTL_NUMBER_OF(OptionNames) + { + if (*BootOptsDesc) + RtlStringCbCatA(BootOptsDesc, BootOptsDescSize, ", "); RtlStringCbCatA(BootOptsDesc, BootOptsDescSize, *OptionNames[BootOptionChoice]); + } if (BootFlags & BOOT_LOGGING) { @@ -83,7 +137,7 @@ GetBootOptionsDescription( { if (*BootOptsDesc) RtlStringCbCatA(BootOptsDesc, BootOptsDescSize, ", "); - RtlStringCbCatA(BootOptsDesc, BootOptsDescSize, OptionsMenuList[4]); + RtlStringCbCatA(BootOptsDesc, BootOptsDescSize, AdvBootOptions[4].Item); } } @@ -91,33 +145,64 @@ GetBootOptionsDescription( { if (*BootOptsDesc) RtlStringCbCatA(BootOptsDesc, BootOptsDescSize, ", "); - RtlStringCbCatA(BootOptsDesc, BootOptsDescSize, OptionsMenuList[5]); + RtlStringCbCatA(BootOptsDesc, BootOptsDescSize, AdvBootOptions[5].Item); } if (BootFlags & BOOT_DEBUGGING) { if (*BootOptsDesc) RtlStringCbCatA(BootOptsDesc, BootOptsDescSize, ", "); - RtlStringCbCatA(BootOptsDesc, BootOptsDescSize, OptionsMenuList[8]); + RtlStringCbCatA(BootOptsDesc, BootOptsDescSize, AdvBootOptions[8].Item); } } VOID MenuNTOptions( - _Inout_ OperatingSystemItem* OperatingSystem) + _Inout_opt_ OperatingSystemItem* OperatingSystem) { - ULONG SelectedMenuItem; + ADVOPTS_ACTION MenuActionsMap[RTL_NUMBER_OF(AdvBootOptions)]; + PCSTR OptionsMenuList[RTL_NUMBER_OF(AdvBootOptions)]; // FIXME! + ULONG i, MenuItemCount; + ULONG SelectedMenuItem = 0; + /* Build the menu, filtering out any item that may not be applicable, + * and set the "Start ReactOS normally" as default. */ + for (i = 0, MenuItemCount = 0; i < RTL_NUMBER_OF(AdvBootOptions); ++i) + { + /* Hide the "Return to OS Choices" item if no OS entry is selected */ + if ((AdvBootOptions[i].Id == ActionBackToPrevMenu) && !OperatingSystem) + continue; +#if DBG && defined(_M_IX86) + /* Filter out ActionBootAcpiApic/ActionBootAcpiSmp + * if we aren't running on standard BIOS-based PC */ + if (AdvBootOptions[i].Id == ActionBootAcpiApic || + AdvBootOptions[i].Id == ActionBootAcpiSmp) + { +#if defined(SARCH_XBOX) || defined(SARCH_PC98) || defined(UEFIBOOT) + continue; +#endif + } +#endif + + /* Set the default option */ + if (AdvBootOptions[i].Id == ActionStartNormally) + SelectedMenuItem = MenuItemCount; + + MenuActionsMap[MenuItemCount] = AdvBootOptions[i].Id; + OptionsMenuList[MenuItemCount++] = AdvBootOptions[i].Item; + } + +doMenu: /* Redraw the backdrop, but don't overwrite boot options */ UiDrawBackdrop(UiGetScreenHeight() - 2); - DisplayBootTimeOptions(OperatingSystem); + if (OperatingSystem) + DisplayBootTimeOptions(OperatingSystem); if (!UiDisplayMenu("Please select an option:", NULL, OptionsMenuList, - RTL_NUMBER_OF(OptionsMenuList), - 10, // Use "Start ReactOS normally" as default; see the switch below. - -1, + MenuItemCount, + SelectedMenuItem, -1, &SelectedMenuItem, TRUE, NULL, NULL)) @@ -126,59 +211,71 @@ MenuNTOptions( return; } - switch (SelectedMenuItem) + switch (MenuActionsMap[SelectedMenuItem]) { - case 0: // Safe Mode + case ActionSafeBoot: BootOptionChoice = SAFEBOOT; BootFlags |= BOOT_LOGGING; break; - case 1: // Safe Mode with Networking + case ActionSafeBootNetwork: BootOptionChoice = SAFEBOOT_NETWORK; BootFlags |= BOOT_LOGGING; break; - case 2: // Safe Mode with Command Prompt + case ActionSafeBootAltShell: BootOptionChoice = SAFEBOOT_ALTSHELL; BootFlags |= BOOT_LOGGING; break; - // case 3: // Separator - // break; - case 4: // Enable Boot Logging + case ActionBootLog: BootFlags |= BOOT_LOGGING; break; - case 5: // Enable VGA Mode + case ActionVGAMode: BootFlags |= BOOT_VGA_MODE; break; - case 6: // Last Known Good Configuration + case ActionLKGConfig: BootOptionChoice = LKG_CONFIG; break; - case 7: // Directory Services Restore Mode + case ActionSafeBootDSRepair: BootOptionChoice = SAFEBOOT_DSREPAIR; break; - case 8: // Debugging Mode + case ActionDebugMode: BootFlags |= BOOT_DEBUGGING; break; - // case 9: // Separator - // break; - case 10: // Start ReactOS normally - // Reset all the parameters to their default values. +#if DBG && defined(_M_IX86) // x86 *ONLY*: HAL/Kernel auto-detection override + case ActionBootAcpiApic: + HALAutoDetectMode = BOOT_ACPI_APIC; + break; + case ActionBootAcpiSmp: + HALAutoDetectMode = BOOT_ACPI_SMP; + break; +#endif +#ifdef HAS_OPTION_MENU_EDIT_CMDLINE + case ActionEditBootCmdLine: + if (OperatingSystem) + EditOperatingSystemEntry(OperatingSystem); + goto doMenu; +#endif + case ActionStartNormally: + /* Reset all the parameters to their default values */ BootOptionChoice = NO_OPTION; +#if DBG && defined(_M_IX86) // x86 *ONLY*: HAL/Kernel auto-detection override + HALAutoDetectMode = BOOT_AUTODETECT; +#endif BootFlags = 0; break; -#ifdef HAS_OPTION_MENU_EDIT_CMDLINE - case 11: // Edit command line - EditOperatingSystemEntry(OperatingSystem); - break; -#endif -#ifdef HAS_OPTION_MENU_REBOOT - case 12: // Reboot + case ActionReboot: OptionMenuReboot(); - break; -#endif + return; + case ActionBackToPrevMenu: + return; /* Just return to the caller */ + DEFAULT_UNREACHABLE; } /* Update the human-readable boot-option description string */ - GetBootOptionsDescription(OperatingSystem->AdvBootOptsDesc, - sizeof(OperatingSystem->AdvBootOptsDesc)); + if (OperatingSystem) + { + GetBootOptionsDescription(OperatingSystem->AdvBootOptsDesc, + sizeof(OperatingSystem->AdvBootOptsDesc)); + } } VOID @@ -187,7 +284,7 @@ AppendBootTimeOptions( PSTR BootOptions, _In_ SIZE_T BootOptionsSize) { - /* NOTE: Keep in sync with the 'enum BootOption' in winldr.h */ + /* NOTE: Keep in sync with the 'enum SAFEBOOT_MODE' in winldr.h */ static const PCSTR OptionsStr[] = { /* NO_OPTION */ NULL, @@ -198,9 +295,29 @@ AppendBootTimeOptions( /* LKG_CONFIG */ NULL, }; + PCSTR OptionsToAdd[2] = {NULL}; + PCSTR OptionsToRemove[2] = {NULL}; + if (BootOptionsSize < sizeof(CHAR)) return; +#if DBG && defined(_M_IX86) // x86 *ONLY*: HAL/Kernel auto-detection override + if ((HALAutoDetectMode != BOOT_AUTODETECT) && (HALAutoDetectMode <= BOOT_ACPI_SMP)) + { + static const PCSTR AutoDetectOptions[] = + { + /* BOOT_AUTODETECT */ NULL, + /* BOOT_ACPI_APIC */ "HAL=halaacpi.dll", + /* BOOT_ACPI_SMP */ "HAL=halmacpi.dll KERNEL=ntkrnlmp.exe", + }; + PCSTR OptionsToRemove[] = {"/HAL=/KERNEL=", "/DETECTHAL", NULL}; + + OptionsToAdd[0] = AutoDetectOptions[HALAutoDetectMode]; + NtLdrUpdateOptions(BootOptions, BootOptionsSize, FALSE, + OptionsToAdd, OptionsToRemove); + } +#endif + switch (BootOptionChoice) { case SAFEBOOT: @@ -209,12 +326,17 @@ AppendBootTimeOptions( case SAFEBOOT_DSREPAIR: { ASSERT(BootOptionChoice < RTL_NUMBER_OF(OptionsStr)); - NtLdrAddOptions(BootOptions, BootOptionsSize, TRUE, OptionsStr[BootOptionChoice]); + + /* SAFEBOOT(:) options are self-excluding */ + OptionsToAdd[0] = OptionsStr[BootOptionChoice]; + OptionsToRemove[0] = "/SAFEBOOT/SAFEBOOT:"; + NtLdrUpdateOptions(BootOptions, BootOptionsSize, TRUE, + OptionsToAdd, OptionsToRemove); break; } case LKG_CONFIG: - DbgPrint("Last known good configuration is not supported yet!\n"); + DbgPrint("Last known good configuration is not yet supported!\n"); break; default: @@ -228,5 +350,11 @@ AppendBootTimeOptions( NtLdrAddOptions(BootOptions, BootOptionsSize, TRUE, "BASEVIDEO"); if (BootFlags & BOOT_DEBUGGING) - NtLdrAddOptions(BootOptions, BootOptionsSize, TRUE, "DEBUG"); + { + /* Remove NODEBUG if present, since we want to have debugging enabled */ + OptionsToAdd[0] = "DEBUG"; + OptionsToRemove[0] = "NODEBUG"; + NtLdrUpdateOptions(BootOptions, BootOptionsSize, TRUE, + OptionsToAdd, OptionsToRemove); + } } diff --git a/boot/freeldr/freeldr/ntldr/setupldr.c b/boot/freeldr/freeldr/ntldr/setupldr.c index cb9512f5c87..e34e630ad9d 100644 --- a/boot/freeldr/freeldr/ntldr/setupldr.c +++ b/boot/freeldr/freeldr/ntldr/setupldr.c @@ -602,7 +602,7 @@ LoadReactOSSetup( } /* If none was found, default to enabling debugging */ if (!DbgLoadOptions) - DbgLoadOptions = "/DEBUG"; + DbgLoadOptions = "DEBUG"; #if !DBG } #endif @@ -626,7 +626,7 @@ LoadReactOSSetup( * do not contain explicitly the DEBUG option), since we want * to have debugging enabled if possible. */ - OptionsToRemove[0] = "/NODEBUG"; + OptionsToRemove[0] = "NODEBUG"; NtLdrGetHigherPriorityOptions(DbgLoadOptions, &ExtraOptions, &HigherPriorityOptions); diff --git a/boot/freeldr/freeldr/ntldr/winldr.c b/boot/freeldr/freeldr/ntldr/winldr.c index 9cd0f193790..019fbda3e10 100644 --- a/boot/freeldr/freeldr/ntldr/winldr.c +++ b/boot/freeldr/freeldr/ntldr/winldr.c @@ -826,7 +826,7 @@ LoadWindowsCore(IN USHORT OperatingSystemVersion, /* * Select the HAL and KERNEL file names. - * Check for any "/HAL=" or "/KERNEL=" override option. + * Check for any "HAL=" or "KERNEL=" override option. * * See the following links to know how the file names are actually chosen: * https://www.geoffchappell.com/notes/windows/boot/bcd/osloader/detecthal.htm @@ -1276,7 +1276,7 @@ LoadAndBootWindows( TRACE("BootOptions(1): '%s'\n", BootOptions); /* - * Set the "/HAL=" and "/KERNEL=" options if needed. + * Set the "HAL=" and "KERNEL=" options if needed. * If already present on the standard "Options=" option line, they take * precedence over those passed via the separate "Hal=" and "Kernel=" * options. diff --git a/boot/freeldr/freeldr/options.c b/boot/freeldr/freeldr/options.c index db5edacfb93..cef0692f0d5 100644 --- a/boot/freeldr/freeldr/options.c +++ b/boot/freeldr/freeldr/options.c @@ -1,6 +1,8 @@ /* * PROJECT: FreeLoader - * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * LICENSE: Dual-licensed: + * GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * MIT (https://spdx.org/licenses/MIT) * PURPOSE: FreeLoader Setup and Configuration F2 menu. * COPYRIGHT: Copyright 1998-2003 Brian Palmer * Copyright 2012 Giannis Adamopoulos @@ -14,21 +16,41 @@ /* GLOBALS ********************************************************************/ -static PCSTR OptionsMenuList[] = +/* Named menu IDs */ +typedef enum _FRLDR_SETUP_ACTION { - "FreeLdr debugging", - - NULL, - + ActionSeparator = -1, + ActionDebugging, #ifdef HAS_OPTION_MENU_EDIT_CMDLINE - "Edit Boot Command Line (F10)", + ActionEditBootCmdLine, #endif #ifdef HAS_OPTION_MENU_CUSTOM_BOOT - "Custom Boot", + ActionCustomBoot, #endif -#ifdef HAS_OPTION_MENU_REBOOT - "Reboot", + ActionReboot, + ActionBackToPrevMenu, +} FRLDR_SETUP_ACTION; + +typedef struct _FRLDR_OPTIONS +{ + ULONG Id; + PCSTR Item; +} FRLDR_OPTIONS; + +static FRLDR_OPTIONS FrLdrOptions[] = // OptionsMenuList +{ + {ActionDebugging, "FreeLdr debugging"}, + + {ActionSeparator, NULL}, + +#ifdef HAS_OPTION_MENU_EDIT_CMDLINE + {ActionEditBootCmdLine, "Edit Boot Command Line (F10)"}, #endif +#ifdef HAS_OPTION_MENU_CUSTOM_BOOT + {ActionCustomBoot, "Custom Boot"}, +#endif + {ActionReboot, "Reboot"}, + {ActionBackToPrevMenu, "Return to OS Choices menu"}, }; static PCSTR FrldrDbgMsg = @@ -53,8 +75,25 @@ VOID FreeLdrSetupMenu( _In_opt_ OperatingSystemItem* OperatingSystem) { + FRLDR_SETUP_ACTION MenuActionsMap[RTL_NUMBER_OF(FrLdrOptions)]; + PCSTR OptionsMenuList[RTL_NUMBER_OF(FrLdrOptions)]; // FIXME! + ULONG i, MenuItemCount; ULONG SelectedMenuItem = 0; + /* Build the menu, filtering out any item that may not be applicable */ + for (i = 0, MenuItemCount = 0; i < RTL_NUMBER_OF(FrLdrOptions); ++i) + { + /* Hide the "Return to OS Choices" item if no OS entry is selected */ + if ((FrLdrOptions[i].Id == ActionBackToPrevMenu) && !OperatingSystem) + continue; +#ifdef HAS_OPTION_MENU_EDIT_CMDLINE + if ((FrLdrOptions[i].Id == ActionEditBootCmdLine) && !OperatingSystem) + continue; +#endif + MenuActionsMap[MenuItemCount] = FrLdrOptions[i].Id; + OptionsMenuList[MenuItemCount++] = FrLdrOptions[i].Item; + } + doMenu: /* Clear the backdrop */ UiDrawBackdrop(UiGetScreenHeight()); @@ -62,7 +101,7 @@ doMenu: if (!UiDisplayMenu(VERSION " Setup and Configuration", OperatingSystem ? NULL : "Press ESC to reboot.", OptionsMenuList, - RTL_NUMBER_OF(OptionsMenuList), + MenuItemCount, SelectedMenuItem, -1, &SelectedMenuItem, TRUE, @@ -72,9 +111,9 @@ doMenu: return; } - switch (SelectedMenuItem) + switch (MenuActionsMap[SelectedMenuItem]) { - case 0: // FreeLdr debugging + case ActionDebugging: { CHAR DebugChannelString[100] = ""; // DebugChannelString[0] = ANSI_NULL; @@ -86,24 +125,24 @@ doMenu: } break; } - // case 1: // Separator - // break; #ifdef HAS_OPTION_MENU_EDIT_CMDLINE - case 2: // Edit command line + case ActionEditBootCmdLine: if (OperatingSystem) EditOperatingSystemEntry(OperatingSystem); break; #endif #ifdef HAS_OPTION_MENU_CUSTOM_BOOT - case 3: // Custom Boot + case ActionCustomBoot: OptionMenuCustomBoot(); break; #endif -#ifdef HAS_OPTION_MENU_REBOOT - case 4: // Reboot + case ActionReboot: OptionMenuReboot(); - break; -#endif + return; + case ActionBackToPrevMenu: + // if (OperatingSystem) + return; /* Just return to the caller */ + DEFAULT_UNREACHABLE; } goto doMenu; } @@ -124,3 +163,9 @@ DisplayBootTimeOptions( OperatingSystem->AdvBootOptsDesc, ATTR(COLOR_LIGHTBLUE, UiGetMenuBgColor())); } + +VOID OptionMenuReboot(VOID) +{ + UiMessageBox("The system will now reboot."); + Reboot(); +}