[FREELDR] ArcGetFileInformation(): Set the Information->Type field for devices (#8418)

CORE-9023

Some of this determination is platform-specific (e.g. BIOS-based PC vs.
NEC PC-98 vs. Xbox), and is done in a per-platform `DiskGetConfigType()`
routine.
This routine is then invoked by `hwdisk.c!DiskOpen()` and `PcInitializeBootDevices()`.
This commit is contained in:
Hermès Bélusca-Maïto
2025-10-04 15:56:52 +02:00
parent e969fbeea8
commit 246f2d29db
9 changed files with 75 additions and 30 deletions

View File

@@ -34,6 +34,7 @@ DBG_DEFAULT_CHANNEL(HWDETECT);
typedef struct tagDISKCONTEXT
{
UCHAR DriveNumber;
BOOLEAN IsFloppy;
ULONG SectorSize;
ULONGLONG SectorOffset;
ULONGLONG SectorCount;
@@ -77,6 +78,8 @@ DiskGetFileInformation(ULONG FileId, FILEINFORMATION* Information)
Information->EndingAddress.QuadPart = (Context->SectorOffset + Context->SectorCount) * Context->SectorSize;
Information->CurrentAddress.QuadPart = Context->SectorNumber * Context->SectorSize;
Information->Type = (Context->IsFloppy ? FloppyDiskPeripheral : DiskPeripheral);
return ESUCCESS;
}
@@ -84,6 +87,7 @@ static ARC_STATUS
DiskOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId)
{
DISKCONTEXT* Context;
CONFIGURATION_TYPE DriveType;
UCHAR DriveNumber;
ULONG DrivePartition, SectorSize;
ULONGLONG SectorOffset = 0;
@@ -100,19 +104,16 @@ DiskOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId)
if (!DissectArcPath(Path, NULL, &DriveNumber, &DrivePartition))
return EINVAL;
if (DrivePartition == 0xff)
DriveType = DiskGetConfigType(DriveNumber);
if (DriveType == CdromController)
{
/* This is a CD-ROM device */
SectorSize = 2048;
}
else
{
/*
* This is either a floppy disk device (DrivePartition == 0) or
* a hard disk device (DrivePartition != 0 && DrivePartition != 0xFF)
* but it doesn't matter which one because they both have 512 bytes
* per sector.
*/
/* This is either a floppy disk or a hard disk device, but it doesn't
* matter which one because they both have 512 bytes per sector */
SectorSize = 512;
}
@@ -145,6 +146,7 @@ DiskOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId)
return ENOMEM;
Context->DriveNumber = DriveNumber;
Context->IsFloppy = (DriveType == FloppyDiskPeripheral);
Context->SectorSize = SectorSize;
Context->SectorOffset = SectorOffset;
Context->SectorCount = SectorCount;
@@ -399,23 +401,6 @@ EnumerateHarddisks(OUT PBOOLEAN BootDriveReported)
return DiskCount;
}
// FIXME: Copied from pcdisk.c
// Actually this function is REALLY PC-specific!!
static BOOLEAN
DiskIsDriveRemovable(UCHAR DriveNumber)
{
/*
* Hard disks use drive numbers >= 0x80 . So if the drive number
* indicates a hard disk then return FALSE.
* 0x49 is our magic ramdisk drive, so return FALSE for that too.
*/
if ((DriveNumber >= 0x80) || (DriveNumber == 0x49))
return FALSE;
/* The drive is a floppy diskette so return TRUE */
return TRUE;
}
static BOOLEAN
DiskGetBootPath(BOOLEAN IsPxe)
{
@@ -474,23 +459,25 @@ PcInitializeBootDevices(VOID)
{
UCHAR DiskCount;
BOOLEAN BootDriveReported = FALSE;
ULONG i;
CONFIGURATION_TYPE DriveType;
DiskCount = EnumerateHarddisks(&BootDriveReported);
/* Initialize FrLdrBootPath, the boot path we're booting from (the "SystemPartition") */
DiskGetBootPath(PxeInit());
/* Add it, if it's a floppy or cdrom */
/* Add it, if it's a floppy or CD-ROM */
DriveType = DiskGetConfigType(FrldrBootDrive);
if ((FrldrBootDrive >= FIRST_BIOS_DISK && !BootDriveReported) ||
DiskIsDriveRemovable(FrldrBootDrive))
(DriveType == FloppyDiskPeripheral || DriveType == CdromController))
{
/* TODO: Check if it's really a CDROM drive */
/* TODO: Check if it's really a CD-ROM drive */
PMASTER_BOOT_RECORD Mbr;
PULONG Buffer;
ULONG Checksum = 0;
ULONG Signature;
ULONG i;
/* Read the MBR */
if (!MachDiskReadLogicalSectors(FrldrBootDrive, 16ULL, 1, DiskReadBuffer))

View File

@@ -398,6 +398,18 @@ DiskGetExtendedDriveParameters(
return TRUE;
}
CONFIGURATION_TYPE
DiskGetConfigType(
_In_ UCHAR DriveNumber)
{
if ((DriveNumber == FrldrBootDrive)/* && DiskIsDriveRemovable(DriveNumber) */ && (FrldrBootPartition == 0xFF))
return CdromController; /* This is our El Torito boot CD-ROM */
else if (DiskIsDriveRemovable(DriveNumber))
return FloppyDiskPeripheral;
else
return DiskPeripheral;
}
static BOOLEAN
InitDriveGeometry(
IN UCHAR DriveNumber,

View File

@@ -149,6 +149,24 @@ Pc98DiskDriveNumberToDrive(IN UCHAR DriveNumber)
return NULL;
}
CONFIGURATION_TYPE
DiskGetConfigType(
_In_ UCHAR DriveNumber)
{
PPC98_DISK_DRIVE DiskDrive;
DiskDrive = Pc98DiskDriveNumberToDrive(DriveNumber);
if (!DiskDrive)
return -1; // MaximumType;
if (DiskDrive->Type & DRIVE_CDROM || DiskDrive->Type & DRIVE_MO)
return CdromController;
else if (DiskDrive->Type & DRIVE_FDD)
return FloppyDiskPeripheral;
else
return DiskPeripheral;
}
static inline
UCHAR
BytesPerSectorToSectorLengthCode(IN ULONG BytesPerSector)

View File

@@ -77,6 +77,22 @@ XboxDiskDriveNumberToDeviceUnit(UCHAR DriveNumber)
return NULL;
}
CONFIGURATION_TYPE
DiskGetConfigType(
_In_ UCHAR DriveNumber)
{
PDEVICE_UNIT DeviceUnit;
DeviceUnit = XboxDiskDriveNumberToDeviceUnit(DriveNumber);
if (!DeviceUnit)
return -1; // MaximumType;
if (DeviceUnit == CdDrive) // (DeviceUnit->Flags & ATA_DEVICE_ATAPI)
return CdromController;
else // if (DeviceUnit == HardDrive)
return DiskPeripheral;
}
BOOLEAN
XboxDiskReadLogicalSectors(
IN UCHAR DriveNumber,

View File

@@ -132,6 +132,8 @@ UefiDiskGetFileInformation(ULONG FileId, FILEINFORMATION *Information)
Information->EndingAddress.QuadPart = (Context->SectorOffset + Context->SectorCount) * Context->SectorSize;
Information->CurrentAddress.QuadPart = Context->SectorNumber * Context->SectorSize;
Information->Type = DiskPeripheral; /* No floppy for you for now... */
return ESUCCESS;
}
@@ -491,8 +493,6 @@ UefiSetBootpath(VOID)
BOOLEAN
UefiInitializeBootDevices(VOID)
{
ULONG i = 0;
DiskReadBufferSize = EFI_PAGE_SIZE;
DiskReadBuffer = MmAllocateMemoryWithType(DiskReadBufferSize, LoaderFirmwareTemporary);
UefiSetupBlockDevices();
@@ -506,6 +506,7 @@ UefiInitializeBootDevices(VOID)
PULONG Buffer;
ULONG Checksum = 0;
ULONG Signature;
ULONG i;
/* Read the MBR */
if (!MachDiskReadLogicalSectors(FrldrBootDrive, 16ULL, 1, DiskReadBuffer))

View File

@@ -40,6 +40,7 @@ static ARC_STATUS RamDiskGetFileInformation(ULONG FileId, FILEINFORMATION* Infor
RtlZeroMemory(Information, sizeof(*Information));
Information->EndingAddress.QuadPart = RamDiskImageLength;
Information->CurrentAddress.QuadPart = RamDiskOffset;
Information->Type = DiskPeripheral;
return ESUCCESS;
}

View File

@@ -141,6 +141,10 @@ typedef struct _PC98_DISK_DRIVE
extern UCHAR FrldrBootDrive;
extern ULONG FrldrBootPartition;
CONFIGURATION_TYPE
DiskGetConfigType(
_In_ UCHAR DriveNumber);
LONG DiskReportError(BOOLEAN bShowError);
BOOLEAN DiskResetController(IN PPC98_DISK_DRIVE DiskDrive);

View File

@@ -56,6 +56,10 @@ BOOLEAN PcFindPciBios(PPCI_REGISTRY_INFO BusData);
extern UCHAR FrldrBootDrive;
extern ULONG FrldrBootPartition;
CONFIGURATION_TYPE
DiskGetConfigType(
_In_ UCHAR DriveNumber);
LONG DiskReportError(BOOLEAN bShowError);
BOOLEAN DiskResetController(UCHAR DriveNumber);

View File

@@ -138,6 +138,8 @@ static ARC_STATUS PxeGetFileInformation(ULONG FileId, FILEINFORMATION* Informati
Information->EndingAddress.LowPart = _FileSize;
Information->CurrentAddress.LowPart = _FilePosition;
Information->Type = NetworkPeripheral;
TRACE("PxeGetFileInformation(%lu) -> FileSize = %lu, FilePointer = 0x%lx\n",
FileId, Information->EndingAddress.LowPart, Information->CurrentAddress.LowPart);