[FREELDR] Add "Edit Boot Command Line" feature. (#1763)

CORE-9023 CORE-16260

Co-authored-by: Hermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
This commit is contained in:
Yaroslav Kibysh 2019-07-28 20:23:41 +03:00 committed by Hermès Bélusca-Maïto
parent 5d5b6a5600
commit b34d516e81
No known key found for this signature in database
GPG key ID: 3B2539C65E7B93D0
6 changed files with 233 additions and 73 deletions

View file

@ -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 },
{"Drive" , EditCustomBootDisk , LoadAndBootDrive },
{"Partition" , EditCustomBootPartition , LoadAndBootPartition },
{"BootSector" , EditCustomBootSectorFile, LoadAndBootBootSector},
{"Linux" , LoadAndBootLinux },
{"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)

View file

@ -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,30 +211,46 @@ 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, 20))
if (!UiEditBox(BootPartitionPrompt, BootPartitionString, sizeof(BootPartitionString)))
return;
if (!UiEditBox(BootSectorFilePrompt, BootSectorFileString, 200))
if (!UiEditBox(BootSectorFilePrompt, BootSectorFileString, sizeof(BootSectorFileString)))
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, "BootSectorFile", BootSectorFileString);
return;
}
/* Generate a unique section name */
TimeInfo = ArcGetTime();
RtlStringCbPrintfA(SectionName, sizeof(SectionName),
@ -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))
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 (SectionId == 0)
{
if (!UiEditBox(BootDrivePrompt, BootDriveString, sizeof(BootDriveString)))
return;
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(BootPartitionPrompt, BootPartitionString, 20))
return;
if (!UiEditBox(ReactOSSystemPathPrompt, ReactOSSystemPath, 200))
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

View file

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

View file

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

View file

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

View file

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