[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:
Hermès Bélusca-Maïto 2019-08-31 00:49:37 +02:00
parent 602fc29ad4
commit bd451f240f
No known key found for this signature in database
GPG key ID: 3B2539C65E7B93D0
30 changed files with 1202 additions and 816 deletions

View file

@ -18,8 +18,8 @@
*/ */
#include <freeldr.h> #include <freeldr.h>
#include <debug.h>
#include <debug.h>
DBG_DEFAULT_CHANNEL(DISK); DBG_DEFAULT_CHANNEL(DISK);
#ifdef _M_IX86 #ifdef _M_IX86
@ -92,24 +92,23 @@ UCHAR DriveMapGetBiosDriveNumber(PCSTR DeviceName)
#ifdef _M_IX86 #ifdef _M_IX86
VOID DriveMapMapDrivesInSection(PCSTR SectionName) VOID
DriveMapMapDrivesInSection(
IN ULONG_PTR SectionId)
{ {
CHAR SettingName[80]; CHAR SettingName[80];
CHAR SettingValue[80]; CHAR SettingValue[80];
CHAR Drive1[80]; CHAR Drive1[80];
CHAR Drive2[80]; CHAR Drive2[80];
ULONG_PTR SectionId;
ULONG SectionItemCount; ULONG SectionItemCount;
ULONG Index; ULONG Index;
ULONG Index2; ULONG Index2;
DRIVE_MAP_LIST DriveMapList; DRIVE_MAP_LIST DriveMapList;
RtlZeroMemory(&DriveMapList, sizeof(DRIVE_MAP_LIST)); if (SectionId == 0)
if (!IniOpenSection(SectionName, &SectionId))
{
return; return;
}
RtlZeroMemory(&DriveMapList, sizeof(DRIVE_MAP_LIST));
// Get the number of items in this section // Get the number of items in this section
SectionItemCount = IniGetNumSectionItems(SectionId); SectionItemCount = IniGetNumSectionItems(SectionId);
@ -125,7 +124,7 @@ VOID DriveMapMapDrivesInSection(PCSTR SectionName)
// Make sure we haven't exceeded the drive map max count // Make sure we haven't exceeded the drive map max count
if (DriveMapList.DriveMapCount >= 4) 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; continue;
} }
@ -150,7 +149,7 @@ VOID DriveMapMapDrivesInSection(PCSTR SectionName)
// Make sure we got good values before we add them to the map // Make sure we got good values before we add them to the map
if (!DriveMapIsValidDriveString(Drive1) || !DriveMapIsValidDriveString(Drive2)) 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; continue;
} }

View file

