From: Alex Henrie alexhenrie24@gmail.com
SCSI command 0x46 (GPCMD_GET_CONFIGURATION) returns in the seventh and eighth bytes the "profile" that the disc drive is currently using, which corresponds to the physical type of the disc in the drive. Profile numbers 16 and up are used for DVDs and blu-rays, and Windows does not distinguish between the two.
The GET CONFIGURATION request format, response format, and profile numbers are defined on pages 1, 2, and 7 of https://www.t10.org/ftp/t10/document.97/97-263r0.pdf and pages 66-71 of https://www.t10.org/ftp/t10/document.05/05-206r0.pdf.
More specific media information is still not implemented.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57790 --- dlls/ntdll/unix/cdrom.c | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-)
diff --git a/dlls/ntdll/unix/cdrom.c b/dlls/ntdll/unix/cdrom.c index 5a700940ceb..af98aabb9f2 100644 --- a/dlls/ntdll/unix/cdrom.c +++ b/dlls/ntdll/unix/cdrom.c @@ -758,11 +758,37 @@ static NTSTATUS CDROM_GetDriveGeometry(int dev, int fd, DISK_GEOMETRY* dg) * CDROM_GetMediaType * */ -static NTSTATUS CDROM_GetMediaType(int dev, GET_MEDIA_TYPES* medtype) +static NTSTATUS CDROM_GetMediaType(int dev, int fd, GET_MEDIA_TYPES* medtype) { - FIXME(": faking success\n"); + FIXME("semi-stub\n"); medtype->DeviceType = FILE_DEVICE_CD_ROM; medtype->MediaInfoCount = 0; + +#if defined(HAVE_SG_IO_HDR_T_INTERFACE_ID) && defined(HAVE_LINUX_CDROM_H) + { + unsigned char drive_config[8]; + unsigned char get_config_cmd[10] = { GPCMD_GET_CONFIGURATION, 0, 0xff, 0xff, + 0, 0, 0, 0, sizeof(drive_config), 0 }; + sg_io_hdr_t iocmd = + { + .interface_id = 'S', + .dxfer_direction = SG_DXFER_FROM_DEV, + .cmd_len = sizeof(get_config_cmd), + .dxfer_len = sizeof(drive_config), + .dxferp = drive_config, + .cmdp = get_config_cmd, + .timeout = 1000, + }; + int err; + + if ((err = ioctl(fd, SG_IO, &iocmd))) + return CDROM_GetStatusCode(err); + + if (iocmd.status == 0 && (drive_config[6] || drive_config[7] >= 0x10)) + medtype->DeviceType = FILE_DEVICE_DVD; + } +#endif + return STATUS_SUCCESS; }
@@ -2908,7 +2934,7 @@ NTSTATUS cdrom_DeviceIoControl( HANDLE device, HANDLE event, PIO_APC_ROUTINE apc sz = sizeof(GET_MEDIA_TYPES); if (in_buffer != NULL || in_size != 0) status = STATUS_INVALID_PARAMETER; else if (out_size < sz) status = STATUS_BUFFER_TOO_SMALL; - else status = CDROM_GetMediaType(dev, out_buffer); + else status = CDROM_GetMediaType(dev, fd, out_buffer); break;
case IOCTL_STORAGE_GET_DEVICE_NUMBER: