应使用哪种类型的 DPC?

根据驱动程序的设计,它可以具有以下任何一项:

  • 单个 DpcForIsr 用于完成所有中断驱动的 I/O 操作

  • 一组一个或多个 CustomDpc 例程。

  • DpcForIsr 和一组特定于操作的 CustomDpc 例程

驱动程序是否具有单个 DpcForIsr 例程和/或一组 CustomDpc 例程,取决于其基础设备的性质以及它必须支持的 I/O 请求集。

大多数最低级别的设备驱动程序都有一个 DpcForIsr 例程,用于完成每个 IRP 的 I/O 处理,这些 IRP 需要在其各自的设备上执行一个或多个操作。 使用单个 DpcForIsr 在一次执行一个操作的设备上完成每个请求的中断驱动的 I/O 操作相对容易。 此类驱动程序的 ISR 只需为每个中断驱动的 I/O 操作调用 IoRequestDpc

除非其设备需要多个 DPC 来完成一组不同的中断驱动 I/O 操作,否则最低级别的驱动程序很少具有 CustomDpc 例程。

使用单个 DpcForIsr 在可以执行并发操作的设备上完成重叠的、中断驱动的 I/O 操作,但经过精心设计后可能比较困难。 除了或而不是排队 DpcForIsr 之外,ISR 还可以通过调用 KeInsertQueueDpc 将一组特定于操作、驱动程序提供的 CustomDpc 例程排队。

例如,请考虑编写串行驱动程序时涉及的一些设计难题。 作为全双工设备的驱动程序,串行驱动程序不能依赖于 IRP 排队到 StartIo 例程的顺序与多任务多处理器系统中设备中断序列之间的一对一对应关系。 此外,串行驱动程序必须处理超时请求和异步用户生成的请求,以取消以前请求的操作、清除缓冲的数据等。

因此,串行驱动程序可能会维护用户模式 COM 端口应用程序可以请求的读取、写入、清除和等待操作的内部队列。 它还可以为内部队列中的 IRP 维护引用计数或使用一些其他跟踪机制,例如一组标志。 其 ISR 将使用驱动程序分配和初始化的 DPC 对象中的任何一个调用 KeInsertQueueDpc ,每个对象都与驱动程序提供的 CustomDpc 例程相关联。