https://git.reactos.org/?p=reactos.git;a=commitdiff;h=b34d516e814b841de4c54…
commit b34d516e814b841de4c54d85c31c1ce9b8d1829c
Author: Yaroslav Kibysh <yanet.prod(a)gmail.com>
AuthorDate: Sun Jul 28 20:23:41 2019 +0300
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Wed Aug 7 18:50:23 2019 +0200
[FREELDR] Add "Edit Boot Command Line" feature. (#1763)
CORE-9023 CORE-16260
Co-authored-by: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
---
boot/freeldr/freeldr/bootmgr.c | 77 +++++++++++---
boot/freeldr/freeldr/custom.c | 178 +++++++++++++++++++++++++--------
boot/freeldr/freeldr/include/custom.h | 24 +++--
boot/freeldr/freeldr/include/freeldr.h | 3 +
boot/freeldr/freeldr/include/options.h | 6 +-
boot/freeldr/freeldr/options.c | 14 ++-
6 files changed, 231 insertions(+), 71 deletions(-)
diff --git a/boot/freeldr/freeldr/bootmgr.c b/boot/freeldr/freeldr/bootmgr.c
index 756f74e69dd..d0ce314bb46 100644
--- a/boot/freeldr/freeldr/bootmgr.c
+++ b/boot/freeldr/freeldr/bootmgr.c
@@ -26,25 +26,30 @@ DBG_DEFAULT_CHANNEL(INIFILE);
/* GLOBALS ********************************************************************/
+typedef
+VOID
+(*EDIT_OS_ENTRY_PROC)(
+ IN ULONG_PTR SectionId OPTIONAL);
+
static const struct
{
PCSTR BootType;
+ EDIT_OS_ENTRY_PROC EditOsEntry;
ARC_ENTRY_POINT OsLoader;
} OSLoadingMethods[] =
{
- {"ReactOSSetup", LoadReactOSSetup },
+ {"ReactOSSetup", EditCustomBootReactOS, LoadReactOSSetup},
#ifdef _M_IX86
- {"BootSector" , LoadAndBootBootSector},
- {"Drive" , LoadAndBootDrive },
- {"Partition" , LoadAndBootPartition },
-
- {"Linux" , LoadAndBootLinux },
+ {"Drive" , EditCustomBootDisk , LoadAndBootDrive },
+ {"Partition" , EditCustomBootPartition , LoadAndBootPartition },
+ {"BootSector" , EditCustomBootSectorFile, LoadAndBootBootSector},
- {"Windows" , LoadAndBootWindows },
- {"WindowsNT40" , LoadAndBootWindows },
+ {"Linux" , EditCustomBootLinux , LoadAndBootLinux },
+ {"WindowsNT40" , EditCustomBootReactOS, LoadAndBootWindows},
#endif
- {"Windows2003" , LoadAndBootWindows },
+ {"Windows" , EditCustomBootReactOS, LoadAndBootWindows},
+ {"Windows2003" , EditCustomBootReactOS, LoadAndBootWindows},
};
/* FUNCTIONS ******************************************************************/
@@ -185,6 +190,42 @@ VOID LoadOperatingSystem(IN OperatingSystemItem* OperatingSystem)
}
}
+#ifdef HAS_OPTION_MENU_EDIT_CMDLINE
+
+VOID EditOperatingSystemEntry(IN OperatingSystemItem* OperatingSystem)
+{
+ ULONG_PTR SectionId;
+ PCSTR SectionName = OperatingSystem->SectionName;
+ ULONG i;
+ CHAR BootType[80];
+
+ /* Try to open the operating system section in the .ini file */
+ if (!IniOpenSection(SectionName, &SectionId))
+ {
+ UiMessageBox("Section [%s] not found in freeldr.ini.", SectionName);
+ return;
+ }
+
+ /* Try to read the boot type */
+ *BootType = ANSI_NULL;
+ IniReadSettingByName(SectionId, "BootType", BootType, sizeof(BootType));
+
+ /* We must have the "BootType" value (it has been possibly added by
InitOperatingSystemList()) */
+ ASSERT(*BootType);
+
+ /* Loop through the OS loading method table and find a suitable OS entry editor */
+ for (i = 0; i < sizeof(OSLoadingMethods) / sizeof(OSLoadingMethods[0]); ++i)
+ {
+ if (_stricmp(BootType, OSLoadingMethods[i].BootType) == 0)
+ {
+ OSLoadingMethods[i].EditOsEntry(SectionId);
+ return;
+ }
+ }
+}
+
+#endif // HAS_OPTION_MENU_EDIT_CMDLINE
+
LONG GetTimeOut(VOID)
{
CHAR TimeOutText[20];
@@ -212,14 +253,22 @@ MainBootMenuKeyPressFilter(
IN ULONG SelectedMenuItem,
IN PVOID Context OPTIONAL)
{
- if (KeyPress == KEY_F8)
+ switch (KeyPress)
{
- DoOptionsMenu();
+ case KEY_F8:
+ DoOptionsMenu(&((OperatingSystemItem*)Context)[SelectedMenuItem]);
return TRUE;
- }
- /* We didn't handle the key */
- return FALSE;
+#ifdef HAS_OPTION_MENU_EDIT_CMDLINE
+ case KEY_F10:
+
EditOperatingSystemEntry(&((OperatingSystemItem*)Context)[SelectedMenuItem]);
+ return TRUE;
+#endif
+
+ default:
+ /* We didn't handle the key */
+ return FALSE;
+ }
}
VOID RunLoader(VOID)
diff --git a/boot/freeldr/freeldr/custom.c b/boot/freeldr/freeldr/custom.c
index 0ef5f5af160..319cbcd61a7 100644
--- a/boot/freeldr/freeldr/custom.c
+++ b/boot/freeldr/freeldr/custom.c
@@ -40,6 +40,8 @@ const CHAR CustomBootPrompt[] = "Press ENTER to boot your custom
boot setup.";
/* FUNCTIONS ******************************************************************/
+#ifdef HAS_OPTION_MENU_CUSTOM_BOOT
+
VOID OptionMenuCustomBoot(VOID)
{
PCSTR CustomBootMenuList[] = {
@@ -70,42 +72,56 @@ VOID OptionMenuCustomBoot(VOID)
{
#ifdef _M_IX86
case 0: // Disk
- OptionMenuCustomBootDisk();
+ EditCustomBootDisk(0);
break;
case 1: // Partition
- OptionMenuCustomBootPartition();
+ EditCustomBootPartition(0);
break;
case 2: // Boot Sector File
- OptionMenuCustomBootBootSectorFile();
+ EditCustomBootSectorFile(0);
break;
case 3: // Linux
- OptionMenuCustomBootLinux();
+ EditCustomBootLinux(0);
break;
case 4: // ReactOS
#else
case 0:
#endif
- OptionMenuCustomBootReactOS();
+ EditCustomBootReactOS(0);
break;
}
}
+#endif // HAS_OPTION_MENU_CUSTOM_BOOT
+
#ifdef _M_IX86
-VOID OptionMenuCustomBootDisk(VOID)
+VOID EditCustomBootDisk(IN ULONG_PTR SectionId OPTIONAL)
{
- ULONG_PTR SectionId;
- CHAR SectionName[100];
- CHAR BootDriveString[20];
TIMEINFO* TimeInfo;
OperatingSystemItem OperatingSystem;
+ CHAR SectionName[100];
+ CHAR BootDriveString[20];
RtlZeroMemory(SectionName, sizeof(SectionName));
RtlZeroMemory(BootDriveString, sizeof(BootDriveString));
- if (!UiEditBox(BootDrivePrompt, BootDriveString, 20))
+ if (SectionId != 0)
+ {
+ /* Load the settings */
+ IniReadSettingByName(SectionId, "BootDrive", BootDriveString,
sizeof(BootDriveString));
+ }
+
+ if (!UiEditBox(BootDrivePrompt, BootDriveString, sizeof(BootDriveString)))
return;
+ /* Modify the settings values and return if we were in edit mode */
+ if (SectionId != 0)
+ {
+ IniModifySettingValue(SectionId, "BootDrive", BootDriveString);
+ return;
+ }
+
/* Generate a unique section name */
TimeInfo = ArcGetTime();
RtlStringCbPrintfA(SectionName, sizeof(SectionName),
@@ -132,25 +148,39 @@ VOID OptionMenuCustomBootDisk(VOID)
LoadOperatingSystem(&OperatingSystem);
}
-VOID OptionMenuCustomBootPartition(VOID)
+VOID EditCustomBootPartition(IN ULONG_PTR SectionId OPTIONAL)
{
- ULONG_PTR SectionId;
+ TIMEINFO* TimeInfo;
+ OperatingSystemItem OperatingSystem;
CHAR SectionName[100];
CHAR BootDriveString[20];
CHAR BootPartitionString[20];
- TIMEINFO* TimeInfo;
- OperatingSystemItem OperatingSystem;
RtlZeroMemory(SectionName, sizeof(SectionName));
RtlZeroMemory(BootDriveString, sizeof(BootDriveString));
RtlZeroMemory(BootPartitionString, sizeof(BootPartitionString));
- if (!UiEditBox(BootDrivePrompt, BootDriveString, 20))
+ if (SectionId != 0)
+ {
+ /* Load the settings */
+ IniReadSettingByName(SectionId, "BootDrive", BootDriveString,
sizeof(BootDriveString));
+ IniReadSettingByName(SectionId, "BootPartition", BootPartitionString,
sizeof(BootPartitionString));
+ }
+
+ if (!UiEditBox(BootDrivePrompt, BootDriveString, sizeof(BootDriveString)))
return;
- if (!UiEditBox(BootPartitionPrompt, BootPartitionString, 20))
+ if (!UiEditBox(BootPartitionPrompt, BootPartitionString,
sizeof(BootPartitionString)))
return;
+ /* Modify the settings values and return if we were in edit mode */
+ if (SectionId != 0)
+ {
+ IniModifySettingValue(SectionId, "BootDrive", BootDriveString);
+ IniModifySettingValue(SectionId, "BootPartition",
BootPartitionString);
+ return;
+ }
+
/* Generate a unique section name */
TimeInfo = ArcGetTime();
RtlStringCbPrintfA(SectionName, sizeof(SectionName),
@@ -181,29 +211,45 @@ VOID OptionMenuCustomBootPartition(VOID)
LoadOperatingSystem(&OperatingSystem);
}
-VOID OptionMenuCustomBootBootSectorFile(VOID)
+VOID EditCustomBootSectorFile(IN ULONG_PTR SectionId OPTIONAL)
{
- ULONG_PTR SectionId;
+ TIMEINFO* TimeInfo;
+ OperatingSystemItem OperatingSystem;
CHAR SectionName[100];
CHAR BootDriveString[20];
CHAR BootPartitionString[20];
CHAR BootSectorFileString[200];
- TIMEINFO* TimeInfo;
- OperatingSystemItem OperatingSystem;
RtlZeroMemory(SectionName, sizeof(SectionName));
RtlZeroMemory(BootDriveString, sizeof(BootDriveString));
RtlZeroMemory(BootPartitionString, sizeof(BootPartitionString));
RtlZeroMemory(BootSectorFileString, sizeof(BootSectorFileString));
- if (!UiEditBox(BootDrivePrompt, BootDriveString, 20))
+ if (SectionId != 0)
+ {
+ /* Load the settings */
+ IniReadSettingByName(SectionId, "BootDrive", BootDriveString,
sizeof(BootDriveString));
+ IniReadSettingByName(SectionId, "BootPartition", BootPartitionString,
sizeof(BootPartitionString));
+ IniReadSettingByName(SectionId, "BootSectorFile", BootSectorFileString,
sizeof(BootSectorFileString));
+ }
+
+ if (!UiEditBox(BootDrivePrompt, BootDriveString, sizeof(BootDriveString)))
+ return;
+
+ if (!UiEditBox(BootPartitionPrompt, BootPartitionString,
sizeof(BootPartitionString)))
return;
- if (!UiEditBox(BootPartitionPrompt, BootPartitionString, 20))
+ if (!UiEditBox(BootSectorFilePrompt, BootSectorFileString,
sizeof(BootSectorFileString)))
return;
- if (!UiEditBox(BootSectorFilePrompt, BootSectorFileString, 200))
+ /* Modify the settings values and return if we were in edit mode */
+ if (SectionId != 0)
+ {
+ IniModifySettingValue(SectionId, "BootDrive", BootDriveString);
+ IniModifySettingValue(SectionId, "BootPartition",
BootPartitionString);
+ IniModifySettingValue(SectionId, "BootSectorFile",
BootSectorFileString);
return;
+ }
/* Generate a unique section name */
TimeInfo = ArcGetTime();
@@ -239,17 +285,16 @@ VOID OptionMenuCustomBootBootSectorFile(VOID)
LoadOperatingSystem(&OperatingSystem);
}
-VOID OptionMenuCustomBootLinux(VOID)
+VOID EditCustomBootLinux(IN ULONG_PTR SectionId OPTIONAL)
{
- ULONG_PTR SectionId;
+ TIMEINFO* TimeInfo;
+ OperatingSystemItem OperatingSystem;
CHAR SectionName[100];
CHAR BootDriveString[20];
CHAR BootPartitionString[20];
CHAR LinuxKernelString[200];
CHAR LinuxInitrdString[200];
CHAR LinuxCommandLineString[200];
- TIMEINFO* TimeInfo;
- OperatingSystemItem OperatingSystem;
RtlZeroMemory(SectionName, sizeof(SectionName));
RtlZeroMemory(BootDriveString, sizeof(BootDriveString));
@@ -258,21 +303,42 @@ VOID OptionMenuCustomBootLinux(VOID)
RtlZeroMemory(LinuxInitrdString, sizeof(LinuxInitrdString));
RtlZeroMemory(LinuxCommandLineString, sizeof(LinuxCommandLineString));
- if (!UiEditBox(BootDrivePrompt, BootDriveString, 20))
+ if (SectionId != 0)
+ {
+ /* Load the settings */
+ IniReadSettingByName(SectionId, "BootDrive", BootDriveString,
sizeof(BootDriveString));
+ IniReadSettingByName(SectionId, "BootPartition", BootPartitionString,
sizeof(BootPartitionString));
+ IniReadSettingByName(SectionId, "Kernel", LinuxKernelString,
sizeof(LinuxKernelString));
+ IniReadSettingByName(SectionId, "Initrd", LinuxInitrdString,
sizeof(LinuxInitrdString));
+ IniReadSettingByName(SectionId, "CommandLine", LinuxCommandLineString,
sizeof(LinuxCommandLineString));
+ }
+
+ if (!UiEditBox(BootDrivePrompt, BootDriveString, sizeof(BootDriveString)))
return;
- if (!UiEditBox(BootPartitionPrompt, BootPartitionString, 20))
+ if (!UiEditBox(BootPartitionPrompt, BootPartitionString,
sizeof(BootPartitionString)))
return;
- if (!UiEditBox(LinuxKernelPrompt, LinuxKernelString, 200))
+ if (!UiEditBox(LinuxKernelPrompt, LinuxKernelString, sizeof(LinuxKernelString)))
return;
- if (!UiEditBox(LinuxInitrdPrompt, LinuxInitrdString, 200))
+ if (!UiEditBox(LinuxInitrdPrompt, LinuxInitrdString, sizeof(LinuxInitrdString)))
return;
- if (!UiEditBox(LinuxCommandLinePrompt, LinuxCommandLineString, 200))
+ if (!UiEditBox(LinuxCommandLinePrompt, LinuxCommandLineString,
sizeof(LinuxCommandLineString)))
return;
+ /* Modify the settings values and return if we were in edit mode */
+ if (SectionId != 0)
+ {
+ IniModifySettingValue(SectionId, "BootDrive", BootDriveString);
+ IniModifySettingValue(SectionId, "BootPartition",
BootPartitionString);
+ IniModifySettingValue(SectionId, "Kernel", LinuxKernelString);
+ IniModifySettingValue(SectionId, "Initrd", LinuxInitrdString);
+ IniModifySettingValue(SectionId, "CommandLine",
LinuxCommandLineString);
+ return;
+ }
+
/* Generate a unique section name */
TimeInfo = ArcGetTime();
RtlStringCbPrintfA(SectionName, sizeof(SectionName),
@@ -320,35 +386,59 @@ VOID OptionMenuCustomBootLinux(VOID)
#endif // _M_IX86
-VOID OptionMenuCustomBootReactOS(VOID)
+VOID EditCustomBootReactOS(IN ULONG_PTR SectionId OPTIONAL)
{
- ULONG_PTR SectionId;
+ TIMEINFO* TimeInfo;
+ OperatingSystemItem OperatingSystem;
CHAR SectionName[100];
CHAR BootDriveString[20];
CHAR BootPartitionString[20];
CHAR ReactOSSystemPath[200];
CHAR ReactOSARCPath[200];
CHAR ReactOSOptions[200];
- TIMEINFO* TimeInfo;
- OperatingSystemItem OperatingSystem;
RtlZeroMemory(SectionName, sizeof(SectionName));
RtlZeroMemory(BootDriveString, sizeof(BootDriveString));
RtlZeroMemory(BootPartitionString, sizeof(BootPartitionString));
RtlZeroMemory(ReactOSSystemPath, sizeof(ReactOSSystemPath));
+ RtlZeroMemory(ReactOSARCPath, sizeof(ReactOSARCPath));
RtlZeroMemory(ReactOSOptions, sizeof(ReactOSOptions));
- if (!UiEditBox(BootDrivePrompt, BootDriveString, 20))
- return;
+ if (SectionId != 0)
+ {
+ /* Load the settings */
+ // TODO? Maybe use DissectArcPath(CHAR *ArcPath, CHAR *BootPath, UCHAR*
BootDrive, ULONG* BootPartition) to get back to the small elements.
+ IniReadSettingByName(SectionId, "SystemPath", ReactOSARCPath,
sizeof(ReactOSARCPath));
+ IniReadSettingByName(SectionId, "Options", ReactOSOptions,
sizeof(ReactOSOptions));
+ }
- if (!UiEditBox(BootPartitionPrompt, BootPartitionString, 20))
- return;
+ if (SectionId == 0)
+ {
+ if (!UiEditBox(BootDrivePrompt, BootDriveString, sizeof(BootDriveString)))
+ return;
- if (!UiEditBox(ReactOSSystemPathPrompt, ReactOSSystemPath, 200))
+ if (!UiEditBox(BootPartitionPrompt, BootPartitionString,
sizeof(BootPartitionString)))
+ return;
+
+ if (!UiEditBox(ReactOSSystemPathPrompt, ReactOSSystemPath,
sizeof(ReactOSSystemPath)))
+ return;
+ }
+ else
+ {
+ if (!UiEditBox(ReactOSSystemPathPrompt, ReactOSARCPath, sizeof(ReactOSARCPath)))
+ return;
+ }
+
+ if (!UiEditBox(ReactOSOptionsPrompt, ReactOSOptions, sizeof(ReactOSOptions)))
return;
- if (!UiEditBox(ReactOSOptionsPrompt, ReactOSOptions, 200))
+ /* Modify the settings values and return if we were in edit mode */
+ if (SectionId != 0)
+ {
+ IniModifySettingValue(SectionId, "SystemPath", ReactOSARCPath);
+ IniModifySettingValue(SectionId, "Options", ReactOSOptions);
return;
+ }
/* Generate a unique section name */
TimeInfo = ArcGetTime();
@@ -383,6 +473,8 @@ VOID OptionMenuCustomBootReactOS(VOID)
LoadOperatingSystem(&OperatingSystem);
}
+#ifdef HAS_OPTION_MENU_REBOOT
+
VOID OptionMenuReboot(VOID)
{
UiMessageBox("The system will now reboot.");
@@ -392,3 +484,5 @@ VOID OptionMenuReboot(VOID)
#endif
Reboot();
}
+
+#endif // HAS_OPTION_MENU_REBOOT
diff --git a/boot/freeldr/freeldr/include/custom.h
b/boot/freeldr/freeldr/include/custom.h
index c139d532004..0bf8d680f32 100644
--- a/boot/freeldr/freeldr/include/custom.h
+++ b/boot/freeldr/freeldr/include/custom.h
@@ -19,19 +19,25 @@
#pragma once
-#ifdef _M_IX86
-
+#define HAS_OPTION_MENU_EDIT_CMDLINE
#define HAS_OPTION_MENU_CUSTOM_BOOT
#define HAS_OPTION_MENU_REBOOT
-VOID OptionMenuReboot(VOID);
+#ifdef _M_IX86
-VOID OptionMenuCustomBoot(VOID);
-VOID OptionMenuCustomBootDisk(VOID);
-VOID OptionMenuCustomBootPartition(VOID);
-VOID OptionMenuCustomBootBootSectorFile(VOID);
-VOID OptionMenuCustomBootLinux(VOID);
+VOID EditCustomBootDisk(IN ULONG_PTR SectionId OPTIONAL);
+VOID EditCustomBootPartition(IN ULONG_PTR SectionId OPTIONAL);
+VOID EditCustomBootSectorFile(IN ULONG_PTR SectionId OPTIONAL);
+VOID EditCustomBootLinux(IN ULONG_PTR SectionId OPTIONAL);
#endif // _M_IX86
-VOID OptionMenuCustomBootReactOS(VOID);
+#ifdef HAS_OPTION_MENU_CUSTOM_BOOT
+VOID OptionMenuCustomBoot(VOID);
+#endif
+
+VOID EditCustomBootReactOS(IN ULONG_PTR SectionId OPTIONAL);
+
+#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 d981dc2649a..0ef42e40595 100644
--- a/boot/freeldr/freeldr/include/freeldr.h
+++ b/boot/freeldr/freeldr/include/freeldr.h
@@ -126,6 +126,9 @@
VOID __cdecl BootMain(IN PCCH CmdLine);
VOID LoadOperatingSystem(IN OperatingSystemItem* OperatingSystem);
+#ifdef HAS_OPTION_MENU_EDIT_CMDLINE
+VOID EditOperatingSystemEntry(IN OperatingSystemItem* OperatingSystem);
+#endif
VOID RunLoader(VOID);
VOID FrLdrCheckCpuCompatibility(VOID);
diff --git a/boot/freeldr/freeldr/include/options.h
b/boot/freeldr/freeldr/include/options.h
index 5ff2a45f999..f7427798366 100644
--- a/boot/freeldr/freeldr/include/options.h
+++ b/boot/freeldr/freeldr/include/options.h
@@ -19,6 +19,6 @@
#pragma once
-VOID DoOptionsMenu(VOID);
-VOID DisplayBootTimeOptions(VOID);
-VOID AppendBootTimeOptions(PCHAR BootOptions);
+VOID DoOptionsMenu(IN OperatingSystemItem* OperatingSystem);
+VOID DisplayBootTimeOptions(VOID);
+VOID AppendBootTimeOptions(PCHAR BootOptions);
diff --git a/boot/freeldr/freeldr/options.c b/boot/freeldr/freeldr/options.c
index 701f8693893..ac302254bf5 100644
--- a/boot/freeldr/freeldr/options.c
+++ b/boot/freeldr/freeldr/options.c
@@ -42,6 +42,9 @@ PCSTR OptionsMenuList[] =
NULL,
"Start ReactOS normally",
+#ifdef HAS_OPTION_MENU_EDIT_CMDLINE
+ "Edit Boot Command Line (F10)",
+#endif
#ifdef HAS_OPTION_MENU_CUSTOM_BOOT
"Custom Boot",
#endif
@@ -86,7 +89,7 @@ static BOOLEAN DebuggingMode = FALSE;
/* FUNCTIONS ******************************************************************/
-VOID DoOptionsMenu(VOID)
+VOID DoOptionsMenu(IN OperatingSystemItem* OperatingSystem)
{
ULONG SelectedMenuItem;
CHAR DebugChannelString[100];
@@ -157,13 +160,18 @@ VOID DoOptionsMenu(VOID)
VgaMode = FALSE;
DebuggingMode = FALSE;
break;
+#ifdef HAS_OPTION_MENU_EDIT_CMDLINE
+ case 12: // Edit command line
+ EditOperatingSystemEntry(OperatingSystem);
+ break;
+#endif
#ifdef HAS_OPTION_MENU_CUSTOM_BOOT
- case 12: // Custom Boot
+ case 13: // Custom Boot
OptionMenuCustomBoot();
break;
#endif
#ifdef HAS_OPTION_MENU_REBOOT
- case 13: // Reboot
+ case 14: // Reboot
OptionMenuReboot();
break;
#endif