mirror of
https://github.com/reactos/reactos.git
synced 2024-06-28 08:51:29 +00:00
[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:
parent
fc29a6c41c
commit
ff85aa0c38
|
@ -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",
|
||||||
|
|
|
@ -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},
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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[]);
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue