windows驱动程序基础_驱动程序有哪些

windows驱动程序基础_驱动程序有哪些驱动对象每个驱动程序会有唯一的驱动对象与之对应,并且这个驱动对象是在驱动加载的时候被内核中的对象管理程序所创建的。驱动对象用DRIVER_OBJECT数据结构表示,它作为驱动的一个实例被内核加载,并

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

  • 驱动对象

每个驱动程序会有唯一的驱动对象与之对应,并且这个驱动对象是在驱动加载的时候被内核中的对象管理程序所创建的。驱动对象用DRIVER_OBJECT数据结构表示,它作为驱动的一个实例被内核加载,并且内核对一个驱动只加载一个实例。确切的说,是由内核中的I/O管理器负责加载的。驱动程序需要在DriverEntry中初始化。

其结构如下:

 1 typedef struct _DRIVER_OBJECT {
 2     CSHORT Type;
 3     CSHORT Size;
 4 
 5     //
 6     // The following links all of the devices created by a single driver
 7     // together on a list, and the Flags word provides an extensible flag
 8     // location for driver objects.
 9     //
10 
11     PDEVICE_OBJECT DeviceObject;//每个驱动程序会有一个或多个设备对象,每个设备对象都有 12     //一个指针指向下一个设备对象,最后一个设备对象指向空。此处的DeviceObject指向驱动对象的第一个设备对象。 13     //通过DeviceObject,就可以遍历驱动对象里的所有设备对象。
14     ULONG Flags;
15 
16     //
17     // The following section describes where the driver is loaded.  The count
18     // field is used to count the number of times the driver has had its
19     // registered reinitialization routine invoked.
20     //
21 
22     PVOID DriverStart;
23     ULONG DriverSize;
24     PVOID DriverSection;
25     PDRIVER_EXTENSION DriverExtension;
26 
27     //
28     // The driver name field is used by the error log thread
29     // determine the name of the driver that an I/O request is/was bound.
30     //
31 
32     UNICODE_STRING DriverName;//驱动程序的名字,一般为\Driver\[驱动程序名称]
33 
34     //
35     // The following section is for registry support.  Thise is a pointer
36     // to the path to the hardware information in the registry
37     //
38 
39     PUNICODE_STRING HardwareDatabase;
40 
41     //
42     // The following section contains the optional pointer to an array of
43     // alternate entry points to a driver for "fast I/O" support.  Fast I/O
44     // is performed by invoking the driver routine directly with separate
45     // parameters, rather than using the standard IRP call mechanism.  Note
46     // that these functions may only be used for synchronous I/O, and when
47     // the file is cached.
48     //
49 
50     PFAST_IO_DISPATCH FastIoDispatch;
51 
52     //
53     // The following section describes the entry points to this particular
54     // driver.  Note that the major function dispatch table must be the last
55     // field in the object so that it remains extensible.
56     //
57 
58     PDRIVER_INITIALIZE DriverInit;
59     PDRIVER_STARTIO DriverStartIo;
60     PDRIVER_UNLOAD DriverUnload;
61     PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION + 1];
62 
63 } DRIVER_OBJECT;

其结构如图所示:

windows驱动程序基础_驱动程序有哪些

  • 设备对象

如上所述,设备对象会有一个指针指向下一个设备对象,形成一个设备链,设备链上的第一个设备是由DRIVER_OBJECT结构体中指明的。

