引用上下文

筛选器管理器使用引用计数来管理微筛选器上下文的生存期。 引用计数是指示上下文状态的数字。

每当成功创建上下文时,FltMgr 会将上下文的引用计数初始化为 1。 这称为对上下文 的初始引用

每当上下文被引用(例如通过成功的上下文 获取)时,FltMgr 会将上下文的引用计数递增 1。

当不再需要上下文时,其引用计数必须递减。 正引用计数意味着上下文可用。 当引用计数变为零时,上下文不可用,FltMgr 最终会释放它。

FltMgr 释放对上下文的初始引用 (在对象被拆解时将引用计数减为零) ,然后调用筛选器的可选 上下文清理回调。 虽然这种情况很少发生,但如果微筛选器必须在拆解之前从对象中删除上下文,则微筛选器必须通过调用 FltDeleteContext 安全地释放对上下文的初始引用。

微筛选器可以通过调用 FltReferenceContext 来增加上下文的引用计数,从而添加对上下文的自己的引用。 微筛选器最终必须通过调用 FltReleaseContext 删除此添加的引用。

下面是典型对象的引用计数历史记录的简短示例。 假设所有 Flt API 调用都成功。

筛选器回调 调用的 Flt API 上下文引用计数 说明
PreCreate FltAllocateContext 1 筛选器正在处理预创建,并决定可能需要跟踪文件。 它分配流上下文,这会导致 FltMgr 将引用计数初始化为 1。 筛选器通过 CompletionContext 参数将上下文传递给其 PostCreate 回调。
PostCreate FltSetStreamContext 2 筛选器将其在 PreCreate 期间分配的上下文传递给其 PostCreate 回调。 创建成功,因此筛选器附加上下文,这会导致 FltMgr 递增引用计数。
PostCreate FltReleaseContext 1 由于 FltSetStreamContext 递增了引用计数,因此筛选器需要删除额外的计数。 筛选器释放上下文后,引用计数为 1,因此上下文保持活动状态。 如果筛选器决定它毕竟不关心此文件,它本可以跳过调用 FltSetStreamContext ,只需调用 FltReleaseContext 即可。 在这种情况下,计数将更改为 0,上下文将被解除分配。
预读 FltGetStreamContext 2 筛选器看到读取的 I/O,并想知道它是否正在跟踪此文件。 它请求并获取其流上下文,因此它知道要跟踪此文件。 FltMgr 递增引用计数。
预读 FltReleaseContext 1 筛选器是使用其上下文完成的,因此会释放它,从而导致引用计数递减。 每个 FltGet*Context 都必须与 FltReleaseContext 保持平衡。
PreCleanup FltGetStreamContext 2 筛选器请求并获取其上下文,这会递增引用计数。
PreCleanup FltReleaseContext 1 筛选器是使用 上下文完成的,因此释放它,这会减少引用计数。
上下文清理回调 0 文件系统正在拆除基础流对象。 (在流对象的特定情况下,由IRP_MJ_CLOSE) 触发拆解。 FltMgr 将引用计数递减为 0,然后调用筛选器的上下文清理回调。 筛选器现在有机会清理其上下文。