注册 IoCompletion 例程
为了注册 IoCompletion 例程,调度例程调用 IoSetCompletionRoutine,提供 IoCompletion 例程的地址以及随后将使用 IoCallDriver 传递给较低级驱动程序的 IRP。
调用 IoSetCompletionRoutine 时,调度例程指定 I/O 管理器应调用指定的 IoCompletion 例程的情况。 如果较低级别的驱动程序成功完成 IRP (InvokeOnSuccess) 、以错误状态值 (InvokeOnError) 完成 IRP,或者取消 IRP (InvokeOnCancel) ,则可以选择调用 IoCompletion 例程。
IoCompletion 例程的目的是监视较低级别的驱动程序对 IRP 执行的操作,并在必要时执行其他完成处理。 具体而言,驱动程序的 IoCompletion 例程的最常见用途如下:
释放驱动程序使用 IoAllocateIrp 或 IoBuildAsynchronousFsdRequest 分配的 IRP
使用这些支持例程之一分配 IRP 的任何更高级别的驱动程序都必须为该 IRP 提供 IoCompletion 例程。 IoCompletion 例程必须调用 IoFreeIrp 来释放驱动程序分配的 IRP。
重复使用传入的 IRP 以请求较低的驱动程序完成一些操作,例如部分传输,直到 IoCompletion 例程满足并完成原始请求
重试低级驱动程序已完成但出现错误的请求
与中间驱动程序相比,最高级别驱动程序(如文件系统)更有可能具有尝试重试请求的 IoCompletion 例程,但可能位于紧密耦合的端口驱动程序之上的类驱动程序除外。 但是,任何中间驱动程序都使用 IoCompletion 例程重试请求。
虽然最高级别或中间驱动程序的 DispatchReadWrite 例程最有可能处理需要 IoCompletion 例程的 IRP,但任何驱动程序中将 IRP 传递给较低级别的驱动程序中的任何调度例程都可以注册 IoCompletion 例程。
对于驱动程序分配的 IRP 和重用的 IRP,调度例程必须使用以下布尔参数调用 IoSetCompletionRoutine :
InvokeOnSuccess 设置为 TRUE
InvokeOnError 设置为 TRUE
如果链中的任何较低驱动程序可能处理可取消的 IRP,则 InvokeOnCancel 设置为 TRUE
通常,无论是否使用STATUS_CANCELLED返回 IRP, InvokeOnCancel 都设置为 TRUE,以确保 IoCompletion 例程释放每个驱动程序分配的 IRP 或检查每次重用 IRP 的完成状态。
使用 IoAllocateIrp 或 IoBuildAsynchronousFsdRequest为较低级别的驱动程序分配 IRP 的调度例程必须为每个驱动程序分配的 IRP 设置 IoCompletion 例程。
调度例程必须设置有关原始 IRP 及其分配的 IRP () 的状态,以便 IoCompletion 例程使用。 IoCompletion 例程至少需要访问原始 IRP 以及分配了多少个额外 IRP。
调度例程应调用 IoSetCompletionRoutine ,并为其分配的 IRP () 的所有 InvokeOnXxx 参数设置为 TRUE 。
对一系列操作重用 IRP 或重试 I/O 操作的调度例程必须为将重复使用或重试的每个 IRP 调用 IoSetCompletionRoutine 。
调度例程必须保存原始 IRP 的状态信息,以供 IoCompletion 例程后续使用。
例如, DispatchReadWrite 例程必须先保存 IoCompletion 例程的输入 IRP 的相关传输参数,然后才能为该 IRP 中下一个较低级别的驱动程序设置部分传输。 如果 DispatchReadWrite 例程修改 IoCompletion 例程需要确定何时满足原始请求的任何参数,则保存参数尤其重要。
如果 IoCompletion 例程可以重试请求,则调度例程必须为其 IoCompletion 例程在完成原始 IRP 并出错之前应尝试的重试次数设置驱动程序确定的上限。
如果要重用 IRP,调度例程应调用 IoSetCompletionRoutine ,并将所有 InvokeOnXxx 参数都设置为 TRUE。
对于异步请求,任何中间驱动程序的调度例程必须为原始 IRP 调用 IoMarkIrpPending 。 然后将 IRP 发送到较低的驱动程序后,它必须返回STATUS_PENDING。
反馈
https://aka.ms/ContentUserFeedback。
即将发布:在整个 2024 年,我们将逐步淘汰作为内容反馈机制的“GitHub 问题”,并将其取代为新的反馈系统。 有关详细信息,请参阅:提交和查看相关反馈