当前位置:  软件>C/C++软件

用户态的文件系统驱动 dokan

    来源:    发布时间:2015-02-04

    本文导语:  dokan是用户态的文件系统驱动,可以称之为fuse for windows。可以用来开发虚拟磁盘,即在“我的电脑”中虚拟出一个硬盘来,可以是硬盘,也可以是可移动磁盘或者网络硬盘。 CreateFile、FindFiles、GetFileInformation需要最优先实现,...

dokan是用户态的文件系统驱动,可以称之为fuse for windows。可以用来开发虚拟磁盘,即在“我的电脑”中虚拟出一个硬盘来,可以是硬盘,也可以是可移动磁盘或者网络硬盘。

用户态的文件系统驱动 dokan[图片]

CreateFile、FindFiles、GetFileInformation需要最优先实现,有了这两个接口,就可以浏览目录了。

进入CreateFile,需要判断请求的虚拟文件是目录还是文件,如果是目录,则需要设置 DokanFileInfo->IsDirectory为True,并直接返回成功。虚拟文件的打开可以根据 CreationDisposition、AccessMode、ShareMode三者组合。最简单的做法是在最开始处对做判断,因为它只有五种可能 性,把文件不存在,但却需要以只读打开的都排除,然后就可以放心地应用:读使用”rb+”, 写使用”wb+”。

Create中返回的文件描述符或者类似的数据可以保存DokanFileInfo->context中,这个值可以在以后的其它函数调用中 访问到:比如CloseFile, CleanUp, DeleteFile, ReadFile, WriteFile等等。

CreateDirectory和实际的文件操作一致。
OpenDirectory一般直接返回成功,除非目录无访问权限,可以人为地返回-1。
CloseFile用处不大,因为在CloseFile之前,有一道CleanUp调用,已经清除了打开的文件。
CleanUp和CloseFile好像会被一前一后地调用,在CleanUp中需要做的事情是根据DokanFileInfo->context 保存的值关闭虚拟文件。并且DokanFileInfo->DeleteOnClose如果为True,则需要把当前请求的文件或者目录删除。文件 删除的动作实际是在Cleanup中实现的。

DeleteDirectory和DeleteFile两个接口实现中,不能够真正去删除文件,而是在文件或者目录需要删除时,返回0即可,系统会继续调用上面说的cleanup来处理删除事件。

在文件的删除时,有可能操作系统传递过来的请求文件并未被关闭,但好在同时DokanFileInfo->context也会被一同传递来,所以可以先强行关闭打开的文件,然后做删除操作。

操作系统的应用程序每次读写文件都是通过ReadFile、WriteFile接口完成的,一般情况下一次求请的大小比较小,比如 65535Bytes等,但也有例外,比如使用FastCopy等多线程文件快速复制工具时,它会直接向ReadFile请求32MB的大小。

ReadFile WriteFile一般情况下都会有DokanFileInfo->context参数传进来,就像平常我们写文件读写的代码一样,总是先 fopen个FILE*出来,然后再读写。 但是也有例外,比如记事本在读文件的时候,就只是给个路径+文件名。 这个时候,需要在ReadFile WriteFile临时专门为这一次请求打开文件,在退出函数时,一定要关闭它。

FlushFileBuffers是个没用的东西,可以不实现。

GetFileInformation非常重要,资源管理器每次打开目录时,会查询当前目录每个文件的信息。如果给出的信息不恰当,比如文件时间如 果是个变化的值(比如图省事,将所以文件的时间设置为当前时间),这样会导致系统不断地查询,非常的恐怖。 在返回的dwFileAttributes中,需要小心地设置文件类型,文件和目录千万要区别正确。 试过FILE_ATTRIBUTE_NORMAL+FILE_ATTRIBUTE_ARCHIVE-FILE_ATTRIBUTE_ENCRYPTED以 及FILE_ATTRIBUTE_DIRECTORY就基本正常工作了,FILE_ATTRIBUTE_ENCRYPTED一定要去掉,不然系统会认为你 虚拟出来的盘符是加密的,往其它盘复制文件时会提示不能处理加密文件而直接失败。

FindFiles函数中,我们需要用传递进来的函数指针FillFindData将我们需要显示的目录和文件填充到系统为我们准备好的地方。只要 文件的属性dwFileAttributes像样,可以构造虚拟文件和目录(比如可以将数据库里的用户和组记录读出来,表示成一层层的目录)。

MoveFile就是移动文件及改名,没什么特殊的地方。

SetEndOfFile一般情况下使用不到,但是如果有软件调用了这个API则还是有用的,比如像fastCopy,为了尽可能地加快复制速度, 它每次从内存将固定大小的数据保存到硬盘,比如大小为31MB的文件,实际上它写了32MB(文件尾部的数据其实是多余的),这是用readFile WriteFile实现的。但它最后会根据原文件的真实大小来做一次setEndOfFile将其裁剪到正确的大小。如果不实现 setEndOfFile,fastcopy就没用了。

SetFileAttributes和SetFileTime如果不想实现,就让它返回0,最好不要为了禁用这两个api.因为像Word之类的软 件,它很在意这两个函数,在保存文件时候不厌其烦地调用,所以为了让Word在虚拟盘上工作正常,必须忽悠它,否则不能保存做过编辑的文档。

GetDiskFreeSpace是返回驱动器的容量信息的,比如虚拟盘可以做容量限制。
GetVolumeInformation返回驱动器的卷标和文件系统类型,可以随便设置,文件类型可以随便取名,比如“XX文件系统”,和NTFS/FAT32是同等地位的。

GetFileInformation 有时候传递过来的DokanFileInfo->context不是空的,所以一定要使用它来查询文件大小。 假设DokanFileInfo->context保存的是fopen打开的fd, 如果使用传递过来的文件名去GetFileAttribute或者Stat()真实文件,有可能会因为缓存的缘故查询到的文件大小不是实时的。这一点在对 文件大小变化敏感的软件上特别重要,比较变态的Word,在保存的时候,它会先保存到临时文件,保存过程中,写一点数据,马上查询文件大小是否有变化是否 和写的数据大小一致。如果这时GetFIleInformation马马虎虎地返回个大小,Word就罢工了,它会以为当前磁盘是不稳定的,或者容量比较 用光,而拒绝保存。


    
 
 

