From 0314a65a581598c78281bd42ae559046fbe5bc8d Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 1 May 2002 22:01:30 +0000 Subject: [PATCH] Implementation of IOCTL_SCSI_PASS_THROUGH and IOCTL_SCSI_PASS_THROUGH_DIRECT. --- configure | 2 + configure.ac | 1 + dlls/ntdll/cdrom.c | 183 ++++++++++++++++++++++++++++++++++++++++++++++++++++ include/config.h.in | 3 + include/ntddscsi.h | 89 +++++++++++++++++++++++++ 5 files changed, 278 insertions(+) create mode 100644 include/ntddscsi.h diff --git a/configure b/configure index 8339bea39c3..cdf3eb8930f 100755 --- a/configure +++ b/configure @@ -10466,6 +10466,7 @@ done + for ac_header in \ arpa/inet.h \ arpa/nameser.h \ @@ -10480,6 +10481,7 @@ for ac_header in \ linux/cdrom.h \ linux/input.h \ linux/joystick.h \ + linux/param.h \ linux/serial.h \ linux/ucdrom.h \ net/if.h \ diff --git a/configure.ac b/configure.ac index 91267fc7bc6..b36fb68e480 100644 --- a/configure.ac +++ b/configure.ac @@ -915,6 +915,7 @@ AC_CHECK_HEADERS(\ linux/cdrom.h \ linux/input.h \ linux/joystick.h \ + linux/param.h \ linux/serial.h \ linux/ucdrom.h \ net/if.h \ diff --git a/dlls/ntdll/cdrom.c b/dlls/ntdll/cdrom.c index 79137c9d6ee..63360c82367 100644 --- a/dlls/ntdll/cdrom.c +++ b/dlls/ntdll/cdrom.c @@ -31,10 +31,14 @@ #include "winioctl.h" #include "ntddstor.h" #include "ntddcdrm.h" +#include "ntddscsi.h" #include "drive.h" #include "file.h" #include "wine/debug.h" +#ifdef HAVE_LINUX_PARAM_H +# include +#endif #ifdef HAVE_LINUX_CDROM_H # include #endif @@ -830,6 +834,159 @@ static DWORD CDROM_RawRead(int dev, const RAW_READ_INFO* raw, void* buffer, DWOR } /****************************************************************** + * CDROM_ScsiPassThroughDirect + * + * + */ +static DWORD CDROM_ScsiPassThroughDirect(int dev, PSCSI_PASS_THROUGH_DIRECT pPacket) +{ + int ret = STATUS_NOT_SUPPORTED; +#if defined(linux) + struct cdrom_generic_command cmd; + struct request_sense sense; + int io; + + if (pPacket->Length < sizeof(SCSI_PASS_THROUGH_DIRECT)) + return STATUS_BUFFER_TOO_SMALL; + + if (pPacket->CdbLength > 12) + return STATUS_INVALID_PARAMETER; + + if (pPacket->SenseInfoLength > sizeof(sense)) + return STATUS_INVALID_PARAMETER; + + memset(&cmd, 0, sizeof(cmd)); + memset(&sense, 0, sizeof(sense)); + + memcpy(&(cmd.cmd), &(pPacket->Cdb), pPacket->CdbLength); + + cmd.buffer = pPacket->DataBuffer; + cmd.buflen = pPacket->DataTransferLength; + cmd.sense = &sense; + cmd.quiet = 0; + cmd.timeout = pPacket->TimeOutValue*HZ; + + switch (pPacket->DataIn) + { + case SCSI_IOCTL_DATA_OUT: + cmd.data_direction = CGC_DATA_WRITE; + break; + case SCSI_IOCTL_DATA_IN: + cmd.data_direction = CGC_DATA_READ; + break; + case SCSI_IOCTL_DATA_UNSPECIFIED: + cmd.data_direction = CGC_DATA_NONE; + break; + default: + return STATUS_INVALID_PARAMETER; + break; + } + + io = ioctl(dev, CDROM_SEND_PACKET, &cmd); + + if (pPacket->SenseInfoLength != 0) + { + memcpy((char*)pPacket + pPacket->SenseInfoOffset, + &sense, pPacket->SenseInfoLength); + } + + pPacket->ScsiStatus = cmd.stat; + + ret = CDROM_GetStatusCode(io); +#endif + return ret; +} + +/****************************************************************** + * CDROM_ScsiPassThrough + * + * + */ +static DWORD CDROM_ScsiPassThrough(int dev, PSCSI_PASS_THROUGH pPacket) +{ + int ret = STATUS_NOT_SUPPORTED; +#if defined(linux) + struct cdrom_generic_command cmd; + struct request_sense sense; + int io; + + if (pPacket->Length < sizeof(SCSI_PASS_THROUGH)) + return STATUS_BUFFER_TOO_SMALL; + + if (pPacket->CdbLength > 12) + return STATUS_INVALID_PARAMETER; + + if (pPacket->SenseInfoLength > sizeof(sense)) + return STATUS_INVALID_PARAMETER; + + memset(&cmd, 0, sizeof(cmd)); + memset(&sense, 0, sizeof(sense)); + + memcpy(&(cmd.cmd), &(pPacket->Cdb), pPacket->CdbLength); + + if ( pPacket->DataBufferOffset > 0x1000 ) + { + cmd.buffer = (void*)pPacket->DataBufferOffset; + } + else + { + cmd.buffer = ((void*)pPacket) + pPacket->DataBufferOffset; + } + cmd.buflen = pPacket->DataTransferLength; + cmd.sense = &sense; + cmd.quiet = 0; + cmd.timeout = pPacket->TimeOutValue*HZ; + + switch (pPacket->DataIn) + { + case SCSI_IOCTL_DATA_OUT: + cmd.data_direction = CGC_DATA_WRITE; + break; + case SCSI_IOCTL_DATA_IN: + cmd.data_direction = CGC_DATA_READ; + break; + case SCSI_IOCTL_DATA_UNSPECIFIED: + cmd.data_direction = CGC_DATA_NONE; + break; + default: + return STATUS_INVALID_PARAMETER; + break; + } + + io = ioctl(dev, CDROM_SEND_PACKET, &cmd); + + if (pPacket->SenseInfoLength != 0) + { + memcpy((char*)pPacket + pPacket->SenseInfoOffset, + &sense, pPacket->SenseInfoLength); + } + + pPacket->ScsiStatus = cmd.stat; + + ret = CDROM_GetStatusCode(io); +#endif + return ret; +} + +/****************************************************************** + * CDROM_ScsiGetAddress + * + * + */ +static DWORD CDROM_ScsiGetAddress(int dev, PSCSI_ADDRESS addr) +{ + FIXME("IOCTL_SCSI_GET_ADDRESS: stub\n"); + + addr->Length = sizeof(SCSI_ADDRESS); + addr->PortNumber = 0; + addr->PathId = 0; + addr->TargetId = 1; + addr->Lun = 0; + + return 0; +} + +/****************************************************************** * CDROM_DeviceIoControl * * @@ -892,6 +1049,12 @@ BOOL CDROM_DeviceIoControl(DWORD clientID, HANDLE hDevice, DWORD dwIoControlCode else error = CDROM_SetTray(dev, TRUE); break; + case IOCTL_CDROM_MEDIA_REMOVAL: + FIXME("IOCTL_CDROM_MEDIA_REMOVAL: stub\n"); + sz = 0; + error = 0; + break; + case IOCTL_DISK_MEDIA_REMOVAL: case IOCTL_STORAGE_MEDIA_REMOVAL: case IOCTL_STORAGE_EJECTION_CONTROL: @@ -1009,6 +1172,26 @@ BOOL CDROM_DeviceIoControl(DWORD clientID, HANDLE hDevice, DWORD dwIoControlCode else error = CDROM_RawRead(dev, (const RAW_READ_INFO*)lpInBuffer, lpOutBuffer, nOutBufferSize, &sz); break; + + case IOCTL_SCSI_PASS_THROUGH_DIRECT: + sz = sizeof(SCSI_PASS_THROUGH_DIRECT); + if (lpOutBuffer == NULL) error = STATUS_INVALID_PARAMETER; + else if (nOutBufferSize < sizeof(SCSI_PASS_THROUGH_DIRECT)) error = STATUS_BUFFER_TOO_SMALL; + else error = CDROM_ScsiPassThroughDirect(dev, (PSCSI_PASS_THROUGH_DIRECT)lpOutBuffer); + break; + case IOCTL_SCSI_PASS_THROUGH: + sz = sizeof(SCSI_PASS_THROUGH); + if (lpOutBuffer == NULL) error = STATUS_INVALID_PARAMETER; + else if (nOutBufferSize < sizeof(SCSI_PASS_THROUGH)) error = STATUS_BUFFER_TOO_SMALL; + else error = CDROM_ScsiPassThrough(dev, (PSCSI_PASS_THROUGH)lpOutBuffer); + break; + case IOCTL_SCSI_GET_ADDRESS: + sz = 0; + if (lpOutBuffer == NULL) error = STATUS_INVALID_PARAMETER; + else if (nOutBufferSize < sizeof(SCSI_ADDRESS)) error = STATUS_BUFFER_TOO_SMALL; + else error = CDROM_ScsiGetAddress(dev, (PSCSI_ADDRESS)lpOutBuffer); + break; + default: FIXME("Unsupported IOCTL %lx\n", dwIoControlCode); sz = 0; diff --git a/include/config.h.in b/include/config.h.in index 5f744ef9110..4da1bafea5e 100644 --- a/include/config.h.in +++ b/include/config.h.in @@ -248,6 +248,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_JOYSTICK_H +/* Define to 1 if you have the header file. */ +#undef HAVE_LINUX_PARAM_H + /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_SERIAL_H diff --git a/include/ntddscsi.h b/include/ntddscsi.h new file mode 100644 index 00000000000..01fd5fcce28 --- /dev/null +++ b/include/ntddscsi.h @@ -0,0 +1,89 @@ +/* + * DDK definitions for scsi media access + * + * Copyright (C) 2002 Laurent Pinchart + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _NTDDSCSI_H_ +#define _NTDDSCSI_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#define IOCTL_SCSI_BASE FILE_DEVICE_CONTROLLER + +#define IOCTL_SCSI_PASS_THROUGH CTL_CODE(IOCTL_SCSI_BASE, 0x0401, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) +#define IOCTL_SCSI_MINIPORT CTL_CODE(IOCTL_SCSI_BASE, 0x0402, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) +#define IOCTL_SCSI_GET_INQUIRY_DATA CTL_CODE(IOCTL_SCSI_BASE, 0x0403, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_SCSI_GET_CAPABILITIES CTL_CODE(IOCTL_SCSI_BASE, 0x0404, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_SCSI_PASS_THROUGH_DIRECT CTL_CODE(IOCTL_SCSI_BASE, 0x0405, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) +#define IOCTL_SCSI_GET_ADDRESS CTL_CODE(IOCTL_SCSI_BASE, 0x0406, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_SCSI_RESCAN_BUS CTL_CODE(IOCTL_SCSI_BASE, 0x0407, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_SCSI_GET_DUMP_POINTERS CTL_CODE(IOCTL_SCSI_BASE, 0x0408, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_SCSI_FREE_DUMP_POINTERS CTL_CODE(IOCTL_SCSI_BASE, 0x0409, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_IDE_PASS_THROUGH CTL_CODE(IOCTL_SCSI_BASE, 0x040a, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) + +#define SCSI_IOCTL_DATA_OUT 0 +#define SCSI_IOCTL_DATA_IN 1 +#define SCSI_IOCTL_DATA_UNSPECIFIED 2 + +typedef struct _SCSI_PASS_THROUGH { + USHORT Length; + UCHAR ScsiStatus; + UCHAR PathId; + UCHAR TargetId; + UCHAR Lun; + UCHAR CdbLength; + UCHAR SenseInfoLength; + UCHAR DataIn; + ULONG DataTransferLength; + ULONG TimeOutValue; + ULONG_PTR DataBufferOffset; + ULONG SenseInfoOffset; + UCHAR Cdb[16]; +} SCSI_PASS_THROUGH, *PSCSI_PASS_THROUGH; + +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; + +typedef struct _SCSI_ADDRESS { + ULONG Length; + UCHAR PortNumber; + UCHAR PathId; + UCHAR TargetId; + UCHAR Lun; +} SCSI_ADDRESS, *PSCSI_ADDRESS; + +#ifdef __cplusplus +} +#endif + +#endif /* _NTDDSCSI_H_ */ -- 2.11.4.GIT