diff --git a/lib/MSWindows/ioctl.c b/lib/MSWindows/ioctl.c index 2d62e037..9eae0779 100644 --- a/lib/MSWindows/ioctl.c +++ b/lib/MSWindows/ioctl.c @@ -1,5 +1,5 @@ /* - $Id: ioctl.c,v 1.5 2004/04/23 22:10:53 rocky Exp $ + $Id: ioctl.c,v 1.6 2004/04/24 04:46:33 rocky Exp $ Copyright (C) 2004 Rocky Bernstein @@ -26,7 +26,7 @@ # include "config.h" #endif -static const char _rcsid[] = "$Id: ioctl.c,v 1.5 2004/04/23 22:10:53 rocky Exp $"; +static const char _rcsid[] = "$Id: ioctl.c,v 1.6 2004/04/24 04:46:33 rocky Exp $"; #include #include @@ -36,8 +36,11 @@ static const char _rcsid[] = "$Id: ioctl.c,v 1.5 2004/04/23 22:10:53 rocky Exp $ #include #include +#include +#include #include +#include /* offsetof() macro */ #include #include @@ -48,52 +51,6 @@ static const char _rcsid[] = "$Id: ioctl.c,v 1.5 2004/04/23 22:10:53 rocky Exp $ modify it a little. */ -#define SCSI_IOCTL_DATA_OUT 0 //Give data to SCSI device (e.g. for writing) -#define SCSI_IOCTL_DATA_IN 1 //Get data from SCSI device (e.g. for reading) -#define SCSI_IOCTL_DATA_UNSPECIFIED 2 //No data (e.g. for ejecting) - -#define IOCTL_SCSI_PASS_THROUGH 0x4D004 -typedef struct ScsiPassThrough { - unsigned short Length; - unsigned char ScsiStatus; - unsigned char PathId; - unsigned char TargetId; - unsigned char Lun; - unsigned char CdbLength; - unsigned char SenseInfoLength; - unsigned char DataIn; - unsigned int DataTransferLength; - unsigned int TimeOutValue; - unsigned int DataBufferOffset; - unsigned int SenseInfoOffset; - unsigned char Cdb[16]; -} SCSI_PASS_THROUGH; - -#define IOCTL_SCSI_PASS_THROUGH_DIRECT 0x4D014 -typedef struct _SCSI_PASS_THROUGH_DIRECT { - USHORT Length; - UCHAR ScsiStatus; - UCHAR PathId; - UCHAR TargetId; - UCHAR Lun; - UCHAR CdbLength; - UCHAR SenseInfoLength; - UCHAR DataIn; - ULONG DataTransferLength; - ULONG TimeOutValue; - PVOID DataBuffer; - ULONG SenseInfoOffset; - UCHAR Cdb[16]; -} SCSI_PASS_THROUGH_DIRECT, *PSCSI_PASS_THROUGH_DIRECT; - -#ifndef IOCTL_CDROM_BASE -# define IOCTL_CDROM_BASE FILE_DEVICE_CD_ROM -#endif -#ifndef IOCTL_CDROM_RAW_READ -#define IOCTL_CDROM_RAW_READ CTL_CODE(IOCTL_CDROM_BASE, 0x000F, \ - METHOD_OUT_DIRECT, FILE_READ_ACCESS) -#endif - #ifndef IOCTL_CDROM_BASE # define IOCTL_CDROM_BASE FILE_DEVICE_CD_ROM #endif @@ -102,8 +59,8 @@ typedef struct _SCSI_PASS_THROUGH_DIRECT { CTL_CODE(IOCTL_CDROM_BASE, 0x0000, METHOD_BUFFERED, FILE_READ_ACCESS) #endif #ifndef IOCTL_CDROM_RAW_READ -#define IOCTL_CDROM_RAW_READ \ - CTL_CODE(IOCTL_CDROM_BASE, 0x000F, METHOD_OUT_DIRECT, FILE_READ_ACCESS) +#define IOCTL_CDROM_RAW_READ CTL_CODE(IOCTL_CDROM_BASE, 0x000F, \ + METHOD_OUT_DIRECT, FILE_READ_ACCESS) #endif #ifndef IOCTL_CDROM_READ_Q_CHANNEL @@ -111,6 +68,13 @@ typedef struct _SCSI_PASS_THROUGH_DIRECT { CTL_CODE(IOCTL_CDROM_BASE, 0x000B, METHOD_BUFFERED, FILE_READ_ACCESS) #endif +typedef struct { + SCSI_PASS_THROUGH Spt; + ULONG Filler; + UCHAR SenseBuf[32]; + UCHAR DataBuf[512]; +} SCSI_PASS_THROUGH_WITH_BUFFERS; + typedef struct _TRACK_DATA { UCHAR Format; UCHAR Control : 4; @@ -480,43 +444,64 @@ cdio_drive_cap_t win32ioctl_get_drive_cap (const void *env) { const _img_private_t *_obj = env; int32_t i_drivetype; - unsigned int len = strlen(_obj->gen.source_name); - char psz_drive[4]; - - strcpy( psz_drive, "X:" ); + SCSI_PASS_THROUGH_WITH_BUFFERS sptwb; + ULONG returned = 0; + ULONG length; - psz_drive[0] = _obj->gen.source_name[len-2]; - i_drivetype = GetDriveType(psz_drive); - switch (i_drivetype) { - case DRIVE_CDROM: + /* If device supports SCSI-3, then we can get the CD drive + capabilities, i.e. ability to read/write to CD-ROM/R/RW + or/and read/write to DVD-ROM/R/RW. */ + + memset(&sptwb,0, sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS)); + + sptwb.Spt.Length = sizeof(SCSI_PASS_THROUGH); + sptwb.Spt.PathId = 0; + sptwb.Spt.TargetId = 1; + sptwb.Spt.Lun = 0; + sptwb.Spt.CdbLength = 6; /* CDB6GENERIC_LENGTH; */ + sptwb.Spt.SenseInfoLength = 24; + sptwb.Spt.DataIn = SCSI_IOCTL_DATA_IN; + sptwb.Spt.DataTransferLength = 192; + sptwb.Spt.TimeOutValue = 2; + sptwb.Spt.DataBufferOffset = + offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS,DataBuf); + sptwb.Spt.SenseInfoOffset = + offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS,SenseBuf); + sptwb.Spt.Cdb[0] = SCSIOP_MODE_SENSE; + sptwb.Spt.Cdb[1] = 0x08; /* target doesn't return block descriptors */ + sptwb.Spt.Cdb[2] = MODE_PAGE_CAPABILITIES; + sptwb.Spt.Cdb[4] = 192; + length = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS,DataBuf) + + sptwb.Spt.DataTransferLength; + + if ( DeviceIoControl(_obj->h_device_handle, + IOCTL_SCSI_PASS_THROUGH, + &sptwb, + sizeof(SCSI_PASS_THROUGH), + &sptwb, + length, + &returned, + FALSE) ) { -#if 0 - DWORD dwBytesReturned; - GET_MEDIA_TYPES mediaTypes; - i_drivetype = CDIO_DRIVE_CD_R; - if ( DeviceIoControl(_obj->h_device_handle, - IOCTL_STORAGE_GET_MEDIA_TYPES_EX, - NULL, 0, &mediaTypes, sizeof(GET_MEDIA_TYPES), - &dwBytesReturned, NULL) ) { - switch (mediaTypes.DeviceType) { - case FILE_DEVICE_DVD: - i_drivetype = CDIO_DRIVE_DVD_R; - break; - case FILE_DEVICE_CD_ROM: - i_drivetype = CDIO_DRIVE_CD_R; - break; - default: - ; - } - } -#else - i_drivetype = CDIO_DRIVE_CD_R; -#endif + /* Reader */ + if (sptwb.DataBuf[6] & 0x01) i_drivetype |= CDIO_DRIVE_CD_R; + if (sptwb.DataBuf[6] & 0x02) i_drivetype |= CDIO_DRIVE_CD_RW; + if (sptwb.DataBuf[6] & 0x08) i_drivetype |= CDIO_DRIVE_DVD; + if (sptwb.DataBuf[6] & 0x10) i_drivetype |= CDIO_DRIVE_DVD_R; + if (sptwb.DataBuf[6] & 0x20) i_drivetype |= CDIO_DRIVE_DVD_RAM; + + /* Writer */ + if (sptwb.DataBuf[7] & 0x01) i_drivetype |= CDIO_DRIVE_CD_R; + if (sptwb.DataBuf[7] & 0x02) i_drivetype |= CDIO_DRIVE_CD_RW; + if (sptwb.DataBuf[7] & 0x08) i_drivetype |= CDIO_DRIVE_DVD; + if (sptwb.DataBuf[7] & 0x10) i_drivetype |= CDIO_DRIVE_DVD_R; + if (sptwb.DataBuf[7] & 0x20) i_drivetype |= CDIO_DRIVE_DVD_RAM; + return i_drivetype; - default: - return CDIO_DRIVE_ERROR; + } else { + i_drivetype = CDIO_DRIVE_CD_R | CDIO_DRIVE_UNKNOWN; } - } + return CDIO_DRIVE_ERROR; } #endif /*HAVE_WIN32_CDROM*/ diff --git a/lib/MSWindows/win32.c b/lib/MSWindows/win32.c index 4410c4a6..4382c732 100644 --- a/lib/MSWindows/win32.c +++ b/lib/MSWindows/win32.c @@ -1,5 +1,5 @@ /* - $Id: win32.c,v 1.4 2004/03/07 02:40:58 rocky Exp $ + $Id: win32.c,v 1.5 2004/04/24 04:46:33 rocky Exp $ Copyright (C) 2003, 2004 Rocky Bernstein @@ -26,7 +26,7 @@ # include "config.h" #endif -static const char _rcsid[] = "$Id: win32.c,v 1.4 2004/03/07 02:40:58 rocky Exp $"; +static const char _rcsid[] = "$Id: win32.c,v 1.5 2004/04/24 04:46:33 rocky Exp $"; #include #include @@ -81,6 +81,24 @@ cdio_is_cdrom(const char drive_letter) { } } +/*! + Return the the kind of drive capabilities of device. + + Note: string is malloc'd so caller should free() then returned + string when done with it. + + */ +static cdio_drive_cap_t +_cdio_get_drive_cap (const void *env) { + const _img_private_t *_obj = env; + + if (_obj->hASPI) { + return CDIO_DRIVE_UNKNOWN; + } else { + return win32ioctl_get_drive_cap (env); + } +} + /*! Initialize CD device. */ @@ -578,8 +596,7 @@ cdio_get_default_device_win32(void) bool cdio_is_device_win32(const char *source_name) { - unsigned int len; - len = strlen(source_name); + unsigned int len = strlen(source_name); if (NULL == source_name) return false; @@ -620,6 +637,7 @@ cdio_open_win32 (const char *source_name) .get_arg = _cdio_get_arg, .get_default_device = cdio_get_default_device_win32, .get_devices = cdio_get_devices_win32, + .get_drive_cap = _cdio_get_drive_cap, .get_first_track_num= _cdio_get_first_track_num, .get_mcn = _cdio_get_mcn, .get_num_tracks = _cdio_get_num_tracks, diff --git a/lib/MSWindows/win32.h b/lib/MSWindows/win32.h index 3c48707c..01140b84 100644 --- a/lib/MSWindows/win32.h +++ b/lib/MSWindows/win32.h @@ -1,5 +1,5 @@ /* - $Id: win32.h,v 1.1 2004/03/05 12:32:45 rocky Exp $ + $Id: win32.h,v 1.2 2004/04/24 04:46:33 rocky Exp $ Copyright (C) 2004 Rocky Bernstein @@ -83,6 +83,15 @@ bool win32ioctl_read_toc (_img_private_t *env); char *win32ioctl_get_mcn (_img_private_t *env); +/*! + Return the the kind of drive capabilities of device. + + Note: string is malloc'd so caller should free() then returned + string when done with it. + + */ +cdio_drive_cap_t win32ioctl_get_drive_cap (const void *env); + /*! Get the format (XA, DATA, AUDIO) of a track. */