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

View File

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

View File

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

View File

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

View File

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

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 BootPartitionPrompt[] = "Enter the boot partition.\n\nEnter 0 for the active (bootable) partition.";
const CHAR ARCPathPrompt[] = "Enter the boot ARC path.\n\nExamples:\nmulti(0)disk(0)rdisk(0)partition(1)\nmulti(0)disk(0)fdisk(0)";
const CHAR ReactOSSystemPathPrompt[] = "Enter the path to your ReactOS system directory.\n\nExamples:\n\\REACTOS\n\\ROS";
const CHAR ReactOSOptionsPrompt[] = "Enter the options you want passed to the kernel.\n\nExamples:\n/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200\n/FASTDETECT /SOS /NOGUIBOOT\n/BASEVIDEO /MAXMEM=64\n/KERNEL=NTKRNLMP.EXE /HAL=HALMPS.DLL";
const CHAR CustomBootPrompt[] = "Press ENTER to boot your custom boot setup.";
@ -55,6 +56,7 @@ VOID OptionMenuCustomBoot(VOID)
"ReactOS Setup"
};
ULONG SelectedMenuItem;
OperatingSystemItem OperatingSystem;
if (!UiDisplayMenu("Please choose a boot method:", NULL,
FALSE,
@ -69,65 +71,111 @@ VOID OptionMenuCustomBoot(VOID)
return;
}
/* Initialize a new custom OS entry */
OperatingSystem.SectionId = 0;
switch (SelectedMenuItem)
{
#ifdef _M_IX86
case 0: // Disk
EditCustomBootDisk(0);
EditCustomBootDisk(&OperatingSystem);
break;
case 1: // Partition
EditCustomBootPartition(0);
EditCustomBootPartition(&OperatingSystem);
break;
case 2: // Boot Sector File
EditCustomBootSectorFile(0);
EditCustomBootSectorFile(&OperatingSystem);
break;
case 3: // Linux
EditCustomBootLinux(0);
EditCustomBootLinux(&OperatingSystem);
break;
case 4: // ReactOS
EditCustomBootReactOS(0, FALSE);
EditCustomBootReactOS(&OperatingSystem, FALSE);
break;
case 5: // ReactOS Setup
EditCustomBootReactOS(0, TRUE);
EditCustomBootReactOS(&OperatingSystem, TRUE);
break;
#else
case 0: // ReactOS
EditCustomBootReactOS(0, FALSE);
EditCustomBootReactOS(&OperatingSystem, FALSE);
break;
case 1: // ReactOS Setup
EditCustomBootReactOS(0, TRUE);
EditCustomBootReactOS(&OperatingSystem, TRUE);
break;
#endif
}
/* And boot it */
if (OperatingSystem.SectionId != 0)
{
UiMessageBox(CustomBootPrompt);
LoadOperatingSystem(&OperatingSystem);
}
}
#endif // HAS_OPTION_MENU_CUSTOM_BOOT
#ifdef _M_IX86
VOID EditCustomBootDisk(IN ULONG_PTR SectionId OPTIONAL)
VOID
EditCustomBootDisk(
IN OUT OperatingSystemItem* OperatingSystem)
{
TIMEINFO* TimeInfo;
OperatingSystemItem OperatingSystem;
ULONG_PTR SectionId = OperatingSystem->SectionId;
CHAR SectionName[100];
CHAR BootDriveString[20];
/* The following is a trick for saving some stack space */
union
{
struct
{
CHAR Guard1;
CHAR Drive[20];
CHAR Guard2;
};
CHAR ArcPath[200];
} BootStrings;
RtlZeroMemory(SectionName, sizeof(SectionName));
RtlZeroMemory(BootDriveString, sizeof(BootDriveString));
RtlZeroMemory(&BootStrings, sizeof(BootStrings));
if (SectionId != 0)
{
/* Load the settings */
IniReadSettingByName(SectionId, "BootDrive", BootDriveString, sizeof(BootDriveString));
/* Check whether we have a "BootPath" value (takes precedence over "BootDrive") */
*BootStrings.ArcPath = ANSI_NULL;
IniReadSettingByName(SectionId, "BootPath", BootStrings.ArcPath, sizeof(BootStrings.ArcPath));
if (!*BootStrings.ArcPath)
{
/* We don't, retrieve the boot drive value instead */
IniReadSettingByName(SectionId, "BootDrive", BootStrings.Drive, sizeof(BootStrings.Drive));
}
}
if (!UiEditBox(BootDrivePrompt, BootDriveString, sizeof(BootDriveString)))
return;
if (!*BootStrings.ArcPath)
{
if (!UiEditBox(BootDrivePrompt, BootStrings.Drive, sizeof(BootStrings.Drive)))
return;
}
if (!*BootStrings.Drive)
{
if (!UiEditBox(ARCPathPrompt, BootStrings.ArcPath, sizeof(BootStrings.ArcPath)))
return;
}
/* Modify the settings values and return if we were in edit mode */
if (SectionId != 0)
{
IniModifySettingValue(SectionId, "BootDrive", BootDriveString);
/* Modify the BootPath if we have one */
if (*BootStrings.ArcPath)
{
IniModifySettingValue(SectionId, "BootPath", BootStrings.ArcPath);
}
else if (*BootStrings.Drive)
{
/* Otherwise, modify the BootDrive */
IniModifySettingValue(SectionId, "BootDrive", BootStrings.Drive);
}
return;
}
@ -146,47 +194,95 @@ VOID EditCustomBootDisk(IN ULONG_PTR SectionId OPTIONAL)
if (!IniAddSettingValueToSection(SectionId, "BootType", "Drive"))
return;
/* Add the BootDrive */
if (!IniAddSettingValueToSection(SectionId, "BootDrive", BootDriveString))
return;
/* Add the BootPath if we have one */
if (*BootStrings.ArcPath)
{
if (!IniAddSettingValueToSection(SectionId, "BootPath", BootStrings.ArcPath))
return;
}
else if (*BootStrings.Drive)
{
/* Otherwise, add the BootDrive */
if (!IniAddSettingValueToSection(SectionId, "BootDrive", BootStrings.Drive))
return;
}
UiMessageBox(CustomBootPrompt);
OperatingSystem.SectionName = SectionName;
OperatingSystem.LoadIdentifier = NULL;
LoadOperatingSystem(&OperatingSystem);
OperatingSystem->SectionId = SectionId;
OperatingSystem->LoadIdentifier = NULL;
}
VOID EditCustomBootPartition(IN ULONG_PTR SectionId OPTIONAL)
VOID
EditCustomBootPartition(
IN OUT OperatingSystemItem* OperatingSystem)
{
TIMEINFO* TimeInfo;
OperatingSystemItem OperatingSystem;
ULONG_PTR SectionId = OperatingSystem->SectionId;
CHAR SectionName[100];
CHAR BootDriveString[20];
CHAR BootPartitionString[20];
/* The following is a trick for saving some stack space */
union
{
struct
{
CHAR Guard1;
CHAR Drive[20];
CHAR Partition[20];
CHAR Guard2;
};
CHAR ArcPath[200];
} BootStrings;
RtlZeroMemory(SectionName, sizeof(SectionName));
RtlZeroMemory(BootDriveString, sizeof(BootDriveString));
RtlZeroMemory(BootPartitionString, sizeof(BootPartitionString));
RtlZeroMemory(&BootStrings, sizeof(BootStrings));
if (SectionId != 0)
{
/* Load the settings */
IniReadSettingByName(SectionId, "BootDrive", BootDriveString, sizeof(BootDriveString));
IniReadSettingByName(SectionId, "BootPartition", BootPartitionString, sizeof(BootPartitionString));
/*
* Check whether we have a "BootPath" value (takes precedence
* over both "BootDrive" and "BootPartition").
*/
*BootStrings.ArcPath = ANSI_NULL;
IniReadSettingByName(SectionId, "BootPath", BootStrings.ArcPath, sizeof(BootStrings.ArcPath));
if (!*BootStrings.ArcPath)
{
/* We don't, retrieve the boot drive and partition values instead */
IniReadSettingByName(SectionId, "BootDrive", BootStrings.Drive, sizeof(BootStrings.Drive));
IniReadSettingByName(SectionId, "BootPartition", BootStrings.Partition, sizeof(BootStrings.Partition));
}
}
if (!UiEditBox(BootDrivePrompt, BootDriveString, sizeof(BootDriveString)))
return;
if (!*BootStrings.ArcPath)
{
if (!UiEditBox(BootDrivePrompt, BootStrings.Drive, sizeof(BootStrings.Drive)))
return;
if (!UiEditBox(BootPartitionPrompt, BootPartitionString, sizeof(BootPartitionString)))
return;
if (*BootStrings.Drive)
{
if (!UiEditBox(BootPartitionPrompt, BootStrings.Partition, sizeof(BootStrings.Partition)))
return;
}
}
if (!*BootStrings.Drive)
{
if (!UiEditBox(ARCPathPrompt, BootStrings.ArcPath, sizeof(BootStrings.ArcPath)))
return;
}
/* Modify the settings values and return if we were in edit mode */
if (SectionId != 0)
{
IniModifySettingValue(SectionId, "BootDrive", BootDriveString);
IniModifySettingValue(SectionId, "BootPartition", BootPartitionString);
/* Modify the BootPath if we have one */
if (*BootStrings.ArcPath)
{
IniModifySettingValue(SectionId, "BootPath", BootStrings.ArcPath);
}
else if (*BootStrings.Drive)
{
/* Otherwise, modify the BootDrive and BootPartition */
IniModifySettingValue(SectionId, "BootDrive", BootStrings.Drive);
IniModifySettingValue(SectionId, "BootPartition", BootStrings.Partition);
}
return;
}
@ -205,48 +301,87 @@ VOID EditCustomBootPartition(IN ULONG_PTR SectionId OPTIONAL)
if (!IniAddSettingValueToSection(SectionId, "BootType", "Partition"))
return;
/* Add the BootDrive */
if (!IniAddSettingValueToSection(SectionId, "BootDrive", BootDriveString))
return;
/* Add the BootPath if we have one */
if (*BootStrings.ArcPath)
{
if (!IniAddSettingValueToSection(SectionId, "BootPath", BootStrings.ArcPath))
return;
}
else if (*BootStrings.Drive)
{
/* Otherwise, add the BootDrive and BootPartition */
if (!IniAddSettingValueToSection(SectionId, "BootDrive", BootStrings.Drive))
return;
/* Add the BootPartition */
if (!IniAddSettingValueToSection(SectionId, "BootPartition", BootPartitionString))
return;
if (!IniAddSettingValueToSection(SectionId, "BootPartition", BootStrings.Partition))
return;
}
UiMessageBox(CustomBootPrompt);
OperatingSystem.SectionName = SectionName;
OperatingSystem.LoadIdentifier = NULL;
LoadOperatingSystem(&OperatingSystem);
OperatingSystem->SectionId = SectionId;
OperatingSystem->LoadIdentifier = NULL;
}
VOID EditCustomBootSectorFile(IN ULONG_PTR SectionId OPTIONAL)
VOID
EditCustomBootSectorFile(
IN OUT OperatingSystemItem* OperatingSystem)
{
TIMEINFO* TimeInfo;
OperatingSystemItem OperatingSystem;
ULONG_PTR SectionId = OperatingSystem->SectionId;
CHAR SectionName[100];
CHAR BootDriveString[20];
CHAR BootPartitionString[20];
/* The following is a trick for saving some stack space */
union
{
struct
{
CHAR Guard1;
CHAR Drive[20];
CHAR Partition[20];
CHAR Guard2;
};
CHAR ArcPath[200];
} BootStrings;
CHAR BootSectorFileString[200];
RtlZeroMemory(SectionName, sizeof(SectionName));
RtlZeroMemory(BootDriveString, sizeof(BootDriveString));
RtlZeroMemory(BootPartitionString, sizeof(BootPartitionString));
RtlZeroMemory(&BootStrings, sizeof(BootStrings));
RtlZeroMemory(BootSectorFileString, sizeof(BootSectorFileString));
if (SectionId != 0)
{
/* Load the settings */
IniReadSettingByName(SectionId, "BootDrive", BootDriveString, sizeof(BootDriveString));
IniReadSettingByName(SectionId, "BootPartition", BootPartitionString, sizeof(BootPartitionString));
/*
* Check whether we have a "BootPath" value (takes precedence
* over both "BootDrive" and "BootPartition").
*/
*BootStrings.ArcPath = ANSI_NULL;
IniReadSettingByName(SectionId, "BootPath", BootStrings.ArcPath, sizeof(BootStrings.ArcPath));
if (!*BootStrings.ArcPath)
{
/* We don't, retrieve the boot drive and partition values instead */
IniReadSettingByName(SectionId, "BootDrive", BootStrings.Drive, sizeof(BootStrings.Drive));
IniReadSettingByName(SectionId, "BootPartition", BootStrings.Partition, sizeof(BootStrings.Partition));
}
IniReadSettingByName(SectionId, "BootSectorFile", BootSectorFileString, sizeof(BootSectorFileString));
}
if (!UiEditBox(BootDrivePrompt, BootDriveString, sizeof(BootDriveString)))
return;
if (!*BootStrings.ArcPath)
{
if (!UiEditBox(BootDrivePrompt, BootStrings.Drive, sizeof(BootStrings.Drive)))
return;
if (!UiEditBox(BootPartitionPrompt, BootPartitionString, sizeof(BootPartitionString)))
return;
if (*BootStrings.Drive)
{
if (!UiEditBox(BootPartitionPrompt, BootStrings.Partition, sizeof(BootStrings.Partition)))
return;
}
}
if (!*BootStrings.Drive)
{
if (!UiEditBox(ARCPathPrompt, BootStrings.ArcPath, sizeof(BootStrings.ArcPath)))
return;
}
if (!UiEditBox(BootSectorFilePrompt, BootSectorFileString, sizeof(BootSectorFileString)))
return;
@ -254,8 +389,28 @@ VOID EditCustomBootSectorFile(IN ULONG_PTR SectionId OPTIONAL)
/* Modify the settings values and return if we were in edit mode */
if (SectionId != 0)
{
IniModifySettingValue(SectionId, "BootDrive", BootDriveString);
IniModifySettingValue(SectionId, "BootPartition", BootPartitionString);
/* Modify the BootPath if we have one */
if (*BootStrings.ArcPath)
{
IniModifySettingValue(SectionId, "BootPath", BootStrings.ArcPath);
}
else if (*BootStrings.Drive)
{
/* Otherwise, modify the BootDrive and BootPartition */
IniModifySettingValue(SectionId, "BootDrive", BootStrings.Drive);
IniModifySettingValue(SectionId, "BootPartition", BootStrings.Partition);
}
else
{
/*
* Otherwise, zero out all values: BootSectorFile will be
* relative to the default system partition.
*/
IniModifySettingValue(SectionId, "BootPath", "");
IniModifySettingValue(SectionId, "BootDrive", "");
IniModifySettingValue(SectionId, "BootPartition", "");
}
IniModifySettingValue(SectionId, "BootSectorFile", BootSectorFileString);
return;
}
@ -275,39 +430,55 @@ VOID EditCustomBootSectorFile(IN ULONG_PTR SectionId OPTIONAL)
if (!IniAddSettingValueToSection(SectionId, "BootType", "BootSector"))
return;
/* Add the BootDrive */
if (!IniAddSettingValueToSection(SectionId, "BootDrive", BootDriveString))
return;
/* Add the BootPath if we have one */
if (*BootStrings.ArcPath)
{
if (!IniAddSettingValueToSection(SectionId, "BootPath", BootStrings.ArcPath))
return;
}
else if (*BootStrings.Drive)
{
/* Otherwise, add the BootDrive and BootPartition */
if (!IniAddSettingValueToSection(SectionId, "BootDrive", BootStrings.Drive))
return;
/* Add the BootPartition */
if (!IniAddSettingValueToSection(SectionId, "BootPartition", BootPartitionString))
return;
if (!IniAddSettingValueToSection(SectionId, "BootPartition", BootStrings.Partition))
return;
}
/* Add the BootSectorFile */
if (!IniAddSettingValueToSection(SectionId, "BootSectorFile", BootSectorFileString))
return;
UiMessageBox(CustomBootPrompt);
OperatingSystem.SectionName = SectionName;
OperatingSystem.LoadIdentifier = NULL;
LoadOperatingSystem(&OperatingSystem);
OperatingSystem->SectionId = SectionId;
OperatingSystem->LoadIdentifier = NULL;
}
VOID EditCustomBootLinux(IN ULONG_PTR SectionId OPTIONAL)
VOID
EditCustomBootLinux(
IN OUT OperatingSystemItem* OperatingSystem)
{
TIMEINFO* TimeInfo;
OperatingSystemItem OperatingSystem;
ULONG_PTR SectionId = OperatingSystem->SectionId;
CHAR SectionName[100];
CHAR BootDriveString[20];
CHAR BootPartitionString[20];
/* The following is a trick for saving some stack space */
union
{
struct
{
CHAR Guard1;
CHAR Drive[20];
CHAR Partition[20];
CHAR Guard2;
};
CHAR ArcPath[200];
} BootStrings;
CHAR LinuxKernelString[200];
CHAR LinuxInitrdString[200];
CHAR LinuxCommandLineString[200];
RtlZeroMemory(SectionName, sizeof(SectionName));
RtlZeroMemory(BootDriveString, sizeof(BootDriveString));
RtlZeroMemory(BootPartitionString, sizeof(BootPartitionString));
RtlZeroMemory(&BootStrings, sizeof(BootStrings));
RtlZeroMemory(LinuxKernelString, sizeof(LinuxKernelString));
RtlZeroMemory(LinuxInitrdString, sizeof(LinuxInitrdString));
RtlZeroMemory(LinuxCommandLineString, sizeof(LinuxCommandLineString));
@ -315,18 +486,41 @@ VOID EditCustomBootLinux(IN ULONG_PTR SectionId OPTIONAL)
if (SectionId != 0)
{
/* Load the settings */
IniReadSettingByName(SectionId, "BootDrive", BootDriveString, sizeof(BootDriveString));
IniReadSettingByName(SectionId, "BootPartition", BootPartitionString, sizeof(BootPartitionString));
/*
* Check whether we have a "BootPath" value (takes precedence
* over both "BootDrive" and "BootPartition").
*/
*BootStrings.ArcPath = ANSI_NULL;
IniReadSettingByName(SectionId, "BootPath", BootStrings.ArcPath, sizeof(BootStrings.ArcPath));
if (!*BootStrings.ArcPath)
{
/* We don't, retrieve the boot drive and partition values instead */
IniReadSettingByName(SectionId, "BootDrive", BootStrings.Drive, sizeof(BootStrings.Drive));
IniReadSettingByName(SectionId, "BootPartition", BootStrings.Partition, sizeof(BootStrings.Partition));
}
IniReadSettingByName(SectionId, "Kernel", LinuxKernelString, sizeof(LinuxKernelString));
IniReadSettingByName(SectionId, "Initrd", LinuxInitrdString, sizeof(LinuxInitrdString));
IniReadSettingByName(SectionId, "CommandLine", LinuxCommandLineString, sizeof(LinuxCommandLineString));
}
if (!UiEditBox(BootDrivePrompt, BootDriveString, sizeof(BootDriveString)))
return;
if (!*BootStrings.ArcPath)
{
if (!UiEditBox(BootDrivePrompt, BootStrings.Drive, sizeof(BootStrings.Drive)))
return;
if (!UiEditBox(BootPartitionPrompt, BootPartitionString, sizeof(BootPartitionString)))
return;
if (*BootStrings.Drive)
{
if (!UiEditBox(BootPartitionPrompt, BootStrings.Partition, sizeof(BootStrings.Partition)))
return;
}
}
if (!*BootStrings.Drive)
{
if (!UiEditBox(ARCPathPrompt, BootStrings.ArcPath, sizeof(BootStrings.ArcPath)))
return;
}
if (!UiEditBox(LinuxKernelPrompt, LinuxKernelString, sizeof(LinuxKernelString)))
return;
@ -340,8 +534,28 @@ VOID EditCustomBootLinux(IN ULONG_PTR SectionId OPTIONAL)
/* Modify the settings values and return if we were in edit mode */
if (SectionId != 0)
{
IniModifySettingValue(SectionId, "BootDrive", BootDriveString);
IniModifySettingValue(SectionId, "BootPartition", BootPartitionString);
/* Modify the BootPath if we have one */
if (*BootStrings.ArcPath)
{
IniModifySettingValue(SectionId, "BootPath", BootStrings.ArcPath);
}
else if (*BootStrings.Drive)
{
/* Otherwise, modify the BootDrive and BootPartition */
IniModifySettingValue(SectionId, "BootDrive", BootStrings.Drive);
IniModifySettingValue(SectionId, "BootPartition", BootStrings.Partition);
}
else
{
/*
* Otherwise, zero out all values: BootSectorFile will be
* relative to the default system partition.
*/
IniModifySettingValue(SectionId, "BootPath", "");
IniModifySettingValue(SectionId, "BootDrive", "");
IniModifySettingValue(SectionId, "BootPartition", "");
}
IniModifySettingValue(SectionId, "Kernel", LinuxKernelString);
IniModifySettingValue(SectionId, "Initrd", LinuxInitrdString);
IniModifySettingValue(SectionId, "CommandLine", LinuxCommandLineString);
@ -363,13 +577,21 @@ VOID EditCustomBootLinux(IN ULONG_PTR SectionId OPTIONAL)
if (!IniAddSettingValueToSection(SectionId, "BootType", "Linux"))
return;
/* Add the BootDrive */
if (!IniAddSettingValueToSection(SectionId, "BootDrive", BootDriveString))
return;
/* Add the BootPath if we have one */
if (*BootStrings.ArcPath)
{
if (!IniAddSettingValueToSection(SectionId, "BootPath", BootStrings.ArcPath))
return;
}
else if (*BootStrings.Drive)
{
/* Otherwise, add the BootDrive and BootPartition */
if (!IniAddSettingValueToSection(SectionId, "BootDrive", BootStrings.Drive))
return;
/* Add the BootPartition */
if (!IniAddSettingValueToSection(SectionId, "BootPartition", BootPartitionString))
return;
if (!IniAddSettingValueToSection(SectionId, "BootPartition", BootStrings.Partition))
return;
}
/* Add the Kernel */
if (!IniAddSettingValueToSection(SectionId, "Kernel", LinuxKernelString))
@ -386,22 +608,19 @@ VOID EditCustomBootLinux(IN ULONG_PTR SectionId OPTIONAL)
if (!IniAddSettingValueToSection(SectionId, "CommandLine", LinuxCommandLineString))
return;
UiMessageBox(CustomBootPrompt);
OperatingSystem.SectionName = SectionName;
OperatingSystem.LoadIdentifier = "Custom Linux Setup";
LoadOperatingSystem(&OperatingSystem);
OperatingSystem->SectionId = SectionId;
OperatingSystem->LoadIdentifier = "Custom Linux Setup";
}
#endif // _M_IX86
VOID
EditCustomBootReactOS(
IN ULONG_PTR SectionId OPTIONAL,
IN OUT OperatingSystemItem* OperatingSystem,
IN BOOLEAN IsSetup)
{
TIMEINFO* TimeInfo;
OperatingSystemItem OperatingSystem;
ULONG_PTR SectionId = OperatingSystem->SectionId;
CHAR SectionName[100];
CHAR BootDriveString[20];
CHAR BootPartitionString[20];
@ -419,7 +638,6 @@ EditCustomBootReactOS(
if (SectionId != 0)
{
/* Load the settings */
// TODO? Maybe use DissectArcPath(CHAR *ArcPath, CHAR *BootPath, UCHAR* BootDrive, ULONG* BootPartition) to get back to the small elements.
IniReadSettingByName(SectionId, "SystemPath", ReactOSARCPath, sizeof(ReactOSARCPath));
IniReadSettingByName(SectionId, "Options", ReactOSOptions, sizeof(ReactOSOptions));
}
@ -478,11 +696,8 @@ EditCustomBootReactOS(
if (!IniAddSettingValueToSection(SectionId, "Options", ReactOSOptions))
return;
UiMessageBox(CustomBootPrompt);
OperatingSystem.SectionName = SectionName;
OperatingSystem.LoadIdentifier = NULL;
LoadOperatingSystem(&OperatingSystem);
OperatingSystem->SectionId = SectionId;
OperatingSystem->LoadIdentifier = NULL;
}
#ifdef HAS_OPTION_MENU_REBOOT

View File

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

View File

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

View File

@ -36,7 +36,10 @@ UCHAR DriveMapGetBiosDriveNumber(PCSTR DeviceName); // Returns a BIOS drive
#ifdef _M_IX86
VOID DriveMapMapDrivesInSection(PCSTR SectionName);
VOID
DriveMapMapDrivesInSection(
IN ULONG_PTR SectionId);
VOID DriveMapInstallInt13Handler(PDRIVE_MAP_LIST DriveMap); // Installs the int 13h handler for the drive mapper
VOID DriveMapRemoveInt13Handler(VOID); // Removes a previously installed int 13h drive map handler

View File

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

View File

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

View File

@ -23,22 +23,33 @@
#define HAS_OPTION_MENU_CUSTOM_BOOT
#define HAS_OPTION_MENU_REBOOT
#ifdef _M_IX86
VOID EditCustomBootDisk(IN ULONG_PTR SectionId OPTIONAL);
VOID EditCustomBootPartition(IN ULONG_PTR SectionId OPTIONAL);
VOID EditCustomBootSectorFile(IN ULONG_PTR SectionId OPTIONAL);
VOID EditCustomBootLinux(IN ULONG_PTR SectionId OPTIONAL);
#endif // _M_IX86
#ifdef HAS_OPTION_MENU_CUSTOM_BOOT
VOID OptionMenuCustomBoot(VOID);
#endif
#ifdef _M_IX86
VOID
EditCustomBootDisk(
IN OUT OperatingSystemItem* OperatingSystem);
VOID
EditCustomBootPartition(
IN OUT OperatingSystemItem* OperatingSystem);
VOID
EditCustomBootSectorFile(
IN OUT OperatingSystemItem* OperatingSystem);
VOID
EditCustomBootLinux(
IN OUT OperatingSystemItem* OperatingSystem);
#endif // _M_IX86
VOID
EditCustomBootReactOS(
IN ULONG_PTR SectionId OPTIONAL,
IN OUT OperatingSystemItem* OperatingSystem,
IN BOOLEAN IsSetup);
#ifdef HAS_OPTION_MENU_REBOOT

View File

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

View File

@ -40,7 +40,14 @@ ARC_STATUS ArcSeek(ULONG FileId, LARGE_INTEGER* Position, SEEKMODE SeekMode);
ARC_STATUS ArcGetFileInformation(ULONG FileId, FILEINFORMATION* Information);
VOID FileSystemError(PCSTR ErrorString);
ULONG FsOpenFile(PCSTR FileName);
ARC_STATUS
FsOpenFile(
IN PCSTR FileName,
IN PCSTR DefaultPath OPTIONAL,
IN OPENMODE OpenMode,
OUT PULONG FileId);
ULONG FsGetNumPathParts(PCSTR Path);
VOID FsGetFirstNameFromPath(PCHAR Buffer, PCSTR Path);

View File

@ -137,17 +137,6 @@ LoadAndBootLinux(
IN PCHAR Argv[],
IN PCHAR Envp[]);
BOOLEAN
LinuxParseIniSection(
IN ULONG Argc,
IN PCHAR Argv[]);
BOOLEAN LinuxReadBootSector(ULONG LinuxKernelFile);
BOOLEAN LinuxReadSetupSector(ULONG LinuxKernelFile);
BOOLEAN LinuxReadKernel(ULONG LinuxKernelFile);
BOOLEAN LinuxCheckKernelVersion(VOID);
BOOLEAN LinuxReadInitrd(ULONG LinuxInitrdFile);
#endif // _M_IX86
#endif // defined __LINUX_H

View File

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

View File

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

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 UiDrawProgressBar(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, ULONG Position, ULONG Range, PCHAR ProgressText); // Draws the progress bar showing nPos percent filled
VOID UiShowMessageBoxesInSection(PCSTR SectionName); // Displays all the message boxes in a given section
// Displays all the message boxes in a given section.
VOID
UiShowMessageBoxesInSection(
IN ULONG_PTR SectionId);
VOID
UiShowMessageBoxesInArgv(

View File

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

View File

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

View File

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

View File

@ -29,8 +29,8 @@
/* INCLUDES *******************************************************************/
#include <freeldr.h>
#include <debug.h>
#include <debug.h>
DBG_DEFAULT_CHANNEL(LINUX);
/* GLOBALS ********************************************************************/
@ -50,11 +50,16 @@ ULONG LinuxCommandLineSize = 0;
PVOID LinuxKernelLoadAddress = NULL;
PVOID LinuxInitrdLoadAddress = NULL;
CHAR LinuxBootDescription[80];
PCSTR LinuxBootPath = NULL;
/* FUNCTIONS ******************************************************************/
VOID
static BOOLEAN LinuxReadBootSector(ULONG LinuxKernelFile);
static BOOLEAN LinuxReadSetupSector(ULONG LinuxKernelFile);
static BOOLEAN LinuxReadKernel(ULONG LinuxKernelFile);
static BOOLEAN LinuxCheckKernelVersion(VOID);
static BOOLEAN LinuxReadInitrd(ULONG LinuxInitrdFile);
static VOID
RemoveQuotes(
IN OUT PSTR QuotedString)
{
@ -85,14 +90,19 @@ LoadAndBootLinux(
IN PCHAR Argv[],
IN PCHAR Envp[])
{
ARC_STATUS Status;
PCSTR Description;
PCSTR ArgValue;
PCSTR BootPath;
UCHAR DriveNumber = 0;
ULONG PartitionNumber = 0;
ULONG LinuxKernel = 0;
ULONG LinuxInitrdFile = 0;
ARC_STATUS Status;
FILEINFORMATION FileInfo;
CHAR ArcPath[MAX_PATH];
Description = GetArgumentValue(Argc, Argv, "LoadIdentifier");
if (Description)
if (Description && *Description)
RtlStringCbPrintfA(LinuxBootDescription, sizeof(LinuxBootDescription), "Loading %s...", Description);
else
strcpy(LinuxBootDescription, "Loading Linux...");
@ -104,34 +114,91 @@ LoadAndBootLinux(
/* Find all the message box settings and run them */
UiShowMessageBoxesInArgv(Argc, Argv);
/* Parse the .ini file section */
if (!LinuxParseIniSection(Argc, Argv))
/*
* Check whether we have a "BootPath" value (takes precedence
* over both "BootDrive" and "BootPartition").
*/
BootPath = GetArgumentValue(Argc, Argv, "BootPath");
if (!BootPath || !*BootPath)
{
/* We don't have one, check whether we use "BootDrive" and "BootPartition" */
/* Retrieve the boot drive (optional, fall back to using default path otherwise) */
ArgValue = GetArgumentValue(Argc, Argv, "BootDrive");
if (ArgValue && *ArgValue)
{
DriveNumber = DriveMapGetBiosDriveNumber(ArgValue);
/* Retrieve the boot partition (not optional and cannot be zero) */
PartitionNumber = 0;
ArgValue = GetArgumentValue(Argc, Argv, "BootPartition");
if (ArgValue && *ArgValue)
PartitionNumber = atoi(ArgValue);
if (PartitionNumber == 0)
{
UiMessageBox("Boot partition cannot be 0!");
goto LinuxBootFailed;
// return EINVAL;
}
/* Construct the corresponding ARC path */
ConstructArcPath(ArcPath, "", DriveNumber, PartitionNumber);
*strrchr(ArcPath, '\\') = ANSI_NULL; // Trim the trailing path separator.
BootPath = ArcPath;
}
else
{
/* Fall back to using the system partition as default path */
BootPath = GetArgumentValue(Argc, Argv, "SystemPartition");
}
}
/* Get the kernel name */
LinuxKernelName = GetArgumentValue(Argc, Argv, "Kernel");
if (!LinuxKernelName || !*LinuxKernelName)
{
UiMessageBox("Linux kernel filename not specified for selected OS!");
goto LinuxBootFailed;
}
/* Get the initrd name (optional) */
LinuxInitrdName = GetArgumentValue(Argc, Argv, "Initrd");
/* Get the command line (optional) */
LinuxCommandLineSize = 0;
LinuxCommandLine = GetArgumentValue(Argc, Argv, "CommandLine");
if (LinuxCommandLine && *LinuxCommandLine)
{
RemoveQuotes(LinuxCommandLine);
LinuxCommandLineSize = (ULONG)strlen(LinuxCommandLine) + 1;
LinuxCommandLineSize = min(LinuxCommandLineSize, 260);
}
/* Open the kernel */
LinuxKernel = FsOpenFile(LinuxKernelName);
if (!LinuxKernel)
Status = FsOpenFile(LinuxKernelName, BootPath, OpenReadOnly, &LinuxKernel);
if (Status != ESUCCESS)
{
UiMessageBox("Linux kernel \'%s\' not found.", LinuxKernelName);
UiMessageBox("Linux kernel '%s' not found.", LinuxKernelName);
goto LinuxBootFailed;
}
/* Open the initrd file image (if necessary) */
if (LinuxInitrdName)
{
LinuxInitrdFile = FsOpenFile(LinuxInitrdName);
if (!LinuxInitrdFile)
Status = FsOpenFile(LinuxInitrdName, BootPath, OpenReadOnly, &LinuxInitrdFile);
if (Status != ESUCCESS)
{
UiMessageBox("Linux initrd image \'%s\' not found.", LinuxInitrdName);
UiMessageBox("Linux initrd image '%s' not found.", LinuxInitrdName);
goto LinuxBootFailed;
}
}
/* Read the boot sector */
/* Load the boot sector */
if (!LinuxReadBootSector(LinuxKernel))
goto LinuxBootFailed;
/* Read the setup sector */
/* Load the setup sector */
if (!LinuxReadSetupSector(LinuxKernel))
goto LinuxBootFailed;
@ -153,11 +220,11 @@ LoadAndBootLinux(
LinuxInitrdSize = FileInfo.EndingAddress.LowPart;
}
/* Read the kernel */
/* Load the kernel */
if (!LinuxReadKernel(LinuxKernel))
goto LinuxBootFailed;
/* Read the initrd (if necessary) */
/* Load the initrd (if necessary) */
if (LinuxInitrdName)
{
if (!LinuxReadInitrd(LinuxInitrdFile))
@ -233,50 +300,11 @@ LinuxBootFailed:
LinuxKernelLoadAddress = NULL;
LinuxInitrdLoadAddress = NULL;
*LinuxBootDescription = ANSI_NULL;
LinuxBootPath = NULL;
return ENOEXEC;
}
BOOLEAN
LinuxParseIniSection(
IN ULONG Argc,
IN PCHAR Argv[])
{
#if 0
LinuxBootPath = GetArgumentValue(Argc, Argv, "BootPath");
if (!LinuxBootPath)
{
UiMessageBox("Boot path not specified for selected OS!");
return FALSE;
}
#endif
/* Get the kernel name */
LinuxKernelName = GetArgumentValue(Argc, Argv, "Kernel");
if (!LinuxKernelName)
{
UiMessageBox("Linux kernel filename not specified for selected OS!");
return FALSE;
}
/* Get the initrd name (optional) */
LinuxInitrdName = GetArgumentValue(Argc, Argv, "Initrd");
/* Get the command line (optional) */
LinuxCommandLineSize = 0;
LinuxCommandLine = GetArgumentValue(Argc, Argv, "CommandLine");
if (LinuxCommandLine)
{
RemoveQuotes(LinuxCommandLine);
LinuxCommandLineSize = (ULONG)strlen(LinuxCommandLine) + 1;
LinuxCommandLineSize = min(LinuxCommandLineSize, 260);
}
return TRUE;
}
BOOLEAN LinuxReadBootSector(ULONG LinuxKernelFile)
static BOOLEAN LinuxReadBootSector(ULONG LinuxKernelFile)
{
LARGE_INTEGER Position;
@ -285,7 +313,7 @@ BOOLEAN LinuxReadBootSector(ULONG LinuxKernelFile)
if (LinuxBootSector == NULL)
return FALSE;
/* Read linux boot sector */
/* Load the linux boot sector */
Position.QuadPart = 0;
if (ArcSeek(LinuxKernelFile, &Position, SeekAbsolute) != ESUCCESS)
return FALSE;
@ -313,12 +341,12 @@ BOOLEAN LinuxReadBootSector(ULONG LinuxKernelFile)
return TRUE;
}
BOOLEAN LinuxReadSetupSector(ULONG LinuxKernelFile)
static BOOLEAN LinuxReadSetupSector(ULONG LinuxKernelFile)
{
LARGE_INTEGER Position;
UCHAR TempLinuxSetupSector[512];
/* Read first linux setup sector */
/* Load the first linux setup sector */
Position.QuadPart = 512;
if (ArcSeek(LinuxKernelFile, &Position, SeekAbsolute) != ESUCCESS)
return FALSE;
@ -343,7 +371,7 @@ BOOLEAN LinuxReadSetupSector(ULONG LinuxKernelFile)
/* Copy over first setup sector */
RtlCopyMemory(LinuxSetupSector, TempLinuxSetupSector, 512);
/* Read in the rest of the linux setup sectors */
/* Load the rest of the linux setup sectors */
Position.QuadPart = 1024;
if (ArcSeek(LinuxKernelFile, &Position, SeekAbsolute) != ESUCCESS)
return FALSE;
@ -371,7 +399,7 @@ BOOLEAN LinuxReadSetupSector(ULONG LinuxKernelFile)
return TRUE;
}
BOOLEAN LinuxReadKernel(ULONG LinuxKernelFile)
static BOOLEAN LinuxReadKernel(ULONG LinuxKernelFile)
{
PVOID LoadAddress;
LARGE_INTEGER Position;
@ -390,7 +418,7 @@ BOOLEAN LinuxReadKernel(ULONG LinuxKernelFile)
LoadAddress = LinuxKernelLoadAddress;
/* Read linux kernel to 0x100000 (1mb) */
/* Load the linux kernel at 0x100000 (1mb) */
Position.QuadPart = 512 + SetupSectorSize;
if (ArcSeek(LinuxKernelFile, &Position, SeekAbsolute) != ESUCCESS)
return FALSE;
@ -408,7 +436,7 @@ BOOLEAN LinuxReadKernel(ULONG LinuxKernelFile)
return TRUE;
}
BOOLEAN LinuxCheckKernelVersion(VOID)
static BOOLEAN LinuxCheckKernelVersion(VOID)
{
/* Just assume old kernel until we find otherwise */
NewStyleLinuxKernel = FALSE;
@ -445,7 +473,7 @@ BOOLEAN LinuxCheckKernelVersion(VOID)
return TRUE;
}
BOOLEAN LinuxReadInitrd(ULONG LinuxInitrdFile)
static BOOLEAN LinuxReadInitrd(ULONG LinuxInitrdFile)
{
ULONG BytesLoaded;
CHAR StatusText[260];
@ -482,7 +510,7 @@ BOOLEAN LinuxReadInitrd(ULONG LinuxInitrdFile)
TRACE("InitrdAddressMax: 0x%x\n", LinuxSetupSector->InitrdAddressMax);
}
/* Read in the ramdisk */
/* Load the ramdisk */
for (BytesLoaded=0; BytesLoaded<LinuxInitrdSize; )
{
if (ArcRead(LinuxInitrdFile, (PVOID)LinuxInitrdLoadAddress, LINUX_READ_CHUNK_SIZE, NULL) != ESUCCESS)

View File

@ -32,34 +32,79 @@ LoadAndBootBootSector(
IN PCHAR Envp[])
{
ARC_STATUS Status;
PCSTR ArgValue;
PCSTR BootPath;
PCSTR FileName;
UCHAR DriveNumber = 0;
ULONG PartitionNumber = 0;
ULONG FileId;
ULONG BytesRead;
CHAR ArcPath[MAX_PATH];
/* Find all the message box settings and run them */
UiShowMessageBoxesInArgv(Argc, Argv);
/* Read the file name */
/*
* Check whether we have a "BootPath" value (takes precedence
* over both "BootDrive" and "BootPartition").
*/
BootPath = GetArgumentValue(Argc, Argv, "BootPath");
if (!BootPath || !*BootPath)
{
/* We don't have one, check whether we use "BootDrive" and "BootPartition" */
/* Retrieve the boot drive (optional, fall back to using default path otherwise) */
ArgValue = GetArgumentValue(Argc, Argv, "BootDrive");
if (ArgValue && *ArgValue)
{
DriveNumber = DriveMapGetBiosDriveNumber(ArgValue);
/* Retrieve the boot partition (not optional and cannot be zero) */
PartitionNumber = 0;
ArgValue = GetArgumentValue(Argc, Argv, "BootPartition");
if (ArgValue && *ArgValue)
PartitionNumber = atoi(ArgValue);
if (PartitionNumber == 0)
{
UiMessageBox("Boot partition cannot be 0!");
return EINVAL;
}
/* Construct the corresponding ARC path */
ConstructArcPath(ArcPath, "", DriveNumber, PartitionNumber);
*strrchr(ArcPath, '\\') = ANSI_NULL; // Trim the trailing path separator.
BootPath = ArcPath;
}
else
{
/* Fall back to using the system partition as default path */
BootPath = GetArgumentValue(Argc, Argv, "SystemPartition");
}
}
/* Retrieve the file name */
FileName = GetArgumentValue(Argc, Argv, "BootSectorFile");
if (!FileName)
if (!FileName || !*FileName)
{
UiMessageBox("Boot sector file not specified for selected OS!");
return EINVAL;
}
FileId = FsOpenFile(FileName);
if (!FileId)
/* Open the boot sector file */
Status = FsOpenFile(FileName, BootPath, OpenReadOnly, &FileId);
if (Status != ESUCCESS)
{
UiMessageBox("%s not found.", FileName);
return ENOENT;
UiMessageBox("Unable to open %s", FileName);
return Status;
}
/* Read boot sector */
/* Now try to load the boot sector. If this fails then abort. */
Status = ArcRead(FileId, (PVOID)0x7c00, 512, &BytesRead);
ArcClose(FileId);
if ((Status != ESUCCESS) || (BytesRead != 512))
{
UiMessageBox("Unable to read boot sector.");
UiMessageBox("Unable to load boot sector.");
return EIO;
}
@ -92,27 +137,51 @@ LoadAndBootBootSector(
static ARC_STATUS
LoadAndBootPartitionOrDrive(
IN UCHAR DriveNumber,
IN ULONG PartitionNumber OPTIONAL)
IN ULONG PartitionNumber OPTIONAL,
IN PCSTR BootPath OPTIONAL)
{
ARC_STATUS Status;
ULONG FileId;
ULONG BytesRead;
CHAR ArcPath[MAX_PATH];
/* Construct the corresponding ARC path */
ConstructArcPath(ArcPath, "", DriveNumber, PartitionNumber);
*strrchr(ArcPath, '\\') = ANSI_NULL; // Trim the trailing path separator.
/*
* If the user specifies an ARC "BootPath" value, it takes precedence
* over both the DriveNumber and PartitionNumber options.
*/
if (BootPath && *BootPath)
{
PCSTR FileName = NULL;
/*
* Retrieve the BIOS drive and partition numbers; verify also that the
* path is "valid" in the sense that it must not contain any file name.
*/
if (!DissectArcPath(BootPath, &FileName, &DriveNumber, &PartitionNumber) ||
(FileName && *FileName))
{
return EINVAL;
}
}
else
{
/* We don't have one, so construct the corresponding ARC path */
ConstructArcPath(ArcPath, "", DriveNumber, PartitionNumber);
*strrchr(ArcPath, '\\') = ANSI_NULL; // Trim the trailing path separator.
BootPath = ArcPath;
}
/* Open the volume */
Status = ArcOpen(ArcPath, OpenReadOnly, &FileId);
Status = ArcOpen((PSTR)BootPath, OpenReadOnly, &FileId);
if (Status != ESUCCESS)
{
UiMessageBox("Unable to open %s", ArcPath);
return ENOENT;
UiMessageBox("Unable to open %s", BootPath);
return Status;
}
/*
* Now try to read the partition boot sector or the MBR (when PartitionNumber == 0).
* Now try to load the partition boot sector or the MBR (when PartitionNumber == 0).
* If this fails then abort.
*/
Status = ArcRead(FileId, (PVOID)0x7c00, 512, &BytesRead);
@ -120,9 +189,9 @@ LoadAndBootPartitionOrDrive(
if ((Status != ESUCCESS) || (BytesRead != 512))
{
if (PartitionNumber != 0)
UiMessageBox("Unable to read partition's boot sector.");
UiMessageBox("Unable to load partition's boot sector.");
else
UiMessageBox("Unable to read MBR boot sector.");
UiMessageBox("Unable to load MBR boot sector.");
return EIO;
}
@ -160,31 +229,39 @@ LoadAndBootPartition(
IN PCHAR Envp[])
{
PCSTR ArgValue;
UCHAR DriveNumber;
ULONG PartitionNumber;
PCSTR BootPath;
UCHAR DriveNumber = 0;
ULONG PartitionNumber = 0;
/* Find all the message box settings and run them */
UiShowMessageBoxesInArgv(Argc, Argv);
/* Read the boot drive */
ArgValue = GetArgumentValue(Argc, Argv, "BootDrive");
if (!ArgValue)
/*
* Check whether we have a "BootPath" value (takes precedence
* over both "BootDrive" and "BootPartition").
*/
BootPath = GetArgumentValue(Argc, Argv, "BootPath");
if (!BootPath || !*BootPath)
{
UiMessageBox("Boot drive not specified for selected OS!");
return EINVAL;
}
DriveNumber = DriveMapGetBiosDriveNumber(ArgValue);
/* We don't have one */
/* Read the boot partition */
ArgValue = GetArgumentValue(Argc, Argv, "BootPartition");
if (!ArgValue)
{
UiMessageBox("Boot partition not specified for selected OS!");
return EINVAL;
}
PartitionNumber = atoi(ArgValue);
/* Retrieve the boot drive */
ArgValue = GetArgumentValue(Argc, Argv, "BootDrive");
if (!ArgValue || !*ArgValue)
{
UiMessageBox("Boot drive not specified for selected OS!");
return EINVAL;
}
DriveNumber = DriveMapGetBiosDriveNumber(ArgValue);
return LoadAndBootPartitionOrDrive(DriveNumber, PartitionNumber);
/* Retrieve the boot partition (optional, fall back to zero otherwise) */
PartitionNumber = 0;
ArgValue = GetArgumentValue(Argc, Argv, "BootPartition");
if (ArgValue && *ArgValue)
PartitionNumber = atoi(ArgValue);
}
return LoadAndBootPartitionOrDrive(DriveNumber, PartitionNumber, BootPath);
}
ARC_STATUS
@ -194,21 +271,39 @@ LoadAndBootDrive(
IN PCHAR Envp[])
{
PCSTR ArgValue;
UCHAR DriveNumber;
PCSTR BootPath;
UCHAR DriveNumber = 0;
/* Find all the message box settings and run them */
UiShowMessageBoxesInArgv(Argc, Argv);
/* Read the boot drive */
ArgValue = GetArgumentValue(Argc, Argv, "BootDrive");
if (!ArgValue)
/* Check whether we have a "BootPath" value (takes precedence over "BootDrive") */
BootPath = GetArgumentValue(Argc, Argv, "BootPath");
if (BootPath && *BootPath)
{
UiMessageBox("Boot drive not specified for selected OS!");
return EINVAL;
/*
* We have one, check that it does not contain any
* "partition()" specification, and fail if so.
*/
if (strstr(BootPath, ")partition("))
{
UiMessageBox("Invalid 'BootPath' value!");
return EINVAL;
}
}
else
{
/* We don't, retrieve the boot drive value instead */
ArgValue = GetArgumentValue(Argc, Argv, "BootDrive");
if (!ArgValue || !*ArgValue)
{
UiMessageBox("Boot drive not specified for selected OS!");
return EINVAL;
}
DriveNumber = DriveMapGetBiosDriveNumber(ArgValue);
}
DriveNumber = DriveMapGetBiosDriveNumber(ArgValue);
return LoadAndBootPartitionOrDrive(DriveNumber, 0);
return LoadAndBootPartitionOrDrive(DriveNumber, 0, BootPath);
}
#endif // _M_IX86

View File

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

View File

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

View File

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

View File

@ -20,8 +20,8 @@
/* INCLUDES *******************************************************************/
#include <freeldr.h>
#include <debug.h>
#include <debug.h>
DBG_DEFAULT_CHANNEL(INIFILE);
#define TAG_OS_ITEM 'tISO'
@ -42,49 +42,16 @@ static PCSTR CopyString(PCSTR Source)
return Dest;
}
static ULONG
GetDefaultOperatingSystem(
IN OperatingSystemItem* OperatingSystemList,
IN ULONG OperatingSystemCount)
{
ULONG DefaultOS = 0;
ULONG i;
ULONG_PTR SectionId;
PCSTR DefaultOSName;
CHAR DefaultOSText[80];
if (!IniOpenSection("FreeLoader", &SectionId))
return 0;
DefaultOSName = CmdLineGetDefaultOS();
if (DefaultOSName == NULL)
{
if (IniReadSettingByName(SectionId, "DefaultOS", DefaultOSText, sizeof(DefaultOSText)))
{
DefaultOSName = DefaultOSText;
}
}
if (DefaultOSName != NULL)
{
for (i = 0; i < OperatingSystemCount; ++i)
{
if (_stricmp(DefaultOSName, OperatingSystemList[i].SectionName) == 0)
{
DefaultOS = i;
break;
}
}
}
return DefaultOS;
}
OperatingSystemItem*
InitOperatingSystemList(
IN ULONG_PTR FrLdrSectionId,
OUT PULONG OperatingSystemCount,
OUT PULONG DefaultOperatingSystem)
{
ULONG DefaultOS = 0;
PCSTR DefaultOSName = NULL;
CHAR DefaultOSText[80];
OperatingSystemItem* Items;
ULONG Count;
ULONG i;
@ -110,7 +77,18 @@ InitOperatingSystemList(
if (!Items)
return NULL;
/* Now loop through and read the operating system section and display names */
/* Retrieve which OS is the default one */
DefaultOSName = CmdLineGetDefaultOS();
if (!DefaultOSName || !*DefaultOSName)
{
if ((FrLdrSectionId != 0) &&
IniReadSettingByName(FrLdrSectionId, "DefaultOS", DefaultOSText, sizeof(DefaultOSText)))
{
DefaultOSName = DefaultOSText;
}
}
/* Now loop through the operating system section and load each item */
for (i = 0; i < Count; ++i)
{
IniReadSettingByNumber(OsSectionId, i,
@ -118,7 +96,7 @@ InitOperatingSystemList(
SettingValue, sizeof(SettingValue));
if (!*SettingName)
{
ERR("Invalid OS entry number %lu, skipping.\n", i);
ERR("Invalid OS entry %lu, skipping.\n", i);
continue;
}
@ -151,6 +129,13 @@ InitOperatingSystemList(
// "OsLoadOptions = '%s'\n",
// SettingName, TitleStart, OsLoadOptions);
/* Find the default OS item while we haven't got one */
if (DefaultOSName && _stricmp(DefaultOSName, SettingName) == 0)
{
DefaultOS = i;
DefaultOSName = NULL; // We have found the first one, don't search for others.
}
/*
* Determine whether this is a legacy operating system entry of the form:
*
@ -174,6 +159,7 @@ InitOperatingSystemList(
*/
/* Try to open the operating system section in the .ini file */
SectionId = 0;
HadSection = IniOpenSection(SettingName, &SectionId);
if (HadSection)
{
@ -192,7 +178,7 @@ InitOperatingSystemList(
{
#ifdef _M_IX86
ULONG FileId;
if (ArcOpen((PSTR)SettingName, OpenReadOnly, &FileId) == ESUCCESS)
if (ArcOpen(SettingName, OpenReadOnly, &FileId) == ESUCCESS)
{
ArcClose(FileId);
strcpy(BootType, "BootSector");
@ -236,7 +222,7 @@ InitOperatingSystemList(
/* Add the section */
if (!IniAddSection(SettingName, &SectionId))
{
ERR("Could not convert legacy OS entry! Continuing...\n");
ERR("Could not convert legacy OS entry %lu, skipping.\n", i);
continue;
}
@ -245,7 +231,7 @@ InitOperatingSystemList(
{
if (!IniAddSettingValueToSection(SectionId, "BootSectorFile", TempBuffer))
{
ERR("Could not convert legacy OS entry! Continuing...\n");
ERR("Could not convert legacy OS entry %lu, skipping.\n", i);
continue;
}
}
@ -253,7 +239,7 @@ InitOperatingSystemList(
{
if (!IniAddSettingValueToSection(SectionId, "SystemPath", TempBuffer))
{
ERR("Could not convert legacy OS entry! Continuing...\n");
ERR("Could not convert legacy OS entry %lu, skipping.\n", i);
continue;
}
}
@ -265,7 +251,7 @@ InitOperatingSystemList(
/* Add the OS options */
if (OsLoadOptions && !IniAddSettingValueToSection(SectionId, "Options", OsLoadOptions))
{
ERR("Could not convert legacy OS entry! Continuing...\n");
ERR("Could not convert legacy OS entry %lu, skipping.\n", i);
continue;
}
}
@ -296,14 +282,15 @@ InitOperatingSystemList(
ERR("Could not modify the options for OS '%s', ignoring.\n", SettingName);
}
/* Copy the OS section name and identifier */
Items[i].SectionName = CopyString(SettingName);
/* Copy the OS section ID and its identifier */
Items[i].SectionId = SectionId;
Items[i].LoadIdentifier = CopyString(TitleStart);
// TRACE("We did Items[%lu]: SectionName = '%s', LoadIdentifier = '%s'\n", i, Items[i].SectionName, Items[i].LoadIdentifier);
// TRACE("We did Items[%lu]: SectionName = '%s' (SectionId = 0x%p), LoadIdentifier = '%s'\n",
// i, SettingName, Items[i].SectionId, Items[i].LoadIdentifier);
}
/* Return success */
*OperatingSystemCount = Count;
*DefaultOperatingSystem = GetDefaultOperatingSystem(Items, Count);
*DefaultOperatingSystem = DefaultOS;
return Items;
}

View File

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

View File

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

View File

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