Windows驱动开发基础:驱动程序的数据结构。转载请标明出处:http://blog.csdn.net/ikerpeng/article/details/38794405

I/O管理器定义了一些数据结构,这些很重要。

1. 驱动对象(DRIVER_OBJECT)

通过一个typedef 定义的以一个struct:

<span style="font-family:Microsoft YaHei;">typedef struct
{
PDEVICE_OBJECT DeviceObject; //指向驱动程序创建的设备对象</span>
<span style="font-family:Microsoft YaHei;">UNICODE_STRING  Drivername // 驱动名称
PUNICODE_STRING HardwareDatabase; //记录的是设备的硬件数据库名,这里同样用Unicode字符串记录
PFAST_IO_DISPATCH FastIoDispatch;//文件驱动中用到的派遣函数
PDRIVER_INITIALIZE DriverInit;//指向DriverEntry函数的,这是通过IO管理器来建立的。
PDRIVER_STARTIO DriverStartIo;//记录StartIO例程的函数地址,用于串行化操作
PDRIVER_UNLOAD DriverUnload;//指定驱动卸载时所用的回调函数地址
PDRIVER_DISPATCH MajorFunction[IRP_MJ_NUM+1];//指向驱动程序的DispatchXXX函数指针的数组
}DRIVER_OBJECT,*PDRIVER_OBJECT;指向驱动程序的DispatchXXX函数指针的数组</span>

里面有一些重要的数据结构:

DeviceObject: 设备对象,可能是一个或多个。由程序猿自己创建,驱动程序被卸载的时候,遍历每一个DriverObject并删除;

DeviceName:设备名称,保存在Unicode字符串里面

HardwareDatabase:

HardwareDatabase记录的是设备的硬件数据库名,这里同样用Unicode字符串记录。该字符串一般为HKEY_LOCAL_MACHINE\Hardware\DESCRIPTION\System,是一个注册表路径。
FastIoDispatch:

文件驱动中用到的派遣函数。指向这个驱动程序的FastIO入口点定义的一个结构。这个成员只能通过FSDs和网络传输驱动来使用。
DriverInit:

指向DriverEntry函数的,这是通过IO管理器来建立的。
DriverStartIo:

记录StartIO例程的函数地址,用于串行化操作,如果一个驱动程序没有StartIo函数,这个成员将是NULL。
DriverUnload:

指定驱动卸载时所用的回调函数地址,如果驱动程序没有卸载函数,这个成员将是NULL。
MajorFunction[IRP_MJ_NUM+1]:

指向驱动程序的DispatchXXX函数指针的数组。每个驱动程序至少要设置一个DispatchXXX函数指针在这个数组里来处理这个驱动程序IRP请求包。任何一个驱动程序可以设置和IRP_MJ_XXX代码一样多的DispatchXXX来处理IRP请求包.每个DispatchXXX结构如下:
NTSTATUS DispatchXXX(IN PDEVICE_OBJECT DeviceObjec, IN PIRP Irp);

2. 设备对象(DeviceObject):

一张图理一下里面的成员的关系:

每个驱动都会有设备对象,每一个设备对象都有一个指针指向下一个设备对象(最后一个为空)。结构体定义如下:

