https://git.reactos.org/?p=reactos.git;a=commitdiff;h=bd451f240f2a1576aceb6…
commit bd451f240f2a1576aceb6f48b31ee49de917960b
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Sat Aug 31 00:49:37 2019 +0200
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Sat Aug 31 01:42:46 2019 +0200
[FREELDR] Code fixes and enhancements.
CORE-9023
FIXES:
======
- Fix parsing of the multiboot options string.
NOTE: They are not yet treated in a case-insensitive manner!
- Fix a bug in ArcOpen() so that it correctly skips the first path
separator (after the adapter-controller-peripheral ARC descriptors).
The path separator can be either a backslash or a slash (both are
allowed according to the specs); they were also already handled
correctly in other parts of the code.
- Fix DissectArcPath() so as to:
* **OPTIONALLY** (and not mandatorily!) return the path part that follows
the ARC adapter-controller-peripheral elements in the ARC path;
* make it correctly handle the (yes, optional!!) partition() part in the
ARC path, for the multi(x)disk(y)rdisk(z) cases.
ENHANCEMENTS:
=============
- Directly retrieve the default OS entry as we enumerate them and
build their list (i.e. merge the GetDefaultOperatingSystem() helper
within InitOperatingSystemList()).
- Directly use the opened 'FreeLoader' INI section via its ID in the
different functions that need it.
- Make the custom-boot and linux loaders honour the boot options they are
supposed to support (see FREELDR.INI documentation / template).
This includes the 'BootDrive' and 'BootPartition' (alternatively the
ARC
'BootPath').
This also allows them to take into account the user-specified choices in the
FreeLdr custom-boot editors.
- Modify the FreeLdr custom-boot editors so as to correctly honour
the priorities of the boot options as specified in the FREELDR.INI
documentation / template.
- Use stack trick (union of structs) to reduce stack usage in the
FreeLdr custom-boot editors, because there are strings buffers that are
used in an alternate manner.
- Extract out from the editors the LoadOperatingSystem() calls, and
move it back into OptionMenuCustomBoot(), so that when this latter
function is called there is no risk of having a stack almost full.
- When building the ARC-compatible argument vector for the loaders, add
the mandatory "SystemPartition" path. This allows the loaders to NOT
call the machine-specific MachDiskGetBootPath() later on (this data is
indeed passed to them by the boot manager part of FreeLdr).
- Improve the FsOpenFile() helper so as to make it:
* return an adequate ARC_STATUS instead of a mere uninformative BOOLEAN;
* take open options, as well as a default path (optional) that would be
prepended to the file name in case the latter is a relative one.
- Make RamDiskLoadVirtualFile() return an actual descriptive ARC_STATUS
value, and make it take an optional default path (same usage as the one
in FsOpenFile() ).
+ Remove useless NTAPI .
- UiInitialize() and TuiTextToColor(), TuiTextToFillStyle(): load or
convert named settings into corresponding values using setting table and
a tight for-loop, instead of duplicating 10x the same parameter reading
logic.
- UiInitialize(): Open the "Display" INI section just once. Remove usage
of DisplayModeText[] buffer.
- UiShowMessageBoxesInSection() and UiShowMessageBoxesInArgv(): reduce
code indentation level.
ENHANCEMENTS for NT OS loader:
==============================
- Don't use MachDiskGetBootPath() but use instead the "SystemPartition"
value passed via the ARC argument vector by the boot manager
(+ validation checks). Use it as the "default path" when calling
FsOpenFile() or loading the ramdisk.
- Honour the FreeLdr-specific "Hal=" and "Kernel=" options by
converting
them into NT standard "/HAL=" and "/KERNEL=" options in the
boot
command line.
Note that if the latter ones are already present on the standard
"Options="
option line, they would take precedence over those passed via the separate
"Hal=" and "Kernel=" FreeLdr-specific options.
Also add some documentation links to Geoff Chappell's website about
how the default HAL and KERNEL names are chosen depending on the
detected underlying platform on which the NT OS loader is running.
---
boot/freeldr/freeldr/arch/i386/drivemap.c | 19 +-
boot/freeldr/freeldr/arch/i386/hwdisk.c | 4 +-
boot/freeldr/freeldr/arcname.c | 78 ++--
boot/freeldr/freeldr/bootmgr.c | 112 +++---
boot/freeldr/freeldr/cmdline.c | 74 ++--
boot/freeldr/freeldr/custom.c | 429 ++++++++++++++++------
boot/freeldr/freeldr/disk/ramdisk.c | 74 ++--
boot/freeldr/freeldr/freeldr.c | 4 +-
boot/freeldr/freeldr/include/arch/i386/drivemap.h | 5 +-
boot/freeldr/freeldr/include/arcname.h | 23 +-
boot/freeldr/freeldr/include/cmdline.h | 8 +-
boot/freeldr/freeldr/include/custom.h | 29 +-
boot/freeldr/freeldr/include/debug.h | 4 +-
boot/freeldr/freeldr/include/fs.h | 9 +-
boot/freeldr/freeldr/include/linux.h | 11 -
boot/freeldr/freeldr/include/oslist.h | 3 +-
boot/freeldr/freeldr/include/ramdisk.h | 12 +-
boot/freeldr/freeldr/include/ui.h | 5 +-
boot/freeldr/freeldr/lib/debug.c | 14 +-
boot/freeldr/freeldr/lib/fs/fs.c | 88 +++--
boot/freeldr/freeldr/lib/peloader.c | 2 +-
boot/freeldr/freeldr/linuxboot.c | 160 ++++----
boot/freeldr/freeldr/miscboot.c | 181 ++++++---
boot/freeldr/freeldr/ntldr/inffile.c | 2 +-
boot/freeldr/freeldr/ntldr/setupldr.c | 36 +-
boot/freeldr/freeldr/ntldr/winldr.c | 127 +++++--
boot/freeldr/freeldr/oslist.c | 87 ++---
boot/freeldr/freeldr/ui/directui.c | 7 +-
boot/freeldr/freeldr/ui/tui.c | 85 ++---
boot/freeldr/freeldr/ui/ui.c | 330 ++++++++---------
30 files changed, 1204 insertions(+), 818 deletions(-)
diff --git a/boot/freeldr/freeldr/arch/i386/drivemap.c
b/boot/freeldr/freeldr/arch/i386/drivemap.c
index 2d38f346e28..1fc96c0f93f 100644
--- a/boot/freeldr/freeldr/arch/i386/drivemap.c
+++ b/boot/freeldr/freeldr/arch/i386/drivemap.c
@@ -18,8 +18,8 @@
*/
#include <freeldr.h>
-#include <debug.h>
+#include <debug.h>
DBG_DEFAULT_CHANNEL(DISK);
#ifdef _M_IX86
@@ -92,24 +92,23 @@ UCHAR DriveMapGetBiosDriveNumber(PCSTR DeviceName)
#ifdef _M_IX86
-VOID DriveMapMapDrivesInSection(PCSTR SectionName)
+VOID
+DriveMapMapDrivesInSection(
+ IN ULONG_PTR SectionId)
{
CHAR SettingName[80];
CHAR SettingValue[80];
CHAR Drive1[80];
CHAR Drive2[80];
- ULONG_PTR SectionId;
ULONG SectionItemCount;
ULONG Index;
ULONG Index2;
DRIVE_MAP_LIST DriveMapList;
- RtlZeroMemory(&DriveMapList, sizeof(DRIVE_MAP_LIST));
-
- if (!IniOpenSection(SectionName, &SectionId))
- {
+ if (SectionId == 0)
return;
- }
+
+ RtlZeroMemory(&DriveMapList, sizeof(DRIVE_MAP_LIST));
// Get the number of items in this section
SectionItemCount = IniGetNumSectionItems(SectionId);
@@ -125,7 +124,7 @@ VOID DriveMapMapDrivesInSection(PCSTR SectionName)
// Make sure we haven't exceeded the drive map max count
if (DriveMapList.DriveMapCount >= 4)
{
- UiMessageBox("Max DriveMap count exceeded in section
[%s]:\n\n%s=%s", SectionName, SettingName, SettingValue);
+ UiMessageBox("Max DriveMap count exceeded in section
[%s]:\n\n%s=%s", ((PINI_SECTION)SectionId)->SectionName, SettingName,
SettingValue);
continue;
}
@@ -150,7 +149,7 @@ VOID DriveMapMapDrivesInSection(PCSTR SectionName)
// Make sure we got good values before we add them to the map
if (!DriveMapIsValidDriveString(Drive1) ||
!DriveMapIsValidDriveString(Drive2))
{
- UiMessageBox("Error in DriveMap setting in section
[%s]:\n\n%s=%s", SectionName, SettingName, SettingValue);
+ UiMessageBox("Error in DriveMap setting in section
[%s]:\n\n%s=%s", ((PINI_SECTION)SectionId)->SectionName, SettingName,
SettingValue);
continue;
}
diff --git a/boot/freeldr/freeldr/arch/i386/hwdisk.c
b/boot/freeldr/freeldr/arch/i386/hwdisk.c
index fde0d8acf89..d3601ec5eeb 100644
--- a/boot/freeldr/freeldr/arch/i386/hwdisk.c
+++ b/boot/freeldr/freeldr/arch/i386/hwdisk.c
@@ -22,7 +22,6 @@
#include <freeldr.h>
#include <debug.h>
-
DBG_DEFAULT_CHANNEL(HWDETECT);
/*
@@ -80,7 +79,6 @@ DiskOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId)
ULONGLONG SectorOffset = 0;
ULONGLONG SectorCount = 0;
PARTITION_TABLE_ENTRY PartitionTableEntry;
- CHAR FileName[1];
if (DiskReadBufferSize == 0)
{
@@ -89,7 +87,7 @@ DiskOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId)
return ENOMEM;
}
- if (!DissectArcPath(Path, FileName, &DriveNumber, &DrivePartition))
+ if (!DissectArcPath(Path, NULL, &DriveNumber, &DrivePartition))
return EINVAL;
if (DrivePartition == 0xff)
diff --git a/boot/freeldr/freeldr/arcname.c b/boot/freeldr/freeldr/arcname.c
index 8e8cf1e801a..26ba703da5b 100644
--- a/boot/freeldr/freeldr/arcname.c
+++ b/boot/freeldr/freeldr/arcname.c
@@ -21,23 +21,32 @@
#include <freeldr.h>
-BOOLEAN DissectArcPath(CHAR *ArcPath, CHAR *BootPath, UCHAR* BootDrive, ULONG*
BootPartition)
+BOOLEAN
+DissectArcPath(
+ IN PCSTR ArcPath,
+ OUT PCSTR* Path OPTIONAL,
+ OUT PUCHAR DriveNumber,
+ OUT PULONG PartitionNumber)
{
- char *p;
+ PCCH p;
/* Detect ramdisk path */
if (_strnicmp(ArcPath, "ramdisk(0)", 10) == 0)
{
/* Magic value for ramdisks */
- *BootDrive = 0x49;
- *BootPartition = 1;
-
- /* Get the path */
- p = ArcPath + 11;
- strcpy(BootPath, p);
+ *DriveNumber = 0x49;
+ *PartitionNumber = 1;
+
+ /* Get the path (optional) */
+ if (Path)
+ {
+ p = ArcPath + 11;
+ *Path = p;
+ }
return TRUE;
}
+ /* NOTE: We are currently limited when handling multi()disk() paths!! */
if (_strnicmp(ArcPath, "multi(0)disk(0)", 15) != 0)
return FALSE;
@@ -49,12 +58,12 @@ BOOLEAN DissectArcPath(CHAR *ArcPath, CHAR *BootPath, UCHAR*
BootDrive, ULONG* B
* multi(0)disk(0)fdisk(x)\path
*/
p = p + 6;
- *BootDrive = atoi(p);
+ *DriveNumber = atoi(p);
p = strchr(p, ')');
if (p == NULL)
return FALSE;
- p++;
- *BootPartition = 0;
+ ++p;
+ *PartitionNumber = 0;
}
else if (_strnicmp(p, "cdrom(", 6) == 0)
{
@@ -63,37 +72,48 @@ BOOLEAN DissectArcPath(CHAR *ArcPath, CHAR *BootPath, UCHAR*
BootDrive, ULONG* B
* multi(0)disk(0)cdrom(x)\path
*/
p = p + 6;
- *BootDrive = atoi(p) + 0x80;
+ *DriveNumber = atoi(p) + 0x80;
p = strchr(p, ')');
if (p == NULL)
return FALSE;
- p++;
- *BootPartition = 0xff;
+ ++p;
+ *PartitionNumber = 0xff;
}
else if (_strnicmp(p, "rdisk(", 6) == 0)
{
/*
* Hard disk path:
- * multi(0)disk(0)rdisk(x)partition(y)\path
+ * multi(0)disk(0)rdisk(x)[partition(y)][\path]
*/
p = p + 6;
- *BootDrive = atoi(p) + 0x80;
- p = strchr(p, ')');
- if ((p == NULL) || (_strnicmp(p, ")partition(", 11) != 0))
- return FALSE;
- p = p + 11;
- *BootPartition = atoi(p);
+ *DriveNumber = atoi(p) + 0x80;
p = strchr(p, ')');
if (p == NULL)
return FALSE;
- p++;
+ ++p;
+ /* The partition is optional */
+ if (_strnicmp(p, "partition(", 10) == 0)
+ {
+ p = p + 10;
+ *PartitionNumber = atoi(p);
+ p = strchr(p, ')');
+ if (p == NULL)
+ return FALSE;
+ ++p;
+ }
+ else
+ {
+ *PartitionNumber = 0;
+ }
}
else
{
return FALSE;
}
- strcpy(BootPath, p);
+ /* Get the path (optional) */
+ if (Path)
+ *Path = p;
return TRUE;
}
@@ -101,12 +121,12 @@ BOOLEAN DissectArcPath(CHAR *ArcPath, CHAR *BootPath, UCHAR*
BootDrive, ULONG* B
/* PathSyntax: scsi() = 0, multi() = 1, ramdisk() = 2 */
BOOLEAN
DissectArcPath2(
- IN CHAR* ArcPath,
- OUT ULONG* x,
- OUT ULONG* y,
- OUT ULONG* z,
- OUT ULONG* Partition,
- OUT ULONG *PathSyntax)
+ IN PCSTR ArcPath,
+ OUT PULONG x,
+ OUT PULONG y,
+ OUT PULONG z,
+ OUT PULONG Partition,
+ OUT PULONG PathSyntax)
{
/* Detect ramdisk() */
if (_strnicmp(ArcPath, "ramdisk(0)", 10) == 0)
diff --git a/boot/freeldr/freeldr/bootmgr.c b/boot/freeldr/freeldr/bootmgr.c
index 8c97eeaaa95..7cf5febf282 100644
--- a/boot/freeldr/freeldr/bootmgr.c
+++ b/boot/freeldr/freeldr/bootmgr.c
@@ -20,8 +20,8 @@
/* INCLUDES *******************************************************************/
#include <freeldr.h>
-#include <debug.h>
+#include <debug.h>
DBG_DEFAULT_CHANNEL(INIFILE);
/* GLOBALS ********************************************************************/
@@ -29,20 +29,20 @@ DBG_DEFAULT_CHANNEL(INIFILE);
typedef
VOID
(*EDIT_OS_ENTRY_PROC)(
- IN ULONG_PTR SectionId OPTIONAL);
+ IN OUT OperatingSystemItem* OperatingSystem);
static VOID
EditCustomBootReactOSSetup(
- IN ULONG_PTR SectionId OPTIONAL)
+ IN OUT OperatingSystemItem* OperatingSystem)
{
- EditCustomBootReactOS(SectionId, TRUE);
+ EditCustomBootReactOS(OperatingSystem, TRUE);
}
static VOID
EditCustomBootNTOS(
- IN ULONG_PTR SectionId OPTIONAL)
+ IN OUT OperatingSystemItem* OperatingSystem)
{
- EditCustomBootReactOS(SectionId, FALSE);
+ EditCustomBootReactOS(OperatingSystem, FALSE);
}
static const struct
@@ -68,6 +68,12 @@ static const struct
/* FUNCTIONS ******************************************************************/
+/*
+ * This function converts the list of key=value options in the given operating
+ * system section into an ARC-compatible argument vector, providing in addition
+ * the extra mandatory Software Loading Environment Variables, following the
+ * ARC specification.
+ */
PCHAR*
BuildArgvForOsLoader(
IN PCSTR LoadIdentifier,
@@ -81,30 +87,34 @@ BuildArgvForOsLoader(
PCHAR* Argv;
PCHAR* Args;
PCHAR SettingName, SettingValue;
-
- /*
- * Convert the list of key=value options in the given operating system section
- * into a ARC-compatible argument vector.
- */
+ CHAR BootPath[MAX_PATH];
*pArgc = 0;
+ ASSERT(SectionId != 0);
+
/* Validate the LoadIdentifier (to make tests simpler later) */
if (LoadIdentifier && !*LoadIdentifier)
LoadIdentifier = NULL;
+ /* Get the boot path we're booting from (the "SystemPartition") */
+ MachDiskGetBootPath(BootPath, sizeof(BootPath));
+
/* Count the number of operating systems in the section */
Count = IniGetNumSectionItems(SectionId);
- /* The argument vector contains the program name, the LoadIdentifier (optional), and
the items in the OS section */
- Argc = 1 + Count;
- if (LoadIdentifier)
- ++Argc;
+ /*
+ * The argument vector contains the program name, the SystemPartition,
+ * the LoadIdentifier (optional), and the items in the OS section.
+ */
+ Argc = 2 + (LoadIdentifier ? 1 : 0) + Count;
/* Calculate the total size needed for the string buffer of the argument vector */
Size = 0;
/* i == 0: Program name */
- /* i == 1: LoadIdentifier */
+ /* i == 1: SystemPartition : from where FreeLdr has been started */
+ Size += (strlen("SystemPartition=") + strlen(BootPath) + 1) *
sizeof(CHAR);
+ /* i == 2: LoadIdentifier : ASCII string that may be used to associate an identifier
with a set of load parameters */
if (LoadIdentifier)
{
Size += (strlen("LoadIdentifier=") + strlen(LoadIdentifier) + 1) *
sizeof(CHAR);
@@ -126,7 +136,15 @@ BuildArgvForOsLoader(
Args = Argv;
/* i == 0: Program name */
*Args++ = NULL;
- /* i == 1: LoadIdentifier */
+ /* i == 1: SystemPartition */
+ {
+ strcpy(SettingName, "SystemPartition=");
+ strcat(SettingName, BootPath);
+
+ *Args++ = SettingName;
+ SettingName += (strlen(SettingName) + 1);
+ }
+ /* i == 2: LoadIdentifier */
if (LoadIdentifier)
{
strcpy(SettingName, "LoadIdentifier=");
@@ -162,19 +180,14 @@ BuildArgvForOsLoader(
VOID LoadOperatingSystem(IN OperatingSystemItem* OperatingSystem)
{
- ULONG_PTR SectionId;
- PCSTR SectionName = OperatingSystem->SectionName;
+ ULONG_PTR SectionId = OperatingSystem->SectionId;
ULONG i;
ULONG Argc;
PCHAR* Argv;
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;
- }
+ /* The operating system section has been opened by InitOperatingSystemList() */
+ ASSERT(SectionId != 0);
/* Try to read the boot type */
*BootType = ANSI_NULL;
@@ -185,7 +198,7 @@ VOID LoadOperatingSystem(IN OperatingSystemItem* OperatingSystem)
#ifdef _M_IX86
/* Install the drive mapper according to this section drive mappings */
- DriveMapMapDrivesInSection(SectionName);
+ DriveMapMapDrivesInSection(SectionId);
#endif
/* Loop through the OS loading method table and find a suitable OS to boot */
@@ -208,17 +221,12 @@ VOID LoadOperatingSystem(IN OperatingSystemItem* OperatingSystem)
VOID EditOperatingSystemEntry(IN OperatingSystemItem* OperatingSystem)
{
- ULONG_PTR SectionId;
- PCSTR SectionName = OperatingSystem->SectionName;
+ ULONG_PTR SectionId = OperatingSystem->SectionId;
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;
- }
+ /* The operating system section has been opened by InitOperatingSystemList() */
+ ASSERT(SectionId != 0);
/* Try to read the boot type */
*BootType = ANSI_NULL;
@@ -232,7 +240,7 @@ VOID EditOperatingSystemEntry(IN OperatingSystemItem*
OperatingSystem)
{
if (_stricmp(BootType, OSLoadingMethods[i].BootType) == 0)
{
- OSLoadingMethods[i].EditOsEntry(SectionId);
+ OSLoadingMethods[i].EditOsEntry(OperatingSystem);
return;
}
}
@@ -240,23 +248,24 @@ VOID EditOperatingSystemEntry(IN OperatingSystemItem*
OperatingSystem)
#endif // HAS_OPTION_MENU_EDIT_CMDLINE
-LONG GetTimeOut(VOID)
+static LONG
+GetTimeOut(
+ IN ULONG_PTR FrLdrSectionId)
{
- CHAR TimeOutText[20];
- LONG TimeOut;
- ULONG_PTR SectionId;
+ LONG TimeOut = -1;
+ CHAR TimeOutText[20];
TimeOut = CmdLineGetTimeOut();
if (TimeOut >= 0)
return TimeOut;
- if (!IniOpenSection("FreeLoader", &SectionId))
- return -1;
+ TimeOut = -1;
- if (IniReadSettingByName(SectionId, "TimeOut", TimeOutText,
sizeof(TimeOutText)))
+ if ((FrLdrSectionId != 0) &&
+ IniReadSettingByName(FrLdrSectionId, "TimeOut", TimeOutText,
sizeof(TimeOutText)))
+ {
TimeOut = atoi(TimeOutText);
- else
- TimeOut = -1;
+ }
return TimeOut;
}
@@ -316,16 +325,18 @@ VOID RunLoader(VOID)
return;
}
- /* Debugger main initialization */
- DebugInit(TRUE);
-
+ /* Open the [FreeLoader] section */
if (!IniOpenSection("FreeLoader", &SectionId))
{
UiMessageBoxCritical("Section [FreeLoader] not found in
freeldr.ini.");
return;
}
- TimeOut = GetTimeOut();
+ /* Debugger main initialization */
+ DebugInit(SectionId);
+
+ /* Retrieve the default timeout */
+ TimeOut = GetTimeOut(SectionId);
/* UI main initialization */
if (!UiInitialize(TRUE))
@@ -334,7 +345,8 @@ VOID RunLoader(VOID)
return;
}
- OperatingSystemList = InitOperatingSystemList(&OperatingSystemCount,
+ OperatingSystemList = InitOperatingSystemList(SectionId,
+ &OperatingSystemCount,
&DefaultOperatingSystem);
if (!OperatingSystemList)
{
@@ -358,7 +370,7 @@ VOID RunLoader(VOID)
}
/* Find all the message box settings and run them */
- UiShowMessageBoxesInSection("FreeLoader");
+ UiShowMessageBoxesInSection(SectionId);
for (;;)
{
diff --git a/boot/freeldr/freeldr/cmdline.c b/boot/freeldr/freeldr/cmdline.c
index 001c9467fc8..19fba954101 100644
--- a/boot/freeldr/freeldr/cmdline.c
+++ b/boot/freeldr/freeldr/cmdline.c
@@ -14,9 +14,9 @@
typedef struct tagCMDLINEINFO
{
- PCCH DebugString;
- PCCH DefaultOperatingSystem;
- LONG TimeOut;
+ PCSTR DebugString;
+ PCSTR DefaultOperatingSystem;
+ LONG TimeOut;
} CMDLINEINFO, *PCMDLINEINFO;
CCHAR DebugString[256];
@@ -26,7 +26,7 @@ CMDLINEINFO CmdLineInfo;
/* FUNCTIONS ******************************************************************/
VOID
-CmdLineParse(IN PCCH CmdLine)
+CmdLineParse(IN PCSTR CmdLine)
{
PCHAR End, Setting;
ULONG_PTR Length, Offset = 0;
@@ -46,16 +46,12 @@ CmdLineParse(IN PCCH CmdLine)
if (Setting)
{
/* Check if there are more command-line parameters following */
- Setting += sizeof("debug=") + sizeof(ANSI_NULL);
+ Setting += sizeof("debug=") - sizeof(ANSI_NULL);
End = strstr(Setting, " ");
- if (End)
- Length = End - Setting;
- else
- Length = sizeof(DebugString);
+ Length = (End ? (End - Setting) : strlen(Setting));
/* Copy the debug string and upcase it */
- strncpy(DebugString, Setting, Length);
- DebugString[Length - 1] = ANSI_NULL;
+ RtlStringCbCopyNA(DebugString, sizeof(DebugString), Setting, Length);
_strupr(DebugString);
/* Replace all separators ';' by spaces */
@@ -71,63 +67,65 @@ CmdLineParse(IN PCCH CmdLine)
/* Get timeout */
Setting = strstr(CmdLine, "timeout=");
- if (Setting) CmdLineInfo.TimeOut = atoi(Setting +
- sizeof("timeout=") +
- sizeof(ANSI_NULL));
+ if (Setting)
+ {
+ CmdLineInfo.TimeOut = atoi(Setting +
+ sizeof("timeout=") - sizeof(ANSI_NULL));
+ }
/* Get default OS */
Setting = strstr(CmdLine, "defaultos=");
if (Setting)
{
/* Check if there are more command-line parameters following */
- Setting += sizeof("defaultos=") + sizeof(ANSI_NULL);
+ Setting += sizeof("defaultos=") - sizeof(ANSI_NULL);
End = strstr(Setting, " ");
- if (End)
- Length = End - Setting;
- else
- Length = sizeof(DefaultOs);
+ Length = (End ? (End - Setting) : strlen(Setting));
/* Copy the default OS */
- strncpy(DefaultOs, Setting, Length);
- DefaultOs[Length - 1] = ANSI_NULL;
+ RtlStringCbCopyNA(DefaultOs, sizeof(DefaultOs), Setting, Length);
CmdLineInfo.DefaultOperatingSystem = DefaultOs;
}
/* Get ramdisk base address */
Setting = strstr(CmdLine, "rdbase=");
- if (Setting) gRamDiskBase = (PVOID)(ULONG_PTR)strtoull(Setting +
- sizeof("rdbase=") -
- sizeof(ANSI_NULL),
- NULL,
- 0);
+ if (Setting)
+ {
+ gRamDiskBase =
+ (PVOID)(ULONG_PTR)strtoull(Setting +
+ sizeof("rdbase=") - sizeof(ANSI_NULL),
+ NULL, 0);
+ }
/* Get ramdisk size */
Setting = strstr(CmdLine, "rdsize=");
- if (Setting) gRamDiskSize = strtoul(Setting +
- sizeof("rdsize=") -
- sizeof(ANSI_NULL),
- NULL,
- 0);
+ if (Setting)
+ {
+ gRamDiskSize = strtoul(Setting +
+ sizeof("rdsize=") - sizeof(ANSI_NULL),
+ NULL, 0);
+ }
/* Get ramdisk offset */
Setting = strstr(CmdLine, "rdoffset=");
- if (Setting) Offset = strtoul(Setting +
- sizeof("rdoffset=") -
- sizeof(ANSI_NULL),
- NULL,
- 0);
+ if (Setting)
+ {
+ Offset = strtoul(Setting +
+ sizeof("rdoffset=") - sizeof(ANSI_NULL),
+ NULL, 0);
+ }
/* Fix it up */
gRamDiskBase = (PVOID)((ULONG_PTR)gRamDiskBase + Offset);
}
-PCCH
+PCSTR
CmdLineGetDebugString(VOID)
{
return CmdLineInfo.DebugString;
}
-PCCH
+PCSTR
CmdLineGetDefaultOS(VOID)
{
return CmdLineInfo.DefaultOperatingSystem;
diff --git a/boot/freeldr/freeldr/custom.c b/boot/freeldr/freeldr/custom.c
index dfeba3051e5..e0afc7bb490 100644
--- a/boot/freeldr/freeldr/custom.c
+++ b/boot/freeldr/freeldr/custom.c
@@ -34,6 +34,7 @@ const CHAR LinuxCommandLinePrompt[] = "Enter the Linux kernel
command line.\n\nE
const CHAR BootDrivePrompt[] = "Enter the boot drive.\n\nExamples:\nfd0 - first
floppy drive\nhd0 - first hard drive\nhd1 - second hard drive\ncd0 - first CD-ROM
drive.\n\nBIOS drive numbers may also be used:\n0 - first floppy drive\n0x80 - first hard
drive\n0x81 - second hard drive";
const CHAR BootPartitionPrompt[] = "Enter the boot partition.\n\nEnter 0 for the
active (bootable) partition.";
+const CHAR ARCPathPrompt[] = "Enter the boot ARC
path.\n\nExamples:\nmulti(0)disk(0)rdisk(0)partition(1)\nmulti(0)disk(0)fdisk(0)";
const CHAR ReactOSSystemPathPrompt[] = "Enter the path to your ReactOS system
directory.\n\nExamples:\n\\REACTOS\n\\ROS";
const CHAR ReactOSOptionsPrompt[] = "Enter the options you want passed to the
kernel.\n\nExamples:\n/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200\n/FASTDETECT /SOS
/NOGUIBOOT\n/BASEVIDEO /MAXMEM=64\n/KERNEL=NTKRNLMP.EXE /HAL=HALMPS.DLL";
const CHAR CustomBootPrompt[] = "Press ENTER to boot your custom boot setup.";
@@ -55,6 +56,7 @@ VOID OptionMenuCustomBoot(VOID)
"ReactOS Setup"
};
ULONG SelectedMenuItem;
+ OperatingSystemItem OperatingSystem;
if (!UiDisplayMenu("Please choose a boot method:", NULL,
FALSE,
@@ -69,65 +71,111 @@ VOID OptionMenuCustomBoot(VOID)
return;
}
+ /* Initialize a new custom OS entry */
+ OperatingSystem.SectionId = 0;
switch (SelectedMenuItem)
{
#ifdef _M_IX86
case 0: // Disk
- EditCustomBootDisk(0);
+ EditCustomBootDisk(&OperatingSystem);
break;
case 1: // Partition
- EditCustomBootPartition(0);
+ EditCustomBootPartition(&OperatingSystem);
break;
case 2: // Boot Sector File
- EditCustomBootSectorFile(0);
+ EditCustomBootSectorFile(&OperatingSystem);
break;
case 3: // Linux
- EditCustomBootLinux(0);
+ EditCustomBootLinux(&OperatingSystem);
break;
case 4: // ReactOS
- EditCustomBootReactOS(0, FALSE);
+ EditCustomBootReactOS(&OperatingSystem, FALSE);
break;
case 5: // ReactOS Setup
- EditCustomBootReactOS(0, TRUE);
+ EditCustomBootReactOS(&OperatingSystem, TRUE);
break;
#else
case 0: // ReactOS
- EditCustomBootReactOS(0, FALSE);
+ EditCustomBootReactOS(&OperatingSystem, FALSE);
break;
case 1: // ReactOS Setup
- EditCustomBootReactOS(0, TRUE);
+ EditCustomBootReactOS(&OperatingSystem, TRUE);
break;
#endif
}
+
+ /* And boot it */
+ if (OperatingSystem.SectionId != 0)
+ {
+ UiMessageBox(CustomBootPrompt);
+ LoadOperatingSystem(&OperatingSystem);
+ }
}
#endif // HAS_OPTION_MENU_CUSTOM_BOOT
#ifdef _M_IX86
-VOID EditCustomBootDisk(IN ULONG_PTR SectionId OPTIONAL)
+VOID
+EditCustomBootDisk(
+ IN OUT OperatingSystemItem* OperatingSystem)
{
TIMEINFO* TimeInfo;
- OperatingSystemItem OperatingSystem;
+ ULONG_PTR SectionId = OperatingSystem->SectionId;
CHAR SectionName[100];
- CHAR BootDriveString[20];
+ /* The following is a trick for saving some stack space */
+ union
+ {
+ struct
+ {
+ CHAR Guard1;
+ CHAR Drive[20];
+ CHAR Guard2;
+ };
+ CHAR ArcPath[200];
+ } BootStrings;
RtlZeroMemory(SectionName, sizeof(SectionName));
- RtlZeroMemory(BootDriveString, sizeof(BootDriveString));
+ RtlZeroMemory(&BootStrings, sizeof(BootStrings));
if (SectionId != 0)
{
/* Load the settings */
- IniReadSettingByName(SectionId, "BootDrive", BootDriveString,
sizeof(BootDriveString));
+
+ /* Check whether we have a "BootPath" value (takes precedence over
"BootDrive") */
+ *BootStrings.ArcPath = ANSI_NULL;
+ IniReadSettingByName(SectionId, "BootPath", BootStrings.ArcPath,
sizeof(BootStrings.ArcPath));
+ if (!*BootStrings.ArcPath)
+ {
+ /* We don't, retrieve the boot drive value instead */
+ IniReadSettingByName(SectionId, "BootDrive", BootStrings.Drive,
sizeof(BootStrings.Drive));
+ }
}
- if (!UiEditBox(BootDrivePrompt, BootDriveString, sizeof(BootDriveString)))
- return;
+ if (!*BootStrings.ArcPath)
+ {
+ if (!UiEditBox(BootDrivePrompt, BootStrings.Drive, sizeof(BootStrings.Drive)))
+ return;
+ }
+ if (!*BootStrings.Drive)
+ {
+ if (!UiEditBox(ARCPathPrompt, BootStrings.ArcPath, sizeof(BootStrings.ArcPath)))
+ return;
+ }
/* Modify the settings values and return if we were in edit mode */
if (SectionId != 0)
{
- IniModifySettingValue(SectionId, "BootDrive", BootDriveString);
+ /* Modify the BootPath if we have one */
+ if (*BootStrings.ArcPath)
+ {
+ IniModifySettingValue(SectionId, "BootPath", BootStrings.ArcPath);
+ }
+ else if (*BootStrings.Drive)
+ {
+ /* Otherwise, modify the BootDrive */
+ IniModifySettingValue(SectionId, "BootDrive", BootStrings.Drive);
+ }
return;
}
@@ -146,47 +194,95 @@ VOID EditCustomBootDisk(IN ULONG_PTR SectionId OPTIONAL)
if (!IniAddSettingValueToSection(SectionId, "BootType",
"Drive"))
return;
- /* Add the BootDrive */
- if (!IniAddSettingValueToSection(SectionId, "BootDrive", BootDriveString))
- return;
-
- UiMessageBox(CustomBootPrompt);
+ /* Add the BootPath if we have one */
+ if (*BootStrings.ArcPath)
+ {
+ if (!IniAddSettingValueToSection(SectionId, "BootPath",
BootStrings.ArcPath))
+ return;
+ }
+ else if (*BootStrings.Drive)
+ {
+ /* Otherwise, add the BootDrive */
+ if (!IniAddSettingValueToSection(SectionId, "BootDrive",
BootStrings.Drive))
+ return;
+ }
- OperatingSystem.SectionName = SectionName;
- OperatingSystem.LoadIdentifier = NULL;
- LoadOperatingSystem(&OperatingSystem);
+ OperatingSystem->SectionId = SectionId;
+ OperatingSystem->LoadIdentifier = NULL;
}
-VOID EditCustomBootPartition(IN ULONG_PTR SectionId OPTIONAL)
+VOID
+EditCustomBootPartition(
+ IN OUT OperatingSystemItem* OperatingSystem)
{
TIMEINFO* TimeInfo;
- OperatingSystemItem OperatingSystem;
+ ULONG_PTR SectionId = OperatingSystem->SectionId;
CHAR SectionName[100];
- CHAR BootDriveString[20];
- CHAR BootPartitionString[20];
+ /* The following is a trick for saving some stack space */
+ union
+ {
+ struct
+ {
+ CHAR Guard1;
+ CHAR Drive[20];
+ CHAR Partition[20];
+ CHAR Guard2;
+ };
+ CHAR ArcPath[200];
+ } BootStrings;
RtlZeroMemory(SectionName, sizeof(SectionName));
- RtlZeroMemory(BootDriveString, sizeof(BootDriveString));
- RtlZeroMemory(BootPartitionString, sizeof(BootPartitionString));
+ RtlZeroMemory(&BootStrings, sizeof(BootStrings));
if (SectionId != 0)
{
/* Load the settings */
- IniReadSettingByName(SectionId, "BootDrive", BootDriveString,
sizeof(BootDriveString));
- IniReadSettingByName(SectionId, "BootPartition", BootPartitionString,
sizeof(BootPartitionString));
+
+ /*
+ * Check whether we have a "BootPath" value (takes precedence
+ * over both "BootDrive" and "BootPartition").
+ */
+ *BootStrings.ArcPath = ANSI_NULL;
+ IniReadSettingByName(SectionId, "BootPath", BootStrings.ArcPath,
sizeof(BootStrings.ArcPath));
+ if (!*BootStrings.ArcPath)
+ {
+ /* We don't, retrieve the boot drive and partition values instead */
+ IniReadSettingByName(SectionId, "BootDrive", BootStrings.Drive,
sizeof(BootStrings.Drive));
+ IniReadSettingByName(SectionId, "BootPartition",
BootStrings.Partition, sizeof(BootStrings.Partition));
+ }
}
- if (!UiEditBox(BootDrivePrompt, BootDriveString, sizeof(BootDriveString)))
- return;
+ if (!*BootStrings.ArcPath)
+ {
+ if (!UiEditBox(BootDrivePrompt, BootStrings.Drive, sizeof(BootStrings.Drive)))
+ return;
- if (!UiEditBox(BootPartitionPrompt, BootPartitionString,
sizeof(BootPartitionString)))
- return;
+ if (*BootStrings.Drive)
+ {
+ if (!UiEditBox(BootPartitionPrompt, BootStrings.Partition,
sizeof(BootStrings.Partition)))
+ return;
+ }
+ }
+ if (!*BootStrings.Drive)
+ {
+ if (!UiEditBox(ARCPathPrompt, BootStrings.ArcPath, sizeof(BootStrings.ArcPath)))
+ return;
+ }
/* Modify the settings values and return if we were in edit mode */
if (SectionId != 0)
{
- IniModifySettingValue(SectionId, "BootDrive", BootDriveString);
- IniModifySettingValue(SectionId, "BootPartition",
BootPartitionString);
+ /* Modify the BootPath if we have one */
+ if (*BootStrings.ArcPath)
+ {
+ IniModifySettingValue(SectionId, "BootPath", BootStrings.ArcPath);
+ }
+ else if (*BootStrings.Drive)
+ {
+ /* Otherwise, modify the BootDrive and BootPartition */
+ IniModifySettingValue(SectionId, "BootDrive", BootStrings.Drive);
+ IniModifySettingValue(SectionId, "BootPartition",
BootStrings.Partition);
+ }
return;
}
@@ -205,48 +301,87 @@ VOID EditCustomBootPartition(IN ULONG_PTR SectionId OPTIONAL)
if (!IniAddSettingValueToSection(SectionId, "BootType",
"Partition"))
return;
- /* Add the BootDrive */
- if (!IniAddSettingValueToSection(SectionId, "BootDrive", BootDriveString))
- return;
-
- /* Add the BootPartition */
- if (!IniAddSettingValueToSection(SectionId, "BootPartition",
BootPartitionString))
- return;
+ /* Add the BootPath if we have one */
+ if (*BootStrings.ArcPath)
+ {
+ if (!IniAddSettingValueToSection(SectionId, "BootPath",
BootStrings.ArcPath))
+ return;
+ }
+ else if (*BootStrings.Drive)
+ {
+ /* Otherwise, add the BootDrive and BootPartition */
+ if (!IniAddSettingValueToSection(SectionId, "BootDrive",
BootStrings.Drive))
+ return;
- UiMessageBox(CustomBootPrompt);
+ if (!IniAddSettingValueToSection(SectionId, "BootPartition",
BootStrings.Partition))
+ return;
+ }
- OperatingSystem.SectionName = SectionName;
- OperatingSystem.LoadIdentifier = NULL;
- LoadOperatingSystem(&OperatingSystem);
+ OperatingSystem->SectionId = SectionId;
+ OperatingSystem->LoadIdentifier = NULL;
}
-VOID EditCustomBootSectorFile(IN ULONG_PTR SectionId OPTIONAL)
+VOID
+EditCustomBootSectorFile(
+ IN OUT OperatingSystemItem* OperatingSystem)
{
TIMEINFO* TimeInfo;
- OperatingSystemItem OperatingSystem;
+ ULONG_PTR SectionId = OperatingSystem->SectionId;
CHAR SectionName[100];
- CHAR BootDriveString[20];
- CHAR BootPartitionString[20];
+ /* The following is a trick for saving some stack space */
+ union
+ {
+ struct
+ {
+ CHAR Guard1;
+ CHAR Drive[20];
+ CHAR Partition[20];
+ CHAR Guard2;
+ };
+ CHAR ArcPath[200];
+ } BootStrings;
CHAR BootSectorFileString[200];
RtlZeroMemory(SectionName, sizeof(SectionName));
- RtlZeroMemory(BootDriveString, sizeof(BootDriveString));
- RtlZeroMemory(BootPartitionString, sizeof(BootPartitionString));
+ RtlZeroMemory(&BootStrings, sizeof(BootStrings));
RtlZeroMemory(BootSectorFileString, sizeof(BootSectorFileString));
if (SectionId != 0)
{
/* Load the settings */
- IniReadSettingByName(SectionId, "BootDrive", BootDriveString,
sizeof(BootDriveString));
- IniReadSettingByName(SectionId, "BootPartition", BootPartitionString,
sizeof(BootPartitionString));
+
+ /*
+ * Check whether we have a "BootPath" value (takes precedence
+ * over both "BootDrive" and "BootPartition").
+ */
+ *BootStrings.ArcPath = ANSI_NULL;
+ IniReadSettingByName(SectionId, "BootPath", BootStrings.ArcPath,
sizeof(BootStrings.ArcPath));
+ if (!*BootStrings.ArcPath)
+ {
+ /* We don't, retrieve the boot drive and partition values instead */
+ IniReadSettingByName(SectionId, "BootDrive", BootStrings.Drive,
sizeof(BootStrings.Drive));
+ IniReadSettingByName(SectionId, "BootPartition",
BootStrings.Partition, sizeof(BootStrings.Partition));
+ }
+
IniReadSettingByName(SectionId, "BootSectorFile", BootSectorFileString,
sizeof(BootSectorFileString));
}
- if (!UiEditBox(BootDrivePrompt, BootDriveString, sizeof(BootDriveString)))
- return;
+ if (!*BootStrings.ArcPath)
+ {
+ if (!UiEditBox(BootDrivePrompt, BootStrings.Drive, sizeof(BootStrings.Drive)))
+ return;
- if (!UiEditBox(BootPartitionPrompt, BootPartitionString,
sizeof(BootPartitionString)))
- return;
+ if (*BootStrings.Drive)
+ {
+ if (!UiEditBox(BootPartitionPrompt, BootStrings.Partition,
sizeof(BootStrings.Partition)))
+ return;
+ }
+ }
+ if (!*BootStrings.Drive)
+ {
+ if (!UiEditBox(ARCPathPrompt, BootStrings.ArcPath, sizeof(BootStrings.ArcPath)))
+ return;
+ }
if (!UiEditBox(BootSectorFilePrompt, BootSectorFileString,
sizeof(BootSectorFileString)))
return;
@@ -254,8 +389,28 @@ VOID EditCustomBootSectorFile(IN ULONG_PTR SectionId OPTIONAL)
/* Modify the settings values and return if we were in edit mode */
if (SectionId != 0)
{
- IniModifySettingValue(SectionId, "BootDrive", BootDriveString);
- IniModifySettingValue(SectionId, "BootPartition",
BootPartitionString);
+ /* Modify the BootPath if we have one */
+ if (*BootStrings.ArcPath)
+ {
+ IniModifySettingValue(SectionId, "BootPath", BootStrings.ArcPath);
+ }
+ else if (*BootStrings.Drive)
+ {
+ /* Otherwise, modify the BootDrive and BootPartition */
+ IniModifySettingValue(SectionId, "BootDrive", BootStrings.Drive);
+ IniModifySettingValue(SectionId, "BootPartition",
BootStrings.Partition);
+ }
+ else
+ {
+ /*
+ * Otherwise, zero out all values: BootSectorFile will be
+ * relative to the default system partition.
+ */
+ IniModifySettingValue(SectionId, "BootPath", "");
+ IniModifySettingValue(SectionId, "BootDrive", "");
+ IniModifySettingValue(SectionId, "BootPartition", "");
+ }
+
IniModifySettingValue(SectionId, "BootSectorFile",
BootSectorFileString);
return;
}
@@ -275,39 +430,55 @@ VOID EditCustomBootSectorFile(IN ULONG_PTR SectionId OPTIONAL)
if (!IniAddSettingValueToSection(SectionId, "BootType",
"BootSector"))
return;
- /* Add the BootDrive */
- if (!IniAddSettingValueToSection(SectionId, "BootDrive", BootDriveString))
- return;
+ /* Add the BootPath if we have one */
+ if (*BootStrings.ArcPath)
+ {
+ if (!IniAddSettingValueToSection(SectionId, "BootPath",
BootStrings.ArcPath))
+ return;
+ }
+ else if (*BootStrings.Drive)
+ {
+ /* Otherwise, add the BootDrive and BootPartition */
+ if (!IniAddSettingValueToSection(SectionId, "BootDrive",
BootStrings.Drive))
+ return;
- /* Add the BootPartition */
- if (!IniAddSettingValueToSection(SectionId, "BootPartition",
BootPartitionString))
- return;
+ if (!IniAddSettingValueToSection(SectionId, "BootPartition",
BootStrings.Partition))
+ return;
+ }
/* Add the BootSectorFile */
if (!IniAddSettingValueToSection(SectionId, "BootSectorFile",
BootSectorFileString))
return;
- UiMessageBox(CustomBootPrompt);
-
- OperatingSystem.SectionName = SectionName;
- OperatingSystem.LoadIdentifier = NULL;
- LoadOperatingSystem(&OperatingSystem);
+ OperatingSystem->SectionId = SectionId;
+ OperatingSystem->LoadIdentifier = NULL;
}
-VOID EditCustomBootLinux(IN ULONG_PTR SectionId OPTIONAL)
+VOID
+EditCustomBootLinux(
+ IN OUT OperatingSystemItem* OperatingSystem)
{
TIMEINFO* TimeInfo;
- OperatingSystemItem OperatingSystem;
+ ULONG_PTR SectionId = OperatingSystem->SectionId;
CHAR SectionName[100];
- CHAR BootDriveString[20];
- CHAR BootPartitionString[20];
+ /* The following is a trick for saving some stack space */
+ union
+ {
+ struct
+ {
+ CHAR Guard1;
+ CHAR Drive[20];
+ CHAR Partition[20];
+ CHAR Guard2;
+ };
+ CHAR ArcPath[200];
+ } BootStrings;
CHAR LinuxKernelString[200];
CHAR LinuxInitrdString[200];
CHAR LinuxCommandLineString[200];
RtlZeroMemory(SectionName, sizeof(SectionName));
- RtlZeroMemory(BootDriveString, sizeof(BootDriveString));
- RtlZeroMemory(BootPartitionString, sizeof(BootPartitionString));
+ RtlZeroMemory(&BootStrings, sizeof(BootStrings));
RtlZeroMemory(LinuxKernelString, sizeof(LinuxKernelString));
RtlZeroMemory(LinuxInitrdString, sizeof(LinuxInitrdString));
RtlZeroMemory(LinuxCommandLineString, sizeof(LinuxCommandLineString));
@@ -315,18 +486,41 @@ VOID EditCustomBootLinux(IN ULONG_PTR SectionId OPTIONAL)
if (SectionId != 0)
{
/* Load the settings */
- IniReadSettingByName(SectionId, "BootDrive", BootDriveString,
sizeof(BootDriveString));
- IniReadSettingByName(SectionId, "BootPartition", BootPartitionString,
sizeof(BootPartitionString));
+
+ /*
+ * Check whether we have a "BootPath" value (takes precedence
+ * over both "BootDrive" and "BootPartition").
+ */
+ *BootStrings.ArcPath = ANSI_NULL;
+ IniReadSettingByName(SectionId, "BootPath", BootStrings.ArcPath,
sizeof(BootStrings.ArcPath));
+ if (!*BootStrings.ArcPath)
+ {
+ /* We don't, retrieve the boot drive and partition values instead */
+ IniReadSettingByName(SectionId, "BootDrive", BootStrings.Drive,
sizeof(BootStrings.Drive));
+ IniReadSettingByName(SectionId, "BootPartition",
BootStrings.Partition, sizeof(BootStrings.Partition));
+ }
+
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 (!*BootStrings.ArcPath)
+ {
+ if (!UiEditBox(BootDrivePrompt, BootStrings.Drive, sizeof(BootStrings.Drive)))
+ return;
- if (!UiEditBox(BootPartitionPrompt, BootPartitionString,
sizeof(BootPartitionString)))
- return;
+ if (*BootStrings.Drive)
+ {
+ if (!UiEditBox(BootPartitionPrompt, BootStrings.Partition,
sizeof(BootStrings.Partition)))
+ return;
+ }
+ }
+ if (!*BootStrings.Drive)
+ {
+ if (!UiEditBox(ARCPathPrompt, BootStrings.ArcPath, sizeof(BootStrings.ArcPath)))
+ return;
+ }
if (!UiEditBox(LinuxKernelPrompt, LinuxKernelString, sizeof(LinuxKernelString)))
return;
@@ -340,8 +534,28 @@ VOID EditCustomBootLinux(IN ULONG_PTR SectionId OPTIONAL)
/* Modify the settings values and return if we were in edit mode */
if (SectionId != 0)
{
- IniModifySettingValue(SectionId, "BootDrive", BootDriveString);
- IniModifySettingValue(SectionId, "BootPartition",
BootPartitionString);
+ /* Modify the BootPath if we have one */
+ if (*BootStrings.ArcPath)
+ {
+ IniModifySettingValue(SectionId, "BootPath", BootStrings.ArcPath);
+ }
+ else if (*BootStrings.Drive)
+ {
+ /* Otherwise, modify the BootDrive and BootPartition */
+ IniModifySettingValue(SectionId, "BootDrive", BootStrings.Drive);
+ IniModifySettingValue(SectionId, "BootPartition",
BootStrings.Partition);
+ }
+ else
+ {
+ /*
+ * Otherwise, zero out all values: BootSectorFile will be
+ * relative to the default system partition.
+ */
+ IniModifySettingValue(SectionId, "BootPath", "");
+ IniModifySettingValue(SectionId, "BootDrive", "");
+ IniModifySettingValue(SectionId, "BootPartition", "");
+ }
+
IniModifySettingValue(SectionId, "Kernel", LinuxKernelString);
IniModifySettingValue(SectionId, "Initrd", LinuxInitrdString);
IniModifySettingValue(SectionId, "CommandLine",
LinuxCommandLineString);
@@ -363,13 +577,21 @@ VOID EditCustomBootLinux(IN ULONG_PTR SectionId OPTIONAL)
if (!IniAddSettingValueToSection(SectionId, "BootType",
"Linux"))
return;
- /* Add the BootDrive */
- if (!IniAddSettingValueToSection(SectionId, "BootDrive", BootDriveString))
- return;
+ /* Add the BootPath if we have one */
+ if (*BootStrings.ArcPath)
+ {
+ if (!IniAddSettingValueToSection(SectionId, "BootPath",
BootStrings.ArcPath))
+ return;
+ }
+ else if (*BootStrings.Drive)
+ {
+ /* Otherwise, add the BootDrive and BootPartition */
+ if (!IniAddSettingValueToSection(SectionId, "BootDrive",
BootStrings.Drive))
+ return;
- /* Add the BootPartition */
- if (!IniAddSettingValueToSection(SectionId, "BootPartition",
BootPartitionString))
- return;
+ if (!IniAddSettingValueToSection(SectionId, "BootPartition",
BootStrings.Partition))
+ return;
+ }
/* Add the Kernel */
if (!IniAddSettingValueToSection(SectionId, "Kernel", LinuxKernelString))
@@ -386,22 +608,19 @@ VOID EditCustomBootLinux(IN ULONG_PTR SectionId OPTIONAL)
if (!IniAddSettingValueToSection(SectionId, "CommandLine",
LinuxCommandLineString))
return;
- UiMessageBox(CustomBootPrompt);
-
- OperatingSystem.SectionName = SectionName;
- OperatingSystem.LoadIdentifier = "Custom Linux Setup";
- LoadOperatingSystem(&OperatingSystem);
+ OperatingSystem->SectionId = SectionId;
+ OperatingSystem->LoadIdentifier = "Custom Linux Setup";
}
#endif // _M_IX86
VOID
EditCustomBootReactOS(
- IN ULONG_PTR SectionId OPTIONAL,
+ IN OUT OperatingSystemItem* OperatingSystem,
IN BOOLEAN IsSetup)
{
TIMEINFO* TimeInfo;
- OperatingSystemItem OperatingSystem;
+ ULONG_PTR SectionId = OperatingSystem->SectionId;
CHAR SectionName[100];
CHAR BootDriveString[20];
CHAR BootPartitionString[20];
@@ -419,7 +638,6 @@ EditCustomBootReactOS(
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));
}
@@ -478,11 +696,8 @@ EditCustomBootReactOS(
if (!IniAddSettingValueToSection(SectionId, "Options", ReactOSOptions))
return;
- UiMessageBox(CustomBootPrompt);
-
- OperatingSystem.SectionName = SectionName;
- OperatingSystem.LoadIdentifier = NULL;
- LoadOperatingSystem(&OperatingSystem);
+ OperatingSystem->SectionId = SectionId;
+ OperatingSystem->LoadIdentifier = NULL;
}
#ifdef HAS_OPTION_MENU_REBOOT
diff --git a/boot/freeldr/freeldr/disk/ramdisk.c b/boot/freeldr/freeldr/disk/ramdisk.c
index c9a096399e4..905c40941fa 100644
--- a/boot/freeldr/freeldr/disk/ramdisk.c
+++ b/boot/freeldr/freeldr/disk/ramdisk.c
@@ -109,62 +109,52 @@ static const DEVVTBL RamDiskVtbl = {
};
VOID
-NTAPI
RamDiskInitialize(VOID)
{
/* Register the RAMDISK device */
FsRegisterDevice("ramdisk(0)", &RamDiskVtbl);
}
-BOOLEAN
-NTAPI
-RamDiskLoadVirtualFile(IN PCHAR FileName)
+ARC_STATUS
+RamDiskLoadVirtualFile(
+ IN PCSTR FileName,
+ IN PCSTR DefaultPath OPTIONAL)
{
+ ARC_STATUS Status;
ULONG RamFileId;
ULONG TotalRead, ChunkSize, Count;
PCHAR MsgBuffer = "Loading RamDisk...";
ULONG PercentPerChunk, Percent;
FILEINFORMATION Information;
LARGE_INTEGER Position;
- ARC_STATUS Status;
- //
- // Display progress
- //
+ /* Display progress */
UiDrawBackdrop();
UiDrawProgressBarCenter(1, 100, MsgBuffer);
- //
- // Try opening the ramdisk file
- //
- RamFileId = FsOpenFile(FileName);
- if (!RamFileId)
- return FALSE;
+ /* Try opening the ramdisk file */
+ Status = FsOpenFile(FileName, DefaultPath, OpenReadOnly, &RamFileId);
+ if (Status != ESUCCESS)
+ return Status;
- //
- // Get the file size
- //
+ /* Get the file size */
Status = ArcGetFileInformation(RamFileId, &Information);
if (Status != ESUCCESS)
{
ArcClose(RamFileId);
- return FALSE;
+ return Status;
}
- //
- // For now, limit RAM disks to 4GB
- //
+ /* For now, limit RAM disks to 4GB */
if (Information.EndingAddress.HighPart != 0)
{
UiMessageBox("RAM disk too big.");
ArcClose(RamFileId);
- return FALSE;
+ return ENOMEM;
}
gRamDiskSize = Information.EndingAddress.LowPart;
- //
- // Allocate memory for it
- //
+ /* Allocate memory for it */
ChunkSize = 8 * 1024 * 1024;
if (gRamDiskSize < ChunkSize)
Percent = PercentPerChunk = 0;
@@ -175,34 +165,26 @@ RamDiskLoadVirtualFile(IN PCHAR FileName)
{
UiMessageBox("Failed to allocate memory for RAM disk.");
ArcClose(RamFileId);
- return FALSE;
+ return ENOMEM;
}
- //
- // Read it in chunks
- //
+ /*
+ * Read it in chunks
+ */
for (TotalRead = 0; TotalRead < gRamDiskSize; TotalRead += ChunkSize)
{
- //
- // Check if we're at the last chunk
- //
+ /* Check if we're at the last chunk */
if ((gRamDiskSize - TotalRead) < ChunkSize)
{
- //
- // Only need the actual data required
- //
+ /* Only need the actual data required */
ChunkSize = gRamDiskSize - TotalRead;
}
- //
- // Draw progress
- //
+ /* Draw progress */
UiDrawProgressBarCenter(Percent, 100, MsgBuffer);
Percent += PercentPerChunk;
- //
- // Copy the contents
- //
+ /* Copy the contents */
Position.HighPart = 0;
Position.LowPart = TotalRead;
Status = ArcSeek(RamFileId, &Position, SeekAbsolute);
@@ -214,17 +196,15 @@ RamDiskLoadVirtualFile(IN PCHAR FileName)
&Count);
}
- //
- // Check for success
- //
- if (Status != ESUCCESS || Count != ChunkSize)
+ /* Check for success */
+ if ((Status != ESUCCESS) || (Count != ChunkSize))
{
MmFreeMemory(gRamDiskBase);
gRamDiskBase = NULL;
gRamDiskSize = 0;
ArcClose(RamFileId);
UiMessageBox("Failed to read RAM disk.");
- return FALSE;
+ return ((Status != ESUCCESS) ? Status : EIO);
}
}
@@ -233,5 +213,5 @@ RamDiskLoadVirtualFile(IN PCHAR FileName)
/* Setup the RAMDISK device */
RamDiskInitialize();
- return TRUE;
+ return ESUCCESS;
}
diff --git a/boot/freeldr/freeldr/freeldr.c b/boot/freeldr/freeldr/freeldr.c
index b1f72965026..f9675733296 100644
--- a/boot/freeldr/freeldr/freeldr.c
+++ b/boot/freeldr/freeldr/freeldr.c
@@ -20,8 +20,8 @@
/* INCLUDES *******************************************************************/
#include <freeldr.h>
-#include <debug.h>
+#include <debug.h>
DBG_DEFAULT_CHANNEL(WARNING);
/* FUNCTIONS ******************************************************************/
@@ -31,7 +31,7 @@ VOID __cdecl BootMain(IN PCCH CmdLine)
CmdLineParse(CmdLine);
/* Debugger pre-initialization */
- DebugInit(FALSE);
+ DebugInit(0);
TRACE("BootMain() called.\n");
diff --git a/boot/freeldr/freeldr/include/arch/i386/drivemap.h
b/boot/freeldr/freeldr/include/arch/i386/drivemap.h
index 8c1d1088523..0737dca8a91 100644
--- a/boot/freeldr/freeldr/include/arch/i386/drivemap.h
+++ b/boot/freeldr/freeldr/include/arch/i386/drivemap.h
@@ -36,7 +36,10 @@ UCHAR DriveMapGetBiosDriveNumber(PCSTR DeviceName); // Returns a
BIOS drive
#ifdef _M_IX86
-VOID DriveMapMapDrivesInSection(PCSTR SectionName);
+VOID
+DriveMapMapDrivesInSection(
+ IN ULONG_PTR SectionId);
+
VOID DriveMapInstallInt13Handler(PDRIVE_MAP_LIST DriveMap); // Installs the int 13h
handler for the drive mapper
VOID DriveMapRemoveInt13Handler(VOID); // Removes a previously
installed int 13h drive map handler
diff --git a/boot/freeldr/freeldr/include/arcname.h
b/boot/freeldr/freeldr/include/arcname.h
index a5df3205c3a..1b30f46a3e2 100644
--- a/boot/freeldr/freeldr/include/arcname.h
+++ b/boot/freeldr/freeldr/include/arcname.h
@@ -24,16 +24,25 @@
// ARC Path Functions
//
///////////////////////////////////////////////////////////////////////////////////////
+
+BOOLEAN
+DissectArcPath(
+ IN PCSTR ArcPath,
+ OUT PCSTR* Path OPTIONAL,
+ OUT PUCHAR DriveNumber,
+ OUT PULONG PartitionNumber);
+
BOOLEAN
DissectArcPath2(
- IN CHAR* ArcPath,
- OUT ULONG* x,
- OUT ULONG* y,
- OUT ULONG* z,
- OUT ULONG* Partition,
- OUT ULONG *PathSyntax);
-BOOLEAN DissectArcPath(CHAR *ArcPath, CHAR *BootPath, UCHAR* BootDrive, ULONG*
BootPartition);
+ IN PCSTR ArcPath,
+ OUT PULONG x,
+ OUT PULONG y,
+ OUT PULONG z,
+ OUT PULONG Partition,
+ OUT PULONG PathSyntax);
+
VOID ConstructArcPath(PCHAR ArcPath, PCHAR SystemFolder, UCHAR Disk, ULONG Partition);
+
#if 0
UCHAR ConvertArcNameToBiosDriveNumber(PCHAR ArcPath);
#endif
diff --git a/boot/freeldr/freeldr/include/cmdline.h
b/boot/freeldr/freeldr/include/cmdline.h
index 3ab13c21fdc..47a733b60ef 100644
--- a/boot/freeldr/freeldr/include/cmdline.h
+++ b/boot/freeldr/freeldr/include/cmdline.h
@@ -19,10 +19,10 @@
#pragma once
-VOID CmdLineParse(IN PCCH CmdLine);
+VOID CmdLineParse(IN PCSTR CmdLine);
-PCCH CmdLineGetDebugString(VOID);
-PCCH CmdLineGetDefaultOS(VOID);
-LONG CmdLineGetTimeOut(VOID);
+PCSTR CmdLineGetDebugString(VOID);
+PCSTR CmdLineGetDefaultOS(VOID);
+LONG CmdLineGetTimeOut(VOID);
/* EOF */
diff --git a/boot/freeldr/freeldr/include/custom.h
b/boot/freeldr/freeldr/include/custom.h
index b38241f135e..57164b84c8e 100644
--- a/boot/freeldr/freeldr/include/custom.h
+++ b/boot/freeldr/freeldr/include/custom.h
@@ -23,22 +23,33 @@
#define HAS_OPTION_MENU_CUSTOM_BOOT
#define HAS_OPTION_MENU_REBOOT
+#ifdef HAS_OPTION_MENU_CUSTOM_BOOT
+VOID OptionMenuCustomBoot(VOID);
+#endif
+
#ifdef _M_IX86
-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);
+VOID
+EditCustomBootDisk(
+ IN OUT OperatingSystemItem* OperatingSystem);
-#endif // _M_IX86
+VOID
+EditCustomBootPartition(
+ IN OUT OperatingSystemItem* OperatingSystem);
-#ifdef HAS_OPTION_MENU_CUSTOM_BOOT
-VOID OptionMenuCustomBoot(VOID);
-#endif
+VOID
+EditCustomBootSectorFile(
+ IN OUT OperatingSystemItem* OperatingSystem);
+
+VOID
+EditCustomBootLinux(
+ IN OUT OperatingSystemItem* OperatingSystem);
+
+#endif // _M_IX86
VOID
EditCustomBootReactOS(
- IN ULONG_PTR SectionId OPTIONAL,
+ IN OUT OperatingSystemItem* OperatingSystem,
IN BOOLEAN IsSetup);
#ifdef HAS_OPTION_MENU_REBOOT
diff --git a/boot/freeldr/freeldr/include/debug.h b/boot/freeldr/freeldr/include/debug.h
index 9cf62ebb8ee..1862220fb82 100644
--- a/boot/freeldr/freeldr/include/debug.h
+++ b/boot/freeldr/freeldr/include/debug.h
@@ -40,7 +40,7 @@
#if DBG && !defined(_M_ARM)
- VOID DebugInit(BOOLEAN MainInit);
+ VOID DebugInit(IN ULONG_PTR FrLdrSectionId);
ULONG DbgPrint(const char *Format, ...);
VOID DbgPrint2(ULONG Mask, ULONG Level, const char *File, ULONG Line, char
*Format, ...);
VOID DebugDumpBuffer(ULONG Mask, PVOID Buffer, ULONG Length);
@@ -113,7 +113,7 @@ void MEMORY_WRITE_BREAKPOINT4(unsigned long addr);
#define UNIMPLEMENTED
- #define DebugInit(init)
+ #define DebugInit(FrLdrSectionId)
#define BugCheck(fmt, ...)
#define DbgDumpBuffer(mask, buf, len)
#define DbgParseDebugChannels(val)
diff --git a/boot/freeldr/freeldr/include/fs.h b/boot/freeldr/freeldr/include/fs.h
index 2d774656df6..68489c9d087 100644
--- a/boot/freeldr/freeldr/include/fs.h
+++ b/boot/freeldr/freeldr/include/fs.h
@@ -40,7 +40,14 @@ ARC_STATUS ArcSeek(ULONG FileId, LARGE_INTEGER* Position, SEEKMODE
SeekMode);
ARC_STATUS ArcGetFileInformation(ULONG FileId, FILEINFORMATION* Information);
VOID FileSystemError(PCSTR ErrorString);
-ULONG FsOpenFile(PCSTR FileName);
+
+ARC_STATUS
+FsOpenFile(
+ IN PCSTR FileName,
+ IN PCSTR DefaultPath OPTIONAL,
+ IN OPENMODE OpenMode,
+ OUT PULONG FileId);
+
ULONG FsGetNumPathParts(PCSTR Path);
VOID FsGetFirstNameFromPath(PCHAR Buffer, PCSTR Path);
diff --git a/boot/freeldr/freeldr/include/linux.h b/boot/freeldr/freeldr/include/linux.h
index 72043f8ef27..d0b35105f2b 100644
--- a/boot/freeldr/freeldr/include/linux.h
+++ b/boot/freeldr/freeldr/include/linux.h
@@ -137,17 +137,6 @@ LoadAndBootLinux(
IN PCHAR Argv[],
IN PCHAR Envp[]);
-BOOLEAN
-LinuxParseIniSection(
- IN ULONG Argc,
- IN PCHAR Argv[]);
-
-BOOLEAN LinuxReadBootSector(ULONG LinuxKernelFile);
-BOOLEAN LinuxReadSetupSector(ULONG LinuxKernelFile);
-BOOLEAN LinuxReadKernel(ULONG LinuxKernelFile);
-BOOLEAN LinuxCheckKernelVersion(VOID);
-BOOLEAN LinuxReadInitrd(ULONG LinuxInitrdFile);
-
#endif // _M_IX86
#endif // defined __LINUX_H
diff --git a/boot/freeldr/freeldr/include/oslist.h
b/boot/freeldr/freeldr/include/oslist.h
index 1676900c220..b4bf62f9d43 100644
--- a/boot/freeldr/freeldr/include/oslist.h
+++ b/boot/freeldr/freeldr/include/oslist.h
@@ -23,11 +23,12 @@
typedef struct tagOperatingSystemItem
{
- PCSTR SectionName;
+ ULONG_PTR SectionId;
PCSTR LoadIdentifier;
} OperatingSystemItem;
OperatingSystemItem*
InitOperatingSystemList(
+ IN ULONG_PTR FrLdrSectionId,
OUT PULONG OperatingSystemCount,
OUT PULONG DefaultOperatingSystem);
diff --git a/boot/freeldr/freeldr/include/ramdisk.h
b/boot/freeldr/freeldr/include/ramdisk.h
index 2e56a37b270..a9dd199feb2 100644
--- a/boot/freeldr/freeldr/include/ramdisk.h
+++ b/boot/freeldr/freeldr/include/ramdisk.h
@@ -11,17 +11,13 @@
//
// Ramdisk Routines
//
-BOOLEAN
-NTAPI
+ARC_STATUS
RamDiskLoadVirtualFile(
- IN PCHAR FileName
-);
+ IN PCSTR FileName,
+ IN PCSTR DefaultPath OPTIONAL);
VOID
-NTAPI
-RamDiskInitialize(
- VOID
-);
+RamDiskInitialize(VOID);
extern PVOID gRamDiskBase;
extern ULONG gRamDiskSize;
diff --git a/boot/freeldr/freeldr/include/ui.h b/boot/freeldr/freeldr/include/ui.h
index f773ae84540..f5abbe69906 100644
--- a/boot/freeldr/freeldr/include/ui.h
+++ b/boot/freeldr/freeldr/include/ui.h
@@ -71,7 +71,10 @@ VOID UiMessageBoxCritical(PCSTR MessageText); //
Displays a me
VOID UiDrawProgressBarCenter(ULONG Position, ULONG Range, PCHAR ProgressText);
// Draws the progress bar showing nPos percent filled
VOID UiDrawProgressBar(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, ULONG
Position, ULONG Range, PCHAR ProgressText); // Draws the progress bar showing
nPos percent filled
-VOID UiShowMessageBoxesInSection(PCSTR SectionName); // Displays all the
message boxes in a given section
+// Displays all the message boxes in a given section.
+VOID
+UiShowMessageBoxesInSection(
+ IN ULONG_PTR SectionId);
VOID
UiShowMessageBoxesInArgv(
diff --git a/boot/freeldr/freeldr/lib/debug.c b/boot/freeldr/freeldr/lib/debug.c
index 1f01f869b22..24c074ddc69 100644
--- a/boot/freeldr/freeldr/lib/debug.c
+++ b/boot/freeldr/freeldr/lib/debug.c
@@ -49,7 +49,7 @@ ULONG PortIrq = 0; // Not used at the moment.
BOOLEAN DebugStartOfLine = TRUE;
-VOID DebugInit(BOOLEAN MainInit)
+VOID DebugInit(IN ULONG_PTR FrLdrSectionId)
{
PCHAR CommandLine, PortString, BaudString, IrqString;
ULONG Value;
@@ -78,7 +78,7 @@ VOID DebugInit(BOOLEAN MainInit)
#endif
/* Check for pre- or main initialization phase */
- if (!MainInit)
+ if (FrLdrSectionId == 0)
{
/* Pre-initialization phase: use the FreeLdr command-line debugging string */
CommandLine = (PCHAR)CmdLineGetDebugString();
@@ -92,14 +92,10 @@ VOID DebugInit(BOOLEAN MainInit)
else
{
/* Main initialization phase: use the FreeLdr INI debugging string */
-
- ULONG_PTR SectionId;
-
- if (!IniOpenSection("FreeLoader", &SectionId))
- return;
-
- if (!IniReadSettingByName(SectionId, "Debug", DebugString,
sizeof(DebugString)))
+ if (!IniReadSettingByName(FrLdrSectionId, "Debug", DebugString,
sizeof(DebugString)))
+ {
return;
+ }
}
/* Get the Command Line */
diff --git a/boot/freeldr/freeldr/lib/fs/fs.c b/boot/freeldr/freeldr/lib/fs/fs.c
index 4000b44bd10..9aa7ca1da65 100644
--- a/boot/freeldr/freeldr/lib/fs/fs.c
+++ b/boot/freeldr/freeldr/lib/fs/fs.c
@@ -23,7 +23,6 @@
#include <freeldr.h>
#include <debug.h>
-
DBG_DEFAULT_CHANNEL(FILESYSTEM);
/* GLOBALS ********************************************************************/
@@ -199,8 +198,8 @@ ARC_STATUS ArcOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId)
if (i == MAX_FDS)
return EMFILE;
- /* Skip leading backslash, if any */
- if (*FileName == '\\')
+ /* Skip leading path separator, if any */
+ if (*FileName == '\\' || *FileName == '/')
FileName++;
/* Open the file */
@@ -263,47 +262,62 @@ VOID FileSystemError(PCSTR ErrorString)
UiMessageBox(ErrorString);
}
-ULONG FsOpenFile(PCSTR FileName)
+ARC_STATUS
+FsOpenFile(
+ IN PCSTR FileName,
+ IN PCSTR DefaultPath OPTIONAL,
+ IN OPENMODE OpenMode,
+ OUT PULONG FileId)
{
+ NTSTATUS Status;
+ SIZE_T cchPathLen;
CHAR FullPath[MAX_PATH] = "";
- ULONG FileId;
- ARC_STATUS Status;
- //
- // Print status message
- //
- TRACE("Opening file '%s'...\n", FileName);
-
- //
- // Check whether FileName is a full path
- // and if not, create a full file name.
- //
- // See ArcOpen: Search last ')', which delimits device and path.
- //
+ /*
+ * Check whether FileName is a full path and if not, create a full
+ * file name using the user-provided default path (if present).
+ *
+ * See ArcOpen(): Search last ')', which delimits device and path.
+ */
if (strrchr(FileName, ')') == NULL)
{
- /* This is not a full path. Use the current (i.e. boot) device. */
- MachDiskGetBootPath(FullPath, sizeof(FullPath));
+ /* This is not a full path: prepend the user-provided default path */
+ if (DefaultPath)
+ {
+ Status = RtlStringCbCopyA(FullPath, sizeof(FullPath), DefaultPath);
+ if (!NT_SUCCESS(Status))
+ return ENAMETOOLONG;
+ }
/* Append a path separator if needed */
- if (FileName[0] != '\\' && FileName[0] != '/')
- strcat(FullPath, "\\");
- }
- // Append (or just copy) the remaining file name.
- strcat(FullPath, FileName);
- //
- // Open the file
- //
- Status = ArcOpen(FullPath, OpenReadOnly, &FileId);
+ cchPathLen = min(sizeof(FullPath)/sizeof(CHAR), strlen(FullPath));
+ if (cchPathLen >= sizeof(FullPath)/sizeof(CHAR))
+ return ENAMETOOLONG;
- //
- // Check for success
- //
- if (Status == ESUCCESS)
- return FileId;
- else
- return 0;
+ if ((*FileName != '\\' && *FileName != '/') &&
+ cchPathLen > 0 && (FullPath[cchPathLen-1] != '\\'
&& FullPath[cchPathLen-1] != '/'))
+ {
+ /* FileName does not start with '\' and FullPath does not end with
'\' */
+ Status = RtlStringCbCatA(FullPath, sizeof(FullPath), "\\");
+ if (!NT_SUCCESS(Status))
+ return ENAMETOOLONG;
+ }
+ else if ((*FileName == '\\' || *FileName == '/') &&
+ cchPathLen > 0 && (FullPath[cchPathLen-1] == '\\' ||
FullPath[cchPathLen-1] == '/'))
+ {
+ /* FileName starts with '\' and FullPath ends with '\' */
+ while (*FileName == '\\' || *FileName == '/')
+ ++FileName; // Skip any backslash
+ }
+ }
+ /* Append (or just copy) the remaining file name */
+ Status = RtlStringCbCatA(FullPath, sizeof(FullPath), FileName);
+ if (!NT_SUCCESS(Status))
+ return ENAMETOOLONG;
+
+ /* Open the file */
+ return ArcOpen(FullPath, OpenMode, FileId);
}
/*
@@ -422,8 +436,4 @@ VOID FsInit(VOID)
FileData[i].DeviceId = (ULONG)-1;
InitializeListHead(&DeviceListHead);
-
- // FIXME: Retrieve the current boot device with MachDiskGetBootPath
- // and store it somewhere in order to not call again and again this
- // function.
}
diff --git a/boot/freeldr/freeldr/lib/peloader.c b/boot/freeldr/freeldr/lib/peloader.c
index 0d4cb3cafba..c306375816e 100644
--- a/boot/freeldr/freeldr/lib/peloader.c
+++ b/boot/freeldr/freeldr/lib/peloader.c
@@ -286,7 +286,7 @@ WinLdrLoadImage(IN PCHAR FileName,
TRACE("WinLdrLoadImage(%s, %ld, *)\n", FileName, MemoryType);
/* Open the image file */
- Status = ArcOpen(FileName, OpenReadOnly, &FileId);
+ Status = ArcOpen((PSTR)FileName, OpenReadOnly, &FileId);
if (Status != ESUCCESS)
{
WARN("ArcOpen(FileName: '%s') failed. Status: %u\n", FileName,
Status);
diff --git a/boot/freeldr/freeldr/linuxboot.c b/boot/freeldr/freeldr/linuxboot.c
index 9f0a53ef9b7..07794661bb9 100644
--- a/boot/freeldr/freeldr/linuxboot.c
+++ b/boot/freeldr/freeldr/linuxboot.c
@@ -29,8 +29,8 @@
/* INCLUDES *******************************************************************/
#include <freeldr.h>
-#include <debug.h>
+#include <debug.h>
DBG_DEFAULT_CHANNEL(LINUX);
/* GLOBALS ********************************************************************/
@@ -50,11 +50,16 @@ ULONG LinuxCommandLineSize = 0;
PVOID LinuxKernelLoadAddress = NULL;
PVOID LinuxInitrdLoadAddress = NULL;
CHAR LinuxBootDescription[80];
-PCSTR LinuxBootPath = NULL;
/* FUNCTIONS ******************************************************************/
-VOID
+static BOOLEAN LinuxReadBootSector(ULONG LinuxKernelFile);
+static BOOLEAN LinuxReadSetupSector(ULONG LinuxKernelFile);
+static BOOLEAN LinuxReadKernel(ULONG LinuxKernelFile);
+static BOOLEAN LinuxCheckKernelVersion(VOID);
+static BOOLEAN LinuxReadInitrd(ULONG LinuxInitrdFile);
+
+static VOID
RemoveQuotes(
IN OUT PSTR QuotedString)
{
@@ -85,14 +90,19 @@ LoadAndBootLinux(
IN PCHAR Argv[],
IN PCHAR Envp[])
{
+ ARC_STATUS Status;
PCSTR Description;
+ PCSTR ArgValue;
+ PCSTR BootPath;
+ UCHAR DriveNumber = 0;
+ ULONG PartitionNumber = 0;
ULONG LinuxKernel = 0;
ULONG LinuxInitrdFile = 0;
- ARC_STATUS Status;
FILEINFORMATION FileInfo;
+ CHAR ArcPath[MAX_PATH];
Description = GetArgumentValue(Argc, Argv, "LoadIdentifier");
- if (Description)
+ if (Description && *Description)
RtlStringCbPrintfA(LinuxBootDescription, sizeof(LinuxBootDescription),
"Loading %s...", Description);
else
strcpy(LinuxBootDescription, "Loading Linux...");
@@ -104,34 +114,91 @@ LoadAndBootLinux(
/* Find all the message box settings and run them */
UiShowMessageBoxesInArgv(Argc, Argv);
- /* Parse the .ini file section */
- if (!LinuxParseIniSection(Argc, Argv))
+ /*
+ * Check whether we have a "BootPath" value (takes precedence
+ * over both "BootDrive" and "BootPartition").
+ */
+ BootPath = GetArgumentValue(Argc, Argv, "BootPath");
+ if (!BootPath || !*BootPath)
+ {
+ /* We don't have one, check whether we use "BootDrive" and
"BootPartition" */
+
+ /* Retrieve the boot drive (optional, fall back to using default path otherwise)
*/
+ ArgValue = GetArgumentValue(Argc, Argv, "BootDrive");
+ if (ArgValue && *ArgValue)
+ {
+ DriveNumber = DriveMapGetBiosDriveNumber(ArgValue);
+
+ /* Retrieve the boot partition (not optional and cannot be zero) */
+ PartitionNumber = 0;
+ ArgValue = GetArgumentValue(Argc, Argv, "BootPartition");
+ if (ArgValue && *ArgValue)
+ PartitionNumber = atoi(ArgValue);
+ if (PartitionNumber == 0)
+ {
+ UiMessageBox("Boot partition cannot be 0!");
+ goto LinuxBootFailed;
+ // return EINVAL;
+ }
+
+ /* Construct the corresponding ARC path */
+ ConstructArcPath(ArcPath, "", DriveNumber, PartitionNumber);
+ *strrchr(ArcPath, '\\') = ANSI_NULL; // Trim the trailing path
separator.
+
+ BootPath = ArcPath;
+ }
+ else
+ {
+ /* Fall back to using the system partition as default path */
+ BootPath = GetArgumentValue(Argc, Argv, "SystemPartition");
+ }
+ }
+
+ /* Get the kernel name */
+ LinuxKernelName = GetArgumentValue(Argc, Argv, "Kernel");
+ if (!LinuxKernelName || !*LinuxKernelName)
+ {
+ UiMessageBox("Linux kernel filename not specified for selected OS!");
goto LinuxBootFailed;
+ }
+
+ /* Get the initrd name (optional) */
+ LinuxInitrdName = GetArgumentValue(Argc, Argv, "Initrd");
+
+ /* Get the command line (optional) */
+ LinuxCommandLineSize = 0;
+ LinuxCommandLine = GetArgumentValue(Argc, Argv, "CommandLine");
+ if (LinuxCommandLine && *LinuxCommandLine)
+ {
+ RemoveQuotes(LinuxCommandLine);
+ LinuxCommandLineSize = (ULONG)strlen(LinuxCommandLine) + 1;
+ LinuxCommandLineSize = min(LinuxCommandLineSize, 260);
+ }
/* Open the kernel */
- LinuxKernel = FsOpenFile(LinuxKernelName);
- if (!LinuxKernel)
+ Status = FsOpenFile(LinuxKernelName, BootPath, OpenReadOnly, &LinuxKernel);
+ if (Status != ESUCCESS)
{
- UiMessageBox("Linux kernel \'%s\' not found.",
LinuxKernelName);
+ UiMessageBox("Linux kernel '%s' not found.", LinuxKernelName);
goto LinuxBootFailed;
}
/* Open the initrd file image (if necessary) */
if (LinuxInitrdName)
{
- LinuxInitrdFile = FsOpenFile(LinuxInitrdName);
- if (!LinuxInitrdFile)
+ Status = FsOpenFile(LinuxInitrdName, BootPath, OpenReadOnly,
&LinuxInitrdFile);
+ if (Status != ESUCCESS)
{
- UiMessageBox("Linux initrd image \'%s\' not found.",
LinuxInitrdName);
+ UiMessageBox("Linux initrd image '%s' not found.",
LinuxInitrdName);
goto LinuxBootFailed;
}
}
- /* Read the boot sector */
+ /* Load the boot sector */
if (!LinuxReadBootSector(LinuxKernel))
goto LinuxBootFailed;
- /* Read the setup sector */
+ /* Load the setup sector */
if (!LinuxReadSetupSector(LinuxKernel))
goto LinuxBootFailed;
@@ -153,11 +220,11 @@ LoadAndBootLinux(
LinuxInitrdSize = FileInfo.EndingAddress.LowPart;
}
- /* Read the kernel */
+ /* Load the kernel */
if (!LinuxReadKernel(LinuxKernel))
goto LinuxBootFailed;
- /* Read the initrd (if necessary) */
+ /* Load the initrd (if necessary) */
if (LinuxInitrdName)
{
if (!LinuxReadInitrd(LinuxInitrdFile))
@@ -233,50 +300,11 @@ LinuxBootFailed:
LinuxKernelLoadAddress = NULL;
LinuxInitrdLoadAddress = NULL;
*LinuxBootDescription = ANSI_NULL;
- LinuxBootPath = NULL;
return ENOEXEC;
}
-BOOLEAN
-LinuxParseIniSection(
- IN ULONG Argc,
- IN PCHAR Argv[])
-{
-#if 0
- LinuxBootPath = GetArgumentValue(Argc, Argv, "BootPath");
- if (!LinuxBootPath)
- {
- UiMessageBox("Boot path not specified for selected OS!");
- return FALSE;
- }
-#endif
-
- /* Get the kernel name */
- LinuxKernelName = GetArgumentValue(Argc, Argv, "Kernel");
- if (!LinuxKernelName)
- {
- UiMessageBox("Linux kernel filename not specified for selected OS!");
- return FALSE;
- }
-
- /* Get the initrd name (optional) */
- LinuxInitrdName = GetArgumentValue(Argc, Argv, "Initrd");
-
- /* Get the command line (optional) */
- LinuxCommandLineSize = 0;
- LinuxCommandLine = GetArgumentValue(Argc, Argv, "CommandLine");
- if (LinuxCommandLine)
- {
- RemoveQuotes(LinuxCommandLine);
- LinuxCommandLineSize = (ULONG)strlen(LinuxCommandLine) + 1;
- LinuxCommandLineSize = min(LinuxCommandLineSize, 260);
- }
-
- return TRUE;
-}
-
-BOOLEAN LinuxReadBootSector(ULONG LinuxKernelFile)
+static BOOLEAN LinuxReadBootSector(ULONG LinuxKernelFile)
{
LARGE_INTEGER Position;
@@ -285,7 +313,7 @@ BOOLEAN LinuxReadBootSector(ULONG LinuxKernelFile)
if (LinuxBootSector == NULL)
return FALSE;
- /* Read linux boot sector */
+ /* Load the linux boot sector */
Position.QuadPart = 0;
if (ArcSeek(LinuxKernelFile, &Position, SeekAbsolute) != ESUCCESS)
return FALSE;
@@ -313,12 +341,12 @@ BOOLEAN LinuxReadBootSector(ULONG LinuxKernelFile)
return TRUE;
}
-BOOLEAN LinuxReadSetupSector(ULONG LinuxKernelFile)
+static BOOLEAN LinuxReadSetupSector(ULONG LinuxKernelFile)
{
LARGE_INTEGER Position;
UCHAR TempLinuxSetupSector[512];
- /* Read first linux setup sector */
+ /* Load the first linux setup sector */
Position.QuadPart = 512;
if (ArcSeek(LinuxKernelFile, &Position, SeekAbsolute) != ESUCCESS)
return FALSE;
@@ -343,7 +371,7 @@ BOOLEAN LinuxReadSetupSector(ULONG LinuxKernelFile)
/* Copy over first setup sector */
RtlCopyMemory(LinuxSetupSector, TempLinuxSetupSector, 512);
- /* Read in the rest of the linux setup sectors */
+ /* Load the rest of the linux setup sectors */
Position.QuadPart = 1024;
if (ArcSeek(LinuxKernelFile, &Position, SeekAbsolute) != ESUCCESS)
return FALSE;
@@ -371,7 +399,7 @@ BOOLEAN LinuxReadSetupSector(ULONG LinuxKernelFile)
return TRUE;
}
-BOOLEAN LinuxReadKernel(ULONG LinuxKernelFile)
+static BOOLEAN LinuxReadKernel(ULONG LinuxKernelFile)
{
PVOID LoadAddress;
LARGE_INTEGER Position;
@@ -390,7 +418,7 @@ BOOLEAN LinuxReadKernel(ULONG LinuxKernelFile)
LoadAddress = LinuxKernelLoadAddress;
- /* Read linux kernel to 0x100000 (1mb) */
+ /* Load the linux kernel at 0x100000 (1mb) */
Position.QuadPart = 512 + SetupSectorSize;
if (ArcSeek(LinuxKernelFile, &Position, SeekAbsolute) != ESUCCESS)
return FALSE;
@@ -408,7 +436,7 @@ BOOLEAN LinuxReadKernel(ULONG LinuxKernelFile)
return TRUE;
}
-BOOLEAN LinuxCheckKernelVersion(VOID)
+static BOOLEAN LinuxCheckKernelVersion(VOID)
{
/* Just assume old kernel until we find otherwise */
NewStyleLinuxKernel = FALSE;
@@ -445,7 +473,7 @@ BOOLEAN LinuxCheckKernelVersion(VOID)
return TRUE;
}
-BOOLEAN LinuxReadInitrd(ULONG LinuxInitrdFile)
+static BOOLEAN LinuxReadInitrd(ULONG LinuxInitrdFile)
{
ULONG BytesLoaded;
CHAR StatusText[260];
@@ -482,7 +510,7 @@ BOOLEAN LinuxReadInitrd(ULONG LinuxInitrdFile)
TRACE("InitrdAddressMax: 0x%x\n",
LinuxSetupSector->InitrdAddressMax);
}
- /* Read in the ramdisk */
+ /* Load the ramdisk */
for (BytesLoaded=0; BytesLoaded<LinuxInitrdSize; )
{
if (ArcRead(LinuxInitrdFile, (PVOID)LinuxInitrdLoadAddress,
LINUX_READ_CHUNK_SIZE, NULL) != ESUCCESS)
diff --git a/boot/freeldr/freeldr/miscboot.c b/boot/freeldr/freeldr/miscboot.c
index f7a0e2a912e..7d40c8a7811 100644
--- a/boot/freeldr/freeldr/miscboot.c
+++ b/boot/freeldr/freeldr/miscboot.c
@@ -32,34 +32,79 @@ LoadAndBootBootSector(
IN PCHAR Envp[])
{
ARC_STATUS Status;
+ PCSTR ArgValue;
+ PCSTR BootPath;
PCSTR FileName;
+ UCHAR DriveNumber = 0;
+ ULONG PartitionNumber = 0;
ULONG FileId;
ULONG BytesRead;
+ CHAR ArcPath[MAX_PATH];
/* Find all the message box settings and run them */
UiShowMessageBoxesInArgv(Argc, Argv);
- /* Read the file name */
+ /*
+ * Check whether we have a "BootPath" value (takes precedence
+ * over both "BootDrive" and "BootPartition").
+ */
+ BootPath = GetArgumentValue(Argc, Argv, "BootPath");
+ if (!BootPath || !*BootPath)
+ {
+ /* We don't have one, check whether we use "BootDrive" and
"BootPartition" */
+
+ /* Retrieve the boot drive (optional, fall back to using default path otherwise)
*/
+ ArgValue = GetArgumentValue(Argc, Argv, "BootDrive");
+ if (ArgValue && *ArgValue)
+ {
+ DriveNumber = DriveMapGetBiosDriveNumber(ArgValue);
+
+ /* Retrieve the boot partition (not optional and cannot be zero) */
+ PartitionNumber = 0;
+ ArgValue = GetArgumentValue(Argc, Argv, "BootPartition");
+ if (ArgValue && *ArgValue)
+ PartitionNumber = atoi(ArgValue);
+ if (PartitionNumber == 0)
+ {
+ UiMessageBox("Boot partition cannot be 0!");
+ return EINVAL;
+ }
+
+ /* Construct the corresponding ARC path */
+ ConstructArcPath(ArcPath, "", DriveNumber, PartitionNumber);
+ *strrchr(ArcPath, '\\') = ANSI_NULL; // Trim the trailing path
separator.
+
+ BootPath = ArcPath;
+ }
+ else
+ {
+ /* Fall back to using the system partition as default path */
+ BootPath = GetArgumentValue(Argc, Argv, "SystemPartition");
+ }
+ }
+
+ /* Retrieve the file name */
FileName = GetArgumentValue(Argc, Argv, "BootSectorFile");
- if (!FileName)
+ if (!FileName || !*FileName)
{
UiMessageBox("Boot sector file not specified for selected OS!");
return EINVAL;
}
- FileId = FsOpenFile(FileName);
- if (!FileId)
+ /* Open the boot sector file */
+ Status = FsOpenFile(FileName, BootPath, OpenReadOnly, &FileId);
+ if (Status != ESUCCESS)
{
- UiMessageBox("%s not found.", FileName);
- return ENOENT;
+ UiMessageBox("Unable to open %s", FileName);
+ return Status;
}
- /* Read boot sector */
+ /* Now try to load the boot sector. If this fails then abort. */
Status = ArcRead(FileId, (PVOID)0x7c00, 512, &BytesRead);
ArcClose(FileId);
if ((Status != ESUCCESS) || (BytesRead != 512))
{
- UiMessageBox("Unable to read boot sector.");
+ UiMessageBox("Unable to load boot sector.");
return EIO;
}
@@ -92,27 +137,51 @@ LoadAndBootBootSector(
static ARC_STATUS
LoadAndBootPartitionOrDrive(
IN UCHAR DriveNumber,
- IN ULONG PartitionNumber OPTIONAL)
+ IN ULONG PartitionNumber OPTIONAL,
+ IN PCSTR BootPath OPTIONAL)
{
ARC_STATUS Status;
ULONG FileId;
ULONG BytesRead;
CHAR ArcPath[MAX_PATH];
- /* Construct the corresponding ARC path */
- ConstructArcPath(ArcPath, "", DriveNumber, PartitionNumber);
- *strrchr(ArcPath, '\\') = ANSI_NULL; // Trim the trailing path separator.
+ /*
+ * If the user specifies an ARC "BootPath" value, it takes precedence
+ * over both the DriveNumber and PartitionNumber options.
+ */
+ if (BootPath && *BootPath)
+ {
+ PCSTR FileName = NULL;
+
+ /*
+ * Retrieve the BIOS drive and partition numbers; verify also that the
+ * path is "valid" in the sense that it must not contain any file
name.
+ */
+ if (!DissectArcPath(BootPath, &FileName, &DriveNumber,
&PartitionNumber) ||
+ (FileName && *FileName))
+ {
+ return EINVAL;
+ }
+ }
+ else
+ {
+ /* We don't have one, so construct the corresponding ARC path */
+ ConstructArcPath(ArcPath, "", DriveNumber, PartitionNumber);
+ *strrchr(ArcPath, '\\') = ANSI_NULL; // Trim the trailing path
separator.
+
+ BootPath = ArcPath;
+ }
/* Open the volume */
- Status = ArcOpen(ArcPath, OpenReadOnly, &FileId);
+ Status = ArcOpen((PSTR)BootPath, OpenReadOnly, &FileId);
if (Status != ESUCCESS)
{
- UiMessageBox("Unable to open %s", ArcPath);
- return ENOENT;
+ UiMessageBox("Unable to open %s", BootPath);
+ return Status;
}
/*
- * Now try to read the partition boot sector or the MBR (when PartitionNumber == 0).
+ * Now try to load the partition boot sector or the MBR (when PartitionNumber == 0).
* If this fails then abort.
*/
Status = ArcRead(FileId, (PVOID)0x7c00, 512, &BytesRead);
@@ -120,9 +189,9 @@ LoadAndBootPartitionOrDrive(
if ((Status != ESUCCESS) || (BytesRead != 512))
{
if (PartitionNumber != 0)
- UiMessageBox("Unable to read partition's boot sector.");
+ UiMessageBox("Unable to load partition's boot sector.");
else
- UiMessageBox("Unable to read MBR boot sector.");
+ UiMessageBox("Unable to load MBR boot sector.");
return EIO;
}
@@ -160,31 +229,39 @@ LoadAndBootPartition(
IN PCHAR Envp[])
{
PCSTR ArgValue;
- UCHAR DriveNumber;
- ULONG PartitionNumber;
+ PCSTR BootPath;
+ UCHAR DriveNumber = 0;
+ ULONG PartitionNumber = 0;
/* Find all the message box settings and run them */
UiShowMessageBoxesInArgv(Argc, Argv);
- /* Read the boot drive */
- ArgValue = GetArgumentValue(Argc, Argv, "BootDrive");
- if (!ArgValue)
+ /*
+ * Check whether we have a "BootPath" value (takes precedence
+ * over both "BootDrive" and "BootPartition").
+ */
+ BootPath = GetArgumentValue(Argc, Argv, "BootPath");
+ if (!BootPath || !*BootPath)
{
- UiMessageBox("Boot drive not specified for selected OS!");
- return EINVAL;
- }
- DriveNumber = DriveMapGetBiosDriveNumber(ArgValue);
+ /* We don't have one */
- /* Read the boot partition */
- ArgValue = GetArgumentValue(Argc, Argv, "BootPartition");
- if (!ArgValue)
- {
- UiMessageBox("Boot partition not specified for selected OS!");
- return EINVAL;
+ /* Retrieve the boot drive */
+ ArgValue = GetArgumentValue(Argc, Argv, "BootDrive");
+ if (!ArgValue || !*ArgValue)
+ {
+ UiMessageBox("Boot drive not specified for selected OS!");
+ return EINVAL;
+ }
+ DriveNumber = DriveMapGetBiosDriveNumber(ArgValue);
+
+ /* Retrieve the boot partition (optional, fall back to zero otherwise) */
+ PartitionNumber = 0;
+ ArgValue = GetArgumentValue(Argc, Argv, "BootPartition");
+ if (ArgValue && *ArgValue)
+ PartitionNumber = atoi(ArgValue);
}
- PartitionNumber = atoi(ArgValue);
- return LoadAndBootPartitionOrDrive(DriveNumber, PartitionNumber);
+ return LoadAndBootPartitionOrDrive(DriveNumber, PartitionNumber, BootPath);
}
ARC_STATUS
@@ -194,21 +271,39 @@ LoadAndBootDrive(
IN PCHAR Envp[])
{
PCSTR ArgValue;
- UCHAR DriveNumber;
+ PCSTR BootPath;
+ UCHAR DriveNumber = 0;
/* Find all the message box settings and run them */
UiShowMessageBoxesInArgv(Argc, Argv);
- /* Read the boot drive */
- ArgValue = GetArgumentValue(Argc, Argv, "BootDrive");
- if (!ArgValue)
+ /* Check whether we have a "BootPath" value (takes precedence over
"BootDrive") */
+ BootPath = GetArgumentValue(Argc, Argv, "BootPath");
+ if (BootPath && *BootPath)
{
- UiMessageBox("Boot drive not specified for selected OS!");
- return EINVAL;
+ /*
+ * We have one, check that it does not contain any
+ * "partition()" specification, and fail if so.
+ */
+ if (strstr(BootPath, ")partition("))
+ {
+ UiMessageBox("Invalid 'BootPath' value!");
+ return EINVAL;
+ }
+ }
+ else
+ {
+ /* We don't, retrieve the boot drive value instead */
+ ArgValue = GetArgumentValue(Argc, Argv, "BootDrive");
+ if (!ArgValue || !*ArgValue)
+ {
+ UiMessageBox("Boot drive not specified for selected OS!");
+ return EINVAL;
+ }
+ DriveNumber = DriveMapGetBiosDriveNumber(ArgValue);
}
- DriveNumber = DriveMapGetBiosDriveNumber(ArgValue);
- return LoadAndBootPartitionOrDrive(DriveNumber, 0);
+ return LoadAndBootPartitionOrDrive(DriveNumber, 0, BootPath);
}
#endif // _M_IX86
diff --git a/boot/freeldr/freeldr/ntldr/inffile.c b/boot/freeldr/freeldr/ntldr/inffile.c
index 950accbe8a8..b3c40606e9a 100644
--- a/boot/freeldr/freeldr/ntldr/inffile.c
+++ b/boot/freeldr/freeldr/ntldr/inffile.c
@@ -934,7 +934,7 @@ InfOpenFile(
//
// Open the .inf file
//
- Status = ArcOpen((PCHAR)FileName, OpenReadOnly, &FileId);
+ Status = ArcOpen((PSTR)FileName, OpenReadOnly, &FileId);
if (Status != ESUCCESS)
{
return FALSE;
diff --git a/boot/freeldr/freeldr/ntldr/setupldr.c
b/boot/freeldr/freeldr/ntldr/setupldr.c
index 0fe5c1fcfd4..81e76feca2c 100644
--- a/boot/freeldr/freeldr/ntldr/setupldr.c
+++ b/boot/freeldr/freeldr/ntldr/setupldr.c
@@ -135,10 +135,12 @@ LoadReactOSSetup(
IN PCHAR Argv[],
IN PCHAR Envp[])
{
+ ARC_STATUS Status;
PCSTR ArgValue;
+ PCSTR SystemPartition;
PCHAR File;
- CHAR FileName[512];
- CHAR BootPath[512];
+ CHAR FileName[MAX_PATH];
+ CHAR BootPath[MAX_PATH];
CHAR BootOptions2[256];
PCSTR LoadOptions;
PSTR BootOptions;
@@ -165,6 +167,14 @@ LoadReactOSSetup(
NULL
};
+ /* Retrieve the (mandatory) system partition */
+ SystemPartition = GetArgumentValue(Argc, Argv, "SystemPartition");
+ if (!SystemPartition || !*SystemPartition)
+ {
+ ERR("No 'SystemPartition' specified, aborting!\n");
+ return EINVAL;
+ }
+
UiDrawStatusText("Setup is loading...");
UiDrawBackdrop();
@@ -180,13 +190,12 @@ LoadReactOSSetup(
else
{
/*
- * IMPROVE: I don't want to call MachDiskGetBootPath here as a
- * default choice because I can call it after (see few lines below).
+ * IMPROVE: I don't want to use the SystemPartition here as a
+ * default choice because I can do it after (see few lines below).
* Instead I reset BootPath here so that we can build the full path
* using the general code from below.
*/
- // MachDiskGetBootPath(BootPath, sizeof(BootPath));
- // RtlStringCbCopyA(BootPath, sizeof(BootPath), ArgValue);
+ // RtlStringCbCopyA(BootPath, sizeof(BootPath), SystemPartition);
*BootPath = ANSI_NULL;
}
@@ -201,8 +210,8 @@ LoadReactOSSetup(
/* Temporarily save the boot path */
RtlStringCbCopyA(FileName, sizeof(FileName), BootPath);
- /* This is not a full path. Use the current (i.e. boot) device. */
- MachDiskGetBootPath(BootPath, sizeof(BootPath));
+ /* This is not a full path: prepend the SystemPartition */
+ RtlStringCbCopyA(BootPath, sizeof(BootPath), SystemPartition);
/* Append a path separator if needed */
if (*FileName != '\\' && *FileName != '/')
@@ -212,7 +221,7 @@ LoadReactOSSetup(
RtlStringCbCatA(BootPath, sizeof(BootPath), FileName);
}
- /* Append a backslash if needed */
+ /* Append a path separator if needed */
if (!*BootPath || BootPath[strlen(BootPath) - 1] != '\\')
RtlStringCbCatA(BootPath, sizeof(BootPath), "\\");
@@ -221,7 +230,7 @@ LoadReactOSSetup(
/* Retrieve the boot options */
*BootOptions2 = ANSI_NULL;
ArgValue = GetArgumentValue(Argc, Argv, "Options");
- if (ArgValue)
+ if (ArgValue && *ArgValue)
RtlStringCbCopyA(BootOptions2, sizeof(BootOptions2), ArgValue);
TRACE("BootOptions: '%s'\n", BootOptions2);
@@ -237,10 +246,11 @@ LoadReactOSSetup(
*strstr(FileName, " ") = ANSI_NULL;
/* Load the ramdisk */
- if (!RamDiskLoadVirtualFile(FileName))
+ Status = RamDiskLoadVirtualFile(FileName, SystemPartition);
+ if (Status != ESUCCESS)
{
UiMessageBox("Failed to load RAM disk file %s", FileName);
- return ENOENT;
+ return Status;
}
}
@@ -292,7 +302,7 @@ LoadReactOSSetup(
}
#endif
- /* Copy loadoptions (original string will be freed) */
+ /* Copy LoadOptions (original string will be freed) */
BootOptions = FrLdrTempAlloc(strlen(LoadOptions) + 1, TAG_BOOT_OPTIONS);
ASSERT(BootOptions);
strcpy(BootOptions, LoadOptions);
diff --git a/boot/freeldr/freeldr/ntldr/winldr.c b/boot/freeldr/freeldr/ntldr/winldr.c
index b114adbef27..a30d763ca65 100644
--- a/boot/freeldr/freeldr/ntldr/winldr.c
+++ b/boot/freeldr/freeldr/ntldr/winldr.c
@@ -65,11 +65,13 @@ WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock,
PCSTR BootPath,
USHORT VersionToBoot)
{
- /* Examples of correct options and paths */
- //CHAR Options[] = "/DEBUGPORT=COM1 /BAUDRATE=115200";
- //CHAR Options[] = "/NODEBUG";
- //CHAR SystemRoot[] = "\\WINNT\\";
- //CHAR ArcBoot[] = "multi(0)disk(0)rdisk(0)partition(1)";
+ /*
+ * Examples of correct options and paths:
+ * CHAR Options[] = "/DEBUGPORT=COM1 /BAUDRATE=115200";
+ * CHAR Options[] = "/NODEBUG";
+ * CHAR SystemRoot[] = "\\WINNT\\";
+ * CHAR ArcBoot[] = "multi(0)disk(0)rdisk(0)partition(1)";
+ */
PSTR LoadOptions, NewLoadOptions;
CHAR HalPath[] = "\\";
@@ -367,7 +369,7 @@ WinLdrLoadModule(PCSTR ModuleName,
*Size = 0;
/* Open the image file */
- Status = ArcOpen((PCHAR)ModuleName, OpenReadOnly, &FileId);
+ Status = ArcOpen((PSTR)ModuleName, OpenReadOnly, &FileId);
if (Status != ESUCCESS)
{
/* In case of errors, we just return, without complaining to the user */
@@ -413,17 +415,16 @@ WinLdrDetectVersion(VOID)
LONG rc;
HKEY hKey;
- rc = RegOpenKey(
- NULL,
- L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\Terminal
Server",
- &hKey);
+ rc = RegOpenKey(NULL,
+
L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\Terminal Server",
+ &hKey);
if (rc != ERROR_SUCCESS)
{
- // Key doesn't exist; assume NT 4.0
+ /* Key doesn't exist; assume NT 4.0 */
return _WIN32_WINNT_NT4;
}
- // We may here want to read the value of ProductVersion
+ /* We may here want to read the value of ProductVersion */
return _WIN32_WINNT_WS03;
}
@@ -483,8 +484,8 @@ LoadWindowsCore(IN USHORT OperatingSystemVersion,
BOOLEAN Success;
PCSTR Options;
CHAR DirPath[MAX_PATH];
- CHAR KernelFileName[MAX_PATH];
CHAR HalFileName[MAX_PATH];
+ CHAR KernelFileName[MAX_PATH];
CHAR KdTransportDllName[MAX_PATH];
PLDR_DATA_TABLE_ENTRY HalDTE, KdComDTE = NULL;
@@ -494,25 +495,27 @@ LoadWindowsCore(IN USHORT OperatingSystemVersion,
RtlStringCbCopyA(DirPath, sizeof(DirPath), BootPath);
RtlStringCbCatA(DirPath, sizeof(DirPath), "system32\\");
- //
- // TODO: Parse also the separate INI values "Kernel=" and "Hal="
- //
-
- /* Default KERNEL and HAL file names */
- RtlStringCbCopyA(KernelFileName, sizeof(KernelFileName), "ntoskrnl.exe");
+ /*
+ * Default HAL and KERNEL file names.
+ * See the following links to know how the file names are actually chosen:
+ *
https://www.geoffchappell.com/notes/windows/boot/bcd/osloader/detecthal.htm
+ *
https://www.geoffchappell.com/notes/windows/boot/bcd/osloader/hal.htm
+ *
https://www.geoffchappell.com/notes/windows/boot/bcd/osloader/kernel.htm
+ */
RtlStringCbCopyA(HalFileName , sizeof(HalFileName) , "hal.dll");
+ RtlStringCbCopyA(KernelFileName, sizeof(KernelFileName), "ntoskrnl.exe");
- /* Find any /KERNEL= or /HAL= switch in the boot options */
+ /* Find any "/HAL=" or "/KERNEL=" switch in the boot options */
Options = BootOptions;
while (Options)
{
/* Skip possible initial whitespace */
Options += strspn(Options, " \t");
- /* Check whether a new option starts and it is either KERNEL or HAL */
+ /* Check whether a new option starts and it is either HAL or KERNEL */
if (*Options != '/' || (++Options,
- !(_strnicmp(Options, "KERNEL=", 7) == 0 ||
- _strnicmp(Options, "HAL=", 4) == 0)) )
+ !(_strnicmp(Options, "HAL=", 4) == 0 ||
+ _strnicmp(Options, "KERNEL=", 7) == 0)) )
{
/* Search for another whitespace */
Options = strpbrk(Options, " \t");
@@ -527,23 +530,23 @@ LoadWindowsCore(IN USHORT OperatingSystemVersion,
break;
}
- /* We have found either KERNEL or HAL options */
- if (_strnicmp(Options, "KERNEL=", 7) == 0)
- {
- Options += 7; i -= 7;
- RtlStringCbCopyNA(KernelFileName, sizeof(KernelFileName), Options, i);
- _strupr(KernelFileName);
- }
- else if (_strnicmp(Options, "HAL=", 4) == 0)
+ /* We have found either HAL or KERNEL options */
+ if (_strnicmp(Options, "HAL=", 4) == 0)
{
Options += 4; i -= 4;
RtlStringCbCopyNA(HalFileName, sizeof(HalFileName), Options, i);
_strupr(HalFileName);
}
+ else if (_strnicmp(Options, "KERNEL=", 7) == 0)
+ {
+ Options += 7; i -= 7;
+ RtlStringCbCopyNA(KernelFileName, sizeof(KernelFileName), Options, i);
+ _strupr(KernelFileName);
+ }
}
}
- TRACE("Kernel file = '%s' ; HAL file = '%s'\n",
KernelFileName, HalFileName);
+ TRACE("HAL file = '%s' ; Kernel file = '%s'\n",
HalFileName, KernelFileName);
/* Load the Kernel */
LoadModule(LoaderBlock, DirPath, KernelFileName, "ntoskrnl.exe",
LoaderSystemCode, KernelDTE, 30);
@@ -653,7 +656,9 @@ LoadAndBootWindows(
IN PCHAR Argv[],
IN PCHAR Envp[])
{
+ ARC_STATUS Status;
PCSTR ArgValue;
+ PCSTR SystemPartition;
PCHAR File;
BOOLEAN Success;
USHORT OperatingSystemVersion;
@@ -662,13 +667,15 @@ LoadAndBootWindows(
CHAR FileName[MAX_PATH];
CHAR BootOptions[256];
+ /* Retrieve the (mandatory) boot type */
ArgValue = GetArgumentValue(Argc, Argv, "BootType");
- if (!ArgValue)
+ if (!ArgValue || !*ArgValue)
{
ERR("No 'BootType' value, aborting!\n");
return EINVAL;
}
+ /* Convert it to an OS version */
if (_stricmp(ArgValue, "Windows") == 0 ||
_stricmp(ArgValue, "Windows2003") == 0)
{
@@ -684,6 +691,14 @@ LoadAndBootWindows(
return EINVAL;
}
+ /* Retrieve the (mandatory) system partition */
+ SystemPartition = GetArgumentValue(Argc, Argv, "SystemPartition");
+ if (!SystemPartition || !*SystemPartition)
+ {
+ ERR("No 'SystemPartition' specified, aborting!\n");
+ return EINVAL;
+ }
+
UiDrawBackdrop();
UiDrawProgressBarCenter(1, 100, "Loading NT...");
@@ -704,8 +719,8 @@ LoadAndBootWindows(
/* Temporarily save the boot path */
RtlStringCbCopyA(FileName, sizeof(FileName), BootPath);
- /* This is not a full path. Use the current (i.e. boot) device. */
- MachDiskGetBootPath(BootPath, sizeof(BootPath));
+ /* This is not a full path: prepend the SystemPartition */
+ RtlStringCbCopyA(BootPath, sizeof(BootPath), SystemPartition);
/* Append a path separator if needed */
if (*FileName != '\\' && *FileName != '/')
@@ -715,7 +730,7 @@ LoadAndBootWindows(
RtlStringCbCatA(BootPath, sizeof(BootPath), FileName);
}
- /* Append a backslash if needed */
+ /* Append a path separator if needed */
if (!*BootPath || BootPath[strlen(BootPath) - 1] != '\\')
RtlStringCbCatA(BootPath, sizeof(BootPath), "\\");
@@ -724,12 +739,45 @@ LoadAndBootWindows(
/* Retrieve the boot options */
*BootOptions = ANSI_NULL;
ArgValue = GetArgumentValue(Argc, Argv, "Options");
- if (ArgValue)
+ if (ArgValue && *ArgValue)
RtlStringCbCopyA(BootOptions, sizeof(BootOptions), ArgValue);
/* Append boot-time options */
AppendBootTimeOptions(BootOptions);
+ /*
+ * Set "/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.
+ */
+ if (strstr(BootOptions, "/HAL=") != 0)
+ {
+ /*
+ * Not found in the options, try to retrieve the
+ * separate value and append it to the options.
+ */
+ ArgValue = GetArgumentValue(Argc, Argv, "Hal");
+ if (ArgValue && *ArgValue)
+ {
+ RtlStringCbCatA(BootOptions, sizeof(BootOptions), " /HAL=");
+ RtlStringCbCatA(BootOptions, sizeof(BootOptions), ArgValue);
+ }
+ }
+ if (strstr(BootOptions, "/KERNEL=") != 0)
+ {
+ /*
+ * Not found in the options, try to retrieve the
+ * separate value and append it to the options.
+ */
+ ArgValue = GetArgumentValue(Argc, Argv, "Kernel");
+ if (ArgValue && *ArgValue)
+ {
+ RtlStringCbCatA(BootOptions, sizeof(BootOptions), " /KERNEL=");
+ RtlStringCbCatA(BootOptions, sizeof(BootOptions), ArgValue);
+ }
+ }
+
TRACE("BootOptions: '%s'\n", BootOptions);
/* Check if a ramdisk file was given */
@@ -743,10 +791,11 @@ LoadAndBootWindows(
*strstr(FileName, " ") = ANSI_NULL;
/* Load the ramdisk */
- if (!RamDiskLoadVirtualFile(FileName))
+ Status = RamDiskLoadVirtualFile(FileName, SystemPartition);
+ if (Status != ESUCCESS)
{
UiMessageBox("Failed to load RAM disk file %s", FileName);
- return ENOENT;
+ return Status;
}
}
diff --git a/boot/freeldr/freeldr/oslist.c b/boot/freeldr/freeldr/oslist.c
index a509e15d556..3a05ebd2fba 100644
--- a/boot/freeldr/freeldr/oslist.c
+++ b/boot/freeldr/freeldr/oslist.c
@@ -20,8 +20,8 @@
/* INCLUDES *******************************************************************/
#include <freeldr.h>
-#include <debug.h>
+#include <debug.h>
DBG_DEFAULT_CHANNEL(INIFILE);
#define TAG_OS_ITEM 'tISO'
@@ -42,49 +42,16 @@ static PCSTR CopyString(PCSTR Source)
return Dest;
}
-static ULONG
-GetDefaultOperatingSystem(
- IN OperatingSystemItem* OperatingSystemList,
- IN ULONG OperatingSystemCount)
-{
- ULONG DefaultOS = 0;
- ULONG i;
- ULONG_PTR SectionId;
- PCSTR DefaultOSName;
- CHAR DefaultOSText[80];
-
- if (!IniOpenSection("FreeLoader", &SectionId))
- return 0;
-
- DefaultOSName = CmdLineGetDefaultOS();
- if (DefaultOSName == NULL)
- {
- if (IniReadSettingByName(SectionId, "DefaultOS", DefaultOSText,
sizeof(DefaultOSText)))
- {
- DefaultOSName = DefaultOSText;
- }
- }
-
- if (DefaultOSName != NULL)
- {
- for (i = 0; i < OperatingSystemCount; ++i)
- {
- if (_stricmp(DefaultOSName, OperatingSystemList[i].SectionName) == 0)
- {
- DefaultOS = i;
- break;
- }
- }
- }
-
- return DefaultOS;
-}
-
OperatingSystemItem*
InitOperatingSystemList(
+ IN ULONG_PTR FrLdrSectionId,
OUT PULONG OperatingSystemCount,
OUT PULONG DefaultOperatingSystem)
{
+ ULONG DefaultOS = 0;
+ PCSTR DefaultOSName = NULL;
+ CHAR DefaultOSText[80];
+
OperatingSystemItem* Items;
ULONG Count;
ULONG i;
@@ -110,7 +77,18 @@ InitOperatingSystemList(
if (!Items)
return NULL;
- /* Now loop through and read the operating system section and display names */
+ /* Retrieve which OS is the default one */
+ DefaultOSName = CmdLineGetDefaultOS();
+ 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 */
for (i = 0; i < Count; ++i)
{
IniReadSettingByNumber(OsSectionId, i,
@@ -118,7 +96,7 @@ InitOperatingSystemList(
SettingValue, sizeof(SettingValue));
if (!*SettingName)
{
- ERR("Invalid OS entry number %lu, skipping.\n", i);
+ ERR("Invalid OS entry %lu, skipping.\n", i);
continue;
}
@@ -151,6 +129,13 @@ InitOperatingSystemList(
// "OsLoadOptions = '%s'\n",
// SettingName, TitleStart, OsLoadOptions);
+ /* Find the default OS item while we haven't got one */
+ if (DefaultOSName && _stricmp(DefaultOSName, SettingName) == 0)
+ {
+ DefaultOS = i;
+ DefaultOSName = NULL; // We have found the first one, don't search for
others.
+ }
+
/*
* Determine whether this is a legacy operating system entry of the form:
*
@@ -174,6 +159,7 @@ InitOperatingSystemList(
*/
/* Try to open the operating system section in the .ini file */
+ SectionId = 0;
HadSection = IniOpenSection(SettingName, &SectionId);
if (HadSection)
{
@@ -192,7 +178,7 @@ InitOperatingSystemList(
{
#ifdef _M_IX86
ULONG FileId;
- if (ArcOpen((PSTR)SettingName, OpenReadOnly, &FileId) == ESUCCESS)
+ if (ArcOpen(SettingName, OpenReadOnly, &FileId) == ESUCCESS)
{
ArcClose(FileId);
strcpy(BootType, "BootSector");
@@ -236,7 +222,7 @@ InitOperatingSystemList(
/* Add the section */
if (!IniAddSection(SettingName, &SectionId))
{
- ERR("Could not convert legacy OS entry! Continuing...\n");
+ ERR("Could not convert legacy OS entry %lu, skipping.\n", i);
continue;
}
@@ -245,7 +231,7 @@ InitOperatingSystemList(
{
if (!IniAddSettingValueToSection(SectionId, "BootSectorFile",
TempBuffer))
{
- ERR("Could not convert legacy OS entry! Continuing...\n");
+ ERR("Could not convert legacy OS entry %lu, skipping.\n",
i);
continue;
}
}
@@ -253,7 +239,7 @@ InitOperatingSystemList(
{
if (!IniAddSettingValueToSection(SectionId, "SystemPath",
TempBuffer))
{
- ERR("Could not convert legacy OS entry! Continuing...\n");
+ ERR("Could not convert legacy OS entry %lu, skipping.\n",
i);
continue;
}
}
@@ -265,7 +251,7 @@ InitOperatingSystemList(
/* Add the OS options */
if (OsLoadOptions && !IniAddSettingValueToSection(SectionId,
"Options", OsLoadOptions))
{
- ERR("Could not convert legacy OS entry! Continuing...\n");
+ ERR("Could not convert legacy OS entry %lu, skipping.\n", i);
continue;
}
}
@@ -296,14 +282,15 @@ InitOperatingSystemList(
ERR("Could not modify the options for OS '%s',
ignoring.\n", SettingName);
}
- /* Copy the OS section name and identifier */
- Items[i].SectionName = CopyString(SettingName);
+ /* Copy the OS section ID and its identifier */
+ Items[i].SectionId = SectionId;
Items[i].LoadIdentifier = CopyString(TitleStart);
- // TRACE("We did Items[%lu]: SectionName = '%s', LoadIdentifier =
'%s'\n", i, Items[i].SectionName, Items[i].LoadIdentifier);
+ // TRACE("We did Items[%lu]: SectionName = '%s' (SectionId = 0x%p),
LoadIdentifier = '%s'\n",
+ // i, SettingName, Items[i].SectionId, Items[i].LoadIdentifier);
}
/* Return success */
*OperatingSystemCount = Count;
- *DefaultOperatingSystem = GetDefaultOperatingSystem(Items, Count);
+ *DefaultOperatingSystem = DefaultOS;
return Items;
}
diff --git a/boot/freeldr/freeldr/ui/directui.c b/boot/freeldr/freeldr/ui/directui.c
index 519fd510dd0..d4fec816131 100644
--- a/boot/freeldr/freeldr/ui/directui.c
+++ b/boot/freeldr/freeldr/ui/directui.c
@@ -10,7 +10,6 @@
/* INCLUDES *******************************************************************/
#include <freeldr.h>
-#include <debug.h>
/* GLOBALS ********************************************************************/
@@ -252,7 +251,8 @@ UiDrawProgressBar(IN ULONG Left,
}
VOID
-UiShowMessageBoxesInSection(IN PCSTR SectionName)
+UiShowMessageBoxesInSection(
+ IN ULONG_PTR SectionId)
{
return;
}
@@ -270,7 +270,8 @@ UiTruncateStringEllipsis(IN PCHAR StringText,
IN ULONG MaxChars)
{
/* If it's too large, just add some ellipsis past the maximum */
- if (strlen(StringText) > MaxChars) strcpy(&StringText[MaxChars - 3],
"...");
+ if (strlen(StringText) > MaxChars)
+ strcpy(&StringText[MaxChars - 3], "...");
}
VOID
diff --git a/boot/freeldr/freeldr/ui/tui.c b/boot/freeldr/freeldr/ui/tui.c
index 44f80163a5b..9b5fad75efe 100644
--- a/boot/freeldr/freeldr/ui/tui.c
+++ b/boot/freeldr/freeldr/ui/tui.c
@@ -22,7 +22,7 @@
#define TAG_TUI_SCREENBUFFER 'SiuT'
#define TAG_TAG_TUI_PALETTE 'PiuT'
-PVOID TextVideoBuffer = NULL;
+PVOID TextVideoBuffer = NULL;
/*
* TuiPrintf()
@@ -699,55 +699,58 @@ VOID TuiDrawProgressBar(ULONG Left, ULONG Top, ULONG Right, ULONG
Bottom, ULONG
UCHAR TuiTextToColor(PCSTR ColorText)
{
- if (_stricmp(ColorText, "Black") == 0)
- return COLOR_BLACK;
- else if (_stricmp(ColorText, "Blue") == 0)
- return COLOR_BLUE;
- else if (_stricmp(ColorText, "Green") == 0)
- return COLOR_GREEN;
- else if (_stricmp(ColorText, "Cyan") == 0)
- return COLOR_CYAN;
- else if (_stricmp(ColorText, "Red") == 0)
- return COLOR_RED;
- else if (_stricmp(ColorText, "Magenta") == 0)
- return COLOR_MAGENTA;
- else if (_stricmp(ColorText, "Brown") == 0)
- return COLOR_BROWN;
- else if (_stricmp(ColorText, "Gray") == 0)
- return COLOR_GRAY;
- else if (_stricmp(ColorText, "DarkGray") == 0)
- return COLOR_DARKGRAY;
- else if (_stricmp(ColorText, "LightBlue") == 0)
- return COLOR_LIGHTBLUE;
- else if (_stricmp(ColorText, "LightGreen") == 0)
- return COLOR_LIGHTGREEN;
- else if (_stricmp(ColorText, "LightCyan") == 0)
- return COLOR_LIGHTCYAN;
- else if (_stricmp(ColorText, "LightRed") == 0)
- return COLOR_LIGHTRED;
- else if (_stricmp(ColorText, "LightMagenta") == 0)
- return COLOR_LIGHTMAGENTA;
- else if (_stricmp(ColorText, "Yellow") == 0)
- return COLOR_YELLOW;
- else if (_stricmp(ColorText, "White") == 0)
- return COLOR_WHITE;
+ static const struct
+ {
+ PCSTR ColorName;
+ UCHAR ColorValue;
+ } Colors[] =
+ {
+ {"Black" , COLOR_BLACK },
+ {"Blue" , COLOR_BLUE },
+ {"Green" , COLOR_GREEN },
+ {"Cyan" , COLOR_CYAN },
+ {"Red" , COLOR_RED },
+ {"Magenta", COLOR_MAGENTA},
+ {"Brown" , COLOR_BROWN },
+ {"Gray" , COLOR_GRAY },
+ {"DarkGray" , COLOR_DARKGRAY },
+ {"LightBlue" , COLOR_LIGHTBLUE },
+ {"LightGreen" , COLOR_LIGHTGREEN },
+ {"LightCyan" , COLOR_LIGHTCYAN },
+ {"LightRed" , COLOR_LIGHTRED },
+ {"LightMagenta", COLOR_LIGHTMAGENTA},
+ {"Yellow" , COLOR_YELLOW },
+ {"White" , COLOR_WHITE },
+ };
+ ULONG i;
+
+ for (i = 0; i < sizeof(Colors)/sizeof(Colors[0]); ++i)
+ {
+ if (_stricmp(ColorText, Colors[i].ColorName) == 0)
+ return Colors[i].ColorValue;
+ }
return COLOR_BLACK;
}
UCHAR TuiTextToFillStyle(PCSTR FillStyleText)
{
- if (_stricmp(FillStyleText, "Light") == 0)
+ static const struct
{
- return LIGHT_FILL;
- }
- else if (_stricmp(FillStyleText, "Medium") == 0)
+ PCSTR FillStyleName;
+ UCHAR FillStyleValue;
+ } FillStyles[] =
{
- return MEDIUM_FILL;
- }
- else if (_stricmp(FillStyleText, "Dark") == 0)
+ {"Light" , LIGHT_FILL },
+ {"Medium", MEDIUM_FILL},
+ {"Dark" , DARK_FILL },
+ };
+ ULONG i;
+
+ for (i = 0; i < sizeof(FillStyles)/sizeof(FillStyles[0]); ++i)
{
- return DARK_FILL;
+ if (_stricmp(FillStyleText, FillStyles[i].FillStyleName) == 0)
+ return FillStyles[i].FillStyleValue;
}
return LIGHT_FILL;
diff --git a/boot/freeldr/freeldr/ui/ui.c b/boot/freeldr/freeldr/ui/ui.c
index e9124fbe15e..fa06f73ae85 100644
--- a/boot/freeldr/freeldr/ui/ui.c
+++ b/boot/freeldr/freeldr/ui/ui.c
@@ -19,41 +19,41 @@
#ifndef _M_ARM
#include <freeldr.h>
+
#include <debug.h>
+DBG_DEFAULT_CHANNEL(UI);
#define TAG_UI_TEXT 'xTiU'
-DBG_DEFAULT_CHANNEL(UI);
-
-ULONG UiScreenWidth; // Screen Width
-ULONG UiScreenHeight; // Screen Height
-
-UCHAR UiStatusBarFgColor = COLOR_BLACK; // Status bar foreground
color
-UCHAR UiStatusBarBgColor = COLOR_CYAN; // Status bar background
color
-UCHAR UiBackdropFgColor = COLOR_WHITE; // Backdrop foreground
color
-UCHAR UiBackdropBgColor = COLOR_BLUE; // Backdrop background
color
-UCHAR UiBackdropFillStyle = MEDIUM_FILL; // Backdrop fill style
-UCHAR UiTitleBoxFgColor = COLOR_WHITE; // Title box foreground
color
-UCHAR UiTitleBoxBgColor = COLOR_RED; // Title box background
color
-UCHAR UiMessageBoxFgColor = COLOR_WHITE; // Message box
foreground color
-UCHAR UiMessageBoxBgColor = COLOR_BLUE; // Message box
background color
-UCHAR UiMenuFgColor = COLOR_WHITE; // Menu foreground color
-UCHAR UiMenuBgColor = COLOR_BLUE; // Menu background color
-UCHAR UiTextColor = COLOR_YELLOW; // Normal text color
-UCHAR UiSelectedTextColor = COLOR_BLACK; // Selected text color
-UCHAR UiSelectedTextBgColor = COLOR_GRAY; // Selected text
background color
-UCHAR UiEditBoxTextColor = COLOR_WHITE; // Edit box text color
-UCHAR UiEditBoxBgColor = COLOR_BLACK; // Edit box text
background color
-
-CHAR UiTitleBoxTitleText[260] = "Boot Menu"; // Title
box's title text
-
-BOOLEAN UiUseSpecialEffects = FALSE; // Tells us if we
should use fade effects
-BOOLEAN UiDrawTime = TRUE; // Tells us if we
should draw the time
-BOOLEAN UiCenterMenu = TRUE; // Tells us if we
should use a centered or left-aligned menu
-BOOLEAN UiMenuBox = TRUE; // Tells us if we
should draw a box around the menu
+ULONG UiScreenWidth; // Screen Width
+ULONG UiScreenHeight; // Screen Height
+
+UCHAR UiStatusBarFgColor = COLOR_BLACK; // Status bar foreground color
+UCHAR UiStatusBarBgColor = COLOR_CYAN; // Status bar background color
+UCHAR UiBackdropFgColor = COLOR_WHITE; // Backdrop foreground color
+UCHAR UiBackdropBgColor = COLOR_BLUE; // Backdrop background color
+UCHAR UiBackdropFillStyle = MEDIUM_FILL; // Backdrop fill style
+UCHAR UiTitleBoxFgColor = COLOR_WHITE; // Title box foreground color
+UCHAR UiTitleBoxBgColor = COLOR_RED; // Title box background color
+UCHAR UiMessageBoxFgColor = COLOR_WHITE; // Message box foreground color
+UCHAR UiMessageBoxBgColor = COLOR_BLUE; // Message box background color
+UCHAR UiMenuFgColor = COLOR_WHITE; // Menu foreground color
+UCHAR UiMenuBgColor = COLOR_BLUE; // Menu background color
+UCHAR UiTextColor = COLOR_YELLOW; // Normal text color
+UCHAR UiSelectedTextColor = COLOR_BLACK; // Selected text color
+UCHAR UiSelectedTextBgColor = COLOR_GRAY; // Selected text background color
+UCHAR UiEditBoxTextColor = COLOR_WHITE; // Edit box text color
+UCHAR UiEditBoxBgColor = COLOR_BLACK; // Edit box text background color
+
+CHAR UiTitleBoxTitleText[260] = "Boot Menu"; // Title box's title text
+
+BOOLEAN UiUseSpecialEffects = FALSE; // Tells us if we should use fade effects
+BOOLEAN UiDrawTime = TRUE; // Tells us if we should draw the time
+BOOLEAN UiCenterMenu = TRUE; // Tells us if we should use a centered or
left-aligned menu
+BOOLEAN UiMenuBox = TRUE; // Tells us if we should draw a box around the
menu
CHAR UiTimeText[260] = "[Time Remaining: ] ";
-const CHAR UiMonthNames[12][15] = { "January ", "February ",
"March ", "April ", "May ", "June ", "July
", "August ", "September ", "October ", "November
", "December " };
+const CHAR UiMonthNames[12][15] = { "January ", "February ",
"March ", "April ", "May ", "June ", "July
", "August ", "September ", "October ", "November
", "December " };
UIVTBL UiVtbl =
{
@@ -83,12 +83,11 @@ UIVTBL UiVtbl =
BOOLEAN UiInitialize(BOOLEAN ShowGui)
{
- 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
+ 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
ULONG_PTR SectionId;
- CHAR DisplayModeText[260];
- CHAR SettingText[260];
- ULONG Depth;
+ ULONG Depth;
+ CHAR SettingText[260];
if (!ShowGui)
{
@@ -101,25 +100,28 @@ BOOLEAN UiInitialize(BOOLEAN ShowGui)
}
TRACE("Initializing User Interface.\n");
- TRACE("Reading in UI settings from [Display] section.\n");
+ TRACE("Reading UI settings from [Display] section.\n");
+
+ /* Open the [Display] section */
+ if (!IniOpenSection("Display", &SectionId))
+ SectionId = 0;
- DisplayModeText[0] = '\0';
- if (IniOpenSection("Display", &SectionId))
+ /* Select the video mode */
+ SettingText[0] = '\0';
+ if ((SectionId != 0) && !IniReadSettingByName(SectionId,
"DisplayMode", SettingText, sizeof(SettingText)))
{
- if (!IniReadSettingByName(SectionId, "DisplayMode", DisplayModeText,
sizeof(DisplayModeText)))
- {
- DisplayModeText[0] = '\0';
- }
- if (IniReadSettingByName(SectionId, "MinimalUI", SettingText,
sizeof(SettingText)))
- {
- UiMinimal = (_stricmp(SettingText, "Yes") == 0 &&
strlen(SettingText) == 3);
- }
+ SettingText[0] = '\0';
}
-
- UiDisplayMode = MachVideoSetDisplayMode(DisplayModeText, TRUE);
+ UiDisplayMode = MachVideoSetDisplayMode(SettingText, TRUE);
MachVideoGetDisplaySize(&UiScreenWidth, &UiScreenHeight, &Depth);
- if (VideoTextMode == UiDisplayMode)
+ /* Select the UI */
+ if ((SectionId != 0) && IniReadSettingByName(SectionId,
"MinimalUI", SettingText, sizeof(SettingText)))
+ {
+ UiMinimal = (_stricmp(SettingText, "Yes") == 0 &&
strlen(SettingText) == 3);
+ }
+
+ if (UiDisplayMode == VideoTextMode)
UiVtbl = (UiMinimal ? MiniTuiVtbl : TuiVtbl);
else
UiVtbl = GuiVtbl;
@@ -130,99 +132,70 @@ BOOLEAN UiInitialize(BOOLEAN ShowGui)
return FALSE;
}
- if (IniOpenSection("Display", &SectionId))
+ /* Load the settings */
+ if (SectionId != 0)
{
- if (IniReadSettingByName(SectionId, "TitleText", SettingText,
sizeof(SettingText)))
- {
- strcpy(UiTitleBoxTitleText, SettingText);
- }
- if (IniReadSettingByName(SectionId, "TimeText", SettingText,
sizeof(SettingText)))
- {
- strcpy(UiTimeText, SettingText);
- }
- if (IniReadSettingByName(SectionId, "StatusBarColor", SettingText,
sizeof(SettingText)))
- {
- UiStatusBarBgColor = UiTextToColor(SettingText);
- }
- if (IniReadSettingByName(SectionId, "StatusBarTextColor", SettingText,
sizeof(SettingText)))
- {
- UiStatusBarFgColor = UiTextToColor(SettingText);
- }
- if (IniReadSettingByName(SectionId, "BackdropTextColor", SettingText,
sizeof(SettingText)))
- {
- UiBackdropFgColor = UiTextToColor(SettingText);
- }
- if (IniReadSettingByName(SectionId, "BackdropColor", SettingText,
sizeof(SettingText)))
- {
- UiBackdropBgColor = UiTextToColor(SettingText);
- }
- if (IniReadSettingByName(SectionId, "BackdropFillStyle", SettingText,
sizeof(SettingText)))
- {
- UiBackdropFillStyle = UiTextToFillStyle(SettingText);
- }
- if (IniReadSettingByName(SectionId, "TitleBoxTextColor", SettingText,
sizeof(SettingText)))
- {
- UiTitleBoxFgColor = UiTextToColor(SettingText);
- }
- if (IniReadSettingByName(SectionId, "TitleBoxColor", SettingText,
sizeof(SettingText)))
- {
- UiTitleBoxBgColor = UiTextToColor(SettingText);
- }
- if (IniReadSettingByName(SectionId, "MessageBoxTextColor", SettingText,
sizeof(SettingText)))
- {
- UiMessageBoxFgColor = UiTextToColor(SettingText);
- }
- if (IniReadSettingByName(SectionId, "MessageBoxColor", SettingText,
sizeof(SettingText)))
- {
- UiMessageBoxBgColor = UiTextToColor(SettingText);
- }
- if (IniReadSettingByName(SectionId, "MenuTextColor", SettingText,
sizeof(SettingText)))
- {
- UiMenuFgColor = UiTextToColor(SettingText);
- }
- if (IniReadSettingByName(SectionId, "MenuColor", SettingText,
sizeof(SettingText)))
+ static const struct
{
- UiMenuBgColor = UiTextToColor(SettingText);
- }
- if (IniReadSettingByName(SectionId, "TextColor", SettingText,
sizeof(SettingText)))
- {
- UiTextColor = UiTextToColor(SettingText);
- }
- if (IniReadSettingByName(SectionId, "SelectedTextColor", SettingText,
sizeof(SettingText)))
- {
- UiSelectedTextColor = UiTextToColor(SettingText);
- }
- if (IniReadSettingByName(SectionId, "SelectedColor", SettingText,
sizeof(SettingText)))
+ PCSTR SettingName;
+ PVOID SettingVar;
+ UCHAR SettingType; // 0: Text, 1: Yes/No, 2: Color, 3: Fill style
+ } Settings[] =
{
- UiSelectedTextBgColor = UiTextToColor(SettingText);
- }
- if (IniReadSettingByName(SectionId, "EditBoxTextColor", SettingText,
sizeof(SettingText)))
- {
- UiEditBoxTextColor = UiTextToColor(SettingText);
- }
- if (IniReadSettingByName(SectionId, "EditBoxColor", SettingText,
sizeof(SettingText)))
- {
- UiEditBoxBgColor = UiTextToColor(SettingText);
- }
- if (IniReadSettingByName(SectionId, "SpecialEffects", SettingText,
sizeof(SettingText)))
+ {"TitleText", &UiTitleBoxTitleText, 0},
+ {"TimeText" , &UiTimeText , 0},
+
+ {"SpecialEffects", &UiUseSpecialEffects, 1},
+ {"ShowTime" , &UiDrawTime , 1},
+ {"MenuBox" , &UiMenuBox , 1},
+ {"CenterMenu" , &UiCenterMenu , 1},
+
+ {"BackdropColor" , &UiBackdropBgColor , 2},
+ {"BackdropTextColor" , &UiBackdropFgColor , 2},
+ {"StatusBarColor" , &UiStatusBarBgColor , 2},
+ {"StatusBarTextColor" , &UiStatusBarFgColor , 2},
+ {"TitleBoxColor" , &UiTitleBoxBgColor , 2},
+ {"TitleBoxTextColor" , &UiTitleBoxFgColor , 2},
+ {"MessageBoxColor" , &UiMessageBoxBgColor , 2},
+ {"MessageBoxTextColor", &UiMessageBoxFgColor , 2},
+ {"MenuColor" , &UiMenuBgColor , 2},
+ {"MenuTextColor" , &UiMenuFgColor , 2},
+ {"TextColor" , &UiTextColor , 2},
+ {"SelectedColor" , &UiSelectedTextBgColor, 2},
+ {"SelectedTextColor" , &UiSelectedTextColor , 2},
+ {"EditBoxColor" , &UiEditBoxBgColor , 2},
+ {"EditBoxTextColor" , &UiEditBoxTextColor , 2},
+
+ {"BackdropFillStyle", &UiBackdropFillStyle, 3},
+ };
+ ULONG i;
+
+ for (i = 0; i < sizeof(Settings)/sizeof(Settings[0]); ++i)
{
- UiUseSpecialEffects = (_stricmp(SettingText, "Yes") == 0 &&
strlen(SettingText) == 3);
- }
- if (IniReadSettingByName(SectionId, "ShowTime", SettingText,
sizeof(SettingText)))
- {
- UiDrawTime = (_stricmp(SettingText, "Yes") == 0 &&
strlen(SettingText) == 3);
- }
- if (IniReadSettingByName(SectionId, "MenuBox", SettingText,
sizeof(SettingText)))
- {
- UiMenuBox = (_stricmp(SettingText, "Yes") == 0 &&
strlen(SettingText) == 3);
- }
- if (IniReadSettingByName(SectionId, "CenterMenu", SettingText,
sizeof(SettingText)))
- {
- UiCenterMenu = (_stricmp(SettingText, "Yes") == 0 &&
strlen(SettingText) == 3);
+ if (!IniReadSettingByName(SectionId, Settings[i].SettingName, SettingText,
sizeof(SettingText)))
+ continue;
+
+ switch (Settings[i].SettingType)
+ {
+ case 0: // Text
+ strcpy((PCHAR)Settings[i].SettingVar, SettingText);
+ break;
+ case 1: // Yes/No
+ *(PBOOLEAN)Settings[i].SettingVar = (_stricmp(SettingText,
"Yes") == 0 && strlen(SettingText) == 3);
+ break;
+ case 2: // Color
+ *(PUCHAR)Settings[i].SettingVar = UiTextToColor(SettingText);
+ break;
+ case 3: // Fill style
+ *(PUCHAR)Settings[i].SettingVar = UiTextToFillStyle(SettingText);
+ break;
+ default:
+ break;
+ }
}
}
- // Draw the backdrop and fade it in if special effects are enabled
+ /* Draw the backdrop and fade it in if special effects are enabled */
UiFadeInBackdrop();
TRACE("UiInitialize() returning TRUE.\n");
@@ -380,53 +353,47 @@ VOID UiDrawProgressBar(ULONG Left, ULONG Top, ULONG Right, ULONG
Bottom, ULONG P
UiVtbl.DrawProgressBar(Left, Top, Right, Bottom, Position, Range, ProgressText);
}
-VOID UiShowMessageBoxesInSection(PCSTR SectionName)
+VOID
+UiShowMessageBoxesInSection(
+ IN ULONG_PTR SectionId)
{
- ULONG Idx;
- CHAR SettingName[80];
- CHAR SettingValue[80];
- PCHAR MessageBoxText;
- ULONG MessageBoxTextSize;
- ULONG_PTR SectionId;
+ ULONG Idx;
+ CHAR SettingName[80];
+ CHAR SettingValue[80];
+ PCHAR MessageBoxText;
+ ULONG MessageBoxTextSize;
- if (!IniOpenSection(SectionName, &SectionId))
- {
+ if (SectionId == 0)
return;
- }
- //
- // Find all the message box settings and run them
- //
- for (Idx=0; Idx<IniGetNumSectionItems(SectionId); Idx++)
+ /* Find all the message box settings and run them */
+ for (Idx = 0; Idx < IniGetNumSectionItems(SectionId); Idx++)
{
IniReadSettingByNumber(SectionId, Idx, SettingName, sizeof(SettingName),
SettingValue, sizeof(SettingValue));
+ if (_stricmp(SettingName, "MessageBox") != 0)
+ continue;
- if (_stricmp(SettingName, "MessageBox") == 0)
- {
- // Get the real length of the MessageBox text
- MessageBoxTextSize = IniGetSectionSettingValueSize(SectionId, Idx);
+ /* Get the real length of the MessageBox text */
+ MessageBoxTextSize = IniGetSectionSettingValueSize(SectionId, Idx);
+ // if (MessageBoxTextSize <= 0)
+ // continue;
- //if (MessageBoxTextSize > 0)
- {
- // Allocate enough memory to hold the text
- MessageBoxText = FrLdrTempAlloc(MessageBoxTextSize, TAG_UI_TEXT);
+ /* Allocate enough memory to hold the text */
+ MessageBoxText = FrLdrTempAlloc(MessageBoxTextSize, TAG_UI_TEXT);
+ if (!MessageBoxText)
+ continue;
- if (MessageBoxText)
- {
- // Get the MessageBox text
- IniReadSettingByNumber(SectionId, Idx, SettingName,
sizeof(SettingName), MessageBoxText, MessageBoxTextSize);
+ /* Get the MessageBox text */
+ IniReadSettingByNumber(SectionId, Idx, SettingName, sizeof(SettingName),
MessageBoxText, MessageBoxTextSize);
- // Fix it up
- UiEscapeString(MessageBoxText);
+ /* Fix it up */
+ UiEscapeString(MessageBoxText);
- // Display it
- UiMessageBox(MessageBoxText);
+ /* Display it */
+ UiMessageBox(MessageBoxText);
- // Free the memory
- FrLdrTempFree(MessageBoxText, TAG_UI_TEXT);
- }
- }
- }
+ /* Free the memory */
+ FrLdrTempFree(MessageBoxText, TAG_UI_TEXT);
}
}
@@ -450,20 +417,20 @@ UiShowMessageBoxesInArgv(
/* Allocate enough memory to hold the text */
MessageBoxText = FrLdrTempAlloc(MessageBoxTextSize, TAG_UI_TEXT);
- if (MessageBoxText)
- {
- /* Get the MessageBox text */
- strcpy(MessageBoxText, ArgValue);
+ if (!MessageBoxText)
+ continue;
- /* Fix it up */
- UiEscapeString(MessageBoxText);
+ /* Get the MessageBox text */
+ strcpy(MessageBoxText, ArgValue);
- /* Display it */
- UiMessageBox(MessageBoxText);
+ /* Fix it up */
+ UiEscapeString(MessageBoxText);
- /* Free the memory */
- FrLdrTempFree(MessageBoxText, TAG_UI_TEXT);
- }
+ /* Display it */
+ UiMessageBox(MessageBoxText);
+
+ /* Free the memory */
+ FrLdrTempFree(MessageBoxText, TAG_UI_TEXT);
}
}
@@ -487,10 +454,9 @@ VOID UiEscapeString(PCHAR String)
VOID UiTruncateStringEllipsis(PCHAR StringText, ULONG MaxChars)
{
+ /* If it's too large, just add some ellipsis past the maximum */
if (strlen(StringText) > MaxChars)
- {
strcpy(&StringText[MaxChars - 3], "...");
- }
}
BOOLEAN