转载请标明是引用于 http://blog.csdn.net/chenyujing1234

欢迎大家提出意见,一起讨论!

参考书籍<<Windows驱动开发技术详解>>

一、数据结构

1、驱动对象(DRIVER_OBJECT)

每个驱动程序会有唯一的驱动对象与之对应,且这个驱动对象是在驱动加载时,

被内核中的对象管理程序所创建的。

typedef struct _DRIVER_OBJECT {
CSHORT Type;
CSHORT Size;
//
// The following links all of the devices created by a single driver
// together on a list, and the Flags word provides an extensible flag
// location for driver objects.
//
PDEVICE_OBJECT DeviceObject;  // 每个驱动程序会有一个或多个设备对象。其中每个
// 设备对象都有一个指向下一个驱动对象,最后一个设备对象指向空。
// 此处的DeviceObject指赂驱动对象的第一个设备对象。
// 通过DeviceObject就可以遍历驱动对象里的所有设备对象。
// 设备对象是由程序员自己创建的,而而OS完成。
// 在驱动卸载时,遍历每个设备对象,并将其删除。
ULONG Flags;
//
// The following section describes where the driver is loaded.  The count
// field is used to count the number of times the driver has had its
// registered reinitialization routine invoked.
//
PVOID DriverStart;
ULONG DriverSize;
PVOID DriverSection;
PDRIVER_EXTENSION DriverExtension;
//
// The driver name field is used by the error log thread
// determine the name of the driver that an I/O request is/was bound.
//
UNICODE_STRING DriverName; // 驱动程序的名字,该串一般为\Driver\[驱动程序名称 ]
//
// The following section is for registry support.  Thise is a pointer
// to the path to the hardware information in the registry
//
PUNICODE_STRING HardwareDatabase;  // 记录的是设备的硬件数据库键名。
// 这里同样用UNICODE字符串记录。
// 一般为\REGISTRY\MACHINE\HARDWAR\DESCRIPTORION\SYSTEM
//
// The following section contains the optional pointer to an array of
// alternate entry points to a driver for "fast I/O" support.  Fast I/O
// is performed by invoking the driver routine directly with separate
// parameters, rather than using the standard IRP call mechanism.  Note
// that these functions may only be used for synchronous I/O, and when
// the file is cached.
//
PFAST_IO_DISPATCH FastIoDispatch;
//
// The following section describes the entry points to this particular
// driver.  Note that the major function dispatch table must be the last
// field in the object so that it remains extensible.
//
PDRIVER_INITIALIZE DriverInit;
PDRIVER_STARTIO DriverStartIo;  // 记录StartIO例程的函数地址
PDRIVER_UNLOAD DriverUnload;    // 指向驱动卸载时所用的回调函数地址
PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION + 1];
} DRIVER_OBJECT;
typedef struct _DRIVER_OBJECT *PDRIVER_OBJECT; 

2、 设备对象(DEVICE_OBJECT)

每个驱动程序会创建一个或多个设备对象,用DEVICE_OBJECT数据结构表示,每个设备对象都会有一个指针指向下一个设备对象,因此形成一个设备链。

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; // 指向下一个设备对象。这里指出的是,如果有更高一层的驱动附加
// 到这个驱动时,AttachedDevice指向的就是那个更高一层的驱动
struct _IRP *CurrentIrp;               // 在使用StartIO例程时,此域指向的是当前IRP结构。
PIO_TIMER Timer;
ULONG Flags;                           // 是一个32位的无符号整型。
ULONG Characteristics;                      // See ntioapi:  FILE_...
__volatile PVPB Vpb;
PVOID DeviceExtension;
DEVICE_TYPE DeviceType;                // 设备的类型。
CCHAR StackSize;                       // 在多层驱动情况下,驱动与驱动之间会形成类似堆栈的结构,
// IRP会依次从最高层传递到最低层。StackSize 描述的就是这个层数
union {
LIST_ENTRY ListEntry;
WAIT_CONTEXT_BLOCK Wcb;
} Queue;
ULONG AlignmentRequirement;            // 设备在大容量传输时,需要内存对齐,以保证传输速度
KDEVICE_QUEUE DeviceQueue;
KDPC Dpc;
//
//  The following field is for exclusive use by the filesystem to keep
//  track of the number of Fsp threads currently using the device
//
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;
//
// The following structure is pointed to by the SectionObject pointer field
// of a file object, and is allocated by the various NT file systems.
//
typedef struct _SECTION_OBJECT_POINTERS {
PVOID DataSectionObject;
PVOID SharedCacheMap;
PVOID ImageSectionObject;
} SECTION_OBJECT_POINTERS;

