Finally implement support for IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, IOCTL_CDROM_GET_DRIVE_GEOMETRY_EX

svn path=/trunk/; revision=69410
This commit is contained in:
Pierre Schweitzer 2015-09-28 21:06:02 +00:00
parent fbd1e44066
commit 15bcae3db8

View 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: {