Minifiler开发心得

Writing a File System Minifilter - Pitfalls, Hints and Tips
 
Minifilter 心得
 
2007-04-09 11:43
Writing a File System Minifilter - Pitfalls, Hints and Tips
The NT Insider, Vol 12, Issue 4, September-October 2005 | Published: 16-Nov-05| Modified: 16-Nov-05
By Rod Widdowson
 
2005年春,Windows 2003 SP1中发布了Filter Manager.在那以后人们可以利用MiniFilter框架书写文件驱动了.
以下就谈谈我们的心得.
 
提高写代码的速度并不意味着设计简单!
清楚的认识到利用Minifilter写文件系统 可以提高开发速度,但并不降低设计难度.
它一系统列的 样板文件这样可以使写过滤驱动的速度大大提高.
但不要以为开发难度就降低了 ,例如 ,你还是得理解过滤驱动是如何嵌入到 Windows内核之中,如何与别的驱动进行协调的 .
在熟练的人手里 ,Filter Manager可以发挥极大的作用 ,CAI BIRD手上将会使它变得危险 !
 

If You're Writing a Lot of Code ‑ Check the Documentation

Filter Mangaer 急过滤驱动开发人员之后急,提供了大量过滤驱动开所要的库。比如说,若你要取得重命名之后文件的文件名 , 可以调用 FltGetDestinationFile NameInformation().
若你要取得共享文件名,可调用 FltParseFileNameInformation() .
你可以在写代码之前,查找 Flt 前缀的函数 , 说不定可以直接在 API 中找到你要的功能 ,
, 好爽的 !  尽量少用 Zw 系统函数 ,Zw 系统在 Flt 中都有对应的函数 !
Flt 系统函数可以防止重入 ! 长远来看 , Vista ,Minifilter 轻松支持 Transactional NTFS, 传统驱动只好边上站着看看风景了?! Hahah...
 

Unload Frequently During Development

OSRONLINE , 常有人问题到 当我们 Unload Minifilter , 驱动挂起, Unload 不下来 .”
99% 的原因是驱动中还有资源没有释放,比如说 LookAsideList,Context,Resource .
利用 Driver Verifier 可以检测到这类问题。

Use Checked Kernel and Checked Filter Manager

 
 
 
若不检查参数,MiniFilter常会在文件打开时返回一个无效参数块
在调试状态时,若出现无效参数块,如下ASSERT会失败的.
FsRtlIsPagingFile((fileObject)) || ((fileObject)->FsContext == NULL && FlagOn((fileObject)->Flags, FO_STREAM_FILE | FO_DIRECT_DEVICE_OPEN)) || FltpIsWellKnownPagingFileName(fileObject)
 
status = FltQueryInformationFile(FltObjects->Instance,
                            FltObjects->FileObject,
                            &fileInfo,
                            sizeof(FILE_ALL_INFORMATION),
                            FileAllInformation,
                            &length);
PreWrite中工作得好好的,但在PreCreate中因为FileObject还没有完全建立好,因此会失败,不能用.
 

How Context Management Works

上下文管理是 Minifilter 中最容易出问题的部分 . 而现在检测上下文引用泄漏有限 , 问题不好找 . 现在最好的方法是在 Driver Verifier 中设置 Pool Track, 这样只知道有泄漏,无法定位是那个地方 . 最好在刚开始编码时就这么设置,代码量大了就真的一个机会也没有了 , 哈,事在人为 !
 
上下文是引用型数据结构 . 只要引用非 0 Filter Manager 就不会释放它 . 当引用变为 0 , 事先设置的 ContextCleanup Callback 回调函数会被调用 , 然后上下文件被删除 .
因此,认识到那些操作影响引用计数是重要的 .
创建 , 查找 , 显式引用一个上下文都会对引用计数进行加一操作 , FltReferenceContext, FltGetContext , FltSetXXXContext 也会进行一个对引用加一的操作 .
引用减一发生在如上下文 detached , 这个操作直接使引用为 0.
引用技术是在多线程环境下保护数据安全性的一种技术 .
 
FltSetContext 把一个上下文件 Attatch 到一个内核数据结构之中,并对引用进行加一的操作 .
什么原因会引发 Detach 操作呢 ? 主要有以下四个 :
1.       当被 Attached 的数据结构被删除时 , 如当文件系统调用 FsRtlTeardownPer StreamContexts,
那么 Filter Manger Detach 所有的 StreamContext.
2.       当被 Attached 的数据结构关联的 filter Instance Detached .
3.       Minifilter 自己调用 FltDeleteContex t , 会发生 Detach 操作 .
4.       调用 FltSetXXXContext 时若设置 FLT_SET_CONTEXT_REPLACE_ IF_EXISTS, 在这种情况下
In this case the old context is not dereferenced, which means it will not go away before the caller has a chance to inspect it. Therefore, the caller has to perform the dereference.
 
以上 1,2,4 是引发 Detaching 的最高要原因 . 因此一般不会主动调用 FltDeleteXXXContext.
 
对大多数函数来说 , 若引用一个上下文,一般会下返回之前解引用它 .

Instance Initialization and Teardown

As we have seen, instance initialization can either happen:
  • Explicitly - via FLTMC, the FltAttachVolume kernel function, or the FilterAttach user mode function; or
  • Automatically - as a result of a minifilter being loaded or a volume becoming otherwise available
Depending on precisely what triggers the call of InstanceSetupCallback, the process context will vary. This requires you to be careful before making any assumptions about the context in which your filter is being called.
Let's look at two examples.
  1. FLTMC ATTACH myfilter C - InstanceSetup Callback will be called in the context of the process running fltmc.
  2. FLTMC LOAD myfilter - InstanceSetup Callback will be called in the context of the system process.
This has several repercussions; many of them are quite subtle. For example, consider what impact the previous mode may have on probe. Therefore, it is important to test at least these two variants, along with the associated detach and teardown homologs.
 

你可能感兴趣的:(职场,休闲,Minifiler)