===========================================================================================================

设备对象的结构如下图:

3、设备扩展

设备对象记录“通用”设备的信息,而另外一些“特殊”信息记录在设备扩展中。各个设备扩展由程序员定义,每个设备的设备扩展也不尽相同。

设备扩展由I/O管理器创建的。并保存在非分页的内存中。

在设备扩展中会记录下列内容:

(1)设备对象的反向指针

(2)设备状态或驱动环境信息

(3)中断对象指针

(4)控制器对象指针

二、驱动的基本结构

1、NT式驱动的基本结构
1、1  驱动加载过程与驱动入口函数(DriverEntry)

参考我的另一篇博客: http://blog.csdn.net/chenyujing1234/article/details/7565364

1、2  创建设备对象

会调用IoCreateDevice函数

IoCreateDevice(
__in  PDRIVER_OBJECT DriverObject,  // 驱动对象的指针。
__in  ULONG DeviceExtensionSize,    // 指定设备扩展的大小,I/O管理器会根据这个大小
// 在内存中创建设备扩展,并与驱动对象关联。
__in_opt PUNICODE_STRING DeviceName,// 设置设备对象的名字。
__in  DEVICE_TYPE DeviceType,
__in  ULONG DeviceCharacteristics,  // 设备设备对象的特征
__in  BOOLEAN Exclusive,            // 设置设备对象是否为内核算模式下使用
__out
__drv_out_deref(
__drv_allocatesMem(Mem)
__drv_when((((inFunctionClass$("DRIVER_INITIALIZE"))
||(inFunctionClass$("DRIVER_DISPATCH")))),
__drv_aliasesMem)
__on_failure(__null))
PDEVICE_OBJECT *DeviceObject        // I/O管理器负责创建这个设备对象,并返回对象的地址。
);

设备名称用UNICODE字符串指定,且字符串必须是"\Device\[设备名]"的形式。

在Windows下的所有设备都是以类似的名字命令的。

当然也可以不指定设备名字。如果在IoCreateDevice没指定设备名字,I/O管理器会自动分配一个数字作为设备的设备名。

eg: \Device\00000001

如果指定了设备名,只能被内核模式下的其他驱动所识别。但在用户模式下的应用程序无法识别这个设备。

让应用程序能识别设备有两种方法:

(1)通过符号链接找到设备。(常用)

(2)通过设备接口找到设备。

符号链接可以理解为设备对象起了一个“别名”。设备对象的名称只能被内核模式的驱动识别,

而别名也可以被用户模式下的APP识别.

eg: 常说的C盘,指向的“C:”的符号链接,其真实对象是“\Device\HarddiskVolume1“

创建符号链接的函数是

NTSTATUS
IoCreateSymbolicLink(
    __in PUNICODE_STRING SymbolicLinkName,
    __in PUNICODE_STRING DeviceName
    );

2、WDM式驱动的基本结构

WDM驱动结构请参考我的另一篇文章

http://blog.csdn.net/chenyujing1234/article/details/7568029

WDM驱动的DriverEntry与NT式驱动的DriverEntry有以下几个不同:

(1)增加了对AddDevice函数的设置。

因为NT驱动是主动加载设备的,也就是一旦加载驱动就创建设备。

而WDM驱动是被动加载设备的。OS必须加载PDO后,调用驱动的AddDevice例程,

AddDevice负责创建FDO,并附加到PDO上。

(2)必须加入IRP_MJ_PNP的派遣回调函数。

它主要负责计算机中即插即用的处理。

具体的回调函数可以参照我的文章

http://blog.csdn.net/chenyujing1234/article/details/7580315

