mirror of
https://github.com/reactos/reactos.git
synced 2025-06-27 10:59:42 +00:00
[FREELDR] Merge boot-drive and partition functionalities together (#6760)
And deprecate corresponding boot types "Drive" and "Partition".
These are replaced by the more general "BootSector" boot type.
Finish the unification of the code, started in commit ff85aa0c3
,
that loads and boots disk MBR, partition VBR or boot sector in file.
A "WarnDeprecated()" helper is added to warn the user about the
deprecated features, and to inform them to adjust their FREELDR.INI
file in accordance.
In addition, bump FreeLoader version to 3.2 (at last!): a lot of
features have been added or deprecated since its last release.
This commit is contained in:
parent
5949c20d97
commit
5f3554a40c
8 changed files with 254 additions and 535 deletions
|
@ -64,36 +64,24 @@
|
||||||
; DarkGray, LightBlue, LightGreen, LightCyan, LightRed, LightMagenta,
|
; DarkGray, LightBlue, LightGreen, LightCyan, LightRed, LightMagenta,
|
||||||
; Yellow, White, Default.
|
; Yellow, White, Default.
|
||||||
;
|
;
|
||||||
; Default color is the one that is being used by BIOS firmware by default.
|
; Default color is the one that is being used by the firmware by default.
|
||||||
; On PC/AT-compatible machines it's Gray, and on NEC PC-98 series it's White.
|
; On PC/AT-compatible machines it's Gray, and on NEC PC-98 series it's White.
|
||||||
|
|
||||||
; [OS-General] Section Commands:
|
; [OS-General] Section Commands:
|
||||||
;
|
;
|
||||||
; BootType - Specifies the boot type: Windows, WindowsNT40, Windows2003,
|
; BootType - Specifies the boot type: BootSector, Linux,
|
||||||
; ReactOSSetup, Linux, BootSector, Partition, Drive
|
; Windows, WindowsNT40, Windows2003, ReactOSSetup.
|
||||||
|
;
|
||||||
; BootPath - ARC path, e.g. multi(0)disk(0)rdisk(x)partition(y)
|
; BootPath - ARC path, e.g. multi(0)disk(0)rdisk(x)partition(y)
|
||||||
; DriveMap - Maps a BIOS drive number to another (i.e. DriveMap=hd1,hd0
|
|
||||||
; maps harddisk1 to harddisk0; or DriveMap=fd1,fd0).
|
|
||||||
|
|
||||||
; ["Drive" OSType] Section Commands:
|
|
||||||
;
|
;
|
||||||
; BootDrive - BIOS drive number to be used.
|
; DriveMap - For BIOS-based PCs, maps a BIOS drive number to another
|
||||||
;
|
; (i.e. DriveMap=hd1,hd0 maps hard-disk 1 to hard-disk 0;
|
||||||
; REMARK: If a "BootPath" ARC path is specified, its value takes precedence
|
; or DriveMap=fd1,fd0 for mapping floppy disks).
|
||||||
; over the "BootDrive" value.
|
|
||||||
|
|
||||||
; ["Partition" OSType] Section Commands:
|
|
||||||
;
|
|
||||||
; BootDrive - BIOS drive number to be used.
|
|
||||||
; BootPartition - Partition number to be used (default: 0).
|
|
||||||
;
|
|
||||||
; REMARK: If a "BootPath" ARC path is specified, its value takes precedence
|
|
||||||
; over both the "BootDrive" and "BootPartition" values.
|
|
||||||
|
|
||||||
; ["BootSector" OSType] Section Commands:
|
; ["BootSector" OSType] Section Commands:
|
||||||
;
|
;
|
||||||
; BootDrive - BIOS drive number to be used.
|
; BootDrive - BIOS drive number to be used.
|
||||||
; BootPartition - Partition number to be used (cannot be 0).
|
; BootPartition - Partition number to be used (optional).
|
||||||
;
|
;
|
||||||
; REMARK: If a "BootPath" ARC path is specified, its value takes precedence
|
; REMARK: If a "BootPath" ARC path is specified, its value takes precedence
|
||||||
; over both the "BootDrive" and "BootPartition" values.
|
; over both the "BootDrive" and "BootPartition" values.
|
||||||
|
@ -102,7 +90,11 @@
|
||||||
; If none of them are given and a relative file path is specified by the
|
; If none of them are given and a relative file path is specified by the
|
||||||
; "BootSectorFile" value, the default boot partition will be used instead.
|
; "BootSectorFile" value, the default boot partition will be used instead.
|
||||||
;
|
;
|
||||||
; BootSectorFile - File name of the bootsector to be loaded.
|
; When a non-zero partition is specified (either via "BootPartition" or
|
||||||
|
; via the "BootPath" ARC path), the drive is accessed in partitioned mode,
|
||||||
|
; and the "BootSectorFile" option is checked for its presence.
|
||||||
|
;
|
||||||
|
; BootSectorFile - File name of the boot sector to be loaded.
|
||||||
; It can be either relative to "BootDrive" and "BootPartition"
|
; It can be either relative to "BootDrive" and "BootPartition"
|
||||||
; (or to "BootPath"), or be an absolute ARC path, in which case
|
; (or to "BootPath"), or be an absolute ARC path, in which case
|
||||||
; the "BootDrive" and "BootPartition" (or "BootPath") values
|
; the "BootDrive" and "BootPartition" (or "BootPath") values
|
||||||
|
@ -195,6 +187,7 @@ SpecialEffects=Yes
|
||||||
|
|
||||||
[Operating Systems]
|
[Operating Systems]
|
||||||
ReactOSHD="ReactOS (HardDrive)"
|
ReactOSHD="ReactOS (HardDrive)"
|
||||||
|
;ReactOS_Debug="ReactOS (Debug)"
|
||||||
ReactOSFloppy="ReactOS (Floppy)"
|
ReactOSFloppy="ReactOS (Floppy)"
|
||||||
Linux="Debian Linux"
|
Linux="Debian Linux"
|
||||||
Floppy="3 1/2 Floppy (A:)"
|
Floppy="3 1/2 Floppy (A:)"
|
||||||
|
@ -209,6 +202,13 @@ Options=/DEBUGPORT=SCREEN
|
||||||
Kernel=\REACTOS\SYSTEM32\NTOSKRNL.EXE
|
Kernel=\REACTOS\SYSTEM32\NTOSKRNL.EXE
|
||||||
Hal=\REACTOS\SYSTEM32\HAL.DLL
|
Hal=\REACTOS\SYSTEM32\HAL.DLL
|
||||||
|
|
||||||
|
;[ReactOS_Debug]
|
||||||
|
;BootType=Windows2003
|
||||||
|
;SystemPath=multi(0)disk(0)rdisk(0)partition(1)\reactos
|
||||||
|
;Options=/DEBUG /DEBUGPORT=COM1 /BAUDRATE=19200
|
||||||
|
;Kernel=\NTOSKRNL.EXE
|
||||||
|
;Hal=\HAL.DLL
|
||||||
|
|
||||||
; Load ReactOS from floppy (drive A:)
|
; Load ReactOS from floppy (drive A:)
|
||||||
[ReactOSFloppy]
|
[ReactOSFloppy]
|
||||||
BootType=Windows2003
|
BootType=Windows2003
|
||||||
|
@ -217,13 +217,6 @@ Options=/DEBUGPORT=SCREEN
|
||||||
Kernel=\reactos\NTOSKRNL.EXE
|
Kernel=\reactos\NTOSKRNL.EXE
|
||||||
Hal=\reactos\HAL.DLL
|
Hal=\reactos\HAL.DLL
|
||||||
|
|
||||||
;[ReactOS (Debug)]
|
|
||||||
;BootType=Windows2003
|
|
||||||
;SystemPath=multi(0)disk(0)rdisk(0)partition(1)\reactos
|
|
||||||
;Options=/DEBUG /DEBUGPORT=COM1 /BAUDRATE=19200
|
|
||||||
;Kernel=\NTOSKRNL.EXE
|
|
||||||
;Hal=\HAL.DLL
|
|
||||||
|
|
||||||
[Linux]
|
[Linux]
|
||||||
BootType=Linux
|
BootType=Linux
|
||||||
BootPath=multi(0)disk(0)rdisk(1)partition(1)
|
BootPath=multi(0)disk(0)rdisk(1)partition(1)
|
||||||
|
@ -232,16 +225,16 @@ Initrd=/initrd.img
|
||||||
CommandLine="root=/dev/sdb1"
|
CommandLine="root=/dev/sdb1"
|
||||||
|
|
||||||
[Floppy]
|
[Floppy]
|
||||||
BootType=Drive
|
BootType=BootSector
|
||||||
BootDrive=fd0
|
BootDrive=fd0
|
||||||
|
|
||||||
[MSWinders]
|
[MSWinders]
|
||||||
BootType=Partition
|
BootType=BootSector
|
||||||
BootPath=multi(0)disk(0)rdisk(0)partition(1)
|
BootPath=multi(0)disk(0)rdisk(0)partition(1)
|
||||||
;DriveMap=hd1,hd0
|
;DriveMap=hd1,hd0
|
||||||
;DriveMap=hd2,hd0
|
;DriveMap=hd2,hd0
|
||||||
;DriveMap=hd3,hd0
|
;DriveMap=hd3,hd0
|
||||||
|
|
||||||
[DriveD]
|
[DriveD]
|
||||||
BootType=Partition
|
BootType=BootSector
|
||||||
BootPath=multi(0)disk(0)rdisk(1)partition(1)
|
BootPath=multi(0)disk(0)rdisk(1)partition(1)
|
||||||
|
|
|
@ -58,22 +58,48 @@ OSLoadingMethods[] =
|
||||||
|
|
||||||
#if defined(_M_IX86) || defined(_M_AMD64)
|
#if defined(_M_IX86) || defined(_M_AMD64)
|
||||||
#ifndef UEFIBOOT
|
#ifndef UEFIBOOT
|
||||||
{"Drive" , EditCustomBootDisk , LoadAndBootDevice},
|
{"BootSector", EditCustomBootSector, LoadAndBootSector},
|
||||||
{"Partition" , EditCustomBootPartition , LoadAndBootDevice},
|
{"Linux" , EditCustomBootLinux , LoadAndBootLinux },
|
||||||
{"BootSector" , EditCustomBootSectorFile, LoadAndBootDevice},
|
|
||||||
{"Linux" , EditCustomBootLinux, LoadAndBootLinux },
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#ifdef _M_IX86
|
#ifdef _M_IX86
|
||||||
{"WindowsNT40" , EditCustomBootNTOS , LoadAndBootWindows},
|
{"WindowsNT40" , EditCustomBootNTOS, LoadAndBootWindows},
|
||||||
#endif
|
#endif
|
||||||
{"Windows" , EditCustomBootNTOS , LoadAndBootWindows},
|
{"Windows" , EditCustomBootNTOS, LoadAndBootWindows},
|
||||||
{"Windows2003" , EditCustomBootNTOS , LoadAndBootWindows},
|
{"Windows2003" , EditCustomBootNTOS, LoadAndBootWindows},
|
||||||
{"WindowsVista", EditCustomBootNTOS , LoadAndBootWindows},
|
{"WindowsVista", EditCustomBootNTOS, LoadAndBootWindows},
|
||||||
};
|
};
|
||||||
|
|
||||||
/* FUNCTIONS ******************************************************************/
|
/* FUNCTIONS ******************************************************************/
|
||||||
|
|
||||||
|
#ifdef HAS_DEPRECATED_OPTIONS
|
||||||
|
/**
|
||||||
|
* @brief Helper for dealing with DEPRECATED features.
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
WarnDeprecated(
|
||||||
|
_In_ PCSTR MsgFmt,
|
||||||
|
...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
CHAR msgString[300];
|
||||||
|
|
||||||
|
va_start(ap, MsgFmt);
|
||||||
|
RtlStringCbVPrintfA(msgString, sizeof(msgString),
|
||||||
|
MsgFmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
UiMessageBox(
|
||||||
|
" WARNING!\n"
|
||||||
|
"\n"
|
||||||
|
"%s\n"
|
||||||
|
"\n"
|
||||||
|
"Should you need assistance, please contact ReactOS developers\n"
|
||||||
|
"on the official ReactOS Mattermost server <chat.reactos.org>.",
|
||||||
|
msgString);
|
||||||
|
}
|
||||||
|
#endif // HAS_DEPRECATED_OPTIONS
|
||||||
|
|
||||||
static const OS_LOADING_METHOD*
|
static const OS_LOADING_METHOD*
|
||||||
GetOSLoadingMethod(
|
GetOSLoadingMethod(
|
||||||
_In_ ULONG_PTR SectionId)
|
_In_ ULONG_PTR SectionId)
|
||||||
|
@ -90,11 +116,43 @@ GetOSLoadingMethod(
|
||||||
IniReadSettingByName(SectionId, "BootType", BootType, sizeof(BootType));
|
IniReadSettingByName(SectionId, "BootType", BootType, sizeof(BootType));
|
||||||
ASSERT(*BootType);
|
ASSERT(*BootType);
|
||||||
|
|
||||||
|
////
|
||||||
|
#ifdef HAS_DEPRECATED_OPTIONS
|
||||||
|
if ((_stricmp(BootType, "Drive") == 0) ||
|
||||||
|
(_stricmp(BootType, "Partition") == 0))
|
||||||
|
{
|
||||||
|
/* Display the deprecation warning message */
|
||||||
|
WarnDeprecated(
|
||||||
|
"The '%s' configuration you are booting into is no longer\n"
|
||||||
|
"supported and will be removed in future FreeLoader versions.\n"
|
||||||
|
"\n"
|
||||||
|
"Please edit FREELDR.INI to replace all occurrences of\n"
|
||||||
|
"\n"
|
||||||
|
" %*s to:\n"
|
||||||
|
" BootType=%s ------> BootType=BootSector",
|
||||||
|
BootType,
|
||||||
|
strlen(BootType), "", // Indentation
|
||||||
|
BootType);
|
||||||
|
|
||||||
|
/* Type fixup */
|
||||||
|
strcpy(BootType, "BootSector");
|
||||||
|
if (!IniModifySettingValue(SectionId, "BootType", BootType))
|
||||||
|
{
|
||||||
|
ERR("Could not fixup the BootType entry for OS '%s', ignoring.\n",
|
||||||
|
((PINI_SECTION)SectionId)->SectionName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // HAS_DEPRECATED_OPTIONS
|
||||||
|
////
|
||||||
|
|
||||||
/* Find the suitable OS loading method */
|
/* Find the suitable OS loading method */
|
||||||
for (i = 0; ; ++i)
|
for (i = 0; ; ++i)
|
||||||
{
|
{
|
||||||
if (i >= RTL_NUMBER_OF(OSLoadingMethods))
|
if (i >= RTL_NUMBER_OF(OSLoadingMethods))
|
||||||
|
{
|
||||||
|
UiMessageBox("Unknown boot entry type '%s'", BootType);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
if (_stricmp(BootType, OSLoadingMethods[i].BootType) == 0)
|
if (_stricmp(BootType, OSLoadingMethods[i].BootType) == 0)
|
||||||
return &OSLoadingMethods[i];
|
return &OSLoadingMethods[i];
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,27 +24,27 @@
|
||||||
/* GLOBALS ********************************************************************/
|
/* GLOBALS ********************************************************************/
|
||||||
|
|
||||||
#if defined(_M_IX86) || defined(_M_AMD64)
|
#if defined(_M_IX86) || defined(_M_AMD64)
|
||||||
const PCSTR BootSectorFilePrompt =
|
static const PCSTR BootSectorFilePrompt =
|
||||||
"Enter the boot sector file path.\n"
|
"Enter the boot sector file path.\n"
|
||||||
|
"Leave blank for booting a disk or partition.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Examples:\n"
|
"Examples:\n"
|
||||||
"\\BOOTSECT.DOS\n"
|
"\\BOOTSECT.DOS\n"
|
||||||
"/boot/bootsect.dos";
|
"/boot/bootsect.dos";
|
||||||
const PCSTR LinuxKernelPrompt =
|
static const PCSTR LinuxKernelPrompt =
|
||||||
"Enter the Linux kernel image path.\n"
|
"Enter the Linux kernel image path.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Examples:\n"
|
"Examples:\n"
|
||||||
"/vmlinuz\n"
|
"/vmlinuz\n"
|
||||||
"/boot/vmlinuz-2.4.18";
|
"/boot/vmlinuz-2.4.18";
|
||||||
const PCSTR LinuxInitrdPrompt =
|
static const PCSTR LinuxInitrdPrompt =
|
||||||
"Enter the initrd image path.\n"
|
"Enter the initrd image path.\n"
|
||||||
|
"Leave blank for no initial ramdisk.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Examples:\n"
|
"Examples:\n"
|
||||||
"/initrd.gz\n"
|
"/initrd.gz\n"
|
||||||
"/boot/root.img.gz\n"
|
"/boot/root.img.gz";
|
||||||
"\n"
|
static const PCSTR LinuxCommandLinePrompt =
|
||||||
"Leave blank for no initial ram disk.";
|
|
||||||
const PCSTR LinuxCommandLinePrompt =
|
|
||||||
"Enter the Linux kernel command line.\n"
|
"Enter the Linux kernel command line.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Examples:\n"
|
"Examples:\n"
|
||||||
|
@ -53,7 +53,7 @@ const PCSTR LinuxCommandLinePrompt =
|
||||||
"root=/dev/sdb1 init=/sbin/init";
|
"root=/dev/sdb1 init=/sbin/init";
|
||||||
#endif /* _M_IX86 || _M_AMD64 */
|
#endif /* _M_IX86 || _M_AMD64 */
|
||||||
|
|
||||||
const PCSTR BootDrivePrompt =
|
static const PCSTR BootDrivePrompt =
|
||||||
"Enter the boot drive.\n"
|
"Enter the boot drive.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Examples:\n"
|
"Examples:\n"
|
||||||
|
@ -66,25 +66,30 @@ const PCSTR BootDrivePrompt =
|
||||||
"0 - first floppy drive\n"
|
"0 - first floppy drive\n"
|
||||||
"0x80 - first hard drive\n"
|
"0x80 - first hard drive\n"
|
||||||
"0x81 - second hard drive";
|
"0x81 - second hard drive";
|
||||||
const PCSTR BootPartitionPrompt =
|
static const PCSTR BootPartitionPrompt =
|
||||||
"Enter the boot partition.\n"
|
"Enter the boot partition.\n";
|
||||||
"\n"
|
// "\n"
|
||||||
"Enter 0 for the active (bootable) partition.";
|
// "Enter 0 for the active (bootable) partition.";
|
||||||
|
/* NOTE: "Active"/bootable partition is a per-platform concept,
|
||||||
|
* and may not really exist. In addition, partition(0) in ARC
|
||||||
|
* means the whole disk (in non-partitioned access).
|
||||||
|
* Commit f2854a864 (r17736) and CORE-156 are thus inaccurate
|
||||||
|
* in this regard. */
|
||||||
|
|
||||||
const PCSTR ARCPathPrompt =
|
static const PCSTR ARCPathPrompt =
|
||||||
"Enter the boot ARC path.\n"
|
"Enter the boot ARC path.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Examples:\n"
|
"Examples:\n"
|
||||||
"multi(0)disk(0)rdisk(0)partition(1)\n"
|
"multi(0)disk(0)rdisk(0)partition(1)\n"
|
||||||
"multi(0)disk(0)fdisk(0)";
|
"multi(0)disk(0)fdisk(0)";
|
||||||
|
|
||||||
const PCSTR ReactOSSystemPathPrompt =
|
static const PCSTR ReactOSSystemPathPrompt =
|
||||||
"Enter the path to your ReactOS system directory.\n"
|
"Enter the path to your ReactOS system directory.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Examples:\n"
|
"Examples:\n"
|
||||||
"\\REACTOS\n"
|
"\\REACTOS\n"
|
||||||
"\\ROS";
|
"\\ROS";
|
||||||
const PCSTR ReactOSOptionsPrompt =
|
static const PCSTR ReactOSOptionsPrompt =
|
||||||
"Enter the load options you want passed to the kernel.\n"
|
"Enter the load options you want passed to the kernel.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Examples:\n"
|
"Examples:\n"
|
||||||
|
@ -92,7 +97,7 @@ const PCSTR ReactOSOptionsPrompt =
|
||||||
"/FASTDETECT /SOS /NOGUIBOOT\n"
|
"/FASTDETECT /SOS /NOGUIBOOT\n"
|
||||||
"/BASEVIDEO /MAXMEM=64\n"
|
"/BASEVIDEO /MAXMEM=64\n"
|
||||||
"/KERNEL=NTKRNLMP.EXE /HAL=HALMPS.DLL";
|
"/KERNEL=NTKRNLMP.EXE /HAL=HALMPS.DLL";
|
||||||
const PCSTR ReactOSSetupOptionsPrompt =
|
static const PCSTR ReactOSSetupOptionsPrompt =
|
||||||
"Enter additional load options you want passed to the ReactOS Setup.\n"
|
"Enter additional load options you want passed to the ReactOS Setup.\n"
|
||||||
"These options will supplement those obtained from the TXTSETUP.SIF\n"
|
"These options will supplement those obtained from the TXTSETUP.SIF\n"
|
||||||
"file, unless you also specify the /SIFOPTIONSOVERRIDE option switch.\n"
|
"file, unless you also specify the /SIFOPTIONSOVERRIDE option switch.\n"
|
||||||
|
@ -100,7 +105,7 @@ const PCSTR ReactOSSetupOptionsPrompt =
|
||||||
"Example:\n"
|
"Example:\n"
|
||||||
"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /NOGUIBOOT";
|
"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /NOGUIBOOT";
|
||||||
|
|
||||||
const PCSTR CustomBootPrompt =
|
static const PCSTR CustomBootPrompt =
|
||||||
"Press ENTER to boot your custom boot setup.";
|
"Press ENTER to boot your custom boot setup.";
|
||||||
|
|
||||||
/* FUNCTIONS ******************************************************************/
|
/* FUNCTIONS ******************************************************************/
|
||||||
|
@ -111,9 +116,7 @@ VOID OptionMenuCustomBoot(VOID)
|
||||||
{
|
{
|
||||||
PCSTR CustomBootMenuList[] = {
|
PCSTR CustomBootMenuList[] = {
|
||||||
#if defined(_M_IX86) || defined(_M_AMD64)
|
#if defined(_M_IX86) || defined(_M_AMD64)
|
||||||
"Disk",
|
"Boot Sector (Disk/Partition/File)",
|
||||||
"Partition",
|
|
||||||
"Boot Sector File",
|
|
||||||
"Linux",
|
"Linux",
|
||||||
#endif
|
#endif
|
||||||
"ReactOS",
|
"ReactOS",
|
||||||
|
@ -140,22 +143,16 @@ VOID OptionMenuCustomBoot(VOID)
|
||||||
switch (SelectedMenuItem)
|
switch (SelectedMenuItem)
|
||||||
{
|
{
|
||||||
#if defined(_M_IX86) || defined(_M_AMD64)
|
#if defined(_M_IX86) || defined(_M_AMD64)
|
||||||
case 0: // Disk
|
case 0: // Boot Sector (Disk/Partition/File)
|
||||||
EditCustomBootDisk(&OperatingSystem);
|
EditCustomBootSector(&OperatingSystem);
|
||||||
break;
|
break;
|
||||||
case 1: // Partition
|
case 1: // Linux
|
||||||
EditCustomBootPartition(&OperatingSystem);
|
|
||||||
break;
|
|
||||||
case 2: // Boot Sector File
|
|
||||||
EditCustomBootSectorFile(&OperatingSystem);
|
|
||||||
break;
|
|
||||||
case 3: // Linux
|
|
||||||
EditCustomBootLinux(&OperatingSystem);
|
EditCustomBootLinux(&OperatingSystem);
|
||||||
break;
|
break;
|
||||||
case 4: // ReactOS
|
case 2: // ReactOS
|
||||||
EditCustomBootReactOS(&OperatingSystem, FALSE);
|
EditCustomBootReactOS(&OperatingSystem, FALSE);
|
||||||
break;
|
break;
|
||||||
case 5: // ReactOS Setup
|
case 3: // ReactOS Setup
|
||||||
EditCustomBootReactOS(&OperatingSystem, TRUE);
|
EditCustomBootReactOS(&OperatingSystem, TRUE);
|
||||||
break;
|
break;
|
||||||
#else
|
#else
|
||||||
|
@ -181,103 +178,8 @@ VOID OptionMenuCustomBoot(VOID)
|
||||||
#if defined(_M_IX86) || defined(_M_AMD64)
|
#if defined(_M_IX86) || defined(_M_AMD64)
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
EditCustomBootDisk(
|
EditCustomBootSector(
|
||||||
IN OUT OperatingSystemItem* OperatingSystem)
|
_Inout_ OperatingSystemItem* OperatingSystem)
|
||||||
{
|
|
||||||
TIMEINFO* TimeInfo;
|
|
||||||
ULONG_PTR SectionId = OperatingSystem->SectionId;
|
|
||||||
CHAR SectionName[100];
|
|
||||||
/* This construct 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(&BootStrings, sizeof(BootStrings));
|
|
||||||
|
|
||||||
if (SectionId != 0)
|
|
||||||
{
|
|
||||||
/* Load the settings */
|
|
||||||
|
|
||||||
/* 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 (!*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)
|
|
||||||
{
|
|
||||||
/* 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Generate a unique section name */
|
|
||||||
TimeInfo = ArcGetTime();
|
|
||||||
RtlStringCbPrintfA(SectionName, sizeof(SectionName),
|
|
||||||
"CustomBootDisk%u%u%u%u%u%u",
|
|
||||||
TimeInfo->Year, TimeInfo->Day, TimeInfo->Month,
|
|
||||||
TimeInfo->Hour, TimeInfo->Minute, TimeInfo->Second);
|
|
||||||
|
|
||||||
/* Add the section */
|
|
||||||
if (!IniAddSection(SectionName, &SectionId))
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Add the BootType */
|
|
||||||
if (!IniAddSettingValueToSection(SectionId, "BootType", "Drive"))
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Add the BootPath if we have one */
|
|
||||||
if (*BootStrings.ArcPath)
|
|
||||||
{
|
|
||||||
if (!IniAddSettingValueToSection(SectionId, "BootPath", BootStrings.ArcPath))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if (*BootStrings.Drive)
|
|
||||||
{
|
|
||||||
/* Otherwise, add the BootDrive */
|
|
||||||
if (!IniAddSettingValueToSection(SectionId, "BootDrive", BootStrings.Drive))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
OperatingSystem->SectionId = SectionId;
|
|
||||||
OperatingSystem->LoadIdentifier = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID
|
|
||||||
EditCustomBootPartition(
|
|
||||||
IN OUT OperatingSystemItem* OperatingSystem)
|
|
||||||
{
|
{
|
||||||
TIMEINFO* TimeInfo;
|
TIMEINFO* TimeInfo;
|
||||||
ULONG_PTR SectionId = OperatingSystem->SectionId;
|
ULONG_PTR SectionId = OperatingSystem->SectionId;
|
||||||
|
@ -294,9 +196,11 @@ EditCustomBootPartition(
|
||||||
};
|
};
|
||||||
CHAR ArcPath[200];
|
CHAR ArcPath[200];
|
||||||
} BootStrings;
|
} BootStrings;
|
||||||
|
CHAR BootSectorFile[200];
|
||||||
|
|
||||||
RtlZeroMemory(SectionName, sizeof(SectionName));
|
RtlZeroMemory(SectionName, sizeof(SectionName));
|
||||||
RtlZeroMemory(&BootStrings, sizeof(BootStrings));
|
RtlZeroMemory(&BootStrings, sizeof(BootStrings));
|
||||||
|
RtlZeroMemory(BootSectorFile, sizeof(BootSectorFile));
|
||||||
|
|
||||||
if (SectionId != 0)
|
if (SectionId != 0)
|
||||||
{
|
{
|
||||||
|
@ -314,6 +218,9 @@ EditCustomBootPartition(
|
||||||
IniReadSettingByName(SectionId, "BootDrive", BootStrings.Drive, sizeof(BootStrings.Drive));
|
IniReadSettingByName(SectionId, "BootDrive", BootStrings.Drive, sizeof(BootStrings.Drive));
|
||||||
IniReadSettingByName(SectionId, "BootPartition", BootStrings.Partition, sizeof(BootStrings.Partition));
|
IniReadSettingByName(SectionId, "BootPartition", BootStrings.Partition, sizeof(BootStrings.Partition));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Always load the file name; it will only be handled later if a partition has been specified */
|
||||||
|
IniReadSettingByName(SectionId, "BootSectorFile", BootSectorFile, sizeof(BootSectorFile));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!*BootStrings.ArcPath)
|
if (!*BootStrings.ArcPath)
|
||||||
|
@ -333,122 +240,15 @@ EditCustomBootPartition(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Modify the settings values and return if we were in edit mode */
|
/* Edit the file name only if a partition has been specified */
|
||||||
if (SectionId != 0)
|
if ((!*BootStrings.ArcPath && atoi(BootStrings.Partition) != 0) ||
|
||||||
|
(*BootStrings.ArcPath && !strstr(BootStrings.ArcPath, ")partition()") &&
|
||||||
|
!strstr(BootStrings.ArcPath, ")partition(0)")))
|
||||||
{
|
{
|
||||||
/* Modify the BootPath if we have one */
|
if (!UiEditBox(BootSectorFilePrompt, BootSectorFile, sizeof(BootSectorFile)))
|
||||||
if (*BootStrings.ArcPath)
|
|
||||||
{
|
|
||||||
IniModifySettingValue(SectionId, "BootPath", BootStrings.ArcPath);
|
|
||||||
}
|
|
||||||
else if (*BootStrings.Drive)
|
|
||||||
{
|
|
||||||
/* Otherwise, modify the BootDrive and BootPartition */
|
|
||||||
IniModifySettingValue(SectionId, "BootDrive", BootStrings.Drive);
|
|
||||||
IniModifySettingValue(SectionId, "BootPartition", BootStrings.Partition);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Generate a unique section name */
|
|
||||||
TimeInfo = ArcGetTime();
|
|
||||||
RtlStringCbPrintfA(SectionName, sizeof(SectionName),
|
|
||||||
"CustomBootPartition%u%u%u%u%u%u",
|
|
||||||
TimeInfo->Year, TimeInfo->Day, TimeInfo->Month,
|
|
||||||
TimeInfo->Hour, TimeInfo->Minute, TimeInfo->Second);
|
|
||||||
|
|
||||||
/* Add the section */
|
|
||||||
if (!IniAddSection(SectionName, &SectionId))
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Add the BootType */
|
|
||||||
if (!IniAddSettingValueToSection(SectionId, "BootType", "Partition"))
|
|
||||||
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;
|
|
||||||
|
|
||||||
if (!IniAddSettingValueToSection(SectionId, "BootPartition", BootStrings.Partition))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
OperatingSystem->SectionId = SectionId;
|
|
||||||
OperatingSystem->LoadIdentifier = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID
|
|
||||||
EditCustomBootSectorFile(
|
|
||||||
IN OUT OperatingSystemItem* OperatingSystem)
|
|
||||||
{
|
|
||||||
TIMEINFO* TimeInfo;
|
|
||||||
ULONG_PTR SectionId = OperatingSystem->SectionId;
|
|
||||||
CHAR SectionName[100];
|
|
||||||
/* This construct 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(&BootStrings, sizeof(BootStrings));
|
|
||||||
RtlZeroMemory(BootSectorFileString, sizeof(BootSectorFileString));
|
|
||||||
|
|
||||||
if (SectionId != 0)
|
|
||||||
{
|
|
||||||
/* Load the settings */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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 (!*BootStrings.ArcPath)
|
|
||||||
{
|
|
||||||
if (!UiEditBox(BootDrivePrompt, BootStrings.Drive, sizeof(BootStrings.Drive)))
|
|
||||||
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 */
|
/* Modify the settings values and return if we were in edit mode */
|
||||||
if (SectionId != 0)
|
if (SectionId != 0)
|
||||||
|
@ -467,22 +267,23 @@ EditCustomBootSectorFile(
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Otherwise, zero out all values: BootSectorFile will be
|
* Otherwise, reset all values: BootSectorFile
|
||||||
* relative to the default system partition.
|
* will be relative to the default system partition.
|
||||||
*/
|
*/
|
||||||
IniModifySettingValue(SectionId, "BootPath", "");
|
IniModifySettingValue(SectionId, "BootPath", "");
|
||||||
IniModifySettingValue(SectionId, "BootDrive", "");
|
IniModifySettingValue(SectionId, "BootDrive", "");
|
||||||
IniModifySettingValue(SectionId, "BootPartition", "");
|
IniModifySettingValue(SectionId, "BootPartition", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
IniModifySettingValue(SectionId, "BootSectorFile", BootSectorFileString);
|
/* Always write back the file name */
|
||||||
|
IniModifySettingValue(SectionId, "BootSectorFile", BootSectorFile);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Generate a unique section name */
|
/* Generate a unique section name */
|
||||||
TimeInfo = ArcGetTime();
|
TimeInfo = ArcGetTime();
|
||||||
RtlStringCbPrintfA(SectionName, sizeof(SectionName),
|
RtlStringCbPrintfA(SectionName, sizeof(SectionName),
|
||||||
"CustomBootSectorFile%u%u%u%u%u%u",
|
"CustomBootSector%u%u%u%u%u%u",
|
||||||
TimeInfo->Year, TimeInfo->Day, TimeInfo->Month,
|
TimeInfo->Year, TimeInfo->Day, TimeInfo->Month,
|
||||||
TimeInfo->Hour, TimeInfo->Minute, TimeInfo->Second);
|
TimeInfo->Hour, TimeInfo->Minute, TimeInfo->Second);
|
||||||
|
|
||||||
|
@ -510,9 +311,12 @@ EditCustomBootSectorFile(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add the BootSectorFile */
|
/* Add the BootSectorFile if any */
|
||||||
if (!IniAddSettingValueToSection(SectionId, "BootSectorFile", BootSectorFileString))
|
if (*BootSectorFile)
|
||||||
|
{
|
||||||
|
if (!IniAddSettingValueToSection(SectionId, "BootSectorFile", BootSectorFile))
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
OperatingSystem->SectionId = SectionId;
|
OperatingSystem->SectionId = SectionId;
|
||||||
OperatingSystem->LoadIdentifier = NULL;
|
OperatingSystem->LoadIdentifier = NULL;
|
||||||
|
@ -612,8 +416,8 @@ EditCustomBootLinux(
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Otherwise, zero out all values: BootSectorFile will be
|
* Otherwise, reset all values: the files will
|
||||||
* relative to the default system partition.
|
* be relative to the default system partition.
|
||||||
*/
|
*/
|
||||||
IniModifySettingValue(SectionId, "BootPath", "");
|
IniModifySettingValue(SectionId, "BootPath", "");
|
||||||
IniModifySettingValue(SectionId, "BootDrive", "");
|
IniModifySettingValue(SectionId, "BootDrive", "");
|
||||||
|
|
|
@ -30,16 +30,8 @@ VOID OptionMenuCustomBoot(VOID);
|
||||||
#if defined(_M_IX86) || defined(_M_AMD64)
|
#if defined(_M_IX86) || defined(_M_AMD64)
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
EditCustomBootDisk(
|
EditCustomBootSector(
|
||||||
IN OUT OperatingSystemItem* OperatingSystem);
|
_Inout_ OperatingSystemItem* OperatingSystem);
|
||||||
|
|
||||||
VOID
|
|
||||||
EditCustomBootPartition(
|
|
||||||
IN OUT OperatingSystemItem* OperatingSystem);
|
|
||||||
|
|
||||||
VOID
|
|
||||||
EditCustomBootSectorFile(
|
|
||||||
IN OUT OperatingSystemItem* OperatingSystem);
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
EditCustomBootLinux(
|
EditCustomBootLinux(
|
||||||
|
|
|
@ -20,6 +20,10 @@
|
||||||
#ifndef __FREELDR_H
|
#ifndef __FREELDR_H
|
||||||
#define __FREELDR_H
|
#define __FREELDR_H
|
||||||
|
|
||||||
|
/* Enabled for supporting the deprecated boot options
|
||||||
|
* that will be removed in a future FreeLdr version */
|
||||||
|
#define HAS_DEPRECATED_OPTIONS
|
||||||
|
|
||||||
#define UINT64_C(val) val##ULL
|
#define UINT64_C(val) val##ULL
|
||||||
#define RVA(m, b) ((PVOID)((ULONG_PTR)(b) + (ULONG_PTR)(m)))
|
#define RVA(m, b) ((PVOID)((ULONG_PTR)(b) + (ULONG_PTR)(m)))
|
||||||
|
|
||||||
|
@ -126,6 +130,13 @@
|
||||||
|
|
||||||
VOID __cdecl BootMain(IN PCCH CmdLine);
|
VOID __cdecl BootMain(IN PCCH CmdLine);
|
||||||
|
|
||||||
|
#ifdef HAS_DEPRECATED_OPTIONS
|
||||||
|
VOID
|
||||||
|
WarnDeprecated(
|
||||||
|
_In_ PCSTR MsgFmt,
|
||||||
|
...);
|
||||||
|
#endif
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
LoadOperatingSystem(
|
LoadOperatingSystem(
|
||||||
_In_ OperatingSystemItem* OperatingSystem);
|
_In_ OperatingSystemItem* OperatingSystem);
|
||||||
|
|
|
@ -22,9 +22,9 @@
|
||||||
#if defined(_M_IX86) || defined(_M_AMD64)
|
#if defined(_M_IX86) || defined(_M_AMD64)
|
||||||
|
|
||||||
ARC_STATUS
|
ARC_STATUS
|
||||||
LoadAndBootDevice(
|
LoadAndBootSector(
|
||||||
IN ULONG Argc,
|
_In_ ULONG Argc,
|
||||||
IN PCHAR Argv[],
|
_In_ PCHAR Argv[],
|
||||||
IN PCHAR Envp[]);
|
_In_ PCHAR Envp[]);
|
||||||
|
|
||||||
#endif /* _M_IX86 || _M_AMD64 */
|
#endif /* _M_IX86 || _M_AMD64 */
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
/* Just some stuff */
|
/* Just some stuff */
|
||||||
#define VERSION "FreeLoader v3.0"
|
#define VERSION "FreeLoader v3.2"
|
||||||
#define COPYRIGHT "Copyright (C) 1996-" COPYRIGHT_YEAR " ReactOS Project"
|
#define COPYRIGHT "Copyright (C) 1996-" COPYRIGHT_YEAR " ReactOS Project"
|
||||||
#define AUTHOR_EMAIL "<www.reactos.org>"
|
#define AUTHOR_EMAIL "<www.reactos.org>"
|
||||||
#define BY_AUTHOR "by ReactOS Project"
|
#define BY_AUTHOR "by ReactOS Project"
|
||||||
|
@ -33,7 +33,7 @@
|
||||||
// If you add major functionality then you increment the major version and zero the minor & patch versions
|
// If you add major functionality then you increment the major version and zero the minor & patch versions
|
||||||
//
|
//
|
||||||
#define FREELOADER_MAJOR_VERSION 3
|
#define FREELOADER_MAJOR_VERSION 3
|
||||||
#define FREELOADER_MINOR_VERSION 0
|
#define FREELOADER_MINOR_VERSION 2
|
||||||
#define FREELOADER_PATCH_VERSION 0
|
#define FREELOADER_PATCH_VERSION 0
|
||||||
|
|
||||||
extern const PCSTR FrLdrVersionString;
|
extern const PCSTR FrLdrVersionString;
|
||||||
|
|
|
@ -23,26 +23,44 @@
|
||||||
|
|
||||||
#include <freeldr.h>
|
#include <freeldr.h>
|
||||||
|
|
||||||
|
#include <debug.h>
|
||||||
|
DBG_DEFAULT_CHANNEL(DISK);
|
||||||
|
|
||||||
/* FUNCTIONS ******************************************************************/
|
/* FUNCTIONS ******************************************************************/
|
||||||
|
|
||||||
static ARC_STATUS
|
/**
|
||||||
LoadBootSector(
|
* @brief
|
||||||
IN ULONG Argc,
|
* Loads and boots a disk MBR, a partition VBR or a file boot sector.
|
||||||
IN PCHAR Argv[],
|
**/
|
||||||
OUT PUCHAR DriveNumber,
|
ARC_STATUS
|
||||||
OUT PULONG PartitionNumber)
|
LoadAndBootSector(
|
||||||
|
_In_ ULONG Argc,
|
||||||
|
_In_ PCHAR Argv[],
|
||||||
|
_In_ PCHAR Envp[])
|
||||||
{
|
{
|
||||||
ARC_STATUS Status;
|
ARC_STATUS Status;
|
||||||
PCSTR ArgValue;
|
PCSTR ArgValue;
|
||||||
PCSTR BootPath;
|
PCSTR BootPath;
|
||||||
PCSTR FileName;
|
PCSTR FileName;
|
||||||
|
UCHAR BiosDriveNumber = 0;
|
||||||
|
ULONG PartitionNumber = 0;
|
||||||
|
ULONG LoadAddress;
|
||||||
ULONG FileId;
|
ULONG FileId;
|
||||||
ULONG BytesRead;
|
ULONG BytesRead;
|
||||||
CHAR ArcPath[MAX_PATH];
|
CHAR ArcPath[MAX_PATH];
|
||||||
ULONG LoadAddress;
|
|
||||||
|
|
||||||
*DriveNumber = 0;
|
#if DBG
|
||||||
*PartitionNumber = 0;
|
/* Ensure the boot type is the one expected */
|
||||||
|
ArgValue = GetArgumentValue(Argc, Argv, "BootType");
|
||||||
|
if (!ArgValue || !*ArgValue || _stricmp(ArgValue, "BootSector") != 0)
|
||||||
|
{
|
||||||
|
ERR("Unexpected boot type '%s', aborting\n", ArgValue ? ArgValue : "n/a");
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Find all the message box settings and run them */
|
||||||
|
UiShowMessageBoxesInArgv(Argc, Argv);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check whether we have a "BootPath" value (takes precedence
|
* Check whether we have a "BootPath" value (takes precedence
|
||||||
|
@ -57,24 +75,13 @@ LoadBootSector(
|
||||||
ArgValue = GetArgumentValue(Argc, Argv, "BootDrive");
|
ArgValue = GetArgumentValue(Argc, Argv, "BootDrive");
|
||||||
if (ArgValue && *ArgValue)
|
if (ArgValue && *ArgValue)
|
||||||
{
|
{
|
||||||
*DriveNumber = DriveMapGetBiosDriveNumber(ArgValue);
|
BiosDriveNumber = DriveMapGetBiosDriveNumber(ArgValue);
|
||||||
|
|
||||||
/* Retrieve the boot partition (not optional and cannot be zero) */
|
/* Retrieve the boot partition (optional, fall back to zero otherwise) */
|
||||||
*PartitionNumber = 0;
|
PartitionNumber = 0;
|
||||||
ArgValue = GetArgumentValue(Argc, Argv, "BootPartition");
|
ArgValue = GetArgumentValue(Argc, Argv, "BootPartition");
|
||||||
if (ArgValue && *ArgValue)
|
if (ArgValue && *ArgValue)
|
||||||
*PartitionNumber = atoi(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
|
else
|
||||||
{
|
{
|
||||||
|
@ -83,268 +90,122 @@ LoadBootSector(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Retrieve the file name */
|
|
||||||
FileName = GetArgumentValue(Argc, Argv, "BootSectorFile");
|
|
||||||
if (!FileName || !*FileName)
|
|
||||||
{
|
|
||||||
UiMessageBox("Boot sector file not specified for selected OS!");
|
|
||||||
return EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Open the boot sector file */
|
|
||||||
Status = FsOpenFile(FileName, BootPath, OpenReadOnly, &FileId);
|
|
||||||
if (Status != ESUCCESS)
|
|
||||||
{
|
|
||||||
UiMessageBox("Unable to open %s", FileName);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(SARCH_PC98)
|
|
||||||
LoadAddress = Pc98GetBootSectorLoadAddress(*DriveNumber);
|
|
||||||
#else
|
|
||||||
LoadAddress = 0x7C00;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Now try to load the boot sector. If this fails then abort. */
|
|
||||||
Status = ArcRead(FileId, UlongToPtr(LoadAddress), 512, &BytesRead);
|
|
||||||
ArcClose(FileId);
|
|
||||||
if ((Status != ESUCCESS) || (BytesRead != 512))
|
|
||||||
{
|
|
||||||
UiMessageBox("Unable to load boot sector.");
|
|
||||||
return EIO;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check for validity */
|
|
||||||
if (*(USHORT*)UlongToPtr(LoadAddress + 0x1FE) != 0xAA55)
|
|
||||||
{
|
|
||||||
UiMessageBox("Invalid boot sector magic (0xaa55)");
|
|
||||||
return ENOEXEC;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Reset the drive and partition numbers so as to use their default values */
|
|
||||||
*DriveNumber = 0;
|
|
||||||
*PartitionNumber = 0;
|
|
||||||
|
|
||||||
return ESUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ARC_STATUS
|
|
||||||
LoadPartitionOrDrive(
|
|
||||||
IN OUT PUCHAR DriveNumber,
|
|
||||||
IN OUT PULONG PartitionNumber,
|
|
||||||
IN PCSTR BootPath OPTIONAL)
|
|
||||||
{
|
|
||||||
ARC_STATUS Status;
|
|
||||||
ULONG FileId;
|
|
||||||
ULONG BytesRead;
|
|
||||||
CHAR ArcPath[MAX_PATH];
|
|
||||||
ULONG LoadAddress;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The ARC "BootPath" value takes precedence over
|
* The ARC "BootPath" value takes precedence over
|
||||||
* both the DriveNumber and PartitionNumber options.
|
* both the BiosDriveNumber and PartitionNumber options.
|
||||||
*/
|
*/
|
||||||
if (BootPath && *BootPath)
|
if (BootPath && *BootPath)
|
||||||
{
|
{
|
||||||
PCSTR FileName = NULL;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Retrieve the BIOS drive and partition numbers; verify also that the
|
* 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.
|
* path is "valid" in the sense that it must not contain any file name.
|
||||||
*/
|
*/
|
||||||
if (!DissectArcPath(BootPath, &FileName, DriveNumber, PartitionNumber) ||
|
FileName = NULL;
|
||||||
|
if (!DissectArcPath(BootPath, &FileName, &BiosDriveNumber, &PartitionNumber) ||
|
||||||
(FileName && *FileName))
|
(FileName && *FileName))
|
||||||
{
|
{
|
||||||
|
UiMessageBox("Currently unsupported BootPath value:\n%s", BootPath);
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* We don't have one, so construct the corresponding ARC path */
|
/* We don't have one, so construct the corresponding ARC path */
|
||||||
ConstructArcPath(ArcPath, "", *DriveNumber, *PartitionNumber);
|
ConstructArcPath(ArcPath, "", BiosDriveNumber, PartitionNumber);
|
||||||
*strrchr(ArcPath, '\\') = ANSI_NULL; // Trim the trailing path separator.
|
*strrchr(ArcPath, '\\') = ANSI_NULL; // Trim the trailing path separator.
|
||||||
|
|
||||||
BootPath = ArcPath;
|
BootPath = ArcPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Open the volume */
|
FileName = NULL;
|
||||||
|
if (strstr(BootPath, ")partition()") || strstr(BootPath, ")partition(0)"))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* The partition specifier is zero i.e. the device is accessed
|
||||||
|
* in an unpartitioned fashion, do not retrieve a file name.
|
||||||
|
*
|
||||||
|
* NOTE: If we access a floppy drive, we would not have a
|
||||||
|
* partition specifier, and PartitionNumber would be == 0,
|
||||||
|
* so don't check explicitly for PartitionNumber because
|
||||||
|
* we want to retrieve a file name.
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Retrieve the file name, if any, and normalize
|
||||||
|
* the pointer to make subsequent tests simpler */
|
||||||
|
FileName = GetArgumentValue(Argc, Argv, "BootSectorFile");
|
||||||
|
if (FileName && !*FileName)
|
||||||
|
FileName = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* If we load a boot sector file, reset the drive number
|
||||||
|
* so as to use the original boot drive/partition */
|
||||||
|
if (FileName)
|
||||||
|
BiosDriveNumber = 0;
|
||||||
|
if (!BiosDriveNumber)
|
||||||
|
{
|
||||||
|
BiosDriveNumber = FrldrBootDrive;
|
||||||
|
PartitionNumber = FrldrBootPartition;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Open the boot sector file or the volume */
|
||||||
|
if (FileName)
|
||||||
|
Status = FsOpenFile(FileName, BootPath, OpenReadOnly, &FileId);
|
||||||
|
else
|
||||||
Status = ArcOpen((PSTR)BootPath, OpenReadOnly, &FileId);
|
Status = ArcOpen((PSTR)BootPath, OpenReadOnly, &FileId);
|
||||||
if (Status != ESUCCESS)
|
if (Status != ESUCCESS)
|
||||||
{
|
{
|
||||||
UiMessageBox("Unable to open %s", BootPath);
|
UiMessageBox("Unable to open %s", FileName ? FileName : BootPath);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(SARCH_PC98)
|
#if defined(SARCH_PC98)
|
||||||
LoadAddress = Pc98GetBootSectorLoadAddress(*DriveNumber);
|
LoadAddress = Pc98GetBootSectorLoadAddress(BiosDriveNumber);
|
||||||
#else
|
#else
|
||||||
LoadAddress = 0x7C00;
|
LoadAddress = 0x7C00;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now try to load the partition boot sector or the MBR (when PartitionNumber == 0).
|
* Now try to load the boot sector: disk MBR (when PartitionNumber == 0),
|
||||||
* If this fails then abort.
|
* partition VBR or boot sector file. If this fails, abort.
|
||||||
*/
|
*/
|
||||||
Status = ArcRead(FileId, UlongToPtr(LoadAddress), 512, &BytesRead);
|
Status = ArcRead(FileId, UlongToPtr(LoadAddress), 512, &BytesRead);
|
||||||
ArcClose(FileId);
|
ArcClose(FileId);
|
||||||
if ((Status != ESUCCESS) || (BytesRead != 512))
|
if ((Status != ESUCCESS) || (BytesRead != 512))
|
||||||
{
|
{
|
||||||
if (*PartitionNumber != 0)
|
PCSTR WhatFailed;
|
||||||
UiMessageBox("Unable to load partition's boot sector.");
|
|
||||||
|
if (FileName)
|
||||||
|
WhatFailed = "boot sector file";
|
||||||
|
else if (PartitionNumber != 0)
|
||||||
|
WhatFailed = "partition's boot sector";
|
||||||
else
|
else
|
||||||
UiMessageBox("Unable to load MBR boot sector.");
|
WhatFailed = "MBR boot sector";
|
||||||
|
|
||||||
|
UiMessageBox("Unable to load %s.", WhatFailed);
|
||||||
return EIO;
|
return EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for validity */
|
/* Check for validity */
|
||||||
if (*(USHORT*)UlongToPtr(LoadAddress + 0x1FE) != 0xAA55)
|
if (*(USHORT*)UlongToPtr(LoadAddress + 0x1FE) != 0xAA55)
|
||||||
{
|
{
|
||||||
UiMessageBox("Invalid boot sector magic (0xaa55)");
|
UiMessageBox("Invalid boot sector magic (0xAA55)");
|
||||||
return ENOEXEC;
|
return ENOEXEC;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ESUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ARC_STATUS
|
|
||||||
LoadPartition(
|
|
||||||
IN ULONG Argc,
|
|
||||||
IN PCHAR Argv[],
|
|
||||||
OUT PUCHAR DriveNumber,
|
|
||||||
OUT PULONG PartitionNumber)
|
|
||||||
{
|
|
||||||
PCSTR ArgValue;
|
|
||||||
PCSTR BootPath;
|
|
||||||
|
|
||||||
*DriveNumber = 0;
|
|
||||||
*PartitionNumber = 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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 */
|
|
||||||
|
|
||||||
/* 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
return LoadPartitionOrDrive(DriveNumber, PartitionNumber, BootPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ARC_STATUS
|
|
||||||
LoadDrive(
|
|
||||||
IN ULONG Argc,
|
|
||||||
IN PCHAR Argv[],
|
|
||||||
OUT PUCHAR DriveNumber,
|
|
||||||
OUT PULONG PartitionNumber)
|
|
||||||
{
|
|
||||||
PCSTR ArgValue;
|
|
||||||
PCSTR BootPath;
|
|
||||||
|
|
||||||
*DriveNumber = 0;
|
|
||||||
*PartitionNumber = 0;
|
|
||||||
|
|
||||||
/* Check whether we have a "BootPath" value (takes precedence over "BootDrive") */
|
|
||||||
BootPath = GetArgumentValue(Argc, Argv, "BootPath");
|
|
||||||
if (BootPath && *BootPath)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
return LoadPartitionOrDrive(DriveNumber, PartitionNumber, BootPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ARC_STATUS
|
|
||||||
LoadAndBootDevice(
|
|
||||||
IN ULONG Argc,
|
|
||||||
IN PCHAR Argv[],
|
|
||||||
IN PCHAR Envp[])
|
|
||||||
{
|
|
||||||
ARC_STATUS Status;
|
|
||||||
PCSTR ArgValue;
|
|
||||||
UCHAR Type;
|
|
||||||
UCHAR DriveNumber = 0;
|
|
||||||
ULONG PartitionNumber = 0;
|
|
||||||
|
|
||||||
/* Retrieve the (mandatory) boot type */
|
|
||||||
ArgValue = GetArgumentValue(Argc, Argv, "BootType");
|
|
||||||
if (!ArgValue || !*ArgValue)
|
|
||||||
return EINVAL;
|
|
||||||
if (_stricmp(ArgValue, "Drive") == 0)
|
|
||||||
Type = 1;
|
|
||||||
else if (_stricmp(ArgValue, "Partition") == 0)
|
|
||||||
Type = 2;
|
|
||||||
else if (_stricmp(ArgValue, "BootSector") == 0)
|
|
||||||
Type = 3;
|
|
||||||
else
|
|
||||||
return EINVAL;
|
|
||||||
|
|
||||||
/* Find all the message box settings and run them */
|
|
||||||
UiShowMessageBoxesInArgv(Argc, Argv);
|
|
||||||
|
|
||||||
/* Load the corresponding device */
|
|
||||||
switch (Type)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
Status = LoadDrive(Argc, Argv, &DriveNumber, &PartitionNumber);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
Status = LoadPartition(Argc, Argv, &DriveNumber, &PartitionNumber);
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
Status = LoadBootSector(Argc, Argv, &DriveNumber, &PartitionNumber);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return EINVAL;
|
|
||||||
}
|
|
||||||
if (Status != ESUCCESS)
|
|
||||||
return Status;
|
|
||||||
|
|
||||||
UiUnInitialize("Booting...");
|
UiUnInitialize("Booting...");
|
||||||
IniCleanup();
|
IniCleanup();
|
||||||
|
|
||||||
#ifndef UEFIBOOT
|
#ifndef UEFIBOOT
|
||||||
/* Boot the loaded sector code */
|
/* Boot the loaded sector code */
|
||||||
ChainLoadBiosBootSectorCode(DriveNumber, PartitionNumber);
|
ChainLoadBiosBootSectorCode(BiosDriveNumber, PartitionNumber);
|
||||||
#endif
|
#endif
|
||||||
/* Must not return! */
|
/* Must not return! */
|
||||||
return ESUCCESS;
|
return ESUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* _M_IX86 || _M_AMD64 */
|
#endif /* _M_IX86 || _M_AMD64 */
|
||||||
|
|
||||||
|
/* EOF */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue