编写后操作回调例程
文件系统微筛选器驱动程序使用一个或多个 后操作回调例程 来筛选 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 下调用的内核模式例程,例如 FltLockUserBuffer 或 RtlCompareUnicodeString。 出于同一原因,操作后回调例程中使用的任何数据结构都必须从非分页池中分配。
以下情况是上述规则的几个例外情况:
如果微筛选器驱动程序的预操作回调例程返回基于 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 。
本节包括: