IOCTL_SCSI_PASS_THROUGH_DIRECT IOCTL (ntddscsi.h)

允许应用程序将几乎任何 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

输入缓冲区

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

输入缓冲区长度

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

输出缓冲区

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

输出缓冲区长度

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

状态块

信息”字段设置为 Irp-AssociatedIrp.SystemBuffer> 的输出缓冲区中返回的字节数。 “状态”字段设置为“STATUS_SUCCESS”,如果SCSI_PASS_THROUGH_DIRECT”中的输入 Length 值设置不正确,或者 DataBuffer 中指定的缓冲区未正确对齐设备,则“状态”字段可能设置为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;
}

要求

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

另请参阅

IOCTL_SCSI_PASS_THROUGH

IOCTL_STORAGE_QUERY_PROPERTY

SCSI_PASS_THROUGH_DIRECT