<span style="font-family:Microsoft YaHei;">typedef struct DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) _DEVICE_OBJECT
{CSHORT Type;USHORT Size;LONG ReferenceCount;/*指向驱动程序中驱动对象的指针*/struct _DRIVER_OBJECT *DriverObject;/*指向下一个设备对象的指针*/struct _DEVICE_OBJECT *NextDevice;struct _DEVICE_OBJECT *AttachedDevice;/*当前IRP结构*/struct _IRP *CurrentIrp;PIO_TIMER Timer;/*设备对象的特性标志*/ULONG Flags;ULONG Characteristics;_volatile PVPB Vpb;/*指向设备扩展对象的指针*/PVOID DeviceExtension;/*指明设备类型*/DEVICE_TYPE DeviceType;/*堆栈的最小层数*/CCHAR StackSize;union {LIST_ENTRY ListEntry;WAIT_CONTEXT_BLOCK Wcb;} Queue;/*内存对齐*/ULONG AlignmentRequirement;KDEVICE_QUEUE DeviceQueue;KDPC Dpc;/**下列成员用于支持文件系统的互斥操作*以便对文件系统处理线程使用设备的计数保持跟踪*/ULONG ActiveThreadCount;PSECURITY_DESCRIPTOR SecurityDescriptor;KEVENT DeviceLock;USHORT SectorSize;USHORT Spare1;struct _DEVOBJ_EXTENSION  *DeviceObjectExtension;PVOID  Reserved;} DEVICE_OBJECT;
typedef struct _DEVICE_OBJECT *PDEVICE_OBJECT;</span>

下面分别描述设备对象中驱动程序可访问成员的具体含义:

PDRIVER_OBJECT DriverObject:指向驱动程序中的驱动对象。同属一个驱动程序的驱动对象指针都指向同一个驱动对象。

PDEVICE_OBJECT NextDevice:指向下一个设备对象。这里的下一个设备对象是同一个驱动程序创建的若干设备对象中的一个。每个设备对象会根据

NextDevice成员形成链表,从而遍历每个设备对象。在每次成功调用IoCreateDevice 后,I/O管理器就会更新该链表。当驱动被卸载时,需要遍历该链表,删除每个设备对象。

PIRP CurrentIrp:如果驱动使用StartIO例程,此成员将指向当前的IRP结构,否则为NULL。

ULONG Flags:此成员是一个32位的无符号整型变量,每个位有不同的含义。可通过按位取“或”操作为新创建的设备对象设置不同的特性。

ULONG Characteristics:此成员说明设备对象的特性,当驱动程序调用IoCreate-Device时,可设置FILE_REMOVABLE_MEDIA(表示存储设备支持可移动介质)、FILE_READ_ONLY_DEVICE(表示设备不能写)、FILE_FLOPPY_DISKETTE(表示设备是软盘设备)等值。

PVOID DeviceExtension:指向设备扩展对象。

DEVICE_TYPE DeviceType:指明设备的类型,由IoCreateDevice设置,根据设备的需要填写相应的设备类型。

CCHAR StackSize:在多层驱动的情况下,驱动与驱动之间形成类似堆栈的结构。IRP会依次从最高层传递到最底层。StackSize就是用于指定发送到该驱动的IRP在堆栈位置的最小层数的。IoCreateDevice在一个新创建的设备对象中设置该成员。

ULONG AlignmentRequirement:进行数据传输的时候,规范设备的地址对齐

其中的DeviceType:指明设备的类型,当作为一个虚拟的设备的时候选择:FILE_DEVICE_UNKNOWN.

3. 设备扩展:

设备对象记录的是通用的信息,而一些特殊的信息则要记录于设备扩展里面了。

在驱动程序里面最好不要使用全局变量,这往往导致函数的不可重入性。将全局变量以设备扩展的形式存储,并加以保护措施,这样可以解决这个问题。

参考文献:

《Windows驱动开发技术详解》

http://www.cnblogs.com/qintangtao/archive/2013/04/09/3009790.html

