引用上下文
筛选器管理器使用引用计数来管理微筛选器上下文的生存期。 引用计数是指示上下文状态的数字。
每当成功创建上下文时,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,然后调用筛选器的上下文清理回调。 筛选器现在有机会清理其上下文。 |