文件名称:驱动程序设计基础专题-filedisk源码分析
文件大小:40KB
文件格式:ZIP
更新时间:2012-10-18 03:51:21
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磁盘驱动基础教程》张云飞注释部分核心层程序 在此表示感谢!
【文件预览】:
ccdeath-filedisk
----filedisk.reg(356B)
----filedisk核心层()
--------Sources(91B)
--------filedisk核心层.dsp(4KB)
--------filedisk核心层.dsw(757B)
--------filedisk核心层.ncb(65KB)
--------MAKEFILE(267B)
--------filedisk核心层.opt(59KB)
--------filedisk核心层.plg(1KB)
--------buildchk.log(2KB)
--------filedisk.c(41KB)
--------filedisk.h(1KB)
----install.txt(307B)
----阅读之前说明.txt(179B)
----filedisk.sys(10KB)
----filedisk应用层()
--------filedisk应用层.opt(53KB)
--------filedisk应用层.ncb(41KB)
--------filedisk应用层.plg(1KB)
--------filedisk.c(10KB)
--------filedisk.h(1KB)
--------filedisk应用层.dsp(4KB)