From b51789c28d7d0ed0ca772e102e0562abe82b3dec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Sat, 4 Oct 2025 16:22:56 +0200 Subject: [PATCH] [FREELDR] scsiport.c: Set the Information->Type field (#8418) CORE-9023 And more accurately detect and report disks: using `InquiryBuffer.DeviceType`, differentiate between "rigid" disks, floppy disks, and CD-ROM drives. --- boot/freeldr/freeldr/disk/scsiport.c | 71 ++++++++++++++++++---------- 1 file changed, 46 insertions(+), 25 deletions(-) diff --git a/boot/freeldr/freeldr/disk/scsiport.c b/boot/freeldr/freeldr/disk/scsiport.c index fa63d6e6387..d04d2743789 100644 --- a/boot/freeldr/freeldr/disk/scsiport.c +++ b/boot/freeldr/freeldr/disk/scsiport.c @@ -67,7 +67,7 @@ typedef struct PVOID NonCachedExtension; ULONG BusNum; - ULONG MaxTargedIds; + ULONG MaxTargetIds; ULONG InterruptFlags; @@ -99,6 +99,7 @@ typedef struct tagDISKCONTEXT UCHAR Lun; /* Device characteristics */ + BOOLEAN IsFloppy; ULONG SectorSize; ULONGLONG SectorOffset; ULONGLONG SectorCount; @@ -196,6 +197,8 @@ static ARC_STATUS DiskGetFileInformation(ULONG FileId, FILEINFORMATION* Informat Information->EndingAddress.QuadPart = (Context->SectorOffset + Context->SectorCount) * Context->SectorSize; Information->CurrentAddress.QuadPart = Context->SectorNumber * Context->SectorSize; + Information->Type = (Context->IsFloppy ? FloppyDiskPeripheral : DiskPeripheral); + return ESUCCESS; } @@ -260,6 +263,7 @@ static ARC_STATUS DiskOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId) Context->PathId = (UCHAR)PathId; Context->TargetId = (UCHAR)TargetId; Context->Lun = (UCHAR)Lun; + Context->IsFloppy = (!strstr(Path, ")cdrom(") && strstr(Path, ")fdisk(")); Context->SectorSize = SectorSize; Context->SectorOffset = SectorOffset; Context->SectorCount = SectorCount; @@ -894,13 +898,11 @@ SpiScanAdapter( /* Remember the extension */ ScsiDeviceExtensions[ScsiBus] = DeviceExtension; - for (TargetId = 0; TargetId < DeviceExtension->MaxTargedIds; TargetId++) + for (TargetId = 0; TargetId < DeviceExtension->MaxTargetIds; TargetId++) { - Lun = 0; - do + for (Lun = 0; Lun < SCSI_MAXIMUM_LOGICAL_UNITS; Lun++) { - TRACE("Scanning SCSI device %d.%d.%d\n", - ScsiBus, TargetId, Lun); + TRACE("Scanning SCSI device %lu.%u.%u\n", ScsiBus, TargetId, Lun); Srb = ExAllocatePool(PagedPool, sizeof(SCSI_REQUEST_BLOCK)); if (!Srb) @@ -926,24 +928,43 @@ SpiScanAdapter( break; } - /* Device exists, create its ARC name */ - if (InquiryBuffer.RemovableMedia) + /* + * Device exists, create its ARC name. + * NOTE: Other devices are not supported: + * - SEQUENTIAL_ACCESS_DEVICE i.e. Tape, + * - WRITE_ONCE_READ_MULTIPLE_DEVICE i.e. Worm. + */ + if ((InquiryBuffer.DeviceType == DIRECT_ACCESS_DEVICE) || + (InquiryBuffer.DeviceType == OPTICAL_DEVICE)) { - sprintf(ArcName, "scsi(%ld)cdrom(%d)fdisk(%d)", - ScsiBus, TargetId, Lun); + if ((InquiryBuffer.DeviceType == DIRECT_ACCESS_DEVICE) && + InquiryBuffer.RemovableMedia) + { + /* Floppy disk */ + RtlStringCbPrintfA(ArcName, sizeof(ArcName), + "scsi(%lu)disk(%u)fdisk(%u)", + ScsiBus, TargetId, Lun); + FsRegisterDevice(ArcName, &DiskVtbl); + } + else + { + /* Other rigid disk */ + RtlStringCbPrintfA(ArcName, sizeof(ArcName), + "scsi(%lu)disk(%u)rdisk(%u)", + ScsiBus, TargetId, Lun); + /* Now, check if it has partitions */ + SpiScanDevice(DeviceExtension, ArcName, PathId, TargetId, Lun); + } + } + else if (InquiryBuffer.DeviceType == READ_ONLY_DIRECT_ACCESS_DEVICE) + { + /* CD-ROM; note that the RemovableMedia bit may or may not be set */ + RtlStringCbPrintfA(ArcName, sizeof(ArcName), + "scsi(%lu)cdrom(%u)fdisk(%u)", + ScsiBus, TargetId, Lun); FsRegisterDevice(ArcName, &DiskVtbl); } - else - { - sprintf(ArcName, "scsi(%ld)disk(%d)rdisk(%d)", - ScsiBus, TargetId, Lun); - /* Now, check if it has partitions */ - SpiScanDevice(DeviceExtension, ArcName, PathId, TargetId, Lun); - } - - /* Check next LUN */ - Lun++; - } while (Lun < SCSI_MAXIMUM_LOGICAL_UNITS); + } } } @@ -1249,14 +1270,14 @@ ScsiPortInitialize( /* Copy all stuff which we ever need from PortConfig to the DeviceExtension */ if (PortConfig.MaximumNumberOfTargets > SCSI_MAXIMUM_TARGETS_PER_BUS) - DeviceExtension->MaxTargedIds = SCSI_MAXIMUM_TARGETS_PER_BUS; + DeviceExtension->MaxTargetIds = SCSI_MAXIMUM_TARGETS_PER_BUS; else - DeviceExtension->MaxTargedIds = PortConfig.MaximumNumberOfTargets; + DeviceExtension->MaxTargetIds = PortConfig.MaximumNumberOfTargets; DeviceExtension->BusNum = PortConfig.SystemIoBusNumber; - TRACE("Adapter found: buses = %d, targets = %d\n", - PortConfig.NumberOfBuses, DeviceExtension->MaxTargedIds); + TRACE("Adapter found: buses = %u, targets = %u\n", + PortConfig.NumberOfBuses, DeviceExtension->MaxTargetIds); /* Initialize adapter */ if (!DeviceExtension->HwInitialize(DeviceExtension->MiniPortDeviceExtension))