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 除外。 对于数据输出命令,要传输的数据必须位于适配器设备对齐缓冲区中。 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 中的输入 长度 值未正确设置或 dataInBuffer 中指定的缓冲区未正确对齐,则 状态 字段可能设置为STATUS_BUFFER_TOO_SMALLSTATUS_INVALID_PARAMETER

言论

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

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


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 请求,基础存储设备必须支持扩展的 SDB。 这意味着支持的 SRB 类型 SRB_TYPE_STORAGE_REQUEST_BLOCK。 应用程序可以使用 IOCTL_STORAGE_QUERY_PROPERTY 请求查询 SRB 支持,其查询类型 为 propertyStandardQuery,以及 StorageDeviceProperty的属性类型。 STORAGE_ADAPTER_DESCRIPTIOR 结构中返回的 SrbType 成员将指示 SRB_TYPE_SCSI_REQUEST_BLOCKSRB_TYPE_STORAGE_REQUEST_BLOCK

要求

要求 价值
标头 ntddscsi.h (包括 Ntddscsi.h)

另请参阅

IOCTL_SCSI_PASS_THROUGH_EX

IOCTL_STORAGE_QUERY_PROPERTY

SCSI_PASS_THROUGH_DIRECT_EX