A little better about detecting drive type via SCSI-3 passthrough.

Still has some problems though.
This commit is contained in:
rocky
2004-04-24 04:46:33 +00:00
parent b05dc3aab0
commit 4909e8cd43
3 changed files with 100 additions and 88 deletions

View File

@@ -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 <rocky@panix.com> Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>
@@ -26,7 +26,7 @@
# include "config.h" # include "config.h"
#endif #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 <cdio/cdio.h> #include <cdio/cdio.h>
#include <cdio/sector.h> #include <cdio/sector.h>
@@ -36,8 +36,11 @@ static const char _rcsid[] = "$Id: ioctl.c,v 1.5 2004/04/23 22:10:53 rocky Exp $
#include <windows.h> #include <windows.h>
#include <ddk/ntddstor.h> #include <ddk/ntddstor.h>
#include <ddk/ntddscsi.h>
#include <ddk/scsi.h>
#include <stdio.h> #include <stdio.h>
#include <stddef.h> /* offsetof() macro */
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
@@ -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. 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 #ifndef IOCTL_CDROM_BASE
# define IOCTL_CDROM_BASE FILE_DEVICE_CD_ROM # define IOCTL_CDROM_BASE FILE_DEVICE_CD_ROM
#endif #endif
@@ -102,8 +59,8 @@ typedef struct _SCSI_PASS_THROUGH_DIRECT {
CTL_CODE(IOCTL_CDROM_BASE, 0x0000, METHOD_BUFFERED, FILE_READ_ACCESS) CTL_CODE(IOCTL_CDROM_BASE, 0x0000, METHOD_BUFFERED, FILE_READ_ACCESS)
#endif #endif
#ifndef IOCTL_CDROM_RAW_READ #ifndef IOCTL_CDROM_RAW_READ
#define IOCTL_CDROM_RAW_READ \ #define IOCTL_CDROM_RAW_READ CTL_CODE(IOCTL_CDROM_BASE, 0x000F, \
CTL_CODE(IOCTL_CDROM_BASE, 0x000F, METHOD_OUT_DIRECT, FILE_READ_ACCESS) METHOD_OUT_DIRECT, FILE_READ_ACCESS)
#endif #endif
#ifndef IOCTL_CDROM_READ_Q_CHANNEL #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) CTL_CODE(IOCTL_CDROM_BASE, 0x000B, METHOD_BUFFERED, FILE_READ_ACCESS)
#endif #endif
typedef struct {
SCSI_PASS_THROUGH Spt;
ULONG Filler;
UCHAR SenseBuf[32];
UCHAR DataBuf[512];
} SCSI_PASS_THROUGH_WITH_BUFFERS;
typedef struct _TRACK_DATA { typedef struct _TRACK_DATA {
UCHAR Format; UCHAR Format;
UCHAR Control : 4; UCHAR Control : 4;
@@ -480,43 +444,64 @@ cdio_drive_cap_t
win32ioctl_get_drive_cap (const void *env) { win32ioctl_get_drive_cap (const void *env) {
const _img_private_t *_obj = env; const _img_private_t *_obj = env;
int32_t i_drivetype; int32_t i_drivetype;
unsigned int len = strlen(_obj->gen.source_name); SCSI_PASS_THROUGH_WITH_BUFFERS sptwb;
char psz_drive[4]; ULONG returned = 0;
ULONG length;
strcpy( psz_drive, "X:" ); /* 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;
psz_drive[0] = _obj->gen.source_name[len-2];
i_drivetype = GetDriveType(psz_drive);
switch (i_drivetype) {
case DRIVE_CDROM:
{
#if 0
DWORD dwBytesReturned;
GET_MEDIA_TYPES mediaTypes;
i_drivetype = CDIO_DRIVE_CD_R;
if ( DeviceIoControl(_obj->h_device_handle, if ( DeviceIoControl(_obj->h_device_handle,
IOCTL_STORAGE_GET_MEDIA_TYPES_EX, IOCTL_SCSI_PASS_THROUGH,
NULL, 0, &mediaTypes, sizeof(GET_MEDIA_TYPES), &sptwb,
&dwBytesReturned, NULL) ) { sizeof(SCSI_PASS_THROUGH),
switch (mediaTypes.DeviceType) { &sptwb,
case FILE_DEVICE_DVD: length,
i_drivetype = CDIO_DRIVE_DVD_R; &returned,
break; FALSE) )
case FILE_DEVICE_CD_ROM: {
i_drivetype = CDIO_DRIVE_CD_R; /* Reader */
break; if (sptwb.DataBuf[6] & 0x01) i_drivetype |= CDIO_DRIVE_CD_R;
default: 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;
#else
i_drivetype = CDIO_DRIVE_CD_R; /* Writer */
#endif 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; return i_drivetype;
default: } else {
i_drivetype = CDIO_DRIVE_CD_R | CDIO_DRIVE_UNKNOWN;
}
return CDIO_DRIVE_ERROR; return CDIO_DRIVE_ERROR;
}
}
} }
#endif /*HAVE_WIN32_CDROM*/ #endif /*HAVE_WIN32_CDROM*/

View File

@@ -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 <rocky@panix.com> Copyright (C) 2003, 2004 Rocky Bernstein <rocky@panix.com>
@@ -26,7 +26,7 @@
# include "config.h" # include "config.h"
#endif #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 <cdio/cdio.h> #include <cdio/cdio.h>
#include <cdio/sector.h> #include <cdio/sector.h>
@@ -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. Initialize CD device.
*/ */
@@ -578,8 +596,7 @@ cdio_get_default_device_win32(void)
bool bool
cdio_is_device_win32(const char *source_name) cdio_is_device_win32(const char *source_name)
{ {
unsigned int len; unsigned int len = strlen(source_name);
len = strlen(source_name);
if (NULL == source_name) return false; if (NULL == source_name) return false;
@@ -620,6 +637,7 @@ cdio_open_win32 (const char *source_name)
.get_arg = _cdio_get_arg, .get_arg = _cdio_get_arg,
.get_default_device = cdio_get_default_device_win32, .get_default_device = cdio_get_default_device_win32,
.get_devices = cdio_get_devices_win32, .get_devices = cdio_get_devices_win32,
.get_drive_cap = _cdio_get_drive_cap,
.get_first_track_num= _cdio_get_first_track_num, .get_first_track_num= _cdio_get_first_track_num,
.get_mcn = _cdio_get_mcn, .get_mcn = _cdio_get_mcn,
.get_num_tracks = _cdio_get_num_tracks, .get_num_tracks = _cdio_get_num_tracks,

View File

@@ -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 <rocky@panix.com> Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>
@@ -83,6 +83,15 @@ bool win32ioctl_read_toc (_img_private_t *env);
char *win32ioctl_get_mcn (_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. Get the format (XA, DATA, AUDIO) of a track.
*/ */