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

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

时间: 2024-11-17 11:02:55

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

Windows驱动开发基础(八)内存管理

Windows驱动开发基础系列,转载请标明出处:http://blog.csdn.net/ikerpeng/article/details/38826159 就32位的计算机来说,他有4G的真实的物理内存.但是这样是不够的,于是引入了虚拟内存的概念.使得每一个进程都有4G的虚拟内存. 虚拟内存实际上就是采用了一种映射的方式.4G的内存实际上被分页.一般来说一个页的大小是4K.也是说它被分为了1M个页.在这么多的页里面,有一部分是对应于物理内存的(可以是多对一的):有一部分是对应于磁盘上的空间,但

Windows 驱动开发基础(九)内核函数

Windows 驱动开发基础系列,转载请标明出处:http://blog.csdn.net/ikerpeng/article/details/38849861 这里主要介绍3类Windows的内核函数:字符串处理函数,文件操作函数, 注册表读写函数.(这些函数都是运行时函数,所以都有Rtl字样) 1 字符串处理函数 首先驱动程序中,常用的字符串包括4种:CHAR (打印的时候注意小写%s), WCHAR(打印的时候注意大写%S), ANSI_STRING, UNICODE_STRING.后面两种

Windows 驱动开发基础(六)NT驱动的基本结构

Windows 驱动开发基础系列,转载请标明出处:http://blog.csdn.net/ikerpeng/article/details/38821919 NT类型的驱动即不是即插即用的驱动,主要包括3部分:DriverEntry函数,CreateDevice函数,DriverUnload函数.其实还有IRP派遣函数,但是这里先不做介绍. 接下来详细的说明一下. 系统启动的时候,就创建了系统进程:驱动加载的时候,系统启动一个新的线程,创建一个驱动对象.而当系统线程调用DriverEntry函

Windows 驱动开发 - 基础1

原来的驱动开发都是WDM(Windows Driver Model)的,那时微软推出DDK(Driver Developer Kit)工具. 现在微软进行了升级由WDF(Windows Driver Foundation)来替代WDM,同时推出WDK(Windows Driver Kit)工具. 安装WDK要求的最低系统为Win XP SP3以上. 推荐使用的IDE:VS2010 一.WDM与WDF的区别 (1) 前者使用面向过程,后者可使用面向对象. (2) 前者可开发总线筛选驱动程序; 后者

Windows 驱动开发 - 基础2

名词:IRP; PDO; FiDO1; FDO; Windows 内核设计本身是不与设备交互由.设备驱动程序检测连接的设备,该设备提供的客户端功能接口与 Windows 内核间接通信.Windows 提供了一个抽象的设备支持接口调用驱动程序模型.驱动程序开发人员的工作是提供一个实现该接口已支持设备的具体要求. .设备栈(Device Stack) 设备的每一次驱动,就会产生一个设备栈. I/O Request (1) 写请求 Win API:WriteFile (2) 读请求 Win API:R

Windows 驱动开发 - 1

上篇<Windows 驱动开发 - 基础2>已经介绍了windows大概的框架.那么使用WDF有那些的不同呢? 我们知道在WDF中,KMDF是必须的.而KMDF是架构在WDM之上的.  WDM驱动程序模型 在 WDM 驱动程序模型中,每个硬件设备至少有两个驱动程序.其中一个驱动程序我们称为功能(function)驱动程序,通常它就是你认为的那个硬件设备驱动程序.它了解使硬件工作的所有细节,负责初始化 I/O 操作,有责任处理 I/O 操作完成时所带来的中断事件,有责任为用户提供一种设备适合的控

(转)Windows驱动编程基础教程

版权声明 本书是免费电子书. 作者保留一切权利.但在保证本书完整性(包括版权声明.前言.正文内容.后记.以及作者的信息),并不增删.改变其中任何文字内容的前提下,欢迎任何读者 以任何形式(包括各种格式的文档)复制和转载本书.同时不限制利用此书赢利的行为(如收费注册下载,或者出售光盘或打印版本).不满足此前提的任何转载. 复制.赢利行为则是侵犯版权的行为. 发现本书的错漏之处,请联系作者.请不要修改本文中任何内容,不经过作者的同意发布修改后的版本. 作者信息 作者网名楚狂人.真名谭文.在上海从事W

Windows驱动开发(中间层)

Windows驱动开发 一.前言 依据<Windows内核安全与驱动开发>及MSDN等网络质料进行学习开发. 二.初步环境 1.下载安装WDK7.1.0(WinDDK\7600.16385.1) 地址:https://msdn.microsoft.com/en-us/windows/hardware/hh852365 2.下载InstDrv软件(用于安装.启动.停止.卸载驱动) 界面如下: 注:srvinstw.exe 也可以安装.卸载sys文件,但需要手动开启.关闭,即在cmd命令窗口下执行

Windows驱动开发(二)

本节主要介绍驱动开发的一些基础知识. 1. 驱动程序的基本组成 1.1. 最经常见到的数据结构 a. DRIVER_OBJECT驱动对象 [cpp] view plaincopy // WDK中对驱动对象的定义 // 每个驱动程序都会有一个唯一的驱动对象与之对应 // 它是在驱动加载时被内核对象管理程序创建的 typedef struct _DRIVER_OBJECT { CSHORT Type; CSHORT Size; // // The following links all of the