您好,欢迎访问三七文档
当前位置:首页 > 行业资料 > 其它行业文档 > 虚拟磁盘的设计与操作
虚拟磁盘的设计与操作——李季季摘要:通常情况下是在磁盘上建立文件系统即硬盘分区,文件系统驱动程序(FSD)已经实现了在硬盘上创建和管理文件,本系统主要实现将一个文件虚拟成一个相应的磁盘,在文件系统驱动程序的基础之上,实现基于虚拟设备的文件系统,这种虚拟技术得到了很多应用,例如虚拟光驱就是其中之一,我们将对磁盘进行相关的操作。关键字:函数加载模块读写操作卸载模块格式化一.整体功能概述:1.通过命令行输入/mount的加载相应虚拟磁盘的命令,执行完毕后便可以在“我的电脑”中看到又多出了与命令行输入相应的盘符,通过format将磁盘格式化或通过右键选择格式化成相应格式后,便可以对它操作。2.通过命令行输入/mount的加载相应虚拟磁盘的命令,执行完后便可以在“我的电脑”中看到又多出了一个虚拟的磁盘,便可以对它执行读写操作。3.在命令行下输入/umount的卸载相应虚拟磁盘的命令,执行完后便可以卸载除刚才加载的虚拟磁盘。二.设计的描述:通常情况下是在磁盘上建立文件系统即硬盘分区,文件系统驱动程序(FSD)已经实现了在硬盘上创建和管理文件,本系统主要实现将一个文件虚拟成一个相应的磁盘,在文件系统驱动程序的基础之上,实现基于虚拟设备的文件系统,这种虚拟技术得到了很多应用,例如虚拟光驱就是其中之一。虚拟磁盘文件系统经过安装可以模拟真实的硬盘,支持各种文件系统功能。三.基本的数据结构FliediskSyntaxFileDiskUmountFileDiskMountFileDiskStatusMainPrintLastError(1)全局变量dir_handleHANDLEdir_handle;该全局变量用于指向一个“目录对象”,存放本驱动程序创建的所有的磁盘对象。(2)模拟磁盘文件信息结构OPEN_FILE_INFORMATIONtypedefstruct_OPEN_FILE_INFORMATION{DEVICE_TYPEDeviceType;//所模拟的磁盘的类型BOOLEANReadOnly;//是否设置虚拟磁盘为只读LARGE_INTEGERFileSize;//本文件的大小USHORTFileNameLength;//文件名的长度UCHARFileName[1];//文件名字符串}OPEN_FILE_INFORMATION;该结构保存了用于虚拟磁盘的文件的详细信息。在应用程序利用mount命令制定这个文件时,会将文件的信息组成这样一个结构后作为参数传入内核。驱动程序会抽取这些信息,并把它们作为虚拟磁盘的磁盘信息,例如磁盘的大小好只读属性。(3)设备扩展结构DEVICE_EXTENSION:自定义的磁盘信息结构,用来保存设备的细节以及对设备的编程方式。Typedefstruct_DEVICE_EXTESION{BOOLEANmedia_in_device;HANDLEfile_handle;//文件句柄ANSI_STRINGfile_name;//文件名LARGE_INTEGERfile_size;//文件的大小BOOLEANread_only;//只读属性PSECURITY_CLIENT_CONTEXTsecurity_client_context;LIST_ENTRYlist_head;KSPIN_LOCKlist_lock;KEVENTrequest_event;PVOIDthread_pointer;BOOLEANterminate_thread;}DEVICE_EXTENSION,*PDEVICE_EXTENSION;本驱动程序所创建的虚拟对象均为自己维护这样一个数据结构。实际上,所有内核驱动程序中的设备对象都维护这样一个数据结构。其主要作用就是在此保存对应设备的一些参数,使得所有有关此设备的处理都可以通过设备对象访问到这些信息。相关函数介绍(1)入口函数DirverEntryDirverEntry(INPDRIVER_OBJECTDriverObject,INPUNICODE_STRINGRegisterPath)该函数主要实现建立相应个数的磁盘对象和向I/O管理器注册4个分发例程以处理来自应用程序的相应请求。(2)分发例程FileDiskCreateCloseFileDiskCreateClose(INPDEVICE_OBJECTDriverObject,INPIRPIrp)在这个函数中相应打开文件和关闭文件对象的请求,对应主功能代码IRP_MJ_CREATE和IPR_MJ_CLOSE。在函数中就是简单的返回打开成功的标记,不需要完成额外的工作。(3)分发例程FileDiskReadWriteFileDiskReadWrite(INPDEVICE_OBJECTDeviceObject,INPIRPIrp)这个函数完成对虚拟磁盘的读写,对应于主功能代码IRP_MJ_WRITE和IRP_MJ_READ。在进行读写之前先确认设备是否存在。(4)分发例程FileDiskDeviceControlFileDiskDeviceControl(INPDEVICE_OBJECTDeviceObject,INPIRPIrp)该函数处理发送到虚拟磁盘的控制信息。(5)分发例程FileDiskUnloadFileDiskUnload(INPDRIVER_OBJECTDriverobject)用于卸载驱动程序。通过调用辅助函数FileDiskDeleteDevice卸载本驱动程序创建的各设备对象和对应的设备对象工作线程。(6)辅助函数辅助函数有FileDiskCreateDevice、FileDiskThread、FileDiskDeleteDevice、FileDiskOpenFile和FileDiskCloseFile这些辅助函数被前面的各个函数调用,以完成相对应的任务,其中最后两个函数在FileDiskThread中进行调用,完成相对应的工作。程序主要模块代码1.虚拟磁盘或光驱的加载模块IntFileDiskMount(IntDeviceNumber,//设备号0123等POPEN_FILE_INFORMATIONOpenFileInformation,//文件类型信息CharDriverletter,//卷名BOOLEANCdImage//是否为CD){charVolumeName[]=”\\\\.\\:”;charDeviceName[255];//临时存放文件名HANDLEDevice;//文件句柄DWORDBytesReturned;//缓冲区VolumeName[4]=DriveLetter;//将空格用盘符号代替Device=CreateFile(VolumeName,//要打开的文件的名字GENERIC_READ|GENERIC_WRITE,//访问模式FILE_SHARE_READ|FILE_SHARE_WRITE,//允许对文件进行读写共享访问NULL,OPEN_EXISTING,//文件必须已经存在。//打开一个文件,如果文件不存在函数将会失败FILE_FLAG_NO_BUFFERING,//禁止对文件进行缓冲处理。文件只能写入磁盘卷的扇区块NULL);if(Device!=INVALID_HANDLE_VALUE)//创建文件成功{SetLastError(ERROR_BUSY);PrintLastError(&VolumeName[4]);return-1;}//上面CreateFile的作用是:判断文件是否已经存在,存在则设置错误信息,中断返回。不存在继续向下执行;if(CdImage){sprintf(DeviceName,DEVICE_NAME_PREFIXCd%u,DeviceNumber);//格式化输出到DeviceName中\Device\FileDiskCd*}else{sprintf(DeviceName,DEVICE_NAME_PREFIX%u,DeviceNumber);//格式化输出到DeviceName中\Device\FileDisk*}if(!DefineDosDevice(//创建一个指向设备命名空间的符号链接,创建失败,输出错误信息;DDD_RAW_TARGET_PATH,&VolumeName[4],//盘符号,例如Z:DeviceName)){PrintLastError(&VolumeName[4]);return-1;//返回}Device=CreateFile(//用CreateFile打开上面建立的符号链接VolumeName,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,//打开一个文件,如果文件不存在函数将会失败,利用DefineDosDevice创建VolumeName[4]与DeviceName的链接故文件存在;FILE_FLAG_NO_BUFFERING,NULL);if(Device==INVALID_HANDLE_VALUE)//创建失败;{PrintLastError(&VolumeName[4]);//错误信息;DefineDosDevice(DDD_REMOVE_DEFINITION,&VolumeName[4],NULL);//删除前面建立的符号链接return-1;//返回}if(!DeviceIoControl(Device,IOCTL_FILE_DISK_OPEN_FILE,OpenFileInformation,sizeof(OPEN_FILE_INFORMATION)+OpenFileInformation-FileNameLength-1,NULL,0,&BytesReturned,NULL))//创建失败{PrintLastError(FileDisk:);//错误处理DefineDosDevice(DDD_REMOVE_DEFINITION,&VolumeName[4],NULL);////删除前面建立的符号链接return-1;//返回}return0;}2.虚拟磁盘或光驱的卸载模块intFileDiskUmount(charDriveLetter){charVolumeName[]=\\\\.\\:;//\\.\:特别特别注意中间有个空格HANDLEDevice;DWORDBytesReturned;VolumeName[4]=DriveLetter;//将空格用盘符号代替Device=CreateFile(//此处的作用是判断文件是否存在VolumeName,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,//文件必须已经存在。打开一个文件,如果文件不存在函数将会失败GetLastError()函数会捕获消息;FILE_FLAG_NO_BUFFERING,NULL);//返回一个无效的文件句柄,说明要卸载的文件系统根本不存在if(Device==INVALID_HANDLE_VALUE){PrintLastError(&VolumeName[4]);//比如要删除Z:但是Z不存在,便会输出错误“Z:系统找不到指定的文件。”return-1;//返回}//如果返回一个有效文件句柄,则虚拟的盘符存在//开始执行/umount的动作//包括以下几个步骤://1、锁定当前卷,通过发送FSCTL_LOCK_VOLUME到设备驱动实现//2、关闭所有该卷上打开的所有文件,通过发送IOCTL_FILE_DISK_CLOSE_FILE到设备驱动实现//3、卸载该卷,通过发送FSCTL_DISMOUNT_VOLUME到设备驱动实现//4、解除该卷的锁定,通过发送FSCTL_UNLOCK_VOLUME到设备驱动实现//5、关闭设备//6、删除虚拟盘符if(!DeviceIoControl(Device,FSCT
本文标题:虚拟磁盘的设计与操作
链接地址:https://www.777doc.com/doc-31332 .html