Welcome

首页 / 软件开发 / C++ / Windows文件过滤驱动经验总结

Windows文件过滤驱动经验总结2011-04-22ai3000看了 ChuKuangRen 的第二版《文件过滤驱动开发教程》后,颇有感触。我想,交流都是 建立在平等的基础上,在抱怨氛围和环境不好的同时应该先想一想自己究竟付出了多少?只 知索取不愿付出的人也就不用抱怨了,要怪也只能怪自己。发自己心得的人无非是两种目的 ,一是引发一些讨论,好纠正自己错误的认识,以便从中获取更多的知识使自己进步的更快 。二是做一份备忘,当自己遗忘的时候能够马上找到相关资料。我这里也总结了近几年做文 件过滤驱动时所积累下来的一些小小经验,这分笔记也是看了 ChuKuangRen 的教程后,临时 想到的一小部分而已,是想到哪写到哪,不是很全,如果以后再回想起什么也会不断补充。 因其工作原因,近段时间在 SOLARIS 驱动与 Linux 内核方面投入的精力比较多,Windows 下的文件过滤驱动一直也没有怎么去碰,所以最后还是那句老话 FIXME。

1、获得文 件全路径以及判断时机

除在所有 IRP_MJ_XXX 之前自己从头创建 IRP 发送到下层设 备查询全路径外,不要尝试在 IRP_MJ_CREATE 以外的地方获得全路径,因为只有在 IRP_MJ_CREATE

中才会使用 ObCreateObject() 来建立一个有效的 FILE_OBJECT。而 在 IRP_READ IRP_WRITE 中它们是直接操作 FCB (File Control Block)的。

2、从头 建立 IRP 发送关注点

无论你建立什么样的 IRP,是 IRP_MJ_CREATE 也好还是 IRP_MJ_DIRECTORY_CONTROL也罢,最要提醒的就是一些标志。不同的标志会代来不同的结果 ,有些结果是直接返回失败。这里指的标志不光是 IRP->Flags,还要考虑 IO_STACK_LOCATION->Flags还有其它等等。尤其是你要达到一些特殊目的,这时候更需要 注意,如 IRP_MN_QUERY_DIRECTORY,不同的标志结果有很大的不同。

3、从头建立 IRP 获取全路径注意点

自己从头建立一个 IRP_MJ_QUERY_INFORMATION 的 IRP 获取 全路径时需要注意,不仅在 IRP_MJ_CREATE 要做区别处理,在 IRP_MJ_CLOSE 也要做同样的 处理,否则如果目标是 NTFS 文件系统的话可能产生 deadlock。如果是 NTFS 那么在 IRP_MJ_CLEANUP 的时候也需要对 FO_STREAM_FILE 类型的文件做同样处理。

4、获得 本地/远程访问用户名(域名/SID)

方法只有在 IRP_MJ_CREATE 中才可用,那是因为 IO_SECURITY_CONTEXT 只有在 IO_STACK_LOCATION- >Parameters.Create.SecurityContext 才会有效。这样你才有可能从 IO_SECURITY_CONTEXT->SecurityContext->AccessState- >SubjectSecurityContext.XXXToken 中获得访问 TOKEN,从而进一步得到用户名或 SID 。记得 IFS 中有一个库,它的 LIB 导出一个函数可以让你在获得以上信息后得到用户名与 域名。但如果你想兼容 NT4 的话,只能自己分析来得出本地和远程的 SID。

5、文件 与目录的判断

正确的方法在楚狂人的文档里已经说过了,再补充一句。如果你的文件 过滤驱动要兼容所有文件系统,那么不要十分相信从 FileObject->FsContext 里取得的 数据。正确的方法还是在你传递下去 IRP_MJ_CREATE 后从最下层文件系统延设备栈返回到你 这里后再获得。

6、加/解密中判断点

只判断 IRP_PAGING_IO, IRP_SYNCHRONOUS_PAGING_IO,IRP_NOCACHE 是没错的。如果有问题,相信是自己的问题。关 于有人提到在 FILE_OBJECT->Flags中的 FO_NO_INTERMEDIATE_BUFFERING 是否需要判断 ,对此问题的回答是只要你判断了 IRP_NOCACHE 就不用再判断 FILE_OBJECT 中的,因为它 最终会设置 IRP->Flags 为 IRP_NOCACHE。关于你看到的诸如 IRP_DEFER_IO_COMPLETION 等 IRP 不要去管它,因为它只是一个过程。最终读写还是如上所介绍。至于以上这些 IRP 哪个是由 CC MGR 发送的,哪些是由 I/O MGR 发送和在什么时候发送的,这个已经有很多讨 论了,相信可以找到。