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>
@@ -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 <cdio/cdio.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 <ddk/ntddstor.h>
#include <ddk/ntddscsi.h>
#include <ddk/scsi.h>
#include <stdio.h>
#include <stddef.h> /* offsetof() macro */
#include <sys/stat.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.
*/
#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];
SCSI_PASS_THROUGH_WITH_BUFFERS sptwb;
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,
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
IOCTL_SCSI_PASS_THROUGH,
&sptwb,
sizeof(SCSI_PASS_THROUGH),
&sptwb,
length,
&returned,
FALSE) )
{
/* 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:
} else {
i_drivetype = CDIO_DRIVE_CD_R | CDIO_DRIVE_UNKNOWN;
}
return CDIO_DRIVE_ERROR;
}
}
}
#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>
@@ -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 <cdio/cdio.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.
*/
@@ -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,

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>
@@ -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.
*/