WDM式驱动的基本结构3 - WDM驱动程序的AddDevice例程

AddDevice例程是WDM驱动所独有的,在NT驱动中没有该例程。在DriverEntry中,需要设置AddDevice例程的函数地址。设置的方式是驱动对象中有个 DriverExtension 子域,DriverExtension中有个AddDevice子域,将该子域指向AddDevice例程的函数地址。

pDriverObject->DriverExtension->AddDevice = HelloWDMAddDevice;

和DriverEntry不同,AddDevice例程的名字可以任意命名,程序员可以用更有意义的名字作为这个函数的名字。在HelloWDM例子中,使用的名称就是HelloWDMAddDevice。

#pragma PAGEDCODE
NTSTATUS HelloWDMAddDevice(IN PDRIVER_OBJECT DriverObject,IN PDEVICE_OBJECT PhysicalDeviceObject)
{ PAGED_CODE();KdPrint(("Enter HelloWDMAddDevice\n"));NTSTATUS status;PDEVICE_OBJECT fdo;UNICODE_STRING devName;// 初始化UNICODE字符串RtlInitUnicodeString(&devName,L"\\Device\\MyWDMDevice");// 创建设备对象status = IoCreateDevice(DriverObject,sizeof(DEVICE_EXTENSION),&(UNICODE_STRING)devName,FILE_DEVICE_UNKNOWN,0,FALSE,&fdo);// 判断是否创建成功if( !NT_SUCCESS(status))return status;// 得到扩展设备PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)fdo->DeviceExtension;// 将FDO附加在PDO上pdx->fdo = fdo;pdx->NextStackDevice = IoAttachDeviceToDeviceStack(fdo, PhysicalDeviceObject);UNICODE_STRING symLinkName;RtlInitUnicodeString(&symLinkName,L"\\DosDevices\\HelloWDM");// 用设备扩展记录设备名和符号链接pdx->ustrDeviceName = devName;pdx->ustrSymLinkName = symLinkName;// 创建符号链接status = IoCreateSymbolicLink(&(UNICODE_STRING)symLinkName,&(UNICODE_STRING)devName);// 如果创建失败,则删除设备对象if( !NT_SUCCESS(status)){IoDeleteSymbolicLink(&pdx->ustrSymLinkName);status = IoCreateSymbolicLink(&symLinkName,&devName);if( !NT_SUCCESS(status)){return status;}}// 设置设备标志fdo->Flags |= DO_BUFFERED_IO | DO_POWER_PAGABLE;fdo->Flags &= ~DO_DEVICE_INITIALIZING;KdPrint(("Leave HelloWDMAddDevice\n"));return STATUS_SUCCESS;
}

从上述代码中可以看出,AddDevice例程类似于NT驱动中DriverEntry创建设备对象的相关操作,但是略有不同。AddDevice函数有两个输入参数,一个是驱动对象DriverObject,另一个是设备对象PhysicalDeviceObject。驱动对象是I/O管理器创建的驱动对象。设备对象PhysicalDeviceObject就是底层驱动创建的PDO设备对象。传进该参数的目的就是将FDO附加在PDO之上。

在AddDevice中可以分为以下几个步骤:
1. 在AddDevice通过IoCreateDevice等函数,创建了设备对象,该设备对象就是FDO,即功能驱动设备对象。和NT驱动一样,可以设置驱动对象的设备名称,也可以不设置,如果不设置设备名称,I/O管理会自动以一个数字作为该设备对象的名称。
2. 创建完FDO后,需要将FDO的地址保存下来,以便以后使用。保存的位置是在设备扩展中,在驱动程序中应该尽量避免使用全局变量,而使用设备扩展。如果该电脑中存在多个同类设备,例如,插入两个型号相同的网卡,操作系统会两次两用AddDevice例程。每个AddDevice例程创建各自的FDO,分别记录在各自的设备扩展中。
3. 驱动程序将创建的FDO附加在PDO上,附加这个动作是依靠IoAttachDeviceToDeviceStack函数实现的。IoAttachDeviceToDeviceStack的声明如下:
        

PDEVICE_OBJECT IoAttachDeviceToDeviceStack(PDEVICE_OBJECT SourceDevice,PDEVICE_OBJECT TargetDevice);

