您的位置:首页 > 其它

Dokan(Windows FUSE)学习笔记

2012-08-09 15:48 134 查看
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: