原始帖子:http://www.aiseminar.cn/bbs/forum.php?mod=viewthread&tid=1825
Dokan Library 帮助程序员在windows系统下轻松建立用户级文件系统,不需要写设备驱动,其与FUSE(Linux user mode file system)类似。
Dokan官网:
http://dokan-dev.github.io
https://github.com/dokan-dev/dokany
备注: 原dokan-dev.net域名已废弃
如果您想在Windows系统上创建一个新的文件系统的话,例如:改进FAT或NTFS文件系统,您就需要自己开发一个文件系统驱动。在Windows系统上开发工作在内核模式的设备驱动程序是一件极为困难的事情。使用Dokan库(Dokan Library),您可以非常方便地创建自己的文件系统而不需要编写设备驱动程序。Dokan库类似于Linux下的FUSE用户空间文件系统,但是它工作在Windows下。
Dokan原理
Dokan Library包含以下部分:
Dokan库包含一个用户模式的DLL文件(dokan.dll)以及一个内核模式文件系统驱动(dokan.sys)。Dokan文件系统驱动一旦安装,您就可以在Windows上创建和普通文件系统一样的文件系统。使用Dokan库创建的文件系统的应用程序称为文件系统应用程序。来自用户程序的文件操作请求(例如:CreateFile,ReadFile,WriteFile等)将被发送的 Windows输入/输出子系统(运行在内核模式),请求之后将被发送到Dokan文件系统驱动程序(dokan.sys)。通过使用Dokan用户模式库文件(dokan.dll)提供的函数,文件系统应用程序能够向文件系统驱动程序注册回调函数。文件系统驱动程序在收到请求后调用注册的回调函数例程来响应请求。回调函数例程的处理结果将返回给用户程序。
例如:当Windows资源管理器请求创建一个目录,请求“OpenDirectory”将发送到 Dokan文件系统驱动程序,然后驱动程序将调用文件系统应用程序提供的OpenDirectory回调函数例程。函数例程的处理结果作为 OpenDirectory请求的响应返回给Windows资源浏览器。如此一来,Dokan文件系统驱动程序就如同一个位于用户程序和文件系统程序之间的代理程序。使用Dokan库的好处是,它允许程序员开发更安全也更容易调试的用户空间文件系统。
SSHFS(SSH文件系统)是一个文件系统客户端程序,使用它可以将远程服务器上的目录挂载在本地直接访问。先前的版本用于输出SFTP提供的目录和文件,而当前的版本主要用于安装有FUSE的系统上。在用户访问服务器资源的过程中,数据通过SSH加密传输,安全而高效。 Dokan是FUSE的Windows实现,使用Dokan SSHFS可以将Linux服务器上的目录以网络盘的形式挂载到本地使用,类似于Samba。要使用Dokan SSHFS需要首先安装Dokan Library,它们可以在Dokan官方网站下载。
与FUSE类似,我们的文件系统程序需要实现一个结构体中的各个操作DOKAN_OPERATIONS(声明在dokan.h中),然后该结构体作为参数调用DokanMain挂载文件系统。这些函数的参数与Windows APIs 一致,但必须做到线程安全,因为有可能有多个线程调用。这些函数有个典型的调用顺序:
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系统调用关闭时。下面是几个操作的声明:
DWORD, // DesiredAccess
DWORD, // CreationDisposition
DWORD, // FlagsAndAttributes
PDOKAN_FILE_INFO); //注意设置IsDirectory = TRUE
//CloseHandle ( Windows API)执行之后调用,如果文件句柄在
//CreateFile中创建,应该在此释放,而不是在CloseFile。
//如果用户在内存中缓存了文件,调用Cleanup之后还有可能调用读写
//如果用户调用CloseHandle后再打开相同文件,CreateFile之前可能
//不会再调用CloseFile,这可能会出共享错误。
PFillFindData, // call this function with PWIN32_FIND_DATAW
PDOKAN_FILE_INFO); //(see PFillFindData definition)
// You should implement either FindFiles or FindFilesWithPattern
int (*FindFilesWithPattern) (
LPCWSTR, // SearchPattern
PFillFindData, // call this function with PWIN32_FIND_DATAW PDOKAN_FILE_INFO);
上面两个函数是回应列目录项操作请求的。对每一个目录项,文件系统程序都会调用函数FillFindData( &win32FindDataw,DokanFileInfo )。由于Windows的shell对于模式匹配不支持,文件系统程序就要执行通配模式。当文件系统程序实现FindFiles,DokanLibrary会自动添加通配模式,我们也可以自己实现FindFilesWithPattern来加以控制。DokanIsNameInExpression (dokan.dll)函数就是用来实现模式匹配的。
可以调用DokanMain函数来挂载文件系统,该程序会阻塞到文件系统被卸载。我们的文件系统要做两件事,一是为Dokan运行库填写DokanOptions,二是填写带各个操作函数指针的DokanOperations作为DokanMain的参数。
PDOKAN_OPTIONS DokanOptions,
PDOKAN_OPERATIONS DokanOperations);
typedef struct _DOKAN_OPTIONS {
USHORTVersion;// 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;
用户也可以使用 DokanCtl 像这样进行卸载:dokanctl.exe /u DriveLetter
Refered to:
Dokan:Windows和Linux文件共享新的途径
http://www.cnblogs.com/dengke/archive/2010/02/22/1670858.html
利用dokan作虚拟磁盘开发
http://www.fqyy.org/sunu/archives/tag/dokan
Dokan(Windows FUSE)学习笔记
http://my.debugman.net/program-198.html