1.      Dokan Library 简介

Dokan Library 帮助程序员在windows系统下轻松建立用户级文件系统,不需要写设备驱动,其与FUSE(Linux user mode file system)类似。

2.      Dokan原理

Dokan Library包含以下部分:   
- user-mode library (dokan.dll)  LGPL    
- driver (dokan.sys)             LGPL    
- control program (dokanctl.exe) MIT    
- mount service (mouter.exe)     MIT    
- samples (mirror.c)             MIT

dokan.sys是内核态文件系统驱动,当此驱动安装之后,就可以创建自己的文件系统了。而我们创建文件系统(实现Dokan库的API)的程序称为文件系统程序。这时,程序提出的文件操作请求(例如CreateFile, ReadFile, WriteFile)就会送到Windows I/O subsystem (内核中运行),后者会继续将请求送到dokan.sys。文件系统程序可以利用dokan.dll提供的函数将我们的回调函数(操作实现函数)注册到dokan.sys中,后者会在收到请求之后调用这些我们提供的函数。回调函数的结果会送回提出请求的程序。(可参见图一)

dokan.sys 相当于一个运行在内核态的代理,作为提出请求的程序和我们实现各种操作的文件系统程序的桥梁。至此,我们程序员就可以在用户态轻松的创建调试文件系统程序,大大提高了开发效率。

3.      创建文件系统

与FUSE类似,我们的文件系统程序需要实现一个结构体中的各个操作DOKAN_OPERATIONS(声明在dokan.h中),然后该结构体作为参数调用DokanMain挂载文件系统。这些函数的参数与Windows APIs 一致,但必须做到线程安全,因为有可能有多个线程调用。

这些函数有个典型的调用顺序:   
1. CreateFile(OpenDirectory, CreateFile)    
2. Other functions    
3. Cleanup    
4. CloseFile

file creation functions (OpenDirectory, CreateFile,…)总是在file access operations (listing directory, reading file attributes, …)之前调用。当文件被CloseFile Windows API关闭时,Cleanup程序总是被dokan.sys调用。

返回值为0时表示操作成功。

每个函数的最后一个参数是DOKAN_FILE_INFO structure

typedef struct _DOKAN_FILE_INFO {

ULONG64 Context;     //文件系统程序维护,可作为文件句柄

ULONG64 DokanContext;  //Dokan Library维护

ULONG ProcessId;   //操作ID

BOOL IsDirectory;  //目录= TRUE

} DOKAN_FILE_INFO, *PDOKAN_FILE_INFO;

每一个文件句柄都与一个DOKAN_FILE_INFO struct对应。该结构创建在文件被CreateFile系统调用打开时,回收在文件被CloseFile系统调用关闭时。

下面是几个操作的声明:

int (*CreateFile) (

LPCWSTR,      // FileName

DWORD,        // DesiredAccess

DWORD,        // ShareMode

DWORD,        // CreationDisposition

DWORD,        // FlagsAndAttributes

PDOKAN_FILE_INFO);

int (*OpenDirectory) (

LPCWSTR,          // FileName

PDOKAN_FILE_INFO);

int (*CreateDirectory) (

LPCWSTR,          // FileName

PDOKAN_FILE_INFO); //注意设置IsDirectory = TRUE

//CloseHandle ( Windows API)执行之后调用,如果文件句柄在//CreateFile中创建,应该在此释放,而不是在CloseFile。

//如果用户在内存中缓存了文件,调用Cleanup之后还有可能调用读写//操作。

int (*Cleanup) (

LPCWSTR,      // FileName

PDOKAN_FILE_INFO);

//如果用户调用CloseHandle后再打开相同文件,CreateFile之前可能//不会再调用CloseFile,这可能会出共享错误。

int (*CloseFile) (

LPCWSTR,      // FileName

PDOKAN_FILE_INFO);

int (*FindFiles) (

LPCWSTR,           // PathName

PFillFindData,     // call this function with PWIN32_FIND_DATAW

PDOKAN_FILE_INFO); //  (see PFillFindData definition)

// You should implement either FindFires or FindFilesWithPattern

int (*FindFilesWithPattern) (

LPCWSTR,           // PathName

LPCWSTR,           // SearchPattern

PFillFindData,     // call this function with PWIN32_FIND_DATAW

PDOKAN_FILE_INFO);

上面两个函数是回应列目录项操作请求的。对每一个目录项,文件系统程序都会调用函数FillFindData( &win32FindDataw,  DokanFileInfo )。由于Windows的shell对于模式匹配不支持,文件系统程序就要执行通配模式。当文件系统程序实现FindFiles,DokanLibrary会自动添加通配模式,我们也可以自己实现FindFilesWithPattern来加以控制。DokanIsNameInExpression (dokan.dll)函数就是用来实现模式匹配的。

4.      挂载

前面已经提到,可以调用DokanMain函数来挂载文件系统。该程序会阻塞到文件系统被卸载。

我们的文件系统要做两件事,一是为Dokan运行库填写DokanOptions,二是填写带各个操作函数指针的DokanOperations作为DokanMain的参数。

int DOKANAPI DokanMain(

PDOKAN_OPTIONS    DokanOptions,

PDOKAN_OPERATIONS DokanOperations);

typedef struct _DOKAN_OPTIONS {

USHORT Version;  // Supported Dokan Version, ex. "530" (Dokan ver 0.5.3)

ULONG ThreadCount;  // number of threads to be used

ULONG Options;      // combination of DOKAN_OPTIONS_*

ULONG64 GlobalContext;  // FileSystem can use this variable

LPCWSTR MountPoint;     // mount point "M:\" (drive letter) or

// "C:\mount\dokan" (path in NTFS)

} DOKAN_OPTIONS, *PDOKAN_OPTIONS;

