编写后操作回调例程

文件系统微筛选器驱动程序使用一个或多个 后操作回调例程 来筛选 I/O 操作。

操作后回调例程可以执行以下操作之一:

  • 直接在操作后例程中完成工作。 所有完成工作都可以在 IRQL <= DISPATCH_LEVEL完成。
  • 在安全的 IRQL 中完成工作。 返回FLT_STATUS_MORE_PROCESSING_REQUIRED并将工作线程排队,以允许在安全 IRQL 下进行处理。 处理完成后,工作线程调用 FltCompletePendedPostOperation 以继续后操作处理。
  • 取消成功的 CREATE 操作。

操作后回调例程 类似于旧文件系统筛选器驱动程序中使用的 完成例程

微筛选器驱动程序为特定类型的 I/O 操作注册操作后回调例程,其方式与注册预操作回调例程的方式相同,即,通过将回调例程的入口点存储在FLT_REGISTRATION结构的 OperationRegistration 成员中,微筛选器驱动程序将其作为参数传递给其 DriverEntry 例程中的 FltRegisterFilter

微筛选器驱动程序仅接收已为其注册了操作前或操作后回调例程的 I/O 操作类型。 微筛选器驱动程序可以为给定类型的 I/O 操作注册预操作回调例程,而无需注册操作后回调,反之亦然。

每个操作后回调例程的定义如下:

typedef FLT_POSTOP_CALLBACK_STATUS 
(*PFLT_POST_OPERATION_CALLBACK) ( 
    IN OUT PFLT_CALLBACK_DATA Data, 
    IN PCFLT_RELATED_OBJECTS FltObjects, 
    IN PVOID CompletionContext, 
    IN FLT_POST_OPERATION_FLAGS Flags 
    ); 

与完成例程一样,在任意线程上下文中,在 IRQL <= DISPATCH_LEVEL 调用操作后回调例程。

由于可以在 IRQL = DISPATCH_LEVEL调用它,因此操作后回调例程不能调用必须在较低 IRQL 下调用的内核模式例程,例如 FltLockUserBufferRtlCompareUnicodeString。 出于同一原因,操作后回调例程中使用的任何数据结构都必须从非分页池中分配。

以下情况是上述规则的几个例外情况:

  • 如果微筛选器驱动程序的预操作回调例程返回基于 IRP 的 I/O 操作的FLT_PREOP_SYNCHRONIZE,则在与预操作回调例程相同的线程上下文中,将在 IRQL <= APC_LEVEL 调用相应的操作后回调例程。

  • 在与预操作回调例程相同的线程上下文中,在 IRQL = PASSIVE_LEVEL 调用快速 I/O 操作的后操作回调例程。

  • 在发起IRP_MJ_CREATE操作的线程上下文中,在 IRQL = PASSIVE_LEVEL 调用创建后回调例程。

当筛选器管理器为给定的 I/O 操作调用微筛选器驱动程序的后操作回调例程时,微筛选器驱动程序会暂时控制 I/O 操作。 微筛选器驱动程序将保留此控件,直到执行以下操作之一:

  • 从操作后回调例程返回FLT_POSTOP_FINISHED_PROCESSING。

  • 从已处理操作后回调例程中的基于 IRP 的 I/O 操作的工作例程调用 FltCompletePendedPostOperation

本节包括:

执行 I/O 操作的完成处理

在操作后回调例程中挂起 I/O 操作

操作后回调例程中的 I/O 操作失败