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 可能需要基础微型端口驱动程序直接访问内存, 则必须 发出此请求。
应用程序可以通过 IRP_MJ_DEVICE_CONTROL 请求发送此请求。
存储类驱动程序将次要 IRP 编号设置为IRP_MN_SCSI_CLASS,以指示请求已由存储类驱动程序处理。
主要代码
输入缓冲区
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_EX 的 DataInBuffer 成员是指向此适配器设备对齐缓冲区的指针。 如果调用方请求请求感知数据,则调用方必须按照 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> 处的缓冲区。
输出缓冲区长度
SenseInfoLength 和 DataOutTransferLength 将更新,以指示传输的数据量。 端口驱动程序会将从设备传输的任何数据返回到 DataOutBuffer 提供的缓存对齐缓冲区。
状态块
“信息”字段设置为 Irp-AssociatedIrp.SystemBuffer> 的输出缓冲区中返回的字节数。 “状态”字段设置为“STATUS_SUCCESS”,或者如果错误地设置“SCSI_PASS_THROUGH_DIRECT_EX”中的输入 Length 值,或者 DataInBuffer 中指定的缓冲区未正确对齐设备,则“状态”字段可能设置为STATUS_BUFFER_TOO_SMALL或STATUS_INVALID_PARAMETER。
注解
对于数据传输操作,需要一个与适配器设备匹配的对齐方式的缓冲区。 应用程序可以通过发出查询类型为 PropertyStandardQuery 且属性 ID 为 StorageAdapterProperty 的IOCTL_STORAGE_QUERY_PROPERTY控制代码请求来检索设备对齐掩码。 对齐掩码位于返回的 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 请求,基础存储设备必须支持扩展 SRB。 这意味着支持的 SRB 类型 SRB_TYPE_STORAGE_REQUEST_BLOCK。 应用程序可以使用查询类型为 PropertyStandardQuery 和 StorageDeviceProperty 的 IOCTL_STORAGE_QUERY_PROPERTY 请求查询 SRB 支持。 STORAGE_ADAPTER_DESCRIPTIOR 结构中返回的 SrbType 成员将指示SRB_TYPE_SCSI_REQUEST_BLOCK或SRB_TYPE_STORAGE_REQUEST_BLOCK。
要求
要求 | 值 |
---|---|
Header | ntddscsi.h (包括 Ntddscsi.h) |
另请参阅
反馈
https://aka.ms/ContentUserFeedback。
即将推出:在整个 2024 年,我们将逐步取消以“GitHub 问题”作为内容的反馈机制,并将其替换为新的反馈系统。 有关详细信息,请参阅:提交和查看相关反馈