-
专题分析:基于驱动程序设计基础的filedisk源码解析
资源介绍
转自看雪的CCDeath
【文章标题】: 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.
4.Use 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()从入口点出发,嘿嘿。
具体部分已经详细在源代码注释了。
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;
核心层总体思路:从注册表获取关于驱动信息,接着由应用程序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来判断参数应该使用的命令。
应用层总体思路:
(argc==5 || argc==6)因为其中有一个是可选的,进行操作是Mount。分析代码时,请一边看结果,一
边分析代码 更容易些。接着对这个option选项中的[size[k|M|G] | /ro | /cd]分别进行处理。最后开始调用Mount
操作。 argc==3,是进行UnMount操作。
只要打开filedisk核心层.dsw,VC自动把filedisk应用层和核心层这两个工程打开。
--------------------------------------------------------------------------------
【经验总结】
下次继续分析,如何驱动加密、扩充容量、隐藏分区等等.......
参考书籍《filedisk源代码作者》
《一些不知名网友解决方案》比如:驱网pdodge注释部分核心层程序、未知网友注释部分应用层程序、
《Windows磁盘驱动基础教程》张云飞注释部分核心层程序
在此表示感谢!
- 上一篇: Access数据库应用教程(8)
- 下一篇: Access数据库应用教程(3)