windows内核开发笔记十二:DriverObject结构

windows内核开发笔记十二:DriverObject结构

       学习好驱动开发,对于内核的结构的了解非常重要,只有熟悉了内核结构,才能更得心应手,每一个驱动对象代表着一个已经装载的内核模式下的驱动, 指向驱动对象的指针是驱动程序中以下例程的输入参数之一: DriverEntry, AddDevice, Reinitialize(可选例程),Unload(可选例程)。驱动对象是一个半透明对象,驱动编写者必须熟悉它的某些成员对象,以实现驱动的初始化功能和卸载功能(如果该驱动能够卸载)。

本节的学习驱动内核开发的一个重要的数据结构:驱动结构DriverObject的这个结构,这个数据结构,合计下来含有15个结构field,这些field有的是开发人员能够访问的,有的是被内核系统程序访问的,这就是所说的半透明的特性。


 

上图描述了在程序中的DriverObject的数据结构,采用C或C++语言开发的程序员,理解起来不会费劲。

    虽然 DDK头中公开了整个结构,但我们仅能直接访问或修改结构中的某些域。在图中,我把驱动程序对象的不透明域用灰背景表示。这些不透明域类似于C++类中的私有成员或保护成员,而透明域类似于公共成员。

typedef struct _DRIVER_OBJECT { 
 //  结构的类型和大小。 
      CSHORT Type;      
      CSHORT Size; 
 
  //  设备对象,这里实际上是一个设备对象的链表的开始。因为 DeviceObject 
  //  中有相关链表信息。读下一小节“设备对象”会得到更多的信息。 
      PDEVICE_OBJECT DeviceObject; 
  …… 
  //  驱动的名字 
      UNICODE_STRING DriverName; 
  …… 
  //  快速 IO分发函数 
      PFAST_IO_DISPATCH FastIoDispatch; 
   …… 
 //  驱动的卸载函数 
      PDRIVER_UNLOAD DriverUnload; 
      //  普通分发函数 
    PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION + 1]; 
} DRIVER_OBJECT;
 

这个图是在内存中的数据存储结构,下图是DriverObject和例程的调用关系。


以下列出的是驱动对象中能被驱动访问的成员:

可访问成员

  • PDEVICE_OBJECT DeviceObject

       指向一个由驱动创建的设备对象,当驱动程序调用IoCreateDevice成功时,该成员会自动更新。驱动程序可以利用该成员以及DEVICE_OBJECT对象中的NextDevice成员来实现对由该驱动创建的所有设备列表中设备的遍历。

  • PDRIVER_EXTENSION DriverExtension

    驱动扩展对象指针,该对象唯一能访问的成员是DriverExtension-> AddDevice,对应的是驱动DriverEntry例程中的AddDevice例程。

  • PUNICODE_STRING HardwareDatabase

       指向\Registry\Machine\Hardware,该路径指向的是注册表中包含该硬件的配置信息。

  • PFAST_IO_DISPATCH FastIoDispatch

       指向快速I/O入口地址,该成员之用于FSD(文件系统驱动)已经网络传输驱动。

  • PDRIVER_INITIALIZE DriverInit

       DriverEntry例程的入口点,由I\O管理器设置。

  • PDRIVER_STARTIO DriverStarIo

       驱动程序中StartIo例程的入口地址(如果有的话),当驱动初始化时,DriverEntry例程负责设置它,如果驱动程序没有StartIo,该成员为NULL。

  • PDRIVER_UNLOAD DriverUnload

       驱动程序中Unload例程的入口地址(如果有的话),当驱动初始化时,DriverEntry例程负责设置它,如果驱动程序没有StartIo,该成员为NULL。

  • PDRIVER_DISPATCHMajorFunction[IRP_MJ_MAXIMUM_FUNCTION + 1]

       派遣例程表,该表包含了驱动中DispatchXxx routines等所有派遣例程的入口地址。该数组的索引值为IRP_MJ_Xxx,该值代表每一个IRP的主功能函数代码(IRP major function code), 任何驱动都必须为IRP_MJ_Xxx请求设置入口地址。每一个DispatchXxx例程的定义在上面的图中对应的函数,这里不再做赘述说明。

不可访问成员“

  • Type :结构类型。
  • Size; :结构大小。
  • DriverName:驱动的名字。 
  • DriverStart: 驱动在内核空间的开始地址

  • DriverSize: 驱动在内核空间的大小

  • DriverSection: 驱动在内核空间段

  • Flags:它的flags 有几个域在过滤程序中经常用到。。。

    DO_BUFFERED_IO(缓冲读取)-------------DO_DIRECT_IO(直接读取)内存描述符表

    DO_DEVICE_INITIALIZING(设备的初始化)--------DO_POWER_PAGED----(电源是否可以出于分页处)
     

DriverObeject的作用如下:

1. 在操作系统首次装载一个驱动程序之后,它会创建一个数据结构用来记录该驱动,该数据结构我们称为  动对象 ( Driver Object )。

2. 驱动对象 记录与驱动程序本身相关的信息,它主要包含了除了DriverEntry之外的其它驱动程序入口函数的入口地址。( 驱动程序是一种具有多个入口函数的程  

3. 驱动对象是由操作系统创建,然后作为DriverEntry的第一个参数传递给相应的驱动程序。

4. 在获得驱动对象的指针之后,所开发的程序需要对其中的一些字段进行初始化。

 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jyl_sh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值