虚拟磁盘驱动程序设计.doc_第1页
虚拟磁盘驱动程序设计.doc_第2页
虚拟磁盘驱动程序设计.doc_第3页
虚拟磁盘驱动程序设计.doc_第4页
虚拟磁盘驱动程序设计.doc_第5页
已阅读5页,还剩23页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Harbin Institute of Technology at Weihai操作系统课程设计报告设计题目: 虚拟磁盘驱动程序的设计 院 系: 计算机科学与技术学院 班 级: 0704102 学 号: 070410218 设 计 者: 杜小丹 哈尔滨工业大学(威海)二零零九年十二月1目录1设计要求12设计目的13设计描述13.1 FSD文件系统驱动13.1.1 本地FSD模型23.1.2 远程FSD模型33.2 对问题的分析33.2.1 试验目标:33.2.2 驱动层的分析33.2.3 驱动层分发例程和应用层的联系43.2.4 应用层的分析53.3 Windows 2000/XP系统中驱动程序的一般结构:53.4 注册表64. 程序流程图65. 设计分析85.1 驱动层85.1.1 核心层各例程的关系图85.1.2 首先给出驱动驱动层各例程的定义:85.1.3 核心层源码分析105.1.4 对核心层整体思路的总结115.2 应用层125.2.1 应用层各函数关系图125.2.2 应用层源码分析125.2.3 对应用层整体思路的总结236. 运行结果246.1 创建虚拟磁盘246.2 卸载虚拟磁盘246.3 创建虚拟光驱246.4 卸载虚拟光驱:257. 心得体会25261设计要求本实验将在Windows XP平台上,分析一个具体的虚拟磁盘的文件系统驱动程序,并完成对它的完善。具体要求如下:(1) 理解文件系统驱动程序(FSD)在系统中的作用和工作机制。(2) 分析试验给出的虚拟磁盘文件系统设备驱动程序,能够掌握其结构和运作机制,同时理解其与FSD的关系。(3) 完善所给虚拟设备文件系统驱动程序,加入虚拟光驱功能的支持。(4) 将虚拟设备驱动程序实际安装到系统中,运行相应应用程序进行测试分析。2设计目的(1) 了解文件系统及文件系统驱动程序的一般原理。(2) 学习开发文件系统驱动程序的开发环境,了解其与DDK(Device Drivers Kit,设备驱动程序开发包)的关系。(3) 掌握虚拟磁盘技术,能够编译生成相应的驱动程序并在系统中安装实现。(4) 进一步掌握Windows 2000/XP系统中驱动程序的一般结构。3设计描述3.1 FSD文件系统驱动v 主要功能 本地FSD:包括ntfs.sys,fastfat.sys,udfs.sys,cdfs.sys,raw fsd等,向I/O管理器注册,实现本地文件系统 远程FSD:包括客户端FSD和服务器端FSD,用以实现通过网络的远程文件共享v FSD的主要作用 显式文件I/O:API函数FSDI/O管理器设备驱动 高速缓存延迟写、提前读:提升磁盘利用效率和系统性能 内存脏页写和缺页处理:保持进程运行的稳定和正确3.1.1 本地FSD模型3.1.2 远程FSD模型3.2 对问题的分析3.2.1 试验目标:本实验的设计目标是用硬盘上的.img,.iso等文件来模拟一个磁盘驱动器或者是一个光驱驱动器,使虚拟盘能够像实际的的磁盘一样进行工作,能够在虚拟盘进行格式化以创建文件系统,在虚拟盘上进行各种文件与目录操作;使虚拟光驱能够像正常的光驱一样,对镜像文件进行操作。注意:在这里,虚拟光驱只能对文件进行读取操作而不能修改文件。3.2.2 驱动层的分析通过各分发例程实现功能,具体在下一部分论述3.2.3 驱动层分发例程和应用层的联系Windows应用程序与设备驱动程部分论述序打交道的主要是通过CreatFile, CloseHandle, ReadFile, WriteFile ,DeviceControl等Win32 API来进行的,这些API对应着驱动程序的一些分发例程。例如,当应用程序调用Win32 API CreateFile的时候,操作系统最终转化为对驱动程序IRP_MJ_CREATE功能代码所对应的分发例程的调用,如果驱动程序没有提供该例程,CreateFile调用就会失败。虚拟盘文件系统驱动程序分发例程与WIN32 API的关系功能代码说明对应的Win32 API虚拟盘文件系统驱动程序分发例程IRP_MJ_CREATE打开文件CreatFileFileDiskCreateCloseIRP_MJ_CLOSE关闭文件CloseHandleFileDiskCreateCloseIRP_MJ_READ从文件读取数据ReadFileFileDiskReadWriteIRP_MJ_WRITE向文件写入数据WriteFileFileDiskReadWriteIRP_MJ_DEVICE_CONTROL控制操作DeviceControlFileDiskDeviceControl在驱动层中处理应用层的历程代码部分如下:/ 根据不同的功能号处理. switch (io_stack-Parameters.DeviceIoControl.IoControlCode) case IOCTL_FILE_DISK_OPEN_FILE: SECURITY_QUALITY_OF_SERVICE security_quality_of_service; if (device_extension-media_in_device) KdPrint(FileDisk: IOCTL_FILE_DISK_OPEN_FILE: Media already openedn); status = STATUS_INVALID_DEVICE_REQUEST; Irp-IoStatus.Information = 0; break; break; case IOCTL_FILE_DISK_CLOSE_FILE: case IOCTL_FILE_DISK_QUERY_FILE: case IOCTL_DISK_CHECK_VERIFY: case IOCTL_CDROM_CHECK_VERIFY: case IOCTL_STORAGE_CHECK_VERIFY: case IOCTL_STORAGE_CHECK_VERIFY2:3.2.4 应用层的分析通过各应用函数实现功能,具体在下一部分论述3.3 Windows 2000/XP系统中驱动程序的一般结构:1. 内核2硬件抽象层3执行体4设备驱动程序5 环境子系统和子系统动态链接库6 系统支持进程3.4 注册表Windows注册表是一个二进制数据库,它包含了应用程序和系统软硬件的全部配置信息、初始化信息及其他重要的数据。计算机每次启动时,都会将注册表内容读入内存,根据注册表的相关信息进行动作,例如是否启动某个程序,提供启动某个程序用到的一些参数。注册表一旦载入内存,就一直被维护着,而且在系统运行期间,各种程序有可能修改它的内容。本实验直接采用注册表导入文件驱动程序的信息写入其中,从而完成驱动安装注册表相关部分。HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesFileDisk分支中添加了相应的信息,使得系统启动时识别并启动该驱动程序。具体讲是在该分支中添加了与本驱动程序同名的一个键。事实上,这个注册分支中存放的就是系统启动要调用的所有驱动程序的一个列表。在本实验中的注册表中限定了应用程序最多只能建4个虚拟磁盘或虚拟光驱。当然可以改变注册filedisk.reg中的值已建立更多的分区。4. 程序流程图 5. 设计分析5.1 驱动层5.1.1 核心层各例程的关系图5.1.2 首先给出驱动驱动层各例程的定义:DriverEntry例程:NTSTATUS DriverEntry ( /驱动入口函数IN PDRIVER_OBJECT DriverObject, /驱动器对象IN PUNICODE_STRING RegistryPath /驱动注册表路径);FileDiskDeviceControl例程:NTSTATUS FileDiskDeviceControl ( /设备控制例程IN PDEVICE_OBJECT DeviceObject, /要操作的设备对象IN PIRP Irp /IRP包指针 )FileDiskReadWrite例程:NTSTATUS FileDiskReadWrite ( /读写例程IN PDEVICE_OBJECT DeviceObject, /要操作的设备对象IN PIRP Irp /IRP包指针 )FileDiskCreateClose分发例程NTSTATUS FileDiskCreateClose ( /分发例程 创建与关闭IN PDEVICE_OBJECT DeviceObject, /设备对象IN PIRP Irp /IRP包指针);UnLoad分发例程:VOID FileDiskUnload ( /卸载例程IN PDRIVER_OBJECT DriverObject /要卸载的设备对象);FileDiskCreateDevice 例程(IN PDRIVER_OBJECT DriverObject,IN ULONG Number,IN DEVICE_TYPE DeviceType);FileDiskThread例程(IN PVOID Context)5.1.3 核心层源码分析1 DriverEntry: 主函数入口;备份传入路径,查询注册表值,调用ZwCreateDirectoryObject创建设备目录,重复4次调用 FileDiskCreateDevice创建设备,初始化操作函数指针。2 FileDiskCreateDevice:调用IoCreateDevice创建设备,KeInitializeEvent初始化事件对象,PsCreateSystemThread创建内核线程,入口函数是FileDiskThread,传入的函数参数为IoCreateDevice返回的设备对象。3 FileDiskThread:首先调用KeSetPriorityThread更改自身线程的优先级为LOW_REALTIME_PRIORITY,然后开始for(;),调用KeWaitForSingleObject函数等待事件对象有信号,如果等到,判断事件类型,有如下几种:IRP_MJ_READ:调用ZwReadFile读取文件,从内核到用户缓冲区;IRP_MJ_WRITE:调用ZwWriteFile写入文件,从用户到内核缓冲区;IRP_MJ_DEVICE_CONTROL:在FileDiskDeviceControl设置事件才会触发,主要有如下两种操作码:IOCTL_FILE_DISK_OPEN_FILE:调用FileDiskOpenFile。IOCTL_FILE_DISK_CLOSE_FILE:调用FileDiskCloseFile。FileDiskOpenFile:根据用户程序传入的映像文件全路径,调用ZwCreateFile在内核中打开它,如果文件不存在则再创建它,返回文件句柄。FileDiskCloseFile:调用ZwClose关闭文件。4 FileDiskCreateClose: 仅返回成功;对应Create,Close操作。5 FileDiskReadWrite:将IO包插入队列,然后调用KeSetEvent函数,激活事件对象;对应Read,Write操作。6 FileDiskDeviceControl:用户程序调用DeviceIoControl的响应函数,主要有如下两种操作:IOCTL_FILE_DISK_OPEN_FILE:设置好参数,将IO包插入队列,设置对象为有信号。IOCTL_FILE_DISK_CLOSE_FILE:将IO包插入队列,设置对象为有信号。其它的操作类型因为输入输出共用一个缓冲区,所以都采用系统默认处理,设置好需要输出的参数后,就直接从这个函数返回了。如:IOCTL_DISK_GET_DRIVE_GEOMETRY,IOCTL_CDROM_GET_DRIVE_GEOMETRY等;7,FileDiskUnload:在驱动程序被动态的卸载的时候,I/O管理器会调用UnLoad例程。它可能执行和DriverEntry例程相反的过程,包括移除所有它所控制的设备的设备名。在filedisk虚拟磁盘驱动程序中,这个卸载函数为FileDiskUnload。用于卸载驱动程序。通过调用辅助函数FileDiskDeleteDevice卸载本驱动程序创建的各设备对象和对应的设备工作线程。8,FileDiskDeleteDevice:Unload例程中调用了FileDiskDeleteDevice,这个函数的主要用途是删除生成的磁盘对象,并终止其处理线程。具体包括以下步骤:得到设备扩展,设置线程终止标志,设置启动事件,等待线程的结束,最终将磁盘设备对象删除9, 有4种操作是自定义的:FileDiskReadWrite函数两种,FileDiskDeviceControl函数两种,对应的操作码分别是:IRP_MJ_READ,IRP_MJ_WRITE,IOCTL_FILE_DISK_OPEN_FILE,IOCTL_FILE_DISK_CLOSE_FILE这4种,在FileDiskThread中等待这4种事件发生,如果等到,就调用相应的函数处理。5.1.4 对核心层整体思路的总结核心层总体思路:从注册表获取关于驱动信息,接着由应用程序DeviceIoControl所发送的控制代码,执行相应的派谴例程。最后进行再对IRP进行处理。5.2 应用层5.2.1 应用层各函数关系图5.2.2 应用层源码分析(1)测试模块int FileDiskSyntax(void)/这个函数主要是为了告诉使用者怎样使用的/测试数据时候用的;fprintf(stderr, =n);/stderr为指向结构体_iobuf的指针;fprintf(stderr, n);/stderr为指向结构体_iobuf的指针;fprintf(stderr, =n);/stderr为指向结构体_iobuf的指针;fprintf(stderr, 创建虚拟磁盘和虚拟光驱的命令行:n); fprintf(stderr, filedisk /mount sizek|M|G | /ro | /cd n);fprintf(stderr, 删除已创建虚拟磁盘和虚拟光驱的命令行:n); fprintf(stderr, filedisk /umount n);fprintf(stderr, 暂时还不知道有什么用:n); fprintf(stderr, filedisk /status n); fprintf(stderr, n); fprintf(stderr, filename formats:n); fprintf(stderr, c:pathfiledisk.imgn); fprintf(stderr, DeviceHarddisk0Partition1pathfiledisk.imgn); fprintf(stderr, serversharepathfiledisk.imgn); fprintf(stderr, n);/举例说明如何使用 fprintf(stderr, example:n); fprintf(stderr, filedisk /mount 0 c:tempfiledisk.img 8M f:n); fprintf(stderr, filedisk /mount 1 c:tempcdimage.iso /cd i:n); fprintf(stderr, filedisk /umount f:n); fprintf(stderr, filedisk /umount i:n); return -1;(2)虚拟磁盘或光驱的加载模块intFileDiskMount( int DeviceNumber, POPEN_FILE_INFORMATION OpenFileInformation, char DriveLetter, BOOLEAN CdImage) char VolumeName = . :;/ . :特别特别注意中间有个空格 char DeviceName255; HANDLE Device;/typedef void *HANDLE; DWORD BytesReturned; VolumeName4 = DriveLetter;/将空格用盘符号代替/*HANDLE CreateFile( LPCTSTR lpFileName,/ 指向文件名的指针 DWORD dwDesiredAccess,/ 访问模式(写 / 读) DWORD dwShareMode,/ 共享模式 LPSECURITY_ATTRIBUTES lpSecurityAttributes,/ 指向安全属性的指针 DWORD dwCreationDisposition,/ 如何创建 DWORD dwFlagsAndAttributes,/ 文件属性 HANDLE hTemplateFile/ 用于复制文件句柄 ); */ Device = CreateFile( VolumeName,/要打开的文件的名字 GENERIC_READ | GENERIC_WRITE,/ 访问模式(写 / 读) FILE_SHARE_READ | FILE_SHARE_WRITE,/共享模式,表示允许对文件进行读写共享访问 NULL, OPEN_EXISTING,/文件必须已经存在。/打开一个文件, 如果文件不存在函数将会失败 FILE_FLAG_NO_BUFFERING,/禁止对文件进行缓冲处理。文件只能写入磁盘卷的扇区块 NULL );/*如执行成功,则返回文件句柄。 INVALID_HANDLE_VALUE 表示出错,会设置 GetLastError 。即使函数成功,但若文件存在,且指定了 CREATE_ALWAYS 或 OPEN_ALWAYS , GetLastError 也会设为 ERROR_ALREADY_EXISTS */ if (Device != INVALID_HANDLE_VALUE)/创建文件成功 SetLastError(ERROR_BUSY); PrintLastError(&VolumeName4); return -1; /上面CreateFile的作用是:判断文件是否已经存在,存在则设置错误信息,中断返回。不存在继续向下执行; if (CdImage) sprintf(DeviceName, DEVICE_NAME_PREFIX Cd %u, DeviceNumber);/格式化输出到DeviceName中DeviceFileDisk Cd* else sprintf(DeviceName, DEVICE_NAME_PREFIX %u, DeviceNumber);/格式化输出到DeviceName中DeviceFileDisk* /*调用DefineDosDevice在应用层创建一个指向设备命名空间的符号链接,用CreateFile打开此链接,然后调用 DeviceIoControl发送控制码是IOCTL_FILE_DISK_OPEN_FILE,内核程序响应后,执行真正打开源映像文件的操作。*在应用层开发中调用它来创建一个?目录下的符号链接,*/ if (!DefineDosDevice(/创建一个指向设备命名空间的符号链接,创建失败,输出错误信息; DDD_RAW_TARGET_PATH, &VolumeName4,/盘符号,例如Z: DeviceName )/*BOOL DefineDosDevice(DWORD dwFlags,/ 控制标志LPCTSTR lpDeviceName,/ MS-DOS 设备名LPCTSTR lpTargetPath/ 路径);*/ PrintLastError(&VolumeName4); return -1;/返回 Device = CreateFile(/用CreateFile打开上面建立的符号链接 VolumeName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,/打开一个文件, 如果文件不存在函数将会失败,利用DefineDosDevice创建VolumeName4与DeviceName的链接故文件存在; FILE_FLAG_NO_BUFFERING, NULL ); if (Device = INVALID_HANDLE_VALUE)/创建失败; PrintLastError(&VolumeName4);/错误信息; DefineDosDevice(DDD_REMOVE_DEFINITION, &VolumeName4, NULL);/删除前面建立的符号链接 return -1;/返回 /*发送控制码是IOCTL_FILE_DISK_OPEN_FILE,内核程序响应后,执行真正打开源映像文件的操作。*/ 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, &VolumeName4, NULL);/删除前面建立的符号链接 return -1;/返回 return 0;(3)虚拟磁盘或光驱的卸载模块 int FileDiskUmount(char DriveLetter) char VolumeName = . :;/ . :特别特别注意中间有个空格 HANDLE Device; DWORD BytesReturned; VolumeName4 = 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(&VolumeName4);/比如要删除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, FSCTL_LOCK_VOLUME,/首先我们得发出FSCTL_LOCK_VOLUME锁住光驱以防止写入 NULL, 0, NULL, 0, &BytesReturned, NULL ) PrintLastError(&VolumeName4);/操作失败,GetLastError()函数会捕获消息,则进行错误处理; return -1;/返回 if (!DeviceIoControl( Device, IOCTL_FILE_DISK_CLOSE_FILE,/发出IOCTL_FILE_DISK_CLOSE_FILE,IO的控制信息 关闭磁盘文件 NULL, 0, NULL, 0, &BytesReturned, NULL ) PrintLastError(FileDisk:);/操作失败,GetLastError()函数会捕获消息,则进行错误处理; return -1;/返回 if (!DeviceIoControl( Device, FSCTL_DISMOUNT_VOLUME,/卸载该卷,通过发送FSCTL_DISMOUNT_VOLUME到设备驱动实现 NULL, 0, NULL, 0, &BytesReturned, NULL ) PrintLastError(&VolumeName4);/操作失败,GetLastError()函数会捕获消息,则进行错误处理; return -1;/返回 if (!DeviceIoControl( Device, FSCTL_UNLOCK_VOLUME,/解除该卷的锁定,通过发送FSCTL_UNLOCK_VOLUME到设备驱动实现 NULL, 0, NULL, 0, &BytesReturned, NULL ) PrintLastError(&VolumeName4);/操作失败,GetLastError()函数会捕获消息,则进行错误处理; return -1;/返回 CloseHandle(Device);/关闭内核对象设备HANDLE if (!DefineDosDevice(/删除虚拟盘符 DDD_REMOVE_DEFINITION, &VolumeName4, NULL ) PrintLastError(&VolumeName4);/操作失败,GetLastError()函数会捕获消息,则进行错误处理; return -1;/返回虚拟盘符 return 0;/正常执行结束,返回int FileDiskStatus(char DriveLetter) char VolumeName = . :;/ . :特别特别注意中间有个空格 HANDLE Device; POPEN_FILE_INFORMATION OpenFileInformation; DWORD BytesReturned; VolumeName4 = DriveLetter;/将空格用盘符号代替 Device = CreateFile(/此处的作用是判断文件是否存在 VolumeName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,/文件必须已经存在。打开一个文件, 如果文件不存在函数将会失败GetLastError()函数会捕获消息; FILE_FLAG_NO_BUFFERING, NULL );/ 返回一个无效的文件句柄,说明文件系统根本不存在 if (Device = INVALID_HANDLE_VALUE) PrintLastError(&VolumeName4);/操作失败,GetLastError()函数会捕获消息,则进行错误处理; return -1;/返回 OpenFileInformation = malloc(sizeof(OPEN_FILE_INFORMATION) + MAX_PATH); if (!DeviceIoControl( Device, IOCTL_FILE_DISK_QUERY_FILE,/向驱动层传递控制码,返回一个指向OpenFileInformation的指针,其中有虚拟磁盘获知光驱的详细信息; NULL, 0, OpenFileInformation, sizeof(OPEN_FILE_INFORMATION) + MAX_PATH, &BytesReturned, NULL ) PrintLastError(&VolumeName4); return -1; if (BytesReturned FileNameLength, OpenFileInformation-FileName, OpenFileInformation-FileSize, OpenFileInformation-ReadOnly ? , ReadOnly : ); return 0;5.2.3 对应用层整体思路的总结mount 调用DefineDosDevice在应用层创建一个指向

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论