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

Dokan流程图

图一

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

<table border="0" cellpadding="0" cellspacing="0" style="margin-top: 0px !important; margin-right: 0px !important; margin-bottom: 0px !important; margin-left: 0px !important; padding-top: 0px !important; padding-right: 0px !important; padding-bottom: 0px !important; padding-left: 0px !important; border-bottom-width: 0px !important; border-bottom-style: solid; border-bottom-color: rgb(217, 217, 217); border-left-width: 0px !important; border-left-style: solid; border-left-color: rgb(217, 217, 217); border-top-left-radius: 0px 0px !important; border-top-right-radius: 0px 0px !important; border-bottom-right-radius: 0px 0px !important; border-bottom-left-radius: 0px 0px !important; background-image: none !important; background-attachment: initial !important; background-origin: initial !important; background-clip: initial !important; background-color: initial !important; border-top-width: 0px !important; border-right-width: 0px !important; border-style: initial !important; border-color: initial !important; bottom: auto !important; float: none !important; height: auto !important; left: auto !important; line-height: 1.1em !important; outline-width: 0px !important; outline-style: initial !important; outline-color: initial !important; overflow-x: visible !important; overflow-y: visible !important; position: static !important; right: auto !important; text-align: left !important; top: auto !important; vertical-align: baseline !important; width: 891px; box-sizing: content-box !important; font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace !important; font-weight: normal !important; font-style: normal !important; font-size: 1em !important; min-height: inherit !important; background-position: initial initial !important; background-repeat: initial initial !important; "><td style="margin-top: 0px !important; margin-right: 0px !important; margin-bottom: 0px !important; margin-left: 0px !important; padding-top: 0px !important; padding-right: 0px !important; padding-bottom: 0px !important; padding-left: 0px !important; text-align: left !important; border-top-width: 0px !important; border-top-style: solid; border-top-color: rgb(217, 217, 217); border-right-width: 0px !important; border-right-style: solid; border-right-color: rgb(217, 217, 217); border-top-left-radius: 0px 0px !important; border-top-right-radius: 0px 0px !important; border-bottom-right-radius: 0px 0px !important; border-bottom-left-radius: 0px 0px !important; background-image: none !important; background-attachment: initial !important; background-origin: initial !important; background-clip: initial !important; background-color: initial !important; border-bottom-width: 0px !important; border-left-width: 0px !important; border-style: initial !important; border-color: initial !important; bottom: auto !important; float: none !important; height: auto !important; left: auto !important; line-height: 1.1em !important; outline-width: 0px !important; outline-style: initial !important; outline-color: initial !important; overflow-x: visible !important; overflow-y: visible !important; position: static !important; right: auto !important; top: auto !important; vertical-align: baseline !important; width: auto !important; box-sizing: content-box !important; font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace !important; font-weight: normal !important; font-style: normal !important; font-size: 1em !important; min-height: inherit !important; color: rgb(175, 175, 175) !important; background-position: initial initial !important; background-repeat: initial initial !important; ">123456<td style="margin-top: 0px !important; margin-right: 0px !important; margin-bottom: 0px !important; margin-left: 0px !important; padding-top: 0px !important; padding-right: 0px !important; padding-bottom: 0px !important; padding-left: 0px !important; text-align: left !important; border-top-width: 0px !important; border-top-style: solid; border-top-color: rgb(217, 217, 217); border-right-width: 0px !important; border-right-style: solid; border-right-color: rgb(217, 217, 217); border-top-left-radius: 0px 0px !important; border-top-right-radius: 0px 0px !important; border-bottom-right-radius: 0px 0px !important; border-bottom-left-radius: 0px 0px !important; background-image: none !important; background-attachment: initial !important; background-origin: initial !important; background-clip: initial !important; background-color: initial !important; border-bottom-width: 0px !important; border-left-width: 0px !important; border-style: initial !important; border-color: initial !important; bottom: auto !important; float: none !important; height: auto !important; left: auto !important; line-height: 1.1em !important; outline-width: 0px !important; outline-style: initial !important; outline-color: initial !important; overflow-x: visible !important; overflow-y: visible !important; position: static !important; right: auto !important; top: auto !important; vertical-align: baseline !important; width: 855px; box-sizing: content-box !important; font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace !important; font-weight: normal !important; font-style: normal !important; font-size: 1em !important; min-height: inherit !important; background-position: initial initial !important; background-repeat: initial initial !important; ">typedefstruct_DOKAN_FILE_INFO {ULONG64Context;     //文件系统程序维护,可作为文件句柄ULONG64DokanContext;  //Dokan Library维护ULONG   ProcessId;   //操作IDBOOL    IsDirectory;  //目录= TRUE} DOKAN_FILE_INFO, *PDOKAN_FILE_INFO;

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

下面是几个操作的声明:

<table border="0" cellpadding="0" cellspacing="0" style="margin-top: 0px !important; margin-right: 0px !important; margin-bottom: 0px !important; margin-left: 0px !important; padding-top: 0px !important; padding-right: 0px !important; padding-bottom: 0px !important; padding-left: 0px !important; border-bottom-width: 0px !important; border-bottom-style: solid; border-bottom-color: rgb(217, 217, 217); border-left-width: 0px !important; border-left-style: solid; border-left-color: rgb(217, 217, 217); border-top-left-radius: 0px 0px !important; border-top-right-radius: 0px 0px !important; border-bottom-right-radius: 0px 0px !important; border-bottom-left-radius: 0px 0px !important; background-image: none !important; background-attachment: initial !important; background-origin: initial !important; background-clip: initial !important; background-color: initial !important; border-top-width: 0px !important; border-right-width: 0px !important; border-style: initial !important; border-color: initial !important; bottom: auto !important; float: none !important; height: auto !important; left: auto !important; line-height: 1.1em !important; outline-width: 0px !important; outline-style: initial !important; outline-color: initial !important; overflow-x: visible !important; overflow-y: visible !important; position: static !important; right: auto !important; text-align: left !important; top: auto !important; vertical-align: baseline !important; width: 891px; box-sizing: content-box !important; font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace !important; font-weight: normal !important; font-style: normal !important; font-size: 1em !important; min-height: inherit !important; background-position: initial initial !important; background-repeat: initial initial !important; "><td style="margin-top: 0px !important; margin-right: 0px !important; margin-bottom: 0px !important; margin-left: 0px !important; padding-top: 0px !important; padding-right: 0px !important; padding-bottom: 0px !important; padding-left: 0px !important; text-align: left !important; border-top-width: 0px !important; border-top-style: solid; border-top-color: rgb(217, 217, 217); border-right-width: 0px !important; border-right-style: solid; border-right-color: rgb(217, 217, 217); border-top-left-radius: 0px 0px !important; border-top-right-radius: 0px 0px !important; border-bottom-right-radius: 0px 0px !important; border-bottom-left-radius: 0px 0px !important; background-image: none !important; background-attachment: initial !important; background-origin: initial !important; background-clip: initial !important; background-color: initial !important; border-bottom-width: 0px !important; border-left-width: 0px !important; border-style: initial !important; border-color: initial !important; bottom: auto !important; float: none !important; height: auto !important; left: auto !important; line-height: 1.1em !important; outline-width: 0px !important; outline-style: initial !important; outline-color: initial !important; overflow-x: visible !important; overflow-y: visible !important; position: static !important; right: auto !important; top: auto !important; vertical-align: baseline !important; width: auto !important; box-sizing: content-box !important; font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace !important; font-weight: normal !important; font-style: normal !important; font-size: 1em !important; min-height: inherit !important; color: rgb(175, 175, 175) !important; background-position: initial initial !important; background-repeat: initial initial !important; ">12345678910111213141516171819202122232425<td style="margin-top: 0px !important; margin-right: 0px !important; margin-bottom: 0px !important; margin-left: 0px !important; padding-top: 0px !important; padding-right: 0px !important; padding-bottom: 0px !important; padding-left: 0px !important; text-align: left !important; border-top-width: 0px !important; border-top-style: solid; border-top-color: rgb(217, 217, 217); border-right-width: 0px !important; border-right-style: solid; border-right-color: rgb(217, 217, 217); border-top-left-radius: 0px 0px !important; border-top-right-radius: 0px 0px !important; border-bottom-right-radius: 0px 0px !important; border-bottom-left-radius: 0px 0px !important; background-image: none !important; background-attachment: initial !important; background-origin: initial !important; background-clip: initial !important; background-color: initial !important; border-bottom-width: 0px !important; border-left-width: 0px !important; border-style: initial !important; border-color: initial !important; bottom: auto !important; float: none !important; height: auto !important; left: auto !important; line-height: 1.1em !important; outline-width: 0px !important; outline-style: initial !important; outline-color: initial !important; overflow-x: visible !important; overflow-y: visible !important; position: static !important; right: auto !important; top: auto !important; vertical-align: baseline !important; width: 846px; box-sizing: content-box !important; font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace !important; font-weight: normal !important; font-style: normal !important; font-size: 1em !important; min-height: inherit !important; background-position: initial initial !important; background-repeat: initial initial !important; ">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<table border="0" cellpadding="0" cellspacing="0" style="margin-top: 0px !important; margin-right: 0px !important; margin-bottom: 0px !important; margin-left: 0px !important; padding-top: 0px !important; padding-right: 0px !important; padding-bottom: 0px !important; padding-left: 0px !important; border-bottom-width: 0px !important; border-bottom-style: solid; border-bottom-color: rgb(217, 217, 217); border-left-width: 0px !important; border-left-style: solid; border-left-color: rgb(217, 217, 217); border-top-left-radius: 0px 0px !important; border-top-right-radius: 0px 0px !important; border-bottom-right-radius: 0px 0px !important; border-bottom-left-radius: 0px 0px !important; background-image: none !important; background-attachment: initial !important; background-origin: initial !important; background-clip: initial !important; background-color: initial !important; border-top-width: 0px !important; border-right-width: 0px !important; border-style: initial !important; border-color: initial !important; bottom: auto !important; float: none !important; height: auto !important; left: auto !important; line-height: 1.1em !important; outline-width: 0px !important; outline-style: initial !important; outline-color: initial !important; overflow-x: visible !important; overflow-y: visible !important; position: static !important; right: auto !important; text-align: left !important; top: auto !important; vertical-align: baseline !important; width: 998px; box-sizing: content-box !important; font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace !important; font-weight: normal !important; font-style: normal !important; font-size: 1em !important; min-height: inherit !important; background-position: initial initial !important; background-repeat: initial initial !important; "><td style="margin-top: 0px !important; margin-right: 0px !important; margin-bottom: 0px !important; margin-left: 0px !important; padding-top: 0px !important; padding-right: 0px !important; padding-bottom: 0px !important; padding-left: 0px !important; text-align: left !important; border-top-width: 0px !important; border-top-style: solid; border-top-color: rgb(217, 217, 217); border-right-width: 0px !important; border-right-style: solid; border-right-color: rgb(217, 217, 217); border-top-left-radius: 0px 0px !important; border-top-right-radius: 0px 0px !important; border-bottom-right-radius: 0px 0px !important; border-bottom-left-radius: 0px 0px !important; background-image: none !important; background-attachment: initial !important; background-origin: initial !important; background-clip: initial !important; background-color: initial !important; border-bottom-width: 0px !important; border-left-width: 0px !important; border-style: initial !important; border-color: initial !important; bottom: auto !important; float: none !important; height: auto !important; left: auto !important; line-height: 1.1em !important; outline-width: 0px !important; outline-style: initial !important; outline-color: initial !important; overflow-x: visible !important; overflow-y: visible !important; position: static !important; right: auto !important; top: auto !important; vertical-align: baseline !important; width: auto !important; box-sizing: content-box !important; font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace !important; font-weight: normal !important; font-style: normal !important; font-size: 1em !important; min-height: inherit !important; color: rgb(175, 175, 175) !important; background-position: initial initial !important; background-repeat: initial initial !important; ">12345678910111213141516171819202122232425262728293031323334<td style="margin-top: 0px !important; margin-right: 0px !important; margin-bottom: 0px !important; margin-left: 0px !important; padding-top: 0px !important; padding-right: 0px !important; padding-bottom: 0px !important; padding-left: 0px !important; text-align: left !important; border-top-width: 0px !important; border-top-style: solid; border-top-color: rgb(217, 217, 217); border-right-width: 0px !important; border-right-style: solid; border-right-color: rgb(217, 217, 217); border-top-left-radius: 0px 0px !important; border-top-right-radius: 0px 0px !important; border-bottom-right-radius: 0px 0px !important; border-bottom-left-radius: 0px 0px !important; background-image: none !important; background-attachment: initial !important; background-origin: initial !important; background-clip: initial !important; background-color: initial !important; border-bottom-width: 0px !important; border-left-width: 0px !important; border-style: initial !important; border-color: initial !important; bottom: auto !important; float: none !important; height: auto !important; left: auto !important; line-height: 1.1em !important; outline-width: 0px !important; outline-style: initial !important; outline-color: initial !important; overflow-x: visible !important; overflow-y: visible !important; position: static !important; right: auto !important; top: auto !important; vertical-align: baseline !important; width: 953px; box-sizing: content-box !important; font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace !important; font-weight: normal !important; font-style: normal !important; font-size: 1em !important; min-height: inherit !important; background-position: initial initial !important; background-repeat: initial initial !important; ">//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的参数。

<table border="0" cellpadding="0" cellspacing="0" style="margin-top: 0px !important; margin-right: 0px !important; margin-bottom: 0px !important; margin-left: 0px !important; padding-top: 0px !important; padding-right: 0px !important; padding-bottom: 0px !important; padding-left: 0px !important; border-bottom-width: 0px !important; border-bottom-style: solid; border-bottom-color: rgb(217, 217, 217); border-left-width: 0px !important; border-left-style: solid; border-left-color: rgb(217, 217, 217); border-top-left-radius: 0px 0px !important; border-top-right-radius: 0px 0px !important; border-bottom-right-radius: 0px 0px !important; border-bottom-left-radius: 0px 0px !important; background-image: none !important; background-attachment: initial !important; background-origin: initial !important; background-clip: initial !important; background-color: initial !important; border-top-width: 0px !important; border-right-width: 0px !important; border-style: initial !important; border-color: initial !important; bottom: auto !important; float: none !important; height: auto !important; left: auto !important; line-height: 1.1em !important; outline-width: 0px !important; outline-style: initial !important; outline-color: initial !important; overflow-x: visible !important; overflow-y: visible !important; position: static !important; right: auto !important; text-align: left !important; top: auto !important; vertical-align: baseline !important; width: 891px; box-sizing: content-box !important; font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace !important; font-weight: normal !important; font-style: normal !important; font-size: 1em !important; min-height: inherit !important; background-position: initial initial !important; background-repeat: initial initial !important; "><td style="margin-top: 0px !important; margin-right: 0px !important; margin-bottom: 0px !important; margin-left: 0px !important; padding-top: 0px !important; padding-right: 0px !important; padding-bottom: 0px !important; padding-left: 0px !important; text-align: left !important; border-top-width: 0px !important; border-top-style: solid; border-top-color: rgb(217, 217, 217); border-right-width: 0px !important; border-right-style: solid; border-right-color: rgb(217, 217, 217); border-top-left-radius: 0px 0px !important; border-top-right-radius: 0px 0px !important; border-bottom-right-radius: 0px 0px !important; border-bottom-left-radius: 0px 0px !important; background-image: none !important; background-attachment: initial !important; background-origin: initial !important; background-clip: initial !important; background-color: initial !important; border-bottom-width: 0px !important; border-left-width: 0px !important; border-style: initial !important; border-color: initial !important; bottom: auto !important; float: none !important; height: auto !important; left: auto !important; line-height: 1.1em !important; outline-width: 0px !important; outline-style: initial !important; outline-color: initial !important; overflow-x: visible !important; overflow-y: visible !important; position: static !important; right: auto !important; top: auto !important; vertical-align: baseline !important; width: auto !important; box-sizing: content-box !important; font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace !important; font-weight: normal !important; font-style: normal !important; font-size: 1em !important; min-height: inherit !important; color: rgb(175, 175, 175) !important; background-position: initial initial !important; background-repeat: initial initial !important; ">123456789101112131415161718192021<td style="margin-top: 0px !important; margin-right: 0px !important; margin-bottom: 0px !important; margin-left: 0px !important; padding-top: 0px !important; padding-right: 0px !important; padding-bottom: 0px !important; padding-left: 0px !important; text-align: left !important; border-top-width: 0px !important; border-top-style: solid; border-top-color: rgb(217, 217, 217); border-right-width: 0px !important; border-right-style: solid; border-right-color: rgb(217, 217, 217); border-top-left-radius: 0px 0px !important; border-top-right-radius: 0px 0px !important; border-bottom-right-radius: 0px 0px !important; border-bottom-left-radius: 0px 0px !important; background-image: none !important; background-attachment: initial !important; background-origin: initial !important; background-clip: initial !important; background-color: initial !important; border-bottom-width: 0px !important; border-left-width: 0px !important; border-style: initial !important; border-color: initial !important; bottom: auto !important; float: none !important; height: auto !important; left: auto !important; line-height: 1.1em !important; outline-width: 0px !important; outline-style: initial !important; outline-color: initial !important; overflow-x: visible !important; overflow-y: visible !important; position: static !important; right: auto !important; top: auto !important; vertical-align: baseline !important; width: 846px; box-sizing: content-box !important; font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace !important; font-weight: normal !important; font-style: normal !important; font-size: 1em !important; min-height: inherit !important; background-position: initial initial !important; background-repeat: initial initial !important; ">intDOKANAPI DokanMain( PDOKAN_OPTIONS    DokanOptions, PDOKAN_OPERATIONS DokanOperations); typedefstruct_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_* ULONG64GlobalContext;  // FileSystem can use this variable LPCWSTRMountPoint;     // mount point "M:\" (drive letter) or // "C:\mount\dokan" (path in NTFS) } DOKAN_OPTIONS, *PDOKAN_OPTIONS;5.      卸载

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

> dokanctl.exe /u DriveLetter

Logo

更多推荐