[CDROM]
authorPierre Schweitzer <pierre@reactos.org>
Mon, 28 Sep 2015 20:20:46 +0000 (20:20 +0000)
committerPierre Schweitzer <pierre@reactos.org>
Mon, 28 Sep 2015 20:20:46 +0000 (20:20 +0000)
- Don't support IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, IOCTL_CDROM_GET_DRIVE_GEOMETRY_EX for now
- Properly implement IRP completion for IOCTL_DISK_GET_LENGTH_INFO, IOCTL_DISK_GET_DRIVE_GEOMETRY

svn path=/trunk/; revision=69409

reactos/drivers/storage/class/cdrom/cdrom.c

index b24dfe2..f86f2de 100644 (file)
@@ -2181,9 +2181,7 @@ ScsiCdRomStartIo(
         }
 
         case IOCTL_DISK_GET_LENGTH_INFO:
-        case IOCTL_DISK_GET_DRIVE_GEOMETRY_EX:
         case IOCTL_DISK_GET_DRIVE_GEOMETRY:
-        case IOCTL_CDROM_GET_DRIVE_GEOMETRY_EX:
         case IOCTL_CDROM_GET_DRIVE_GEOMETRY: {
 
             //
@@ -3041,6 +3039,131 @@ CdRomDeviceControlCompletion(
 
         switch (realIrpStack->Parameters.DeviceIoControl.IoControlCode) {
 
+        case IOCTL_DISK_GET_LENGTH_INFO: {
+
+            PREAD_CAPACITY_DATA readCapacityBuffer = srb->DataBuffer;
+            ULONG               lastSector;
+            ULONG               bps;
+            ULONG               lastBit;
+            ULONG               tmp;
+
+            //
+            // Swizzle bytes from Read Capacity and translate into
+            // the necessary geometry information in the device extension.
+            //
+
+            tmp = readCapacityBuffer->BytesPerBlock;
+            ((PFOUR_BYTE)&bps)->Byte0 = ((PFOUR_BYTE)&tmp)->Byte3;
+            ((PFOUR_BYTE)&bps)->Byte1 = ((PFOUR_BYTE)&tmp)->Byte2;
+            ((PFOUR_BYTE)&bps)->Byte2 = ((PFOUR_BYTE)&tmp)->Byte1;
+            ((PFOUR_BYTE)&bps)->Byte3 = ((PFOUR_BYTE)&tmp)->Byte0;
+
+            //
+            // Insure that bps is a power of 2.
+            // This corrects a problem with the HP 4020i CDR where it
+            // returns an incorrect number for bytes per sector.
+            //
+
+            if (!bps) {
+                bps = 2048;
+            } else {
+                lastBit = (ULONG) -1;
+                while (bps) {
+                    lastBit++;
+                    bps = bps >> 1;
+                }
+
+                bps = 1 << lastBit;
+            }
+            deviceExtension->DiskGeometry->Geometry.BytesPerSector = bps;
+
+            DebugPrint((2,
+                        "CdRomDeviceControlCompletion: Calculated bps %#x\n",
+                        deviceExtension->DiskGeometry->Geometry.BytesPerSector));
+
+            //
+            // Copy last sector in reverse byte order.
+            //
+
+            tmp = readCapacityBuffer->LogicalBlockAddress;
+            ((PFOUR_BYTE)&lastSector)->Byte0 = ((PFOUR_BYTE)&tmp)->Byte3;
+            ((PFOUR_BYTE)&lastSector)->Byte1 = ((PFOUR_BYTE)&tmp)->Byte2;
+            ((PFOUR_BYTE)&lastSector)->Byte2 = ((PFOUR_BYTE)&tmp)->Byte1;
+            ((PFOUR_BYTE)&lastSector)->Byte3 = ((PFOUR_BYTE)&tmp)->Byte0;
+
+            //
+            // Calculate sector to byte shift.
+            //
+
+            WHICH_BIT(bps, deviceExtension->SectorShift);
+
+            DebugPrint((2,"SCSI ScsiClassReadDriveCapacity: Sector size is %d\n",
+                deviceExtension->DiskGeometry->Geometry.BytesPerSector));
+
+            DebugPrint((2,"SCSI ScsiClassReadDriveCapacity: Number of Sectors is %d\n",
+                lastSector + 1));
+
+            //
+            // Calculate media capacity in bytes.
+            //
+
+            deviceExtension->PartitionLength.QuadPart = (LONGLONG)(lastSector + 1);
+
+            //
+            // Calculate number of cylinders.
+            //
+
+            deviceExtension->DiskGeometry->Geometry.Cylinders.QuadPart = (LONGLONG)((lastSector + 1)/(32 * 64));
+
+            deviceExtension->PartitionLength.QuadPart =
+                (deviceExtension->PartitionLength.QuadPart << deviceExtension->SectorShift);
+
+            if (DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) {
+
+                //
+                // This device supports removable media.
+                //
+
+                deviceExtension->DiskGeometry->Geometry.MediaType = RemovableMedia;
+
+            } else {
+
+                //
+                // Assume media type is fixed disk.
+                //
+
+                deviceExtension->DiskGeometry->Geometry.MediaType = FixedMedia;
+            }
+
+            //
+            // Assume sectors per track are 32;
+            //
+
+            deviceExtension->DiskGeometry->Geometry.SectorsPerTrack = 32;
+
+            //
+            // Assume tracks per cylinder (number of heads) is 64.
+            //
+
+            deviceExtension->DiskGeometry->Geometry.TracksPerCylinder = 64;
+
+            //
+            // Copy the device extension's geometry info into the user buffer.
+            //
+
+            RtlMoveMemory(realIrp->AssociatedIrp.SystemBuffer,
+                          &deviceExtension->PartitionLength,
+                          sizeof(GET_LENGTH_INFORMATION));
+
+            //
+            // update information field.
+            //
+
+            realIrp->IoStatus.Information = sizeof(DISK_GEOMETRY);
+            break;
+        }
+
+        case IOCTL_DISK_GET_DRIVE_GEOMETRY:
         case IOCTL_CDROM_GET_DRIVE_GEOMETRY: {
 
             PREAD_CAPACITY_DATA readCapacityBuffer = srb->DataBuffer;