其定义如下:

 1 typedef struct DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) _DEVICE_OBJECT{
 2     CSHORT Type;
 3     USHORT Size;
 4     LONG ReferenceCount;
 5     struct _DRIVER_OBJECT *DriverObject;//指向驱动程序中的驱动对象。同属于一个驱动程序的设备  6     //对象指向的是统一的驱动对象
 7     struct _DEVICE_OBJECT *NextDevice;//设备链中的下一个设备对象
 8     struct _DEVICE_OBJECT *AttachedDevice;//通常指向的是过滤驱动的设备对象
 9     struct _IRP *CurrentIrp;//使用StartIO例程的时候,指向正在处理的IRP包
10     PIO_TIMER Timer;
11     ULONG Flags;                                // See above:  DO_...
12     ULONG Characteristics;                      // See ntioapi:  FILE_...
13     __volatile PVPB Vpb;
14     PVOID DeviceExtension;//指向设备的扩展对象,被指向的这个结构体是由程序员自己定义的
15     DEVICE_TYPE DeviceType;//指明设备的类型,如果创建的是虚拟设备,应选择FILE_DEVICE_UNKNOWN
16     CCHAR StackSize;
17     union {
18         LIST_ENTRY ListEntry;
19         WAIT_CONTEXT_BLOCK Wcb;
20     } Queue;
21     ULONG AlignmentRequirement;
22     KDEVICE_QUEUE DeviceQueue;
23     KDPC Dpc;
24 
25     //
26     //  The following field is for exclusive use by the filesystem to keep
27     //  track of the number of Fsp threads currently using the device
28     //
29 
30     ULONG ActiveThreadCount;
31     PSECURITY_DESCRIPTOR SecurityDescriptor;
32     KEVENT DeviceLock;
33 
34     USHORT SectorSize;
35     USHORT Spare1;
36 
37     struct _DEVOBJ_EXTENSION  *DeviceObjectExtension;
38     PVOID  Reserved;
39 
40 } DEVICE_OBJECT;

设备对象结构如图所示:

windows驱动程序基础_驱动程序有哪些

  • NT式驱动的基本结构

DriverEntry对驱动程序进行初始化工作,它是由系统进程所调用的。驱动加载的时候,系统进程启动新的线程,调用执行体组件中的对象管理器,创建一个驱动对象。这个驱动对象是一个DRIVER_OBJECT的结构体。另外,系统进程调用执行体组件中的配置管理程序,查询此驱动程序对应的注册表中的项。

对象管理器传入一个没有被初始化的对象的指针pDriverObject,而这个指针所指向的结构体就在DriverEntry中被填入内容(初始化)

windows驱动程序基础_驱动程序有哪些

在DriverEntry中,一般设置卸载例程和IRP的派遣函数,这些都是对驱动对象的设置。

  • 创建设备对象
NTSTATUS IoCreateDevice(
  _In_     PDRIVER_OBJECT  DriverObject,
  _In_     ULONG           DeviceExtensionSize,
  _In_opt_ PUNICODE_STRING DeviceName,//设备名用UNICODE字符串指定,且字符串必须是“\Device\[设备名]”
  _In_     DEVICE_TYPE     DeviceType,
  _In_     ULONG           DeviceCharacteristics,
  _In_     BOOLEAN         Exclusive,
  _Out_    PDEVICE_OBJECT  *DeviceObject
);

设备名只能被内核模式下的其它驱动所识别。用户模式下的程序要识别设备只有两种方法,一种是通过符号链接找到设备,二是通过设备接口找到设备。例如,C盘,指的是名为“C:”的符号链接,其真正的设备对象是“\Device\HarddiskVolume1”。

创建符号链接的函数如下:

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

在内核模式下,符号链接是以“\??\”开头的,如C盘就是“\??\C:”,而用户模式下,是以“\\.\”开头的,如“\\.\C:”

  • DriverUnload

在驱动对象中设置DriverUnload例程,此例程在驱动被卸载的时候调用。它通常负责删除在DriverEntry中创建的设备对象,并且将设备对象所关联的符号链接删除。另外,它还进行一些资源的回收。

  •  WinObj

以管理员身份运行才可以看到驱动对象:

windows驱动程序基础_驱动程序有哪些

查看设备对象:

windows驱动程序基础_驱动程序有哪些

查看符号链接:

windows驱动程序基础_驱动程序有哪些

  • DeviceTree

查看驱动对象:

windows驱动程序基础_驱动程序有哪些

查看设备对象:

windows驱动程序基础_驱动程序有哪些

  • 设备的层次结构

驱动程序的垂直层次结构:

每层的设备对象由不同的驱动程序所创建,或者说每层的设备对应着不同的驱动程序。底层设备对象寻找上一层的设备对象是依靠底层设备对象的AttachedDevice来寻找,如果某一个设备的AttachedDevice为空,说明已经到了设备堆栈的顶部,如图所示:

windows驱动程序基础_驱动程序有哪些

而高层设备寻找低一层的设备对象,设备对象没有相关子域可以使用。解决的办法是通过程序员自定义设备扩展,在设备扩展记录低一层的设备对象。

驱动程序的水平层次结构:

 

windows驱动程序基础_驱动程序有哪些

以USB设备为例,首先在PCI总线上,会枚举到USB控制器设备,并加载PDO和FDO。这个FDO会枚举在这个控制器上的USB HUB设备,为之创建PDO,并加载相应的FDO。该FDO枚举所有插在USB HUB上的USB设备,为之创建PDO,并加载相应的FDO。我们可以利用DriverTree查看一个驱动设备的加载过程:

windows驱动程序基础_驱动程序有哪些

  • 实验:枚举设备对

代码如下:

windows驱动程序基础_驱动程序有哪些

但此时输出结果又乱码:

windows驱动程序基础_驱动程序有哪些

出现乱码是因为,Buffer的类型是PWCHAR,以%S格式输出这个字符串需要Buffer有0结尾来判断输出的长度,而在给UnicodeString类型的赋值时,其中的Buffer并没有传入这个0。

所以应改为如下代码:

windows驱动程序基础_驱动程序有哪些

这样就能正常输出了:

windows驱动程序基础_驱动程序有哪些

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/167905.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • webpack es6转es5原理_webpack和vue cli区别

    webpack es6转es5原理_webpack和vue cli区别首先下载babel-loadernpminstall–save-devbabel-loader@7babel-corebabel-preset-es2015要在最外部输入指令不然会报错然后在webpack.config.js中写相关代码{test:/\.js$/,exclude:/(node_modules|bower_components)/,use:{

  • goland 2021.4.14 激活码_通用破解码

    goland 2021.4.14 激活码_通用破解码,https://javaforall.cn/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

  • Flash cookie — 本地共享对象(LOCAL SHARED OBJECTS)

    Flash cookie — 本地共享对象(LOCAL SHARED OBJECTS)写道本地共享对象(有时也称为“Flashcookie”)是一些可由您访问的站点在您的计算机上创建的数据文件。共享对象大多数情况下用来增强您浏览Web的体验。网站可以在您的计算机上编写cookie,当您下次访问该网站时,它将加载该cookie及其信息,从而使您拥有一种更加个性化的体验。例如,您可能让站点记住您的登录名。该信息存储在cookie中,并在您下次访问时被检索…

  • Python源码剖析_python编程300例pdf

    Python源码剖析_python编程300例pdf关注“Java后端技术全栈”回复“面试”获取全套面试资料Python是一种跨平台的计算机程序设计语言,是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。Python最初被设…

  • mysql:Windows修改MySQL数据库密码(修改或忘记密码)

    mysql:Windows修改MySQL数据库密码(修改或忘记密码)今天练习远程访问数据库时,为了方便访问,就想着把数据库密码改为统一的,以后我们也会经常遇到MySQL需要修改密码的情况,比如密码太简单、忘记密码等等。在这里我就借鉴其他人的方法总结几种修改MySQL密码的方法。我就以实际操作修改root密码为例,操作系统为windows这里我们需要注意的是,修改MySQL是需要MySQL中的root权限,一般用户是无法更改的,除非请求管理员。修改密码的三种简…

  • java中|与||,&与&&到底有什么区别呢?

    java中|与||,&与&&到底有什么区别呢?在java中,很多人都不知道&与&&,|与||的区别。&,&&:(与,短路与):一样的地方就是二者执行最后的结果是一样的,但是执行的过程有区别,对于&:无论&左边是否为false,他都会继续检验右边的boolean值。对于&&:只要检测到左边Boolean值为false时,就会直接判断结果,不会在检验右边的值(因为”与”有一个false最后结果就是false了)所以&&的执行效率更

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号