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

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就罢工了,它会以为当前磁盘是不稳定的,或者容量比较用光,而拒绝保存。

利用dokan作虚拟磁盘开发的更多相关文章

  1. [Python] 利用Django进行Web开发系列(一)

    1 写在前面 在没有接触互联网这个行业的时候,我就一直很好奇网站是怎么构建的.现在虽然从事互联网相关的工作,但是也一直没有接触过Web开发之类的东西,但是兴趣终归还是要有的,而且是需要自己动手去实践的 ...

  2. [Python] 利用Django进行Web开发系列(二)

    1 编写第一个静态页面——Hello world页面 在上一篇博客<[Python] 利用Django进行Web开发系列(一)>中,我们创建了自己的目录mysite. Step1:创建视图 ...

  3. Web API应用架构在Winform混合框架中的应用(4)--利用代码生成工具快速开发整套应用

    前面几篇介绍了Web API的基础信息,以及如何基于混合框架的方式在WInform界面里面整合了Web API的接入方式,虽然我们看似调用过程比较复杂,但是基于整个框架的支持和考虑,我们提供了代码生成 ...

  4. php利用zookeeper作dispatcher服务器

    ===== https://blog.eood.cn/php_share_memory 最常见的apc 可以缓存php的opcode提高应用的性能,可以在同个php-fpm进程池间共享数据 常见功能: ...

  5. 跟我一起学WCF(2)——利用.NET Remoting技术开发分布式应用

    一.引言 上一篇博文分享了消息队列(MSMQ)技术来实现分布式应用,在这篇博文继续分享下.NET平台下另一种分布式技术——.NET Remoting. 二..NET Remoting 介绍 2.1 . ...

  6. 转载:如何利用Vim进行Erlang开发

    转自:http://ovalpo.info/how_to_use_vim_for_erlang_dev/ 如何利用Vim进行Erlang开发 by Martin J. Logan on Septemb ...

  7. 利用Sails.js+MongoDB开发博客系统

    http://yoyoyohamapi.me/categories/利用Sails-js-MongoDB开发博客系统/ 利用Sails.js+MongoDB开发博客系统 Apr 14, 2016 利用 ...

  8. 利用connect建立前端开发服务器

    利用connect建立前端开发服务器 对于前后端完全分离的系统,开发时候我们需要给前端配置服务器,当然我们可以选择Nginx之类的服务器进行配置,但我们也能使用NodeJS构建高自由度的前端开发服务器 ...

  9. Microsoft Tech Summit 2018 课程简述:利用 Windows 新特性开发出更好的手绘视频应用

    概述 Microsoft Tech Summit 2018 微软技术暨生态大会将于10月24日至27日在上海世博中心举行,这也会是国内举办的最后一届 Tech Summit,2019 年开始会以 Mi ...

随机推荐

  1. 第13章 Swing程序设计

    1.Swing概述 GUI(图形用户界面)为程序提供图形界面,最初的设计目的是为程序员构建一个通用的GUI,使其能够在所有平台上运行.但Java 1.0中基础类AWT(抽象窗口工具箱)并没有达到这个要 ...

  2. sql server两种分页方法

    方法一: --分页方法一 OrderID,CustomerID, EmployeeID,OrderDate,ShippedDate,ShipName,ShipAddress,Freight from ...

  3. 安装MSYS2过程遇到的问题及解决记录

    1.在安装结束后按照官方教程开始更新系统是遇到了如下的错误 could not open file /var/lib/pacman/sync/msys32.db: Unrecognized archi ...

  4. 页面开发辅助类—HtmlHelper初步了解

    1.1 有失必有得 在ASP.Net MVC中微软并没有提供类似服务器端控件那种开发方式,毕竟微软的MVC就是传统的请求处理响应的回归.所以抛弃之前的那种事件响应的模型,抛弃服务器端控件也理所当然. ...

  5. Gym 100917L Liesbeth and the String 规律&&胡搞

    题目: Description standard input/outputStatements Little Liesbeth likes to play with strings. Initiall ...

  6. phpstudy 安装memcached服务和memcache扩展

    memcached安装步骤: 首先,将下载好的memcahed解压到某个文件目录下,例如 C:\memcached 然后,在cmd里,输入"C:\memcached\memcached.ex ...

  7. XAMPP(v1.83)中的PHP(v5.5.15)访问SQLServer2014

    驱动安装: 1. 下载SQLServer的微软官方PHP驱动,http://msdn.microsoft.com/en-us/sqlserver/ff657782.aspx 2. 安装SQLSRV31 ...

  8. 默认系统为UEFI启动的GPT分区的WIN7(8),如何安装VHD的UEFI WIN8(7)

    默认系统为UEFI启动的GPT分区的WIN7(8),如何安装VHD的UEFI WIN8(7) 情况A:如果默认系统为UEFI启动.GPT分区的WIN7,想安装个VHD的UEFI WIN8.1 1:系统 ...

  9. android Actionmode 样式自定义

    <style name="Base.Theme.DesignDemo" parent="Theme.AppCompat.Light.NoActionBar" ...

  10. as3 公式

    AS3缓动公式:sprite.x += (targetX - sprite.x) * easing;//easing为缓动系数变量sprite.y += (targetY - sprite.y) * ...