windows驱动开发-WDM框架(一)

news2024/12/24 2:23:00

在前面的文章中解释过,NT5.0之后windows确定了新的架构Windows Driver Model (WDM),在Vista之后又推出了Windows Driver Framework(WDF),这两个都属于驱动程序框架,那么它们的之间的关系是怎样的?

WDF是对WDM进行的封装,是为更快、更简单的进行驱动开发进行的二次封装,故WDM里面的所有概念对于WDF都是适用的,所以理解内核架构可以学习WDM,开发驱动程序则使用WDF框架。

驱动程序类型

有三种类型的 WDM 驱动程序:总线驱动程序、功能驱动程序和过滤驱动程序。

总线驱动程序是用于控制单个 I/O 总线设备,提供总线功能,检测并报告连接到总线的子设备;
功能驱动程序用于控制单个设备,提供每种设备中具体某个设备的功能控制;
过滤驱动程序用于过滤设备、或者总线的 I/O 请求;

驱动程序开发人员必须了解不同类型的 WDM 驱动程序并知道自己正在编写哪种类型的驱动程序,这一点非常重要, 例如,驱动程序是否处理每个PNP的IRP以及如何处理此类 IRP 取决于所编写的驱动程序的类型。

过滤驱动英文描述为Filter Driver,这个翻译并不准确,但是非常形象,它一般用于对功能驱动或者总线驱动的I/O请求进行处理,这个过程就像“过滤”一样。

在后续的内核源代码和驱动分析解读中,我们可以看到为什么会有驱动程序类型的划分以及它们是为什么这么划分的。

内核组件和功能

内核组件是概念性而非实体,例如I/O管理器,并不是有一个IoManager.dll的动态库,而是将内核代码中关于I/O管理的部分代码抽象出来,称为I/O管理器。下面是一些开发中涉及的内核组件:

对象管理器: 用于管理所有的内核对象,它负责管理对象的创建和销毁、保留对象命名空间数据库以跟踪对象信息、跟踪分配给每个进程的资源、跟踪特定对象的访问权限以提供安全性、管理对象的生存期,并确定何时自动销毁对象以回收资源空间;

内存管理器:管理操作系统的物理内存。 此内存主要以随机访问内存的形式 (RAM) 。

内存管理器负责以虚拟和动态方式管理内存的分配和解除分配、支持内存映射文件、共享内存和写入时复制;

线程管理器: 它主要处理进程中的所有线程的执行。 无论有一个处理器还是多个处理器,都必须在进行驱动程序编程时非常小心,以确保进程的所有线程都被设计为无论处理线程的顺序如何,驱动程序都将正常运行。

如果来自不同进程的线程尝试同时使用同一资源,则可能会出现问题。 Windows 提供了几种技术来避免此问题。 确保不同进程中的线程不触及同一资源的技术称为“同步” 。

注意:由于线程调度器位于DPC链表的最底层,故驱动程序很可以中断线程调度器,所有某些情况下,驱动程序本身也是线程调度器的一部分。

I/O管理器: 计算机由各种设备组成,这些设备提供输入和输出 (外部世界的 I/O) 。 设备驱动程序提供设备和操作系统之间的软件连接。 I/O 管理器管理应用程序和设备驱动程序提供的接口之间的通信。 由于设备的运行速度可能与操作系统不匹配,因此操作系统和设备驱动程序之间的通信主要通过 I/O 请求数据包 (IRP) 完成。 这些数据包类似于网络数据包或 Windows 消息数据包。 它们从操作系统传递到特定驱动程序,以及从一个驱动程序传递到另一个驱动程序。

I/O 系统提供称为堆栈的分层驱动程序模型,这和编程语言中的堆栈是不一样的驱动程序的堆栈看起来如下:

图中的1为总线驱动、2是总线驱动的过滤驱动、3称之为功能驱动的下沿过滤驱动、4则是功能驱动、5为功能驱动的上沿驱动。

