filedisk源码分析
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
file_disk源码分析
--------------------------------------------------------------------------------
【成果3.7】驱动程序设计基础专题-filedisk源码分析
1 个附件
【文章标题】: WinMount虚拟磁盘深入研究(-)之filedisk源代码详细分析
【下载地址】: 自己搜索下载
【作者声明】: 只是感兴趣,没有其他目的。
失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
我的驱动入门三终结版,还再学习中。
由于个人也有些事情要处理,研究起刘涛涛WinMount 的虚拟
磁盘,而且这方面的书籍,貌似乎没见过,只有傻傻的几K代码存在,没注释什么的,整体框架也没说。
虚拟光驱用实现文件来模拟磁盘的原理,是文件系统驱动程序。
把filedisk驱动安装,查看install.txt文件。
1.Copy the driver (filedisk.sys) to %systemroot%\system32\drivers\.
2.Import filedisk.reg to the Registry.
3.Reboot.
e the program filedisk.exe to mount/umount files, for an example
of use see the file example.txt.
可以不用重起机子的方法,找一个动载加载驱动工具:DriverMonitor不错了。
然后在“开始菜单”->
"运行"输入"net start filedisk" 出现:“请求的服务已经启动”。
这个必须得成功才行哦。
接下来注意点。
cmd后出现这个目录C:\Documents and Settings \Administrator>,在接下来敲入
filedisk /mount 0 c:\temp\filedisk.img 8M f:
C:\Documents and Settings \Administrator>filedisk /mount 0 c:\temp\filedisk.img 8M r: 回车一下。
出现"FileDisk:系统找不到指定路径" 。
原因就出在这"c:\temp\filedisk.img" 中的C:\temp要这个目录才行。
至于filedisk.img不是必须,会自动创建。
如果有出现"FileDisk:函数不正确" 中的“filedisk /mount 0 ”中"0"代号已经被使用。
可以改为"1". 查看一下,结果就出现一个还未格式化8M R磁盘,查看C:\temp下生成一个filedisk.img也8M。
想卸载
掉"filedisk /umount r:". 还可以创建很大的虚拟磁盘,你把"8M"改换其他的就是了。
以上如果都没出现结果,基本上就没兴趣继续研究下去了,我看到了很多人初学filedisk都遇到以上这
些问题(包括我在内) ,把我折腾了半天。
先来分析驱动层代码,后来分析应用层代码。
更详细的请看附件里的源代码。
我对代码工程方式重新布
局,用起来更方便。
===================================//先来分析驱动层代码
1.对filedisk.h进行分析
#define FILE_DEVICE_FILE_DISK 0x8000//用户定义范围0x8000~
#define IOCTL_FILE_DISK_OPEN_FILE CTL_CODE(FILE_DEVICE_FILE_DISK, 0x800,
METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
#define IOCTL_FILE_DISK_CLOSE_FILE CTL_CODE(FILE_DEVICE_FILE_DISK, 0x801,
METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
#define IOCTL_FILE_DISK_QUERY_FILE CTL_CODE(
FILE_DEVICE_FILE_DISK, 0x802,
METHOD_BUFFERED, FILE_READ_ACCESS)
typedef struct _OPEN_FILE_INFORMATION {
LARGE_INTEGER FileSize;//文件大小
BOOLEAN ReadOnly;//只读属性
USHORT FileNameLength;//文件名长度
UCHAR FileName[1];//文件名
UCHAR DeviceType;//判断是K\G\M
} OPEN_FILE_INFORMATION, *POPEN_FILE_INFORMATION;
定义控制代码分别是“打开文件”、“关闭文件”、“查询?”
2.看一下filedisk核心层\filedisk.c
分析定义和声明的变量,接着从入口处分析,最后分析其他派谴例程。
定义几个IoCtrl合并宏,并定义几个结构体:MRB结构体、分区参数表等。
NTSTATUS DriverEntry()从入口点出发,嘿嘿。
[COLOR="Red"]具体部分已经详细在源代码注释了。
[/COLOR]
typedef struct _DEVICE_EXTENSION {
BOOLEAN media_in_device;
HANDLE file_handle;
FILE_STANDARD_INFORMATION file_information;
BOOLEAN read_only;
PSECURITY_CLIENT_CONTEXT security_client_context;
LIST_ENTRY list_head;
KSPIN_LOCK list_lock;
KEVENT request_event;
PVOID thread_pointer;
BOOLEAN terminate_thread;
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
media_in_device是指这个设备是否已经指定了一个文件作为存储媒质。
这是一个用文件来虚拟磁
盘的驱动。
那么一个磁盘应该对应一个实际存在的文件。
读写这个磁盘的请求最终转变为对文件的读写。
如果一个磁盘设备对象还没有指定文件,那么这个内容是FALSE.
file_handle是文件句柄。
也就是这个虚拟磁盘所对应的文件。
file_information是这个文件的一些信息。
read_only是否只读。
security_client_context 访问文件的时候需要使用的一个线程客户安全性上下文。
typedef struct _DISK_GEOMETRY {
LARGE_INTEGER Cylinders; // 磁柱个数
MEDIA_TYPE MediaType; // 媒质类型
ULONG TracksPerCylinder; // 每个磁柱上的磁道数
ULONG SectorsPerTrack; // 每个磁道上的扇区数
ULONG BytesPerSector; // 每个扇区上的字节数
} DISK_GEOMETRY, *PDISK_GEOMETRY;
[COLOR="Red"] 核心层总体思路:[/COLOR]从注册表获取关于驱动信息,接着由应用程序DeviceIoControl所发送的控制代码,
执行相应的派谴例程。
最后进行对IRP进行处理就OK了。
===================================//后来分析应用层代码
这个是真的是不知道名字网友分析,我只能对他\她严重表示感谢。
注释的很详细,非本人注释,本人
只是注释一点。
我提一下整体思路就好了。
先分析一些重要变量名接着分析5个函数,最后从main()函数分析,具体请看
//变量分析
char* Command;//命令行,比如你输入的“filedisk /umount r:”
int DeviceNumber;//虚拟的盘数,比如0-4个
char* FileName;//用来虚拟磁盘所用的全文件名.比如:“c:\temp\filedisk.img ”
char* Option;//可选比如“/ro| / cd”;ro:只读
方式MOUNT,cd:虚拟CD_ROM
char DriveLetter;//虚拟的盘符,比如"r:"盘
BOOLEAN CdImage = FALSE;
POPEN_FILE_INFORMATION OpenFileInformation;//打开文件信息
Command = argv[1];
int Syntax(void);//syntax[sinteks]语法, 有秩序的排列, 句子构造, 句法意思。
意思就是举例语
//式,怎么使用这个filedisk.的语法格式
void PrintLastError(char* Prefix)//打印出错信息,特别是里面的一个formatmessage()函数是用来
int FileDiskMount(int DeviceNumber,POPEN_FILE_INFORMATION OpenFileInformation,char DriveLetter,BOOLEAN CdImage)
//这个函数很明显是安装上一个虚拟盘。
首先判断是否存在该卷,存在则输出错误信息,不存在则创建。
// 通过DeviceIoControl对驱动程序发送IRP消息。
int Umount(char DriveLetter)//这个函数很明显是卸载掉虚拟盘。
判断要UnMount的盘存在否。
//DefineDosDevice()这个函数很帅。
// 1、锁定当前卷,通过发送FSCTL_LOCK_VOLUME到设备驱动实现
// 2、关闭所有该卷上打开的所有文件,通过发送IOCTL_FILE_DISK_CLOSE_FILE到设备驱动实现// 3、卸载该卷,通过发送FSCTL_DISMOUNT_VOLUME到设备驱动实现
// 4、解除该卷的锁定,通过发送FSCTL_UNLOCK_VOLUME到设备驱动实现
// 5、关闭设备
// 6、删除虚拟盘符
int main(int argc, char* argv[])//需要命令行。
首先定义一下重要变量名,就上面说的重要变量名。
然后根据解析命令行,调用相应的函数来完成我们所需要的操作。
顺便联想一下。
int main(int argc,char * argv[])参数的使用。
比如命令行输入:cfile computer C_Langle .此时argc=3. argv[]指向3个字符串,这些理解了。
后面就没问题了。
它是根据argc来判断参数应该使用的命令。
[COLOR="red"] 应用层总体思路:[/COLOR]
(argc==5 || argc==6)因为其中有一个是可选的,进行操作是Mount。
分析代码时,请一边看结果,一
边分析代码更容易些。
接着对这个option选项中的[size[k|M|G] | /ro | /cd]分别进行处理。
最后开始调用Mount
操作。
argc==3,是进行UnMount操作。
[COLOR="red"] 只要打开filedisk核心层.dsw[/COLOR],VC自动把filedisk应用层和核
心层这两个工程打开。