*/
#include <freeldr.h>
-#include <debug.h>
+#include <debug.h>
DBG_DEFAULT_CHANNEL(DISK);
#ifdef _M_IX86
#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);
// 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;
}
// 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;
}
#include <freeldr.h>
#include <debug.h>
-
DBG_DEFAULT_CHANNEL(HWDETECT);
/*
ULONGLONG SectorOffset = 0;
ULONGLONG SectorCount = 0;
PARTITION_TABLE_ENTRY PartitionTableEntry;
- CHAR FileName[1];
if (DiskReadBufferSize == 0)
{
return ENOMEM;
}
- if (!DissectArcPath(Path, FileName, &DriveNumber, &DrivePartition))
+ if (!DissectArcPath(Path, NULL, &DriveNumber, &DrivePartition))
return EINVAL;
if (DrivePartition == 0xff)
#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;
-
- /* Get the path */
- p = ArcPath + 11;
- strcpy(BootPath, p);
+ *DriveNumber = 0x49;
+ *PartitionNumber = 1;
+
+ /* 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;
* 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)
{
* 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;
}
/* 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)
/* INCLUDES *******************************************************************/
#include <freeldr.h>
-#include <debug.h>
+#include <debug.h>
DBG_DEFAULT_CHANNEL(INIFILE);
/* GLOBALS ********************************************************************/
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
/* 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,
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);
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=");
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;
#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 */
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;
{
if (_stricmp(BootType, OSLoadingMethods[i].BootType) == 0)
{
- OSLoadingMethods[i].EditOsEntry(SectionId);
+ OSLoadingMethods[i].EditOsEntry(OperatingSystem);
return;
}
}
#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;
}
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))
return;
}
- OperatingSystemList = InitOperatingSystemList(&OperatingSystemCount,
+ OperatingSystemList = InitOperatingSystemList(SectionId,
+ &OperatingSystemCount,
&DefaultOperatingSystem);
if (!OperatingSystemList)
{
}
/* Find all the message box settings and run them */
- UiShowMessageBoxesInSection("FreeLoader");
+ UiShowMessageBoxesInSection(SectionId);
for (;;)
{
typedef struct tagCMDLINEINFO
{
- PCCH DebugString;
- PCCH DefaultOperatingSystem;
- LONG TimeOut;
+ PCSTR DebugString;
+ PCSTR DefaultOperatingSystem;
+ LONG TimeOut;
} CMDLINEINFO, *PCMDLINEINFO;
CCHAR DebugString[256];
/* FUNCTIONS ******************************************************************/
VOID
-CmdLineParse(IN PCCH CmdLine)
+CmdLineParse(IN PCSTR CmdLine)
{
PCHAR End, Setting;
ULONG_PTR Length, Offset = 0;
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 */
/* 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;
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.";
"ReactOS Setup"
};
ULONG SelectedMenuItem;
+ OperatingSystemItem OperatingSystem;
if (!UiDisplayMenu("Please choose a boot method:", NULL,
FALSE,
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;
}
if (!IniAddSettingValueToSection(SectionId, "BootType", "Drive"))
return;
- /* Add the BootDrive */
- if (!IniAddSettingValueToSection(SectionId, "BootDrive", BootDriveString))
- return;
-
- UiMessageBox(CustomBootPrompt);
+ /* 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;
+ }
- 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;
}
if (!IniAddSettingValueToSection(SectionId, "BootType", "Partition"))
return;
- /* Add the BootDrive */
- if (!IniAddSettingValueToSection(SectionId, "BootDrive", BootDriveString))
- return;
-
- /* Add the BootPartition */
- if (!IniAddSettingValueToSection(SectionId, "BootPartition", BootPartitionString))
- 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;
- UiMessageBox(CustomBootPrompt);
+ if (!IniAddSettingValueToSection(SectionId, "BootPartition", BootStrings.Partition))
+ return;
+ }
- 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;
/* 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;
}
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));
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;
/* 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);
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))
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];
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));
}
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
};
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;
{
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);
&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);
}
}
/* Setup the RAMDISK device */
RamDiskInitialize();
- return TRUE;
+ return ESUCCESS;
}
/* INCLUDES *******************************************************************/
#include <freeldr.h>
-#include <debug.h>
+#include <debug.h>
DBG_DEFAULT_CHANNEL(WARNING);
/* FUNCTIONS ******************************************************************/
CmdLineParse(CmdLine);
/* Debugger pre-initialization */
- DebugInit(FALSE);
+ DebugInit(0);
TRACE("BootMain() called.\n");
#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
// 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
#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 */
#define HAS_OPTION_MENU_CUSTOM_BOOT
#define HAS_OPTION_MENU_REBOOT
+#ifdef HAS_OPTION_MENU_CUSTOM_BOOT
+VOID OptionMenuCustomBoot(VOID);
+#endif
+
#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);
+VOID
+EditCustomBootDisk(
+ IN OUT OperatingSystemItem* OperatingSystem);
-#endif // _M_IX86
+VOID
+EditCustomBootPartition(
+ IN OUT OperatingSystemItem* OperatingSystem);
-#ifdef HAS_OPTION_MENU_CUSTOM_BOOT
-VOID OptionMenuCustomBoot(VOID);
-#endif
+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
#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);
#define UNIMPLEMENTED
- #define DebugInit(init)
+ #define DebugInit(FrLdrSectionId)
#define BugCheck(fmt, ...)
#define DbgDumpBuffer(mask, buf, len)
#define DbgParseDebugChannels(val)
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);
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
typedef struct tagOperatingSystemItem
{
- PCSTR SectionName;
+ ULONG_PTR SectionId;
PCSTR LoadIdentifier;
} OperatingSystemItem;
OperatingSystemItem*
InitOperatingSystemList(
+ IN ULONG_PTR FrLdrSectionId,
OUT PULONG OperatingSystemCount,
OUT PULONG DefaultOperatingSystem);
//
// 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;
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(
BOOLEAN DebugStartOfLine = TRUE;
-VOID DebugInit(BOOLEAN MainInit)
+VOID DebugInit(IN ULONG_PTR FrLdrSectionId)
{
PCHAR CommandLine, PortString, BaudString, IrqString;
ULONG Value;
#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();
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 */
#include <freeldr.h>
#include <debug.h>
-
DBG_DEFAULT_CHANNEL(FILESYSTEM);
/* GLOBALS ********************************************************************/
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 */
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, "\\");
- }
- // Append (or just copy) the remaining file name.
- strcat(FullPath, FileName);
- //
- // Open the file
- //
- Status = ArcOpen(FullPath, OpenReadOnly, &FileId);
+ cchPathLen = min(sizeof(FullPath)/sizeof(CHAR), strlen(FullPath));
+ if (cchPathLen >= sizeof(FullPath)/sizeof(CHAR))
+ return ENAMETOOLONG;
- //
- // Check for success
- //
- if (Status == ESUCCESS)
- return FileId;
- else
- return 0;
+ 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 */
+ Status = RtlStringCbCatA(FullPath, sizeof(FullPath), FileName);
+ if (!NT_SUCCESS(Status))
+ return ENAMETOOLONG;
+
+ /* Open the file */
+ return ArcOpen(FullPath, OpenMode, FileId);
}
/*
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.
}
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);
/* INCLUDES *******************************************************************/
#include <freeldr.h>
-#include <debug.h>
+#include <debug.h>
DBG_DEFAULT_CHANNEL(LINUX);
/* GLOBALS ********************************************************************/
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)
{
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...");
/* 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;
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))
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;
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;
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;
/* 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;
return TRUE;
}
-BOOLEAN LinuxReadKernel(ULONG LinuxKernelFile)
+static BOOLEAN LinuxReadKernel(ULONG LinuxKernelFile)
{
PVOID LoadAddress;
LARGE_INTEGER Position;
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;
return TRUE;
}
-BOOLEAN LinuxCheckKernelVersion(VOID)
+static BOOLEAN LinuxCheckKernelVersion(VOID)
{
/* Just assume old kernel until we find otherwise */
NewStyleLinuxKernel = FALSE;
return TRUE;
}
-BOOLEAN LinuxReadInitrd(ULONG LinuxInitrdFile)
+static BOOLEAN LinuxReadInitrd(ULONG LinuxInitrdFile)
{
ULONG BytesLoaded;
CHAR StatusText[260];
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)
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;
}
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);
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;
}
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;
+ /* 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);
+
+ /* Retrieve the boot partition (optional, fall back to zero otherwise) */
+ PartitionNumber = 0;
+ ArgValue = GetArgumentValue(Argc, Argv, "BootPartition");
+ if (ArgValue && *ArgValue)
+ PartitionNumber = atoi(ArgValue);
}
- PartitionNumber = atoi(ArgValue);
- return LoadAndBootPartitionOrDrive(DriveNumber, PartitionNumber);
+ return LoadAndBootPartitionOrDrive(DriveNumber, PartitionNumber, BootPath);
}
ARC_STATUS
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
//
// Open the .inf file
//
- Status = ArcOpen((PCHAR)FileName, OpenReadOnly, &FileId);
+ Status = ArcOpen((PSTR)FileName, OpenReadOnly, &FileId);
if (Status != ESUCCESS)
{
return FALSE;
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;
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();
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;
}
/* 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 != '/')
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), "\\");
/* 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);
*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;
}
}
}
#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);
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[] = "\\";
*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 */
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;
}
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;
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");
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);
IN PCHAR Argv[],
IN PCHAR Envp[])
{
+ ARC_STATUS Status;
PCSTR ArgValue;
+ PCSTR SystemPartition;
PCHAR File;
BOOLEAN Success;
USHORT OperatingSystemVersion;
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)
{
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...");
/* 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 != '/')
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), "\\");
/* 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 */
*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;
}
}
/* INCLUDES *******************************************************************/
#include <freeldr.h>
-#include <debug.h>
+#include <debug.h>
DBG_DEFAULT_CHANNEL(INIFILE);
#define TAG_OS_ITEM 'tISO'
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;
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,
SettingValue, sizeof(SettingValue));
if (!*SettingName)
{
- ERR("Invalid OS entry number %lu, skipping.\n", i);
+ ERR("Invalid OS entry %lu, skipping.\n", i);
continue;
}
// "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:
*
*/
/* Try to open the operating system section in the .ini file */
+ SectionId = 0;
HadSection = IniOpenSection(SettingName, &SectionId);
if (HadSection)
{
{
#ifdef _M_IX86
ULONG FileId;
- if (ArcOpen((PSTR)SettingName, OpenReadOnly, &FileId) == ESUCCESS)
+ if (ArcOpen(SettingName, OpenReadOnly, &FileId) == ESUCCESS)
{
ArcClose(FileId);
strcpy(BootType, "BootSector");
/* 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;
}
{
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;
}
}
{
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;
}
}
/* 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;
}
}
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;
}
/* INCLUDES *******************************************************************/
#include <freeldr.h>
-#include <debug.h>
/* GLOBALS ********************************************************************/
}
VOID
-UiShowMessageBoxesInSection(IN PCSTR SectionName)
+UiShowMessageBoxesInSection(
+ IN ULONG_PTR SectionId)
{
return;
}
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
#define TAG_TUI_SCREENBUFFER 'SiuT'
#define TAG_TAG_TUI_PALETTE 'PiuT'
-PVOID TextVideoBuffer = NULL;
+PVOID TextVideoBuffer = NULL;
/*
* TuiPrintf()
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;
#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
-
-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
-
-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
+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
+
+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
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 =
{
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)
{
}
TRACE("Initializing User Interface.\n");
- TRACE("Reading in UI settings from [Display] section.\n");
+ TRACE("Reading UI settings from [Display] section.\n");
+
+ /* Open the [Display] section */
+ if (!IniOpenSection("Display", &SectionId))
+ SectionId = 0;
- DisplayModeText[0] = '\0';
- if (IniOpenSection("Display", &SectionId))
+ /* 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;
return FALSE;
}
- if (IniOpenSection("Display", &SectionId))
+ /* Load the settings */
+ if (SectionId != 0)
{
- if (IniReadSettingByName(SectionId, "TitleText", SettingText, sizeof(SettingText)))
- {
- strcpy(UiTitleBoxTitleText, SettingText);
- }
- if (IniReadSettingByName(SectionId, "TimeText", SettingText, sizeof(SettingText)))
- {
- strcpy(UiTimeText, SettingText);
- }
- if (IniReadSettingByName(SectionId, "StatusBarColor", SettingText, sizeof(SettingText)))
- {
- 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)))
+ static const struct
{
- 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)))
+ PCSTR SettingName;
+ PVOID SettingVar;
+ UCHAR SettingType; // 0: Text, 1: Yes/No, 2: Color, 3: Fill style
+ } Settings[] =
{
- 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)))
+ {"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)
{
- 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");
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);
}
}
/* 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);
}
}
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