在windows设备栈中,每个驱动只能看到自己的上级驱动和下级驱动,故每个驱动都可以自己是过滤驱动,认为上面的是功能驱动,下面的是总线驱动!这一点是通过前向指针和后向指针来实现的!

驱动程序必须及时发送和接收 IRP 才能使整个堆栈高效运行,这一点非常重要。 如果驱动程序是堆栈的一部分,并且未正确接收、处理和传递信息,则驱动程序可能会导致系统崩溃。

I/O 管理器有两个子组件:即插即用管理器和电源管理器。

PNP管理器: 即插即用 (PnP) 是硬件技术和软件技术的组合,使电脑能够在将设备添加到系统时识别。 使用 PnP 时,系统配置可以在用户很少或无需输入的情况下进行更改。 例如,插入 U 盘时,Windows 可以检测 U 盘并自动将其添加到文件系统。 但是,若要执行此操作,硬件必须遵循某些要求,驱动程序也必须遵循。

PNP总线会管理所有支持PNP的总线,但它建立在非PNP总线的基础之上,例如,PCI总线上的USB或者1394总线分别支持PNP,但是PCI线没办法支持PNP。
电源管理器:Windows 使用电源管理技术来降低电脑(尤其是电池供电的笔记本电脑)的功耗。 例如,Windows 计算机可以处于睡眠或休眠状态。 计算机设备的复杂电源管理系统已经发展,因此,当计算机开始关闭或降低功耗时,连接的设备也可以以适当的方式关闭,以便不会丢失任何数据。 但这些设备需要一个警告,指示电源状态正在更改,它们可能还需要成为通信循环的一部分,该循环告诉控制设备等待,直到它们可以正确关闭。

Windows 内核模式电源管理器管理所有支持电源状态更改的电源状态的有序更改。 这通常通过控制其他设备的复杂设备堆栈来完成。 每个控制设备称为 节点 ,并且必须有一个驱动程序,该驱动程序可以通过设备堆栈上下处理电源状态更改的通信。

如果要编写可能受电源状态更改影响的驱动程序,则必须能够在驱动程序代码中处理以下类型的信息:

  • 系统活动级别;
  • 系统电池电量;
  • 当前要关闭、睡眠或休眠的请求。
  • 用户操作,例如按下电源按钮。
  • 控制面板设置,例如以 10% 的电池电量自动关闭。

电源管理器与策略管理结合使用来处理系统和设备的电源管理,并协调电源事件,生成、处理、完成电源管理相关的IRP;电源管理器收集更改电源状态的请求,确定设备必须更改其电源状态的顺序,然后发送相应的 IRP 以告知相应的驱动程序 (这些更改反过来可能会告知子设备进行更改) ; 策略管理器监视系统中的活动,并将用户状态、应用程序状态和设备驱动程序状态集成到电源策略中。

驱动程序例程

每个内核模式驱动程序都是围绕一组系统定义的标准驱动程序例程构造的。 内核模式驱动程序通过调用系统提供的驱动程序支持例程处理在这些标准例程中 I/O 请求数据包。

在这里,例程和回调函数等同,不过由于驱动基本是按照微软提供的例子来编写的,所以也会被称为例程,驱动程序本身是一个DLL,但是和常规DLL不一样的是,它只对外到处一个接口。

所有驱动程序,无论它们在附加驱动程序链中的级别如何,都必须具有一组基本的标准例程才能处理 IRP。 驱动程序是否必须实现其他标准例程取决于驱动程序是控制物理设备还是分层在物理设备驱动程序上,以及基础物理设备的性质。 控制物理设备的最低级别驱动程序比更高级别的驱动程序具有更多的所需例程,后者通常将 IRP 传递给较低级别的驱动程序进行处理。

标准驱动程序例程可以分为两组:每个内核模式驱动程序必须实现和可选实现,具体取决于驱动程序类型和它在设备堆栈中的位置。

下面是必须实现的例程

例程名称具体功能备注
DriverEntry初始化驱动程序及其驱动程序对象驱动入口
AddDevice初始化设备并创建设备对象设备新增
Dispatch对I/O请求的处理
Unload驱动卸载

驱动卸载

下面是可选实现的例程

例程名称具体功能
Reinitialize初始化失败后用于重新初始化的例程
StartIo开始处理I/O请求
Interrupt中断例程
DeferredProcedureCallsDPC过程
SynchCritSection同步对驱动程序数据的访问
AdapterControlDMA适配器控制
IoCompletionI/O完成例程
CancelIO取消I/O请求
CustomTimerDpc定时器DPC

如何判断需要实现哪些例程?这取决于具体的需求,例如,在1394设备中,我们需要考虑DMA的问题,如果在虚拟设备中,是不需要考虑硬件中断的问题的。所以我们先谈论必须实现的例程,然后在后续的案例分析中,再讨论每中驱动需要实现的可选例程。

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

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

相关文章

学习空间转换-3D转换

1.什么是空间转换? 使用的是transform属性实现元素在空间内的位移,旋转,缩放等效果。 空间:是从坐标轴角度定义的。x,y,z三条坐标轴构成的一个立体空间,Z轴位置与视线方向相同。 所以空间转换也被叫做3D转换 语法&a…

本地消息表模式保障分布式系统最终一致性

系统架构说明 状态转换说明 订单表消息表process_queue库存系统return_queue说明成功失败///订单库回滚成功成功失败//订单系统重发消息成功成功成功失败/Broker自动重试,注意接口幂等成功成功成功库存不足退回/Broker通知回掉,订单/消息作废成功成功成…

【做一名健康的CSDNer】《脱单恋爱秘籍》 —— 让爱情不再是难题

在这个快节奏的数字时代,程序员们以其独特的智慧和专业技能,为世界带来了翻天覆地的变化。然而,当代码和逻辑成为日常,爱情和人际关系的编程似乎变得复杂起来。为了帮助程序员们在爱情的道路上也能取得成功,我们精心打…

统一SQL-支持unpivot列转行

统一SQL介绍 https://www.light-pg.com/docs/LTSQL/current/index.html 源和目标 源数据库:Oracle 目标数据库:TDSQL-MySQL 操作目标 在Oracle中,可以使用unpivot将列转换成行,在TDSQL-MySQL中没有对应的功能,由…

Jenkins和gitlab实现CICD

1 背景 在开发TracerBackend服务的时候,每次更改代码之后需要推送到gitlab,然后ssh登录到Ubuntu的服务器上部署新的代码。服务成功启动之后,在本地执行测试用例,觉得这一套操作流程还是挺复杂的。想起公司的代码发布流程&#xf…

拓展网络技能:利用lua-http库下载www.linkedin.com信息的方法

引言 在当今的数字时代,网络技能的重要性日益凸显。本文将介绍如何使用Lua语言和lua-http库来下载和提取LinkedIn网站的信息,这是一种扩展网络技能的有效方法。 背景介绍 在当今科技潮流中,Lua语言以其轻量级和高效的特性,不仅…

在PostgreSQL中如何实现分区表以提高查询效率和管理大型表?

文章目录 解决方案1. 确定分区键2. 创建分区表3. 数据插入与查询4. 维护与管理 示例代码1. 创建父表和子表2. 插入数据3. 查询数据 总结 随着数据量的增长,单一的大型表可能会遇到性能瓶颈和管理难题。PostgreSQL的分区表功能允许我们将一个大型表分割成多个较小的、…

Python编程玩转二维码

文章目录 Python编程玩转二维码第一部分:背景介绍第二部分:qrcode库是什么?第三部分:如何安装这个库?第四部分:库函数使用方法第五部分:场景应用第六部分:常见Bug及解决方案第七部分…

【leetcode面试经典150题】63. 删除链表的倒数第 N 个结点(C++)

