[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).
This commit is contained in:
Hermès Bélusca-Maïto 2019-08-06 22:30:54 +02:00
parent d21ffe6336
commit d05be0da3f
No known key found for this signature in database
GPG Key ID: 3B2539C65E7B93D0
19 changed files with 867 additions and 487 deletions

View File

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

View File

@ -22,71 +22,147 @@
#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 ******************************************************************/
PCHAR*
BuildArgvForOsLoader(
IN PCSTR LoadIdentifier,
IN ULONG_PTR SectionId,
OUT PULONG pArgc)
{
SIZE_T Size;
ULONG Count;
ULONG i;
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)
{
Size += (strlen("LoadIdentifier=") + strlen(LoadIdentifier) + 1) * sizeof(CHAR);
}
for (i = 0; i < Count; ++i)
{
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);
*Args++ = SettingName;
SettingName += (strlen(SettingName) + 1);
}
for (i = 0; i < Count; ++i)
{
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 DBG
/* Dump the argument vector for debugging */
for (i = 0; i < Argc; ++i)
{
TRACE("Argv[%lu]: '%s'\n", i, Argv[i]);
}
#endif
*pArgc = Argc;
return Argv;
}
VOID LoadOperatingSystem(IN OperatingSystemItem* OperatingSystem)
{
ULONG_PTR SectionId;
PCSTR SectionName = OperatingSystem->SystemPartition;
CHAR BootType[80];
PCSTR SectionName = OperatingSystem->SectionName;
ULONG i;
ULONG Argc;
PCHAR* Argv;
CHAR BootType[80];
/* Try to open the operating system section in the .ini file */
if (IniOpenSection(SectionName, &SectionId))
if (!IniOpenSection(SectionName, &SectionId))
{
/* Try to read the boot type */
IniReadSettingByName(SectionId, "BootType", BootType, sizeof(BootType));
}
else
{
BootType[0] = ANSI_NULL;
UiMessageBox("Section [%s] not found in freeldr.ini.", SectionName);
return;
}
if (BootType[0] == ANSI_NULL && SectionName[0] != ANSI_NULL)
{
/* 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");
}
}
/* 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 */
@ -98,48 +174,17 @@ VOID LoadOperatingSystem(IN OperatingSystemItem* OperatingSystem)
{
if (_stricmp(BootType, OSLoadingMethods[i].BootType) == 0)
{
OSLoadingMethods[i].Load(OperatingSystem,
OSLoadingMethods[i].OperatingSystemVersion);
Argv = BuildArgvForOsLoader(OperatingSystem->LoadIdentifier, SectionId, &Argc);
if (Argv)
{
OSLoadingMethods[i].OsLoader(Argc, Argv, NULL);
FrLdrHeapFree(Argv, TAG_STRING);
}
return;
}
}
}
ULONG GetDefaultOperatingSystem(OperatingSystemItem* OperatingSystemList, ULONG OperatingSystemCount)
{
CHAR DefaultOSText[80];
PCSTR DefaultOSName;
ULONG_PTR SectionId;
ULONG DefaultOS = 0;
ULONG Idx;
if (!IniOpenSection("FreeLoader", &SectionId))
return 0;
DefaultOSName = CmdLineGetDefaultOS();
if (DefaultOSName == NULL)
{
if (IniReadSettingByName(SectionId, "DefaultOS", DefaultOSText, sizeof(DefaultOSText)))
{
DefaultOSName = DefaultOSText;
}
}
if (DefaultOSName != NULL)
{
for (Idx = 0; Idx < OperatingSystemCount; Idx++)
{
if (_stricmp(DefaultOSName, OperatingSystemList[Idx].SystemPartition) == 0)
{
DefaultOS = Idx;
break;
}
}
}
return DefaultOS;
}
LONG GetTimeOut(VOID)
{
CHAR TimeOutText[20];
@ -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)

View File

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

View File

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

View File

@ -58,6 +58,7 @@
/* Internal headers */
// #include <arcemul.h>
#include <arcname.h>
#include <arcsupp.h>
#include <bytesex.h>
#include <cache.h>
#include <cmdline.h>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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, "\\");
/* 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);
/* Null-terminate */
*strstr(FileName, " ") = ANSI_NULL;
/* Load the ramdisk */
if (!RamDiskLoadVirtualFile(FileName))
{
UiMessageBox("Failed to load RAM disk file %s", FileName);
return;
}
}
if (!*BootPath || BootPath[strlen(BootPath) - 1] != '\\')
RtlStringCbCatA(BootPath, sizeof(BootPath), "\\");
TRACE("BootPath: '%s'\n", BootPath);
/* And check if we booted from floppy */
/* Retrieve the boot options */
*BootOptions2 = ANSI_NULL;
ArgValue = GetArgumentValue(Argc, Argv, "Options");
if (ArgValue)
RtlStringCbCopyA(BootOptions2, sizeof(BootOptions2), ArgValue);
TRACE("BootOptions: '%s'\n", BootOptions2);
/* 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);
}

View File

@ -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;
TRACE("BootPath: '%s'\n", BootPath);
/* 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);
}
/* 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

View File

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

View File

@ -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));
/* Search start and end of the title */
OsLoadOptions = NULL;
TitleStart = SettingValue;
while (*TitleStart == ' ' || *TitleStart == '"')
TitleStart++;
TitleEnd = TitleStart;
if (*TitleEnd != ANSI_NULL)
TitleEnd++;
while (*TitleEnd != ANSI_NULL && *TitleEnd != '"')
TitleEnd++;
if (*TitleEnd != ANSI_NULL)
IniReadSettingByNumber(OsSectionId, i,
SettingName, sizeof(SettingName),
SettingValue, sizeof(SettingValue));
if (!*SettingName)
{
*TitleEnd = ANSI_NULL;
OsLoadOptions = TitleEnd + 1;
ERR("Invalid OS entry number %lu, skipping.\n", i);
continue;
}
/* Copy the system partition, identifier and options */
Items[Idx].SystemPartition = CopyString(SettingName);
Items[Idx].LoadIdentifier = CopyString(TitleStart);
Items[Idx].OsLoadOptions = CopyString(OsLoadOptions);
/* Retrieve the start and end of the title */
TitleStart = SettingValue;
/* Trim any leading whitespace and quotes */
while (*TitleStart == ' ' || *TitleStart == '\t' || *TitleStart == '"')
++TitleStart;
TitleEnd = TitleStart;
/* Go up to the first last quote */
while (*TitleEnd != ANSI_NULL && *TitleEnd != '"')
++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)
{
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 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;
}

View File

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

View File

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