[CDROM]
authorPierre Schweitzer <pierre@reactos.org>
Mon, 28 Sep 2015 21:06:02 +0000 (21:06 +0000)
committerPierre Schweitzer <pierre@reactos.org>
Mon, 28 Sep 2015 21:06:02 +0000 (21:06 +0000)
Finally implement support for IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, IOCTL_CDROM_GET_DRIVE_GEOMETRY_EX

svn path=/trunk/; revision=69410

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

index f86f2de..a05e855 100644 (file)
@@ -2181,7 +2181,9 @@ 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: {
 
             //
@@ -3163,6 +3165,139 @@ CdRomDeviceControlCompletion(
             break;
         }
 
+        case IOCTL_DISK_GET_DRIVE_GEOMETRY_EX:
+        case IOCTL_CDROM_GET_DRIVE_GEOMETRY_EX: {
+
+            PREAD_CAPACITY_DATA readCapacityBuffer = srb->DataBuffer;
+            ULONG               lastSector;
+            ULONG               bps;
+            ULONG               lastBit;
+            ULONG               tmp;
+            PDISK_GEOMETRY_EX   geometryEx;
+
+            //
+            // 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.
+            //
+
+            geometryEx = realIrp->AssociatedIrp.SystemBuffer;
+            RtlMoveMemory(&geometryEx->Geometry,
+                          &deviceExtension->DiskGeometry->Geometry,
+                          sizeof(DISK_GEOMETRY));
+
+            //
+            // Copy the extended information
+            //
+
+            geometryEx->DiskSize = deviceExtension->PartitionLength;
+
+            //
+            // update information field.
+            //
+
+            realIrp->IoStatus.Information = FIELD_OFFSET(DISK_GEOMETRY_EX, Data);;
+            break;
+        }
+
         case IOCTL_DISK_GET_DRIVE_GEOMETRY:
         case IOCTL_CDROM_GET_DRIVE_GEOMETRY: {