mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 09:34:43 +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
5 changed files with 108 additions and 69 deletions
|
@ -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",
|
||||
|
|
|
@ -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},
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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[]);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue