windows平台xFsRedir目录重定向程序2020年更新

                                                                                                 by fanxiushu 2020-12-09 转载或引用请注明原始作者


今年对xFsRedir程序的更新幅度是比较大的.
首先在大概4月份的时候,增加了基于更底层的虚拟磁盘驱动来替换主驱动xfs_redir.sys内嵌的简单虚拟磁盘功能。
而这次的更新则是增加了文件重定向功能,增加了特殊程序才能使用重定向的功能,
虚拟磁盘部分增加了iSCSI协议,SMB通讯部分增加了第三方开源库。
修改了主驱动和扩展虚拟磁盘驱动的某些BUG。

如果对xFsRedir有兴趣,可关注GITHUB上的程序,本文章对应的最新版本是 4.1 :
https://github.com/fanxiushu/xFsRedir

具体的更新可以罗列成以下几条:
1, 目录重定向部分增加单个文件重定向,增加可以指定特殊程序才能使用重定向的功能
2, SMB通讯协议同时提供了第三方开源代码和windows系统调用两种方式,可根据情况自行选择某种SMB通信。
3, 虚拟磁盘部分增加iSCSI通讯协议, 必须使用扩展虚拟磁盘驱动才能支持iSCSI协议映射整块磁盘
4,版本4.0以上的xFsRedir在每个重定向目录增加了‘范秀树.xFsRedir.说明.txt’版权说明文件,
   增加了桌面水印,同时必须以System系统账户和服务方式运行xFsRedir,
5, (这是今年四月份的更新)使用基于Storport底层框架的虚拟磁盘驱动代替直接IO的虚拟磁盘驱动,
   windows系统把这种虚拟磁盘当成真正的物理磁盘,
   并且能在磁盘管理器和设备管理器中查询到虚拟磁盘

BUG修改:
1,扩展虚拟磁盘驱动中,修正了可能长时间无法回应请求数据块,从而造成系统蓝屏问题(尤其是win10系统,下面会再次提及)。
2,  修正了主驱动某些比较难发现的BUG,比如经常创建和删除监控目录,有时可能造成内存方面的系统崩溃。
3,以前的版本中,不知道是什么时候开始的,大概是win10以上的系统中,当我把监控目录设置到vmware的虚拟机目录所在的盘符中,
      同时开启虚拟机和访问监控目录,容易造成整个系统死锁。
      由于主驱动确实有一把全局锁,主驱动本身实现的就是一个文件系统,windows文件系统是复杂的,
      各种回调函数都是可以重入的,如果某些BUG,确实会造成整个系统死锁。
      这次为了解决这个BUG,几乎把代码折腾了个遍,几乎是重构了一遍主驱动,
      后来换了一种加锁方式,才算解决(下面也会再次提及)。

xFsRedir新增的只有特殊程序才能看到重定向的目录或文件的功能,也许在某些特殊场所比较有用,
特别是某些需要加密或隐私处理的目录或文件。比如下图的实例,以 K:\ReFile目录为实例:

windows平台xFsRedir目录重定向程序2020年更新_第1张图片


上图可能看起立比较吃力,做个大致解释,
以K:\ReFile目录为例,其实整个K盘符都是通过xFsRedir虚拟的。
ReFile目录内一共设置了三个重定向的子目录或文件,
其中两个文件: xdisp_virt.exe, xFsRedir.exe, 设置这个两个重定向的文件只能被cmd.exe和notepad.exe程序访问,
而子目录PC1-E设置成只能被explorer.exe(资源管理器)访问,
于是在图中,就出现了矩形框里边标注的奇景:
cmd.exe控制台程序和notepad.exe记事本程序中,只能看到和使用 xdisp_virt.exe和xFsRedir.exe两个文件,看不到PC1-E子目录。
而在资源管理器中,只能看到和使用PC1-E目录,不能查询到xdisp_virt.exe和xFsRedir.exe这两个文件。
而在其他程序,比如写字板程序中,则是什么都看不到,自然更无法访问了。

xFsRedir增加了文件重定向功能。
这里xFsRedir主驱动实现的文件重定向,属于重量级的,为何这么说呢?
一般实现文件重定向,就是只是在文件过滤驱动中,
简单的在IRP_MJ_CREATE 派遣函数里边重新设置新的文件路径,然后返回STATUS_REPARSE。
这样windows系统自动重新解析新的文件路径,然后打开这个新路径的文件,这样就达到了文件重定向的目的,
所以不论是原理还是代码实现起来,都是比较简单的。
当然局限性也比较大,比如只能是本地电脑的文件,重定向文件必须在电脑中存在等。

