在 Windows 中向 SCSI 设备发送特定的 SCSI 命令

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3316284/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 14:53:31  来源:igfitidea点击:

Sending a specific SCSI command to a SCSI device in Windows

windowswinapidevice-driverscsi

提问by Ganesh

Does windows have specific interface by which I can send a specific scsi command such Inquiry to scsi device ? I searched the net, found passing reference to SCSI Pass Through interface. But Its very Vague.

Windows 是否有特定的接口,我可以通过它向 scsi 设备发送特定的 scsi 命令,例如查询?我在网上搜索,找到了对 SCSI Pass Through 接口的传递引用。但它非常模糊。

Is there any documentation for that API on how to use it??

有没有关于如何使用该 API 的文档?

回答by Hardy Feng

#include <iostream>
#include <windows.h>
#include <winioctl.h>
#define ULONG_PTR ULONG
#include <ntddscsi.h> //from SDK
#include <spti.h>      //from DDK 
using namespace std;

int demo()
{
    HANDLE hDisk;
    SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER sptdwb; 
    ULONG length = 0;
    DWORD bytesReturn;
    BYTE bufDataRead[64*1024+10];
    int iRet;        

    hDisk = CreateFile(path,GENERIC_READ | GENERIC_WRITE,     
            FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,OPEN_EXISTING,0,NULL                                 
            );
    if (hDisk ==INVALID_HANDLE_VALUE)  {              
          return 0;
    }
    ZeroMemory(&sptdwb, sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER));
    sptdwb.sptd.Length = sizeof(SCSI_PASS_THROUGH_DIRECT);
    sptdwb.sptd.PathId = 0;
    sptdwb.sptd.TargetId = 1;
    sptdwb.sptd.Lun = 0;
    sptdwb.sptd.CdbLength = 6;
    sptdwb.sptd.DataIn = SCSI_IOCTL_DATA_IN;
    sptdwb.sptd.SenseInfoLength = 24;
    sptdwb.sptd.DataTransferLength = 8; 
    sptdwb.sptd.TimeOutValue = 2;
    sptdwb.sptd.DataBuffer = bufDataRead; 
    sptdwb.sptd.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER,ucSenseBuf);       
    sptdwb.sptd.Cdb[0] = 0x12;
    sptdwb.sptd.Cdb[1] = 0x00;
    sptdwb.sptd.Cdb[2] = 0x00;
    sptdwb.sptd.Cdb[3] = 0x00;
    sptdwb.sptd.Cdb[4] = 0xFF;
    sptdwb.sptd.Cdb[5] = 0x00;

    length = sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER);
    iRet = DeviceIoControl(hDisk,
            IOCTL_SCSI_PASS_THROUGH_DIRECT,
            &sptdwb,
            length,
            &sptdwb,
            length,
            &bytesReturn,
            NULL);
    if (0 == iRet)  {
        printf("inquiry fail");
        return 0;
    } else {
    //Check returned data in sptdwb.sptd.DataBuffer.
    }       
    return 0;

}

}

回答by J Evans

SCSI covers a vast amount of ground. Are you talking to a CD/DVD/Disk/Tape/Scanner or what.

SCSI 覆盖了大量的领域。你是在说 CD/DVD/磁盘/磁带/扫描仪还是什么。

For CD/DVD the best (and only) free reference for setup/read/write commands are to be found here: http://www.t10.org/drafts.htm

对于 CD/DVD,可以在此处找到有关设置/读/写命令的最佳(也是唯一)免费参考:http: //www.t10.org/drafts.htm

Re SPTI, there is some very basic documentation in the old 'Programmers guide to SCSI'. There is an article on an ASPI -> SPTI converter that can be found on the DDJ web site.

关于 SPTI,旧的“SCSI 程序员指南”中有一些非常基本的文档。DDJ 网站上有一篇关于 ASPI -> SPTI 转换器的文章。

Bear in mind that SPTI is simply an API, it imposes nor knows anything about SCSI message content or format.

请记住,SPTI 只是一个 API,它对 SCSI 消息内容或格式施加也不知道任何信息。

  • Brian Sawert, Addison Wesley 1998.
  • 布赖恩·索沃特,艾迪生·韦斯利,1998 年。

回答by Neno Ganchev

You can send SCSI commands to the SCSI Port driver by sending it an IRP_MJ_SCSI IRP, see http://msdn.microsoft.com/en-us/library/ff565387(VS.85).aspx. However, you will have to construct the SCSI CBD yourself, and I have yet to find a document which describes it.

您可以通过向 SCSI 端口驱动程序发送 IRP_MJ_SCSI IRP 来将 SCSI 命令发送到它,请参阅http://msdn.microsoft.com/en-us/library/ff565387(VS.85).aspx。但是,您必须自己构建 SCSI CBD,而且我还没有找到描述它的文档。

回答by Brett Henning

Anymore, the SCSI commands are broken down into a number of specs. The INQUIRY command is in the SPC spec, while device type specific commands are broken down into several specs (i.e. block, ses, ...).

此外,SCSI 命令被分解为许多规范。INQUIRY 命令在 SPC 规范中,而特定于设备类型的命令被分解为几个规范(即块、ses、...)。