mtwyaya
驱动牛犊
驱动牛犊
  • 注册日期2002-10-20
  • 最后登录2008-08-15
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望2点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
阅读:2101回复:6

一个minirdr的写作过程

楼主#
更多 发布于:2004-07-21 11:26
两个月前,组长安排我和师兄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

最新喜欢:

aasa2aasa2 TOMG2004TOMG20...
freducn2002
驱动小牛
驱动小牛
  • 注册日期2002-06-26
  • 最后登录2018-05-29
  • 粉丝0
  • 关注0
  • 积分11分
  • 威望29点
  • 贡献值0点
  • 好评度7点
  • 原创分0分
  • 专家分0分
  • 社区居民
沙发#
发布于:2004-07-21 14:48
赞!
wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
板凳#
发布于:2004-07-21 19:13
好,希望以后能多点这样总结.....
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
dj_ukyo
驱动小牛
驱动小牛
  • 注册日期2003-03-13
  • 最后登录2009-06-02
  • 粉丝0
  • 关注0
  • 积分118分
  • 威望16点
  • 贡献值0点
  • 好评度14点
  • 原创分0分
  • 专家分0分
地板#
发布于:2004-07-26 11:16
是的,恩泽大众!
AllenZh
驱动老牛
驱动老牛
  • 注册日期2001-08-19
  • 最后登录2015-11-27
  • 粉丝19
  • 关注10
  • 积分1316分
  • 威望2387点
  • 贡献值7点
  • 好评度321点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2004-07-26 22:34
不错,要的就是这种精神
1,承接Windows下驱动/应用开发 2,本人原创虚拟鼠标/键盘,触摸屏,虚拟显卡,Mirror驱动,XP无盘的SCSI虚拟磁盘驱动等 3,windows下有尝技术服务(包括BUG调试,员工培训等) 欢迎深圳和海外企业联系.msn:mfczmh@sina.com
bigworm1
驱动牛犊
驱动牛犊
  • 注册日期2005-02-26
  • 最后登录2005-02-26
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2005-02-26 15:12
我现在也在研究nulmrx,但是根本不能用,ie访问\\\\nulsvr\\share并没有成功,为了知道为什么不可用,我加了一些dbgprint函数,但是当输入\\\\nulsvr\\share时,相应的字符串并没有被打印出来。所以请教一下,大虾当初是怎么装上nulmrx的?
mtwyaya
驱动牛犊
驱动牛犊
  • 注册日期2002-10-20
  • 最后登录2008-08-15
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望2点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2005-03-03 09:15
你的驱动并没有装上吧?
只要照着readme里面的作就可以了阿
你可以看看注册表 有没有ini文件中所说明的项
另外sys放在drivers目录下面 dll放在system32目录下面
其他都是readme里面的步骤
游客

返回顶部