阅读:2101回复:6
一个minirdr的写作过程
两个月前,组长安排我和师兄tanky写一个网络文件系统,当时我对文件系统一无所知,只是有过几个其他驱动的编写经验.
到现在,我的第一个试验性质的网络文件系统已经基本成型了,当然还有一些bug没有做好. 首先开始的是文件系统的学习过程. 这方面的资料实在太少了,我手上有一本<nt filesystem internals>,国内的网站就是驱动开发网了,国外也没有什么这方面的网站. 对文件系统的第一步是从驱动开发网开始的,这里要谢谢这里的很多网友,因为最初我是完全什么都不懂的,包括ifs都没有办法得到. 我看完了这个网的文件系统部分几乎所有的帖子,花了几天的时间阿!看完之后我发现这个版讨论的最多好像就是文件的隐藏问题了, 还有其他的加密解密等等.这里不得不提一下,这里的程序大部分只停留在过滤器的程度,没有涉及到真正的文件系统本身,而我做的则是 文件系统,这也是我发表这则帖子的原因之一,希望可以作为对我喜欢的这个网站的一个补充把,也希望能与大家一起学习. 我从这个网站下载了filemon的源码,它和dbgview是我编写minirdr过程中的最主要的工具之一. 我从最开始的sfilter开始做起,从驱动网复制了一些代码来实现最开始的隐藏文件的功能.忘了是copy那一位大侠的代码了,总之是 比较简单的实现了隐藏文件的问题.接着我又试了一下添加一项的功能等等,都还比较顺利. 最后我把sfilter的query_directory改造了一下,变成一个打印出所有目录项的小工具了,这个工具后来起到了一定的作用. 顺便说一下,我的一个不好的习惯就是太依赖softice了,但是更多的时候我想采用直接打印加上dbgview可能更直观更容易发现问题, 因为人的耐心和细心是有限的,softice再好用的太多你也感到很烦了,所以不要懒得加上这些打印就直接用softice watch, 这方面tanky有一个很好的习惯,呵呵. 但是我陷入了迷茫之中,不知道我要做的到底是一个什么样的系统,是过滤器呢还是一个fsd? 我在网上问了好多这方面的问题,感谢很多热心网友的回答,但是仍然不知道怎么样才是我所需要的答案. 接着我花了一两个星期看完了nt filesystem internals这本书(好长阿,看得不是很仔细), 这里要推荐一下这本唯一的文件系统方面的书,确实写的不错. 仍然没有头绪,我只好把ifs里面的文件系统例子一个个的开始看了.我最开始的想法是在fastfat的基础上面改,但是后来发现 nulmrx是更好的选择. 在确定了方案之后,接下来的事情就顺利很多了. 首先实现的是NulMRxQueryDirectory函数.我的第一步计划是虚拟一个网络驱动器,但是里面的目录信息是自己随便填的,由于有了前面的 隐藏目录项的经验,这一步比较顺利.接着我改成把一个本地的目录映射到我的驱动器中间来,采用的是ZwQueryDirectoryFile函数. 这些都做好了之后我就自己定义了一下网络通讯协议,然后编写了一个测试用的服务器程序, 这样下一步的工作就是开始真正的做一个网络文件系统了. 解释一下minirdr,按照nt filesystem internals上面的说法,网络文件系统了包括两部分,一个是服务器部分(不记得名字了) ,一个是客户端部分(叫做redirector),而minirdr就是mini redirector了把? 接下来就是做有网络通讯的minirdr了.网络通讯协议要采用的是tdi,以前做iscsi的时候做好了的,所以不用改就直接拿来用了. 下面就主要说一下几个函数的一些用法把,还有一些缺陷. NulMRxQueryDirectory: 这个函数是比较复杂的一个,虽然代码都不长. SrvOpen->pAlreadyPrefixedName CurrentIrpStack->Parameters.QueryDirectory.FileName 这是两个比较重要的参数,这两个参数我花了很长的时间才清楚到底该怎么用. 前面是当前已经打开的目录名,后面一个是你要查询的文件名. 使用filemon观察一下xp文件系统,你会发现很多这样的信息,比如: IRP_MJ_DIRECTORY_CONTROL K:\abcd\ SUCCESS FileBothDirectoryInformation: * IRP_MJ_DIRECTORY_CONTROL K:\abcd\ SUCCESS FileBothDirectoryInformation IRP_MJ_DIRECTORY_CONTROL K:\abcd\ NO MORE FILES FileBothDirectoryInformation IRP_MJ_DIRECTORY_CONTROL K:\ SUCCESS FileBothDirectoryInformation: abcd 看一下filemon的源代码,你可以发现类似K:\abcd\这样的数据是SrvOpen->pAlreadyPrefixedName, 类似*,空,abcd则是 CurrentIrpStack->Parameters.QueryDirectory.FileName. 另外返回的信息也是很有讲究的,什么时候返回SUCCESS,什么时候返回NO MORE FILES呢,这个问题到现在我也没有彻底弄清楚, 不知道用什么参数组合得到应该怎么样返回. 我采用了一种比较弱智的方法,就是用计数器来做的. 因为我观察系统的消息发现,每次都是上面的前三条消息重复出现, 第一次的*出现的时候表示是RxContext->QueryDirectory.ReturnSingleEntry为1,这时候返回第一个目录项. 第二次返回除去第一个之外的其他项,返回SUCCESS,第三次返回除去第一个之外的其他项,返回NO MORE FILES. 另外,不是所有的 NulMRxQueryDirectory都返回目录下的信息,比如说上面的 FileBothDirectoryInformation: abcd. 这时候CurrentIrpStack->Parameters.QueryDirectory.FileName不等于*,也不为空,这时候你就要返回 CurrentIrpStack->Parameters.QueryDirectory.FileName本身的信息,而不是把它当作一个目录. CurrentIrpStack->Parameters.QueryDirectory.FileName也可以是一个文件名的,这时候要返回文件的信息. 当然,这些都是按照FILE_BOTH_DIR_INFORMATION的格式返回的. NulMRxQueryVolumeInformation: 这个比较简单,就是一些卷信息的返回. NulMRxSetFileInformation: 这里面包括重命名(包括拖动),delete.就是FileDispositionInformation 和FileRenameInformation了. 这两个我的程序实现还有一个问题没有解决,就是重命名还有delete之后要通知操作系统发一个 change notify命令, 我使用的是FsRtlNotifyFullReportChange,但是并没有什么效果,目前我正在想办法改这个地方. 因为没有notify的话,系统以为原来的文件还存在,所以你的rename和delete会弹出一个错误,但是由于我是拿到服务器处理的, 所以刷新之后发现操作正常处理了,只是弹出的错误框看起来很不爽. rename之前会试图open你要rename成的目标文件名,如果没有命名冲突这时候你返回no_such_file就可以了. NulMRxQueryFileInformation: 主要是FileBasicInformation和FileStandardInformation吧,并不难. 另外FileInternalInformation和FileEaInformation你要返回success NulMRxRead和NulMRxWrite: 这里很简单,但是RxContext->IoStatusBlock.Status=STATUS_SUCCESS; RxContext->IoStatusBlock.Information=ByteCount;要加上 否则不正确. NulMRxCreate: 包括新建和打开. 系统新建一个文件的方法是这样的: 比如新建文本文件,它会首先create 新建文本文件,如果不存在这个名称,你就返回success,否则返回name_collision 接着系统create 新建文本文件(2),...直到返回success找到合适的名字为止. 新建目录呢,则是先open 新建文件夹,这时候你返回no_such_file,或者success,如果是success系统就会open 新建文件夹(2)... 知道返回no_such_file找到合适的名字为止. 对于open就是简单的no_such_file,或者success. 写的很扎乱,而且有点虎头蛇尾,但是还是希望有兴趣写rdr的和我一起探讨一下. email:mtwyayacn@163.com |
|
沙发#
发布于:2004-07-21 14:48
赞!
|
|
板凳#
发布于:2004-07-21 19:13
好,希望以后能多点这样总结.....
|
|
|
地板#
发布于:2004-07-26 11:16
是的,恩泽大众!
|
|
地下室#
发布于:2004-07-26 22:34
不错,要的就是这种精神
|
|
|
5楼#
发布于:2005-02-26 15:12
我现在也在研究nulmrx,但是根本不能用,ie访问\\\\nulsvr\\share并没有成功,为了知道为什么不可用,我加了一些dbgprint函数,但是当输入\\\\nulsvr\\share时,相应的字符串并没有被打印出来。所以请教一下,大虾当初是怎么装上nulmrx的?
|
|
6楼#
发布于:2005-03-03 09:15
你的驱动并没有装上吧?
只要照着readme里面的作就可以了阿 你可以看看注册表 有没有ini文件中所说明的项 另外sys放在drivers目录下面 dll放在system32目录下面 其他都是readme里面的步骤 |
|