mirror of
https://github.com/reactos/reactos.git
synced 2024-12-14 06:33:30 +08:00
[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:
parent
d21ffe6336
commit
d05be0da3f
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
28
boot/freeldr/freeldr/include/arcsupp.h
Normal file
28
boot/freeldr/freeldr/include/arcsupp.h
Normal 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);
|
@ -58,6 +58,7 @@
|
||||
/* Internal headers */
|
||||
// #include <arcemul.h>
|
||||
#include <arcname.h>
|
||||
#include <arcsupp.h>
|
||||
#include <bytesex.h>
|
||||
#include <cache.h>
|
||||
#include <cmdline.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);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
47
boot/freeldr/freeldr/lib/arcsupp.c
Normal file
47
boot/freeldr/freeldr/lib/arcsupp.c
Normal 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);
|
||||
}
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user