[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...).
This commit is contained in:
Hermès Bélusca-Maïto 2019-09-17 23:04:39 +02:00
parent fc29a6c41c
commit ff85aa0c38
No known key found for this signature in database
GPG key ID: 3B2539C65E7B93D0
5 changed files with 108 additions and 69 deletions

View file

@ -75,11 +75,14 @@ typedef struct
/* DISK IO ERROR SUPPORT *****************************************************/ /* 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) static PCSTR DiskGetErrorCodeString(ULONG ErrorCode)
@ -121,7 +124,7 @@ static VOID DiskError(PCSTR ErrorString, ULONG ErrorCode)
{ {
CHAR ErrorCodeString[200]; CHAR ErrorCodeString[200];
if (bReportError == FALSE) if (lReportError < 0)
return; return;
sprintf(ErrorCodeString, "%s\n\nError Code: 0x%lx\nError: %s", sprintf(ErrorCodeString, "%s\n\nError Code: 0x%lx\nError: %s",

View file

@ -55,9 +55,9 @@ static const struct
{"ReactOSSetup", EditCustomBootReactOSSetup, LoadReactOSSetup}, {"ReactOSSetup", EditCustomBootReactOSSetup, LoadReactOSSetup},
#ifdef _M_IX86 #ifdef _M_IX86
{"Drive" , EditCustomBootDisk , LoadAndBootDrive }, {"Drive" , EditCustomBootDisk , LoadAndBootDevice},
{"Partition" , EditCustomBootPartition , LoadAndBootPartition }, {"Partition" , EditCustomBootPartition , LoadAndBootDevice},
{"BootSector" , EditCustomBootSectorFile, LoadAndBootBootSector}, {"BootSector" , EditCustomBootSectorFile, LoadAndBootDevice},
{"Linux" , EditCustomBootLinux, LoadAndBootLinux }, {"Linux" , EditCustomBootLinux, LoadAndBootLinux },
{"WindowsNT40" , EditCustomBootNTOS , LoadAndBootWindows}, {"WindowsNT40" , EditCustomBootNTOS , LoadAndBootWindows},

View file

@ -58,7 +58,7 @@ BOOLEAN PcFindPciBios(PPCI_REGISTRY_INFO BusData);
extern UCHAR FrldrBootDrive; extern UCHAR FrldrBootDrive;
extern ULONG FrldrBootPartition; extern ULONG FrldrBootPartition;
VOID DiskReportError(BOOLEAN bError); LONG DiskReportError(BOOLEAN bShowError);
BOOLEAN DiskResetController(UCHAR DriveNumber); BOOLEAN DiskResetController(UCHAR DriveNumber);
BOOLEAN DiskGetExtendedDriveParameters(UCHAR DriveNumber, PVOID Buffer, USHORT BufferSize); BOOLEAN DiskGetExtendedDriveParameters(UCHAR DriveNumber, PVOID Buffer, USHORT BufferSize);

View file

@ -22,19 +22,7 @@
#ifdef _M_IX86 #ifdef _M_IX86
ARC_STATUS ARC_STATUS
LoadAndBootBootSector( LoadAndBootDevice(
IN ULONG Argc,
IN PCHAR Argv[],
IN PCHAR Envp[]);
ARC_STATUS
LoadAndBootPartition(
IN ULONG Argc,
IN PCHAR Argv[],
IN PCHAR Envp[]);
ARC_STATUS
LoadAndBootDrive(
IN ULONG Argc, IN ULONG Argc,
IN PCHAR Argv[], IN PCHAR Argv[],
IN PCHAR Envp[]); IN PCHAR Envp[]);

View file

@ -25,24 +25,23 @@
/* FUNCTIONS ******************************************************************/ /* FUNCTIONS ******************************************************************/
ARC_STATUS static ARC_STATUS
LoadAndBootBootSector( LoadBootSector(
IN ULONG Argc, IN ULONG Argc,
IN PCHAR Argv[], IN PCHAR Argv[],
IN PCHAR Envp[]) OUT PUCHAR DriveNumber,
OUT PULONG PartitionNumber)
{ {
ARC_STATUS Status; ARC_STATUS Status;
PCSTR ArgValue; PCSTR ArgValue;
PCSTR BootPath; PCSTR BootPath;
PCSTR FileName; PCSTR FileName;
UCHAR DriveNumber = 0;
ULONG PartitionNumber = 0;
ULONG FileId; ULONG FileId;
ULONG BytesRead; ULONG BytesRead;
CHAR ArcPath[MAX_PATH]; CHAR ArcPath[MAX_PATH];
/* Find all the message box settings and run them */ *DriveNumber = 0;
UiShowMessageBoxesInArgv(Argc, Argv); *PartitionNumber = 0;
/* /*
* Check whether we have a "BootPath" value (takes precedence * Check whether we have a "BootPath" value (takes precedence
@ -57,21 +56,21 @@ LoadAndBootBootSector(
ArgValue = GetArgumentValue(Argc, Argv, "BootDrive"); ArgValue = GetArgumentValue(Argc, Argv, "BootDrive");
if (ArgValue && *ArgValue) if (ArgValue && *ArgValue)
{ {
DriveNumber = DriveMapGetBiosDriveNumber(ArgValue); *DriveNumber = DriveMapGetBiosDriveNumber(ArgValue);
/* Retrieve the boot partition (not optional and cannot be zero) */ /* Retrieve the boot partition (not optional and cannot be zero) */
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) if (*PartitionNumber == 0)
{ {
UiMessageBox("Boot partition cannot be 0!"); UiMessageBox("Boot partition cannot be 0!");
return EINVAL; return EINVAL;
} }
/* Construct the corresponding ARC path */ /* Construct the corresponding ARC path */
ConstructArcPath(ArcPath, "", DriveNumber, PartitionNumber); ConstructArcPath(ArcPath, "", *DriveNumber, *PartitionNumber);
*strrchr(ArcPath, '\\') = ANSI_NULL; // Trim the trailing path separator. *strrchr(ArcPath, '\\') = ANSI_NULL; // Trim the trailing path separator.
BootPath = ArcPath; BootPath = ArcPath;
@ -115,18 +114,17 @@ LoadAndBootBootSector(
return ENOEXEC; return ENOEXEC;
} }
UiUnInitialize("Booting..."); /* Reset the drive and partition numbers so as to use their default values */
IniCleanup(); *DriveNumber = 0;
*PartitionNumber = 0;
ChainLoadBiosBootSectorCode(0 /*DriveNumber*/, 0 /*PartitionNumber*/);
/* Must not return! */
return ESUCCESS; return ESUCCESS;
} }
static ARC_STATUS static ARC_STATUS
LoadAndBootPartitionOrDrive( LoadPartitionOrDrive(
IN UCHAR DriveNumber, IN OUT PUCHAR DriveNumber,
IN ULONG PartitionNumber OPTIONAL, IN OUT PULONG PartitionNumber,
IN PCSTR BootPath OPTIONAL) IN PCSTR BootPath OPTIONAL)
{ {
ARC_STATUS Status; ARC_STATUS Status;
@ -135,8 +133,8 @@ LoadAndBootPartitionOrDrive(
CHAR ArcPath[MAX_PATH]; CHAR ArcPath[MAX_PATH];
/* /*
* If the user specifies an ARC "BootPath" value, it takes precedence * The ARC "BootPath" value takes precedence over
* over both the DriveNumber and PartitionNumber options. * both the DriveNumber and PartitionNumber options.
*/ */
if (BootPath && *BootPath) if (BootPath && *BootPath)
{ {
@ -146,7 +144,7 @@ LoadAndBootPartitionOrDrive(
* 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) || if (!DissectArcPath(BootPath, &FileName, DriveNumber, PartitionNumber) ||
(FileName && *FileName)) (FileName && *FileName))
{ {
return EINVAL; return EINVAL;
@ -155,7 +153,7 @@ LoadAndBootPartitionOrDrive(
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, "", *DriveNumber, *PartitionNumber);
*strrchr(ArcPath, '\\') = ANSI_NULL; // Trim the trailing path separator. *strrchr(ArcPath, '\\') = ANSI_NULL; // Trim the trailing path separator.
BootPath = ArcPath; BootPath = ArcPath;
@ -177,7 +175,7 @@ LoadAndBootPartitionOrDrive(
ArcClose(FileId); ArcClose(FileId);
if ((Status != ESUCCESS) || (BytesRead != 512)) if ((Status != ESUCCESS) || (BytesRead != 512))
{ {
if (PartitionNumber != 0) if (*PartitionNumber != 0)
UiMessageBox("Unable to load partition's boot sector."); UiMessageBox("Unable to load partition's boot sector.");
else else
UiMessageBox("Unable to load MBR boot sector."); UiMessageBox("Unable to load MBR boot sector.");
@ -191,27 +189,21 @@ LoadAndBootPartitionOrDrive(
return ENOEXEC; return ENOEXEC;
} }
UiUnInitialize("Booting...");
IniCleanup();
ChainLoadBiosBootSectorCode(DriveNumber, PartitionNumber);
/* Must not return! */
return ESUCCESS; return ESUCCESS;
} }
ARC_STATUS static ARC_STATUS
LoadAndBootPartition( LoadPartition(
IN ULONG Argc, IN ULONG Argc,
IN PCHAR Argv[], IN PCHAR Argv[],
IN PCHAR Envp[]) OUT PUCHAR DriveNumber,
OUT PULONG PartitionNumber)
{ {
PCSTR ArgValue; PCSTR ArgValue;
PCSTR BootPath; PCSTR BootPath;
UCHAR DriveNumber = 0;
ULONG PartitionNumber = 0;
/* Find all the message box settings and run them */ *DriveNumber = 0;
UiShowMessageBoxesInArgv(Argc, Argv); *PartitionNumber = 0;
/* /*
* Check whether we have a "BootPath" value (takes precedence * Check whether we have a "BootPath" value (takes precedence
@ -229,30 +221,30 @@ LoadAndBootPartition(
UiMessageBox("Boot drive not specified for selected OS!"); UiMessageBox("Boot drive not specified for selected OS!");
return EINVAL; return EINVAL;
} }
DriveNumber = DriveMapGetBiosDriveNumber(ArgValue); *DriveNumber = DriveMapGetBiosDriveNumber(ArgValue);
/* Retrieve the boot partition (optional, fall back to zero otherwise) */ /* 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);
} }
return LoadAndBootPartitionOrDrive(DriveNumber, PartitionNumber, BootPath); return LoadPartitionOrDrive(DriveNumber, PartitionNumber, BootPath);
} }
ARC_STATUS static ARC_STATUS
LoadAndBootDrive( LoadDrive(
IN ULONG Argc, IN ULONG Argc,
IN PCHAR Argv[], IN PCHAR Argv[],
IN PCHAR Envp[]) OUT PUCHAR DriveNumber,
OUT PULONG PartitionNumber)
{ {
PCSTR ArgValue; PCSTR ArgValue;
PCSTR BootPath; PCSTR BootPath;
UCHAR DriveNumber = 0;
/* Find all the message box settings and run them */ *DriveNumber = 0;
UiShowMessageBoxesInArgv(Argc, Argv); *PartitionNumber = 0;
/* Check whether we have a "BootPath" value (takes precedence over "BootDrive") */ /* Check whether we have a "BootPath" value (takes precedence over "BootDrive") */
BootPath = GetArgumentValue(Argc, Argv, "BootPath"); BootPath = GetArgumentValue(Argc, Argv, "BootPath");
@ -277,10 +269,66 @@ LoadAndBootDrive(
UiMessageBox("Boot drive not specified for selected OS!"); UiMessageBox("Boot drive not specified for selected OS!");
return EINVAL; 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 #endif // _M_IX86