[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 *****************************************************/
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",

View 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},

View 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);

View file

@ -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[]);

View file

@ -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