[FREELDR] The multiboot command-line and FREELOADER section options become global settings (#6803)

Dual-license settings.c: "old" code (CmdLineParse) stays BSD
and new code (mine) becomes MIT.
This commit is contained in:
Hermès Bélusca-Maïto 2024-04-24 19:51:14 +02:00
parent 2f4bb4084d
commit 7bee32d237
No known key found for this signature in database
GPG key ID: 3B2539C65E7B93D0
9 changed files with 152 additions and 156 deletions

View file

@ -26,17 +26,19 @@ EfiEntry(
_In_ EFI_HANDLE ImageHandle, _In_ EFI_HANDLE ImageHandle,
_In_ EFI_SYSTEM_TABLE *SystemTable) _In_ EFI_SYSTEM_TABLE *SystemTable)
{ {
PCSTR CmdLine = ""; // FIXME: Determine a command-line from UEFI boot options
SystemTable->ConOut->OutputString(SystemTable->ConOut, L"UEFI EntryPoint: Starting freeldr from UEFI"); SystemTable->ConOut->OutputString(SystemTable->ConOut, L"UEFI EntryPoint: Starting freeldr from UEFI");
GlobalImageHandle = ImageHandle; GlobalImageHandle = ImageHandle;
GlobalSystemTable = SystemTable; GlobalSystemTable = SystemTable;
/* Needed for default settings */ /* Load the default settings from the command-line */
CmdLineParse(""); LoadSettings(CmdLine);
/* Debugger pre-initialization */ /* Debugger pre-initialization */
DebugInit(0); DebugInit(BootMgrInfo.DebugString);
MachInit(""); MachInit(CmdLine);
/* UI pre-initialization */ /* UI pre-initialization */
if (!UiInitialize(FALSE)) if (!UiInitialize(FALSE))

View file

@ -322,28 +322,6 @@ EditOperatingSystemEntry(
} }
#endif // HAS_OPTION_MENU_EDIT_CMDLINE #endif // HAS_OPTION_MENU_EDIT_CMDLINE
static LONG
GetTimeOut(
IN ULONG_PTR FrLdrSectionId)
{
LONG TimeOut = -1;
CHAR TimeOutText[20];
TimeOut = CmdLineGetTimeOut();
if (TimeOut >= 0)
return TimeOut;
TimeOut = -1;
if ((FrLdrSectionId != 0) &&
IniReadSettingByName(FrLdrSectionId, "TimeOut", TimeOutText, sizeof(TimeOutText)))
{
TimeOut = atoi(TimeOutText);
}
return TimeOut;
}
BOOLEAN BOOLEAN
MainBootMenuKeyPressFilter( MainBootMenuKeyPressFilter(
IN ULONG KeyPress, IN ULONG KeyPress,
@ -370,14 +348,12 @@ MainBootMenuKeyPressFilter(
VOID RunLoader(VOID) VOID RunLoader(VOID)
{ {
ULONG_PTR SectionId;
LONG TimeOut;
ULONG OperatingSystemCount;
OperatingSystemItem* OperatingSystemList; OperatingSystemItem* OperatingSystemList;
PCSTR* OperatingSystemDisplayNames; PCSTR* OperatingSystemDisplayNames;
ULONG DefaultOperatingSystem; ULONG OperatingSystemCount;
ULONG SelectedOperatingSystem; ULONG DefaultOperatingSystem;
ULONG i; ULONG SelectedOperatingSystem;
ULONG i;
if (!MachInitializeBootDevices()) if (!MachInitializeBootDevices())
{ {
@ -395,24 +371,23 @@ VOID RunLoader(VOID)
#endif #endif
#endif #endif
/* Open FREELDR.INI and load the global FreeLoader settings */
if (!IniFileInitialize()) if (!IniFileInitialize())
{ {
UiMessageBoxCritical("Error initializing .ini file."); UiMessageBoxCritical("Error initializing .ini file.");
return; return;
} }
LoadSettings(NULL);
/* Open the [FreeLoader] section */ #if 0
if (!IniOpenSection("FreeLoader", &SectionId)) if (FALSE)
{ {
UiMessageBoxCritical("Section [FreeLoader] not found in freeldr.ini."); UiMessageBoxCritical("Could not load global FreeLoader settings.");
return; return;
} }
#endif
/* Debugger main initialization */ /* Debugger main initialization */
DebugInit(SectionId); DebugInit(BootMgrInfo.DebugString);
/* Retrieve the default timeout */
TimeOut = GetTimeOut(SectionId);
/* UI main initialization */ /* UI main initialization */
if (!UiInitialize(TRUE)) if (!UiInitialize(TRUE))
@ -421,8 +396,7 @@ VOID RunLoader(VOID)
return; return;
} }
OperatingSystemList = InitOperatingSystemList(SectionId, OperatingSystemList = InitOperatingSystemList(&OperatingSystemCount,
&OperatingSystemCount,
&DefaultOperatingSystem); &DefaultOperatingSystem);
if (!OperatingSystemList) if (!OperatingSystemList)
{ {
@ -446,7 +420,7 @@ VOID RunLoader(VOID)
} }
/* Find all the message box settings and run them */ /* Find all the message box settings and run them */
UiShowMessageBoxesInSection(SectionId); UiShowMessageBoxesInSection(BootMgrInfo.FrLdrSection);
for (;;) for (;;)
{ {
@ -461,7 +435,7 @@ VOID RunLoader(VOID)
OperatingSystemDisplayNames, OperatingSystemDisplayNames,
OperatingSystemCount, OperatingSystemCount,
DefaultOperatingSystem, DefaultOperatingSystem,
TimeOut, BootMgrInfo.TimeOut,
&SelectedOperatingSystem, &SelectedOperatingSystem,
FALSE, FALSE,
MainBootMenuKeyPressFilter, MainBootMenuKeyPressFilter,
@ -471,7 +445,7 @@ VOID RunLoader(VOID)
goto Reboot; goto Reboot;
} }
TimeOut = -1; BootMgrInfo.TimeOut = -1;
/* Load the chosen operating system */ /* Load the chosen operating system */
LoadOperatingSystem(&OperatingSystemList[SelectedOperatingSystem]); LoadOperatingSystem(&OperatingSystemList[SelectedOperatingSystem]);

View file

@ -42,10 +42,11 @@ CCHAR FrLdrBootPath[MAX_PATH] = "";
VOID __cdecl BootMain(IN PCCH CmdLine) VOID __cdecl BootMain(IN PCCH CmdLine)
{ {
CmdLineParse(CmdLine); /* Load the default settings from the command-line */
LoadSettings(CmdLine);
/* Debugger pre-initialization */ /* Debugger pre-initialization */
DebugInit(0); DebugInit(BootMgrInfo.DebugString);
MachInit(CmdLine); MachInit(CmdLine);

View file

@ -40,7 +40,10 @@
#if DBG #if DBG
VOID DebugInit(IN ULONG_PTR FrLdrSectionId); VOID
DebugInit(
_In_ PCSTR DebugString);
ULONG DbgPrint(const char *Format, ...); ULONG DbgPrint(const char *Format, ...);
VOID DbgPrint2(ULONG Mask, ULONG Level, const char *File, ULONG Line, char *Format, ...); VOID DbgPrint2(ULONG Mask, ULONG Level, const char *File, ULONG Line, char *Format, ...);
VOID DebugDumpBuffer(ULONG Mask, PVOID Buffer, ULONG Length); VOID DebugDumpBuffer(ULONG Mask, PVOID Buffer, ULONG Length);
@ -114,7 +117,7 @@ void MEMORY_WRITE_BREAKPOINT4(unsigned long addr);
#define UNIMPLEMENTED #define UNIMPLEMENTED
#define DebugInit(FrLdrSectionId) #define DebugInit(DebugString)
#define BugCheck(fmt, ...) #define BugCheck(fmt, ...)
#define DbgDumpBuffer(mask, buf, len) #define DbgDumpBuffer(mask, buf, len)
#define DebugDisableScreenPort() #define DebugDisableScreenPort()

View file

@ -29,6 +29,5 @@ typedef struct tagOperatingSystemItem
OperatingSystemItem* OperatingSystemItem*
InitOperatingSystemList( InitOperatingSystemList(
IN ULONG_PTR FrLdrSectionId, _Out_ PULONG OperatingSystemCount,
OUT PULONG OperatingSystemCount, _Out_ PULONG DefaultOperatingSystem);
OUT PULONG DefaultOperatingSystem);

View file

@ -1,28 +1,24 @@
/* /*
* FreeLdr boot loader * PROJECT: FreeLoader
* Copyright (C) 2002, 2003 ReactOS Team * LICENSE: MIT (https://spdx.org/licenses/MIT)
* * PURPOSE: Command-line parsing and global settings management
* This program is free software; you can redistribute it and/or modify * COPYRIGHT: Copyright 2024 Hermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
#pragma once #pragma once
VOID CmdLineParse(IN PCSTR CmdLine); typedef struct _BOOTMGRINFO
{
PCSTR DebugString;
PCSTR DefaultOs;
LONG TimeOut;
ULONG_PTR FrLdrSection;
} BOOTMGRINFO, *PBOOTMGRINFO;
PCSTR CmdLineGetDebugString(VOID); extern BOOTMGRINFO BootMgrInfo;
PCSTR CmdLineGetDefaultOS(VOID);
LONG CmdLineGetTimeOut(VOID); VOID
LoadSettings(
_In_opt_ PCSTR CmdLine);
/* EOF */ /* EOF */

View file

@ -59,11 +59,14 @@ VOID
ARMWriteToUART(UCHAR Data); ARMWriteToUART(UCHAR Data);
#endif #endif
VOID DebugInit(IN ULONG_PTR FrLdrSectionId) VOID
DebugInit(
_In_ PCSTR DebugString)
{ {
PCHAR CommandLine, PortString, BaudString, IrqString; static BOOLEAN Initialized = FALSE;
PSTR CommandLine, PortString, BaudString, IrqString;
ULONG Value; ULONG Value;
CHAR DebugString[256]; CHAR DbgStringBuffer[256];
/* Always reset the debugging channels */ /* Always reset the debugging channels */
@ -87,29 +90,20 @@ VOID DebugInit(IN ULONG_PTR FrLdrSectionId)
DbgChannels[DPRINT_WINDOWS] = MAX_LEVEL; DbgChannels[DPRINT_WINDOWS] = MAX_LEVEL;
#endif #endif
/* Check for pre- or main initialization phase */ CommandLine = NULL;
if (FrLdrSectionId == 0) if (!DebugString || !*DebugString)
{ {
/* Pre-initialization phase: use the FreeLdr command-line debugging string */ /* No command-line is provided: during pre-initialization,
CommandLine = (PCHAR)CmdLineGetDebugString(); * initialize the debug port with default settings;
* otherwise just return during main initialization */
/* If no command-line is provided, initialize the debug port with default settings */ if (!Initialized)
if (CommandLine == NULL)
goto Done; goto Done;
return;
strcpy(DebugString, CommandLine);
}
else
{
/* Main initialization phase: use the FreeLdr INI debugging string */
if (!IniReadSettingByName(FrLdrSectionId, "Debug", DebugString, sizeof(DebugString)))
{
return;
}
} }
/* Get the Command Line */ /* Get a copy of the command-line */
CommandLine = DebugString; strcpy(DbgStringBuffer, DebugString);
CommandLine = DbgStringBuffer;
/* Upcase it */ /* Upcase it */
_strupr(CommandLine); _strupr(CommandLine);
@ -193,6 +187,8 @@ VOID DebugInit(IN ULONG_PTR FrLdrSectionId)
} }
Done: Done:
Initialized = TRUE;
/* Try to initialize the port; if it fails, remove the corresponding flag */ /* Try to initialize the port; if it fails, remove the corresponding flag */
if (DebugPort & RS232) if (DebugPort & RS232)
{ {

View file

@ -44,15 +44,12 @@ static PCSTR CopyString(PCSTR Source)
OperatingSystemItem* OperatingSystemItem*
InitOperatingSystemList( InitOperatingSystemList(
IN ULONG_PTR FrLdrSectionId, _Out_ PULONG OperatingSystemCount,
OUT PULONG OperatingSystemCount, _Out_ PULONG DefaultOperatingSystem)
OUT PULONG DefaultOperatingSystem)
{ {
ULONG DefaultOS = 0;
PCSTR DefaultOSName = NULL;
CHAR DefaultOSText[80];
OperatingSystemItem* Items; OperatingSystemItem* Items;
PCSTR DefaultOSName;
ULONG DefaultOS = 0;
ULONG Count; ULONG Count;
ULONG i; ULONG i;
ULONG_PTR OsSectionId, SectionId; ULONG_PTR OsSectionId, SectionId;
@ -63,7 +60,7 @@ InitOperatingSystemList(
CHAR SettingName[260]; CHAR SettingName[260];
CHAR SettingValue[260]; CHAR SettingValue[260];
CHAR BootType[80]; CHAR BootType[80];
CHAR TempBuffer[sizeof(SettingValue)/sizeof(CHAR)]; CHAR TempBuffer[_countof(SettingValue)];
/* Open the [Operating Systems] section */ /* Open the [Operating Systems] section */
if (!IniOpenSection("Operating Systems", &OsSectionId)) if (!IniOpenSection("Operating Systems", &OsSectionId))
@ -77,16 +74,8 @@ InitOperatingSystemList(
if (!Items) if (!Items)
return NULL; return NULL;
/* Retrieve which OS is the default one */ /* Retrieve the default OS */
DefaultOSName = CmdLineGetDefaultOS(); DefaultOSName = BootMgrInfo.DefaultOs;
if (!DefaultOSName || !*DefaultOSName)
{
if ((FrLdrSectionId != 0) &&
IniReadSettingByName(FrLdrSectionId, "DefaultOS", DefaultOSText, sizeof(DefaultOSText)))
{
DefaultOSName = DefaultOSText;
}
}
/* Now loop through the operating system section and load each item */ /* Now loop through the operating system section and load each item */
for (i = 0; i < Count; ++i) for (i = 0; i < Count; ++i)

View file

@ -1,9 +1,10 @@
/* /*
* PROJECT: ReactOS Boot Loader * PROJECT: FreeLoader
* LICENSE: BSD - See COPYING.ARM in the top level directory * LICENSE: BSD - See COPYING.ARM in the top level directory
* FILE: boot/freeldr/freeldr/cmdline.c * or MIT (https://spdx.org/licenses/MIT)
* PURPOSE: FreeLDR Command Line Parsing * PURPOSE: Command-line parsing and global settings management
* PROGRAMMERS: ReactOS Portable Systems Group * COPYRIGHT: Copyright 2008-2010 ReactOS Portable Systems Group <ros.arm@reactos.org>
* Copyright 2015-2024 Hermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
*/ */
/* INCLUDES *******************************************************************/ /* INCLUDES *******************************************************************/
@ -12,32 +13,27 @@
/* GLOBALS ********************************************************************/ /* GLOBALS ********************************************************************/
typedef struct tagCMDLINEINFO static CCHAR DebugString[256];
{ static CCHAR DefaultOs[256];
PCSTR DebugString; BOOTMGRINFO BootMgrInfo = {0};
PCSTR DefaultOs;
LONG TimeOut;
} CMDLINEINFO, *PCMDLINEINFO;
CCHAR DebugString[256];
CCHAR DefaultOs[256];
CMDLINEINFO CmdLineInfo;
/* FUNCTIONS ******************************************************************/ /* FUNCTIONS ******************************************************************/
VOID static VOID
CmdLineParse(IN PCSTR CmdLine) CmdLineParse(
_In_ PCSTR CmdLine)
{ {
PCHAR End, Setting; PCHAR End, Setting;
ULONG_PTR Length, Offset = 0; ULONG_PTR Length, Offset = 0;
/* Set defaults */ /* Set defaults */
CmdLineInfo.DebugString = NULL; BootMgrInfo.DebugString = NULL;
CmdLineInfo.DefaultOs = NULL; BootMgrInfo.DefaultOs = NULL;
CmdLineInfo.TimeOut = -1; BootMgrInfo.TimeOut = -1;
// BootMgrInfo.FrLdrSection = 0;
/* /*
* Get debug string, in the following format: * Get the debug string, in the following format:
* "debug=option1=XXX;option2=YYY;..." * "debug=option1=XXX;option2=YYY;..."
* and translate it into the format: * and translate it into the format:
* "OPTION1=XXX OPTION2=YYY ..." * "OPTION1=XXX OPTION2=YYY ..."
@ -62,18 +58,18 @@ CmdLineParse(IN PCSTR CmdLine)
Setting++; Setting++;
} }
CmdLineInfo.DebugString = DebugString; BootMgrInfo.DebugString = DebugString;
} }
/* Get timeout */ /* Get the timeout */
Setting = strstr(CmdLine, "timeout="); Setting = strstr(CmdLine, "timeout=");
if (Setting) if (Setting)
{ {
CmdLineInfo.TimeOut = atoi(Setting + BootMgrInfo.TimeOut = atoi(Setting +
sizeof("timeout=") - sizeof(ANSI_NULL)); sizeof("timeout=") - sizeof(ANSI_NULL));
} }
/* Get default OS */ /* Get the default OS */
Setting = strstr(CmdLine, "defaultos="); Setting = strstr(CmdLine, "defaultos=");
if (Setting) if (Setting)
{ {
@ -84,10 +80,10 @@ CmdLineParse(IN PCSTR CmdLine)
/* Copy the default OS */ /* Copy the default OS */
RtlStringCbCopyNA(DefaultOs, sizeof(DefaultOs), Setting, Length); RtlStringCbCopyNA(DefaultOs, sizeof(DefaultOs), Setting, Length);
CmdLineInfo.DefaultOs = DefaultOs; BootMgrInfo.DefaultOs = DefaultOs;
} }
/* Get ramdisk base address */ /* Get the ramdisk base address */
Setting = strstr(CmdLine, "rdbase="); Setting = strstr(CmdLine, "rdbase=");
if (Setting) if (Setting)
{ {
@ -97,7 +93,7 @@ CmdLineParse(IN PCSTR CmdLine)
NULL, 0); NULL, 0);
} }
/* Get ramdisk size */ /* Get the ramdisk size */
Setting = strstr(CmdLine, "rdsize="); Setting = strstr(CmdLine, "rdsize=");
if (Setting) if (Setting)
{ {
@ -106,7 +102,7 @@ CmdLineParse(IN PCSTR CmdLine)
NULL, 0); NULL, 0);
} }
/* Get ramdisk offset */ /* Get the ramdisk offset */
Setting = strstr(CmdLine, "rdoffset="); Setting = strstr(CmdLine, "rdoffset=");
if (Setting) if (Setting)
{ {
@ -119,20 +115,60 @@ CmdLineParse(IN PCSTR CmdLine)
gInitRamDiskBase = (PVOID)((ULONG_PTR)gInitRamDiskBase + Offset); gInitRamDiskBase = (PVOID)((ULONG_PTR)gInitRamDiskBase + Offset);
} }
PCSTR VOID
CmdLineGetDebugString(VOID) LoadSettings(
_In_opt_ PCSTR CmdLine)
{ {
return CmdLineInfo.DebugString; /* Pre-initialization: The settings originate from the command-line.
* Main initialization: Overwrite them if needed with those from freeldr.ini */
if (CmdLine)
{
CmdLineParse(CmdLine);
return;
}
else if (IsListEmpty(&IniFileSectionListHead))
{
// ERR("LoadSettings() called but no freeldr.ini\n");
return;
}
/* Open the [FreeLoader] section and load the settings */
if ((BootMgrInfo.FrLdrSection == 0) &&
!IniOpenSection("FreeLoader", &BootMgrInfo.FrLdrSection))
{
UiMessageBoxCritical("Section [FreeLoader] not found in freeldr.ini");
return;
}
/* Get the debug string. Always override it with the one from freeldr.ini */
if (IniReadSettingByName(BootMgrInfo.FrLdrSection, "Debug",
DebugString, sizeof(DebugString)))
{
BootMgrInfo.DebugString = DebugString;
}
/* Get the timeout. Keep the existing one if it is valid,
* otherwise retrieve it from freeldr.ini */
if (BootMgrInfo.TimeOut < 0)
{
CHAR TimeOutText[20];
BootMgrInfo.TimeOut = -1;
if (IniReadSettingByName(BootMgrInfo.FrLdrSection, "TimeOut",
TimeOutText, sizeof(TimeOutText)))
{
BootMgrInfo.TimeOut = atoi(TimeOutText);
}
}
/* Get the default OS */
if (!BootMgrInfo.DefaultOs || !*BootMgrInfo.DefaultOs)
{
if (IniReadSettingByName(BootMgrInfo.FrLdrSection, "DefaultOS",
DefaultOs, sizeof(DefaultOs)))
{
BootMgrInfo.DefaultOs = DefaultOs;
}
}
} }
PCSTR /* EOF */
CmdLineGetDefaultOS(VOID)
{
return CmdLineInfo.DefaultOs;
}
LONG
CmdLineGetTimeOut(VOID)
{
return CmdLineInfo.TimeOut;
}