diff --git a/boot/freeldr/FREELDR.INI b/boot/freeldr/FREELDR.INI index 1887ac78017..1f8a4895640 100644 --- a/boot/freeldr/FREELDR.INI +++ b/boot/freeldr/FREELDR.INI @@ -64,36 +64,24 @@ ; DarkGray, LightBlue, LightGreen, LightCyan, LightRed, LightMagenta, ; 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. ; [OS-General] Section Commands: ; -; BootType - Specifies the boot type: Windows, WindowsNT40, Windows2003, -; ReactOSSetup, Linux, BootSector, Partition, Drive +; BootType - Specifies the boot type: BootSector, Linux, +; Windows, WindowsNT40, Windows2003, ReactOSSetup. +; ; 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. -; -; REMARK: If a "BootPath" ARC path is specified, its value takes precedence -; 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. +; 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; +; or DriveMap=fd1,fd0 for mapping floppy disks). ; ["BootSector" OSType] Section Commands: ; ; 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 ; 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 ; "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" ; (or to "BootPath"), or be an absolute ARC path, in which case ; the "BootDrive" and "BootPartition" (or "BootPath") values @@ -195,6 +187,7 @@ SpecialEffects=Yes [Operating Systems] ReactOSHD="ReactOS (HardDrive)" +;ReactOS_Debug="ReactOS (Debug)" ReactOSFloppy="ReactOS (Floppy)" Linux="Debian Linux" Floppy="3 1/2 Floppy (A:)" @@ -209,6 +202,13 @@ Options=/DEBUGPORT=SCREEN Kernel=\REACTOS\SYSTEM32\NTOSKRNL.EXE 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:) [ReactOSFloppy] BootType=Windows2003 @@ -217,13 +217,6 @@ Options=/DEBUGPORT=SCREEN Kernel=\reactos\NTOSKRNL.EXE 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] BootType=Linux BootPath=multi(0)disk(0)rdisk(1)partition(1) @@ -232,16 +225,16 @@ Initrd=/initrd.img CommandLine="root=/dev/sdb1" [Floppy] -BootType=Drive +BootType=BootSector BootDrive=fd0 [MSWinders] -BootType=Partition +BootType=BootSector BootPath=multi(0)disk(0)rdisk(0)partition(1) ;DriveMap=hd1,hd0 ;DriveMap=hd2,hd0 ;DriveMap=hd3,hd0 [DriveD] -BootType=Partition +BootType=BootSector BootPath=multi(0)disk(0)rdisk(1)partition(1) diff --git a/boot/freeldr/freeldr/bootmgr.c b/boot/freeldr/freeldr/bootmgr.c index b0dc77ee324..f843e6addb9 100644 --- a/boot/freeldr/freeldr/bootmgr.c +++ b/boot/freeldr/freeldr/bootmgr.c @@ -58,22 +58,48 @@ OSLoadingMethods[] = #if defined(_M_IX86) || defined(_M_AMD64) #ifndef UEFIBOOT - {"Drive" , EditCustomBootDisk , LoadAndBootDevice}, - {"Partition" , EditCustomBootPartition , LoadAndBootDevice}, - {"BootSector" , EditCustomBootSectorFile, LoadAndBootDevice}, - {"Linux" , EditCustomBootLinux, LoadAndBootLinux }, + {"BootSector", EditCustomBootSector, LoadAndBootSector}, + {"Linux" , EditCustomBootLinux , LoadAndBootLinux }, #endif #endif #ifdef _M_IX86 - {"WindowsNT40" , EditCustomBootNTOS , LoadAndBootWindows}, + {"WindowsNT40" , EditCustomBootNTOS, LoadAndBootWindows}, #endif - {"Windows" , EditCustomBootNTOS , LoadAndBootWindows}, - {"Windows2003" , EditCustomBootNTOS , LoadAndBootWindows}, - {"WindowsVista", EditCustomBootNTOS , LoadAndBootWindows}, + {"Windows" , EditCustomBootNTOS, LoadAndBootWindows}, + {"Windows2003" , EditCustomBootNTOS, LoadAndBootWindows}, + {"WindowsVista", EditCustomBootNTOS, LoadAndBootWindows}, }; /* 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 .", + msgString); +} +#endif // HAS_DEPRECATED_OPTIONS + static const OS_LOADING_METHOD* GetOSLoadingMethod( _In_ ULONG_PTR SectionId) @@ -90,11 +116,43 @@ GetOSLoadingMethod( IniReadSettingByName(SectionId, "BootType", BootType, sizeof(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 */ for (i = 0; ; ++i) { if (i >= RTL_NUMBER_OF(OSLoadingMethods)) + { + UiMessageBox("Unknown boot entry type '%s'", BootType); return NULL; + } if (_stricmp(BootType, OSLoadingMethods[i].BootType) == 0) return &OSLoadingMethods[i]; } diff --git a/boot/freeldr/freeldr/custom.c b/boot/freeldr/freeldr/custom.c index 105acbd0703..f0e984deb66 100644 --- a/boot/freeldr/freeldr/custom.c +++ b/boot/freeldr/freeldr/custom.c @@ -24,27 +24,27 @@ /* GLOBALS ********************************************************************/ #if defined(_M_IX86) || defined(_M_AMD64) -const PCSTR BootSectorFilePrompt = +static const PCSTR BootSectorFilePrompt = "Enter the boot sector file path.\n" + "Leave blank for booting a disk or partition.\n" "\n" "Examples:\n" "\\BOOTSECT.DOS\n" "/boot/bootsect.dos"; -const PCSTR LinuxKernelPrompt = +static const PCSTR LinuxKernelPrompt = "Enter the Linux kernel image path.\n" "\n" "Examples:\n" "/vmlinuz\n" "/boot/vmlinuz-2.4.18"; -const PCSTR LinuxInitrdPrompt = +static const PCSTR LinuxInitrdPrompt = "Enter the initrd image path.\n" + "Leave blank for no initial ramdisk.\n" "\n" "Examples:\n" "/initrd.gz\n" - "/boot/root.img.gz\n" - "\n" - "Leave blank for no initial ram disk."; -const PCSTR LinuxCommandLinePrompt = + "/boot/root.img.gz"; +static const PCSTR LinuxCommandLinePrompt = "Enter the Linux kernel command line.\n" "\n" "Examples:\n" @@ -53,7 +53,7 @@ const PCSTR LinuxCommandLinePrompt = "root=/dev/sdb1 init=/sbin/init"; #endif /* _M_IX86 || _M_AMD64 */ -const PCSTR BootDrivePrompt = +static const PCSTR BootDrivePrompt = "Enter the boot drive.\n" "\n" "Examples:\n" @@ -66,25 +66,30 @@ const PCSTR BootDrivePrompt = "0 - first floppy drive\n" "0x80 - first hard drive\n" "0x81 - second hard drive"; -const PCSTR BootPartitionPrompt = - "Enter the boot partition.\n" - "\n" - "Enter 0 for the active (bootable) partition."; +static const PCSTR BootPartitionPrompt = + "Enter the boot partition.\n"; + // "\n" + // "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" "\n" "Examples:\n" "multi(0)disk(0)rdisk(0)partition(1)\n" "multi(0)disk(0)fdisk(0)"; -const PCSTR ReactOSSystemPathPrompt = +static const PCSTR ReactOSSystemPathPrompt = "Enter the path to your ReactOS system directory.\n" "\n" "Examples:\n" "\\REACTOS\n" "\\ROS"; -const PCSTR ReactOSOptionsPrompt = +static const PCSTR ReactOSOptionsPrompt = "Enter the load options you want passed to the kernel.\n" "\n" "Examples:\n" @@ -92,7 +97,7 @@ const PCSTR ReactOSOptionsPrompt = "/FASTDETECT /SOS /NOGUIBOOT\n" "/BASEVIDEO /MAXMEM=64\n" "/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" "These options will supplement those obtained from the TXTSETUP.SIF\n" "file, unless you also specify the /SIFOPTIONSOVERRIDE option switch.\n" @@ -100,7 +105,7 @@ const PCSTR ReactOSSetupOptionsPrompt = "Example:\n" "/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /NOGUIBOOT"; -const PCSTR CustomBootPrompt = +static const PCSTR CustomBootPrompt = "Press ENTER to boot your custom boot setup."; /* FUNCTIONS ******************************************************************/ @@ -111,9 +116,7 @@ VOID OptionMenuCustomBoot(VOID) { PCSTR CustomBootMenuList[] = { #if defined(_M_IX86) || defined(_M_AMD64) - "Disk", - "Partition", - "Boot Sector File", + "Boot Sector (Disk/Partition/File)", "Linux", #endif "ReactOS", @@ -140,22 +143,16 @@ VOID OptionMenuCustomBoot(VOID) switch (SelectedMenuItem) { #if defined(_M_IX86) || defined(_M_AMD64) - case 0: // Disk - EditCustomBootDisk(&OperatingSystem); + case 0: // Boot Sector (Disk/Partition/File) + EditCustomBootSector(&OperatingSystem); break; - case 1: // Partition - EditCustomBootPartition(&OperatingSystem); - break; - case 2: // Boot Sector File - EditCustomBootSectorFile(&OperatingSystem); - break; - case 3: // Linux + case 1: // Linux EditCustomBootLinux(&OperatingSystem); break; - case 4: // ReactOS + case 2: // ReactOS EditCustomBootReactOS(&OperatingSystem, FALSE); break; - case 5: // ReactOS Setup + case 3: // ReactOS Setup EditCustomBootReactOS(&OperatingSystem, TRUE); break; #else @@ -181,103 +178,8 @@ VOID OptionMenuCustomBoot(VOID) #if defined(_M_IX86) || defined(_M_AMD64) VOID -EditCustomBootDisk( - 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 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) +EditCustomBootSector( + _Inout_ OperatingSystemItem* OperatingSystem) { TIMEINFO* TimeInfo; ULONG_PTR SectionId = OperatingSystem->SectionId; @@ -294,9 +196,11 @@ EditCustomBootPartition( }; CHAR ArcPath[200]; } BootStrings; + CHAR BootSectorFile[200]; RtlZeroMemory(SectionName, sizeof(SectionName)); RtlZeroMemory(&BootStrings, sizeof(BootStrings)); + RtlZeroMemory(BootSectorFile, sizeof(BootSectorFile)); if (SectionId != 0) { @@ -314,6 +218,9 @@ EditCustomBootPartition( IniReadSettingByName(SectionId, "BootDrive", BootStrings.Drive, sizeof(BootStrings.Drive)); 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) @@ -333,122 +240,15 @@ EditCustomBootPartition( return; } - /* Modify the settings values and return if we were in edit mode */ - if (SectionId != 0) + /* Edit the file name only if a partition has been specified */ + 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 (*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; - } - - /* 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)) + if (!UiEditBox(BootSectorFilePrompt, BootSectorFile, sizeof(BootSectorFile))) 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 */ if (SectionId != 0) @@ -467,22 +267,23 @@ EditCustomBootSectorFile( else { /* - * Otherwise, zero out all values: BootSectorFile will be - * relative to the default system partition. + * Otherwise, reset all values: BootSectorFile + * will be relative to the default system partition. */ IniModifySettingValue(SectionId, "BootPath", ""); IniModifySettingValue(SectionId, "BootDrive", ""); IniModifySettingValue(SectionId, "BootPartition", ""); } - IniModifySettingValue(SectionId, "BootSectorFile", BootSectorFileString); + /* Always write back the file name */ + IniModifySettingValue(SectionId, "BootSectorFile", BootSectorFile); return; } /* Generate a unique section name */ TimeInfo = ArcGetTime(); 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->Hour, TimeInfo->Minute, TimeInfo->Second); @@ -510,9 +311,12 @@ EditCustomBootSectorFile( return; } - /* Add the BootSectorFile */ - if (!IniAddSettingValueToSection(SectionId, "BootSectorFile", BootSectorFileString)) - return; + /* Add the BootSectorFile if any */ + if (*BootSectorFile) + { + if (!IniAddSettingValueToSection(SectionId, "BootSectorFile", BootSectorFile)) + return; + } OperatingSystem->SectionId = SectionId; OperatingSystem->LoadIdentifier = NULL; @@ -612,8 +416,8 @@ EditCustomBootLinux( else { /* - * Otherwise, zero out all values: BootSectorFile will be - * relative to the default system partition. + * Otherwise, reset all values: the files will + * be relative to the default system partition. */ IniModifySettingValue(SectionId, "BootPath", ""); IniModifySettingValue(SectionId, "BootDrive", ""); diff --git a/boot/freeldr/freeldr/include/custom.h b/boot/freeldr/freeldr/include/custom.h index 8fb4f7bdae3..53263546d46 100644 --- a/boot/freeldr/freeldr/include/custom.h +++ b/boot/freeldr/freeldr/include/custom.h @@ -30,16 +30,8 @@ VOID OptionMenuCustomBoot(VOID); #if defined(_M_IX86) || defined(_M_AMD64) VOID -EditCustomBootDisk( - IN OUT OperatingSystemItem* OperatingSystem); - -VOID -EditCustomBootPartition( - IN OUT OperatingSystemItem* OperatingSystem); - -VOID -EditCustomBootSectorFile( - IN OUT OperatingSystemItem* OperatingSystem); +EditCustomBootSector( + _Inout_ OperatingSystemItem* OperatingSystem); VOID EditCustomBootLinux( diff --git a/boot/freeldr/freeldr/include/freeldr.h b/boot/freeldr/freeldr/include/freeldr.h index f37e585b232..084d4795b35 100644 --- a/boot/freeldr/freeldr/include/freeldr.h +++ b/boot/freeldr/freeldr/include/freeldr.h @@ -20,6 +20,10 @@ #ifndef __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 RVA(m, b) ((PVOID)((ULONG_PTR)(b) + (ULONG_PTR)(m))) @@ -126,6 +130,13 @@ VOID __cdecl BootMain(IN PCCH CmdLine); +#ifdef HAS_DEPRECATED_OPTIONS +VOID +WarnDeprecated( + _In_ PCSTR MsgFmt, + ...); +#endif + VOID LoadOperatingSystem( _In_ OperatingSystemItem* OperatingSystem); diff --git a/boot/freeldr/freeldr/include/miscboot.h b/boot/freeldr/freeldr/include/miscboot.h index 0f05fd1ce03..7acecd0daf2 100644 --- a/boot/freeldr/freeldr/include/miscboot.h +++ b/boot/freeldr/freeldr/include/miscboot.h @@ -22,9 +22,9 @@ #if defined(_M_IX86) || defined(_M_AMD64) ARC_STATUS -LoadAndBootDevice( - IN ULONG Argc, - IN PCHAR Argv[], - IN PCHAR Envp[]); +LoadAndBootSector( + _In_ ULONG Argc, + _In_ PCHAR Argv[], + _In_ PCHAR Envp[]); #endif /* _M_IX86 || _M_AMD64 */ diff --git a/boot/freeldr/freeldr/include/ver.h b/boot/freeldr/freeldr/include/ver.h index 708b60db939..26cbb1195d9 100644 --- a/boot/freeldr/freeldr/include/ver.h +++ b/boot/freeldr/freeldr/include/ver.h @@ -20,7 +20,7 @@ #pragma once /* Just some stuff */ -#define VERSION "FreeLoader v3.0" +#define VERSION "FreeLoader v3.2" #define COPYRIGHT "Copyright (C) 1996-" COPYRIGHT_YEAR " ReactOS Project" #define AUTHOR_EMAIL "" #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 // #define FREELOADER_MAJOR_VERSION 3 -#define FREELOADER_MINOR_VERSION 0 +#define FREELOADER_MINOR_VERSION 2 #define FREELOADER_PATCH_VERSION 0 extern const PCSTR FrLdrVersionString; diff --git a/boot/freeldr/freeldr/miscboot.c b/boot/freeldr/freeldr/miscboot.c index 445cecc9e3f..5243d8c9186 100644 --- a/boot/freeldr/freeldr/miscboot.c +++ b/boot/freeldr/freeldr/miscboot.c @@ -23,26 +23,44 @@ #include +#include +DBG_DEFAULT_CHANNEL(DISK); + /* FUNCTIONS ******************************************************************/ -static ARC_STATUS -LoadBootSector( - IN ULONG Argc, - IN PCHAR Argv[], - OUT PUCHAR DriveNumber, - OUT PULONG PartitionNumber) +/** + * @brief + * Loads and boots a disk MBR, a partition VBR or a file boot sector. + **/ +ARC_STATUS +LoadAndBootSector( + _In_ ULONG Argc, + _In_ PCHAR Argv[], + _In_ PCHAR Envp[]) { ARC_STATUS Status; PCSTR ArgValue; PCSTR BootPath; PCSTR FileName; + UCHAR BiosDriveNumber = 0; + ULONG PartitionNumber = 0; + ULONG LoadAddress; ULONG FileId; ULONG BytesRead; CHAR ArcPath[MAX_PATH]; - ULONG LoadAddress; - *DriveNumber = 0; - *PartitionNumber = 0; +#if DBG + /* 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 @@ -57,24 +75,13 @@ LoadBootSector( ArgValue = GetArgumentValue(Argc, Argv, "BootDrive"); if (ArgValue && *ArgValue) { - *DriveNumber = DriveMapGetBiosDriveNumber(ArgValue); + BiosDriveNumber = DriveMapGetBiosDriveNumber(ArgValue); - /* Retrieve the boot partition (not optional and cannot be zero) */ - *PartitionNumber = 0; + /* Retrieve the boot partition (optional, fall back to zero otherwise) */ + 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; + PartitionNumber = atoi(ArgValue); } 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 - * both the DriveNumber and PartitionNumber options. + * both the BiosDriveNumber 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 = NULL; + if (!DissectArcPath(BootPath, &FileName, &BiosDriveNumber, &PartitionNumber) || (FileName && *FileName)) { + UiMessageBox("Currently unsupported BootPath value:\n%s", BootPath); return EINVAL; } } else { /* 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. - BootPath = ArcPath; } - /* Open the volume */ - Status = ArcOpen((PSTR)BootPath, OpenReadOnly, &FileId); + 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); if (Status != ESUCCESS) { - UiMessageBox("Unable to open %s", BootPath); + UiMessageBox("Unable to open %s", FileName ? FileName : BootPath); return Status; } #if defined(SARCH_PC98) - LoadAddress = Pc98GetBootSectorLoadAddress(*DriveNumber); + LoadAddress = Pc98GetBootSectorLoadAddress(BiosDriveNumber); #else LoadAddress = 0x7C00; #endif /* - * Now try to load the partition boot sector or the MBR (when PartitionNumber == 0). - * If this fails then abort. + * Now try to load the boot sector: disk MBR (when PartitionNumber == 0), + * partition VBR or boot sector file. If this fails, abort. */ Status = ArcRead(FileId, UlongToPtr(LoadAddress), 512, &BytesRead); ArcClose(FileId); if ((Status != ESUCCESS) || (BytesRead != 512)) { - if (*PartitionNumber != 0) - UiMessageBox("Unable to load partition's boot sector."); + PCSTR WhatFailed; + + if (FileName) + WhatFailed = "boot sector file"; + else if (PartitionNumber != 0) + WhatFailed = "partition's boot sector"; else - UiMessageBox("Unable to load MBR boot sector."); + WhatFailed = "MBR boot sector"; + + UiMessageBox("Unable to load %s.", WhatFailed); return EIO; } /* Check for validity */ if (*(USHORT*)UlongToPtr(LoadAddress + 0x1FE) != 0xAA55) { - UiMessageBox("Invalid boot sector magic (0xaa55)"); + UiMessageBox("Invalid boot sector magic (0xAA55)"); 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..."); IniCleanup(); #ifndef UEFIBOOT /* Boot the loaded sector code */ - ChainLoadBiosBootSectorCode(DriveNumber, PartitionNumber); + ChainLoadBiosBootSectorCode(BiosDriveNumber, PartitionNumber); #endif /* Must not return! */ return ESUCCESS; } #endif /* _M_IX86 || _M_AMD64 */ + +/* EOF */