MS Windows driver hacking hopefully to get closer to passing back sense data.
For now it seems that some pass-through direct doesn't work while the less-good passthrough does. Sigh.
This commit is contained in:
@@ -1,6 +1,4 @@
|
|||||||
/*
|
/*
|
||||||
$Id: win32_ioctl.c,v 1.30 2008/04/21 18:30:21 karl Exp $
|
|
||||||
|
|
||||||
Copyright (C) 2004, 2005, 2008, 2010 Rocky Bernstein <rocky@gnu.org>
|
Copyright (C) 2004, 2005, 2008, 2010 Rocky Bernstein <rocky@gnu.org>
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
@@ -92,10 +90,19 @@ typedef struct _CDROM_TOC_FULL {
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
SCSI_PASS_THROUGH_DIRECT sptd;
|
SCSI_PASS_THROUGH_DIRECT sptd;
|
||||||
ULONG Filler;
|
ULONG Filler; /* Realign buffer to double-word boundary */
|
||||||
UCHAR ucSenseBuf[32];
|
UCHAR ucSenseBuf[32];
|
||||||
|
UCHAR DataBuf[512];
|
||||||
} SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER;
|
} SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER;
|
||||||
|
|
||||||
|
typedef struct _SCSI_PASS_THROUGH_WITH_BUFFER {
|
||||||
|
SCSI_PASS_THROUGH Spt;
|
||||||
|
ULONG Filler; /* realign buffer to double-word boundary */
|
||||||
|
UCHAR SenseBuf[32];
|
||||||
|
UCHAR DataBuf[512];
|
||||||
|
} SCSI_PASS_THROUGH_WITH_BUFFER;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "win32.h"
|
#include "win32.h"
|
||||||
|
|
||||||
@@ -478,6 +485,7 @@ set_scsi_tuple_win32ioctl(_img_private_t *env)
|
|||||||
|
|
||||||
Return 0 if command completed successfully.
|
Return 0 if command completed successfully.
|
||||||
*/
|
*/
|
||||||
|
#if 0
|
||||||
int
|
int
|
||||||
run_mmc_cmd_win32ioctl( void *p_user_data,
|
run_mmc_cmd_win32ioctl( void *p_user_data,
|
||||||
unsigned int i_timeout_ms,
|
unsigned int i_timeout_ms,
|
||||||
@@ -489,6 +497,7 @@ run_mmc_cmd_win32ioctl( void *p_user_data,
|
|||||||
SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER sptdwb;
|
SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER sptdwb;
|
||||||
|
|
||||||
bool b_success;
|
bool b_success;
|
||||||
|
unsigned long length = 0;
|
||||||
DWORD dw_bytes_returned;
|
DWORD dw_bytes_returned;
|
||||||
|
|
||||||
memset(&sptdwb, 0, sizeof(sptdwb));
|
memset(&sptdwb, 0, sizeof(sptdwb));
|
||||||
@@ -506,19 +515,28 @@ run_mmc_cmd_win32ioctl( void *p_user_data,
|
|||||||
SCSI_IOCTL_DATA_UNSPECIFIED;
|
SCSI_IOCTL_DATA_UNSPECIFIED;
|
||||||
sptdwb.sptd.DataTransferLength= i_buf;
|
sptdwb.sptd.DataTransferLength= i_buf;
|
||||||
sptdwb.sptd.TimeOutValue = msecs2secs(i_timeout_ms);
|
sptdwb.sptd.TimeOutValue = msecs2secs(i_timeout_ms);
|
||||||
|
|
||||||
sptdwb.sptd.DataBuffer = (void *) p_buf;
|
sptdwb.sptd.DataBuffer = (void *) p_buf;
|
||||||
|
/*
|
||||||
sptdwb.sptd.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER,
|
sptdwb.sptd.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER,
|
||||||
ucSenseBuf);
|
ucSenseBuf);
|
||||||
|
*/
|
||||||
|
sptdwb.sptd.SenseInfoOffset = 0;
|
||||||
|
|
||||||
memcpy(sptdwb.sptd.Cdb, p_cdb, i_cdb);
|
memcpy(sptdwb.sptd.Cdb, p_cdb, i_cdb);
|
||||||
|
length = offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER,DataBuf) +
|
||||||
|
sptdwb.sptd.DataTransferLength;
|
||||||
|
|
||||||
/* Send the command to drive */
|
/* Send the command to drive */
|
||||||
b_success = DeviceIoControl(p_env->h_device_handle,
|
b_success = DeviceIoControl(p_env->h_device_handle,
|
||||||
IOCTL_SCSI_PASS_THROUGH_DIRECT,
|
IOCTL_SCSI_PASS_THROUGH,
|
||||||
(void *)&sptdwb,
|
(void *)&sptdwb,
|
||||||
(DWORD)sizeof(sptdwb),
|
sizeof(SCSI_PASS_THROUGH),
|
||||||
|
NULL, 0,
|
||||||
|
/*
|
||||||
&sptdwb,
|
&sptdwb,
|
||||||
(DWORD)sizeof(sptdwb),
|
length,
|
||||||
|
*/
|
||||||
&dw_bytes_returned,
|
&dw_bytes_returned,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
@@ -548,6 +566,89 @@ run_mmc_cmd_win32ioctl( void *p_user_data,
|
|||||||
|
|
||||||
return DRIVER_OP_SUCCESS;
|
return DRIVER_OP_SUCCESS;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
int
|
||||||
|
run_mmc_cmd_win32ioctl( void *p_user_data,
|
||||||
|
unsigned int i_timeout_ms,
|
||||||
|
unsigned int i_cdb, const mmc_cdb_t * p_cdb,
|
||||||
|
cdio_mmc_direction_t e_direction,
|
||||||
|
unsigned int i_buf, /*in/out*/ void *p_buf )
|
||||||
|
{
|
||||||
|
_img_private_t *p_env = p_user_data;
|
||||||
|
SCSI_PASS_THROUGH_WITH_BUFFER sptwb;
|
||||||
|
|
||||||
|
bool b_success;
|
||||||
|
unsigned long length = 0;
|
||||||
|
DWORD dw_bytes_returned;
|
||||||
|
|
||||||
|
memset(&sptwb, 0, sizeof(sptwb));
|
||||||
|
|
||||||
|
sptwb.Spt.Length = sizeof(sptwb.Spt);
|
||||||
|
sptwb.Spt.PathId = 0; /* SCSI card ID will be filled in
|
||||||
|
automatically */
|
||||||
|
sptwb.Spt.TargetId= 0; /* SCSI target ID will also be filled in */
|
||||||
|
sptwb.Spt.Lun = 0; /* SCSI lun ID will also be filled in */
|
||||||
|
sptwb.Spt.CdbLength = i_cdb;
|
||||||
|
sptwb.Spt.SenseInfoLength = sizeof(sptwb.SenseBuf);
|
||||||
|
sptwb.Spt.DataIn =
|
||||||
|
(SCSI_MMC_DATA_READ == e_direction) ? SCSI_IOCTL_DATA_IN :
|
||||||
|
(SCSI_MMC_DATA_WRITE == e_direction) ? SCSI_IOCTL_DATA_OUT :
|
||||||
|
SCSI_IOCTL_DATA_UNSPECIFIED;
|
||||||
|
|
||||||
|
if (SCSI_MMC_DATA_WRITE == e_direction) memcpy(&sptwb.DataBuf, p_buf, i_buf);
|
||||||
|
|
||||||
|
sptwb.Spt.DataTransferLength= i_buf;
|
||||||
|
sptwb.Spt.TimeOutValue = msecs2secs(i_timeout_ms);
|
||||||
|
|
||||||
|
sptwb.Spt.DataBufferOffset =
|
||||||
|
offsetof(SCSI_PASS_THROUGH_WITH_BUFFER,DataBuf);
|
||||||
|
sptwb.Spt.SenseInfoOffset =
|
||||||
|
offsetof(SCSI_PASS_THROUGH_WITH_BUFFER, SenseBuf);
|
||||||
|
|
||||||
|
memcpy(sptwb.Spt.Cdb, p_cdb, i_cdb);
|
||||||
|
sptwb.Spt.Cdb[4] = i_buf;
|
||||||
|
length = offsetof(SCSI_PASS_THROUGH_WITH_BUFFER,DataBuf) +
|
||||||
|
sptwb.Spt.DataTransferLength;
|
||||||
|
|
||||||
|
/* Send the command to drive */
|
||||||
|
b_success = DeviceIoControl(p_env->h_device_handle,
|
||||||
|
IOCTL_SCSI_PASS_THROUGH,
|
||||||
|
(void *)&sptwb,
|
||||||
|
sizeof(SCSI_PASS_THROUGH),
|
||||||
|
&sptwb,
|
||||||
|
length,
|
||||||
|
&dw_bytes_returned,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if ( !b_success ) {
|
||||||
|
char *psz_msg = NULL;
|
||||||
|
long int i_err = GetLastError();
|
||||||
|
FORMAT_ERROR(i_err, psz_msg);
|
||||||
|
if (psz_msg)
|
||||||
|
cdio_info("Error: %s", psz_msg);
|
||||||
|
else
|
||||||
|
cdio_info("Error: %ld", i_err);
|
||||||
|
LocalFree(psz_msg);
|
||||||
|
return DRIVER_OP_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(p_buf, &sptwb.DataBuf, i_buf);
|
||||||
|
|
||||||
|
/* Record SCSI sense reply for API call mmc_last_cmd_sense().
|
||||||
|
*/
|
||||||
|
if (sptwb.SenseBuf[7]) {
|
||||||
|
int sense_size = sptwb.SenseBuf[7] + 8; /* SPC 4.5.3, Table 26:
|
||||||
|
252 bytes legal, 263 bytes
|
||||||
|
possible */
|
||||||
|
if (sense_size > sizeof(sptwb.SenseBuf))
|
||||||
|
sense_size = sizeof(sptwb.SenseBuf);
|
||||||
|
memcpy((void *) p_env->gen.scsi_mmc_sense, &sptwb.SenseBuf, sense_size);
|
||||||
|
p_env->gen.scsi_mmc_sense_valid = sense_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
return DRIVER_OP_SUCCESS;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Get disc type associated with cd object.
|
Get disc type associated with cd object.
|
||||||
@@ -1112,7 +1213,7 @@ get_mcn_win32ioctl (const _img_private_t *p_env) {
|
|||||||
&dw_bytes_returned, NULL ) ) {
|
&dw_bytes_returned, NULL ) ) {
|
||||||
cdio_warn( "could not read Q Channel at track %d", 1);
|
cdio_warn( "could not read Q Channel at track %d", 1);
|
||||||
} else if (mcn.Mcval)
|
} else if (mcn.Mcval)
|
||||||
return strdup(mcn.MediaCatalog);
|
return strdup((const char *) mcn.MediaCatalog);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* -*- C -*-
|
/* -*- C -*-
|
||||||
Copyright (C) 2009 Thomas Schmitt <scdbackup@gmx.net>
|
Copyright (C) 2009 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
Copyright (C) 20010 Rocky Bernstein <rocky@gnu.org>
|
Copyright (C) 2010 Rocky Bernstein <rocky@gnu.org>
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -629,19 +629,19 @@ tmmc_test(char *drive_path, int flag)
|
|||||||
sense_avail);
|
sense_avail);
|
||||||
{ret = 2; goto ex;}
|
{ret = 2; goto ex;}
|
||||||
}
|
}
|
||||||
/* Provoke sense reply by requesting inappropriate mode page 3Eh */
|
/* Cause sense reply failure by requesting inappropriate mode page 3Eh */
|
||||||
ret = tmmc_mode_sense(p_cdio, &sense_avail, sense,
|
ret = tmmc_mode_sense(p_cdio, &sense_avail, sense,
|
||||||
0x3e, 0, alloc_len, buf, &buf_fill, !!verbose);
|
0x3e, 0, alloc_len, buf, &buf_fill, !!verbose);
|
||||||
if (ret != 0 && sense_avail < 18) {
|
if (ret != 0 && sense_avail < 18) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Error: Deliberately illegal command yields only %d sense bytes. Expected >= 18.\n",
|
"Error: An illegal command yields only %d sense bytes. Expected >= 18.\n",
|
||||||
sense_avail);
|
sense_avail);
|
||||||
{ret = 2; goto ex;}
|
{ret = 2; goto ex;}
|
||||||
} else if(ret == 0) {
|
} else if(ret == 0) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Warning: tmmc_mode_sense() cannot provoke failure by mode page 3Eh\n");
|
"Warning: tmmc_mode_sense() cannot cause a failure via mode page 3Eh\n");
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Hint: Consider to set in tmmc_test(): with_tray_dance = 1\n");
|
"Consider to set in tmmc_test(): with_tray_dance = 1\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Test availability of sense reply in case of unready drive.
|
/* Test availability of sense reply in case of unready drive.
|
||||||
@@ -665,9 +665,9 @@ tmmc_test(char *drive_path, int flag)
|
|||||||
{ret = 2; goto ex;}
|
{ret = 2; goto ex;}
|
||||||
} else if(ret == 0) {
|
} else if(ret == 0) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Warning: tmmc_mode_sense() cannot provoke failure by mode page 3Eh\n");
|
"Warning: tmmc_mode_sense() cannot cause failure via mode page 3Eh\n");
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Hint: Consider to set in tmmc_test(): with_tray_dance = 1\n");
|
"Consider to set in tmmc_test(): with_tray_dance = 1\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user