Windows Dokan简介

Windows Dokan简介,第1张

Dokan创建之初的目的和FUSE(Filesystem in Userspace)一样,即为了实现用户自己的文件系统。开发者通过dokan开发文件系统,实现的是一个应用程序而不是复杂的内核驱动。(Windows内核驱动开发也不见得比Linux简单。)Dokan就是Windows上的FUSE。而目前Dokan已经支持Fuse,意味着Linux Fuse程序也可以实现向Windows平台的迁移。

目前Dokan已经被替换成Dokany(自0.6.0版本),广泛支持32位或64位X86和ARM架构。支持的Windows版本有

- Windows Server 2019/2016/2012 R2/2012/2008 R2 SP1

- Windows 10/8.1/8/7 SP1

简而言之,和FUSE如出一辙。

Dokan库包含用户态的动态链接库(dokan.dll)和内核态的驱动程序(dokan1.sys)。( 可以类比FUSE提供用户态的动态链接库libfuse.so和内核态驱动fuse.ko。) 使用dokan库创建的文件系统视为 文件系统程序 。 

文件 *** 作比如创建文件CreateFile、读文件ReadFile和写文件WriteFile的请求将会发送给内核态子系统,然后转递给驱动程序。 文件系统程序 通过用户态提供的函数接口,在驱动程序中注册回调接口。驱动程序到信息后会调用这些回调函数,最后这些请求在用户态的文件系统程序中被处理。Dokan扮演的是应用程序和 文件系统程序 直接的代理角色。

第一步实现DOKAN_OPERATIONS结构体里的函数。这些函数会被注册成回调函数。DOKAN_OPERATIONS会在主函数DokanMain中作为参数传递使用。

一般 *** 作文件的顺序是

- DOKAN_OPERATIONS::ZwCreateFile

- 其他 *** 作,比如写、读等

- DOKAN_OPERATIONS::CleanUp

- DOKAN_OPERATIONS::CloseFile

即创建、实际 *** 作、清理和关闭。清理主要是清理请求和关闭文件句柄,而关闭是清理尚存的上下文结构。

每个 *** 作成功返回STATUS_SUCCESS,如果失败则返回不同的错误状态NTSTATUS。另外,每一个Dokan *** 作都要带一个结构体DOKAN_FILE_INFO。每个文件句柄会关联该结构。该结构的主要目的是保存当前 *** 作的文件信息,比如上下文 *** 作信息、是否为目录类型、是否读缓存、同步 *** 作等定义 *** 作行为的信息。具体详见附录中地址。

实现了 线程安全 的文件系统 *** 作,调用DokanMain函数即可挂载文件系统到Windows中,该函数会在卸载之前保持阻塞状态。

源码包里面提供了Mirror,可以作为案例入门Dokan的开发。

Dokan Fuse在使用时需要链接 dokanfuse.dll 的动态库。 另外由于Linux和Windows在处理删除和重命名上的不同会导致一些移植出现问题 (Linux允许打开的文件被删除,而Windows则不允许)。

项目地址:https://github.com/dokan-dev/dokany

结构体DOKAN_FILE_INFO描述:https://dokan-dev.github.io/dokany-doc/html/struct_d_o_k_a_n___f_i_l_e___i_n_f_o.html

1.Dokan Library 简介

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

2.Dokan原理

Dokan Library包含以下部分:

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 一致,但必须做到线程安全,因为有可能有多个线程调用。

这些函数有个典型的调用顺序:

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_OPTIONSDokanOptions,

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 像这样进行卸载:

你把你的16GU盘按你那个4G的盘符格式再从新做一下.

如果按F12不行的话,直接进BIOS调!

看你的情况应该不会有什么大问题呀。

应该在BIOS里能认到你的U盘,你的U盘引导又没问题的话,是能进去的! 如果还不行的话,你也可以试试CMOS放下电...还不行的话,再联系!期待回复

那换个格式呢? HDD,FDD等! 其实我感觉CMOS放电你也可以试试。也就动下手的事情!还有我不明白你说的克隆是什么意思?不会是复制把! 嘿


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/tougao/9894110.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-03
下一篇 2023-05-03

发表评论

登录后才能评论

评论列表(0条)

保存