您可能感兴趣的文章:

  • UIO(linux Userspace I/O子系统)用户空间设备驱动I/O技术介绍
  • 请问做好的驱动,发布给用户的时候,用户必须要在各自的Linux中重新编译驱动源码才能使用吗?
  • 请教用户空间编写设备驱动
  • linux下怎么些用户态的驱动?
  • 内核驱动如何同步发消息给用户
  • 讨论:内核,驱动,用户空间大批量数据交换的最佳方式
  • 用户程序的ioctl是怎么和驱动程序中的ioctl实现联系
  • 请问用户态与驱动传参数除了用file_operations这个结构外还有其他方法么
  • 请问如何传用户空间数组到驱动程序?
  • 如何使用USB设备的驱动来写用户程序?(主要考虑 如何控制与读写数据)
  • 驱动中如何将用户空间内存映射到内核空间使用?
  • (请来拿分) 内核态驱动的中断里怎么发信号给用户程序?
  • 还是不懂,驱动到底如何能同步的发送信号给用户程序,请教高人,谢谢了
  • 有人做过内核空间和用户空间的内存映射吗 内核空间和用户空间交换数据用内存映射的方法,结果做的驱动可以工作,但经常会引起死机
  • 刚开始学写驱动,请大家帮我看一下,ioremap上后怎么降数据拷贝到用户空间??
  • 请问驱动程序里怎么得到用户空间地址对应的物理地址?
  • 我在一个字符设备写了一些方法,read,write等,我在用户层使用这些系统调用的时候怎么用到我这个字符设备驱动所定义的??
  • 为什么装了NVida显卡驱动我的Mplayer用Root可以播放,但用普通用户却不行呢
  • ubuntu 中 使用 root 用户 mount 一个文件夹后,一般用户怎么访问这个文件加?
  • linux下的FTP登陆后进入到用户文件夹,怎么样配置才能让这个用户可以访问任意的文件夹
  • 在linux下,一个用户如果从另一个用户的文件夹下获取文件?
  • 我是想写批处理文件将一个文件myfile自动拷到用户的 windowssystem 下,但不知用户的windows在c: 还是其他盘,我改怎做???
  • 利用root用户修改一般用户密码的批处理文件怎么写呢?
  • Solaris中添加了新用户后,该用户的默认文件夹在哪里啊?
  • linux 新建用户后,在用户目录下没有.bash_profile文件生成
  • 请教各位!我以普通用户身份进入x window 部份文件夹被锁住了!以root用户就没问题。如何解决??
  • linux6.0下安装oracle11g, 新建用户后,在用户目录下为什么没有.bash_profile文件生成? 求教高手。谢谢!
  • 文件或文件夹,如何指定某用户的读写权限?
  • 救命呀,LINUX删除用户操作后,我的WINDOWS文件系统文件丢失了!在线等!
  • 急问:在linux里面怎么察看一个文件夹或文件有哪些用户在使用?
  • 怎样用chown改变目录的所属用户和组时,怎样把这个目录下的子目录和所有子目录里的文件的所属用户和组都同时该了啊
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • windows 系统是否是多用户操作系统,如何理解“多用户操作系统”的“多用户”?
  • 用户无法设定默认的系统文本编辑器。本地管理员如何协助该用户确定系统默认的文本编辑器?
  • 使用Linux/UNIX的系统用户进行PHP用户登录验证 iis7站长之家
  • 使用Linux/UNIX的系统用户进行PHP用户登录验证
  • linux系统中建立一个用户专门用来修改系统时间怎么做?
  • 如何查看系统中有多少个组?有多少个用户?如何把指定用户加到指定组中?
  • 我装了中软Linux3.1,启动时要求输入用户名和口令,但安装时并没有提示指定用户名,所以现在输入用户名老是错误,不能进入系统,请问该怎
  • proftpd安装后匿名用户和系统用户都无法连接
  • 我的redhat安装好后,从其他系统居然不能以root用户telnet登陆,以普通用户就可以,怎么办?
  • 急!请教高手:在Solaris系统中,对于远程telnet方式,发现只有root用户登录成功,其他用户不能登录,报no shell错误,是什么原因?
  • 求助!centOs系统root用户连接ftp失败,别的用户连接ftp成功?
  • RED HAT 9.0系统 如何访问 局域网 windows XP 的用户,并通过XP用户机上网.
  • 请教如何让Samba用户,, 不能登陆系统?
  • 请问怎么知道系统下有哪几个用户?
  • linux查看当前系统用户的总数以及shell数量
  • rh7.2系统的默认的用户
  • oracle+jsp 多用户查询系统讨论:
  • LINUX下获取WINDOWS用户(组)和系统服务?
  • SCO UNIX中如何telnet可以不受系统用户数目限制?
  • 多用户博客系统 Textcube
  • Linux常用命令介绍:更改所属用户群组或档案属性
  • 概念混乱,请专人解释:实际用户ID,有效用户ID,设置用户ID
  • Linux进程的内核栈和用户栈概念,相互关系及切换过程
  • proftp中,如何让FTP的用户是非Linux用户,只是FTP用户?
  • CentOS安装Telnet,以root用户登陆Telnet以及CentOS的各种终端解释
  • 我装的是RED HAT LINUX 8.0,我在root用户中把root用户删除了,怎办也进不了root用户
  • 怎样让普通用户拥有超级用户的权限,是把普通用户的组设为root组吗?具体怎么做,急死了
  • 我一个服务器同时接受到很多个用户的认证请求(得到用户名和密码),然后把用户名密码发给认证服务器。因为是远程认证,所
  • root用户附权限给其他用户问题
  • 如何添加一个用户,让这个用户只能访问某个特定的目录,
  • 匿名用户登录nobody用户的作用


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3