https://git.reactos.org/?p=reactos.git;a=commitdiff;h=d05be0da3f4d8c5c3bc60…
commit d05be0da3f4d8c5c3bc60e1b8249b586212642bc
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Tue Aug 6 22:30:54 2019 +0200
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Tue Aug 6 23:40:05 2019 +0200
[FREELDR] Some ARC-spec compatibility refactoring + simplifications & fixes.
CORE-9023
- During loading and initialization of the list of operating systems
available in freeldr.ini, convert any legacy operating system entry
encountered -- they are like those in NTLDR's boot.ini file, i.e.:
ArcOsLoadPartition="LoadIdentifier" /List /of /Options
into a new operating system INI entry, like those used by default in
FreeLoader. This allows us to avoid treating this corner-case later in
different parts of the code. Also, the "BootType" value is now
determined there, only once.
- Convert the OS loaders entry-points to ARC-compatible ones, following
the "Advanced RISC Computing Specification, Version 1.2" specification
https://www.netbsd.org/docs/Hardware/Machines/ARC/riscspec.pdf
- Introduce helpers for retrieving options values from the argument vector
in a simple way.
- Simplify LoadOperatingSystem(), since now the "BootType" value has
been determined once while loading the list of OSes (see above) and
is well-defined there. Use the BuildArgvForOsLoader() helper to build
the ARC-compatible argument vector from the corresponding INI settings
for the selected operating system entry, and use it when calling the
corresponding OS loader.
- In the OS loaders, since we can now directly read the settings from
the argument vector (instead of using INI settings), we can avoid
using a bunch of fixed-size string buffers, and avoid potentially
failing IniOpenSection() calls as well.
- Simplify code in the Linux loader (and the RemoveQuotes() function).
- Add UiShowMessageBoxesInArgv() that acts on the "MessageBox=" settings
passed through the argument vector (equivalent to
UiShowMessageBoxesInSection() ).
- Use string-safe functions where needed (copy/concatenation/printf on
fixed-size buffers).
---
boot/freeldr/freeldr/CMakeLists.txt | 1 +
boot/freeldr/freeldr/bootmgr.c | 203 ++++++++++++++----------
boot/freeldr/freeldr/custom.c | 62 ++++----
boot/freeldr/freeldr/include/arcsupp.h | 28 ++++
boot/freeldr/freeldr/include/freeldr.h | 1 +
boot/freeldr/freeldr/include/linux.h | 14 +-
boot/freeldr/freeldr/include/miscboot.h | 26 +--
boot/freeldr/freeldr/include/oslist.h | 10 +-
boot/freeldr/freeldr/include/ui.h | 7 +
boot/freeldr/freeldr/include/winldr.h | 22 ++-
boot/freeldr/freeldr/lib/arcsupp.c | 47 ++++++
boot/freeldr/freeldr/linuxboot.c | 156 +++++++++---------
boot/freeldr/freeldr/miscboot.c | 113 ++++++--------
boot/freeldr/freeldr/ntldr/setupldr.c | 152 ++++++++----------
boot/freeldr/freeldr/ntldr/winldr.c | 184 +++++++++++-----------
boot/freeldr/freeldr/ntldr/winldr.h | 2 +-
boot/freeldr/freeldr/oslist.c | 269 ++++++++++++++++++++++++++++----
boot/freeldr/freeldr/ui/directui.c | 8 +
boot/freeldr/freeldr/ui/ui.c | 37 +++++
19 files changed, 861 insertions(+), 481 deletions(-)
diff --git a/boot/freeldr/freeldr/CMakeLists.txt b/boot/freeldr/freeldr/CMakeLists.txt
index 4ffa44a7ca4..d4263050ad4 100644
--- a/boot/freeldr/freeldr/CMakeLists.txt
+++ b/boot/freeldr/freeldr/CMakeLists.txt
@@ -37,6 +37,7 @@ include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/elf)
add_definitions(-D_NTHAL_ -D_BLDR_ -D_NTSYSTEM_)
list(APPEND FREELDR_BOOTLIB_SOURCE
+ lib/arcsupp.c
lib/debug.c
lib/peloader.c
lib/comm/rs232.c
diff --git a/boot/freeldr/freeldr/bootmgr.c b/boot/freeldr/freeldr/bootmgr.c
index 5df8182c901..cdd370567c2 100644
--- a/boot/freeldr/freeldr/bootmgr.c
+++ b/boot/freeldr/freeldr/bootmgr.c
@@ -22,122 +22,167 @@
#include <freeldr.h>
#include <debug.h>
-/* GLOBALS ********************************************************************/
+DBG_DEFAULT_CHANNEL(INIFILE);
-typedef
-VOID
-(*OS_LOADING_METHOD)(IN OperatingSystemItem* OperatingSystem,
- IN USHORT OperatingSystemVersion);
+/* GLOBALS ********************************************************************/
static const struct
{
- PCHAR BootType;
- USHORT OperatingSystemVersion;
- OS_LOADING_METHOD Load;
+ PCSTR BootType;
+ ARC_ENTRY_POINT OsLoader;
} OSLoadingMethods[] =
{
- {"ReactOSSetup", 0 , LoadReactOSSetup },
+ {"ReactOSSetup", LoadReactOSSetup },
#ifdef _M_IX86
- {"BootSector" , 0 , LoadAndBootBootSector},
- {"Drive" , 0 , LoadAndBootDrive },
- {"Partition" , 0 , LoadAndBootPartition },
+ {"BootSector" , LoadAndBootBootSector},
+ {"Drive" , LoadAndBootDrive },
+ {"Partition" , LoadAndBootPartition },
- {"Linux" , 0 , LoadAndBootLinux },
+ {"Linux" , LoadAndBootLinux },
- {"Windows" , 0 , LoadAndBootWindows },
- {"WindowsNT40" , _WIN32_WINNT_NT4 , LoadAndBootWindows },
+ {"Windows" , LoadAndBootWindows },
+ {"WindowsNT40" , LoadAndBootWindows },
#endif
- {"Windows2003" , _WIN32_WINNT_WS03, LoadAndBootWindows },
+ {"Windows2003" , LoadAndBootWindows },
};
/* FUNCTIONS ******************************************************************/
-VOID LoadOperatingSystem(IN OperatingSystemItem* OperatingSystem)
+PCHAR*
+BuildArgvForOsLoader(
+ IN PCSTR LoadIdentifier,
+ IN ULONG_PTR SectionId,
+ OUT PULONG pArgc)
{
- ULONG_PTR SectionId;
- PCSTR SectionName = OperatingSystem->SystemPartition;
- CHAR BootType[80];
+ SIZE_T Size;
+ ULONG Count;
ULONG i;
-
- /* Try to open the operating system section in the .ini file */
- if (IniOpenSection(SectionName, &SectionId))
+ ULONG Argc;
+ 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.
+ */
+
+ *pArgc = 0;
+
+ /* Validate the LoadIdentifier (to make tests simpler later) */
+ if (LoadIdentifier && !*LoadIdentifier)
+ LoadIdentifier = NULL;
+
+ /* 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;
+
+ /* Calculate the total size needed for the string buffer of the argument vector */
+ Size = 0;
+ /* i == 0: Program name */
+ /* i == 1: LoadIdentifier */
+ if (LoadIdentifier)
{
- /* Try to read the boot type */
- IniReadSettingByName(SectionId, "BootType", BootType,
sizeof(BootType));
+ Size += (strlen("LoadIdentifier=") + strlen(LoadIdentifier) + 1) *
sizeof(CHAR);
}
- else
+ for (i = 0; i < Count; ++i)
{
- BootType[0] = ANSI_NULL;
+ Size += IniGetSectionSettingNameSize(SectionId, i); // Counts also the
NULL-terminator, that we transform into the '=' sign separator.
+ Size += IniGetSectionSettingValueSize(SectionId, i); // Counts also the
NULL-terminator.
}
+ Size += sizeof(ANSI_NULL); // Final NULL-terminator.
+
+ /* Allocate memory to hold the argument vector: pointers and string buffer */
+ Argv = FrLdrHeapAlloc(Argc * sizeof(PCHAR) + Size, TAG_STRING);
+ if (!Argv)
+ return NULL;
+
+ /* Initialize the argument vector: loop through the section and copy the key=value
options */
+ SettingName = (PCHAR)((ULONG_PTR)Argv + (Argc * sizeof(PCHAR)));
+ Args = Argv;
+ /* i == 0: Program name */
+ *Args++ = NULL;
+ /* i == 1: LoadIdentifier */
+ if (LoadIdentifier)
+ {
+ strcpy(SettingName, "LoadIdentifier=");
+ strcat(SettingName, LoadIdentifier);
- if (BootType[0] == ANSI_NULL && SectionName[0] != ANSI_NULL)
+ *Args++ = SettingName;
+ SettingName += (strlen(SettingName) + 1);
+ }
+ for (i = 0; i < Count; ++i)
{
- /* Try to infer the boot type value */
-#ifdef _M_IX86
- ULONG FileId;
- if (ArcOpen((PSTR)SectionName, OpenReadOnly, &FileId) == ESUCCESS)
- {
- ArcClose(FileId);
- strcpy(BootType, "BootSector");
- }
- else
-#endif
- {
- strcpy(BootType, "Windows");
- }
+ Size = IniGetSectionSettingNameSize(SectionId, i);
+ SettingValue = SettingName + Size;
+ IniReadSettingByNumber(SectionId, i,
+ SettingName, Size,
+ SettingValue, IniGetSectionSettingValueSize(SectionId,
i));
+ SettingName[Size - 1] = '=';
+
+ *Args++ = SettingName;
+ SettingName += (strlen(SettingName) + 1);
}
-#if defined(_M_IX86)
- /* Install the drive mapper according to this section drive mappings */
- DriveMapMapDrivesInSection(SectionName);
-#endif
-
- /* Loop through the OS loading method table and find a suitable OS to boot */
- for (i = 0; i < sizeof(OSLoadingMethods) / sizeof(OSLoadingMethods[0]); ++i)
+#if DBG
+ /* Dump the argument vector for debugging */
+ for (i = 0; i < Argc; ++i)
{
- if (_stricmp(BootType, OSLoadingMethods[i].BootType) == 0)
- {
- OSLoadingMethods[i].Load(OperatingSystem,
- OSLoadingMethods[i].OperatingSystemVersion);
- return;
- }
+ TRACE("Argv[%lu]: '%s'\n", i, Argv[i]);
}
+#endif
+
+ *pArgc = Argc;
+ return Argv;
}
-ULONG GetDefaultOperatingSystem(OperatingSystemItem* OperatingSystemList, ULONG
OperatingSystemCount)
+VOID LoadOperatingSystem(IN OperatingSystemItem* OperatingSystem)
{
- CHAR DefaultOSText[80];
- PCSTR DefaultOSName;
ULONG_PTR SectionId;
- ULONG DefaultOS = 0;
- ULONG Idx;
-
- if (!IniOpenSection("FreeLoader", &SectionId))
- return 0;
+ PCSTR SectionName = OperatingSystem->SectionName;
+ ULONG i;
+ ULONG Argc;
+ PCHAR* Argv;
+ CHAR BootType[80];
- DefaultOSName = CmdLineGetDefaultOS();
- if (DefaultOSName == NULL)
+ /* Try to open the operating system section in the .ini file */
+ if (!IniOpenSection(SectionName, &SectionId))
{
- if (IniReadSettingByName(SectionId, "DefaultOS", DefaultOSText,
sizeof(DefaultOSText)))
- {
- DefaultOSName = DefaultOSText;
- }
+ UiMessageBox("Section [%s] not found in freeldr.ini.", SectionName);
+ return;
}
- if (DefaultOSName != NULL)
+ /* Try to read the boot type */
+ *BootType = ANSI_NULL;
+ IniReadSettingByName(SectionId, "BootType", BootType, sizeof(BootType));
+
+ /* We must have the "BootType" value (it has been possibly added by
InitOperatingSystemList()) */
+ ASSERT(*BootType);
+
+#if defined(_M_IX86)
+ /* Install the drive mapper according to this section drive mappings */
+ DriveMapMapDrivesInSection(SectionName);
+#endif
+
+ /* Loop through the OS loading method table and find a suitable OS to boot */
+ for (i = 0; i < sizeof(OSLoadingMethods) / sizeof(OSLoadingMethods[0]); ++i)
{
- for (Idx = 0; Idx < OperatingSystemCount; Idx++)
+ if (_stricmp(BootType, OSLoadingMethods[i].BootType) == 0)
{
- if (_stricmp(DefaultOSName, OperatingSystemList[Idx].SystemPartition) == 0)
+ Argv = BuildArgvForOsLoader(OperatingSystem->LoadIdentifier, SectionId,
&Argc);
+ if (Argv)
{
- DefaultOS = Idx;
- break;
+ OSLoadingMethods[i].OsLoader(Argc, Argv, NULL);
+ FrLdrHeapFree(Argv, TAG_STRING);
}
+ return;
}
}
-
- return DefaultOS;
}
LONG GetTimeOut(VOID)
@@ -176,11 +221,11 @@ BOOLEAN MainBootMenuKeyPressFilter(ULONG KeyPress)
VOID RunLoader(VOID)
{
ULONG_PTR SectionId;
+ LONG TimeOut;
ULONG OperatingSystemCount;
OperatingSystemItem* OperatingSystemList;
PCSTR* OperatingSystemDisplayNames;
ULONG DefaultOperatingSystem;
- LONG TimeOut;
ULONG SelectedOperatingSystem;
ULONG i;
@@ -222,21 +267,19 @@ VOID RunLoader(VOID)
return;
}
- OperatingSystemList = InitOperatingSystemList(&OperatingSystemCount);
+ OperatingSystemList = InitOperatingSystemList(&OperatingSystemCount,
+ &DefaultOperatingSystem);
if (!OperatingSystemList)
{
UiMessageBox("Unable to read operating systems section in
freeldr.ini.\nPress ENTER to reboot.");
goto Reboot;
}
-
if (OperatingSystemCount == 0)
{
UiMessageBox("There were no operating systems listed in freeldr.ini.\nPress
ENTER to reboot.");
goto Reboot;
}
- DefaultOperatingSystem = GetDefaultOperatingSystem(OperatingSystemList,
OperatingSystemCount);
-
/* Create list of display names */
OperatingSystemDisplayNames = FrLdrTempAlloc(sizeof(PCSTR) * OperatingSystemCount,
'mNSO');
if (!OperatingSystemDisplayNames)
diff --git a/boot/freeldr/freeldr/custom.c b/boot/freeldr/freeldr/custom.c
index 02e55b62fde..25fee60a4eb 100644
--- a/boot/freeldr/freeldr/custom.c
+++ b/boot/freeldr/freeldr/custom.c
@@ -108,7 +108,10 @@ VOID OptionMenuCustomBootDisk(VOID)
/* Generate a unique section name */
TimeInfo = ArcGetTime();
- sprintf(SectionName, "CustomBootDisk%u%u%u%u%u%u", TimeInfo->Year,
TimeInfo->Day, TimeInfo->Month, TimeInfo->Hour, TimeInfo->Minute,
TimeInfo->Second);
+ RtlStringCbPrintfA(SectionName, sizeof(SectionName),
+ "CustomBootDisk%u%u%u%u%u%u",
+ TimeInfo->Year, TimeInfo->Day, TimeInfo->Month,
+ TimeInfo->Hour, TimeInfo->Minute, TimeInfo->Second);
/* Add the section */
if (!IniAddSection(SectionName, &SectionId))
@@ -124,11 +127,8 @@ VOID OptionMenuCustomBootDisk(VOID)
UiMessageBox(CustomBootPrompt);
- OperatingSystem.SystemPartition = SectionName;
- OperatingSystem.LoadIdentifier = NULL;
- OperatingSystem.OsLoadOptions = NULL;
-
- // LoadAndBootDrive(&OperatingSystem, 0);
+ OperatingSystem.SectionName = SectionName;
+ OperatingSystem.LoadIdentifier = NULL;
LoadOperatingSystem(&OperatingSystem);
}
@@ -153,7 +153,10 @@ VOID OptionMenuCustomBootPartition(VOID)
/* Generate a unique section name */
TimeInfo = ArcGetTime();
- sprintf(SectionName, "CustomBootPartition%u%u%u%u%u%u", TimeInfo->Year,
TimeInfo->Day, TimeInfo->Month, TimeInfo->Hour, TimeInfo->Minute,
TimeInfo->Second);
+ RtlStringCbPrintfA(SectionName, sizeof(SectionName),
+ "CustomBootPartition%u%u%u%u%u%u",
+ TimeInfo->Year, TimeInfo->Day, TimeInfo->Month,
+ TimeInfo->Hour, TimeInfo->Minute, TimeInfo->Second);
/* Add the section */
if (!IniAddSection(SectionName, &SectionId))
@@ -173,11 +176,8 @@ VOID OptionMenuCustomBootPartition(VOID)
UiMessageBox(CustomBootPrompt);
- OperatingSystem.SystemPartition = SectionName;
- OperatingSystem.LoadIdentifier = NULL;
- OperatingSystem.OsLoadOptions = NULL;
-
- // LoadAndBootPartition(&OperatingSystem, 0);
+ OperatingSystem.SectionName = SectionName;
+ OperatingSystem.LoadIdentifier = NULL;
LoadOperatingSystem(&OperatingSystem);
}
@@ -207,7 +207,10 @@ VOID OptionMenuCustomBootBootSectorFile(VOID)
/* Generate a unique section name */
TimeInfo = ArcGetTime();
- sprintf(SectionName, "CustomBootSectorFile%u%u%u%u%u%u", TimeInfo->Year,
TimeInfo->Day, TimeInfo->Month, TimeInfo->Hour, TimeInfo->Minute,
TimeInfo->Second);
+ RtlStringCbPrintfA(SectionName, sizeof(SectionName),
+ "CustomBootSectorFile%u%u%u%u%u%u",
+ TimeInfo->Year, TimeInfo->Day, TimeInfo->Month,
+ TimeInfo->Hour, TimeInfo->Minute, TimeInfo->Second);
/* Add the section */
if (!IniAddSection(SectionName, &SectionId))
@@ -231,11 +234,8 @@ VOID OptionMenuCustomBootBootSectorFile(VOID)
UiMessageBox(CustomBootPrompt);
- OperatingSystem.SystemPartition = SectionName;
- OperatingSystem.LoadIdentifier = NULL;
- OperatingSystem.OsLoadOptions = NULL;
-
- // LoadAndBootBootSector(&OperatingSystem, 0);
+ OperatingSystem.SectionName = SectionName;
+ OperatingSystem.LoadIdentifier = NULL;
LoadOperatingSystem(&OperatingSystem);
}
@@ -275,7 +275,10 @@ VOID OptionMenuCustomBootLinux(VOID)
/* Generate a unique section name */
TimeInfo = ArcGetTime();
- sprintf(SectionName, "CustomLinux%u%u%u%u%u%u", TimeInfo->Year,
TimeInfo->Day, TimeInfo->Month, TimeInfo->Hour, TimeInfo->Minute,
TimeInfo->Second);
+ RtlStringCbPrintfA(SectionName, sizeof(SectionName),
+ "CustomLinux%u%u%u%u%u%u",
+ TimeInfo->Year, TimeInfo->Day, TimeInfo->Month,
+ TimeInfo->Hour, TimeInfo->Minute, TimeInfo->Second);
/* Add the section */
if (!IniAddSection(SectionName, &SectionId))
@@ -298,7 +301,7 @@ VOID OptionMenuCustomBootLinux(VOID)
return;
/* Add the Initrd */
- if (strlen(LinuxInitrdString) > 0)
+ if (*LinuxInitrdString)
{
if (!IniAddSettingValueToSection(SectionId, "Initrd",
LinuxInitrdString))
return;
@@ -310,11 +313,8 @@ VOID OptionMenuCustomBootLinux(VOID)
UiMessageBox(CustomBootPrompt);
- OperatingSystem.SystemPartition = SectionName;
- OperatingSystem.LoadIdentifier = "Custom Linux Setup";
- OperatingSystem.OsLoadOptions = NULL;
-
- // LoadAndBootLinux(&OperatingSystem, 0);
+ OperatingSystem.SectionName = SectionName;
+ OperatingSystem.LoadIdentifier = "Custom Linux Setup";
LoadOperatingSystem(&OperatingSystem);
}
@@ -352,7 +352,10 @@ VOID OptionMenuCustomBootReactOS(VOID)
/* Generate a unique section name */
TimeInfo = ArcGetTime();
- sprintf(SectionName, "CustomReactOS%u%u%u%u%u%u", TimeInfo->Year,
TimeInfo->Day, TimeInfo->Month, TimeInfo->Hour, TimeInfo->Minute,
TimeInfo->Second);
+ RtlStringCbPrintfA(SectionName, sizeof(SectionName),
+ "CustomReactOS%u%u%u%u%u%u",
+ TimeInfo->Year, TimeInfo->Day, TimeInfo->Month,
+ TimeInfo->Hour, TimeInfo->Minute, TimeInfo->Second);
/* Add the section */
if (!IniAddSection(SectionName, &SectionId))
@@ -375,11 +378,8 @@ VOID OptionMenuCustomBootReactOS(VOID)
UiMessageBox(CustomBootPrompt);
- OperatingSystem.SystemPartition = SectionName;
- OperatingSystem.LoadIdentifier = NULL;
- OperatingSystem.OsLoadOptions = NULL; // ReactOSOptions
-
- // LoadAndBootWindows(&OperatingSystem, _WIN32_WINNT_WS03);
+ OperatingSystem.SectionName = SectionName;
+ OperatingSystem.LoadIdentifier = NULL;
LoadOperatingSystem(&OperatingSystem);
}
diff --git a/boot/freeldr/freeldr/include/arcsupp.h
b/boot/freeldr/freeldr/include/arcsupp.h
new file mode 100644
index 00000000000..7208974d4be
--- /dev/null
+++ b/boot/freeldr/freeldr/include/arcsupp.h
@@ -0,0 +1,28 @@
+/*
+ * PROJECT: FreeLoader
+ * LICENSE: GPL-2.0+ (
https://spdx.org/licenses/GPL-2.0+)
+ * PURPOSE: Generic ARC Support Functions
+ * COPYRIGHT: Copyright 2019 Hermes Belusca-Maito
+ */
+
+#pragma once
+
+typedef
+ARC_STATUS
+(__cdecl *ARC_ENTRY_POINT)(
+ IN ULONG Argc,
+ IN PCHAR Argv[],
+ IN PCHAR Envp[]);
+
+PCHAR
+GetNextArgumentValue(
+ IN ULONG Argc,
+ IN PCHAR Argv[],
+ IN OUT PULONG LastIndex OPTIONAL,
+ IN PCHAR ArgumentName);
+
+PCHAR
+GetArgumentValue(
+ IN ULONG Argc,
+ IN PCHAR Argv[],
+ IN PCHAR ArgumentName);
diff --git a/boot/freeldr/freeldr/include/freeldr.h
b/boot/freeldr/freeldr/include/freeldr.h
index 82a6b89f06b..71d47884402 100644
--- a/boot/freeldr/freeldr/include/freeldr.h
+++ b/boot/freeldr/freeldr/include/freeldr.h
@@ -58,6 +58,7 @@
/* Internal headers */
// #include <arcemul.h>
#include <arcname.h>
+#include <arcsupp.h>
#include <bytesex.h>
#include <cache.h>
#include <cmdline.h>
diff --git a/boot/freeldr/freeldr/include/linux.h b/boot/freeldr/freeldr/include/linux.h
index 78c16bcb4fc..3d5c7896f5a 100644
--- a/boot/freeldr/freeldr/include/linux.h
+++ b/boot/freeldr/freeldr/include/linux.h
@@ -131,11 +131,17 @@ typedef struct
VOID __cdecl BootNewLinuxKernel(VOID); // Implemented in linux.S
VOID __cdecl BootOldLinuxKernel(ULONG KernelSize); // Implemented in linux.S
-VOID
-LoadAndBootLinux(IN OperatingSystemItem* OperatingSystem,
- IN USHORT OperatingSystemVersion);
+ARC_STATUS
+LoadAndBootLinux(
+ IN ULONG Argc,
+ IN PCHAR Argv[],
+ IN PCHAR Envp[]);
+
+BOOLEAN
+LinuxParseIniSection(
+ IN ULONG Argc,
+ IN PCHAR Argv[]);
-BOOLEAN LinuxParseIniSection(PCSTR OperatingSystemName);
BOOLEAN LinuxReadBootSector(PFILE LinuxKernelFile);
BOOLEAN LinuxReadSetupSector(PFILE LinuxKernelFile);
BOOLEAN LinuxReadKernel(PFILE LinuxKernelFile);
diff --git a/boot/freeldr/freeldr/include/miscboot.h
b/boot/freeldr/freeldr/include/miscboot.h
index d7634963ae0..5e80ab0fa68 100644
--- a/boot/freeldr/freeldr/include/miscboot.h
+++ b/boot/freeldr/freeldr/include/miscboot.h
@@ -21,14 +21,22 @@
#ifdef _M_IX86
-VOID
-LoadAndBootBootSector(IN OperatingSystemItem* OperatingSystem,
- IN USHORT OperatingSystemVersion);
-VOID
-LoadAndBootPartition(IN OperatingSystemItem* OperatingSystem,
- IN USHORT OperatingSystemVersion);
-VOID
-LoadAndBootDrive(IN OperatingSystemItem* OperatingSystem,
- IN USHORT OperatingSystemVersion);
+ARC_STATUS
+LoadAndBootBootSector(
+ IN ULONG Argc,
+ IN PCHAR Argv[],
+ IN PCHAR Envp[]);
+
+ARC_STATUS
+LoadAndBootPartition(
+ IN ULONG Argc,
+ IN PCHAR Argv[],
+ IN PCHAR Envp[]);
+
+ARC_STATUS
+LoadAndBootDrive(
+ IN ULONG Argc,
+ IN PCHAR Argv[],
+ IN PCHAR Envp[]);
#endif // _M_IX86
diff --git a/boot/freeldr/freeldr/include/oslist.h
b/boot/freeldr/freeldr/include/oslist.h
index 934ee628c65..1676900c220 100644
--- a/boot/freeldr/freeldr/include/oslist.h
+++ b/boot/freeldr/freeldr/include/oslist.h
@@ -19,11 +19,15 @@
#pragma once
+#define TAG_STRING ' rtS'
+
typedef struct tagOperatingSystemItem
{
- PCSTR SystemPartition;
+ PCSTR SectionName;
PCSTR LoadIdentifier;
- PCSTR OsLoadOptions;
} OperatingSystemItem;
-OperatingSystemItem* InitOperatingSystemList(ULONG* OperatingSystemCountPointer);
+OperatingSystemItem*
+InitOperatingSystemList(
+ OUT PULONG OperatingSystemCount,
+ OUT PULONG DefaultOperatingSystem);
diff --git a/boot/freeldr/freeldr/include/ui.h b/boot/freeldr/freeldr/include/ui.h
index d531448d3af..151c0af1d48 100644
--- a/boot/freeldr/freeldr/include/ui.h
+++ b/boot/freeldr/freeldr/include/ui.h
@@ -70,7 +70,14 @@ VOID UiMessageBox(PCSTR Format, ...); //
Displays a me
VOID UiMessageBoxCritical(PCSTR MessageText); // Displays a message box
on the screen with an ok button using no system resources
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
+
+VOID
+UiShowMessageBoxesInArgv(
+ IN ULONG Argc,
+ IN PCHAR Argv[]);
+
VOID UiEscapeString(PCHAR String); // Processes a string
and changes all occurrences of "\n" to '\n'
BOOLEAN UiEditBox(PCSTR MessageText, PCHAR EditTextBuffer, ULONG Length);
diff --git a/boot/freeldr/freeldr/include/winldr.h
b/boot/freeldr/freeldr/include/winldr.h
index 56af2eda3f4..7bd4b581f05 100644
--- a/boot/freeldr/freeldr/include/winldr.h
+++ b/boot/freeldr/freeldr/include/winldr.h
@@ -58,17 +58,23 @@ typedef struct _ARC_DISK_SIGNATURE_EX
CHAR ArcName[MAX_PATH];
} ARC_DISK_SIGNATURE_EX, *PARC_DISK_SIGNATURE_EX;
-///////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
//
// ReactOS Loading Functions
//
-///////////////////////////////////////////////////////////////////////////////////////
-VOID LoadAndBootWindows(IN OperatingSystemItem* OperatingSystem,
- IN USHORT OperatingSystemVersion);
-
-VOID
-LoadReactOSSetup(IN OperatingSystemItem* OperatingSystem,
- IN USHORT OperatingSystemVersion);
+////////////////////////////////////////////////////////////////////////////////
+
+ARC_STATUS
+LoadAndBootWindows(
+ IN ULONG Argc,
+ IN PCHAR Argv[],
+ IN PCHAR Envp[]);
+
+ARC_STATUS
+LoadReactOSSetup(
+ IN ULONG Argc,
+ IN PCHAR Argv[],
+ IN PCHAR Envp[]);
// conversion.c and conversion.h
diff --git a/boot/freeldr/freeldr/lib/arcsupp.c b/boot/freeldr/freeldr/lib/arcsupp.c
new file mode 100644
index 00000000000..1292ece5e22
--- /dev/null
+++ b/boot/freeldr/freeldr/lib/arcsupp.c
@@ -0,0 +1,47 @@
+/*
+ * PROJECT: FreeLoader
+ * LICENSE: GPL-2.0+ (
https://spdx.org/licenses/GPL-2.0+)
+ * PURPOSE: Generic ARC Support Functions
+ * COPYRIGHT: Copyright 2019 Hermes Belusca-Maito
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include <freeldr.h>
+
+/* FUNCTIONS *****************************************************************/
+
+PCHAR
+GetNextArgumentValue(
+ IN ULONG Argc,
+ IN PCHAR Argv[],
+ IN OUT PULONG LastIndex OPTIONAL,
+ IN PCHAR ArgumentName)
+{
+ ULONG i;
+ SIZE_T ArgNameLen = strlen(ArgumentName);
+
+ for (i = (LastIndex ? *LastIndex : 0); i < Argc; ++i)
+ {
+ if (strlen(Argv[i]) >= ArgNameLen + 1 /* Count the '=' sign */
&&
+ _strnicmp(Argv[i], ArgumentName, ArgNameLen) == 0 &&
+ Argv[i][ArgNameLen] == '=')
+ {
+ /* Found it, return the value */
+ if (LastIndex) *LastIndex = i;
+ return &Argv[i][ArgNameLen + 1];
+ }
+ }
+
+ if (LastIndex) *LastIndex = (ULONG)-1;
+ return NULL;
+}
+
+PCHAR
+GetArgumentValue(
+ IN ULONG Argc,
+ IN PCHAR Argv[],
+ IN PCHAR ArgumentName)
+{
+ return GetNextArgumentValue(Argc, Argv, NULL, ArgumentName);
+}
diff --git a/boot/freeldr/freeldr/linuxboot.c b/boot/freeldr/freeldr/linuxboot.c
index d59ae161801..6ddc8b99c30 100644
--- a/boot/freeldr/freeldr/linuxboot.c
+++ b/boot/freeldr/freeldr/linuxboot.c
@@ -38,53 +38,55 @@ ULONG SetupSectorSize = 0;
BOOLEAN NewStyleLinuxKernel = FALSE;
ULONG LinuxKernelSize = 0;
ULONG LinuxInitrdSize = 0;
-CHAR LinuxKernelName[260];
-CHAR LinuxInitrdName[260];
-BOOLEAN LinuxHasInitrd = FALSE;
-CHAR LinuxCommandLine[260] = "";
+PCSTR LinuxKernelName = NULL;
+PCSTR LinuxInitrdName = NULL;
+PSTR LinuxCommandLine = NULL;
ULONG LinuxCommandLineSize = 0;
PVOID LinuxKernelLoadAddress = NULL;
PVOID LinuxInitrdLoadAddress = NULL;
CHAR LinuxBootDescription[80];
-CHAR LinuxBootPath[260] = "";
+PCSTR LinuxBootPath = NULL;
/* FUNCTIONS ******************************************************************/
-BOOLEAN RemoveQuotes(PCHAR QuotedString)
+VOID
+RemoveQuotes(
+ IN OUT PSTR QuotedString)
{
- CHAR TempString[200];
- PCHAR p;
- PSTR Start;
+ PCHAR p;
+ PSTR Start;
+ SIZE_T Size;
/* Skip spaces up to " */
p = QuotedString;
- while (*p == ' ' || *p == '"')
- p++;
+ while (*p == ' ' || *p == '\t' || *p == '"')
+ ++p;
Start = p;
/* Go up to next " */
- while (*p != '"' && *p != ANSI_NULL)
- p++;
+ while (*p != ANSI_NULL && *p != '"')
+ ++p;
+ /* NULL-terminate */
*p = ANSI_NULL;
- /* Copy result */
- strcpy(TempString, Start);
- strcpy(QuotedString, TempString);
-
- return TRUE;
+ /* Move the NULL-terminated string back into 'QuotedString' in place */
+ Size = (strlen(Start) + 1) * sizeof(CHAR);
+ memmove(QuotedString, Start, Size);
}
-VOID
-LoadAndBootLinux(IN OperatingSystemItem* OperatingSystem,
- IN USHORT OperatingSystemVersion)
+ARC_STATUS
+LoadAndBootLinux(
+ IN ULONG Argc,
+ IN PCHAR Argv[],
+ IN PCHAR Envp[])
{
- PCSTR SectionName = OperatingSystem->SystemPartition;
- PCSTR Description = OperatingSystem->LoadIdentifier;
+ PCSTR Description;
PFILE LinuxKernel = 0;
PFILE LinuxInitrdFile = 0;
+ Description = GetArgumentValue(Argc, Argv, "LoadIdentifier");
if (Description)
- sprintf(LinuxBootDescription, "Loading %s...", Description);
+ RtlStringCbPrintfA(LinuxBootDescription, sizeof(LinuxBootDescription),
"Loading %s...", Description);
else
strcpy(LinuxBootDescription, "Loading Linux...");
@@ -92,8 +94,11 @@ LoadAndBootLinux(IN OperatingSystemItem* OperatingSystem,
UiDrawStatusText(LinuxBootDescription);
UiDrawProgressBarCenter(0, 100, LinuxBootDescription);
+ /* Find all the message box settings and run them */
+ UiShowMessageBoxesInArgv(Argc, Argv);
+
/* Parse the .ini file section */
- if (!LinuxParseIniSection(SectionName))
+ if (!LinuxParseIniSection(Argc, Argv))
goto LinuxBootFailed;
/* Open the kernel */
@@ -105,7 +110,7 @@ LoadAndBootLinux(IN OperatingSystemItem* OperatingSystem,
}
/* Open the initrd file image (if necessary) */
- if (LinuxHasInitrd)
+ if (LinuxInitrdName)
{
LinuxInitrdFile = FsOpenFile(LinuxInitrdName);
if (!LinuxInitrdFile)
@@ -134,7 +139,7 @@ LoadAndBootLinux(IN OperatingSystemItem* OperatingSystem,
goto LinuxBootFailed;
/* Read the initrd (if necessary) */
- if (LinuxHasInitrd)
+ if (LinuxInitrdName)
{
if (!LinuxReadInitrd(LinuxInitrdFile))
goto LinuxBootFailed;
@@ -161,7 +166,9 @@ LoadAndBootLinux(IN OperatingSystemItem* OperatingSystem,
RtlCopyMemory((PVOID)0x90000, LinuxBootSector, 512);
RtlCopyMemory((PVOID)0x90200, LinuxSetupSector, SetupSectorSize);
- RtlCopyMemory((PVOID)0x99000, LinuxCommandLine, LinuxCommandLineSize);
+ RtlCopyMemory((PVOID)0x99000,
+ LinuxCommandLine ? LinuxCommandLine : "",
+ LinuxCommandLine ? LinuxCommandLineSize : sizeof(ANSI_NULL));
UiUnInitialize("Booting Linux...");
IniCleanup();
@@ -196,54 +203,52 @@ LinuxBootFailed:
LinuxBootSector = NULL;
LinuxSetupSector = NULL;
- LinuxKernelLoadAddress = NULL;
- LinuxInitrdLoadAddress = NULL;
SetupSectorSize = 0;
NewStyleLinuxKernel = FALSE;
LinuxKernelSize = 0;
- LinuxHasInitrd = FALSE;
- strcpy(LinuxCommandLine, "");
+ LinuxInitrdSize = 0;
+ LinuxKernelName = NULL;
+ LinuxInitrdName = NULL;
+ LinuxCommandLine = NULL;
LinuxCommandLineSize = 0;
+ LinuxKernelLoadAddress = NULL;
+ LinuxInitrdLoadAddress = NULL;
+ *LinuxBootDescription = ANSI_NULL;
+ LinuxBootPath = NULL;
+
+ return ENOEXEC;
}
-BOOLEAN LinuxParseIniSection(PCSTR SectionName)
+BOOLEAN
+LinuxParseIniSection(
+ IN ULONG Argc,
+ IN PCHAR Argv[])
{
- ULONG_PTR SectionId;
-
- /* Find all the message box settings and run them */
- UiShowMessageBoxesInSection(SectionName);
-
- /* 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 FALSE;
- }
-
- if (!IniReadSettingByName(SectionId, "BootPath", LinuxBootPath,
sizeof(LinuxBootPath)))
+ LinuxBootPath = GetArgumentValue(Argc, Argv, "BootPath");
+ if (!LinuxBootPath)
{
UiMessageBox("Boot path not specified for selected OS!");
return FALSE;
}
/* Get the kernel name */
- if (!IniReadSettingByName(SectionId, "Kernel", LinuxKernelName,
sizeof(LinuxKernelName)))
+ LinuxKernelName = GetArgumentValue(Argc, Argv, "Kernel");
+ if (!LinuxKernelName)
{
UiMessageBox("Linux kernel filename not specified for selected OS!");
return FALSE;
}
- /* Get the initrd name */
- if (IniReadSettingByName(SectionId, "Initrd", LinuxInitrdName,
sizeof(LinuxInitrdName)))
- {
- LinuxHasInitrd = TRUE;
- }
+ /* Get the initrd name (optional) */
+ LinuxInitrdName = GetArgumentValue(Argc, Argv, "Initrd");
- /* Get the command line */
- if (IniReadSettingByName(SectionId, "CommandLine", LinuxCommandLine,
sizeof(LinuxCommandLine)))
+ /* Get the command line (optional) */
+ LinuxCommandLineSize = 0;
+ LinuxCommandLine = GetArgumentValue(Argc, Argv, "CommandLine");
+ if (LinuxCommandLine)
{
RemoveQuotes(LinuxCommandLine);
- LinuxCommandLineSize = strlen(LinuxCommandLine) + 1;
+ LinuxCommandLineSize = min(strlen(LinuxCommandLine) + 1, 260);
}
return TRUE;
@@ -270,14 +275,14 @@ BOOLEAN LinuxReadBootSector(PFILE LinuxKernelFile)
// DbgDumpBuffer(DPRINT_LINUX, LinuxBootSector, 512);
- TRACE("SetupSectors: %d\n", LinuxBootSector->SetupSectors);
- TRACE("RootFlags: 0x%x\n", LinuxBootSector->RootFlags);
- TRACE("SystemSize: 0x%x\n", LinuxBootSector->SystemSize);
- TRACE("SwapDevice: 0x%x\n", LinuxBootSector->SwapDevice);
- TRACE("RamSize: 0x%x\n", LinuxBootSector->RamSize);
- TRACE("VideoMode: 0x%x\n", LinuxBootSector->VideoMode);
- TRACE("RootDevice: 0x%x\n", LinuxBootSector->RootDevice);
- TRACE("BootFlag: 0x%x\n", LinuxBootSector->BootFlag);
+ TRACE("SetupSectors: %d\n" , LinuxBootSector->SetupSectors);
+ TRACE("RootFlags: 0x%x\n", LinuxBootSector->RootFlags);
+ TRACE("SystemSize: 0x%x\n", LinuxBootSector->SystemSize);
+ TRACE("SwapDevice: 0x%x\n", LinuxBootSector->SwapDevice);
+ TRACE("RamSize: 0x%x\n", LinuxBootSector->RamSize);
+ TRACE("VideoMode: 0x%x\n", LinuxBootSector->VideoMode);
+ TRACE("RootDevice: 0x%x\n", LinuxBootSector->RootDevice);
+ TRACE("BootFlag: 0x%x\n", LinuxBootSector->BootFlag);
return TRUE;
}
@@ -286,14 +291,13 @@ BOOLEAN LinuxReadSetupSector(PFILE LinuxKernelFile)
{
UCHAR TempLinuxSetupSector[512];
- LinuxSetupSector = (PLINUX_SETUPSECTOR)TempLinuxSetupSector;
-
/* Read first linux setup sector */
FsSetFilePointer(LinuxKernelFile, 512);
if (!FsReadFile(LinuxKernelFile, 512, NULL, TempLinuxSetupSector))
return FALSE;
/* Check the kernel version */
+ LinuxSetupSector = (PLINUX_SETUPSECTOR)TempLinuxSetupSector;
if (!LinuxCheckKernelVersion())
return FALSE;
@@ -318,18 +322,18 @@ BOOLEAN LinuxReadSetupSector(PFILE LinuxKernelFile)
// DbgDumpBuffer(DPRINT_LINUX, LinuxSetupSector, SetupSectorSize);
TRACE("SetupHeaderSignature: 0x%x (HdrS)\n",
LinuxSetupSector->SetupHeaderSignature);
- TRACE("Version: 0x%x\n", LinuxSetupSector->Version);
+ TRACE("Version: 0x%x\n", LinuxSetupSector->Version);
TRACE("RealModeSwitch: 0x%x\n", LinuxSetupSector->RealModeSwitch);
- TRACE("SetupSeg: 0x%x\n", LinuxSetupSector->SetupSeg);
+ TRACE("SetupSeg: 0x%x\n", LinuxSetupSector->SetupSeg);
TRACE("StartSystemSeg: 0x%x\n", LinuxSetupSector->StartSystemSeg);
- TRACE("KernelVersion: 0x%x\n", LinuxSetupSector->KernelVersion);
- TRACE("TypeOfLoader: 0x%x\n", LinuxSetupSector->TypeOfLoader);
- TRACE("LoadFlags: 0x%x\n", LinuxSetupSector->LoadFlags);
- TRACE("SetupMoveSize: 0x%x\n", LinuxSetupSector->SetupMoveSize);
- TRACE("Code32Start: 0x%x\n", LinuxSetupSector->Code32Start);
+ TRACE("KernelVersion: 0x%x\n", LinuxSetupSector->KernelVersion);
+ TRACE("TypeOfLoader: 0x%x\n", LinuxSetupSector->TypeOfLoader);
+ TRACE("LoadFlags: 0x%x\n", LinuxSetupSector->LoadFlags);
+ TRACE("SetupMoveSize: 0x%x\n", LinuxSetupSector->SetupMoveSize);
+ TRACE("Code32Start: 0x%x\n", LinuxSetupSector->Code32Start);
TRACE("RamdiskAddress: 0x%x\n", LinuxSetupSector->RamdiskAddress);
- TRACE("RamdiskSize: 0x%x\n", LinuxSetupSector->RamdiskSize);
- TRACE("BootSectKludgeOffset: 0x%x\n",
LinuxSetupSector->BootSectKludgeOffset);
+ TRACE("RamdiskSize: 0x%x\n", LinuxSetupSector->RamdiskSize);
+ TRACE("BootSectKludgeOffset: 0x%x\n",
LinuxSetupSector->BootSectKludgeOffset);
TRACE("BootSectKludgeSegment: 0x%x\n",
LinuxSetupSector->BootSectKludgeSegment);
TRACE("HeapEnd: 0x%x\n", LinuxSetupSector->HeapEnd);
@@ -398,7 +402,7 @@ BOOLEAN LinuxCheckKernelVersion(VOID)
LinuxSetupSector->LoadFlags |= LINUX_FLAG_CAN_USE_HEAP;
}
- if ((NewStyleLinuxKernel == FALSE) && (LinuxHasInitrd))
+ if ((NewStyleLinuxKernel == FALSE) && (LinuxInitrdName))
{
UiMessageBox("Error: Cannot load a ramdisk (initrd) with an old kernel
image.");
return FALSE;
@@ -437,7 +441,7 @@ BOOLEAN LinuxReadInitrd(PFILE LinuxInitrdFile)
LinuxSetupSector->RamdiskSize = LinuxInitrdSize;
TRACE("RamdiskAddress: 0x%x\n", LinuxSetupSector->RamdiskAddress);
- TRACE("RamdiskSize: 0x%x\n", LinuxSetupSector->RamdiskSize);
+ TRACE("RamdiskSize: 0x%x\n", LinuxSetupSector->RamdiskSize);
if (LinuxSetupSector->Version >= 0x0203)
{
diff --git a/boot/freeldr/freeldr/miscboot.c b/boot/freeldr/freeldr/miscboot.c
index 4ad2daa90c6..98cb5278594 100644
--- a/boot/freeldr/freeldr/miscboot.c
+++ b/boot/freeldr/freeldr/miscboot.c
@@ -25,51 +25,46 @@
/* FUNCTIONS ******************************************************************/
-VOID
-LoadAndBootBootSector(IN OperatingSystemItem* OperatingSystem,
- IN USHORT OperatingSystemVersion)
+ARC_STATUS
+LoadAndBootBootSector(
+ IN ULONG Argc,
+ IN PCHAR Argv[],
+ IN PCHAR Envp[])
{
- ULONG_PTR SectionId;
- PCSTR SectionName = OperatingSystem->SystemPartition;
- CHAR FileName[260];
+ PCSTR FileName;
PFILE FilePointer;
ULONG BytesRead;
/* Find all the message box settings and run them */
- UiShowMessageBoxesInSection(SectionName);
+ UiShowMessageBoxesInArgv(Argc, Argv);
- /* 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;
- }
-
- if (!IniReadSettingByName(SectionId, "BootSectorFile", FileName,
sizeof(FileName)))
+ /* Read the file name */
+ FileName = GetArgumentValue(Argc, Argv, "BootSectorFile");
+ if (!FileName)
{
UiMessageBox("Boot sector file not specified for selected OS!");
- return;
+ return EINVAL;
}
FilePointer = FsOpenFile(FileName);
if (!FilePointer)
{
UiMessageBox("%s not found.", FileName);
- return;
+ return ENOENT;
}
/* Read boot sector */
if (!FsReadFile(FilePointer, 512, &BytesRead, (void*)0x7c00) || (BytesRead !=
512))
{
UiMessageBox("Unable to read boot sector.");
- return;
+ return EIO;
}
/* Check for validity */
if (*((USHORT*)(0x7c00 + 0x1fe)) != 0xaa55)
{
UiMessageBox("Invalid boot sector magic (0xaa55)");
- return;
+ return ENOEXEC;
}
UiUnInitialize("Booting...");
@@ -87,65 +82,59 @@ LoadAndBootBootSector(IN OperatingSystemItem* OperatingSystem,
// DiskStopFloppyMotor();
// DisableA20();
ChainLoadBiosBootSectorCode();
+ return ESUCCESS;
}
-VOID
-LoadAndBootPartition(IN OperatingSystemItem* OperatingSystem,
- IN USHORT OperatingSystemVersion)
+ARC_STATUS
+LoadAndBootPartition(
+ IN ULONG Argc,
+ IN PCHAR Argv[],
+ IN PCHAR Envp[])
{
- ULONG_PTR SectionId;
- PCSTR SectionName = OperatingSystem->SystemPartition;
- CHAR SettingValue[80];
+ PCSTR ArgValue;
PARTITION_TABLE_ENTRY PartitionTableEntry;
UCHAR DriveNumber;
ULONG PartitionNumber;
/* Find all the message box settings and run them */
- UiShowMessageBoxesInSection(SectionName);
-
- /* 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;
- }
+ UiShowMessageBoxesInArgv(Argc, Argv);
/* Read the boot drive */
- if (!IniReadSettingByName(SectionId, "BootDrive", SettingValue,
sizeof(SettingValue)))
+ ArgValue = GetArgumentValue(Argc, Argv, "BootDrive");
+ if (!ArgValue)
{
UiMessageBox("Boot drive not specified for selected OS!");
- return;
+ return EINVAL;
}
-
- DriveNumber = DriveMapGetBiosDriveNumber(SettingValue);
+ DriveNumber = DriveMapGetBiosDriveNumber(ArgValue);
/* Read the boot partition */
- if (!IniReadSettingByName(SectionId, "BootPartition", SettingValue,
sizeof(SettingValue)))
+ ArgValue = GetArgumentValue(Argc, Argv, "BootPartition");
+ if (!ArgValue)
{
UiMessageBox("Boot partition not specified for selected OS!");
- return;
+ return EINVAL;
}
-
- PartitionNumber = atoi(SettingValue);
+ PartitionNumber = atoi(ArgValue);
/* Get the partition table entry */
if (!DiskGetPartitionEntry(DriveNumber, PartitionNumber, &PartitionTableEntry))
{
- return;
+ return ENOENT;
}
/* Now try to read the partition boot sector. If this fails then abort. */
if (!MachDiskReadLogicalSectors(DriveNumber,
PartitionTableEntry.SectorCountBeforePartition, 1, (PVOID)0x7C00))
{
UiMessageBox("Unable to read partition's boot sector.");
- return;
+ return EIO;
}
/* Check for validity */
if (*((USHORT*)(0x7c00 + 0x1fe)) != 0xaa55)
{
UiMessageBox("Invalid boot sector magic (0xaa55)");
- return;
+ return ENOEXEC;
}
UiUnInitialize("Booting...");
@@ -164,47 +153,42 @@ LoadAndBootPartition(IN OperatingSystemItem* OperatingSystem,
// DisableA20();
FrldrBootDrive = DriveNumber;
ChainLoadBiosBootSectorCode();
+ return ESUCCESS;
}
-VOID
-LoadAndBootDrive(IN OperatingSystemItem* OperatingSystem,
- IN USHORT OperatingSystemVersion)
+ARC_STATUS
+LoadAndBootDrive(
+ IN ULONG Argc,
+ IN PCHAR Argv[],
+ IN PCHAR Envp[])
{
- ULONG_PTR SectionId;
- PCSTR SectionName = OperatingSystem->SystemPartition;
- CHAR SettingValue[80];
+ PCSTR ArgValue;
UCHAR DriveNumber;
/* Find all the message box settings and run them */
- UiShowMessageBoxesInSection(SectionName);
-
- /* 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;
- }
+ UiShowMessageBoxesInArgv(Argc, Argv);
- if (!IniReadSettingByName(SectionId, "BootDrive", SettingValue,
sizeof(SettingValue)))
+ /* Read the boot drive */
+ ArgValue = GetArgumentValue(Argc, Argv, "BootDrive");
+ if (!ArgValue)
{
UiMessageBox("Boot drive not specified for selected OS!");
- return;
+ return EINVAL;
}
-
- DriveNumber = DriveMapGetBiosDriveNumber(SettingValue);
+ DriveNumber = DriveMapGetBiosDriveNumber(ArgValue);
/* Now try to read the boot sector (or mbr). If this fails then abort. */
if (!MachDiskReadLogicalSectors(DriveNumber, 0, 1, (PVOID)0x7C00))
{
UiMessageBox("Unable to read boot sector");
- return;
+ return EIO;
}
/* Check for validity */
if (*((USHORT*)(0x7c00 + 0x1fe)) != 0xaa55)
{
UiMessageBox("Invalid boot sector magic (0xaa55)");
- return;
+ return ENOEXEC;
}
UiUnInitialize("Booting...");
@@ -223,6 +207,7 @@ LoadAndBootDrive(IN OperatingSystemItem* OperatingSystem,
// DisableA20();
FrldrBootDrive = DriveNumber;
ChainLoadBiosBootSectorCode();
+ return ESUCCESS;
}
#endif // _M_IX86
diff --git a/boot/freeldr/freeldr/ntldr/setupldr.c
b/boot/freeldr/freeldr/ntldr/setupldr.c
index 68841f8cda6..98b66e82f95 100644
--- a/boot/freeldr/freeldr/ntldr/setupldr.c
+++ b/boot/freeldr/freeldr/ntldr/setupldr.c
@@ -141,18 +141,17 @@ SetupLdrScanBootDrivers(PLIST_ENTRY BootDriverListHead, HINF
InfHandle, LPCSTR S
/* SETUP STARTER **************************************************************/
-VOID
-LoadReactOSSetup(IN OperatingSystemItem* OperatingSystem,
- IN USHORT OperatingSystemVersion)
+ARC_STATUS
+LoadReactOSSetup(
+ IN ULONG Argc,
+ IN PCHAR Argv[],
+ IN PCHAR Envp[])
{
- ULONG_PTR SectionId;
- PCSTR SectionName = OperatingSystem->SystemPartition;
- CHAR SettingsValue[80];
- BOOLEAN HasSection;
- CHAR BootOptions2[256];
+ PCSTR ArgValue;
PCHAR File;
CHAR FileName[512];
CHAR BootPath[512];
+ CHAR BootOptions2[256];
LPCSTR LoadOptions;
LPSTR BootOptions;
BOOLEAN BootFromFloppy;
@@ -163,7 +162,8 @@ LoadReactOSSetup(IN OperatingSystemItem* OperatingSystem,
PLOADER_PARAMETER_BLOCK LoaderBlock;
PSETUP_LOADER_BLOCK SetupBlock;
LPCSTR SystemPath;
- LPCSTR SourcePaths[] =
+
+ static LPCSTR SourcePaths[] =
{
"", /* Only for floppy boot */
#if defined(_M_IX86)
@@ -179,31 +179,27 @@ LoadReactOSSetup(IN OperatingSystemItem* OperatingSystem,
UiDrawStatusText("Setup is loading...");
- /* Get OS setting value */
- SettingsValue[0] = ANSI_NULL;
- IniOpenSection("Operating Systems", &SectionId);
- IniReadSettingByName(SectionId, SectionName, SettingsValue, sizeof(SettingsValue));
-
- /* Open the operating system section specified in the .ini file */
- HasSection = IniOpenSection(SectionName, &SectionId);
-
UiDrawBackdrop();
UiDrawProgressBarCenter(1, 100, "Loading ReactOS Setup...");
- /* Read the system path is set in the .ini file */
- BootPath[0] = ANSI_NULL;
- if (!HasSection || !IniReadSettingByName(SectionId, "SystemPath", BootPath,
sizeof(BootPath)))
+ /* Retrieve the system path */
+ *BootPath = ANSI_NULL;
+ ArgValue = GetArgumentValue(Argc, Argv, "SystemPath");
+ if (ArgValue)
+ {
+ RtlStringCbCopyA(BootPath, sizeof(BootPath), ArgValue);
+ }
+ else
{
/*
* IMPROVE: I don't want to call MachDiskGetBootPath here as a
* default choice because I can call it after (see few lines below).
- * Also doing the strcpy call as it is done in winldr.c is not
- * really what we want. Instead I reset BootPath here so that
- * we can build the full path using the general code from below.
+ * Instead I reset BootPath here so that we can build the full path
+ * using the general code from below.
*/
// MachDiskGetBootPath(BootPath, sizeof(BootPath));
- // strcpy(BootPath, SectionName);
- BootPath[0] = ANSI_NULL;
+ // RtlStringCbCopyA(BootPath, sizeof(BootPath), ArgValue);
+ *BootPath = ANSI_NULL;
}
/*
@@ -215,65 +211,34 @@ LoadReactOSSetup(IN OperatingSystemItem* OperatingSystem,
if (strrchr(BootPath, ')') == NULL)
{
/* Temporarily save the boot path */
- strcpy(FileName, BootPath);
+ RtlStringCbCopyA(FileName, sizeof(FileName), BootPath);
/* This is not a full path. Use the current (i.e. boot) device. */
MachDiskGetBootPath(BootPath, sizeof(BootPath));
/* Append a path separator if needed */
- if (FileName[0] != '\\' && FileName[0] != '/')
- strcat(BootPath, "\\");
+ if (*FileName != '\\' && *FileName != '/')
+ RtlStringCbCatA(BootPath, sizeof(BootPath), "\\");
/* Append the remaining path */
- strcat(BootPath, FileName);
+ RtlStringCbCatA(BootPath, sizeof(BootPath), FileName);
}
/* Append a backslash if needed */
- if ((strlen(BootPath) == 0) || BootPath[strlen(BootPath) - 1] != '\\')
- strcat(BootPath, "\\");
+ if (!*BootPath || BootPath[strlen(BootPath) - 1] != '\\')
+ RtlStringCbCatA(BootPath, sizeof(BootPath), "\\");
- /* Read boot options */
- BootOptions2[0] = ANSI_NULL;
- if (!HasSection || !IniReadSettingByName(SectionId, "Options",
BootOptions2, sizeof(BootOptions2)))
- {
- /* Retrieve the options after the quoted title */
- PCSTR p = SettingsValue;
-
- /* Trim any leading whitespace and quotes */
- while (*p == ' ' || *p == '\t' || *p == '"')
- ++p;
- /* Skip all the text up to the first last quote */
- while (*p != ANSI_NULL && *p != '"')
- ++p;
- /* Trim any trailing whitespace and quotes */
- while (*p == ' ' || *p == '\t' || *p == '"')
- ++p;
-
- strcpy(BootOptions2, p);
- TRACE("BootOptions: '%s'\n", BootOptions2);
- }
-
- /* Check if a ramdisk file was given */
- File = strstr(BootOptions2, "/RDPATH=");
- if (File)
- {
- /* Copy the file name and everything else after it */
- strcpy(FileName, File + 8);
+ TRACE("BootPath: '%s'\n", BootPath);
- /* Null-terminate */
- *strstr(FileName, " ") = ANSI_NULL;
+ /* Retrieve the boot options */
+ *BootOptions2 = ANSI_NULL;
+ ArgValue = GetArgumentValue(Argc, Argv, "Options");
+ if (ArgValue)
+ RtlStringCbCopyA(BootOptions2, sizeof(BootOptions2), ArgValue);
- /* Load the ramdisk */
- if (!RamDiskLoadVirtualFile(FileName))
- {
- UiMessageBox("Failed to load RAM disk file %s", FileName);
- return;
- }
- }
+ TRACE("BootOptions: '%s'\n", BootOptions2);
- TRACE("BootPath: '%s'\n", BootPath);
-
- /* And check if we booted from floppy */
+ /* Check if we booted from floppy */
BootFromFloppy = strstr(BootPath, "fdisk") != NULL;
/* Open 'txtsetup.sif' from any of source paths */
@@ -284,11 +249,11 @@ LoadReactOSSetup(IN OperatingSystemItem* OperatingSystem,
if (!SystemPath)
{
UiMessageBox("Failed to open txtsetup.sif");
- return;
+ return ENOENT;
}
- strcpy(File, SystemPath);
- strcpy(FileName, BootPath);
- strcat(FileName, "txtsetup.sif");
+ RtlStringCbCopyA(File, sizeof(BootPath) - (File - BootPath)*sizeof(CHAR),
SystemPath);
+ RtlStringCbCopyA(FileName, sizeof(FileName), BootPath);
+ RtlStringCbCatA(FileName, sizeof(FileName), "txtsetup.sif");
if (InfOpenFile(&InfHandle, FileName, &ErrorLine))
{
break;
@@ -301,13 +266,13 @@ LoadReactOSSetup(IN OperatingSystemItem* OperatingSystem,
if (!InfFindFirstLine(InfHandle, "SetupData", "OsLoadOptions",
&InfContext))
{
ERR("Failed to find 'SetupData/OsLoadOptions'\n");
- return;
+ return EINVAL;
}
if (!InfGetDataField(&InfContext, 1, &LoadOptions))
{
ERR("Failed to get load options\n");
- return;
+ return EINVAL;
}
#if DBG
@@ -323,10 +288,29 @@ LoadReactOSSetup(IN OperatingSystemItem* OperatingSystem,
/* Copy loadoptions (original string will be freed) */
BootOptions = FrLdrTempAlloc(strlen(LoadOptions) + 1, TAG_BOOT_OPTIONS);
+ ASSERT(BootOptions);
strcpy(BootOptions, LoadOptions);
TRACE("BootOptions: '%s'\n", BootOptions);
+ /* Check if a ramdisk file was given */
+ File = strstr(BootOptions2, "/RDPATH=");
+ if (File)
+ {
+ /* Copy the file name and everything else after it */
+ RtlStringCbCopyA(FileName, sizeof(FileName), File + 8);
+
+ /* Null-terminate */
+ *strstr(FileName, " ") = ANSI_NULL;
+
+ /* Load the ramdisk */
+ if (!RamDiskLoadVirtualFile(FileName))
+ {
+ UiMessageBox("Failed to load RAM disk file %s", FileName);
+ return ENOENT;
+ }
+ }
+
/* Allocate and minimalist-initialize LPB */
AllocateAndInitLPB(&LoaderBlock);
@@ -344,11 +328,11 @@ LoadReactOSSetup(IN OperatingSystemItem* OperatingSystem,
TRACE("Setup SYSTEM hive %s\n", (Success ? "loaded" : "not
loaded"));
/* Bail out if failure */
if (!Success)
- return;
+ return ENOEXEC;
/* Load NLS data, they are in the System32 directory of the installation medium */
- strcpy(FileName, BootPath);
- strcat(FileName, "system32\\");
+ RtlStringCbCopyA(FileName, sizeof(FileName), BootPath);
+ RtlStringCbCatA(FileName, sizeof(FileName), "system32\\");
SetupLdrLoadNlsData(LoaderBlock, InfHandle, FileName);
// UiDrawStatusText("Press F6 if you need to install a 3rd-party SCSI or RAID
driver...");
@@ -362,9 +346,9 @@ LoadReactOSSetup(IN OperatingSystemItem* OperatingSystem,
UiDrawStatusText("The Setup program is starting...");
/* Load ReactOS Setup */
- LoadAndBootWindowsCommon(_WIN32_WINNT_WS03,
- LoaderBlock,
- BootOptions,
- BootPath,
- TRUE);
+ return LoadAndBootWindowsCommon(_WIN32_WINNT_WS03,
+ LoaderBlock,
+ BootOptions,
+ BootPath,
+ TRUE);
}
diff --git a/boot/freeldr/freeldr/ntldr/winldr.c b/boot/freeldr/freeldr/ntldr/winldr.c
index e8e2eb2fbff..98de7f29922 100644
--- a/boot/freeldr/freeldr/ntldr/winldr.c
+++ b/boot/freeldr/freeldr/ntldr/winldr.c
@@ -88,16 +88,15 @@ WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock,
LPSTR LoadOptions, NewLoadOptions;
CHAR HalPath[] = "\\";
- CHAR ArcBoot[256];
- CHAR MiscFiles[256];
+ CHAR ArcBoot[MAX_PATH+1];
+ CHAR MiscFiles[MAX_PATH+1];
ULONG i;
ULONG_PTR PathSeparator;
PLOADER_PARAMETER_EXTENSION Extension;
/* Construct SystemRoot and ArcBoot from SystemPath */
PathSeparator = strstr(BootPath, "\\") - BootPath;
- strncpy(ArcBoot, BootPath, PathSeparator);
- ArcBoot[PathSeparator] = ANSI_NULL;
+ RtlStringCbCopyNA(ArcBoot, sizeof(ArcBoot), BootPath, PathSeparator);
TRACE("ArcBoot: '%s'\n", ArcBoot);
TRACE("SystemRoot: '%s'\n", SystemRoot);
@@ -105,7 +104,7 @@ WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock,
/* Fill ARC BootDevice */
LoaderBlock->ArcBootDeviceName = WinLdrSystemBlock->ArcBootDeviceName;
- strncpy(LoaderBlock->ArcBootDeviceName, ArcBoot, MAX_PATH);
+ RtlStringCbCopyA(LoaderBlock->ArcBootDeviceName,
sizeof(WinLdrSystemBlock->ArcBootDeviceName), ArcBoot);
LoaderBlock->ArcBootDeviceName = PaToVa(LoaderBlock->ArcBootDeviceName);
/* Fill ARC HalDevice, it matches ArcBoot path */
@@ -114,17 +113,17 @@ WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock,
/* Fill SystemRoot */
LoaderBlock->NtBootPathName = WinLdrSystemBlock->NtBootPathName;
- strncpy(LoaderBlock->NtBootPathName, SystemRoot, MAX_PATH);
+ RtlStringCbCopyA(LoaderBlock->NtBootPathName,
sizeof(WinLdrSystemBlock->NtBootPathName), SystemRoot);
LoaderBlock->NtBootPathName = PaToVa(LoaderBlock->NtBootPathName);
/* Fill NtHalPathName */
LoaderBlock->NtHalPathName = WinLdrSystemBlock->NtHalPathName;
- strncpy(LoaderBlock->NtHalPathName, HalPath, MAX_PATH);
+ RtlStringCbCopyA(LoaderBlock->NtHalPathName,
sizeof(WinLdrSystemBlock->NtHalPathName), HalPath);
LoaderBlock->NtHalPathName = PaToVa(LoaderBlock->NtHalPathName);
/* Fill LoadOptions and strip the '/' switch symbol in front of each option
*/
NewLoadOptions = LoadOptions = LoaderBlock->LoadOptions =
WinLdrSystemBlock->LoadOptions;
- strncpy(LoaderBlock->LoadOptions, Options, MAX_OPTIONS_LENGTH);
+ RtlStringCbCopyA(LoaderBlock->LoadOptions,
sizeof(WinLdrSystemBlock->LoadOptions), Options);
do
{
@@ -205,8 +204,8 @@ WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock,
}
#endif
/* Load drivers database */
- strcpy(MiscFiles, BootPath);
- strcat(MiscFiles, "AppPatch\\drvmain.sdb");
+ RtlStringCbCopyA(MiscFiles, sizeof(MiscFiles), BootPath);
+ RtlStringCbCatA(MiscFiles, sizeof(MiscFiles), "AppPatch\\drvmain.sdb");
Extension->DrvDBImage = PaToVa(WinLdrLoadModule(MiscFiles,
&Extension->DrvDBSize,
LoaderRegistryData));
@@ -235,21 +234,21 @@ WinLdrLoadDeviceDriver(PLIST_ENTRY LoadOrderListHead,
PVOID DriverBase = NULL;
// Separate the path to file name and directory path
- _snprintf(DriverPath, sizeof(DriverPath), "%wZ", FilePath);
+ RtlStringCbPrintfA(DriverPath, sizeof(DriverPath), "%wZ", FilePath);
DriverNamePos = strrchr(DriverPath, '\\');
if (DriverNamePos != NULL)
{
// Copy the name
- strcpy(DllName, DriverNamePos+1);
+ RtlStringCbCopyA(DllName, sizeof(DllName), DriverNamePos+1);
// Cut out the name from the path
- *(DriverNamePos+1) = 0;
+ *(DriverNamePos+1) = ANSI_NULL;
}
else
{
// There is no directory in the path
- strcpy(DllName, DriverPath);
- DriverPath[0] = ANSI_NULL;
+ RtlStringCbCopyA(DllName, sizeof(DllName), DriverPath);
+ *DriverPath = ANSI_NULL;
}
TRACE("DriverPath: '%s', DllName: '%s', LPB\n", DriverPath,
DllName);
@@ -263,7 +262,7 @@ WinLdrLoadDeviceDriver(PLIST_ENTRY LoadOrderListHead,
}
// It's not loaded, we have to load it
- _snprintf(FullPath, sizeof(FullPath), "%s%wZ", BootPath, FilePath);
+ RtlStringCbPrintfA(FullPath, sizeof(FullPath), "%s%wZ", BootPath,
FilePath);
Success = WinLdrLoadImage(FullPath, LoaderBootDriver, &DriverBase);
if (!Success)
return FALSE;
@@ -280,7 +279,7 @@ WinLdrLoadDeviceDriver(PLIST_ENTRY LoadOrderListHead,
(*DriverDTE)->Flags |= Flags;
// Look for any dependencies it may have, and load them too
- sprintf(FullPath,"%s%s", BootPath, DriverPath);
+ RtlStringCbPrintfA(FullPath, sizeof(FullPath), "%s%s", BootPath,
DriverPath);
Success = WinLdrScanImportDescriptorTable(LoadOrderListHead, FullPath, *DriverDTE);
if (!Success)
{
@@ -359,7 +358,7 @@ WinLdrLoadModule(PCSTR ModuleName,
/* Inform user we are loading files */
//UiDrawBackdrop();
- //sprintf(ProgressString, "Loading %s...", FileName);
+ //RtlStringCbPrintfA(ProgressString, sizeof(ProgressString), "Loading
%s...", FileName);
//UiDrawProgressBarCenter(1, 100, ProgressString);
TRACE("Loading module %s\n", ModuleName);
@@ -441,11 +440,11 @@ LoadModule(
PVOID BaseAddress = NULL;
UiDrawBackdrop();
- sprintf(ProgressString, "Loading %s...", File);
+ RtlStringCbPrintfA(ProgressString, sizeof(ProgressString), "Loading %s...",
File);
UiDrawProgressBarCenter(Percentage, 100, ProgressString);
- strcpy(FullFileName, Path);
- strcat(FullFileName, File);
+ RtlStringCbCopyA(FullFileName, sizeof(FullFileName), Path);
+ RtlStringCbCatA(FullFileName, sizeof(FullFileName), File);
Success = WinLdrLoadImage(FullFileName, MemoryType, &BaseAddress);
if (!Success)
@@ -488,16 +487,16 @@ LoadWindowsCore(IN USHORT OperatingSystemVersion,
if (!KernelDTE) return FALSE;
/* Initialize SystemRoot\System32 path */
- strcpy(DirPath, BootPath);
- strcat(DirPath, "system32\\");
+ 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 */
- strcpy(KernelFileName, "ntoskrnl.exe");
- strcpy(HalFileName , "hal.dll");
+ RtlStringCbCopyA(KernelFileName, sizeof(KernelFileName), "ntoskrnl.exe");
+ RtlStringCbCopyA(HalFileName , sizeof(HalFileName) , "hal.dll");
/* Find any /KERNEL= or /HAL= switch in the boot options */
Options = BootOptions;
@@ -528,15 +527,13 @@ LoadWindowsCore(IN USHORT OperatingSystemVersion,
if (_strnicmp(Options, "KERNEL=", 7) == 0)
{
Options += 7; i -= 7;
- strncpy(KernelFileName, Options, i);
- KernelFileName[i] = ANSI_NULL;
+ RtlStringCbCopyNA(KernelFileName, sizeof(KernelFileName), Options, i);
_strupr(KernelFileName);
}
else if (_strnicmp(Options, "HAL=", 4) == 0)
{
Options += 4; i -= 4;
- strncpy(HalFileName, Options, i);
- HalFileName[i] = ANSI_NULL;
+ RtlStringCbCopyNA(HalFileName, sizeof(HalFileName), Options, i);
_strupr(HalFileName);
}
}
@@ -611,20 +608,20 @@ LoadWindowsCore(IN USHORT OperatingSystemVersion,
* Format: /DEBUGPORT=COM1 or
/DEBUGPORT=FILE:\Device\HarddiskX\PartitionY\debug.log or /DEBUGPORT=FOO
* If we only have /DEBUGPORT= (i.e. without any port name), defaults it to
"COM".
*/
- strcpy(KdTransportDllName, "KD");
+ RtlStringCbCopyA(KdTransportDllName, sizeof(KdTransportDllName),
"KD");
if (_strnicmp(Options, "COM", 3) == 0 && '0' <=
Options[3] && Options[3] <= '9')
{
- strncat(KdTransportDllName, Options, 3);
+ RtlStringCbCatNA(KdTransportDllName, sizeof(KdTransportDllName), Options,
3);
}
else
{
size_t i = strcspn(Options, " \t:"); /* Skip valid separators:
whitespace or colon */
if (i == 0)
- strcat(KdTransportDllName, "COM");
+ RtlStringCbCatA(KdTransportDllName, sizeof(KdTransportDllName),
"COM");
else
- strncat(KdTransportDllName, Options, i);
+ RtlStringCbCatNA(KdTransportDllName, sizeof(KdTransportDllName),
Options, i);
}
- strcat(KdTransportDllName, ".DLL");
+ RtlStringCbCatA(KdTransportDllName, sizeof(KdTransportDllName),
".DLL");
_strupr(KdTransportDllName);
/*
@@ -646,38 +643,51 @@ LoadWindowsCore(IN USHORT OperatingSystemVersion,
return Success;
}
-VOID
-LoadAndBootWindows(IN OperatingSystemItem* OperatingSystem,
- IN USHORT OperatingSystemVersion)
+ARC_STATUS
+LoadAndBootWindows(
+ IN ULONG Argc,
+ IN PCHAR Argv[],
+ IN PCHAR Envp[])
{
- ULONG_PTR SectionId;
- PCSTR SectionName = OperatingSystem->SystemPartition;
+ PCSTR ArgValue;
PCHAR File;
BOOLEAN Success;
- BOOLEAN HasSection;
- CHAR SettingsValue[80];
+ USHORT OperatingSystemVersion;
+ PLOADER_PARAMETER_BLOCK LoaderBlock;
CHAR BootPath[MAX_PATH];
CHAR FileName[MAX_PATH];
CHAR BootOptions[256];
- PLOADER_PARAMETER_BLOCK LoaderBlock;
- /* Get OS setting value */
- SettingsValue[0] = ANSI_NULL;
- IniOpenSection("Operating Systems", &SectionId);
- IniReadSettingByName(SectionId, SectionName, SettingsValue, sizeof(SettingsValue));
+ ArgValue = GetArgumentValue(Argc, Argv, "BootType");
+ if (!ArgValue)
+ {
+ ERR("No 'BootType' value, aborting!\n");
+ return EINVAL;
+ }
- /* Open the operating system section specified in the .ini file */
- HasSection = IniOpenSection(SectionName, &SectionId);
+ if (_stricmp(ArgValue, "Windows") == 0 ||
+ _stricmp(ArgValue, "Windows2003") == 0)
+ {
+ OperatingSystemVersion = _WIN32_WINNT_WS03;
+ }
+ else if (_stricmp(ArgValue, "WindowsNT40") == 0)
+ {
+ OperatingSystemVersion = _WIN32_WINNT_NT4;
+ }
+ else
+ {
+ ERR("Unknown 'BootType' value '%s', aborting!\n",
ArgValue);
+ return EINVAL;
+ }
UiDrawBackdrop();
UiDrawProgressBarCenter(1, 100, "Loading NT...");
- /* Read the system path is set in the .ini file */
- BootPath[0] = ANSI_NULL;
- if (!HasSection || !IniReadSettingByName(SectionId, "SystemPath", BootPath,
sizeof(BootPath)))
- {
- strcpy(BootPath, SectionName);
- }
+ /* Retrieve the system path */
+ *BootPath = ANSI_NULL;
+ ArgValue = GetArgumentValue(Argc, Argv, "SystemPath");
+ if (ArgValue)
+ RtlStringCbCopyA(BootPath, sizeof(BootPath), ArgValue);
/*
* Check whether BootPath is a full path
@@ -688,53 +698,42 @@ LoadAndBootWindows(IN OperatingSystemItem* OperatingSystem,
if (strrchr(BootPath, ')') == NULL)
{
/* Temporarily save the boot path */
- strcpy(FileName, BootPath);
+ RtlStringCbCopyA(FileName, sizeof(FileName), BootPath);
/* This is not a full path. Use the current (i.e. boot) device. */
MachDiskGetBootPath(BootPath, sizeof(BootPath));
/* Append a path separator if needed */
- if (FileName[0] != '\\' && FileName[0] != '/')
- strcat(BootPath, "\\");
+ if (*FileName != '\\' && *FileName != '/')
+ RtlStringCbCatA(BootPath, sizeof(BootPath), "\\");
/* Append the remaining path */
- strcat(BootPath, FileName);
+ RtlStringCbCatA(BootPath, sizeof(BootPath), FileName);
}
/* Append a backslash if needed */
- if ((BootPath[0] == 0) || BootPath[strlen(BootPath) - 1] != '\\')
- strcat(BootPath, "\\");
+ if (!*BootPath || BootPath[strlen(BootPath) - 1] != '\\')
+ RtlStringCbCatA(BootPath, sizeof(BootPath), "\\");
- /* Read boot options */
- BootOptions[0] = ANSI_NULL;
- if (!HasSection || !IniReadSettingByName(SectionId, "Options", BootOptions,
sizeof(BootOptions)))
- {
- /* Retrieve the options after the quoted title */
- PCSTR p = SettingsValue;
-
- /* Trim any leading whitespace and quotes */
- while (*p == ' ' || *p == '\t' || *p == '"')
- ++p;
- /* Skip all the text up to the first last quote */
- while (*p != ANSI_NULL && *p != '"')
- ++p;
- /* Trim any trailing whitespace and quotes */
- while (*p == ' ' || *p == '\t' || *p == '"')
- ++p;
-
- strcpy(BootOptions, p);
- TRACE("BootOptions: '%s'\n", BootOptions);
- }
+ TRACE("BootPath: '%s'\n", BootPath);
+
+ /* Retrieve the boot options */
+ *BootOptions = ANSI_NULL;
+ ArgValue = GetArgumentValue(Argc, Argv, "Options");
+ if (ArgValue)
+ RtlStringCbCopyA(BootOptions, sizeof(BootOptions), ArgValue);
/* Append boot-time options */
AppendBootTimeOptions(BootOptions);
+ TRACE("BootOptions: '%s'\n", BootOptions);
+
/* Check if a ramdisk file was given */
File = strstr(BootOptions, "/RDPATH=");
if (File)
{
/* Copy the file name and everything else after it */
- strcpy(FileName, File + 8);
+ RtlStringCbCopyA(FileName, sizeof(FileName), File + 8);
/* Null-terminate */
*strstr(FileName, " ") = ANSI_NULL;
@@ -743,15 +742,13 @@ LoadAndBootWindows(IN OperatingSystemItem* OperatingSystem,
if (!RamDiskLoadVirtualFile(FileName))
{
UiMessageBox("Failed to load RAM disk file %s", FileName);
- return;
+ return ENOENT;
}
}
/* Let user know we started loading */
//UiDrawStatusText("Loading...");
- TRACE("BootPath: '%s'\n", BootPath);
-
/* Allocate and minimalist-initialize LPB */
AllocateAndInitLPB(&LoaderBlock);
@@ -762,24 +759,24 @@ LoadAndBootWindows(IN OperatingSystemItem* OperatingSystem,
TRACE("SYSTEM hive %s\n", (Success ? "loaded" : "not
loaded"));
/* Bail out if failure */
if (!Success)
- return;
+ return ENOEXEC;
/* Load NLS data, OEM font, and prepare boot drivers list */
Success = WinLdrScanSystemHive(LoaderBlock, BootPath);
TRACE("SYSTEM hive %s\n", (Success ? "scanned" : "not
scanned"));
/* Bail out if failure */
if (!Success)
- return;
+ return ENOEXEC;
/* Finish loading */
- LoadAndBootWindowsCommon(OperatingSystemVersion,
- LoaderBlock,
- BootOptions,
- BootPath,
- FALSE);
+ return LoadAndBootWindowsCommon(OperatingSystemVersion,
+ LoaderBlock,
+ BootOptions,
+ BootPath,
+ FALSE);
}
-VOID
+ARC_STATUS
LoadAndBootWindowsCommon(
USHORT OperatingSystemVersion,
PLOADER_PARAMETER_BLOCK LoaderBlock,
@@ -820,7 +817,7 @@ LoadAndBootWindowsCommon(
if (!Success)
{
UiMessageBox("Error loading NTOS core.");
- return;
+ return ENOEXEC;
}
/* Load boot drivers */
@@ -875,6 +872,7 @@ LoadAndBootWindowsCommon(
/* Pass control */
(*KiSystemStartup)(LoaderBlockVA);
+ return ESUCCESS;
}
VOID
diff --git a/boot/freeldr/freeldr/ntldr/winldr.h b/boot/freeldr/freeldr/ntldr/winldr.h
index 31ca33dd442..b5e43d06e18 100644
--- a/boot/freeldr/freeldr/ntldr/winldr.h
+++ b/boot/freeldr/freeldr/ntldr/winldr.h
@@ -142,7 +142,7 @@ WinLdrpDumpBootDriver(PLOADER_PARAMETER_BLOCK LoaderBlock);
VOID
WinLdrpDumpArcDisks(PLOADER_PARAMETER_BLOCK LoaderBlock);
-VOID
+ARC_STATUS
LoadAndBootWindowsCommon(
USHORT OperatingSystemVersion,
PLOADER_PARAMETER_BLOCK LoaderBlock,
diff --git a/boot/freeldr/freeldr/oslist.c b/boot/freeldr/freeldr/oslist.c
index 967b4149fb2..a509e15d556 100644
--- a/boot/freeldr/freeldr/oslist.c
+++ b/boot/freeldr/freeldr/oslist.c
@@ -20,8 +20,10 @@
/* INCLUDES *******************************************************************/
#include <freeldr.h>
+#include <debug.h>
+
+DBG_DEFAULT_CHANNEL(INIFILE);
-#define TAG_STRING ' rtS'
#define TAG_OS_ITEM 'tISO'
/* FUNCTIONS ******************************************************************/
@@ -40,23 +42,68 @@ static PCSTR CopyString(PCSTR Source)
return Dest;
}
-OperatingSystemItem* InitOperatingSystemList(ULONG* OperatingSystemCountPointer)
+static ULONG
+GetDefaultOperatingSystem(
+ IN OperatingSystemItem* OperatingSystemList,
+ IN ULONG OperatingSystemCount)
{
- ULONG Idx;
- CHAR SettingName[260];
- CHAR SettingValue[260];
+ 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(
+ OUT PULONG OperatingSystemCount,
+ OUT PULONG DefaultOperatingSystem)
+{
+ OperatingSystemItem* Items;
+ ULONG Count;
+ ULONG i;
+ ULONG_PTR OsSectionId, SectionId;
PCHAR TitleStart, TitleEnd;
PCSTR OsLoadOptions;
- ULONG Count;
- OperatingSystemItem* Items;
+ BOOLEAN HadSection;
+ BOOLEAN HadNoBootType;
+ CHAR SettingName[260];
+ CHAR SettingValue[260];
+ CHAR BootType[80];
+ CHAR TempBuffer[sizeof(SettingValue)/sizeof(CHAR)];
- /* Open the [FreeLoader] section */
- if (!IniOpenSection("Operating Systems", &SectionId))
+ /* Open the [Operating Systems] section */
+ if (!IniOpenSection("Operating Systems", &OsSectionId))
return NULL;
- /* Count number of operating systems in the section */
- Count = IniGetNumSectionItems(SectionId);
+ /* Count the number of operating systems in the section */
+ Count = IniGetNumSectionItems(OsSectionId);
/* Allocate memory to hold operating system lists */
Items = FrLdrHeapAlloc(Count * sizeof(OperatingSystemItem), TAG_OS_ITEM);
@@ -64,33 +111,199 @@ OperatingSystemItem* InitOperatingSystemList(ULONG*
OperatingSystemCountPointer)
return NULL;
/* Now loop through and read the operating system section and display names */
- for (Idx = 0; Idx < Count; Idx++)
+ for (i = 0; i < Count; ++i)
{
- IniReadSettingByNumber(SectionId, Idx, SettingName, sizeof(SettingName),
SettingValue, sizeof(SettingValue));
+ IniReadSettingByNumber(OsSectionId, i,
+ SettingName, sizeof(SettingName),
+ SettingValue, sizeof(SettingValue));
+ if (!*SettingName)
+ {
+ ERR("Invalid OS entry number %lu, skipping.\n", i);
+ continue;
+ }
- /* Search start and end of the title */
- OsLoadOptions = NULL;
+ /* Retrieve the start and end of the title */
TitleStart = SettingValue;
- while (*TitleStart == ' ' || *TitleStart == '"')
- TitleStart++;
+ /* Trim any leading whitespace and quotes */
+ while (*TitleStart == ' ' || *TitleStart == '\t' || *TitleStart
== '"')
+ ++TitleStart;
TitleEnd = TitleStart;
- if (*TitleEnd != ANSI_NULL)
- TitleEnd++;
+ /* Go up to the first last quote */
while (*TitleEnd != ANSI_NULL && *TitleEnd != '"')
- TitleEnd++;
- if (*TitleEnd != ANSI_NULL)
+ ++TitleEnd;
+
+ /* NULL-terminate the title */
+ if (*TitleEnd)
+ *TitleEnd++ = ANSI_NULL; // Skip the quote too.
+
+ /* Retrieve the options after the quoted title */
+ if (*TitleEnd)
+ {
+ /* Trim any trailing whitespace and quotes */
+ while (*TitleEnd == ' ' || *TitleEnd == '\t' || *TitleEnd ==
'"')
+ ++TitleEnd;
+ }
+ OsLoadOptions = (*TitleEnd ? TitleEnd : NULL);
+
+ // TRACE("\n"
+ // "SettingName = '%s'\n"
+ // "TitleStart = '%s'\n"
+ // "OsLoadOptions = '%s'\n",
+ // SettingName, TitleStart, OsLoadOptions);
+
+ /*
+ * Determine whether this is a legacy operating system entry of the form:
+ *
+ * [Operating Systems]
+ * ArcOsLoadPartition="LoadIdentifier" /List /of /Options
+ *
+ * and if so, convert it into a new operating system INI entry:
+ *
+ * [Operating Systems]
+ * SectionIdentifier="LoadIdentifier"
+ *
+ * [SectionIdentifier]
+ * BootType=...
+ * SystemPath=ArcOsLoadPartition
+ * Options=/List /of /Options
+ *
+ * The "BootType" value is heuristically determined from the form of
+ * the ArcOsLoadPartition: if this is an ARC path, the "BootType"
value
+ * is "Windows", otherwise if this is a DOS path the
"BootType" value
+ * is "BootSector". This ensures backwards-compatibility with NTLDR.
+ */
+
+ /* Try to open the operating system section in the .ini file */
+ HadSection = IniOpenSection(SettingName, &SectionId);
+ if (HadSection)
+ {
+ /* This is a new OS entry: try to read the boot type */
+ IniReadSettingByName(SectionId, "BootType", BootType,
sizeof(BootType));
+ }
+ else
+ {
+ /* This is a legacy OS entry: no explicit BootType specified, we will infer
one */
+ *BootType = ANSI_NULL;
+ }
+
+ /* Check whether we have got a BootType value; if not, try to infer one */
+ HadNoBootType = (*BootType == ANSI_NULL);
+ if (HadNoBootType)
+ {
+#ifdef _M_IX86
+ ULONG FileId;
+ if (ArcOpen((PSTR)SettingName, OpenReadOnly, &FileId) == ESUCCESS)
+ {
+ ArcClose(FileId);
+ strcpy(BootType, "BootSector");
+ }
+ else
+#endif
+ {
+ strcpy(BootType, "Windows");
+ }
+ }
+
+ /* This is a legacy OS entry: convert it into a new OS entry */
+ if (!HadSection)
{
- *TitleEnd = ANSI_NULL;
- OsLoadOptions = TitleEnd + 1;
+ TIMEINFO* TimeInfo;
+
+ /* Save the system path from the original SettingName (overwritten below) */
+ RtlStringCbCopyA(TempBuffer, sizeof(TempBuffer), SettingName);
+
+ /* Generate a unique section name */
+ TimeInfo = ArcGetTime();
+ if (_stricmp(BootType, "BootSector") == 0)
+ {
+ RtlStringCbPrintfA(SettingName, sizeof(SettingName),
+ "BootSectorFile%u%u%u%u%u%u",
+ TimeInfo->Year, TimeInfo->Day,
TimeInfo->Month,
+ TimeInfo->Hour, TimeInfo->Minute,
TimeInfo->Second);
+ }
+ else if (_stricmp(BootType, "Windows") == 0)
+ {
+ RtlStringCbPrintfA(SettingName, sizeof(SettingName),
+ "Windows%u%u%u%u%u%u",
+ TimeInfo->Year, TimeInfo->Day,
TimeInfo->Month,
+ TimeInfo->Hour, TimeInfo->Minute,
TimeInfo->Second);
+ }
+ else
+ {
+ ASSERT(FALSE);
+ }
+
+ /* Add the section */
+ if (!IniAddSection(SettingName, &SectionId))
+ {
+ ERR("Could not convert legacy OS entry! Continuing...\n");
+ continue;
+ }
+
+ /* Add the system path */
+ if (_stricmp(BootType, "BootSector") == 0)
+ {
+ if (!IniAddSettingValueToSection(SectionId, "BootSectorFile",
TempBuffer))
+ {
+ ERR("Could not convert legacy OS entry! Continuing...\n");
+ continue;
+ }
+ }
+ else if (_stricmp(BootType, "Windows") == 0)
+ {
+ if (!IniAddSettingValueToSection(SectionId, "SystemPath",
TempBuffer))
+ {
+ ERR("Could not convert legacy OS entry! Continuing...\n");
+ continue;
+ }
+ }
+ else
+ {
+ ASSERT(FALSE);
+ }
+
+ /* Add the OS options */
+ if (OsLoadOptions && !IniAddSettingValueToSection(SectionId,
"Options", OsLoadOptions))
+ {
+ ERR("Could not convert legacy OS entry! Continuing...\n");
+ continue;
+ }
+ }
+
+ /* Add or modify the BootType if needed */
+ if (HadNoBootType && !IniModifySettingValue(SectionId,
"BootType", BootType))
+ {
+ ERR("Could not fixup the BootType entry for OS '%s',
ignoring.\n", SettingName);
+ }
+
+ /*
+ * If this is a new OS entry, but some options were given appended to
+ * the OS entry item, append them instead to the "Options=" value.
+ */
+ if (HadSection && OsLoadOptions && *OsLoadOptions)
+ {
+ /* Read the original "Options=" value */
+ *TempBuffer = ANSI_NULL;
+ if (!IniReadSettingByName(SectionId, "Options", TempBuffer,
sizeof(TempBuffer)))
+ TRACE("No 'Options' value found for OS '%s',
ignoring.\n", SettingName);
+
+ /* Concatenate the options together */
+ RtlStringCbCatA(TempBuffer, sizeof(TempBuffer), " ");
+ RtlStringCbCatA(TempBuffer, sizeof(TempBuffer), OsLoadOptions);
+
+ /* Save them */
+ if (!IniModifySettingValue(SectionId, "Options", TempBuffer))
+ ERR("Could not modify the options for OS '%s',
ignoring.\n", SettingName);
}
- /* Copy the system partition, identifier and options */
- Items[Idx].SystemPartition = CopyString(SettingName);
- Items[Idx].LoadIdentifier = CopyString(TitleStart);
- Items[Idx].OsLoadOptions = CopyString(OsLoadOptions);
+ /* Copy the OS section name and identifier */
+ Items[i].SectionName = CopyString(SettingName);
+ Items[i].LoadIdentifier = CopyString(TitleStart);
+ // TRACE("We did Items[%lu]: SectionName = '%s', LoadIdentifier =
'%s'\n", i, Items[i].SectionName, Items[i].LoadIdentifier);
}
/* Return success */
- *OperatingSystemCountPointer = Count;
+ *OperatingSystemCount = Count;
+ *DefaultOperatingSystem = GetDefaultOperatingSystem(Items, Count);
return Items;
}
diff --git a/boot/freeldr/freeldr/ui/directui.c b/boot/freeldr/freeldr/ui/directui.c
index a602700988c..b117cd3f5a4 100644
--- a/boot/freeldr/freeldr/ui/directui.c
+++ b/boot/freeldr/freeldr/ui/directui.c
@@ -257,6 +257,14 @@ UiShowMessageBoxesInSection(IN PCSTR SectionName)
return;
}
+VOID
+UiShowMessageBoxesInArgv(
+ IN ULONG Argc,
+ IN PCHAR Argv[])
+{
+ return;
+}
+
VOID
UiTruncateStringEllipsis(IN PCHAR StringText,
IN ULONG MaxChars)
diff --git a/boot/freeldr/freeldr/ui/ui.c b/boot/freeldr/freeldr/ui/ui.c
index 7acbdb331f9..98035ee84b6 100644
--- a/boot/freeldr/freeldr/ui/ui.c
+++ b/boot/freeldr/freeldr/ui/ui.c
@@ -430,6 +430,43 @@ VOID UiShowMessageBoxesInSection(PCSTR SectionName)
}
}
+VOID
+UiShowMessageBoxesInArgv(
+ IN ULONG Argc,
+ IN PCHAR Argv[])
+{
+ ULONG LastIndex;
+ PCSTR ArgValue;
+ PCHAR MessageBoxText;
+ ULONG MessageBoxTextSize;
+
+ /* Find all the message box settings and run them */
+ for (LastIndex = 0;
+ (ArgValue = GetNextArgumentValue(Argc, Argv, &LastIndex,
"MessageBox")) != NULL;
+ ++LastIndex)
+ {
+ /* Get the real length of the MessageBox text */
+ MessageBoxTextSize = (strlen(ArgValue) + 1) * sizeof(CHAR);
+
+ /* Allocate enough memory to hold the text */
+ MessageBoxText = FrLdrTempAlloc(MessageBoxTextSize, TAG_UI_TEXT);
+ if (MessageBoxText)
+ {
+ /* Get the MessageBox text */
+ strcpy(MessageBoxText, ArgValue);
+
+ /* Fix it up */
+ UiEscapeString(MessageBoxText);
+
+ /* Display it */
+ UiMessageBox(MessageBoxText);
+
+ /* Free the memory */
+ FrLdrTempFree(MessageBoxText, TAG_UI_TEXT);
+ }
+ }
+}
+
VOID UiEscapeString(PCHAR String)
{
ULONG Idx;