5.      卸载

调用 DokanUnmount进行文件系统的卸载。用户也可以使用 DokanCtl 像这样进行卸载:

> dokanctl.exe /u DriveLetter

 
 

Dokan简介[转]的更多相关文章

  1. ASP.NET Core 1.1 简介

    ASP.NET Core 1.1 于2016年11月16日发布.这个版本包括许多伟大的新功能以及许多错误修复和一般的增强.这个版本包含了多个新的中间件组件.针对Windows的WebListener服 ...

  2. MVVM模式和在WPF中的实现(一)MVVM模式简介

    MVVM模式解析和在WPF中的实现(一) MVVM模式简介 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在 ...

  3. Cassandra简介

    在前面的一篇文章<图形数据库Neo4J简介>中,我们介绍了一种非常流行的图形数据库Neo4J的使用方法.而在本文中,我们将对另外一种类型的NoSQL数据库——Cassandra进行简单地介 ...

  4. REST简介

    一说到REST,我想大家的第一反应就是“啊,就是那种前后台通信方式.”但是在要求详细讲述它所提出的各个约束,以及如何开始搭建REST服务时,却很少有人能够清晰地说出它到底是什么,需要遵守什么样的准则. ...

  5. Microservice架构模式简介

    在2014年,Sam Newman,Martin Fowler在ThoughtWorks的一位同事,出版了一本新书<Building Microservices>.该书描述了如何按照Mic ...

  6. const,static,extern 简介

    const,static,extern 简介 一.const与宏的区别: const简介:之前常用的字符串常量,一般是抽成宏,但是苹果不推荐我们抽成宏,推荐我们使用const常量. 执行时刻:宏是预编 ...

  7. HTTPS简介

    一.简单总结 1.HTTPS概念总结 HTTPS 就是对HTTP进行了TLS或SSL加密. 应用层的HTTP协议通过传输层的TCP协议来传输,HTTPS 在 HTTP和 TCP中间加了一层TLS/SS ...

  8. 【Machine Learning】机器学习及其基础概念简介

    机器学习及其基础概念简介 作者:白宁超 2016年12月23日21:24:51 摘要:随着机器学习和深度学习的热潮,各种图书层出不穷.然而多数是基础理论知识介绍,缺乏实现的深入理解.本系列文章是作者结 ...

  9. Cesium简介以及离线部署运行

    Cesium简介 cesium是国外一个基于JavaScript编写的使用WebGL的地图引擎,一款开源3DGIS的js库.cesium支持3D,2D,2.5D形式的地图展示,可以自行绘制图形,高亮区 ...

随机推荐

  1. cobbler 奇葩出错

    写此随笔,只是为了记录我安装cobbler遇到的奇怪问题,虽然这个问题很让我无语,但是竟然折腾了我一天.废话不多说,入题: 一如既往的按照以前的安装方式安装cobbler,不会出错的地方我就一带而过了 ...

  2. js实现复制内容

    一.实现点击按钮,复制文本框中的的内容                         <script type="text/javascript"> function ...

  3. 国内首家MR头显公司于CES惊艳亮相

    在刚刚过去的CES2017大会上,我们看到了许多较为优秀的VR产品,而在这里面,有一家名不见经传的中国公司易瞳发布了一款兼具VR和AR功能的头显VMG-MARK.它的外观与联想VR和骁龙VR820等产 ...

  4. 解码红外遥控信号——使用遥控器的按键来调节LED的亮度

    程序开始时,提示遥控键0~4的代码,然后程序通过设置LED的亮度来对被按下的按钮作出响应,以0关闭LED,1~4提供增加的亮度. 代码如下:(需要使用IRremote库,可在库管理中搜索该库进行下载后 ...

  5. Linux学习初步

    centOS 6.5关闭防火墙步骤  关闭命令:  service iptables stop         永久关闭防火墙:chkconfig iptables off两个命令同时运行,运行完成后 ...

  6. 用CSS实现文本框尖角

    经常看到这样的尖角,以前不懂,以为都是用图片做出来的,后来惊奇的发现,原来很多都是用CSS做出来的,既美观又节省资源,真是两全其美啊! 那么,用CSS怎么实现这种效果呢?首先,来写一个简单的代码: & ...

  7. 【IE6的疯狂之七】样式中文注释后引发失效

    这是IE6 出现的奇怪现象.这是由于css 和html 的编码不同所引致. 满足下面条件就会引起 注释下面的样式不起作用:1. css有中文注释2. css为ANSI编码3. html为utf-8编码 ...

  8. 拒绝深坑!记录找了多半天时间的C++编译失败的错误

    采用新的源码,和原来的服务改动也不是很大,但是拒绝深坑啊,找了半天以为是源码的问题,结果倒好原来是环境的问题,还是要感谢一个神一样的人物的帮助 编译的时候一直出现undefined reference ...

  9. js的严格模式

    严格模式: 严格模式这下的主要区别如下: 严格模式下的好处:

  10. cocos2dx 举例说明 convertToNodeSpace 与 convertToWorldSpace 的使用

    convertToNodeSpace:把世界坐标转换到当前节点的本地坐标系中. //可以应用于判断子节点是否被点击,这时就需要把坐标从世界坐标系转换为父节点的坐标系. //当然大多数情况会用CCMen ...