From ff85aa0c38971ed7c54470bc6986edca781d710e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Tue, 17 Sep 2019 23:04:39 +0200 Subject: [PATCH] [FREELDR] Other enhancements. - Modify DiskReportError() to use an internal "display counter", so that imbricated DiskReportError(FALSE) ... DiskReportError(TRUE) can behave as expected. - Merge LoadAndBootDrive(), LoadAndBootPartition(), LoadAndBootBootSector() into one LoadAndBootDevice() function + its helpers (in progress...). --- boot/freeldr/freeldr/arch/i386/pcdisk.c | 11 +- boot/freeldr/freeldr/bootmgr.c | 6 +- boot/freeldr/freeldr/include/arch/pc/machpc.h | 2 +- boot/freeldr/freeldr/include/miscboot.h | 14 +- boot/freeldr/freeldr/miscboot.c | 144 ++++++++++++------ 5 files changed, 108 insertions(+), 69 deletions(-) diff --git a/boot/freeldr/freeldr/arch/i386/pcdisk.c b/boot/freeldr/freeldr/arch/i386/pcdisk.c index 0f1c5ad6509..87c21fc3b64 100644 --- a/boot/freeldr/freeldr/arch/i386/pcdisk.c +++ b/boot/freeldr/freeldr/arch/i386/pcdisk.c @@ -75,11 +75,14 @@ typedef struct /* DISK IO ERROR SUPPORT *****************************************************/ -static BOOLEAN bReportError = TRUE; +static LONG lReportError = 0; // >= 0: display errors; < 0: hide errors. -VOID DiskReportError(BOOLEAN bError) +LONG DiskReportError(BOOLEAN bShowError) { - bReportError = bError; + /* Set the reference count */ + if (bShowError) ++lReportError; + else --lReportError; + return lReportError; } static PCSTR DiskGetErrorCodeString(ULONG ErrorCode) @@ -121,7 +124,7 @@ static VOID DiskError(PCSTR ErrorString, ULONG ErrorCode) { CHAR ErrorCodeString[200]; - if (bReportError == FALSE) + if (lReportError < 0) return; sprintf(ErrorCodeString, "%s\n\nError Code: 0x%lx\nError: %s", diff --git a/boot/freeldr/freeldr/bootmgr.c b/boot/freeldr/freeldr/bootmgr.c index 4e2d9a8d2ef..4a1923dff19 100644 --- a/boot/freeldr/freeldr/bootmgr.c +++ b/boot/freeldr/freeldr/bootmgr.c @@ -55,9 +55,9 @@ static const struct {"ReactOSSetup", EditCustomBootReactOSSetup, LoadReactOSSetup}, #ifdef _M_IX86 - {"Drive" , EditCustomBootDisk , LoadAndBootDrive }, - {"Partition" , EditCustomBootPartition , LoadAndBootPartition }, - {"BootSector" , EditCustomBootSectorFile, LoadAndBootBootSector}, + {"Drive" , EditCustomBootDisk , LoadAndBootDevice}, + {"Partition" , EditCustomBootPartition , LoadAndBootDevice}, + {"BootSector" , EditCustomBootSectorFile, LoadAndBootDevice}, {"Linux" , EditCustomBootLinux, LoadAndBootLinux }, {"WindowsNT40" , EditCustomBootNTOS , LoadAndBootWindows}, diff --git a/boot/freeldr/freeldr/include/arch/pc/machpc.h b/boot/freeldr/freeldr/include/arch/pc/machpc.h index 8efe091ff9d..d5d8bebce1d 100644 --- a/boot/freeldr/freeldr/include/arch/pc/machpc.h +++ b/boot/freeldr/freeldr/include/arch/pc/machpc.h @@ -58,7 +58,7 @@ BOOLEAN PcFindPciBios(PPCI_REGISTRY_INFO BusData); extern UCHAR FrldrBootDrive; extern ULONG FrldrBootPartition; -VOID DiskReportError(BOOLEAN bError); +LONG DiskReportError(BOOLEAN bShowError); BOOLEAN DiskResetController(UCHAR DriveNumber); BOOLEAN DiskGetExtendedDriveParameters(UCHAR DriveNumber, PVOID Buffer, USHORT BufferSize); diff --git a/boot/freeldr/freeldr/include/miscboot.h b/boot/freeldr/freeldr/include/miscboot.h index 5e80ab0fa68..9ba1cb8448d 100644 --- a/boot/freeldr/freeldr/include/miscboot.h +++ b/boot/freeldr/freeldr/include/miscboot.h @@ -22,19 +22,7 @@ #ifdef _M_IX86 ARC_STATUS -LoadAndBootBootSector( - IN ULONG Argc, - IN PCHAR Argv[], - IN PCHAR Envp[]); - -ARC_STATUS -LoadAndBootPartition( - IN ULONG Argc, - IN PCHAR Argv[], - IN PCHAR Envp[]); - -ARC_STATUS -LoadAndBootDrive( +LoadAndBootDevice( IN ULONG Argc, IN PCHAR Argv[], IN PCHAR Envp[]); diff --git a/boot/freeldr/freeldr/miscboot.c b/boot/freeldr/freeldr/miscboot.c index e8f91c8e674..6ea56631654 100644 --- a/boot/freeldr/freeldr/miscboot.c +++ b/boot/freeldr/freeldr/miscboot.c @@ -25,24 +25,23 @@ /* FUNCTIONS ******************************************************************/ -ARC_STATUS -LoadAndBootBootSector( +static ARC_STATUS +LoadBootSector( IN ULONG Argc, IN PCHAR Argv[], - IN PCHAR Envp[]) + OUT PUCHAR DriveNumber, + OUT PULONG PartitionNumber) { 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); + *DriveNumber = 0; + *PartitionNumber = 0; /* * Check whether we have a "BootPath" value (takes precedence @@ -57,21 +56,21 @@ LoadAndBootBootSector( ArgValue = GetArgumentValue(Argc, Argv, "BootDrive"); if (ArgValue && *ArgValue) { - DriveNumber = DriveMapGetBiosDriveNumber(ArgValue); + *DriveNumber = DriveMapGetBiosDriveNumber(ArgValue); /* Retrieve the boot partition (not optional and cannot be zero) */ - PartitionNumber = 0; + *PartitionNumber = 0; ArgValue = GetArgumentValue(Argc, Argv, "BootPartition"); if (ArgValue && *ArgValue) - PartitionNumber = atoi(ArgValue); - if (PartitionNumber == 0) + *PartitionNumber = atoi(ArgValue); + if (*PartitionNumber == 0) { UiMessageBox("Boot partition cannot be 0!"); return EINVAL; } /* Construct the corresponding ARC path */ - ConstructArcPath(ArcPath, "", DriveNumber, PartitionNumber); + ConstructArcPath(ArcPath, "", *DriveNumber, *PartitionNumber); *strrchr(ArcPath, '\\') = ANSI_NULL; // Trim the trailing path separator. BootPath = ArcPath; @@ -115,18 +114,17 @@ LoadAndBootBootSector( return ENOEXEC; } - UiUnInitialize("Booting..."); - IniCleanup(); + /* Reset the drive and partition numbers so as to use their default values */ + *DriveNumber = 0; + *PartitionNumber = 0; - ChainLoadBiosBootSectorCode(0 /*DriveNumber*/, 0 /*PartitionNumber*/); - /* Must not return! */ return ESUCCESS; } static ARC_STATUS -LoadAndBootPartitionOrDrive( - IN UCHAR DriveNumber, - IN ULONG PartitionNumber OPTIONAL, +LoadPartitionOrDrive( + IN OUT PUCHAR DriveNumber, + IN OUT PULONG PartitionNumber, IN PCSTR BootPath OPTIONAL) { ARC_STATUS Status; @@ -135,8 +133,8 @@ LoadAndBootPartitionOrDrive( CHAR ArcPath[MAX_PATH]; /* - * If the user specifies an ARC "BootPath" value, it takes precedence - * over both the DriveNumber and PartitionNumber options. + * The ARC "BootPath" value takes precedence over + * both the DriveNumber and PartitionNumber options. */ if (BootPath && *BootPath) { @@ -146,7 +144,7 @@ LoadAndBootPartitionOrDrive( * 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) || + if (!DissectArcPath(BootPath, &FileName, DriveNumber, PartitionNumber) || (FileName && *FileName)) { return EINVAL; @@ -155,7 +153,7 @@ LoadAndBootPartitionOrDrive( else { /* We don't have one, so construct the corresponding ARC path */ - ConstructArcPath(ArcPath, "", DriveNumber, PartitionNumber); + ConstructArcPath(ArcPath, "", *DriveNumber, *PartitionNumber); *strrchr(ArcPath, '\\') = ANSI_NULL; // Trim the trailing path separator. BootPath = ArcPath; @@ -177,7 +175,7 @@ LoadAndBootPartitionOrDrive( ArcClose(FileId); if ((Status != ESUCCESS) || (BytesRead != 512)) { - if (PartitionNumber != 0) + if (*PartitionNumber != 0) UiMessageBox("Unable to load partition's boot sector."); else UiMessageBox("Unable to load MBR boot sector."); @@ -191,27 +189,21 @@ LoadAndBootPartitionOrDrive( return ENOEXEC; } - UiUnInitialize("Booting..."); - IniCleanup(); - - ChainLoadBiosBootSectorCode(DriveNumber, PartitionNumber); - /* Must not return! */ return ESUCCESS; } -ARC_STATUS -LoadAndBootPartition( +static ARC_STATUS +LoadPartition( IN ULONG Argc, IN PCHAR Argv[], - IN PCHAR Envp[]) + OUT PUCHAR DriveNumber, + OUT PULONG PartitionNumber) { PCSTR ArgValue; PCSTR BootPath; - UCHAR DriveNumber = 0; - ULONG PartitionNumber = 0; - /* Find all the message box settings and run them */ - UiShowMessageBoxesInArgv(Argc, Argv); + *DriveNumber = 0; + *PartitionNumber = 0; /* * Check whether we have a "BootPath" value (takes precedence @@ -229,30 +221,30 @@ LoadAndBootPartition( UiMessageBox("Boot drive not specified for selected OS!"); return EINVAL; } - DriveNumber = DriveMapGetBiosDriveNumber(ArgValue); + *DriveNumber = DriveMapGetBiosDriveNumber(ArgValue); /* Retrieve the boot partition (optional, fall back to zero otherwise) */ - PartitionNumber = 0; + *PartitionNumber = 0; ArgValue = GetArgumentValue(Argc, Argv, "BootPartition"); if (ArgValue && *ArgValue) - PartitionNumber = atoi(ArgValue); + *PartitionNumber = atoi(ArgValue); } - return LoadAndBootPartitionOrDrive(DriveNumber, PartitionNumber, BootPath); + return LoadPartitionOrDrive(DriveNumber, PartitionNumber, BootPath); } -ARC_STATUS -LoadAndBootDrive( +static ARC_STATUS +LoadDrive( IN ULONG Argc, IN PCHAR Argv[], - IN PCHAR Envp[]) + OUT PUCHAR DriveNumber, + OUT PULONG PartitionNumber) { PCSTR ArgValue; PCSTR BootPath; - UCHAR DriveNumber = 0; - /* Find all the message box settings and run them */ - UiShowMessageBoxesInArgv(Argc, Argv); + *DriveNumber = 0; + *PartitionNumber = 0; /* Check whether we have a "BootPath" value (takes precedence over "BootDrive") */ BootPath = GetArgumentValue(Argc, Argv, "BootPath"); @@ -277,10 +269,66 @@ LoadAndBootDrive( UiMessageBox("Boot drive not specified for selected OS!"); return EINVAL; } - DriveNumber = DriveMapGetBiosDriveNumber(ArgValue); + *DriveNumber = DriveMapGetBiosDriveNumber(ArgValue); } - return LoadAndBootPartitionOrDrive(DriveNumber, 0, BootPath); + 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(); + + /* Boot the loaded sector code at 0x7C00 */ + ChainLoadBiosBootSectorCode(DriveNumber, PartitionNumber); + /* Must not return! */ + return ESUCCESS; } #endif // _M_IX86