而在xFsRedir中实现的文件重定向,是根据目录重定向的功能修改简化而来。
过滤驱动实现目录重定向,是个复杂的过程,具体可以查看我之前的CSDN上文章的介绍。
因此xFsRedir的文件重定向,依然是全程拦截FILE_OBJECT文件对象到应用层,然后在应用层实现各种通讯协议与服务端通讯。
也正是这样,被重定向的文件与被重定向的目录有相似的特性,
比如文件可以无需在电脑上存在,可以通过各种通讯协议与服务端进行数据传输。
当然,因为FILE_OBJECT文件对象被文件过滤驱动全程拦截,不再传递给NTFS文件系统底层。
FILE_OBJECT的FsContext和FsContext2指针依然指向的是挂载的分区卷的根目录,
这会对某些需要访问FsContext的特殊驱动程序,带来混乱的访问行为(这种特殊驱动程序,应该是很少见)

以上两个功能,是有网友发邮件提出的,后来想想实现起来也没啥问题,就添加进xFsRedir了。
还有一个问题,提及的人也较多,就是SMB登录问题,说是老是登陆不上,
不过我的电脑从来没发生过这种事情。
原先的xFsRedir使用SMB通讯,首先是调用  WNetAddConnection2尝试登录,
然后调用 NetShareEnum枚举共享目录,再然后就是调用CreateFile系统函数 打开形如 \\Server\Share\path的路径。
就是这样进行SMB通讯的,使用WIN32API函数,有个非常奇葩的要求,
必须是当前登录用户才能成功登录到SMB服务端,而xFsRedir是以服务方式运行的。
在System账户中调用WNetAddConnection2 是无法登录到,必须首先调用 ImpersonateLoggedOnUser模仿当前登录用户,
至于说是登录不上的,很可能是 ImpersonateLoggedOnUser调用不成功,自然也会造成后续一系列的API调用失败。

这次更新,添加了第三方开源的SMB代码来实现登录,这样,xFsRedir程序就集成了两种SMB通讯方式:
一种是原来的WIN32API方式,一种是开源SMB方式。
开源SMB的好处是无需借用win32API,自然也无需登录到当前活动用户这种奇特的要求。
如果两种方式都无法登录SMB, 那恭喜你中奖了。

SMB的开源客户端,得益于 Ronnie Sahlberg 作者,GITHUB上的地址:
https://github.com/sahlberg

不知道从什么时候开始,大概是更新到最新WIN10版本的时候,或者升级到最新的vmware版本的时候,
记不清时间了。
我通常是把vmware的虚拟机器目录放到E盘的vmware_OS目录中,这个目录是几百GB的大家伙。
当我把xFsRedir的监控目录挂载到E盘的某个其他目录上的时候,
然后启动vmware,开启两个虚拟机系统, 同时访问xFsRedir挂载的E盘的监控目录,
整个系统发生了死锁,系统依然能运行,就是一旦访问E盘的任何文件,就死等在那里。
后来因为没时间解决,就避开了这个问题,别让xFsRedir挂载E盘的任何目录。

这次的更新,想着要解决这个大麻烦。
 vmware毕竟是底层软件,调用底层的API很多,可能某些API的调用使得xFsRedir出现了问题。
首先想到的就是因为文件操作发生了死等,那多半我的xfs_redir.sys驱动中的全局锁发生了死锁。
以前的介绍文件过滤驱动实现目录重定向原理的文章说过的,xFsRedir实现的目录重定向是拦截FILE_OBJECT文件对象指针,
FILE_OBJECT对象是系统全局性的,我们必须把它和我们自己定义的结构通过MAP结构存储起来,因此使用全局锁是不可避免的。
xfs_redir.sys驱动中只有一把全局锁,而且对整个IO操作都是通过这把全局锁锁定的。
因此一开始就想到,可能是在全局锁锁定的某段代码中调用了某个系统函数,
而这个系统函数执行了某些操作,再次进入了我们的派遣回调函数或者其它回调函数中,回调函数会再次请求全局锁,于是死锁发生了。
因为找不到究竟是哪些系统函数会发生这种行为,于是打算把所有的系统函数调用都放到全局锁之外执行。
也包括IoCompleteRequest完成IRP的系统函数。
这种改动可不是小改动,因为以前开发代码的时候,好多的系统函数都是在全局锁里边调用的,
因为也是没办法,放到外边执行容易引起同步竞争问题。
花了N多天的时间,几乎是把代码重整了一遍,自信是把几乎所有的系统函数调用都放到全局锁外边来执行了,
相信这次能让xFsRedir和vmware愉快的共存了,然而,结果依然一样,这次不但会与vmware发生死锁,还同时引发了其他问题,
系统动不动就蓝屏,或者来个莫名其妙的 BSOD,就是非常不稳定。
没办法,只能恢复到以前的版本,好在我在每次修改代码前都做了备份。
满满的自信被严重打击了,于是一度想放弃解决这个问题,对外标注xFsRedir与vmware不能共存好了。
可是心有不甘,于是又在代码上胡乱涂改,
(不是不做在线BUG调试,而是这种问题极度难调试,就跟内存出现问题一样,可能比内存出现问题还难寻找)
再后来没办法了,干脆换种思路,把原来认为对的代码,再换种别的做法试试。
首先要换的就是全局锁的加锁方式:
我原来使用的是ERESOURCE资源锁加锁的,使用 ExAcquireResourceExclusiveLite 系统函数 来实现独占访问,
根据MSDN文档描述的,资源锁加锁之前,需要调用 FsRtlEnterFileSystem 来屏蔽APC调用。
这次修改的时候直接换成了FAST_MUTEX 互斥锁,因为FastMutex 自己会屏蔽APC调用,所以也无需调用FsRtlEnterFileSystem 。
就只是换成了FastMutex全局锁,其他的还是原来的代码。
结果xFsRedir居然能与vmware愉快的共存了。

