From bf26ae38a54e7bfc5d93916c395ce030bde028ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Sat, 4 Apr 2026 21:30:16 +0200 Subject: [PATCH] [FREELDR] Make FreeLoader a bit more usable even if FREELDR.INI is missing CORE-9023 In case FREELDR.INI is missing, or there are no operating systems listed and available (either the corresponding section is missing, or is empty), fall back to the FreeLoader Setup and Configuration F2 menu, that allows performing a minimal number of operations (enabling FreeLoader debugging; doing a custom boot... and more to come!) Fix also a bug in `InitOperatingSystemList()`, that would allow allocating an empty list with zero items. Now it returns NULL if no operating systems are found. Default to the Minimal text UI instead of the fullfledged one, if no "MinimalUI" option can be found in FREELDR.INI (or if the INI is missing). --- boot/freeldr/freeldr/bootmgr.c | 41 +++++++++++--------------- boot/freeldr/freeldr/include/options.h | 2 +- boot/freeldr/freeldr/options.c | 7 +++-- boot/freeldr/freeldr/oslist.c | 8 +++++ boot/freeldr/freeldr/settings.c | 5 ++-- boot/freeldr/freeldr/ui/ui.c | 2 +- 6 files changed, 34 insertions(+), 31 deletions(-) diff --git a/boot/freeldr/freeldr/bootmgr.c b/boot/freeldr/freeldr/bootmgr.c index f73aa7f621b..9157efdc903 100644 --- a/boot/freeldr/freeldr/bootmgr.c +++ b/boot/freeldr/freeldr/bootmgr.c @@ -395,63 +395,53 @@ VOID RunLoader(VOID) #ifndef UEFIBOOT /* Load additional SCSI driver (if any) */ if (LoadBootDeviceDriver() != ESUCCESS) - { UiMessageBoxCritical("Unable to load additional boot device drivers."); - } #endif #endif /* Open FREELDR.INI and load the global FreeLoader settings */ if (!IniFileInitialize()) - { UiMessageBoxCritical("Error initializing .ini file."); - return; - } LoadSettings(NULL); #if 0 if (FALSE) - { UiMessageBoxCritical("Could not load global FreeLoader settings."); - return; - } #endif /* Debugger main initialization */ DebugInit(GetBootMgrInfo()->DebugString); - /* UI main initialization */ + /* UI main initialization. If it fails, fall back to default UI. */ if (!UiInitialize(TRUE)) - { UiMessageBoxCritical("Unable to initialize UI."); - return; - } + /* If no FREELDR.INI, skip everything else and fall back to the FreeLdr setup menu */ + if (IsListEmpty(IniGetFileSectionListHead())) + goto Fallback; + + /* Find all the message box settings and run them */ + UiShowMessageBoxesInSection(GetBootMgrInfo()->FrLdrSection); + + /* Retrieve the list of boot entries */ OperatingSystemList = InitOperatingSystemList(&OperatingSystemCount, &SelectedOperatingSystem); if (!OperatingSystemList) { - UiMessageBox("Unable to read operating systems section in freeldr.ini.\nPress ENTER to reboot."); - goto Reboot; - } - if (OperatingSystemCount == 0) - { - UiMessageBox("There were no operating systems listed in freeldr.ini.\nPress ENTER to reboot."); - goto Reboot; + UiMessageBox("There are no operating systems listed in freeldr.ini."); + goto Fallback; } + ASSERT(OperatingSystemCount != 0); /* Create list of display names */ OperatingSystemDisplayNames = FrLdrTempAlloc(sizeof(PCSTR) * OperatingSystemCount, 'mNSO'); if (!OperatingSystemDisplayNames) - goto Reboot; + goto Fallback; for (i = 0; i < OperatingSystemCount; i++) { OperatingSystemDisplayNames[i] = OperatingSystemList[i].LoadIdentifier; } - /* Find all the message box settings and run them */ - UiShowMessageBoxesInSection(GetBootMgrInfo()->FrLdrSection); - for (;;) { /* Redraw the backdrop, but don't overwrite boot options */ @@ -489,6 +479,11 @@ VOID RunLoader(VOID) UiInitialize(TRUE); } +Fallback: + /* Fall back to the FreeLdr setup menu */ + FreeLdrSetupMenu(NULL); + UiMessageBox("The system will now reboot."); + Reboot: UiUnInitialize("Rebooting..."); IniCleanup(); diff --git a/boot/freeldr/freeldr/include/options.h b/boot/freeldr/freeldr/include/options.h index ebc2bfe023b..00eef427647 100644 --- a/boot/freeldr/freeldr/include/options.h +++ b/boot/freeldr/freeldr/include/options.h @@ -9,7 +9,7 @@ VOID FreeLdrSetupMenu( - _In_ OperatingSystemItem* OperatingSystem); + _In_opt_ OperatingSystemItem* OperatingSystem); VOID DisplayBootTimeOptions( diff --git a/boot/freeldr/freeldr/options.c b/boot/freeldr/freeldr/options.c index 2c2c683fa79..db5edacfb93 100644 --- a/boot/freeldr/freeldr/options.c +++ b/boot/freeldr/freeldr/options.c @@ -51,7 +51,7 @@ static PCSTR FrldrDbgMsg = VOID FreeLdrSetupMenu( - _In_ OperatingSystemItem* OperatingSystem) + _In_opt_ OperatingSystemItem* OperatingSystem) { ULONG SelectedMenuItem = 0; @@ -60,7 +60,7 @@ doMenu: UiDrawBackdrop(UiGetScreenHeight()); if (!UiDisplayMenu(VERSION " Setup and Configuration", - NULL, + OperatingSystem ? NULL : "Press ESC to reboot.", OptionsMenuList, RTL_NUMBER_OF(OptionsMenuList), SelectedMenuItem, -1, @@ -90,7 +90,8 @@ doMenu: // break; #ifdef HAS_OPTION_MENU_EDIT_CMDLINE case 2: // Edit command line - EditOperatingSystemEntry(OperatingSystem); + if (OperatingSystem) + EditOperatingSystemEntry(OperatingSystem); break; #endif #ifdef HAS_OPTION_MENU_CUSTOM_BOOT diff --git a/boot/freeldr/freeldr/oslist.c b/boot/freeldr/freeldr/oslist.c index d38d7f8aa33..a03829322ad 100644 --- a/boot/freeldr/freeldr/oslist.c +++ b/boot/freeldr/freeldr/oslist.c @@ -62,12 +62,20 @@ InitOperatingSystemList( CHAR BootType[80]; CHAR TempBuffer[_countof(SettingValue)]; + /* Default with an empty list */ + *OperatingSystemCount = 0; + /* Open the [Operating Systems] section */ if (!IniOpenSection("Operating Systems", &OsSectionId)) + { + UiMessageBox("Operating Systems section not found in freeldr.ini"); return NULL; + } /* Count the number of operating systems in the section */ Count = IniGetNumSectionItems(OsSectionId); + if (Count == 0) /* Fail if no operating systems are found */ + return NULL; /* Allocate memory to hold operating system lists */ Items = FrLdrHeapAlloc(Count * sizeof(OperatingSystemItem), TAG_OS_ITEM); diff --git a/boot/freeldr/freeldr/settings.c b/boot/freeldr/freeldr/settings.c index 0c0d8b05148..e45ef40c75f 100644 --- a/boot/freeldr/freeldr/settings.c +++ b/boot/freeldr/freeldr/settings.c @@ -163,7 +163,7 @@ LoadSettings( * If a section is already loaded, skip further checks. */ if (!BootMgrInfo.FrLdrSection) { - for (ULONG i = 0; i < sizeof(LoaderSections) / sizeof(LoaderSections[0]); i++) + for (ULONG i = 0; i < RTL_NUMBER_OF(LoaderSections); ++i) { PCSTR Section = LoaderSections[i]; @@ -173,10 +173,9 @@ LoadSettings( break; } } - if (!FoundLoaderSection) { - UiMessageBoxCritical("Bootloader Section not found in freeldr.ini"); + UiMessageBoxCritical("Bootloader section not found in freeldr.ini"); return; } } diff --git a/boot/freeldr/freeldr/ui/ui.c b/boot/freeldr/freeldr/ui/ui.c index 946b49f4354..3624cdaa462 100644 --- a/boot/freeldr/freeldr/ui/ui.c +++ b/boot/freeldr/freeldr/ui/ui.c @@ -92,7 +92,7 @@ UIVTBL UiVtbl = BOOLEAN UiInitialize(BOOLEAN ShowUi) { VIDEODISPLAYMODE UiDisplayMode; // Tells us if we are in text or graphics mode - BOOLEAN UiMinimal = FALSE; // Tells us if we are using a minimal console-like UI + BOOLEAN UiMinimal = TRUE; // Tells us if we are using a minimal console-like UI ULONG_PTR SectionId; ULONG Depth; CHAR SettingText[260];