Author: pschweitzer Date: Mon Sep 28 21:06:02 2015 New Revision: 69410
URL: http://svn.reactos.org/svn/reactos?rev=69410&view=rev Log: [CDROM] Finally implement support for IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, IOCTL_CDROM_GET_DRIVE_GEOMETRY_EX
Modified: trunk/reactos/drivers/storage/class/cdrom/cdrom.c
Modified: trunk/reactos/drivers/storage/class/cdrom/cdrom.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/storage/class/cdrom... ============================================================================== --- trunk/reactos/drivers/storage/class/cdrom/cdrom.c [iso-8859-1] (original) +++ trunk/reactos/drivers/storage/class/cdrom/cdrom.c [iso-8859-1] Mon Sep 28 21:06:02 2015 @@ -2181,7 +2181,9 @@ }
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 @@ 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: {