Window XP驱动开发(十) 驱动程序的基本结构相关推荐

  1. Window XP驱动开发(十三) 芯片功能驱动端 (代码实现,针对USB2.0 芯片CY7C68013A)

    转载请标明是引用于 http://blog.csdn.net/chenyujing1234 欢迎大家提出意见,一起讨论! 需要源码的可以与我联系. 针对USB2.0 芯片CY7C68013A+FPGA ...

  2. Window XP驱动开发(二) 环境搭建(VS2008+WDK+DDKWzard)及示例源码分析

    郁闷,做了WCE嵌入式驱动这么久还没热身够,又被调到做window xp下的驱动开发.没办法.只能受令了. 现在就开始自己的学习之旅吧. 转载请标明是引用于 http://blog.csdn.net/ ...

  3. Window XP驱动开发(二十一) 过滤驱动程序

    转载请标明是引用于 http://blog.csdn.net/chenyujing1234 欢迎大家拍砖 参考书籍<<Windows驱动开发技术详解>> 过滤驱动程序的开发十分 ...

  4. Window XP驱动开发(二十四)虚拟串口设备驱动

    转载请标明是引用于 http://blog.csdn.net/chenyujing1234 欢迎大家拍砖 在我的一篇文章<<winCE中实现虚拟串口的方法 >>中,讲到在win ...

  5. window XP驱动开发(一)如何下载WDK

    转自: http://www.cnblogs.com/fiestay/archive/2008/07/14/1242513.html 我试过了下载过程是成功的. =================== ...

  6. windows xp 驱动开发(十八) USB驱动程序开发用到的工具总结

    转载请标明是引用于 http://blog.csdn.net/chenyujing1234 欢迎拍砖! 观察USB设备的工具. 通过这些工具可以方便学习USB协议 一.   usbview 请参考我的 ...

  7. windows xp 驱动开发(三)DDK与WDK WDM的区别

    转自: http://www.cnblogs.com/hyddd/archive/2009/03/15/1412684.html 最近尝试去了解WINDOWS下的驱动开发,现在总结一下最近看到的资料. ...

  8. c语言+usb驱动开发,usb驱动程序分析

    usb驱动是linux内核中比较复杂的驱动之一,因此,大多数usb教程建议从usb-skeleton开始学习usb驱动.个人认为这是相当正确的,usb-sekelton提供了一个usb驱动开发的模板, ...

  9. i.MX 6ULL 驱动开发 十四:LED(paltform驱动框架)

    一.驱动设计思想(机制.策略.分离.分层) 驱动设计思想(机制.策略.分离.分层)_正在起飞的蜗牛的博客-CSDN博客_机制与策略分离 二.驱动开发框架 三.platform 基本概念 Linux 驱 ...

最新文章

  1. mysql 设计表_mysql,表设计
  2. 自定义关机计算机,在win7系统中自定义设置关机壁纸教程介绍
  3. 前端学习(1295):第三方模块npm
  4. yii2 smarty php,Yii2-smarty的一些小坑
  5. 静态页面评论处理以及列表处理
  6. android音效插件,安卓最强音效插件ViPER4Android(V4A)效果器 最新版(FX版)2.0.0.9/(XHiFi版)2.0.0.2_1下载...
  7. VMware搭建PXE无盘工作站,出现这种问题各位遇到过吗?
  8. 微信小程序图片上传以及剪切(image-cropper的简单使用)
  9. 旷视研究院参会PRCV2019 推进模式识别与CV技术交流
  10. 计算机睡眠和休眠哪个更好,电脑睡眠和休眠哪个好 有什么区别
  11. 上岸快手,我选择一条不一样的路
  12. 鲲鹏、昇腾、欧拉——计算产业的矩阵已足够宽广
  13. JavaScript复习
  14. Revit API之BoundingBoxXYZ的用法和剖面框(Section Box)
  15. 关于发展开源芯片技术体系的思考
  16. ComboBox控件
  17. 招聘管理系统有哪些比较实用的功能呢?
  18. 售后服务的基本流程有哪些
  19. RBF网络逼近算法(matlab)——S-Function函数实现
  20. Windows下利用**SDFormatter**格式化SD卡

热门文章

  1. 【MySQL】创建高性能的索引
  2. 计算机翻译turtle,turtle是什么意思_turtle的翻译_音标_读音_用法_例句_爱词霸在线词典...
  3. 词嵌入(word embedding)(pytorch)
  4. [补充]上集 Ch. 19-12(AJAX)在ListView / GridView的「样版」里面,放置 UpdatePanel
  5. vue中echarts使用案例:饼图(可直接使用)
  6. 【EhCache: 一款Java的进程内缓存框架】EhCache 是什么、代码实战、版本3的改进
  7. 如何写一封稍微像样的求职邮件
  8. 163.net邮箱,让海外邮件收发畅通无阻
  9. 推荐5款免费好用的chatGPT平台
  10. 计算机专业答辩系统抄袭怎么办,计算机毕业设计答辩怎么老是不过?