* SourceDevice:要附加在别的设备之上的设备。将FDO附加在PDO之上时,这个填写的是FDO的地址。
* TargetDevice:被附加的设备。将FDO附加在PDO之上时,这个填写的是PDO的地址,当FDO想附加在PDO上时,有时会在PDO和FDO上附加过滤驱动。此时,FDO其实是附加在过滤设备上,而过滤设备附加在PDO上。
* 返回值:附加以后,返回附加设备的下层设备。如果中间没有过滤驱动的话,返回值就是PDO,如果中间有过滤驱动,返回的是过滤驱动。

当FDO附加到PDO上时,PDO会通过AttachedDevice子域知道它上面的设备是FDO(或者是过滤驱动)。但是FDO却不知道自己的下层是什么设备。解决的办法是,通过设备扩展记录FDO下层的设备。下面是HelloWDM的设备扩展的定义:

typedef struct _DEVICE_EXTENSION
{PDEVICE_OBJECT fdo;PDEVICE_OBJECT NextStackDevice;UNICODE_STRING ustrDeviceName;    // 设备名UNICODE_STRING ustrSymLinkName;    // 符号链接名
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;

我们在自己编写驱动程序时,可以根据自己的需要定制自己的设备扩展。子域fdo是为了保存FDO的地址,以备后用。子域NextStackDevice是为了定位设备的下一层设备。

在附加操作完成,需要设定符号链接,以便用户应用程序可以访问该设备。
4. 设置fdo的flags子域。DO_BUFFERED_IO是定义设备为“缓冲内存设备”。另外~DO_DEVICE_INITIALIZING,是将Flag上的DO_DEVICE_INITIALIZING位清零。保证设备初始化完成,这一步是必须得。


 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/658203.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

笔记---中国剩余定理

全程学自y总 AcWing.204.表达整数的奇怪方式 给定 2 n 2n 2n 个整数 a a a1, a a a2,…, a a an 和 m m m1, m m m2,…, m m mn,求一个最小的非负整数 x x x,满足 ∀ i ∈ [ 1 , n ] , x ≡ m ∀i∈[1,n],x≡m ∀i∈[1,n],x≡mi ( m o d a (mod a (…

【大语言模型】大型语言模型的数据收集和预处理

前言 LLM(大型语言模型)是先进的人工智能模型,使用大量文本数据进行广泛的训练。 通过这种培训,他们学习语言结构和模式,并能够执行各种与语言相关的任务,例如摘要、翻译、情感分析等。 由于LLM具有执行以前机器难以完成的自然语言任务的卓越能力,近年来LLM受到了广泛关…

ES客户端接入方式

在 Elasticsearch (ES) 中,有两种常见的客户端接入方式:Transport Client(传输客户端)和 Node Client(节点客户端)。这两种客户端都可用于与 Elasticsearch 集群进行通信和执行操作,但它们在连接…

博科交换机常用配置命令

文章目录 1、光纤交换机IP地址查询2、什么是Zone3、创建 zone和cfg 3-1、使用 zonecreate 命令创建 zone 3-2、使用cfgcreate 命令创建cfg 3-3、使用 cfgenable 生效配置文件 3-4、使用cfgsave保存 配置文件 3-5、显示 zone 信息 4、常用后…

Backtrader 文档学习- Broker - Fillers

Backtrader 文档学习- Broker - Fillers 1. 概述 当使用交易量进行订单执行时,backtrader的模拟broker具有默认策略: 忽略交易量 (默认策略是broker忽略成交量) 基于两个前提条件:在流动性充裕的市场中进行交易&…

深度强化学习(王树森)笔记11

深度强化学习(DRL) 本文是学习笔记,如有侵权,请联系删除。本文在ChatGPT辅助下完成。 参考链接 Deep Reinforcement Learning官方链接:https://github.com/wangshusen/DRL 源代码链接:https://github.c…

HTML5的新特性

目录 一&#xff0c;新增语义化标签 二&#xff0c;新增的多媒体标签 三&#xff0c;新增input表单 四&#xff0c;新增的表单属性 一&#xff0c;新增语义化标签 二&#xff0c;新增的多媒体标签 1&#xff0c;音频&#xff1a;<audio>.。。用MP3 <audio src…

带自执行安装脚本的ROS包的生成

带自执行安装脚本的ROS包的生成 在打包和安装ROS包时, 会有一些固定的配置需要去人为实现, 比如网络配置, 设备树的管理等, 比较麻烦, 不如一次性解决掉, 所以查了相关文档 过程: # 使用bloom-generate rosdebian生成debian文件夹 bloom-generate rosdebian # 进入debian文件…

ICV:signoff_check_drc脚本

更多学习内容请关注「拾陆楼」知识星球 拾陆楼知识星球入口 往期文章链接: ICV:metal fill insertion流程 ICV:metal fill insertion脚本

Windows XP x86 sp3 安装 Python3.4.4

1 下载 Python3.4.4&#xff0c;下载地址&#xff0c;点击红色部分。 Python Release Python 3.4.4 | Python.org 2 一路 Next&#xff0c;将 C:\Python34 和 C:\Python34\Scripts 加入环境变量。 3 python 查看版本&#xff0c;python -m pip list 查看安装的包。 4 其他(打…

【数据结构】链表的一些面试题

简单不先于复杂&#xff0c;而是在复杂之后。 链表面试题 删除链表中等于给定值 val 的所有结点。OJ链接 //1.常规方法struct ListNode* removeElements(struct ListNode* head, int val) {struct ListNode* cur head, *prev NULL;while(cur){if(cur->val val){//1.头删/…

Python使用分治算法作归并排序

对于分治算法的一个较为常规的应用中&#xff0c;归并排序是一个使用分治算法的排序方式。给定一个随机排序的数组&#xff0c;我们要将其元素按照升序或者降序的方式进行排序&#xff0c;可以设想到这样的一种算法&#xff0c;如果一个数组的上半部分和下半部分已经排好序&…

聚观早报 | 360 AI搜索App上线;岚图汽车与京东达成合作

聚观早报每日整理最值得关注的行业重点事件&#xff0c;帮助大家及时了解最新行业动态&#xff0c;每日读报&#xff0c;就读聚观365资讯简报。 整理丨Cutie 1月30日消息 360 AI搜索App上线 岚图汽车与京东达成合作 三星电子在硅谷新设实验室 小米平板7系列参数曝光 Spa…

【全csdn最前沿LVGL9】基础对象lv_obj

文章目录 前言一、LVGL9的下载二、基础对象lv_obj2.1 概述2.2 布局2.3 lv_obj的使用创建一个lv_obj设置大小设置位置设置对齐父对象与子对象事件 总结 前言 LVGL&#xff08;LittlevGL&#xff09;是一个开源的嵌入式图形库&#xff0c;用于在嵌入式系统中创建用户界面。LVGL提…

故障诊断 | 一文解决,BiLSTM双向长短期记忆神经网络故障诊断(Matlab)

文章目录 效果一览文章概述专栏介绍模型描述源码设计参考资料效果一览 文章概述 故障诊断模型 | Maltab实现BiLSTM双向长短期记忆神经网络故障诊断 专栏介绍 订阅【故障诊断】专栏,不定期更新机器学习和深度学习在故障诊断中的应用;订阅

qt-C++笔记之contains()和isEmpty()函数、以及部分其他函数列举

qt-C笔记之contains()和isEmpty()函数、以及部分其他函数列举 code review! 文章目录 qt-C笔记之contains()和isEmpty()函数、以及部分其他函数列举contains()isEmpty() 类似的其他函数列举通用容器类函数字符串特有函数 在Qt C开发中&#xff0c; contains() 和 isEmpty()…

【深度学习】全连接神经网络

全连接神经网络 全连接神经网络的结构 整体结构 神经网络:类似神经元,前一层可以不断地传递给下一层。 神经网络模型由多个单元结构组成。 单元结构 单元结构的数学公式: a = h ( w x + b ) a=h(wx+b) a=h(wx+b) h(x):激活函数 比如sigmoid就是激活函数之一隐藏层大多…

Sketch 99.5中文 优秀的网站和移动应用设计软件

Sketch for mac用于数字世界的图形设计。在一个屡获殊荣的软件包中提供强大的工具和优雅的界面。因为做美丽的事情应该是一种快乐&#xff0c;而不是负担。 软件下载&#xff1a;Sketch 99.5中文激活版下载 Sketch支持每层多个填充&#xff0c;边框和阴影&#xff1b;具有强大的…

数据结构day7

1.思维导图 1.二叉树递归创建 2.二叉树先中后序遍历 3.二叉树计算节点 4.二叉树计算深度。 5.编程实现快速排序降序

点云数据集标注的相关工具

点云数据标注是三维计算机视觉领域中重要的一环&#xff0c;专门用于为点云数据添加语义信息&#xff0c;以便进行后续的机器学习和深度学习处理。以下是一些用于点云数据标注的软件及其特点的详细介绍&#xff1a; 1. CloudCompare 描述&#xff1a;CloudCompare是一个开源软…