IOCTL_SCSI_PASS_THROUGH_DIRECT_EX IOCTL (ntddscsi.h)

IOCTL_SCSI_PASS_THROUGH_DIRECT_EX控制代码请求是IOCTL_SCSI_PASS_THROUGH_DIRECT请求的扩展版本。 此请求支持双向数据传输,并允许命令数据块 (CDB) > 16 字节。

允许应用程序将几乎任何 SCSI 命令发送到目标设备,但存在以下限制:

  • 不允许使用多目标命令,例如 COPY。
  • 如果存在目标类型的设备的类驱动程序,则必须将请求发送到该类驱动程序。 因此,仅当连接到该 LU 的设备类型没有类驱动程序时,应用程序才能将此请求直接发送到目标逻辑单元的系统端口驱动程序。
  • 如果输入 CDB 可能需要基础微型端口驱动程序直接访问内存, 则必须 发出此请求。
调用应用程序创建 SCSI 命令描述符块,如果出现 CHECK CONDITION,该块可以包含对请求感知数据的请求。 如果 CDB 请求数据传输操作,调用方必须设置适配器设备对齐的缓冲区,微型端口驱动程序可以直接从该缓冲区或缓冲区中传输数据。 此请求通常用于传输 (>16K) 的较大数据量。

应用程序可以通过 IRP_MJ_DEVICE_CONTROL 请求发送此请求。

存储类驱动程序将次要 IRP 编号设置为IRP_MN_SCSI_CLASS,以指示请求已由存储类驱动程序处理。

注意 SCSI 端口驱动程序和 SCSI 微型端口驱动程序模型将来可能会更改或不可用。 相反,我们建议使用 Storport 驱动程序Storport 微型端口 驱动程序模型。
 

主要代码

IRP_MJ_DEVICE_CONTROL

输入缓冲区

Parameters.DeviceIoControl.InputBufferLength 指示 Irp->AssociatedIrp.SystemBuffer 处缓冲区的大小(以字节为单位),该大小必须至少 ( (SCSI_PASS_THROUGH_DIRECT_EX) ) 的感知数据大小 + 大小SCSI_PASS_THROUGH_DIRECT_EX结构的大小是固定的。

此结构包括 SCSI CDB,调用方必须初始化该 CDB,但路径、目标 ID 和 LUN 除外,这些路径、目标 ID 和 LUN 由端口驱动程序填充。 对于数据输出命令,要传输的数据必须位于适配器设备对齐的缓冲区中。 SCSI_PASS_THROUGH_DIRECT_EXDataInBuffer 成员是指向此适配器设备对齐缓冲区的指针。 如果调用方请求请求感知数据,则调用方必须按照 SCSI_PASS_THROUGH_DIRECT_EX 结构分配额外的存储。

输入缓冲区长度

Parameters.DeviceIoControl.InputBufferLength 指示 Irp->AssociatedIrp.SystemBuffer 处缓冲区的大小(以字节为单位),该大小必须至少 ( (SCSI_PASS_THROUGH_DIRECT_EX) ) 的感知数据大小 + 大小SCSI_PASS_THROUGH_DIRECT_EX结构的大小是固定的。

输出缓冲区

端口驱动程序将任何请求感知数据和SCSI_PASS_THROUGH_DIRECT_EX结构返回到 Irp-AssociatedIrp.SystemBuffer> 处的缓冲区。

输出缓冲区长度

SenseInfoLengthDataOutTransferLength 将更新,以指示传输的数据量。 端口驱动程序会将从设备传输的任何数据返回到 DataOutBuffer 提供的缓存对齐缓冲区。

状态块

信息”字段设置为 Irp-AssociatedIrp.SystemBuffer> 的输出缓冲区中返回的字节数。 状态”字段设置为“STATUS_SUCCESS”,或者如果错误地设置“SCSI_PASS_THROUGH_DIRECT_EX”中的输入 Length 值,或者 DataInBuffer 中指定的缓冲区未正确对齐设备,则“状态”字段可能设置为STATUS_BUFFER_TOO_SMALL或STATUS_INVALID_PARAMETER。

注解

对于数据传输操作,需要一个与适配器设备匹配的对齐方式的缓冲区。 应用程序可以通过发出查询类型为 PropertyStandardQuery 且属性 ID 为 StorageAdapterPropertyIOCTL_STORAGE_QUERY_PROPERTY控制代码请求来检索设备对齐掩码。 对齐掩码位于返回的 STORAGE_ADAPTER_DESCRIPTOR 结构的 AlignmentMask 成员中。 驱动程序还可以使用适配器的 DeviceObjectAlignmentMask 成员中的值。

在以下示例函数中,缓冲区准备为设备对齐的数据传输缓冲区。


PVOID AllocateAlignedBuffer(ULONG size, ULONG AlignmentMask, PVOID *pUnAlignedBuffer)
{
    PVOID AlignedBuffer;
    ULONG_PTR FullWordMask = (ULONG_PTR)AlignmentMask;

    if (AlignmentMask == 0)
    {
        AlignedBuffer = malloc(size);
        // return the original buffer to free later
        *pUnAlignedBuffer = AlignedBuffer;
    }
    else
    {
        // expand the size for the alignment window
        size += AlignmentMask;
        AlignedBuffer = malloc(size);
        // return the original buffer to free later
        *pUnAlignedBuffer = AlignedBuffer;
        // adjust buffer pointer for the desired alignment
        AlignedBuffer = (PVOID)(((ULONG_PTR)AlignedBuffer + FullWordMask) & ~FullWordMask);
    }

    return AlignedBuffer;
}

为了发出 IOCTL_SCSI_PASS_THROUGH_DIRECT_EX 请求,基础存储设备必须支持扩展 SRB。 这意味着支持的 SRB 类型 SRB_TYPE_STORAGE_REQUEST_BLOCK。 应用程序可以使用查询类型为 PropertyStandardQueryStorageDevicePropertyIOCTL_STORAGE_QUERY_PROPERTY 请求查询 SRB 支持。 STORAGE_ADAPTER_DESCRIPTIOR 结构中返回的 SrbType 成员将指示SRB_TYPE_SCSI_REQUEST_BLOCKSRB_TYPE_STORAGE_REQUEST_BLOCK

要求

要求
Header ntddscsi.h (包括 Ntddscsi.h)

另请参阅

IOCTL_SCSI_PASS_THROUGH_EX

IOCTL_STORAGE_QUERY_PROPERTY

SCSI_PASS_THROUGH_DIRECT_EX