Dokan簡介[轉]


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

 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM