IOCTL_SCSI_PASS_THROUGH IOCTL (ntddscsi.h)
允许应用程序将几乎任何 SCSI 命令发送到目标设备,但存在以下限制:
- 不允许使用多目标命令,例如 COPY。
- 不支持双向数据传输操作。
- 如果存在目标类型的设备的类驱动程序,则必须将请求发送到该类驱动程序。 因此,仅当连接到 LU 的设备类型没有类驱动程序时,应用程序才能将此请求直接发送到目标逻辑单元的系统端口驱动程序, (LU) 。 系统端口驱动程序不会检查确定设备是否已由类驱动程序在处理传递请求之前声明。 因此,如果应用程序绕过已声明设备的类驱动程序,并将该设备的直通请求直接发送到端口驱动程序,则类驱动程序和应用程序之间可能会发生设备控制冲突。 如果传递请求发送到适配器设备对象,并且它源自用户模式,并且面向类驱动程序声明的 LU,则 Storport 会使请求失败并STATUS_INVALID_DEVICE_REQUEST。 如果请求发送到 LU 设备对象、源自内核模式或面向无人认领的 LU,则会将其传递给微型端口驱动程序。
- 如果 CDB 可能需要基础微型端口驱动程序直接访问内存,则不能使用此请求。 如果调用方 CDB 可能需要直接访问内存,请改用 IOCTL_SCSI_PASS_THROUGH_DIRECT 。
- 应用程序不得尝试异步发送直通请求。 所有直通请求都必须是同步的。
- 应用程序不需要管理特权来向设备发送直通请求,但它们必须具有对设备的读/写访问权限。
IOCTL_SCSI_PASS_THROUGH 是缓冲的设备控制请求。 若要绕过系统内存中的缓冲,调用方应使用 IOCTL_SCSI_PASS_THROUGH_DIRECT。 处理 IOCTL_SCSI_PASS_THROUGH_DIRECT 请求时,系统会锁定用户内存中的缓冲区,设备直接访问此内存。
此请求通常用于传输 (<16K) 的少量数据。
应用程序可以通过 IRP_MJ_DEVICE_CONTROL 请求发送此请求。
存储类驱动程序将次要 IRP 编号设置为IRP_MN_SCSI_CLASS,以指示请求已由存储类驱动程序处理。
主要代码
输入缓冲区
此结构包括 SCSI CDB,调用方必须初始化该 CDB,但路径、目标 ID 和逻辑单元号除外, (LUN) (由端口驱动程序填充)。 对于数据输出命令,要传输的数据包含在 SCSI_PASS_THROUGH 结构中 DataBufferOffset 的 Irp-AssociatedIrp.SystemBuffer> 缓冲区中。 但是,如果调用方要求请求感知数据,则调用方必须在 SCSI_PASS_THROUGH之后立即分配额外的存储。
输入缓冲区长度
Parameters.DeviceIoControl.InputBufferLength 指示 Irp->AssociatedIrp.SystemBuffer 处缓冲区的大小(以字节为单位),该大小必须至少 ( (SCSI_PASS_THROUGH) ) 的感知数据大小 + 大小 。 SCSI_PASS_THROUGH结构的大小因 DataTransferLength 规范而异。输出缓冲区
端口驱动程序返回任何请求感知数据和从设备传输到 Irp-AssociatedIrp.SystemBuffer> 缓冲区的任何数据。
输出缓冲区长度
更新SCSI_PASS_THROUGH结构中的 SenseInfoLength 和 DataTransferLength 以指示传输的数据量。
状态块
“信息”字段设置为 Irp-AssociatedIrp.SystemBuffer> 的输出缓冲区中返回的字节数。 “ 状态” 字段设置为“STATUS_SUCCESS”,如果错误地设置SCSI_PASS_THROUGH中的输入 Length 值,则可能会 STATUS_BUFFER_TOO_SMALL或STATUS_INVALID_PARAMETER 。
要求
要求 | 值 |
---|---|
Header | ntddscsi.h (包括 Ntddscsi.h) |