@ -22,7 +22,6 @@
#include <freeldr.h> #include <freeldr.h>
#include <debug.h> #include <debug.h>
DBG_DEFAULT_CHANNEL(HWDETECT); DBG_DEFAULT_CHANNEL(HWDETECT);
/* /*
@ -80,7 +79,6 @@ DiskOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId)
ULONGLONG SectorOffset = 0; ULONGLONG SectorOffset = 0;
ULONGLONG SectorCount = 0; ULONGLONG SectorCount = 0;
PARTITION_TABLE_ENTRY PartitionTableEntry; PARTITION_TABLE_ENTRY PartitionTableEntry;
CHAR FileName[1];
if (DiskReadBufferSize == 0) if (DiskReadBufferSize == 0)
{ {
@ -89,7 +87,7 @@ DiskOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId)
return ENOMEM; return ENOMEM;
} }
if (!DissectArcPath(Path, FileName, &DriveNumber, &DrivePartition)) if (!DissectArcPath(Path, NULL, &DriveNumber, &DrivePartition))
return EINVAL; return EINVAL;
if (DrivePartition == 0xff) if (DrivePartition == 0xff)

View file

@ -21,23 +21,32 @@
#include <freeldr.h> #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 */ /* Detect ramdisk path */
if (_strnicmp(ArcPath, "ramdisk(0)", 10) == 0) if (_strnicmp(ArcPath, "ramdisk(0)", 10) == 0)
{ {
/* Magic value for ramdisks */ /* Magic value for ramdisks */
*BootDrive = 0x49; *DriveNumber = 0x49;
*BootPartition = 1; *PartitionNumber = 1;
/* Get the path */ /* Get the path (optional) */
p = ArcPath + 11; if (Path)
strcpy(BootPath, p); {
p = ArcPath + 11;
*Path = p;
}
return TRUE; return TRUE;
} }
/* NOTE: We are currently limited when handling multi()disk() paths!! */
if (_strnicmp(ArcPath, "multi(0)disk(0)", 15) != 0) if (_strnicmp(ArcPath, "multi(0)disk(0)", 15) != 0)
return FALSE; return FALSE;
@ -49,12 +58,12 @@ BOOLEAN DissectArcPath(CHAR *ArcPath, CHAR *BootPath, UCHAR* BootDrive, ULONG* B
* multi(0)disk(0)fdisk(x)\path * multi(0)disk(0)fdisk(x)\path
*/ */
p = p + 6; p = p + 6;
*BootDrive = atoi(p); *DriveNumber = atoi(p);
p = strchr(p, ')'); p = strchr(p, ')');
if (p == NULL) if (p == NULL)
return FALSE; return FALSE;
p++; ++p;
*BootPartition = 0; *PartitionNumber = 0;
} }
else if (_strnicmp(p, "cdrom(", 6) == 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 * multi(0)disk(0)cdrom(x)\path
*/ */
p = p + 6; p = p + 6;
*BootDrive = atoi(p) + 0x80; *DriveNumber = atoi(p) + 0x80;
p = strchr(p, ')'); p = strchr(p, ')');
if (p == NULL) if (p == NULL)
return FALSE; return FALSE;
p++; ++p;
*BootPartition = 0xff; *PartitionNumber = 0xff;
} }
else if (_strnicmp(p, "rdisk(", 6) == 0) else if (_strnicmp(p, "rdisk(", 6) == 0)
{ {
/* /*
* Hard disk path: * Hard disk path:
* multi(0)disk(0)rdisk(x)partition(y)\path * multi(0)disk(0)rdisk(x)[partition(y)][\path]
*/ */
p = p + 6; p = p + 6;
*BootDrive = atoi(p) + 0x80; *DriveNumber = atoi(p) + 0x80;
p = strchr(p, ')');
if ((p == NULL) || (_strnicmp(p, ")partition(", 11) != 0))
return FALSE;
p = p + 11;
*BootPartition = atoi(p);
p = strchr(p, ')'); p = strchr(p, ')');
if (p == NULL) if (p == NULL)
return FALSE; 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 else
{ {
return FALSE; return FALSE;
} }
strcpy(BootPath, p); /* Get the path (optional) */
if (Path)
*Path = p;
return TRUE; return TRUE;
} }
@ -101,12 +121,12 @@ BOOLEAN DissectArcPath(CHAR *ArcPath, CHAR *BootPath, UCHAR* BootDrive, ULONG* B
/* PathSyntax: scsi() = 0, multi() = 1, ramdisk() = 2 */ /* PathSyntax: scsi() = 0, multi() = 1, ramdisk() = 2 */
BOOLEAN BOOLEAN
DissectArcPath2( DissectArcPath2(
IN CHAR* ArcPath, IN PCSTR ArcPath,
OUT ULONG* x, OUT PULONG x,
OUT ULONG* y, OUT PULONG y,
OUT ULONG* z, OUT PULONG z,
OUT ULONG* Partition, OUT PULONG Partition,
OUT ULONG *PathSyntax) OUT PULONG PathSyntax)
{ {
/* Detect ramdisk() */ /* Detect ramdisk() */
if (_strnicmp(ArcPath, "ramdisk(0)", 10) == 0) if (_strnicmp(ArcPath, "ramdisk(0)", 10) == 0)

View file

@ -20,8 +20,8 @@
/* INCLUDES *******************************************************************/ /* INCLUDES *******************************************************************/
#include <freeldr.h> #include <freeldr.h>
#include <debug.h>
#include <debug.h>
DBG_DEFAULT_CHANNEL(INIFILE); DBG_DEFAULT_CHANNEL(INIFILE);
/* GLOBALS ********************************************************************/ /* GLOBALS ********************************************************************/
@ -29,20 +29,20 @@ DBG_DEFAULT_CHANNEL(INIFILE);
typedef typedef
VOID VOID
(*EDIT_OS_ENTRY_PROC)( (*EDIT_OS_ENTRY_PROC)(
IN ULONG_PTR SectionId OPTIONAL); IN OUT OperatingSystemItem* OperatingSystem);
static VOID static VOID
EditCustomBootReactOSSetup( EditCustomBootReactOSSetup(
IN ULONG_PTR SectionId OPTIONAL) IN OUT OperatingSystemItem* OperatingSystem)
{ {
EditCustomBootReactOS(SectionId, TRUE); EditCustomBootReactOS(OperatingSystem, TRUE);
} }
static VOID static VOID
EditCustomBootNTOS( EditCustomBootNTOS(
IN ULONG_PTR SectionId OPTIONAL) IN OUT OperatingSystemItem* OperatingSystem)
{ {
EditCustomBootReactOS(SectionId, FALSE); EditCustomBootReactOS(OperatingSystem, FALSE);
} }
static const struct static const struct
@ -68,6 +68,12 @@ static const struct
/* FUNCTIONS ******************************************************************/ /* 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* PCHAR*
BuildArgvForOsLoader( BuildArgvForOsLoader(
IN PCSTR LoadIdentifier, IN PCSTR LoadIdentifier,
@ -81,30 +87,34 @@ BuildArgvForOsLoader(
PCHAR* Argv; PCHAR* Argv;
PCHAR* Args; PCHAR* Args;
PCHAR SettingName, SettingValue; PCHAR SettingName, SettingValue;
CHAR BootPath[MAX_PATH];
/*
* Convert the list of key=value options in the given operating system section
* into a ARC-compatible argument vector.
*/
*pArgc = 0; *pArgc = 0;
ASSERT(SectionId != 0);
/* Validate the LoadIdentifier (to make tests simpler later) */ /* Validate the LoadIdentifier (to make tests simpler later) */
if (LoadIdentifier && !*LoadIdentifier) if (LoadIdentifier && !*LoadIdentifier)
LoadIdentifier = NULL; 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 the number of operating systems in the section */
Count = IniGetNumSectionItems(SectionId); Count = IniGetNumSectionItems(SectionId);
/* The argument vector contains the program name, the LoadIdentifier (optional), and the items in the OS section */ /*
Argc = 1 + Count; * The argument vector contains the program name, the SystemPartition,
if (LoadIdentifier) * the LoadIdentifier (optional), and the items in the OS section.
++Argc; */
Argc = 2 + (LoadIdentifier ? 1 : 0) + Count;
/* Calculate the total size needed for the string buffer of the argument vector */ /* Calculate the total size needed for the string buffer of the argument vector */
Size = 0; Size = 0;
/* i == 0: Program name */ /* 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) if (LoadIdentifier)
{ {
Size += (strlen("LoadIdentifier=") + strlen(LoadIdentifier) + 1) * sizeof(CHAR); Size += (strlen("LoadIdentifier=") + strlen(LoadIdentifier) + 1) * sizeof(CHAR);
@ -126,7 +136,15 @@ BuildArgvForOsLoader(
Args = Argv; Args = Argv;
/* i == 0: Program name */ /* i == 0: Program name */
*Args++ = NULL; *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) if (LoadIdentifier)
{ {
strcpy(SettingName, "LoadIdentifier="); strcpy(SettingName, "LoadIdentifier=");
@ -162,19 +180,14 @@ BuildArgvForOsLoader(
VOID LoadOperatingSystem(IN OperatingSystemItem* OperatingSystem) VOID LoadOperatingSystem(IN OperatingSystemItem* OperatingSystem)
{ {
ULONG_PTR SectionId; ULONG_PTR SectionId = OperatingSystem->SectionId;
PCSTR SectionName = OperatingSystem->SectionName;
ULONG i; ULONG i;
ULONG Argc; ULONG Argc;
PCHAR* Argv; PCHAR* Argv;
CHAR BootType[80]; CHAR BootType[80];
/* Try to open the operating system section in the .ini file */ /* The operating system section has been opened by InitOperatingSystemList() */
if (!IniOpenSection(SectionName, &SectionId)) ASSERT(SectionId != 0);
{
UiMessageBox("Section [%s] not found in freeldr.ini.", SectionName);
return;
}
/* Try to read the boot type */ /* Try to read the boot type */
*BootType = ANSI_NULL; *BootType = ANSI_NULL;
@ -185,7 +198,7 @@ VOID LoadOperatingSystem(IN OperatingSystemItem* OperatingSystem)
#ifdef _M_IX86 #ifdef _M_IX86
/* Install the drive mapper according to this section drive mappings */ /* Install the drive mapper according to this section drive mappings */
DriveMapMapDrivesInSection(SectionName); DriveMapMapDrivesInSection(SectionId);
#endif #endif
/* Loop through the OS loading method table and find a suitable OS to boot */ /* 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) VOID EditOperatingSystemEntry(IN OperatingSystemItem* OperatingSystem)
{ {
ULONG_PTR SectionId; ULONG_PTR SectionId = OperatingSystem->SectionId;
PCSTR SectionName = OperatingSystem->SectionName;
ULONG i; ULONG i;
CHAR BootType[80]; CHAR BootType[80];
/* Try to open the operating system section in the .ini file */ /* The operating system section has been opened by InitOperatingSystemList() */
if (!IniOpenSection(SectionName, &SectionId)) ASSERT(SectionId != 0);
{
UiMessageBox("Section [%s] not found in freeldr.ini.", SectionName);
return;
}
/* Try to read the boot type */ /* Try to read the boot type */
*BootType = ANSI_NULL; *BootType = ANSI_NULL;
@ -232,7 +240,7 @@ VOID EditOperatingSystemEntry(IN OperatingSystemItem* OperatingSystem)
{ {
if (_stricmp(BootType, OSLoadingMethods[i].BootType) == 0) if (_stricmp(BootType, OSLoadingMethods[i].BootType) == 0)
{ {
OSLoadingMethods[i].EditOsEntry(SectionId); OSLoadingMethods[i].EditOsEntry(OperatingSystem);
return; return;
} }
} }
@ -240,23 +248,24 @@ VOID EditOperatingSystemEntry(IN OperatingSystemItem* OperatingSystem)
#endif // HAS_OPTION_MENU_EDIT_CMDLINE #endif // HAS_OPTION_MENU_EDIT_CMDLINE
LONG GetTimeOut(VOID) static LONG
GetTimeOut(
IN ULONG_PTR FrLdrSectionId)
{ {
CHAR TimeOutText[20]; LONG TimeOut = -1;
LONG TimeOut; CHAR TimeOutText[20];
ULONG_PTR SectionId;
TimeOut = CmdLineGetTimeOut(); TimeOut = CmdLineGetTimeOut();
if (TimeOut >= 0) if (TimeOut >= 0)
return TimeOut; return TimeOut;
if (!IniOpenSection("FreeLoader", &SectionId)) TimeOut = -1;
return -1;
if (IniReadSettingByName(SectionId, "TimeOut", TimeOutText, sizeof(TimeOutText))) if ((FrLdrSectionId != 0) &&
IniReadSettingByName(FrLdrSectionId, "TimeOut", TimeOutText, sizeof(TimeOutText)))
{
TimeOut = atoi(TimeOutText); TimeOut = atoi(TimeOutText);
else }
TimeOut = -1;
return TimeOut; return TimeOut;
} }
@ -316,16 +325,18 @@ VOID RunLoader(VOID)
return; return;
} }
/* Debugger main initialization */ /* Open the [FreeLoader] section */
DebugInit(TRUE);
if (!IniOpenSection("FreeLoader", &SectionId)) if (!IniOpenSection("FreeLoader", &SectionId))
{ {
UiMessageBoxCritical("Section [FreeLoader] not found in freeldr.ini."); UiMessageBoxCritical("Section [FreeLoader] not found in freeldr.ini.");
return; return;
} }
TimeOut = GetTimeOut(); /* Debugger main initialization */
DebugInit(SectionId);
/* Retrieve the default timeout */
TimeOut = GetTimeOut(SectionId);
/* UI main initialization */ /* UI main initialization */
if (!UiInitialize(TRUE)) if (!UiInitialize(TRUE))
@ -334,7 +345,8 @@ VOID RunLoader(VOID)
return; return;
} }
OperatingSystemList = InitOperatingSystemList(&OperatingSystemCount, OperatingSystemList = InitOperatingSystemList(SectionId,
&OperatingSystemCount,
&DefaultOperatingSystem); &DefaultOperatingSystem);
if (!OperatingSystemList) if (!OperatingSystemList)
{ {
@ -358,7 +370,7 @@ VOID RunLoader(VOID)
} }
/* Find all the message box settings and run them */ /* Find all the message box settings and run them */
UiShowMessageBoxesInSection("FreeLoader"); UiShowMessageBoxesInSection(SectionId);
for (;;) for (;;)
{ {

View file

@ -14,9 +14,9 @@
typedef struct tagCMDLINEINFO typedef struct tagCMDLINEINFO
{ {
PCCH DebugString; PCSTR DebugString;
PCCH DefaultOperatingSystem; PCSTR DefaultOperatingSystem;
LONG TimeOut; LONG TimeOut;
} CMDLINEINFO, *PCMDLINEINFO; } CMDLINEINFO, *PCMDLINEINFO;
CCHAR DebugString[256]; CCHAR DebugString[256];
@ -26,7 +26,7 @@ CMDLINEINFO CmdLineInfo;
/* FUNCTIONS ******************************************************************/ /* FUNCTIONS ******************************************************************/
VOID VOID
CmdLineParse(IN PCCH CmdLine) CmdLineParse(IN PCSTR CmdLine)
{ {
PCHAR End, Setting; PCHAR End, Setting;
ULONG_PTR Length, Offset = 0; ULONG_PTR Length, Offset = 0;
@ -46,16 +46,12 @@ CmdLineParse(IN PCCH CmdLine)
if (Setting) if (Setting)
{ {
/* Check if there are more command-line parameters following */ /* Check if there are more command-line parameters following */
Setting += sizeof("debug=") + sizeof(ANSI_NULL); Setting += sizeof("debug=") - sizeof(ANSI_NULL);
End = strstr(Setting, " "); End = strstr(Setting, " ");
if (End) Length = (End ? (End - Setting) : strlen(Setting));
Length = End - Setting;
else
Length = sizeof(DebugString);
/* Copy the debug string and upcase it */ /* Copy the debug string and upcase it */
strncpy(DebugString, Setting, Length); RtlStringCbCopyNA(DebugString, sizeof(DebugString), Setting, Length);
DebugString[Length - 1] = ANSI_NULL;
_strupr(DebugString); _strupr(DebugString);
/* Replace all separators ';' by spaces */ /* Replace all separators ';' by spaces */
@ -71,63 +67,65 @@ CmdLineParse(IN PCCH CmdLine)
/* Get timeout */ /* Get timeout */
Setting = strstr(CmdLine, "timeout="); Setting = strstr(CmdLine, "timeout=");
if (Setting) CmdLineInfo.TimeOut = atoi(Setting + if (Setting)
sizeof("timeout=") + {
sizeof(ANSI_NULL)); CmdLineInfo.TimeOut = atoi(Setting +
sizeof("timeout=") - sizeof(ANSI_NULL));
}
/* Get default OS */ /* Get default OS */
Setting = strstr(CmdLine, "defaultos="); Setting = strstr(CmdLine, "defaultos=");
if (Setting) if (Setting)
{ {
/* Check if there are more command-line parameters following */ /* Check if there are more command-line parameters following */
Setting += sizeof("defaultos=") + sizeof(ANSI_NULL); Setting += sizeof("defaultos=") - sizeof(ANSI_NULL);
End = strstr(Setting, " "); End = strstr(Setting, " ");
if (End) Length = (End ? (End - Setting) : strlen(Setting));
Length = End - Setting;
else
Length = sizeof(DefaultOs);
/* Copy the default OS */ /* Copy the default OS */
strncpy(DefaultOs, Setting, Length); RtlStringCbCopyNA(DefaultOs, sizeof(DefaultOs), Setting, Length);
DefaultOs[Length - 1] = ANSI_NULL;
CmdLineInfo.DefaultOperatingSystem = DefaultOs; CmdLineInfo.DefaultOperatingSystem = DefaultOs;
} }
/* Get ramdisk base address */ /* Get ramdisk base address */
Setting = strstr(CmdLine, "rdbase="); Setting = strstr(CmdLine, "rdbase=");
if (Setting) gRamDiskBase = (PVOID)(ULONG_PTR)strtoull(Setting + if (Setting)
sizeof("rdbase=") - {
sizeof(ANSI_NULL), gRamDiskBase =
NULL, (PVOID)(ULONG_PTR)strtoull(Setting +
0); sizeof("rdbase=") - sizeof(ANSI_NULL),
NULL, 0);
}
/* Get ramdisk size */ /* Get ramdisk size */
Setting = strstr(CmdLine, "rdsize="); Setting = strstr(CmdLine, "rdsize=");
if (Setting) gRamDiskSize = strtoul(Setting + if (Setting)
sizeof("rdsize=") - {
sizeof(ANSI_NULL), gRamDiskSize = strtoul(Setting +
NULL, sizeof("rdsize=") - sizeof(ANSI_NULL),
0); NULL, 0);
}
/* Get ramdisk offset */ /* Get ramdisk offset */
Setting = strstr(CmdLine, "rdoffset="); Setting = strstr(CmdLine, "rdoffset=");
if (Setting) Offset = strtoul(Setting + if (Setting)
sizeof("rdoffset=") - {
sizeof(ANSI_NULL), Offset = strtoul(Setting +
NULL, sizeof("rdoffset=") - sizeof(ANSI_NULL),
0); NULL, 0);
}
/* Fix it up */ /* Fix it up */
gRamDiskBase = (PVOID)((ULONG_PTR)gRamDiskBase + Offset); gRamDiskBase = (PVOID)((ULONG_PTR)gRamDiskBase + Offset);
} }
PCCH PCSTR
CmdLineGetDebugString(VOID) CmdLineGetDebugString(VOID)
{ {
return CmdLineInfo.DebugString; return CmdLineInfo.DebugString;
} }
PCCH PCSTR
CmdLineGetDefaultOS(VOID) CmdLineGetDefaultOS(VOID)
{ {
return CmdLineInfo.DefaultOperatingSystem; return CmdLineInfo.DefaultOperatingSystem;

View file

@ -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 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 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 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 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."; const CHAR CustomBootPrompt[] = "Press ENTER to boot your custom boot setup.";
@ -55,6 +56,7 @@ VOID OptionMenuCustomBoot(VOID)
"ReactOS Setup" "ReactOS Setup"
}; };
ULONG SelectedMenuItem; ULONG SelectedMenuItem;
OperatingSystemItem OperatingSystem;
if (!UiDisplayMenu("Please choose a boot method:", NULL, if (!UiDisplayMenu("Please choose a boot method:", NULL,
FALSE, FALSE,
@ -69,65 +71,111 @@ VOID OptionMenuCustomBoot(VOID)
return; return;
} }
/* Initialize a new custom OS entry */
OperatingSystem.SectionId = 0;
switch (SelectedMenuItem) switch (SelectedMenuItem)
{ {
#ifdef _M_IX86 #ifdef _M_IX86
case 0: // Disk case 0: // Disk
EditCustomBootDisk(0); EditCustomBootDisk(&OperatingSystem);
break; break;
case 1: // Partition case 1: // Partition
EditCustomBootPartition(0); EditCustomBootPartition(&OperatingSystem);
break; break;
case 2: // Boot Sector File case 2: // Boot Sector File
EditCustomBootSectorFile(0); EditCustomBootSectorFile(&OperatingSystem);
break; break;
case 3: // Linux case 3: // Linux
EditCustomBootLinux(0); EditCustomBootLinux(&OperatingSystem);
break; break;
case 4: // ReactOS case 4: // ReactOS
EditCustomBootReactOS(0, FALSE); EditCustomBootReactOS(&OperatingSystem, FALSE);
break; break;
case 5: // ReactOS Setup case 5: // ReactOS Setup
EditCustomBootReactOS(0, TRUE); EditCustomBootReactOS(&OperatingSystem, TRUE);
break; break;
#else #else
case 0: // ReactOS case 0: // ReactOS
EditCustomBootReactOS(0, FALSE); EditCustomBootReactOS(&OperatingSystem, FALSE);
break; break;
case 1: // ReactOS Setup case 1: // ReactOS Setup
EditCustomBootReactOS(0, TRUE); EditCustomBootReactOS(&OperatingSystem, TRUE);
break; break;
#endif #endif
} }
/* And boot it */
if (OperatingSystem.SectionId != 0)
{
UiMessageBox(CustomBootPrompt);
LoadOperatingSystem(&OperatingSystem);
}
} }
#endif // HAS_OPTION_MENU_CUSTOM_BOOT #endif // HAS_OPTION_MENU_CUSTOM_BOOT
#ifdef _M_IX86 #ifdef _M_IX86
VOID EditCustomBootDisk(IN ULONG_PTR SectionId OPTIONAL) VOID
EditCustomBootDisk(
IN OUT OperatingSystemItem* OperatingSystem)
{ {
TIMEINFO* TimeInfo; TIMEINFO* TimeInfo;
OperatingSystemItem OperatingSystem; ULONG_PTR SectionId = OperatingSystem->SectionId;
CHAR SectionName[100]; 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(SectionName, sizeof(SectionName));
RtlZeroMemory(BootDriveString, sizeof(BootDriveString)); RtlZeroMemory(&BootStrings, sizeof(BootStrings));
if (SectionId != 0) if (SectionId != 0)
{ {
/* Load the settings */ /* 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))) if (!*BootStrings.ArcPath)
return; {
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 */ /* Modify the settings values and return if we were in edit mode */
if (SectionId != 0) 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; return;
} }
@ -146,47 +194,95 @@ VOID EditCustomBootDisk(IN ULONG_PTR SectionId OPTIONAL)
if (!IniAddSettingValueToSection(SectionId, "BootType", "Drive")) if (!IniAddSettingValueToSection(SectionId, "BootType", "Drive"))
return; return;
/* Add the BootDrive */ /* Add the BootPath if we have one */
if (!IniAddSettingValueToSection(SectionId, "BootDrive", BootDriveString)) if (*BootStrings.ArcPath)
return; {
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->SectionId = SectionId;
OperatingSystem->LoadIdentifier = NULL;
OperatingSystem.SectionName = SectionName;
OperatingSystem.LoadIdentifier = NULL;
LoadOperatingSystem(&OperatingSystem);
} }
VOID EditCustomBootPartition(IN ULONG_PTR SectionId OPTIONAL) VOID
EditCustomBootPartition(
IN OUT OperatingSystemItem* OperatingSystem)
{ {
TIMEINFO* TimeInfo; TIMEINFO* TimeInfo;
OperatingSystemItem OperatingSystem; ULONG_PTR SectionId = OperatingSystem->SectionId;
CHAR SectionName[100]; CHAR SectionName[100];
CHAR BootDriveString[20]; /* The following is a trick for saving some stack space */
CHAR BootPartitionString[20]; union
{
struct
{
CHAR Guard1;
CHAR Drive[20];
CHAR Partition[20];
CHAR Guard2;
};
CHAR ArcPath[200];
} BootStrings;
RtlZeroMemory(SectionName, sizeof(SectionName)); RtlZeroMemory(SectionName, sizeof(SectionName));
RtlZeroMemory(BootDriveString, sizeof(BootDriveString)); RtlZeroMemory(&BootStrings, sizeof(BootStrings));
RtlZeroMemory(BootPartitionString, sizeof(BootPartitionString));
if (SectionId != 0) if (SectionId != 0)
{ {
/* Load the settings */ /* 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))) if (!*BootStrings.ArcPath)
return; {
if (!UiEditBox(BootDrivePrompt, BootStrings.Drive, sizeof(BootStrings.Drive)))
return;
if (!UiEditBox(BootPartitionPrompt, BootPartitionString, sizeof(BootPartitionString))) if (*BootStrings.Drive)
return; {
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 */ /* Modify the settings values and return if we were in edit mode */
if (SectionId != 0) if (SectionId != 0)
{ {
IniModifySettingValue(SectionId, "BootDrive", BootDriveString); /* Modify the BootPath if we have one */
IniModifySettingValue(SectionId, "BootPartition", BootPartitionString); 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; return;
} }
@ -205,48 +301,87 @@ VOID EditCustomBootPartition(IN ULONG_PTR SectionId OPTIONAL)
if (!IniAddSettingValueToSection(SectionId, "BootType", "Partition")) if (!IniAddSettingValueToSection(SectionId, "BootType", "Partition"))
return; return;
/* Add the BootDrive */ /* Add the BootPath if we have one */
if (!IniAddSettingValueToSection(SectionId, "BootDrive", BootDriveString)) if (*BootStrings.ArcPath)
return; {
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", BootStrings.Partition))
if (!IniAddSettingValueToSection(SectionId, "BootPartition", BootPartitionString)) return;
return; }
UiMessageBox(CustomBootPrompt); OperatingSystem->SectionId = SectionId;
OperatingSystem->LoadIdentifier = NULL;
OperatingSystem.SectionName = SectionName;
OperatingSystem.LoadIdentifier = NULL;
LoadOperatingSystem(&OperatingSystem);
} }
VOID EditCustomBootSectorFile(IN ULONG_PTR SectionId OPTIONAL) VOID
EditCustomBootSectorFile(
IN OUT OperatingSystemItem* OperatingSystem)
{ {
TIMEINFO* TimeInfo; TIMEINFO* TimeInfo;
OperatingSystemItem OperatingSystem; ULONG_PTR SectionId = OperatingSystem->SectionId;
CHAR SectionName[100]; CHAR SectionName[100];
CHAR BootDriveString[20]; /* The following is a trick for saving some stack space */
CHAR BootPartitionString[20]; union
{
struct
{
CHAR Guard1;
CHAR Drive[20];
CHAR Partition[20];
CHAR Guard2;
};
CHAR ArcPath[200];
} BootStrings;
CHAR BootSectorFileString[200]; CHAR BootSectorFileString[200];
RtlZeroMemory(SectionName, sizeof(SectionName)); RtlZeroMemory(SectionName, sizeof(SectionName));
RtlZeroMemory(BootDriveString, sizeof(BootDriveString)); RtlZeroMemory(&BootStrings, sizeof(BootStrings));
RtlZeroMemory(BootPartitionString, sizeof(BootPartitionString));
RtlZeroMemory(BootSectorFileString, sizeof(BootSectorFileString)); RtlZeroMemory(BootSectorFileString, sizeof(BootSectorFileString));
if (SectionId != 0) if (SectionId != 0)
{ {
/* Load the settings */ /* 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)); IniReadSettingByName(SectionId, "BootSectorFile", BootSectorFileString, sizeof(BootSectorFileString));
} }
if (!UiEditBox(BootDrivePrompt, BootDriveString, sizeof(BootDriveString))) if (!*BootStrings.ArcPath)
return; {
if (!UiEditBox(BootDrivePrompt, BootStrings.Drive, sizeof(BootStrings.Drive)))
return;
if (!UiEditBox(BootPartitionPrompt, BootPartitionString, sizeof(BootPartitionString))) if (*BootStrings.Drive)
return; {
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))) if (!UiEditBox(BootSectorFilePrompt, BootSectorFileString, sizeof(BootSectorFileString)))
return; return;
@ -254,8 +389,28 @@ VOID EditCustomBootSectorFile(IN ULONG_PTR SectionId OPTIONAL)
/* Modify the settings values and return if we were in edit mode */ /* Modify the settings values and return if we were in edit mode */
if (SectionId != 0) if (SectionId != 0)
{ {
IniModifySettingValue(SectionId, "BootDrive", BootDriveString); /* Modify the BootPath if we have one */
IniModifySettingValue(SectionId, "BootPartition", BootPartitionString); 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); IniModifySettingValue(SectionId, "BootSectorFile", BootSectorFileString);
return; return;
} }
@ -275,39 +430,55 @@ VOID EditCustomBootSectorFile(IN ULONG_PTR SectionId OPTIONAL)
if (!IniAddSettingValueToSection(SectionId, "BootType", "BootSector")) if (!IniAddSettingValueToSection(SectionId, "BootType", "BootSector"))
return; return;
/* Add the BootDrive */ /* Add the BootPath if we have one */
if (!IniAddSettingValueToSection(SectionId, "BootDrive", BootDriveString)) if (*BootStrings.ArcPath)
return; {
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", BootStrings.Partition))
if (!IniAddSettingValueToSection(SectionId, "BootPartition", BootPartitionString)) return;
return; }
/* Add the BootSectorFile */ /* Add the BootSectorFile */
if (!IniAddSettingValueToSection(SectionId, "BootSectorFile", BootSectorFileString)) if (!IniAddSettingValueToSection(SectionId, "BootSectorFile", BootSectorFileString))
return; return;
UiMessageBox(CustomBootPrompt); OperatingSystem->SectionId = SectionId;
OperatingSystem->LoadIdentifier = NULL;
OperatingSystem.SectionName = SectionName;
OperatingSystem.LoadIdentifier = NULL;
LoadOperatingSystem(&OperatingSystem);
} }
VOID EditCustomBootLinux(IN ULONG_PTR SectionId OPTIONAL) VOID
EditCustomBootLinux(
IN OUT OperatingSystemItem* OperatingSystem)
{ {
TIMEINFO* TimeInfo; TIMEINFO* TimeInfo;
OperatingSystemItem OperatingSystem; ULONG_PTR SectionId = OperatingSystem->SectionId;
CHAR SectionName[100]; CHAR SectionName[100];
CHAR BootDriveString[20]; /* The following is a trick for saving some stack space */
CHAR BootPartitionString[20]; union
{
struct
{
CHAR Guard1;
CHAR Drive[20];
CHAR Partition[20];
CHAR Guard2;
};
CHAR ArcPath[200];
} BootStrings;
CHAR LinuxKernelString[200]; CHAR LinuxKernelString[200];
CHAR LinuxInitrdString[200]; CHAR LinuxInitrdString[200];
CHAR LinuxCommandLineString[200]; CHAR LinuxCommandLineString[200];
RtlZeroMemory(SectionName, sizeof(SectionName)); RtlZeroMemory(SectionName, sizeof(SectionName));
RtlZeroMemory(BootDriveString, sizeof(BootDriveString)); RtlZeroMemory(&BootStrings, sizeof(BootStrings));
RtlZeroMemory(BootPartitionString, sizeof(BootPartitionString));
RtlZeroMemory(LinuxKernelString, sizeof(LinuxKernelString)); RtlZeroMemory(LinuxKernelString, sizeof(LinuxKernelString));
RtlZeroMemory(LinuxInitrdString, sizeof(LinuxInitrdString)); RtlZeroMemory(LinuxInitrdString, sizeof(LinuxInitrdString));
RtlZeroMemory(LinuxCommandLineString, sizeof(LinuxCommandLineString)); RtlZeroMemory(LinuxCommandLineString, sizeof(LinuxCommandLineString));
@ -315,18 +486,41 @@ VOID EditCustomBootLinux(IN ULONG_PTR SectionId OPTIONAL)
if (SectionId != 0) if (SectionId != 0)
{ {
/* Load the settings */ /* 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, "Kernel", LinuxKernelString, sizeof(LinuxKernelString));
IniReadSettingByName(SectionId, "Initrd", LinuxInitrdString, sizeof(LinuxInitrdString)); IniReadSettingByName(SectionId, "Initrd", LinuxInitrdString, sizeof(LinuxInitrdString));
IniReadSettingByName(SectionId, "CommandLine", LinuxCommandLineString, sizeof(LinuxCommandLineString)); IniReadSettingByName(SectionId, "CommandLine", LinuxCommandLineString, sizeof(LinuxCommandLineString));
} }
if (!UiEditBox(BootDrivePrompt, BootDriveString, sizeof(BootDriveString))) if (!*BootStrings.ArcPath)
return; {
if (!UiEditBox(BootDrivePrompt, BootStrings.Drive, sizeof(BootStrings.Drive)))
return;
if (!UiEditBox(BootPartitionPrompt, BootPartitionString, sizeof(BootPartitionString))) if (*BootStrings.Drive)
return; {
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))) if (!UiEditBox(LinuxKernelPrompt, LinuxKernelString, sizeof(LinuxKernelString)))
return; return;
@ -340,8 +534,28 @@ VOID EditCustomBootLinux(IN ULONG_PTR SectionId OPTIONAL)
/* Modify the settings values and return if we were in edit mode */ /* Modify the settings values and return if we were in edit mode */
if (SectionId != 0) if (SectionId != 0)
{ {
IniModifySettingValue(SectionId, "BootDrive", BootDriveString); /* Modify the BootPath if we have one */
IniModifySettingValue(SectionId, "BootPartition", BootPartitionString); 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, "Kernel", LinuxKernelString);
IniModifySettingValue(SectionId, "Initrd", LinuxInitrdString); IniModifySettingValue(SectionId, "Initrd", LinuxInitrdString);
IniModifySettingValue(SectionId, "CommandLine", LinuxCommandLineString); IniModifySettingValue(SectionId, "CommandLine", LinuxCommandLineString);
@ -363,13 +577,21 @@ VOID EditCustomBootLinux(IN ULONG_PTR SectionId OPTIONAL)
if (!IniAddSettingValueToSection(SectionId, "BootType", "Linux")) if (!IniAddSettingValueToSection(SectionId, "BootType", "Linux"))
return; return;
/* Add the BootDrive */ /* Add the BootPath if we have one */
if (!IniAddSettingValueToSection(SectionId, "BootDrive", BootDriveString)) if (*BootStrings.ArcPath)
return; {
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", BootStrings.Partition))
if (!IniAddSettingValueToSection(SectionId, "BootPartition", BootPartitionString)) return;
return; }
/* Add the Kernel */ /* Add the Kernel */
if (!IniAddSettingValueToSection(SectionId, "Kernel", LinuxKernelString)) if (!IniAddSettingValueToSection(SectionId, "Kernel", LinuxKernelString))
@ -386,22 +608,19 @@ VOID EditCustomBootLinux(IN ULONG_PTR SectionId OPTIONAL)
if (!IniAddSettingValueToSection(SectionId, "CommandLine", LinuxCommandLineString)) if (!IniAddSettingValueToSection(SectionId, "CommandLine", LinuxCommandLineString))
return; return;
UiMessageBox(CustomBootPrompt); OperatingSystem->SectionId = SectionId;
OperatingSystem->LoadIdentifier = "Custom Linux Setup";
OperatingSystem.SectionName = SectionName;
OperatingSystem.LoadIdentifier = "Custom Linux Setup";
LoadOperatingSystem(&OperatingSystem);
} }
#endif // _M_IX86 #endif // _M_IX86
VOID VOID
EditCustomBootReactOS( EditCustomBootReactOS(
IN ULONG_PTR SectionId OPTIONAL, IN OUT OperatingSystemItem* OperatingSystem,
IN BOOLEAN IsSetup) IN BOOLEAN IsSetup)
{ {
TIMEINFO* TimeInfo; TIMEINFO* TimeInfo;
OperatingSystemItem OperatingSystem; ULONG_PTR SectionId = OperatingSystem->SectionId;
CHAR SectionName[100]; CHAR SectionName[100];
CHAR BootDriveString[20]; CHAR BootDriveString[20];
CHAR BootPartitionString[20]; CHAR BootPartitionString[20];
@ -419,7 +638,6 @@ EditCustomBootReactOS(
if (SectionId != 0) if (SectionId != 0)
{ {
/* Load the settings */ /* 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, "SystemPath", ReactOSARCPath, sizeof(ReactOSARCPath));
IniReadSettingByName(SectionId, "Options", ReactOSOptions, sizeof(ReactOSOptions)); IniReadSettingByName(SectionId, "Options", ReactOSOptions, sizeof(ReactOSOptions));
} }
@ -478,11 +696,8 @@ EditCustomBootReactOS(
if (!IniAddSettingValueToSection(SectionId, "Options", ReactOSOptions)) if (!IniAddSettingValueToSection(SectionId, "Options", ReactOSOptions))
return; return;
UiMessageBox(CustomBootPrompt); OperatingSystem->SectionId = SectionId;
OperatingSystem->LoadIdentifier = NULL;
OperatingSystem.SectionName = SectionName;
OperatingSystem.LoadIdentifier = NULL;
LoadOperatingSystem(&OperatingSystem);
} }
#ifdef HAS_OPTION_MENU_REBOOT #ifdef HAS_OPTION_MENU_REBOOT

View file

@ -109,62 +109,52 @@ static const DEVVTBL RamDiskVtbl = {
}; };
VOID VOID
NTAPI
RamDiskInitialize(VOID) RamDiskInitialize(VOID)
{ {
/* Register the RAMDISK device */ /* Register the RAMDISK device */
FsRegisterDevice("ramdisk(0)", &RamDiskVtbl); FsRegisterDevice("ramdisk(0)", &RamDiskVtbl);
} }
BOOLEAN ARC_STATUS
NTAPI RamDiskLoadVirtualFile(
RamDiskLoadVirtualFile(IN PCHAR FileName) IN PCSTR FileName,
IN PCSTR DefaultPath OPTIONAL)
{ {
ARC_STATUS Status;
ULONG RamFileId; ULONG RamFileId;
ULONG TotalRead, ChunkSize, Count; ULONG TotalRead, ChunkSize, Count;
PCHAR MsgBuffer = "Loading RamDisk..."; PCHAR MsgBuffer = "Loading RamDisk...";
ULONG PercentPerChunk, Percent; ULONG PercentPerChunk, Percent;
FILEINFORMATION Information; FILEINFORMATION Information;
LARGE_INTEGER Position; LARGE_INTEGER Position;
ARC_STATUS Status;
// /* Display progress */
// Display progress
//
UiDrawBackdrop(); UiDrawBackdrop();
UiDrawProgressBarCenter(1, 100, MsgBuffer); UiDrawProgressBarCenter(1, 100, MsgBuffer);
// /* Try opening the ramdisk file */
// Try opening the ramdisk file Status = FsOpenFile(FileName, DefaultPath, OpenReadOnly, &RamFileId);
// if (Status != ESUCCESS)
RamFileId = FsOpenFile(FileName); return Status;
if (!RamFileId)
return FALSE;
// /* Get the file size */
// Get the file size
//
Status = ArcGetFileInformation(RamFileId, &Information); Status = ArcGetFileInformation(RamFileId, &Information);
if (Status != ESUCCESS) if (Status != ESUCCESS)
{ {
ArcClose(RamFileId); 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) if (Information.EndingAddress.HighPart != 0)
{ {
UiMessageBox("RAM disk too big."); UiMessageBox("RAM disk too big.");
ArcClose(RamFileId); ArcClose(RamFileId);
return FALSE; return ENOMEM;
} }
gRamDiskSize = Information.EndingAddress.LowPart; gRamDiskSize = Information.EndingAddress.LowPart;
// /* Allocate memory for it */
// Allocate memory for it
//
ChunkSize = 8 * 1024 * 1024; ChunkSize = 8 * 1024 * 1024;
if (gRamDiskSize < ChunkSize) if (gRamDiskSize < ChunkSize)
Percent = PercentPerChunk = 0; Percent = PercentPerChunk = 0;
@ -175,34 +165,26 @@ RamDiskLoadVirtualFile(IN PCHAR FileName)
{ {
UiMessageBox("Failed to allocate memory for RAM disk."); UiMessageBox("Failed to allocate memory for RAM disk.");
ArcClose(RamFileId); ArcClose(RamFileId);
return FALSE; return ENOMEM;
} }
// /*
// Read it in chunks * Read it in chunks
// */
for (TotalRead = 0; TotalRead < gRamDiskSize; TotalRead += ChunkSize) 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) if ((gRamDiskSize - TotalRead) < ChunkSize)
{ {
// /* Only need the actual data required */
// Only need the actual data required
//
ChunkSize = gRamDiskSize - TotalRead; ChunkSize = gRamDiskSize - TotalRead;
} }
// /* Draw progress */
// Draw progress
//
UiDrawProgressBarCenter(Percent, 100, MsgBuffer); UiDrawProgressBarCenter(Percent, 100, MsgBuffer);
Percent += PercentPerChunk; Percent += PercentPerChunk;
// /* Copy the contents */
// Copy the contents
//
Position.HighPart = 0; Position.HighPart = 0;
Position.LowPart = TotalRead; Position.LowPart = TotalRead;
Status = ArcSeek(RamFileId, &Position, SeekAbsolute); Status = ArcSeek(RamFileId, &Position, SeekAbsolute);
@ -214,17 +196,15 @@ RamDiskLoadVirtualFile(IN PCHAR FileName)
&Count); &Count);
} }
// /* Check for success */
// Check for success if ((Status != ESUCCESS) || (Count != ChunkSize))
//
if (Status != ESUCCESS || Count != ChunkSize)
{ {
MmFreeMemory(gRamDiskBase); MmFreeMemory(gRamDiskBase);
gRamDiskBase = NULL; gRamDiskBase = NULL;
gRamDiskSize = 0; gRamDiskSize = 0;
ArcClose(RamFileId); ArcClose(RamFileId);
UiMessageBox("Failed to read RAM disk."); 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 */ /* Setup the RAMDISK device */
RamDiskInitialize(); RamDiskInitialize();
return TRUE; return ESUCCESS;
} }

View file

@ -20,8 +20,8 @@
/* INCLUDES *******************************************************************/ /* INCLUDES *******************************************************************/
#include <freeldr.h> #include <freeldr.h>
#include <debug.h>
#include <debug.h>
DBG_DEFAULT_CHANNEL(WARNING); DBG_DEFAULT_CHANNEL(WARNING);
/* FUNCTIONS ******************************************************************/ /* FUNCTIONS ******************************************************************/
@ -31,7 +31,7 @@ VOID __cdecl BootMain(IN PCCH CmdLine)
CmdLineParse(CmdLine); CmdLineParse(CmdLine);
/* Debugger pre-initialization */ /* Debugger pre-initialization */
DebugInit(FALSE); DebugInit(0);
TRACE("BootMain() called.\n"); TRACE("BootMain() called.\n");

View file

@ -36,7 +36,10 @@ UCHAR DriveMapGetBiosDriveNumber(PCSTR DeviceName); // Returns a BIOS drive
#ifdef _M_IX86 #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 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 VOID DriveMapRemoveInt13Handler(VOID); // Removes a previously installed int 13h drive map handler

View file

@ -24,16 +24,25 @@
// ARC Path Functions // ARC Path Functions
// //
/////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////
BOOLEAN
DissectArcPath(
IN PCSTR ArcPath,
OUT PCSTR* Path OPTIONAL,
OUT PUCHAR DriveNumber,
OUT PULONG PartitionNumber);
BOOLEAN BOOLEAN
DissectArcPath2( DissectArcPath2(
IN CHAR* ArcPath, IN PCSTR ArcPath,
OUT ULONG* x, OUT PULONG x,
OUT ULONG* y, OUT PULONG y,
OUT ULONG* z, OUT PULONG z,
OUT ULONG* Partition, OUT PULONG Partition,
OUT ULONG *PathSyntax); OUT PULONG PathSyntax);
BOOLEAN DissectArcPath(CHAR *ArcPath, CHAR *BootPath, UCHAR* BootDrive, ULONG* BootPartition);
VOID ConstructArcPath(PCHAR ArcPath, PCHAR SystemFolder, UCHAR Disk, ULONG Partition); VOID ConstructArcPath(PCHAR ArcPath, PCHAR SystemFolder, UCHAR Disk, ULONG Partition);
#if 0 #if 0
UCHAR ConvertArcNameToBiosDriveNumber(PCHAR ArcPath); UCHAR ConvertArcNameToBiosDriveNumber(PCHAR ArcPath);
#endif #endif

View file

@ -19,10 +19,10 @@
#pragma once #pragma once
VOID CmdLineParse(IN PCCH CmdLine); VOID CmdLineParse(IN PCSTR CmdLine);
PCCH CmdLineGetDebugString(VOID); PCSTR CmdLineGetDebugString(VOID);
PCCH CmdLineGetDefaultOS(VOID); PCSTR CmdLineGetDefaultOS(VOID);
LONG CmdLineGetTimeOut(VOID); LONG CmdLineGetTimeOut(VOID);
/* EOF */ /* EOF */

View file

@ -23,22 +23,33 @@
#define HAS_OPTION_MENU_CUSTOM_BOOT #define HAS_OPTION_MENU_CUSTOM_BOOT
#define HAS_OPTION_MENU_REBOOT #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 #ifdef HAS_OPTION_MENU_CUSTOM_BOOT
VOID OptionMenuCustomBoot(VOID); VOID OptionMenuCustomBoot(VOID);
#endif #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 VOID
EditCustomBootReactOS( EditCustomBootReactOS(
IN ULONG_PTR SectionId OPTIONAL, IN OUT OperatingSystemItem* OperatingSystem,
IN BOOLEAN IsSetup); IN BOOLEAN IsSetup);
#ifdef HAS_OPTION_MENU_REBOOT #ifdef HAS_OPTION_MENU_REBOOT

View file

@ -40,7 +40,7 @@
#if DBG && !defined(_M_ARM) #if DBG && !defined(_M_ARM)
VOID DebugInit(BOOLEAN MainInit); VOID DebugInit(IN ULONG_PTR FrLdrSectionId);
ULONG DbgPrint(const char *Format, ...); ULONG DbgPrint(const char *Format, ...);
VOID DbgPrint2(ULONG Mask, ULONG Level, const char *File, ULONG Line, char *Format, ...); VOID DbgPrint2(ULONG Mask, ULONG Level, const char *File, ULONG Line, char *Format, ...);
VOID DebugDumpBuffer(ULONG Mask, PVOID Buffer, ULONG Length); VOID DebugDumpBuffer(ULONG Mask, PVOID Buffer, ULONG Length);
@ -113,7 +113,7 @@ void MEMORY_WRITE_BREAKPOINT4(unsigned long addr);
#define UNIMPLEMENTED #define UNIMPLEMENTED
#define DebugInit(init) #define DebugInit(FrLdrSectionId)
#define BugCheck(fmt, ...) #define BugCheck(fmt, ...)
#define DbgDumpBuffer(mask, buf, len) #define DbgDumpBuffer(mask, buf, len)
#define DbgParseDebugChannels(val) #define DbgParseDebugChannels(val)

View file

@ -40,7 +40,14 @@ ARC_STATUS ArcSeek(ULONG FileId, LARGE_INTEGER* Position, SEEKMODE SeekMode);
ARC_STATUS ArcGetFileInformation(ULONG FileId, FILEINFORMATION* Information); ARC_STATUS ArcGetFileInformation(ULONG FileId, FILEINFORMATION* Information);
VOID FileSystemError(PCSTR ErrorString); 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); ULONG FsGetNumPathParts(PCSTR Path);
VOID FsGetFirstNameFromPath(PCHAR Buffer, PCSTR Path); VOID FsGetFirstNameFromPath(PCHAR Buffer, PCSTR Path);

View file

@ -137,17 +137,6 @@ LoadAndBootLinux(
IN PCHAR Argv[], IN PCHAR Argv[],
IN PCHAR Envp[]); 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 // _M_IX86
#endif // defined __LINUX_H #endif // defined __LINUX_H

View file

@ -23,11 +23,12 @@
typedef struct tagOperatingSystemItem typedef struct tagOperatingSystemItem
{ {
PCSTR SectionName; ULONG_PTR SectionId;
PCSTR LoadIdentifier; PCSTR LoadIdentifier;
} OperatingSystemItem; } OperatingSystemItem;
OperatingSystemItem* OperatingSystemItem*
InitOperatingSystemList( InitOperatingSystemList(
IN ULONG_PTR FrLdrSectionId,
OUT PULONG OperatingSystemCount, OUT PULONG OperatingSystemCount,
OUT PULONG DefaultOperatingSystem); OUT PULONG DefaultOperatingSystem);

View file

@ -11,17 +11,13 @@
// //
// Ramdisk Routines // Ramdisk Routines
// //
BOOLEAN ARC_STATUS
NTAPI
RamDiskLoadVirtualFile( RamDiskLoadVirtualFile(
IN PCHAR FileName IN PCSTR FileName,
); IN PCSTR DefaultPath OPTIONAL);
VOID VOID
NTAPI RamDiskInitialize(VOID);
RamDiskInitialize(
VOID
);
extern PVOID gRamDiskBase; extern PVOID gRamDiskBase;
extern ULONG gRamDiskSize; extern ULONG gRamDiskSize;

View file

@ -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 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 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 VOID
UiShowMessageBoxesInArgv( UiShowMessageBoxesInArgv(

View file

@ -49,7 +49,7 @@ ULONG PortIrq = 0; // Not used at the moment.
BOOLEAN DebugStartOfLine = TRUE; BOOLEAN DebugStartOfLine = TRUE;
VOID DebugInit(BOOLEAN MainInit) VOID DebugInit(IN ULONG_PTR FrLdrSectionId)
{ {
PCHAR CommandLine, PortString, BaudString, IrqString; PCHAR CommandLine, PortString, BaudString, IrqString;
ULONG Value; ULONG Value;
@ -78,7 +78,7 @@ VOID DebugInit(BOOLEAN MainInit)
#endif #endif
/* Check for pre- or main initialization phase */ /* Check for pre- or main initialization phase */
if (!MainInit) if (FrLdrSectionId == 0)
{ {
/* Pre-initialization phase: use the FreeLdr command-line debugging string */ /* Pre-initialization phase: use the FreeLdr command-line debugging string */
CommandLine = (PCHAR)CmdLineGetDebugString(); CommandLine = (PCHAR)CmdLineGetDebugString();
@ -92,14 +92,10 @@ VOID DebugInit(BOOLEAN MainInit)
else else
{ {
/* Main initialization phase: use the FreeLdr INI debugging string */ /* Main initialization phase: use the FreeLdr INI debugging string */
if (!IniReadSettingByName(FrLdrSectionId, "Debug", DebugString, sizeof(DebugString)))
ULONG_PTR SectionId; {
if (!IniOpenSection("FreeLoader", &SectionId))
return;
if (!IniReadSettingByName(SectionId, "Debug", DebugString, sizeof(DebugString)))
return; return;
}
} }
/* Get the Command Line */ /* Get the Command Line */

View file

@ -23,7 +23,6 @@
#include <freeldr.h> #include <freeldr.h>
#include <debug.h> #include <debug.h>
DBG_DEFAULT_CHANNEL(FILESYSTEM); DBG_DEFAULT_CHANNEL(FILESYSTEM);
/* GLOBALS ********************************************************************/ /* GLOBALS ********************************************************************/
@ -199,8 +198,8 @@ ARC_STATUS ArcOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId)
if (i == MAX_FDS) if (i == MAX_FDS)
return EMFILE; return EMFILE;
/* Skip leading backslash, if any */ /* Skip leading path separator, if any */
if (*FileName == '\\') if (*FileName == '\\' || *FileName == '/')
FileName++; FileName++;
/* Open the file */ /* Open the file */
@ -263,47 +262,62 @@ VOID FileSystemError(PCSTR ErrorString)
UiMessageBox(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] = ""; CHAR FullPath[MAX_PATH] = "";
ULONG FileId;
ARC_STATUS Status;
// /*
// Print status message * Check whether FileName is a full path and if not, create a full
// * file name using the user-provided default path (if present).
TRACE("Opening file '%s'...\n", FileName); *
* See ArcOpen(): Search last ')', which delimits device and path.
// */
// Check whether FileName is a full path
// and if not, create a full file name.
//
// See ArcOpen: Search last ')', which delimits device and path.
//
if (strrchr(FileName, ')') == NULL) if (strrchr(FileName, ')') == NULL)
{ {
/* This is not a full path. Use the current (i.e. boot) device. */ /* This is not a full path: prepend the user-provided default path */
MachDiskGetBootPath(FullPath, sizeof(FullPath)); if (DefaultPath)
{
Status = RtlStringCbCopyA(FullPath, sizeof(FullPath), DefaultPath);
if (!NT_SUCCESS(Status))
return ENAMETOOLONG;
}
/* Append a path separator if needed */ /* 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. /* Append (or just copy) the remaining file name */
strcat(FullPath, FileName); Status = RtlStringCbCatA(FullPath, sizeof(FullPath), FileName);
if (!NT_SUCCESS(Status))
return ENAMETOOLONG;
// /* Open the file */
// Open the file return ArcOpen(FullPath, OpenMode, FileId);
//
Status = ArcOpen(FullPath, OpenReadOnly, &FileId);
//
// Check for success
//
if (Status == ESUCCESS)
return FileId;
else
return 0;
} }
/* /*
@ -422,8 +436,4 @@ VOID FsInit(VOID)
FileData[i].DeviceId = (ULONG)-1; FileData[i].DeviceId = (ULONG)-1;
InitializeListHead(&DeviceListHead); InitializeListHead(&DeviceListHead);
// FIXME: Retrieve the current boot device with MachDiskGetBootPath
// and store it somewhere in order to not call again and again this
// function.
} }

View file

@ -286,7 +286,7 @@ WinLdrLoadImage(IN PCHAR FileName,
TRACE("WinLdrLoadImage(%s, %ld, *)\n", FileName, MemoryType); TRACE("WinLdrLoadImage(%s, %ld, *)\n", FileName, MemoryType);
/* Open the image file */ /* Open the image file */
Status = ArcOpen(FileName, OpenReadOnly, &FileId); Status = ArcOpen((PSTR)FileName, OpenReadOnly, &FileId);
if (Status != ESUCCESS) if (Status != ESUCCESS)
{ {
WARN("ArcOpen(FileName: '%s') failed. Status: %u\n", FileName, Status); WARN("ArcOpen(FileName: '%s') failed. Status: %u\n", FileName, Status);

View file

@ -29,8 +29,8 @@
/* INCLUDES *******************************************************************/ /* INCLUDES *******************************************************************/
#include <freeldr.h> #include <freeldr.h>
#include <debug.h>
#include <debug.h>
DBG_DEFAULT_CHANNEL(LINUX); DBG_DEFAULT_CHANNEL(LINUX);
/* GLOBALS ********************************************************************/ /* GLOBALS ********************************************************************/
@ -50,11 +50,16 @@ ULONG LinuxCommandLineSize = 0;
PVOID LinuxKernelLoadAddress = NULL; PVOID LinuxKernelLoadAddress = NULL;
PVOID LinuxInitrdLoadAddress = NULL; PVOID LinuxInitrdLoadAddress = NULL;
CHAR LinuxBootDescription[80]; CHAR LinuxBootDescription[80];
PCSTR LinuxBootPath = NULL;
/* FUNCTIONS ******************************************************************/ /* 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( RemoveQuotes(
IN OUT PSTR QuotedString) IN OUT PSTR QuotedString)
{ {
@ -85,14 +90,19 @@ LoadAndBootLinux(
IN PCHAR Argv[], IN PCHAR Argv[],
IN PCHAR Envp[]) IN PCHAR Envp[])
{ {
ARC_STATUS Status;
PCSTR Description; PCSTR Description;
PCSTR ArgValue;
PCSTR BootPath;
UCHAR DriveNumber = 0;
ULONG PartitionNumber = 0;
ULONG LinuxKernel = 0; ULONG LinuxKernel = 0;
ULONG LinuxInitrdFile = 0; ULONG LinuxInitrdFile = 0;
ARC_STATUS Status;
FILEINFORMATION FileInfo; FILEINFORMATION FileInfo;
CHAR ArcPath[MAX_PATH];
Description = GetArgumentValue(Argc, Argv, "LoadIdentifier"); Description = GetArgumentValue(Argc, Argv, "LoadIdentifier");
if (Description) if (Description && *Description)
RtlStringCbPrintfA(LinuxBootDescription, sizeof(LinuxBootDescription), "Loading %s...", Description); RtlStringCbPrintfA(LinuxBootDescription, sizeof(LinuxBootDescription), "Loading %s...", Description);
else else
strcpy(LinuxBootDescription, "Loading Linux..."); strcpy(LinuxBootDescription, "Loading Linux...");
@ -104,34 +114,91 @@ LoadAndBootLinux(
/* Find all the message box settings and run them */ /* Find all the message box settings and run them */
UiShowMessageBoxesInArgv(Argc, Argv); 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; 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 */ /* Open the kernel */
LinuxKernel = FsOpenFile(LinuxKernelName); Status = FsOpenFile(LinuxKernelName, BootPath, OpenReadOnly, &LinuxKernel);
if (!LinuxKernel) if (Status != ESUCCESS)
{ {
UiMessageBox("Linux kernel \'%s\' not found.", LinuxKernelName); UiMessageBox("Linux kernel '%s' not found.", LinuxKernelName);
goto LinuxBootFailed; goto LinuxBootFailed;
} }
/* Open the initrd file image (if necessary) */ /* Open the initrd file image (if necessary) */
if (LinuxInitrdName) if (LinuxInitrdName)
{ {
LinuxInitrdFile = FsOpenFile(LinuxInitrdName); Status = FsOpenFile(LinuxInitrdName, BootPath, OpenReadOnly, &LinuxInitrdFile);
if (!LinuxInitrdFile) if (Status != ESUCCESS)
{ {
UiMessageBox("Linux initrd image \'%s\' not found.", LinuxInitrdName); UiMessageBox("Linux initrd image '%s' not found.", LinuxInitrdName);
goto LinuxBootFailed; goto LinuxBootFailed;
} }
} }
/* Read the boot sector */ /* Load the boot sector */
if (!LinuxReadBootSector(LinuxKernel)) if (!LinuxReadBootSector(LinuxKernel))
goto LinuxBootFailed; goto LinuxBootFailed;
/* Read the setup sector */ /* Load the setup sector */
if (!LinuxReadSetupSector(LinuxKernel)) if (!LinuxReadSetupSector(LinuxKernel))
goto LinuxBootFailed; goto LinuxBootFailed;
@ -153,11 +220,11 @@ LoadAndBootLinux(
LinuxInitrdSize = FileInfo.EndingAddress.LowPart; LinuxInitrdSize = FileInfo.EndingAddress.LowPart;
} }
/* Read the kernel */ /* Load the kernel */
if (!LinuxReadKernel(LinuxKernel)) if (!LinuxReadKernel(LinuxKernel))
goto LinuxBootFailed; goto LinuxBootFailed;
/* Read the initrd (if necessary) */ /* Load the initrd (if necessary) */
if (LinuxInitrdName) if (LinuxInitrdName)
{ {
if (!LinuxReadInitrd(LinuxInitrdFile)) if (!LinuxReadInitrd(LinuxInitrdFile))
@ -233,50 +300,11 @@ LinuxBootFailed:
LinuxKernelLoadAddress = NULL; LinuxKernelLoadAddress = NULL;
LinuxInitrdLoadAddress = NULL; LinuxInitrdLoadAddress = NULL;
*LinuxBootDescription = ANSI_NULL; *LinuxBootDescription = ANSI_NULL;
LinuxBootPath = NULL;
return ENOEXEC; return ENOEXEC;
} }
BOOLEAN static BOOLEAN LinuxReadBootSector(ULONG LinuxKernelFile)
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)
{ {
LARGE_INTEGER Position; LARGE_INTEGER Position;
@ -285,7 +313,7 @@ BOOLEAN LinuxReadBootSector(ULONG LinuxKernelFile)
if (LinuxBootSector == NULL) if (LinuxBootSector == NULL)
return FALSE; return FALSE;
/* Read linux boot sector */ /* Load the linux boot sector */
Position.QuadPart = 0; Position.QuadPart = 0;
if (ArcSeek(LinuxKernelFile, &Position, SeekAbsolute) != ESUCCESS) if (ArcSeek(LinuxKernelFile, &Position, SeekAbsolute) != ESUCCESS)
return FALSE; return FALSE;
@ -313,12 +341,12 @@ BOOLEAN LinuxReadBootSector(ULONG LinuxKernelFile)
return TRUE; return TRUE;
} }
BOOLEAN LinuxReadSetupSector(ULONG LinuxKernelFile) static BOOLEAN LinuxReadSetupSector(ULONG LinuxKernelFile)
{ {
LARGE_INTEGER Position; LARGE_INTEGER Position;
UCHAR TempLinuxSetupSector[512]; UCHAR TempLinuxSetupSector[512];
/* Read first linux setup sector */ /* Load the first linux setup sector */
Position.QuadPart = 512; Position.QuadPart = 512;
if (ArcSeek(LinuxKernelFile, &Position, SeekAbsolute) != ESUCCESS) if (ArcSeek(LinuxKernelFile, &Position, SeekAbsolute) != ESUCCESS)
return FALSE; return FALSE;
@ -343,7 +371,7 @@ BOOLEAN LinuxReadSetupSector(ULONG LinuxKernelFile)
/* Copy over first setup sector */ /* Copy over first setup sector */
RtlCopyMemory(LinuxSetupSector, TempLinuxSetupSector, 512); RtlCopyMemory(LinuxSetupSector, TempLinuxSetupSector, 512);
/* Read in the rest of the linux setup sectors */ /* Load the rest of the linux setup sectors */
Position.QuadPart = 1024; Position.QuadPart = 1024;
if (ArcSeek(LinuxKernelFile, &Position, SeekAbsolute) != ESUCCESS) if (ArcSeek(LinuxKernelFile, &Position, SeekAbsolute) != ESUCCESS)
return FALSE; return FALSE;
@ -371,7 +399,7 @@ BOOLEAN LinuxReadSetupSector(ULONG LinuxKernelFile)
return TRUE; return TRUE;
} }
BOOLEAN LinuxReadKernel(ULONG LinuxKernelFile) static BOOLEAN LinuxReadKernel(ULONG LinuxKernelFile)
{ {
PVOID LoadAddress; PVOID LoadAddress;
LARGE_INTEGER Position; LARGE_INTEGER Position;
@ -390,7 +418,7 @@ BOOLEAN LinuxReadKernel(ULONG LinuxKernelFile)
LoadAddress = LinuxKernelLoadAddress; LoadAddress = LinuxKernelLoadAddress;
/* Read linux kernel to 0x100000 (1mb) */ /* Load the linux kernel at 0x100000 (1mb) */
Position.QuadPart = 512 + SetupSectorSize; Position.QuadPart = 512 + SetupSectorSize;
if (ArcSeek(LinuxKernelFile, &Position, SeekAbsolute) != ESUCCESS) if (ArcSeek(LinuxKernelFile, &Position, SeekAbsolute) != ESUCCESS)
return FALSE; return FALSE;
@ -408,7 +436,7 @@ BOOLEAN LinuxReadKernel(ULONG LinuxKernelFile)
return TRUE; return TRUE;
} }
BOOLEAN LinuxCheckKernelVersion(VOID) static BOOLEAN LinuxCheckKernelVersion(VOID)
{ {
/* Just assume old kernel until we find otherwise */ /* Just assume old kernel until we find otherwise */
NewStyleLinuxKernel = FALSE; NewStyleLinuxKernel = FALSE;
@ -445,7 +473,7 @@ BOOLEAN LinuxCheckKernelVersion(VOID)
return TRUE; return TRUE;
} }
BOOLEAN LinuxReadInitrd(ULONG LinuxInitrdFile) static BOOLEAN LinuxReadInitrd(ULONG LinuxInitrdFile)
{ {
ULONG BytesLoaded; ULONG BytesLoaded;
CHAR StatusText[260]; CHAR StatusText[260];
@ -482,7 +510,7 @@ BOOLEAN LinuxReadInitrd(ULONG LinuxInitrdFile)
TRACE("InitrdAddressMax: 0x%x\n", LinuxSetupSector->InitrdAddressMax); TRACE("InitrdAddressMax: 0x%x\n", LinuxSetupSector->InitrdAddressMax);
} }
/* Read in the ramdisk */ /* Load the ramdisk */
for (BytesLoaded=0; BytesLoaded<LinuxInitrdSize; ) for (BytesLoaded=0; BytesLoaded<LinuxInitrdSize; )
{ {
if (ArcRead(LinuxInitrdFile, (PVOID)LinuxInitrdLoadAddress, LINUX_READ_CHUNK_SIZE, NULL) != ESUCCESS) if (ArcRead(LinuxInitrdFile, (PVOID)LinuxInitrdLoadAddress, LINUX_READ_CHUNK_SIZE, NULL) != ESUCCESS)

View file

@ -32,34 +32,79 @@ LoadAndBootBootSector(
IN PCHAR Envp[]) IN PCHAR Envp[])
{ {
ARC_STATUS Status; ARC_STATUS Status;
PCSTR ArgValue;
PCSTR BootPath;
PCSTR FileName; PCSTR FileName;
UCHAR DriveNumber = 0;
ULONG PartitionNumber = 0;
ULONG FileId; ULONG FileId;
ULONG BytesRead; ULONG BytesRead;
CHAR ArcPath[MAX_PATH];
/* Find all the message box settings and run them */ /* Find all the message box settings and run them */
UiShowMessageBoxesInArgv(Argc, Argv); 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"); FileName = GetArgumentValue(Argc, Argv, "BootSectorFile");
if (!FileName) if (!FileName || !*FileName)
{ {
UiMessageBox("Boot sector file not specified for selected OS!"); UiMessageBox("Boot sector file not specified for selected OS!");
return EINVAL; return EINVAL;
} }
FileId = FsOpenFile(FileName); /* Open the boot sector file */
if (!FileId) Status = FsOpenFile(FileName, BootPath, OpenReadOnly, &FileId);
if (Status != ESUCCESS)
{ {
UiMessageBox("%s not found.", FileName); UiMessageBox("Unable to open %s", FileName);
return ENOENT; return Status;
} }
/* Read boot sector */ /* Now try to load the boot sector. If this fails then abort. */
Status = ArcRead(FileId, (PVOID)0x7c00, 512, &BytesRead); Status = ArcRead(FileId, (PVOID)0x7c00, 512, &BytesRead);
ArcClose(FileId); ArcClose(FileId);
if ((Status != ESUCCESS) || (BytesRead != 512)) if ((Status != ESUCCESS) || (BytesRead != 512))
{ {
UiMessageBox("Unable to read boot sector."); UiMessageBox("Unable to load boot sector.");
return EIO; return EIO;
} }
@ -92,27 +137,51 @@ LoadAndBootBootSector(
static ARC_STATUS static ARC_STATUS
LoadAndBootPartitionOrDrive( LoadAndBootPartitionOrDrive(
IN UCHAR DriveNumber, IN UCHAR DriveNumber,
IN ULONG PartitionNumber OPTIONAL) IN ULONG PartitionNumber OPTIONAL,
IN PCSTR BootPath OPTIONAL)
{ {
ARC_STATUS Status; ARC_STATUS Status;
ULONG FileId; ULONG FileId;
ULONG BytesRead; ULONG BytesRead;
CHAR ArcPath[MAX_PATH]; CHAR ArcPath[MAX_PATH];
/* Construct the corresponding ARC path */ /*
ConstructArcPath(ArcPath, "", DriveNumber, PartitionNumber); * If the user specifies an ARC "BootPath" value, it takes precedence
*strrchr(ArcPath, '\\') = ANSI_NULL; // Trim the trailing path separator. * 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 */ /* Open the volume */
Status = ArcOpen(ArcPath, OpenReadOnly, &FileId); Status = ArcOpen((PSTR)BootPath, OpenReadOnly, &FileId);
if (Status != ESUCCESS) if (Status != ESUCCESS)
{ {
UiMessageBox("Unable to open %s", ArcPath); UiMessageBox("Unable to open %s", BootPath);
return ENOENT; 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. * If this fails then abort.
*/ */
Status = ArcRead(FileId, (PVOID)0x7c00, 512, &BytesRead); Status = ArcRead(FileId, (PVOID)0x7c00, 512, &BytesRead);
@ -120,9 +189,9 @@ LoadAndBootPartitionOrDrive(
if ((Status != ESUCCESS) || (BytesRead != 512)) if ((Status != ESUCCESS) || (BytesRead != 512))
{ {
if (PartitionNumber != 0) if (PartitionNumber != 0)
UiMessageBox("Unable to read partition's boot sector."); UiMessageBox("Unable to load partition's boot sector.");
else else
UiMessageBox("Unable to read MBR boot sector."); UiMessageBox("Unable to load MBR boot sector.");
return EIO; return EIO;
} }
@ -160,31 +229,39 @@ LoadAndBootPartition(
IN PCHAR Envp[]) IN PCHAR Envp[])
{ {
PCSTR ArgValue; PCSTR ArgValue;
UCHAR DriveNumber; PCSTR BootPath;
ULONG PartitionNumber; UCHAR DriveNumber = 0;
ULONG PartitionNumber = 0;
/* Find all the message box settings and run them */ /* Find all the message box settings and run them */
UiShowMessageBoxesInArgv(Argc, Argv); UiShowMessageBoxesInArgv(Argc, Argv);
/* Read the boot drive */ /*
ArgValue = GetArgumentValue(Argc, Argv, "BootDrive"); * Check whether we have a "BootPath" value (takes precedence
if (!ArgValue) * over both "BootDrive" and "BootPartition").
*/
BootPath = GetArgumentValue(Argc, Argv, "BootPath");
if (!BootPath || !*BootPath)
{ {
UiMessageBox("Boot drive not specified for selected OS!"); /* We don't have one */
return EINVAL;
}
DriveNumber = DriveMapGetBiosDriveNumber(ArgValue);
/* Read the boot partition */ /* Retrieve the boot drive */
ArgValue = GetArgumentValue(Argc, Argv, "BootPartition"); ArgValue = GetArgumentValue(Argc, Argv, "BootDrive");
if (!ArgValue) if (!ArgValue || !*ArgValue)
{ {
UiMessageBox("Boot partition not specified for selected OS!"); UiMessageBox("Boot drive not specified for selected OS!");
return EINVAL; return EINVAL;
} }
PartitionNumber = atoi(ArgValue); 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 ARC_STATUS
@ -194,21 +271,39 @@ LoadAndBootDrive(
IN PCHAR Envp[]) IN PCHAR Envp[])
{ {
PCSTR ArgValue; PCSTR ArgValue;
UCHAR DriveNumber; PCSTR BootPath;
UCHAR DriveNumber = 0;
/* Find all the message box settings and run them */ /* Find all the message box settings and run them */
UiShowMessageBoxesInArgv(Argc, Argv); UiShowMessageBoxesInArgv(Argc, Argv);
/* Read the boot drive */ /* Check whether we have a "BootPath" value (takes precedence over "BootDrive") */
ArgValue = GetArgumentValue(Argc, Argv, "BootDrive"); BootPath = GetArgumentValue(Argc, Argv, "BootPath");
if (!ArgValue) 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 #endif // _M_IX86

View file

@ -934,7 +934,7 @@ InfOpenFile(
// //
// Open the .inf file // Open the .inf file
// //
Status = ArcOpen((PCHAR)FileName, OpenReadOnly, &FileId); Status = ArcOpen((PSTR)FileName, OpenReadOnly, &FileId);
if (Status != ESUCCESS) if (Status != ESUCCESS)
{ {
return FALSE; return FALSE;

View file

@ -135,10 +135,12 @@ LoadReactOSSetup(
IN PCHAR Argv[], IN PCHAR Argv[],
IN PCHAR Envp[]) IN PCHAR Envp[])
{ {
ARC_STATUS Status;
PCSTR ArgValue; PCSTR ArgValue;
PCSTR SystemPartition;
PCHAR File; PCHAR File;
CHAR FileName[512]; CHAR FileName[MAX_PATH];
CHAR BootPath[512]; CHAR BootPath[MAX_PATH];
CHAR BootOptions2[256]; CHAR BootOptions2[256];
PCSTR LoadOptions; PCSTR LoadOptions;
PSTR BootOptions; PSTR BootOptions;
@ -165,6 +167,14 @@ LoadReactOSSetup(
NULL 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..."); UiDrawStatusText("Setup is loading...");
UiDrawBackdrop(); UiDrawBackdrop();
@ -180,13 +190,12 @@ LoadReactOSSetup(
else else
{ {
/* /*
* IMPROVE: I don't want to call MachDiskGetBootPath here as a * IMPROVE: I don't want to use the SystemPartition here as a
* default choice because I can call it after (see few lines below). * 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 * Instead I reset BootPath here so that we can build the full path
* using the general code from below. * using the general code from below.
*/ */
// MachDiskGetBootPath(BootPath, sizeof(BootPath)); // RtlStringCbCopyA(BootPath, sizeof(BootPath), SystemPartition);
// RtlStringCbCopyA(BootPath, sizeof(BootPath), ArgValue);
*BootPath = ANSI_NULL; *BootPath = ANSI_NULL;
} }
@ -201,8 +210,8 @@ LoadReactOSSetup(
/* Temporarily save the boot path */ /* Temporarily save the boot path */
RtlStringCbCopyA(FileName, sizeof(FileName), BootPath); RtlStringCbCopyA(FileName, sizeof(FileName), BootPath);
/* This is not a full path. Use the current (i.e. boot) device. */ /* This is not a full path: prepend the SystemPartition */
MachDiskGetBootPath(BootPath, sizeof(BootPath)); RtlStringCbCopyA(BootPath, sizeof(BootPath), SystemPartition);
/* Append a path separator if needed */ /* Append a path separator if needed */
if (*FileName != '\\' && *FileName != '/') if (*FileName != '\\' && *FileName != '/')
@ -212,7 +221,7 @@ LoadReactOSSetup(
RtlStringCbCatA(BootPath, sizeof(BootPath), FileName); RtlStringCbCatA(BootPath, sizeof(BootPath), FileName);
} }
/* Append a backslash if needed */ /* Append a path separator if needed */
if (!*BootPath || BootPath[strlen(BootPath) - 1] != '\\') if (!*BootPath || BootPath[strlen(BootPath) - 1] != '\\')
RtlStringCbCatA(BootPath, sizeof(BootPath), "\\"); RtlStringCbCatA(BootPath, sizeof(BootPath), "\\");
@ -221,7 +230,7 @@ LoadReactOSSetup(
/* Retrieve the boot options */ /* Retrieve the boot options */
*BootOptions2 = ANSI_NULL; *BootOptions2 = ANSI_NULL;
ArgValue = GetArgumentValue(Argc, Argv, "Options"); ArgValue = GetArgumentValue(Argc, Argv, "Options");
if (ArgValue) if (ArgValue && *ArgValue)
RtlStringCbCopyA(BootOptions2, sizeof(BootOptions2), ArgValue); RtlStringCbCopyA(BootOptions2, sizeof(BootOptions2), ArgValue);
TRACE("BootOptions: '%s'\n", BootOptions2); TRACE("BootOptions: '%s'\n", BootOptions2);
@ -237,10 +246,11 @@ LoadReactOSSetup(
*strstr(FileName, " ") = ANSI_NULL; *strstr(FileName, " ") = ANSI_NULL;
/* Load the ramdisk */ /* Load the ramdisk */
if (!RamDiskLoadVirtualFile(FileName)) Status = RamDiskLoadVirtualFile(FileName, SystemPartition);
if (Status != ESUCCESS)
{ {
UiMessageBox("Failed to load RAM disk file %s", FileName); UiMessageBox("Failed to load RAM disk file %s", FileName);
return ENOENT; return Status;
} }
} }
@ -292,7 +302,7 @@ LoadReactOSSetup(
} }
#endif #endif
/* Copy loadoptions (original string will be freed) */ /* Copy LoadOptions (original string will be freed) */
BootOptions = FrLdrTempAlloc(strlen(LoadOptions) + 1, TAG_BOOT_OPTIONS); BootOptions = FrLdrTempAlloc(strlen(LoadOptions) + 1, TAG_BOOT_OPTIONS);
ASSERT(BootOptions); ASSERT(BootOptions);
strcpy(BootOptions, LoadOptions); strcpy(BootOptions, LoadOptions);

View file

@ -65,11 +65,13 @@ WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock,
PCSTR BootPath, PCSTR BootPath,
USHORT VersionToBoot) USHORT VersionToBoot)
{ {
/* Examples of correct options and paths */ /*
//CHAR Options[] = "/DEBUGPORT=COM1 /BAUDRATE=115200"; * Examples of correct options and paths:
//CHAR Options[] = "/NODEBUG"; * CHAR Options[] = "/DEBUGPORT=COM1 /BAUDRATE=115200";
//CHAR SystemRoot[] = "\\WINNT\\"; * CHAR Options[] = "/NODEBUG";
//CHAR ArcBoot[] = "multi(0)disk(0)rdisk(0)partition(1)"; * CHAR SystemRoot[] = "\\WINNT\\";
* CHAR ArcBoot[] = "multi(0)disk(0)rdisk(0)partition(1)";
*/
PSTR LoadOptions, NewLoadOptions; PSTR LoadOptions, NewLoadOptions;
CHAR HalPath[] = "\\"; CHAR HalPath[] = "\\";
@ -367,7 +369,7 @@ WinLdrLoadModule(PCSTR ModuleName,
*Size = 0; *Size = 0;
/* Open the image file */ /* Open the image file */
Status = ArcOpen((PCHAR)ModuleName, OpenReadOnly, &FileId); Status = ArcOpen((PSTR)ModuleName, OpenReadOnly, &FileId);
if (Status != ESUCCESS) if (Status != ESUCCESS)
{ {
/* In case of errors, we just return, without complaining to the user */ /* In case of errors, we just return, without complaining to the user */
@ -413,17 +415,16 @@ WinLdrDetectVersion(VOID)
LONG rc; LONG rc;
HKEY hKey; HKEY hKey;
rc = RegOpenKey( rc = RegOpenKey(NULL,
NULL, L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\Terminal Server",
L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\Terminal Server", &hKey);
&hKey);
if (rc != ERROR_SUCCESS) if (rc != ERROR_SUCCESS)
{ {
// Key doesn't exist; assume NT 4.0 /* Key doesn't exist; assume NT 4.0 */
return _WIN32_WINNT_NT4; 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; return _WIN32_WINNT_WS03;
} }
@ -483,8 +484,8 @@ LoadWindowsCore(IN USHORT OperatingSystemVersion,
BOOLEAN Success; BOOLEAN Success;
PCSTR Options; PCSTR Options;
CHAR DirPath[MAX_PATH]; CHAR DirPath[MAX_PATH];
CHAR KernelFileName[MAX_PATH];
CHAR HalFileName[MAX_PATH]; CHAR HalFileName[MAX_PATH];
CHAR KernelFileName[MAX_PATH];
CHAR KdTransportDllName[MAX_PATH]; CHAR KdTransportDllName[MAX_PATH];
PLDR_DATA_TABLE_ENTRY HalDTE, KdComDTE = NULL; PLDR_DATA_TABLE_ENTRY HalDTE, KdComDTE = NULL;
@ -494,25 +495,27 @@ LoadWindowsCore(IN USHORT OperatingSystemVersion,
RtlStringCbCopyA(DirPath, sizeof(DirPath), BootPath); RtlStringCbCopyA(DirPath, sizeof(DirPath), BootPath);
RtlStringCbCatA(DirPath, sizeof(DirPath), "system32\\"); RtlStringCbCatA(DirPath, sizeof(DirPath), "system32\\");
// /*
// TODO: Parse also the separate INI values "Kernel=" and "Hal=" * 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
/* Default KERNEL and HAL file names */ * https://www.geoffchappell.com/notes/windows/boot/bcd/osloader/hal.htm
RtlStringCbCopyA(KernelFileName, sizeof(KernelFileName), "ntoskrnl.exe"); * https://www.geoffchappell.com/notes/windows/boot/bcd/osloader/kernel.htm
*/
RtlStringCbCopyA(HalFileName , sizeof(HalFileName) , "hal.dll"); 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; Options = BootOptions;
while (Options) while (Options)
{ {
/* Skip possible initial whitespace */ /* Skip possible initial whitespace */
Options += strspn(Options, " \t"); 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, 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 */ /* Search for another whitespace */
Options = strpbrk(Options, " \t"); Options = strpbrk(Options, " \t");
@ -527,23 +530,23 @@ LoadWindowsCore(IN USHORT OperatingSystemVersion,
break; break;
} }
/* We have found either KERNEL or HAL options */ /* We have found either HAL or KERNEL options */
if (_strnicmp(Options, "KERNEL=", 7) == 0) if (_strnicmp(Options, "HAL=", 4) == 0)
{
Options += 7; i -= 7;
RtlStringCbCopyNA(KernelFileName, sizeof(KernelFileName), Options, i);
_strupr(KernelFileName);
}
else if (_strnicmp(Options, "HAL=", 4) == 0)
{ {
Options += 4; i -= 4; Options += 4; i -= 4;
RtlStringCbCopyNA(HalFileName, sizeof(HalFileName), Options, i); RtlStringCbCopyNA(HalFileName, sizeof(HalFileName), Options, i);
_strupr(HalFileName); _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 */ /* Load the Kernel */
LoadModule(LoaderBlock, DirPath, KernelFileName, "ntoskrnl.exe", LoaderSystemCode, KernelDTE, 30); LoadModule(LoaderBlock, DirPath, KernelFileName, "ntoskrnl.exe", LoaderSystemCode, KernelDTE, 30);
@ -653,7 +656,9 @@ LoadAndBootWindows(
IN PCHAR Argv[], IN PCHAR Argv[],
IN PCHAR Envp[]) IN PCHAR Envp[])
{ {
ARC_STATUS Status;
PCSTR ArgValue; PCSTR ArgValue;
PCSTR SystemPartition;
PCHAR File; PCHAR File;
BOOLEAN Success; BOOLEAN Success;
USHORT OperatingSystemVersion; USHORT OperatingSystemVersion;
@ -662,13 +667,15 @@ LoadAndBootWindows(
CHAR FileName[MAX_PATH]; CHAR FileName[MAX_PATH];
CHAR BootOptions[256]; CHAR BootOptions[256];
/* Retrieve the (mandatory) boot type */
ArgValue = GetArgumentValue(Argc, Argv, "BootType"); ArgValue = GetArgumentValue(Argc, Argv, "BootType");
if (!ArgValue) if (!ArgValue || !*ArgValue)
{ {
ERR("No 'BootType' value, aborting!\n"); ERR("No 'BootType' value, aborting!\n");
return EINVAL; return EINVAL;
} }
/* Convert it to an OS version */
if (_stricmp(ArgValue, "Windows") == 0 || if (_stricmp(ArgValue, "Windows") == 0 ||
_stricmp(ArgValue, "Windows2003") == 0) _stricmp(ArgValue, "Windows2003") == 0)
{ {
@ -684,6 +691,14 @@ LoadAndBootWindows(
return EINVAL; return EINVAL;
} }
/* Retrieve the (mandatory) system partition */
SystemPartition = GetArgumentValue(Argc, Argv, "SystemPartition");
if (!SystemPartition || !*SystemPartition)
{
ERR("No 'SystemPartition' specified, aborting!\n");
return EINVAL;
}
UiDrawBackdrop(); UiDrawBackdrop();
UiDrawProgressBarCenter(1, 100, "Loading NT..."); UiDrawProgressBarCenter(1, 100, "Loading NT...");
@ -704,8 +719,8 @@ LoadAndBootWindows(
/* Temporarily save the boot path */ /* Temporarily save the boot path */
RtlStringCbCopyA(FileName, sizeof(FileName), BootPath); RtlStringCbCopyA(FileName, sizeof(FileName), BootPath);
/* This is not a full path. Use the current (i.e. boot) device. */ /* This is not a full path: prepend the SystemPartition */
MachDiskGetBootPath(BootPath, sizeof(BootPath)); RtlStringCbCopyA(BootPath, sizeof(BootPath), SystemPartition);
/* Append a path separator if needed */ /* Append a path separator if needed */
if (*FileName != '\\' && *FileName != '/') if (*FileName != '\\' && *FileName != '/')
@ -715,7 +730,7 @@ LoadAndBootWindows(
RtlStringCbCatA(BootPath, sizeof(BootPath), FileName); RtlStringCbCatA(BootPath, sizeof(BootPath), FileName);
} }
/* Append a backslash if needed */ /* Append a path separator if needed */
if (!*BootPath || BootPath[strlen(BootPath) - 1] != '\\') if (!*BootPath || BootPath[strlen(BootPath) - 1] != '\\')
RtlStringCbCatA(BootPath, sizeof(BootPath), "\\"); RtlStringCbCatA(BootPath, sizeof(BootPath), "\\");
@ -724,12 +739,45 @@ LoadAndBootWindows(
/* Retrieve the boot options */ /* Retrieve the boot options */
*BootOptions = ANSI_NULL; *BootOptions = ANSI_NULL;
ArgValue = GetArgumentValue(Argc, Argv, "Options"); ArgValue = GetArgumentValue(Argc, Argv, "Options");
if (ArgValue) if (ArgValue && *ArgValue)
RtlStringCbCopyA(BootOptions, sizeof(BootOptions), ArgValue); RtlStringCbCopyA(BootOptions, sizeof(BootOptions), ArgValue);
/* Append boot-time options */ /* Append boot-time options */
AppendBootTimeOptions(BootOptions); 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); TRACE("BootOptions: '%s'\n", BootOptions);
/* Check if a ramdisk file was given */ /* Check if a ramdisk file was given */
@ -743,10 +791,11 @@ LoadAndBootWindows(
*strstr(FileName, " ") = ANSI_NULL; *strstr(FileName, " ") = ANSI_NULL;
/* Load the ramdisk */ /* Load the ramdisk */
if (!RamDiskLoadVirtualFile(FileName)) Status = RamDiskLoadVirtualFile(FileName, SystemPartition);
if (Status != ESUCCESS)
{ {
UiMessageBox("Failed to load RAM disk file %s", FileName); UiMessageBox("Failed to load RAM disk file %s", FileName);
return ENOENT; return Status;
} }
} }

View file

@ -20,8 +20,8 @@
/* INCLUDES *******************************************************************/ /* INCLUDES *******************************************************************/
#include <freeldr.h> #include <freeldr.h>
#include <debug.h>
#include <debug.h>
DBG_DEFAULT_CHANNEL(INIFILE); DBG_DEFAULT_CHANNEL(INIFILE);
#define TAG_OS_ITEM 'tISO' #define TAG_OS_ITEM 'tISO'
@ -42,49 +42,16 @@ static PCSTR CopyString(PCSTR Source)
return Dest; 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* OperatingSystemItem*
InitOperatingSystemList( InitOperatingSystemList(
IN ULONG_PTR FrLdrSectionId,
OUT PULONG OperatingSystemCount, OUT PULONG OperatingSystemCount,
OUT PULONG DefaultOperatingSystem) OUT PULONG DefaultOperatingSystem)
{ {
ULONG DefaultOS = 0;
PCSTR DefaultOSName = NULL;
CHAR DefaultOSText[80];
OperatingSystemItem* Items; OperatingSystemItem* Items;
ULONG Count; ULONG Count;
ULONG i; ULONG i;
@ -110,7 +77,18 @@ InitOperatingSystemList(
if (!Items) if (!Items)
return NULL; 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) for (i = 0; i < Count; ++i)
{ {
IniReadSettingByNumber(OsSectionId, i, IniReadSettingByNumber(OsSectionId, i,
@ -118,7 +96,7 @@ InitOperatingSystemList(
SettingValue, sizeof(SettingValue)); SettingValue, sizeof(SettingValue));
if (!*SettingName) if (!*SettingName)
{ {
ERR("Invalid OS entry number %lu, skipping.\n", i); ERR("Invalid OS entry %lu, skipping.\n", i);
continue; continue;
} }
@ -151,6 +129,13 @@ InitOperatingSystemList(
// "OsLoadOptions = '%s'\n", // "OsLoadOptions = '%s'\n",
// SettingName, TitleStart, OsLoadOptions); // 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: * 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 */ /* Try to open the operating system section in the .ini file */
SectionId = 0;
HadSection = IniOpenSection(SettingName, &SectionId); HadSection = IniOpenSection(SettingName, &SectionId);
if (HadSection) if (HadSection)
{ {
@ -192,7 +178,7 @@ InitOperatingSystemList(
{ {
#ifdef _M_IX86 #ifdef _M_IX86
ULONG FileId; ULONG FileId;
if (ArcOpen((PSTR)SettingName, OpenReadOnly, &FileId) == ESUCCESS) if (ArcOpen(SettingName, OpenReadOnly, &FileId) == ESUCCESS)
{ {
ArcClose(FileId); ArcClose(FileId);
strcpy(BootType, "BootSector"); strcpy(BootType, "BootSector");
@ -236,7 +222,7 @@ InitOperatingSystemList(
/* Add the section */ /* Add the section */
if (!IniAddSection(SettingName, &SectionId)) 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; continue;
} }
@ -245,7 +231,7 @@ InitOperatingSystemList(
{ {
if (!IniAddSettingValueToSection(SectionId, "BootSectorFile", TempBuffer)) 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; continue;
} }
} }
@ -253,7 +239,7 @@ InitOperatingSystemList(
{ {
if (!IniAddSettingValueToSection(SectionId, "SystemPath", TempBuffer)) 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; continue;
} }
} }
@ -265,7 +251,7 @@ InitOperatingSystemList(
/* Add the OS options */ /* Add the OS options */
if (OsLoadOptions && !IniAddSettingValueToSection(SectionId, "Options", OsLoadOptions)) 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; continue;
} }
} }
@ -296,14 +282,15 @@ InitOperatingSystemList(
ERR("Could not modify the options for OS '%s', ignoring.\n", SettingName); ERR("Could not modify the options for OS '%s', ignoring.\n", SettingName);
} }
/* Copy the OS section name and identifier */ /* Copy the OS section ID and its identifier */
Items[i].SectionName = CopyString(SettingName); Items[i].SectionId = SectionId;
Items[i].LoadIdentifier = CopyString(TitleStart); 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 */ /* Return success */
*OperatingSystemCount = Count; *OperatingSystemCount = Count;
*DefaultOperatingSystem = GetDefaultOperatingSystem(Items, Count); *DefaultOperatingSystem = DefaultOS;
return Items; return Items;
} }

View file

@ -10,7 +10,6 @@
/* INCLUDES *******************************************************************/ /* INCLUDES *******************************************************************/
#include <freeldr.h> #include <freeldr.h>
#include <debug.h>
/* GLOBALS ********************************************************************/ /* GLOBALS ********************************************************************/
@ -252,7 +251,8 @@ UiDrawProgressBar(IN ULONG Left,
} }
VOID VOID
UiShowMessageBoxesInSection(IN PCSTR SectionName) UiShowMessageBoxesInSection(
IN ULONG_PTR SectionId)
{ {
return; return;
} }
@ -270,7 +270,8 @@ UiTruncateStringEllipsis(IN PCHAR StringText,
IN ULONG MaxChars) IN ULONG MaxChars)
{ {
/* If it's too large, just add some ellipsis past the maximum */ /* 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 VOID

View file

@ -22,7 +22,7 @@
#define TAG_TUI_SCREENBUFFER 'SiuT' #define TAG_TUI_SCREENBUFFER 'SiuT'
#define TAG_TAG_TUI_PALETTE 'PiuT' #define TAG_TAG_TUI_PALETTE 'PiuT'
PVOID TextVideoBuffer = NULL; PVOID TextVideoBuffer = NULL;
/* /*
* TuiPrintf() * TuiPrintf()
@ -699,55 +699,58 @@ VOID TuiDrawProgressBar(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, ULONG
UCHAR TuiTextToColor(PCSTR ColorText) UCHAR TuiTextToColor(PCSTR ColorText)
{ {
if (_stricmp(ColorText, "Black") == 0) static const struct
return COLOR_BLACK; {
else if (_stricmp(ColorText, "Blue") == 0) PCSTR ColorName;
return COLOR_BLUE; UCHAR ColorValue;
else if (_stricmp(ColorText, "Green") == 0) } Colors[] =
return COLOR_GREEN; {
else if (_stricmp(ColorText, "Cyan") == 0) {"Black" , COLOR_BLACK },
return COLOR_CYAN; {"Blue" , COLOR_BLUE },
else if (_stricmp(ColorText, "Red") == 0) {"Green" , COLOR_GREEN },
return COLOR_RED; {"Cyan" , COLOR_CYAN },
else if (_stricmp(ColorText, "Magenta") == 0) {"Red" , COLOR_RED },
return COLOR_MAGENTA; {"Magenta", COLOR_MAGENTA},
else if (_stricmp(ColorText, "Brown") == 0) {"Brown" , COLOR_BROWN },
return COLOR_BROWN; {"Gray" , COLOR_GRAY },
else if (_stricmp(ColorText, "Gray") == 0) {"DarkGray" , COLOR_DARKGRAY },
return COLOR_GRAY; {"LightBlue" , COLOR_LIGHTBLUE },
else if (_stricmp(ColorText, "DarkGray") == 0) {"LightGreen" , COLOR_LIGHTGREEN },
return COLOR_DARKGRAY; {"LightCyan" , COLOR_LIGHTCYAN },
else if (_stricmp(ColorText, "LightBlue") == 0) {"LightRed" , COLOR_LIGHTRED },
return COLOR_LIGHTBLUE; {"LightMagenta", COLOR_LIGHTMAGENTA},
else if (_stricmp(ColorText, "LightGreen") == 0) {"Yellow" , COLOR_YELLOW },
return COLOR_LIGHTGREEN; {"White" , COLOR_WHITE },
else if (_stricmp(ColorText, "LightCyan") == 0) };
return COLOR_LIGHTCYAN; ULONG i;
else if (_stricmp(ColorText, "LightRed") == 0)
return COLOR_LIGHTRED; for (i = 0; i < sizeof(Colors)/sizeof(Colors[0]); ++i)
else if (_stricmp(ColorText, "LightMagenta") == 0) {
return COLOR_LIGHTMAGENTA; if (_stricmp(ColorText, Colors[i].ColorName) == 0)
else if (_stricmp(ColorText, "Yellow") == 0) return Colors[i].ColorValue;
return COLOR_YELLOW; }
else if (_stricmp(ColorText, "White") == 0)
return COLOR_WHITE;
return COLOR_BLACK; return COLOR_BLACK;
} }
UCHAR TuiTextToFillStyle(PCSTR FillStyleText) UCHAR TuiTextToFillStyle(PCSTR FillStyleText)
{ {
if (_stricmp(FillStyleText, "Light") == 0) static const struct
{ {
return LIGHT_FILL; PCSTR FillStyleName;
} UCHAR FillStyleValue;
else if (_stricmp(FillStyleText, "Medium") == 0) } FillStyles[] =
{ {
return MEDIUM_FILL; {"Light" , LIGHT_FILL },
} {"Medium", MEDIUM_FILL},
else if (_stricmp(FillStyleText, "Dark") == 0) {"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; return LIGHT_FILL;

View file

@ -19,41 +19,41 @@
#ifndef _M_ARM #ifndef _M_ARM
#include <freeldr.h> #include <freeldr.h>
#include <debug.h> #include <debug.h>
DBG_DEFAULT_CHANNEL(UI);
#define TAG_UI_TEXT 'xTiU' #define TAG_UI_TEXT 'xTiU'
DBG_DEFAULT_CHANNEL(UI); ULONG UiScreenWidth; // Screen Width
ULONG UiScreenHeight; // Screen Height
ULONG UiScreenWidth; // Screen Width UCHAR UiStatusBarFgColor = COLOR_BLACK; // Status bar foreground color
ULONG UiScreenHeight; // Screen Height 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 CHAR UiTitleBoxTitleText[260] = "Boot Menu"; // Title box's title text
UCHAR UiStatusBarBgColor = COLOR_CYAN; // Status bar background color
UCHAR UiBackdropFgColor = COLOR_WHITE; // Backdrop foreground color
UCHAR UiBackdropBgColor = COLOR_BLUE; // Backdrop background color
UCHAR UiBackdropFillStyle = MEDIUM_FILL; // Backdrop fill style
UCHAR UiTitleBoxFgColor = COLOR_WHITE; // Title box foreground color
UCHAR UiTitleBoxBgColor = COLOR_RED; // Title box background color
UCHAR UiMessageBoxFgColor = COLOR_WHITE; // Message box foreground color
UCHAR UiMessageBoxBgColor = COLOR_BLUE; // Message box background color
UCHAR UiMenuFgColor = COLOR_WHITE; // Menu foreground color
UCHAR UiMenuBgColor = COLOR_BLUE; // Menu background color
UCHAR UiTextColor = COLOR_YELLOW; // Normal text color
UCHAR UiSelectedTextColor = COLOR_BLACK; // Selected text color
UCHAR UiSelectedTextBgColor = COLOR_GRAY; // Selected text background color
UCHAR UiEditBoxTextColor = COLOR_WHITE; // Edit box text color
UCHAR UiEditBoxBgColor = COLOR_BLACK; // Edit box text background color
CHAR UiTitleBoxTitleText[260] = "Boot Menu"; // Title box's title text BOOLEAN UiUseSpecialEffects = FALSE; // Tells us if we should use fade effects
BOOLEAN UiDrawTime = TRUE; // Tells us if we should draw the time
BOOLEAN UiUseSpecialEffects = FALSE; // Tells us if we should use fade effects BOOLEAN UiCenterMenu = TRUE; // Tells us if we should use a centered or left-aligned menu
BOOLEAN UiDrawTime = TRUE; // Tells us if we should draw the time BOOLEAN UiMenuBox = TRUE; // Tells us if we should draw a box around the menu
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: ] "; 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 = UIVTBL UiVtbl =
{ {
@ -83,12 +83,11 @@ UIVTBL UiVtbl =
BOOLEAN UiInitialize(BOOLEAN ShowGui) BOOLEAN UiInitialize(BOOLEAN ShowGui)
{ {
VIDEODISPLAYMODE UiDisplayMode; // Tells us if we are in text or graphics mode 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 BOOLEAN UiMinimal = FALSE; // Tells us if we are using a minimal console-like UI
ULONG_PTR SectionId; ULONG_PTR SectionId;
CHAR DisplayModeText[260]; ULONG Depth;
CHAR SettingText[260]; CHAR SettingText[260];
ULONG Depth;
if (!ShowGui) if (!ShowGui)
{ {
@ -101,25 +100,28 @@ BOOLEAN UiInitialize(BOOLEAN ShowGui)
} }
TRACE("Initializing User Interface.\n"); 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'; /* Open the [Display] section */
if (IniOpenSection("Display", &SectionId)) 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))) SettingText[0] = '\0';
{
DisplayModeText[0] = '\0';
}
if (IniReadSettingByName(SectionId, "MinimalUI", SettingText, sizeof(SettingText)))
{
UiMinimal = (_stricmp(SettingText, "Yes") == 0 && strlen(SettingText) == 3);
}
} }
UiDisplayMode = MachVideoSetDisplayMode(SettingText, TRUE);
UiDisplayMode = MachVideoSetDisplayMode(DisplayModeText, TRUE);
MachVideoGetDisplaySize(&UiScreenWidth, &UiScreenHeight, &Depth); 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); UiVtbl = (UiMinimal ? MiniTuiVtbl : TuiVtbl);
else else
UiVtbl = GuiVtbl; UiVtbl = GuiVtbl;
@ -130,99 +132,70 @@ BOOLEAN UiInitialize(BOOLEAN ShowGui)
return FALSE; 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); PCSTR SettingName;
} PVOID SettingVar;
if (IniReadSettingByName(SectionId, "TimeText", SettingText, sizeof(SettingText))) UCHAR SettingType; // 0: Text, 1: Yes/No, 2: Color, 3: Fill style
} Settings[] =
{ {
strcpy(UiTimeText, SettingText); {"TitleText", &UiTitleBoxTitleText, 0},
} {"TimeText" , &UiTimeText , 0},
if (IniReadSettingByName(SectionId, "StatusBarColor", SettingText, sizeof(SettingText)))
{"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, Settings[i].SettingName, SettingText, sizeof(SettingText)))
} continue;
if (IniReadSettingByName(SectionId, "StatusBarTextColor", SettingText, sizeof(SettingText)))
{ switch (Settings[i].SettingType)
UiStatusBarFgColor = UiTextToColor(SettingText); {
} case 0: // Text
if (IniReadSettingByName(SectionId, "BackdropTextColor", SettingText, sizeof(SettingText))) strcpy((PCHAR)Settings[i].SettingVar, SettingText);
{ break;
UiBackdropFgColor = UiTextToColor(SettingText); case 1: // Yes/No
} *(PBOOLEAN)Settings[i].SettingVar = (_stricmp(SettingText, "Yes") == 0 && strlen(SettingText) == 3);
if (IniReadSettingByName(SectionId, "BackdropColor", SettingText, sizeof(SettingText))) break;
{ case 2: // Color
UiBackdropBgColor = UiTextToColor(SettingText); *(PUCHAR)Settings[i].SettingVar = UiTextToColor(SettingText);
} break;
if (IniReadSettingByName(SectionId, "BackdropFillStyle", SettingText, sizeof(SettingText))) case 3: // Fill style
{ *(PUCHAR)Settings[i].SettingVar = UiTextToFillStyle(SettingText);
UiBackdropFillStyle = UiTextToFillStyle(SettingText); break;
} default:
if (IniReadSettingByName(SectionId, "TitleBoxTextColor", SettingText, sizeof(SettingText))) break;
{ }
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);
} }
} }
// 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(); UiFadeInBackdrop();
TRACE("UiInitialize() returning TRUE.\n"); 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); UiVtbl.DrawProgressBar(Left, Top, Right, Bottom, Position, Range, ProgressText);
} }
VOID UiShowMessageBoxesInSection(PCSTR SectionName) VOID
UiShowMessageBoxesInSection(
IN ULONG_PTR SectionId)
{ {
ULONG Idx; ULONG Idx;
CHAR SettingName[80]; CHAR SettingName[80];
CHAR SettingValue[80]; CHAR SettingValue[80];
PCHAR MessageBoxText; PCHAR MessageBoxText;
ULONG MessageBoxTextSize; ULONG MessageBoxTextSize;
ULONG_PTR SectionId;
if (!IniOpenSection(SectionName, &SectionId)) if (SectionId == 0)
{
return; return;
}
// /* Find all the message box settings and run them */
// Find all the message box settings and run them for (Idx = 0; Idx < IniGetNumSectionItems(SectionId); Idx++)
//
for (Idx=0; Idx<IniGetNumSectionItems(SectionId); Idx++)
{ {
IniReadSettingByNumber(SectionId, Idx, SettingName, sizeof(SettingName), SettingValue, sizeof(SettingValue)); 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 // if (MessageBoxTextSize <= 0)
MessageBoxTextSize = IniGetSectionSettingValueSize(SectionId, Idx); // continue;
//if (MessageBoxTextSize > 0) /* Allocate enough memory to hold the text */
{ MessageBoxText = FrLdrTempAlloc(MessageBoxTextSize, TAG_UI_TEXT);
// Allocate enough memory to hold the text if (!MessageBoxText)
MessageBoxText = FrLdrTempAlloc(MessageBoxTextSize, TAG_UI_TEXT); 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 /* Fix it up */
UiEscapeString(MessageBoxText); UiEscapeString(MessageBoxText);
// Display it /* Display it */
UiMessageBox(MessageBoxText); UiMessageBox(MessageBoxText);
// Free the memory /* Free the memory */
FrLdrTempFree(MessageBoxText, TAG_UI_TEXT); FrLdrTempFree(MessageBoxText, TAG_UI_TEXT);
}
}
}
} }
} }
@ -450,20 +417,20 @@ UiShowMessageBoxesInArgv(
/* Allocate enough memory to hold the text */ /* Allocate enough memory to hold the text */
MessageBoxText = FrLdrTempAlloc(MessageBoxTextSize, TAG_UI_TEXT); MessageBoxText = FrLdrTempAlloc(MessageBoxTextSize, TAG_UI_TEXT);
if (MessageBoxText) if (!MessageBoxText)
{ continue;
/* Get the MessageBox text */
strcpy(MessageBoxText, ArgValue);
/* Fix it up */ /* Get the MessageBox text */
UiEscapeString(MessageBoxText); strcpy(MessageBoxText, ArgValue);
/* Display it */ /* Fix it up */
UiMessageBox(MessageBoxText); UiEscapeString(MessageBoxText);
/* Free the memory */ /* Display it */
FrLdrTempFree(MessageBoxText, TAG_UI_TEXT); UiMessageBox(MessageBoxText);
}
/* Free the memory */
FrLdrTempFree(MessageBoxText, TAG_UI_TEXT);
} }
} }
@ -487,10 +454,9 @@ VOID UiEscapeString(PCHAR String)
VOID UiTruncateStringEllipsis(PCHAR StringText, ULONG MaxChars) VOID UiTruncateStringEllipsis(PCHAR StringText, ULONG MaxChars)
{ {
/* If it's too large, just add some ellipsis past the maximum */
if (strlen(StringText) > MaxChars) if (strlen(StringText) > MaxChars)
{
strcpy(&StringText[MaxChars - 3], "..."); strcpy(&StringText[MaxChars - 3], "...");
}
} }
BOOLEAN BOOLEAN