[FREELDR] Other enhancements.
authorHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Tue, 17 Sep 2019 21:04:39 +0000 (23:04 +0200)
committerHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Tue, 17 Sep 2019 22:27:53 +0000 (00:27 +0200)
- 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
boot/freeldr/freeldr/bootmgr.c
boot/freeldr/freeldr/include/arch/pc/machpc.h
boot/freeldr/freeldr/include/miscboot.h
boot/freeldr/freeldr/miscboot.c

index 0f1c5ad..87c21fc 100644 (file)
@@ -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",
index 4e2d9a8..4a1923d 100644 (file)
@@ -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},
index 8efe091..d5d8beb 100644 (file)
@@ -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);
 
index 5e80ab0..9ba1cb8 100644 (file)
 #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[]);
index e8f91c8..6ea5663 100644 (file)
 
 /* 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 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();
 
-    return LoadAndBootPartitionOrDrive(DriveNumber, 0, BootPath);
+    /* Boot the loaded sector code at 0x7C00 */
+    ChainLoadBiosBootSectorCode(DriveNumber, PartitionNumber);
+    /* Must not return! */
+    return ESUCCESS;
 }
 
 #endif // _M_IX86