旧筛选器驱动程序移植指南

建议开发人员将旧筛选器驱动程序移植到筛选器管理器模型,以便为其筛选器驱动程序获取更好的功能并提高系统可靠性。 有经验的开发人员应该发现将旧筛选器驱动程序移植到微筛选器驱动程序相对容易。 Microsoft 的筛选器驱动程序开发人员建议使用以下方法:

  • 从可靠的回归测试套件开始,验证旧筛选器驱动程序与移植的微筛选器驱动程序之间的行为。

  • 创建一个微筛选器驱动程序 shell,并系统地将功能从旧筛选器驱动程序移动到微筛选器驱动程序。 例如,让附件正常工作,然后一次移植一个操作,在每个操作之后进行测试。

  • 最后更改用户模式/内核模式通信,以便可以使用现有工具来测试微筛选器驱动程序。

  • 使用 PREfast 进行编译,并使用已启用驱动程序验证程序中的筛选器验证程序 I/O 验证选项进行测试。

在移植过程中,应查看所有旧筛选器驱动程序代码,以充分利用筛选器管理器功能。 具体而言,请记住以下事项:

  • 在适当时,基于 IRP 的 I/O 和快速 I/O 操作可以通过相同的操作,这有助于减少代码重复。

  • 注册操作时,微筛选器驱动程序可以显式选择忽略所有分页 I/O 和缓存 I/O,这样就无需代码来检查这些。

  • 实例通知极大地简化了附加/分离逻辑。

  • 仅注册微筛选器驱动程序必须处理的操作;可以忽略其他所有内容。

  • 利用筛选器管理器上下文和名称管理支持。

  • 利用筛选器管理器对发出非递归 I/O 的支持。

  • 与旧版筛选器驱动程序不同,微筛选器驱动程序不能依赖本地变量来维护从预操作处理到操作后处理的上下文。 请考虑分配查看列表来存储操作状态。

  • 使用名称或上下文完成时,请务必释放引用。

  • 用户模式下的完成端口为生成队列添加了一种强大的技术。 你可能只需要与单个命名端口建立一个连接。

下表列出了旧筛选器驱动程序中的常见操作及其映射到筛选器管理器模型的方式。

旧版筛选器驱动程序模型 筛选器管理器模型

不带完成例程的直通操作

如果微筛选器驱动程序永远无法用于这种类型的 I/O 操作,请不要为此操作注册预操作或操作后回调例程。

否则,从为此操作注册的预操作回调例程返回FLT_PREOP_SUCCESS_NO_CALLBACK。

请参阅 返回FLT_PREOP_SUCCESS_NO_CALLBACK

具有完成例程的直通操作

从预操作回调例程返回FLT_PREOP_SUCCESS_WITH_CALLBACK。

请参阅 返回FLT_PREOP_SUCCESS_WITH_CALLBACK

预操作回调例程中的 Pend 操作

根据需要调用 FltLockUserBuffer ,以确保正确锁定任何用户缓冲区,以便在工作线程中访问它们。

通过调用支持例程(如 FltAllocateDeferredIoWorkItemFltQueueDeferredIoWorkItem)将工作排到工作线程。

从预操作回调例程返回FLT_PREOP_PENDING。

准备好将 I/O 操作返回到筛选器管理器时,请调用 FltCompletePendedPreOperation

请参阅 在预操作回调例程中挂起 I/O 操作

操作后回调例程中的 Pend 操作

在预操作回调例程中,调用 FltLockUserBuffer 以确保正确锁定用户缓冲区,以便在工作线程中访问它们。

通过调用支持例程(如 FltAllocateGenericWorkItemFltQueueGenericWorkItem)将工作排到工作线程。

从操作后回调例程返回FLT_POSTOP_MORE_PROCESSING_REQUIRED。

准备好将 I/O 操作返回到筛选器管理器时,请调用 FltCompletePendedPostOperation

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

同步操作

从预操作回调例程返回FLT_PREOP_SYNCHRONIZE。

请参阅 返回FLT_PREOP_SYNCHRONIZE

在预操作回调例程中完成操作

设置操作FLT_CALLBACK_DATA结构的IoStatus 成员中的最终操作状态和信息。

从预操作回调例程返回FLT_PREOP_COMPLETE。

请参阅 在预操作回调例程中完成 I/O 操作

在预操作回调例程中插入操作后完成该操作

设置操作FLT_CALLBACK_DATA结构的IoStatus 成员中的最终操作状态和信息。

从处理 I/O 操作的工作线程调用 FltCompletePendedPreOperation ,并将FLT_PREOP_COMPLETE作为 CallbackStatus 参数传递。

请参阅 在预操作回调例程中完成 I/O 操作

完成例程中的所有完成工作

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

请参阅 编写操作后回调例程

在安全 IRQL 中完成工作

从操作后回调例程调用 FltDoCompletionProcessingWhenSafe

请参阅 确保以安全 IRQL 执行完成处理

从完成例程发出事件信号

从此操作的预操作回调例程返回FLT_PREOP_SYNCHRONIZE。

筛选器管理器在与预操作回调例程相同的线程上下文中调用操作后回调例程(IRQL <= APC_LEVEL)。

请参阅 返回FLT_PREOP_SYNCHRONIZE

成功创建操作失败

从创建操作的后操作回调例程调用 FltCancelFileOpen

在操作的 FLT_CALLBACK_DATA 结构的 IoStatus 成员中设置适当的错误 NTSTATUS 值。

返回FLT_POSTOP_FINISHED_PROCESSING。

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

禁止通过 I/O 操作的快速 I/O 路径进行 I/O

从操作的预操作回调例程返回FLT_STATUS_DISALLOW_FAST_IO。

请参阅 禁止在预操作回调例程中执行快速 I/O 操作

修改 I/O 操作的参数

在操作的 FLT_CALLBACK_DATA 结构的 Iopb 成员中设置修改的参数值。

通过调用 FltSetCallbackDataDirty 将FLT_CALLBACK_DATA结构标记为脏,但修改了 FLT_CALLBACK_DATA 结构的 IoStatus 成员的内容除外。

请参阅 修改 I/O 操作的参数

锁定操作的用户缓冲区

使用 访问 I/O 操作的用户缓冲区中所述的技术和指南。