【leetcode面试经典150题】专栏系列将为准备暑期实习生以及秋招的同学们提高在面试时的经典面试算法题的思路和想法。本专栏将以一题多解和精简算法思路为主,题解使用C语言。(若有使用其他语言的同学也可了解题解思路,本质上语法内容一致&…

【深度学习-番外1】Win10系统搭建VSCode+Anaconda+Pytorch+CUDA深度学习环境和框架全过程

专栏的老读者们都知道,以前的文章以使用MATLAB的为多。 不过后续陆续开始展开深度学习算法的应用,就会逐渐引入Python语言了(当然MATLAB的代码也会同步更新),这是由于在深度学习领域,Python应用更为广泛。…

mysql_explain执行计划字段解析

【README】 本文对 explain打印的执行结果的字段进行解析; 本文总结自: MySQL :: MySQL 8.3 Reference Manual :: 10.8.2 EXPLAIN Output Formathttps://dev.mysql.com/doc/refman/8.3/en/explain-output.html 列名含义id选择标识select_type选择类型…

文本溢出体验进阶:CSS 技巧实现单行/多行隐藏展示以及实际场景应用,确保内容可读性和布局整洁性

CSS文本溢出隐藏是一种常见的场景,它广泛应用于各种网页设计中,旨在确保内容的可读性和布局的整洁性,特别是在空间有限或需要适应不同屏幕尺寸的情况下。 一、文本溢出隐藏并显示省略号 1、单行文本溢出隐藏并显示省略号 对于单行文本&…

【游戏专区】飞机大战

打过飞机的人都知道,不是那么好打滴,求得麻袋,甩掉你那脑子里的黄色信息。活不多说,我们开始吧。 1、easyX的原理 基于Windows图形编程,将Windows下的复杂程序过程进行封装,仅给用户提供一个简单熟悉的接…

.NET .exe .dll 反编译 程序反编译 程序逆向

反编译是对程序进行逆向分析、研究,以推导出软件产品所使用的思路、原理、结构、算法、处理过程、运行方法等设计要素。 反编译.NET程序需要使用专门的反编译工具 🧿使用dotPeek进行反编译 1.下载dotPeek dotPeek:JetBrains 出品的免费 .N…

视频质量评价 SSIM 算法详细介绍

SSIM SSIM(Structural Similarity Index Measure)是一种用于衡量两幅图像之间相似度的指标,是属于全参考视频质量评价算法范畴;它在图像质量评估领域得到了广泛的应用。SSIM是基于人类视觉系统的特性设计的,它考虑了图像的亮度、对比度和结构信息。SSIM的值范围在-1到1之…

【状态压缩 并集查找 图论】2157. 字符串分组

本文涉及知识点 状态压缩 并集查找 图论 LeetCode2157. 字符串分组 给你一个下标从 0 开始的字符串数组 words 。每个字符串都只包含 小写英文字母 。words 中任意一个子串中,每个字母都至多只出现一次。 如果通过以下操作之一,我们可以从 s1 的字母集…

SQLite FTS3 和 FTS4 扩展(三十二)

返回:SQLite—系列文章目录 上一篇:SQLite 的命令行 Shell(三十一) 下一篇:SQLite—系列文章目录 概述 FTS3 和 FTS4 是 SQLite 虚拟表模块,允许用户执行 对一组文档进行全文搜索。最常见(和最有效…

csdn的编写教程(官方给的)

自定义的目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个注脚…

CCF-CSP真题《202312-3 树上搜索》思路+c++满分题解

想查看其他题的真题及题解的同学可以前往查看:CCF-CSP真题附题解大全 问题描述 试题编号:202312-3试题名称:树上搜索时间限制:1.0s内存限制:512.0MB问题描述: 题目背景 问题描述 输入格式 输出格式 样…

【Leetcode每日一题】 穷举vs暴搜vs深搜vs回溯vs剪枝_全排列 - 全排列(难度⭐⭐)(62)

1. 题目解析 题目链接:46. 全排列 这个问题的理解其实相当简单,只需看一下示例,基本就能明白其含义了。 2.算法原理 回溯算法是一种通过探索所有可能的候选解来找出所有解的算法。当候选解被确认不是一个解(或者至少不是最后一…