1 / 31

第五章 设备管理

第五章 设备管理. 设备管理 --- 概述. Windows I/O 系统概述 I/O 系统结构 Windows 驱动程序 I/O 系统内核对象 I/O 请求和处理. Windows I/O 系统概述. I/O 系统: 负责管理输入输出设备。 向用户隐藏硬件细节。. I/O 系统结构. I/O 系统组成 I/O 管理器 设备驱动程序 PnP 管理器 电源管理器 WMI 支持例程 注册表 硬件抽象层( HAL ). Windows 驱动程序. 驱动程序的功能 发送控制命令,进行错误处理

astra
Download Presentation

第五章 设备管理

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 第五章 设备管理

  2. 设备管理---概述 • Windows I/O系统概述 • I/O系统结构 • Windows驱动程序 • I/O系统内核对象 • I/O请求和处理

  3. Windows I/O系统概述 • I/O系统: 负责管理输入输出设备。 向用户隐藏硬件细节。

  4. I/O系统结构 • I/O系统组成 • I/O管理器 • 设备驱动程序 • PnP管理器 • 电源管理器 • WMI支持例程 • 注册表 • 硬件抽象层(HAL)

  5. Windows驱动程序 • 驱动程序的功能 • 发送控制命令,进行错误处理 • 对各种可能的有关设备排队、挂起、唤醒等操作进行处理 • 执行缓冲区策略 • 执行一些特殊处理,比如代码转换。 • 驱动程序的分类 • 用户态驱动程序:虚拟设备驱动程序和Windows子系统打印机驱动程序 • 核心态驱动程序:文件系统驱动程序 、即插即用驱动程序 、非即插即用驱动程序 • 其他内核态驱动程序:WDM驱动程序、分层的驱动程序

  6. Windows驱动程序--续 驱动程序分类图:

  7. Windows驱动程序--续 • 驱动程序的基本结构 • 初始化例程 • “添加-设备”例程 • 分发例程 • 启动I/O例程 • 中断服务例程 • DPC例程

  8. I/O系统内核对象 • 文件对象 文件对象代表一个文件、设备或目录的打开实例。Windows系统将所有的设备都当成文件,所以文件对象就代表这个设备的设备对象。 • 驱动程序对象 • 驱动程序代表 系统中的一个 独立的驱动程序 • 驱动程序对象结构

  9. I/O系统内核对象--续 • 设备对象和设备扩展 • 设备对象 代表一个具体的物理设备。 • 设备扩展 包含与特定设备相关的数据。 • 设备对象中包含一个指向对应驱动程序对象的指针,这样I/O管理器就能在接收到一个I/O请求时应该调用哪个驱动程序来处理该I/O请求。 • “下一个设备对象”指针指向属于同一个驱动程序的下一个设备对象,该域把多个设备对象连接起来。

  10. I/O系统内核对象--续 • 对象之间的关系 • 文件对象指向一个打开的设备实例,每当一个线程打开一个文件或设备时,都用一个文件对象指向对应的设备对象 • 驱动程序对象有多个与他相关的设备对象,这样就能方便的实现对硬件设备的控制。 • 设备对象还有一个指针指向该驱动程序对象,I/O管理器在接收到一个I/O请求时就知道该调用哪个驱动程序。

  11. I/O请求和处理 • I/O请求包 I/O系统使用一个I/O请求包(IRP,I/O Request Packet)表示每个I/O请求。当线程调用I/O服务时,I/O管理器就为该请求创建一个IRP数据结构,同时为该IRP传递一个指向相应驱动程序的指针。当驱动程序接收到一个IRP包时,执行IRP指定的操作,操作完成后将该IRP传递给I/O管理器。

  12. I/O请求和处理--续 • I/O请求处理 • 请求处理过程: • I/O管理器接收用户发来的请求,并为该请求分配一个IRP数据结构。 • 检查I/O请求的合法性,并将IRP传递给合适的驱动程序。 • 驱动程序根据IRP的参数设置对设备进行操作。 • 操作完成时,驱动程序将IRP传递给I/O管理器。 • I/O管理器检查IRP的状态域,查看用户的I/O请求是否完成。

  13. I/O请求和处理--续 • I/O请求处理过程图

  14. 设备管理---实验 WDM驱动程序 驱动程序实例 驱动程序加载

  15. WDM驱动程序 • WDM是一个分层的驱动程序模型。在该模型中,驱动程序的层和堆栈一起工作处理I/O请求。

  16. WDM驱动程序结构 可以把一个完整的驱动程序看作一个容器,它包含许多例程,当操作系统遇到一个IRP时,它就调用这个容器中的例程执行该IRP的各种操作。 驱动程序一般都有几个支持不同类型IRP的派遣函数,因此WDM驱动程序开发者的一个任务就是为这个容器选择所需要的例程。 WDM驱动程序--续

  17. WDM驱动程序--续 • DriverEntry例程 DriverEntry是内核模式驱动程序主入口点函数,大部分的设备初始化工作都是在这个例程中完成的。函数原型如下: NTSTATUS DriverEntry ( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ); 函数返回值是一个长整型的NTSTATUS值

  18. WDM驱动程序--续 DriverEntry函数的主要工作有一下几个方面: • 首先是为驱动程序指定派遣函数。 • 每个WDM驱动程序必须能处理PNP、POWER、SYSTEM_CONTROL这三种请求;应该在这里为这些请求指定派遣函数。 • 在省略号处,你可以插入设置其它MajorFunction指针的其他代码,比如IRP_MJ_CREATE、IRP_MJ_READ、IRP_MJ_WRITE等。 • 如果驱动程序需要访问设备的服务键,可以在这里备份RegistryPath串。 • 返回STATUS_SUCCESS说明函数成功。如果失败,应该返回NTSTATUS.H中的一个错误代码,或者返回用户定义的错误代码。STATUS_SUCCESS的值为0。

  19. WDM驱动程序--续 • AddDevice例程 DriverEntry例程只能在驱动程序第一次被装入时执行一次,但是一个驱动程序可以被多个实际的设备利用,所以WDM驱动程序有一个特殊的AddDevice函数,PnP管理器为每个设备实例调用该函数。 函数原型为: NTSTATUS AddDevice ( PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT pdo )

  20. WDM驱动程序--续 对于功能驱动程序,其AddDevice函数的基本职责是创建一个设备对象并把它连接到以pdo为底的设备堆栈中。相关步骤如下: • 调用IoCreateDevice创建设备对象,并建立一个私有的设备扩展对象。 • 寄存一个或多个设备接口,以便应用程序能知道设备的存在。另外,还可以给出设备名并创建符号连接。 • 初始化设备扩展和设备对象的Flag成员。 • 调用IoAttachDeviceToDeviceStack函数把新设备对象放到堆栈上。

  21. WDM驱动程序--续 • 分发例程 分发例程是一个设备驱动程序所提供的主要函数。可以实现设备的打开、关闭、读、写、电源管理、系统控制等功能。 分发例程主要包括以下几个: • 启动I/O例程 • 中断服务程序(ISR) • 中断服务的DPC例程 • 一个或者多个I/O完成例程 • 取消I/O例程 • 系统停机通知例程 • “错误-记录”例程

  22. WDM驱动程序--续 所有的分发函数都有一个统一的函数原型: NTSTATUS dispatch_function( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { //添加函数处理代码 return STATUS_SUCCESS; }

  23. WDM驱动程序--续 • Unload例程 DriverUnload例程的作用是释放DriverEntry例程在全局初始化过程中申请的任何资源,但它几乎没什么可做。如果你在DriverEntry中备份了RegistryPath串,应该在这里释放备份所占用的内存: VOID DriverUnload (PDRIVER_OBJECT DriverObject) { RtlFreeUnicodeString(&servkey); } 如果DriverEntry例程返回一个失败状态代码,系统将不再调用DriverUnload例程。因此不能让DriverEntry例程出错后产生任何副作用,必须在它返回错误代码前消除副作用。

  24. 驱动程序实例 • 源代码组成 HelloWorld驱动程序的源代码由四个文件组成,分别是HelloWorld.c,HelloWorld.h,makefile和source,这四个文件存放在HelloWorld文件夹里,下面分别介绍这四个文件的内容。 • HelloWorld.h HelloWorld.h文件主要工作是定义一些宏,和进行函数原型声明。

  25. 驱动程序实例--续 • HelloWorld.c 该文件包含三个函数,分别DriverEntry(),HelloWorldDispatch(),HelloWorldUnload()。 • DriverEntry()是驱动程序的入口函数 • HelloWorldDispatch()是分发函数,负责实现驱动程序的读写、打开、关闭等操作; • HelloWorldUnload()是驱动程序的卸载函数 • MAKEFILE文件和SOURCE文件 • 对于所有的驱动程序,MAKEFILE文件都是一样的 . • SOURCE文件包含一些宏,用以指导BUILD工具如何生成驱动程序可执行文件,从哪里获得输入以及在哪里进行输出。

  26. 驱动程序加载 • 驱动安装过程分析 加载和运行一个服务需要执行的典型操作步骤有: • 调用OpenSCManager()打开服务控制管理器,获取管理器句柄。 • 调用CreateService()创建一个服务,服务类型为内核驱动。 • 调用OpenService()取得服务句柄。 • 调用StartService()启动服务。 • 调用CloseServiceHandle()关闭服务句柄。

  27. 驱动程序的安装函数 执行流程图 当调用CreateService创建服务时,系统调用NtLoadDriver函数执行驱动程序的加载操作,但是NtLoadDriver只做一些判断,具体的加载工作由IopLoadUnloadDriver函数完成,所以上图中有一个从CreateService到NtloadDriver的调用,还有一个从NtLoadDriver到IopLoadUnloadDriver的调用路线,下面会介绍IopLoadUnloadDriver所做的具体工作。当调用StartService启动服务时,系统会调用驱动程序的入口点函数,进行一些初始化操作。 驱动程序加载--续

  28. 驱动程序加载--续 • 关键代码分析 NtLoadDriver( )函数在 \wrk-v1.2\base\ntos\io\iomgr\loadunld.c中定义,函数原型如下: NTSTATUS NtLoadDriver ( __in PUNICODE_STRING DriverServiceName ); • 参数:DriverServiceName是要加载的驱动程序在注册表中的名称。这是一个UNICODE_STRING类型的参数,指定要加载的驱动程序。 • 返回值:成功操作结束后返回操作的状态码,失败则返回NULL。

  29. 驱动程序加载--续 NtLoadDriver() 函数执行流程图

  30. 驱动程序加载--续 • 实验目的 验证驱动程序的动态加载过程。 • 实验原理 验证用户态应用程序在动态加载驱动程序时对NtLoadDriver ( )函数的调用过程。 • 实验环境 调试工具:Windbg 编程工具:Visual Studio 2005 操作系统:VMware 5.0+Windows Server 2003 • 实验内容 利用Visual Studio编写一个loadsys函数实现驱动程序的动态加载,然后编写一个程序test001,对驱动程序的功能表现进行测试。

  31. 驱动程序加载--续 • 实验过程 • 步骤1:修改源代码 根据关键代码分析部分的结果, 对\wrk-v1.2\base\ntos\io\iomgr\loadunld.c中的NtLoadDriver 函数添加注释信息 • 步骤2:重新编译WRK内核 • 步骤3:加载驱动程序 • 步骤4:卸载驱动程序

More Related