Windows驱动开发基础(五)驱动程序的数据结构相关推荐

  1. windows 驱动开发基础(二)事件通知---关于irp处理,DPC,链表等

    代码来源及参考:wdk 7,路径:C:\WinDDK\7600.16385.1\src\general\event 这个例子演示了两种关于当硬件事件发生时,驱动如何通知应用程序的方法.一种是基于eve ...

  2. Windows驱动开发学习笔记(五)—— SSDT HOOK

    Windows驱动开发学习笔记(五)-- SSDT HOOK 系统服务表 系统服务描述符表 实验一:通过代码获取SSDT表地址 通过页表基址修改页属性 方法1:修改页属性 方法2:修改CR0寄存器 实 ...

  3. Windows驱动开发学习笔记(二)—— 驱动调试内核编程基础

    Windows驱动开发学习笔记(二)-- 驱动调试&内核编程基础 基础知识 驱动调试 PDB(Program Debug Database) WinDbg 加载 PDB 实验:调试 .sys ...

  4. Windows驱动开发学习笔记(一)—— 环境配置第一个驱动程序

    Windows驱动开发学习笔记(一)-- 环境配置&第一个驱动程序 环境配置 第一个驱动程序 环境配置 安装VS2010:https://pan.baidu.com/s/1uZWWxCtB60 ...

  5. 【嵌入式Linux】嵌入式Linux驱动开发基础知识之LED模板驱动程序的改造:设备树

    文章目录 前言 1.驱动的三种编写方法 2.怎么使用设备树写驱动程序 2.1.设备树节点要与platform_driver能匹配 2.2.修改platform_driver的源码 3.实验和调试技巧 ...

  6. windows 驱动开发入门——驱动中的数据结构

    最近在学习驱动编程方面的内容,在这将自己的一些心得分享出来,供大家参考,与大家共同进步,本人学习驱动主要是通过两本书--<独钓寒江 windows安全编程> 和 <windows驱动 ...

  7. Windows驱动编程基础教程

    前言     本书非常适合熟悉Windows应用编程的读者转向驱动开发.所有的内容都从最基础的编程方法入手.介绍相关的内核API,然后举出示范的例子.这本书只有不到70页,是一本非常精简的小册子.所以 ...

  8. Windows驱动开发书籍简介

    分享到 一键分享 QQ空间 新浪微博 百度搜藏 人人网 腾讯微博 百度相册 开心网 腾讯朋友 百度贴吧 豆瓣网 搜狐微博 百度新首页 QQ好友 和讯微博 更多... 百度分享 首页 我的主页 相册 广 ...

  9. 楚狂人Windows驱动编程基础教程

    版权声明     本书是免费电子书.作者保留一切权利.但在保证本书完整性(包括版权声明.前言.正文内容.后记.以及作者的信息),并不增删.改变其中任何文字内容的前提下,欢迎任何读者以任何形式(包括各种 ...

最新文章

  1. MFC关于Radio按钮分组与选择的操作
  2. 敏捷大观园 - 视频分享第6弹!
  3. System.out.println(Runtime.getRuntime().availableProcessors());获取cpu核数
  4. Android 圆角TabLayout
  5. Linux下配置服务器节点上的时区
  6. (28)自动化构建工具Gulp
  7. Raki的读paper小记:FastText:Enriching Word Vectors with Subword Information
  8. R语言学习笔记四:秩和检验
  9. win7系统激活最简单方法
  10. granite crushers in german
  11. 直播评论可以用html,网页制作HTML5实现直播间评论滚动效果的代码
  12. 时势下的HMS和GMS的前世今生——前生篇
  13. 云计算概念 IaaS PaaS SaaS
  14. 优秀的 Verilog/FPGA开源网站介绍
  15. 免费查重可以一直使用吗? ​​
  16. ZStack Cube:超融合3.0,场景化的一体机
  17. STM32------ADC(电压检测)
  18. 保留两位小数除法算式_小学数学小数除法练习题
  19. SQL 语句大全、MySQL原生操作语句
  20. 谜题51:那个点是什么?

热门文章

  1. 2022年12月电子学会Python等级考试试卷(三级)答案解析
  2. 无线网络覆盖方案案例
  3. Swift--监听iPhone键盘弹出及隐藏事件
  4. Vue数据绑定(单向绑定,双向绑定)
  5. php mysql 溢出_mysql时间戳溢出问题
  6. 群晖Synology 218+拆机升级内存12GB
  7. chatgpt生成【2023高考作文】北京卷二 - 亮相
  8. linux partprobe命令
  9. mysql unix时间加索引_【mysql】mysql时间字段怎么加索引
  10. Java中接口继承接口