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