示例:简单Pass-Through调度和完成

注意

为了获得最佳可靠性和性能,请使用支持筛选器管理器的 文件系统微筛选器驱动程序 ,而不是旧版文件系统筛选器驱动程序。 若要将旧驱动程序移植到微筛选器驱动程序,请参阅 移植旧筛选器驱动程序的指南

若要为 IRP 设置完成例程并向下传递 IRP,旧文件系统筛选器驱动程序的调度例程必须执行以下操作:

以下代码示例演示了此方法:

IoCopyCurrentIrpStackLocationToNext( Irp ); 
IoSetCompletionRoutine( Irp,                                 // Irp
                        MyLegacyFilterPassThroughCompletion, // CompletionRoutine
                        (PVOID)recordList,                   // Context
                        TRUE,                                // InvokeOnSuccess
                        TRUE,                                // InvokeOnError
                        TRUE);                               // InvokeOnCancel
return IoCallDriver ( NextLowerDriverDeviceObject, Irp ); 

在此示例中,对 IoSetCompletionRoutine 的调用为 IRP 设置完成例程。

调用 IoSetCompletionRoutine 中的前两个参数是指向 IRP 的指针和完成例程的名称。 第三个参数是指向要传递到完成例程的驱动程序定义结构的指针。 此结构包含完成例程在 IRP 上执行完成处理时所需的上下文信息。 必须从非分页池中分配上下文结构,因为可以在 IRQL DISPATCH_LEVEL调用完成例程。

传递给 IoSetCompletionRoutine 的最后三个参数是指定在 I/O 请求成功、失败还是取消时调用完成例程的标志。

如果调度例程设置完成例程并在调用 IoCallDriver (后立即返回,如上一个调度例程) 所示,则相应的完成例程必须检查 IRP 的 PendingReturned 标志,如果已设置,则调用 IoMarkIrpPending。 然后,它应返回STATUS_SUCCESS,如以下示例所示:

if (Irp->PendingReturned) {
    IoMarkIrpPending( Irp );
}
return STATUS_SUCCESS;
  • 此方法的优点

    设置完成例程允许驱动程序在较低级别的驱动程序处理 IRP 后进一步处理 IRP。 完成例程可以根据请求的 I/O 操作的结果来决定如何处理 IRP。

  • 此方法的缺点

    由于它在 IRQL <= DISPATCH_LEVEL 的任意线程上下文中运行,因此完成例程只能对 IRP 执行有限的处理。