首页新闻找找看学习计划

关于C++ 使用ASPI 向光驱发送SCSI命令遇到的问题

0
悬赏园豆:200 [已解决问题] 解决于 2013-08-09 08:25

先贴代码
这段代码是获取硬件类型为CDROM的硬件名称,

C/C++ code
 
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
BYTE __fastcall getDriveName( BYTE hostadapter, BYTE target, char* stringbuffer )
{
    SRB_ExecSCSICmd s;
    BYTE buf[100];
 
    memset( &s, 0, sizeof( s ) );
    memset( buf, 0, 100 );
 
    s.SRB_Cmd        = SC_EXEC_SCSI_CMD;
    s.SRB_HaId       = hostadapter;
    s.SRB_Target     = target;
    s.SRB_Lun        = 0;
    s.SRB_Flags      = SRB_DIR_IN | SRB_EVENT_NOTIFY;
    s.SRB_BufLen     = 100;
    s.SRB_BufPointer = buf;
    s.SRB_SenseLen   = SENSE_LEN;
    s.SRB_CDBLen     = 6;
 
    s.CDBByte[0]     = SCSI_INQUIRY;
    s.CDBByte[1]     = 0;
    s.CDBByte[2]     = 0;
    s.CDBByte[3]     = 0;
    s.CDBByte[4]     = 100;
    s.CDBByte[5]     = 0;
    BYTE byStatus = ExecSCSICommand(&s);   //ExecSCSICommand封装SendASPI32Command即为发送方法
 
 
    if( byStatus != SS_COMP )
    {
        //cout << "getDriveName returned status:" << LookupASPIStatus(byStatus).c_str()  << endl;
    }
 
 
    if( byStatus == SS_ERR && s.SRB_TargStat == STATUS_CHKCOND )
    {
        BYTE SenseKey = s.SenseArea[2] & (BYTE)15;
        BYTE ASC = s.SenseArea[12];
        BYTE ASCQ = s.SenseArea[13];
    }
 
    //if the command was successful
    if( byStatus == SS_COMP )
    {
        //extract the whole string identifying the drive
        forint i = 8; i < 36; i++ )
        {
            stringbuffer[i-8] = buf[i];
        }
        //the part I wish to extract is 28 characters long
        stringbuffer[28] = NULL;
    }
 
    return byStatus;
}




再看下面的代码,这段代码是获取类型为CDROM硬件的转速

C/C++ code?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
int __fastcall getCDSpeed(BYTE hostadapter, BYTE target)
{
    SRB_ExecSCSICmd s;
    unsigned char b[256];
 
    memset( &s, 0, sizeof( s ) );
    memset( b, 0xFF, 256 );
 
    s.SRB_Cmd      = SC_EXEC_SCSI_CMD;
    s.SRB_HaId     = hostadapter;
    s.SRB_Target   = target;
    s.SRB_Lun      = 0;
    s.SRB_Flags    = SRB_DIR_IN | SRB_EVENT_NOTIFY;
    s.SRB_BufLen   = 256;
    s.SRB_BufPointer = b;
    s.SRB_CDBLen   = 12;
    s.CDBByte[0]   = SCSI_MODESENSE;
    s.CDBByte[2]   = 0x2A;    //mode page 0x2A contains the speed
    s.CDBByte[7]   = 0x01;
    s.CDBByte[8]   = 0x00;
 
    BYTE byStatus = ExecSCSICommand(&s);
 
    if( byStatus == SS_COMP )
    {
 
    }
 
    if( byStatus == SS_ERR && s.SRB_TargStat == STATUS_CHKCOND )
    {
        BYTE SenseKey = s.SenseArea[2] & (BYTE)15;
        BYTE ASC = s.SenseArea[12];
        BYTE ASCQ = s.SenseArea[13];
    }
    //speed is stored in bytes 22 & 23 of mode page 0x2A
    return (int)((b[22] << 8) + b[23]);
}



问题请教:
1.向硬件发送的SRB_ExecSCSICmd这个结构体里的CDBByte Byte数组到底是怎样设置的,通过上面两段代码可以看到,获取硬件不同属性就是通过设置这个数组来获取的,
获取硬件名称这样设置的,

C/C++ code?
1
2
3
4
5
    s.CDBByte[0]     = SCSI_INQUIRY;
    s.CDBByte[1]     = 0;
    s.CDBByte[2]     = 0;
    s.CDBByte[3]     = 0;
    s.CDBByte[4]     = 100;


获取硬件转速,这样设置的

C/C++ code?
1
2
3
4
    s.CDBByte[0]   = SCSI_MODESENSE;
    s.CDBByte[2]   = 0x2A;    //mode page 0x2A contains the speed
    s.CDBByte[7]   = 0x01;
    s.CDBByte[8]   = 0x00;



我现在就是不明白这些参数为什么要这样设置,有什么标准文档吗,赐教。

zbyhi的主页 zbyhi | 初学一级 | 园豆:4
提问于:2013-07-19 16:39
< >
分享
最佳答案
0

CBD数组表示一个SCSI命令,第一个字节是命令,后面都是参数,参数就是一个数据块,根据命令的需要设置。

google 一下吧。

收获园豆:200
天边彩云 | 小虾三级 |园豆:629 | 2013-07-19 17:10

查了一些资料没大明白,所以才上论坛上来发帖来着。

zbyhi | 园豆:4 (初学一级) | 2013-07-19 17:14

@zbyhi: SCSI命令都是公开的标准,每个命令和每个命令的参数都有哪些设置应该有详细文档说明的。

google SCSI command ,第二个结果就是希捷提供的SCSI命令手册,非常详细。

天边彩云 | 园豆:629 (小虾三级) | 2013-07-19 17:18
其他回答(1)
0

复杂的问题,

SOUTHER | 园豆:825 (小虾三级) | 2013-07-28 22:07
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册