这是什么原因呢?非常迷惑,
只好再次仔细查询MSDN文档描述,发现了FastMute下和ERESOURCE有个区别,
虽然 调用 ExAcquireResourceExclusiveLite 之前调用FsRtlEnterFileSystem函数能屏蔽User APCs和kernel normal APCs,
但是无法屏蔽 kernel special APCs。
而FastMutex是屏蔽所有APCs的执行。
于是这么大胆的推测:
在我以前的 被ERESOURCE全局锁加锁的代码片段中,在执行的时候,被kernel special APCs 打断,
(因为FsRtlEnterFileSystem 无法屏蔽 kernel special APCs的执行。)
CPU转去执行 kernel special APCs中的代码,结果这个代码有可能会再次调用我们驱动中的回调函数,
回调函数会再次请求ERESOURCE全局资源锁,而这个kernel special APCs代码与之前已经被加锁的代码不再同一个线程执行。
于是死锁发生了。
可能是以前的windows版本和以前的vmware版本几乎没有引发kernel special APCs调用,所以不会出现问题,
而新的win10版本或新vmware版本,调用了某些特殊API函数,刚好引发了 kernel special APCs调用,而且引发了上面描述的死锁情景。

解决了这个问题,再到后来打算修改全局锁的行为,
因为xfs_redir.sys就一把全局锁,同时处理 FILE_OBJECT对象指针的映射和查找,以及每个监控目录下的所有IO请求。
这次修改也是很能折腾的,先是放的太开了,就如上面提到的,先是把全部系统函数都放到没有锁的地方执行,
结果,还是和上面的一样,系统非常不稳定,容易蓝屏。
没办法,经过多次折腾,把全局锁换成了两种锁:
对FILE_OBJECT的映射和查找,依然是FastMutex全局锁处理,然后每个监控目录下,都有一个FastMutex锁,专门锁定IO请求的处理。
同时IO锁也并不放开,该在IO锁里边调用的系统函数,还是必须在IO锁里边调用。

经过这么长时间的折腾,已经是精疲力尽了。对windows的文件系统的处理就是个大麻烦!
(至于新版本的驱动是否还会引发其他问题,只好等待时间去验证了。)
然后再回到虚拟磁盘驱动的处理,感觉就是个小儿科一样的事情,太轻松了。

这次打算添加iSCSI的支持,实现iSCSI磁盘,其实只需要在应用层添加iSCSI通讯协议就可以了。
虚拟磁盘驱动还是使用原来已经开发好的扩展虚拟磁盘驱动就可以了。
不过这次开发应用层iSCSI协议的的时候,因为在服务端安装了某个不知道哪的iSCSI服务端,造成调试的时候,
请求的扇区数据长时间无法返回,或者说是网络通讯死等在那里,
结果我的机器居然蓝屏了!由网络通讯不畅引发蓝屏,肯定是虚拟磁盘驱动的问题了。
然后调试扩展虚拟磁盘驱动得知,是由于太长时间没回复,windows系统已经发送请求取消了SRB数据块,
但是我的驱动中没没有处理这个取消请求,造成了系统蓝屏。
于是赶紧修改这个BUG,这是目前发现的扩展虚拟磁盘驱动的唯一BUG。
不过对应 本地镜像文件和 \\Server\\Share\image.img 方式访问的SMB文件,
驱动中依然没处理这个取消请求,因为应该不会发生这种超时太长的问题,
如果不放心,可以使用应用层的SMB协议代替 \\Server\Share\的方式。

iSCSI应用层的通讯协议依然得感谢 Ronnie Sahlberg 作者。

如果对xFsRedir有兴趣,可以去GITHUB(https://github.com/fanxiushu)下载使用,最新版本稍后会发布上去。
4以上的新版本,增加了桌面LOGO,以及版权声明文件,如果带来不便,敬请谅解。

下图是新版本中,提供了 查询private协议和iSCSI协议服务端的虚拟磁盘列表,也就是能自动查询服务端的虚拟磁盘。

windows平台xFsRedir目录重定向程序2020年更新_第2张图片


 

你可能感兴趣的:(windows,驱动开发,文件系统,windows,驱动程序,文件系统)