Author: hbelusca
Date: Sun Jan 29 15:43:12 2017
New Revision: 73621
URL:
http://svn.reactos.org/svn/reactos?rev=73621&view=rev
Log:
[FREELDR]
- Simplify the implementation of the 'DiskGetBootPath' function;
- Cache the retrived freeldr boot path (corresponding to a given 'FrldrBootDrive'
number);
- Introduce a 'DiskIsCdRomDrive' function to attempt to fix CORE-12692 .
Modified:
trunk/reactos/boot/freeldr/freeldr/arch/i386/pcdisk.c
trunk/reactos/boot/freeldr/freeldr/disk/disk.c
trunk/reactos/boot/freeldr/freeldr/include/disk.h
Modified: trunk/reactos/boot/freeldr/freeldr/arch/i386/pcdisk.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/arch/…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/arch/i386/pcdisk.c [iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/arch/i386/pcdisk.c [iso-8859-1] Sun Jan 29 15:43:12
2017
@@ -17,6 +17,8 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+// #if defined(__i386__) || defined(_M_AMD64)
+
#include <freeldr.h>
#define NDEBUG
@@ -25,6 +27,7 @@
DBG_DEFAULT_CHANNEL(DISK);
#include <pshpack2.h>
+
typedef struct
{
UCHAR PacketSize; // 00h - Size of packet (10h or 18h)
@@ -38,6 +41,38 @@
// Commented since some earlier BIOSes
refuse to work with
// such extended structure
} I386_DISK_ADDRESS_PACKET, *PI386_DISK_ADDRESS_PACKET;
+
+typedef struct
+{
+ UCHAR PacketSize; // 00h - Size of packet in bytes (13h)
+ UCHAR MediaType; // 01h - Boot media type (see #00282)
+ UCHAR DriveNumber; /* 02h - Drive number:
+ * 00h Floppy image
+ * 80h Bootable hard disk
+ * 81h-FFh Nonbootable or no emulation
+ */
+ UCHAR Controller; // 03h - CD-ROM controller number
+ ULONG LBAImage; // 04h - Logical Block Address of disk image to emulate
+ USHORT DeviceSpec; /* 08h - Device specification (see also #00282)
+ * (IDE) Bit 0:
+ * Drive is slave instead of master
+ * (SCSI) Bits 7-0:
+ * LUN and PUN
+ * Bits 15-8:
+ * Bus number
+ */
+ USHORT Buffer; // 0Ah - Segment of 3K buffer for caching CD-ROM reads
+ USHORT LoadSeg; // 0Ch - Load segment for initial boot image.
+ // If 0000h, load at segment 07C0h.
+ USHORT SectorCount; // 0Eh - Number of 512-byte virtual sectors to load
+ // (only valid for AH=4Ch).
+ UCHAR CHSGeometry[3]; /* 10h - Low byte of cylinder count (for INT 13/AH=08h)
+ * 11h - Sector count, high bits of cylinder count (for INT
13/AH=08h)
+ * 12h - Head count (for INT 13/AH=08h)
+ */
+ UCHAR Reserved;
+} I386_CDROM_SPEC_PACKET, *PI386_CDROM_SPEC_PACKET;
+
#include <poppack.h>
/* FUNCTIONS *****************************************************************/
@@ -540,6 +575,69 @@
}
}
+
+static BOOLEAN
+FallbackDiskIsCdRomDrive(UCHAR DriveNumber)
+{
+ MASTER_BOOT_RECORD MasterBootRecord;
+
+ TRACE("FallbackDiskIsCdRomDrive(0x%x)\n", DriveNumber);
+
+ /* CD-ROM drive numbers are always > 0x80 */
+ if (DriveNumber <= 0x80)
+ return FALSE;
+
+ /*
+ * We suppose that a CD-ROM does not have a MBR
+ * (not always true: example of the Hybrid USB-ISOs).
+ */
+ return !DiskReadBootRecord(DriveNumber, 0, &MasterBootRecord);
+}
+
+BOOLEAN DiskIsCdRomDrive(UCHAR DriveNumber)
+{
+ REGS RegsIn, RegsOut;
+ PI386_CDROM_SPEC_PACKET Packet = (PI386_CDROM_SPEC_PACKET)(BIOSCALLBUFFER);
+
+ TRACE("DiskIsCdRomDrive(0x%x)\n", DriveNumber);
+
+ /* CD-ROM drive numbers are always > 0x80 */
+ if (DriveNumber <= 0x80)
+ return FALSE;
+
+ /* Setup disk address packet */
+ RtlZeroMemory(Packet, sizeof(*Packet));
+ Packet->PacketSize = sizeof(*Packet);
+
+ /*
+ * BIOS Int 13h, function 4B01h - Bootable CD-ROM - Get Disk Emulation Status
+ * AX = 4B01h
+ * DL = drive number
+ * DS:SI -> empty specification packet
+ * Return:
+ * CF clear if successful
+ * CF set on error
+ * AX = return codes
+ * DS:SI specification packet filled
+ */
+ RegsIn.w.ax = 0x4B01;
+ RegsIn.b.dl = DriveNumber;
+ RegsIn.x.ds = BIOSCALLBUFSEGMENT; // DS:SI -> specification packet
+ RegsIn.w.si = BIOSCALLBUFOFFSET;
+
+ Int386(0x13, &RegsIn, &RegsOut);
+
+ // return (INT386_SUCCESS(RegsOut) && (Packet->DriveNumber ==
DriveNumber));
+ /*
+ * If the simple test failed, try to use the fallback code,
+ * but we can be on *very* thin ice.
+ */
+ if (!INT386_SUCCESS(RegsOut) || (Packet->DriveNumber != DriveNumber))
+ return FallbackDiskIsCdRomDrive(DriveNumber);
+ else
+ return TRUE;
+}
+
BOOLEAN
PcDiskGetBootPath(OUT PCHAR BootPath, IN ULONG Size)
{
@@ -550,6 +648,17 @@
// we were booting from network (and: PC --> PXE, etc...)
// and if so, set the correct ARC path. But then this new
// logic could be moved back to DiskGetBootPath...
+
+ if (*FrldrBootPath)
+ {
+ /* Copy back the buffer */
+ if (Size < strlen(FrldrBootPath) + 1)
+ return FALSE;
+ strncpy(BootPath, FrldrBootPath, Size);
+ return TRUE;
+ }
+
+ // FIXME! FIXME! Do this in some drive recognition procedure!!!!
if (PxeInit())
{
strcpy(BootPath, "net(0)");
Modified: trunk/reactos/boot/freeldr/freeldr/disk/disk.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/disk/…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/disk/disk.c [iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/disk/disk.c [iso-8859-1] Sun Jan 29 15:43:12 2017
@@ -24,6 +24,8 @@
#include <debug.h>
DBG_DEFAULT_CHANNEL(DISK);
+
+CHAR FrldrBootPath[MAX_PATH] = "";
static BOOLEAN bReportError = TRUE;
@@ -98,93 +100,55 @@
return TRUE;
}
-BOOLEAN
-DiskGetBootPath(OUT PCHAR BootPath, IN ULONG Size)
+
+extern BOOLEAN
+DiskIsCdRomDrive(UCHAR DriveNumber);
+
+BOOLEAN DiskGetBootPath(OUT PCHAR BootPath, IN ULONG Size)
{
- static char Path[] = "multi(0)disk(0)";
- char Device[4];
- MASTER_BOOT_RECORD MasterBootRecord;
+ if (*FrldrBootPath)
+ goto Done;
/* 0x49 is our magic ramdisk drive, so try to detect it first */
if (FrldrBootDrive == 0x49)
{
/* This is the ramdisk. See ArmDiskGetBootPath too... */
-
- PCCH RamDiskPath = "ramdisk(0)";
-
- if (Size < sizeof(RamDiskPath))
- {
- return FALSE;
- }
-
- strcpy(BootPath, RamDiskPath);
+ // sprintf(FrldrBootPath, "ramdisk(%u)", 0);
+ strcpy(FrldrBootPath, "ramdisk(0)");
}
else if (FrldrBootDrive < 0x80)
{
/* This is a floppy */
-
- if (Size <= sizeof(Path) + 7 + sizeof(Device))
- {
- return FALSE;
- }
-
- strcpy(BootPath, Path);
-
- _itoa(FrldrBootDrive, Device, 10);
- strcat(BootPath, "fdisk(");
- strcat(BootPath, Device);
- strcat(BootPath, ")");
+ sprintf(FrldrBootPath, "multi(0)disk(0)fdisk(%u)", FrldrBootDrive);
}
- /* FIXME */
- else if (DiskReadBootRecord(FrldrBootDrive, 0, &MasterBootRecord))
+ else if (DiskIsCdRomDrive(FrldrBootDrive))
+ {
+ /* This is a CD-ROM drive */
+ sprintf(FrldrBootPath, "multi(0)disk(0)cdrom(%u)", FrldrBootDrive -
0x80);
+ }
+ else
{
ULONG BootPartition;
PARTITION_TABLE_ENTRY PartitionEntry;
- char Partition[4];
/* This is a hard disk */
if (!DiskGetActivePartitionEntry(FrldrBootDrive, &PartitionEntry,
&BootPartition))
{
- DbgPrint("Invalid active partition information\n");
+ ERR("Invalid active partition information\n");
return FALSE;
}
FrldrBootPartition = BootPartition;
- if (Size <= sizeof(Path) + 18 + sizeof(Device) + sizeof(Partition))
- {
- return FALSE;
- }
-
- strcpy(BootPath, Path);
-
- _itoa(FrldrBootDrive - 0x80, Device, 10);
- strcat(BootPath, "rdisk(");
- strcat(BootPath, Device);
- strcat(BootPath, ")");
-
- _itoa(FrldrBootPartition, Partition, 10);
- strcat(BootPath, "partition(");
- strcat(BootPath, Partition);
- strcat(BootPath, ")");
- }
- else
- {
- /* This is a CD-ROM drive */
-
- if (Size <= sizeof(Path) + 7 + sizeof(Device))
- {
- return FALSE;
- }
-
- strcpy(BootPath, Path);
-
- _itoa(FrldrBootDrive - 0x80, Device, 10);
- strcat(BootPath, "cdrom(");
- strcat(BootPath, Device);
- strcat(BootPath, ")");
+ sprintf(FrldrBootPath, "multi(0)disk(0)rdisk(%u)partition(%lu)",
+ FrldrBootDrive - 0x80, FrldrBootPartition);
}
+Done:
+ /* Copy back the buffer */
+ if (Size < strlen(FrldrBootPath) + 1)
+ return FALSE;
+ strncpy(BootPath, FrldrBootPath, Size);
return TRUE;
}
Modified: trunk/reactos/boot/freeldr/freeldr/include/disk.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/inclu…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/include/disk.h [iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/include/disk.h [iso-8859-1] Sun Jan 29 15:43:12
2017
@@ -121,16 +121,21 @@
// FreeLoader Disk Functions
//
///////////////////////////////////////////////////////////////////////////////////////
-VOID DiskReportError (BOOLEAN bError);
+VOID DiskReportError(BOOLEAN bError);
VOID DiskError(PCSTR ErrorString, ULONG ErrorCode);
PCSTR DiskGetErrorCodeString(ULONG ErrorCode);
BOOLEAN DiskIsDriveRemovable(UCHAR DriveNumber);
+
+BOOLEAN DiskGetBootPath(OUT PCHAR BootPath, IN ULONG Size);
+/* Platform-specific boot drive and partition numbers */
extern UCHAR FrldrBootDrive;
extern ULONG FrldrBootPartition;
+/* ARC path of the boot drive and partition */
+extern CHAR FrldrBootPath[MAX_PATH];
+
+/* Buffer for disk reads */
extern PVOID DiskReadBuffer;
extern SIZE_T DiskReadBufferSize;
-
-BOOLEAN DiskGetBootPath(OUT PCHAR BootPath, IN ULONG Size);
///////////////////////////////////////////////////////////////////////////////////////