使用缓冲 I/O 执行 DispatchReadWrite
为缓冲 I/O 设置设备对象的任何最低级别设备驱动程序,通过将从设备传输的数据返回到 Irp-AssociatedIrp.SystemBuffer> 处锁定的系统空间缓冲区,来满足读取请求。 它通过将数据从同一缓冲区传出到其设备来满足写入请求。
因此,此类设备驱动程序的 DispatchReadWrite 例程通常在收到转移请求时执行以下操作:
调用 IoGetCurrentIrpStackLocation 并确定传输请求的方向。
检查请求的参数的有效性。
对于读取请求,例程通常会检查驱动程序的 IoStackLocation-Parameters.Read.Length> 值,以确定缓冲区是否足够大,可以接收从设备传输的数据。
例如,系统键盘类驱动程序处理仅来自 Win32 用户输入线程的读取请求。 此驱动程序定义一个结构,KEYBOARD_INPUT_DATA,用于存储来自设备的击键,并在任何给定时刻将其中一些结构保存在内部环形缓冲区中,以满足传入的读取请求。
对于写入请求,例程通常检查 Parameters.Write.Length 处的值,并在必要时检查 Irp-AssociatedIrp.SystemBuffer> 中的数据是否有效:也就是说,如果其设备仅接受包含具有定义值范围的成员的结构化数据包。
如果任何参数无效, DispatchReadWrite 例程会立即完成 IRP,如 完成 IRP 中所述。 否则,该例程会传递 IRP,以供其他驱动程序例程进一步处理,如在 驱动程序堆栈中传递 IRP 中所述。
使用缓冲 I/O 的最低级别设备驱动程序通常必须通过读取或写入请求发起方指定的大小的数据来满足传输请求。 此类驱动程序可能会为传入或发送到其设备的数据定义结构,并且可能会像系统键盘类驱动程序那样在内部缓冲结构化数据。
内部缓冲数据的驱动程序应支持 IRP_MJ_FLUSH_BUFFERS 请求,还可以支持 IRP_MJ_SHUTDOWN 请求。
链中的最高级别驱动程序通常负责在将读/写请求传递给较低级别的驱动程序之前检查输入 IRP 的参数。 因此,许多较低级别的驱动程序可以假定其在读/写 IRP 中的 I/O 堆栈位置具有有效的参数。 如果链中最低级别的驱动程序知道设备对数据传输的约束,则需要该驱动程序检查其 I/O 堆栈位置中参数的有效性。