[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.
This commit is contained in:
Hermès Bélusca-Maïto
2026-04-23 23:28:00 +02:00
parent 925d227faa
commit bac97c58e2
9 changed files with 295 additions and 127 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -75,12 +75,12 @@
#include <inifile.h>
#include <keycodes.h>
#include <linux.h>
#include <options.h>
#include <custom.h>
#include <miscboot.h>
#include <machine.h>
#include <mm.h>
#include <multiboot.h>
#include <options.h>
#include <oslist.h>
#include <ramdisk.h>
#include <settings.h>

View File

@@ -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

View File

@@ -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 <hermes.belusca-maito@reactos.org>
*/
#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);

View File

@@ -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 <brianp@sginet.com>
* Copyright 2010 Cameron Gutman <cameron.gutman@reactos.org>
@@ -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);
}
}

View File

@@ -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);

View File

@@ -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.

View File

@@ -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 <brianp@sginet.com>
* Copyright 2012 Giannis Adamopoulos <gadamopoulos@reactos.org>
@@ -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();
}