NDIS小端口驱动开发(一)

在四种NDIS相关的驱动中,微型端口驱动(也经常翻译为为小端口驱动)位于驱动栈的底部,一般将它理解为NIC设备的驱动程序:

有几种类型的微型端口驱动程序类型:

  • 无连接微型端口驱动程序用于控制无连接网络媒体 ,如以太网的网络接口卡 (NIC) 的微型端;
  • 面向连接的微型端口驱动程序:面向连接的网络媒体编写微型端口驱动程序;
  • WAN 微型端口驱动程序:控制广域网 (WAN) NIC 的微型端口驱动程序;
  • 具有 WDM 下部接口的微型端口:该微型端口驱动程序与其他内核驱动程序进行交互,并且具有 Microsoft Windows 驱动程序模型 (WDM) 较低接口;
  • IrDA 微型端口驱动程序:控制 IrDA 适配器的微型端口驱动程序;
  • 支持可缩放网络的微型端口驱动程序:支持可缩放网络的微型端口驱动程序;
  • 支持将 TCP/IP 卸载到硬件的微型端口驱动程序 ;

所有 NDIS 6.0 及更高版本的驱动程序都会反序列化。反序列化的 NDIS 微型端口驱动程序序列化其自己的 MiniportXxx 函数的操作,并在内部对所有发送请求进行排队,而不是依赖于 NDIS 来执行这些函数。 因此,与序列化微型端口驱动程序相比,反序列化的微型端口驱动程序可以实现明显更好的全双工性能。

反序列化的驱动程序模型是 NDIS 微型端口驱动程序的默认模型。 面向连接的微型端口驱动程序以及具有 WDM 下边缘的微型端口驱动程序必须是反序列化的驱动程序。 

网络接口卡(NIC)支持

NDIS 微型端口驱动程序可以管理的网络接口卡 (NIC) 类型以及不同类型的 NIC 如何影响驱动程序传输网络数据的方式分类如下:

  • 向 NDIS 报告 NIC 的中类型: 若要报告 NIC 的中等类型,微型端口驱动程序会将指针传递到 NdisMSetMiniportAttributes 函数的 MiniportAttributes 参数中的 NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES 结构。 微型端口驱动程序在初始化期间从其 MiniportInitializeEx 函数调用 NdisMSetMiniportAttributes。 微型端口驱动程序应在NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES结构中设置注册属性之后和设置任何其他属性之前设置 MiniportAttributes 属性。 必须设置 MiniportAttributes 属性。 驱动程序在设置 MiniportAttributes 属性时,将 NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES 结构的 MediaType 成员设置为适当的媒体类型。当过度的 NDIS 协议驱动程序调用 NdisOpenAdapterEx 以绑定到指定的微型端口适配器时,它会提供一个可以操作的介质类型的列表。 NDIS 使用微型端口驱动程序和协议驱动程序中的信息来设置绑定。 此绑定提供用于在驱动程序堆栈中上下传输网络数据的路径。
  • 物理 NIC: 微型端口驱动程序完成初始化微型端口适配器以及发送和接收网络数据的步骤取决于物理设备的功能,如下所示。
  • NDIS-WDM NIC:对于 NDIS-WDM NIC(例如基于 USB 的 NIC),微型端口驱动程序使用 DMA 管理内存的方式对 NDIS 并不重要,也不可见。
  • 总线主 DMA NIC: 这些 NIC 可以通过板载 DMA 控制器直接访问主机内存,该控制器无需使用主机 CPU 即可管理网络与主机内存之间的数据传输。若要发送,微型端口驱动程序会设置 NIC 来映射传出缓冲区。 然后,微型端口驱动程序会导致设备从此内存开始传输。 NIC DMA 控制器将数据从共享系统内存传输到网络,并在发送完成后中断 CPU。 为了接收,DMA 控制器在通知主机中断之前将传入数据传输到主机内存。总线主 DMA NIC 通常具有一个板载环形缓冲区,微型端口驱动程序将该缓冲区映射到系统内存中的一组缓冲区。 通常,可以对 NIC 进行编程,以有效地处理多个数据包。 管理此类 NIC 的微型端口驱动程序通常支持多包发送和接收,因为 NIC 可以有效地处理多个数据包,从而提高其 I/O 吞吐量。
  • 非总线主机 DMA NIC: 目前,非总线主机 DMA NIC 包括以下内容:
  1. 系统 DMA NIC:管理此类 NIC 的微型端口驱动程序使用系统 DMA 控制器来管理数据包数据与网络之间的传输。 数据传输需要主机 CPU 的配合。
  2. 虚拟 NIC 和微型端口: 在虚拟机中,NDIS 微型端口驱动程序可以将仅软件资源作为虚拟微型端口进行管理,也可以管理表示硬件资源的虚拟 NIC。 
适配器状态

对于驱动管理的每个微型端口适配器, NDIS 微型端口驱动程序必须支持以下一组操作状态:

停止、关闭、正在初始化、已暂停、重新启动、正在运行、正在暂停,如下图:

注意 重置操作不会影响微型端口适配器的操作状态。 此外,重置操作正在进行时,适配器的状态可能会更改。 例如,当重置操作正在进行时,NDIS 可能会调用驱动程序的暂停处理程序。 在这种情况下,驱动程序可以按任何顺序完成重置或暂停操作,同时遵循每个操作的正常要求。 对于重置操作,驱动程序可能会使传输请求数据包失败,也可以让数据包保持排队并稍后完成。 但是,应注意在传输数据包挂起时,驱动程序无法完成暂停操作。

下面定义了适配器状态:

  • “已停止 ”是所有微型端口适配器的初始状态。 当微型端口适配器处于“已停止”状态,并且 NDIS 调用驱动程序的 MiniportInitializeEx 函数来初始化微型端口适配器时,微型端口适配器将进入“正在初始化”状态。 如果 MiniportInitializeEx 失败,微型端口适配器将返回到 Halted 状态。 当微型端口适配器处于“已暂停”状态并且 NDIS 调用 MiniportHaltEx 函数时,微型端口适配器将返回到“已暂停”状态;
  • 在系统关闭并重新启动之前,不能使用处于 关闭 状态的微型端口适配器。 当微型端口适配器处于“已暂停”、“正在重启”、“正在运行”或“正在暂停”状态,并且 NDIS 调用微型端口驱动程序的 MiniportShutdownEx 函数时,微型端口适配器将进入“关闭”状态;
  • 在 “正在初始化 ”状态下,微型端口驱动程序完成初始化微型端口适配器所需的任何操作。 当微型端口适配器处于“已停止”状态,并且 NDIS 调用微型端口驱动程序的 MiniportInitializeEx 函数时,微型端口适配器将进入“正在初始化”状态。 如果 MiniportInitializeEx 成功,微型端口适配器将进入 Paused 状态。 如果 MiniportInitializeEx 失败,微型端口适配器将返回到 Halted 状态;
  • 当微型端口适配器处于 “已暂停” 状态时,微型端口驱动程序不会指示已收到网络数据或接受发送请求。 当微型端口适配器处于暂停状态并且暂停操作完成时,微型端口适配器将进入“已暂停”状态。 当微型端口适配器处于“正在初始化”状态并且 MiniportInitializeEx 成功时,微型端口适配器将进入“已暂停”状态。 当 NDIS 调用微型端口驱动程序的 MiniportRestart 函数时,微型端口适配器将从“已暂停”状态转换为“正在重启”状态。 当 NDIS 调用微型端口驱动程序的 MiniportHaltEx 函数时,微型端口适配器将从“已暂停”状态转换为“已停止”状态;
  • 在 “正在重启” 状态下,微型端口驱动程序完成重启微型端口适配器的发送和接收操作所需的任何操作。 当微型端口适配器处于“已暂停”状态并且 NDIS 调用驱动程序的 MiniportRestart 函数时,微型端口适配器将进入“正在重启”状态。 如果重启失败,微型端口适配器将返回到“已暂停”状态。 如果重启成功,微型端口适配器将进入“正在运行”状态;
  • 在 “正在运行” 状态下,微型端口驱动程序对微型端口适配器执行正常的发送和接收处理。 当微型端口适配器处于“正在重启”状态,并且驱动程序已准备好执行发送和接收操作时,微型端口适配器将进入“正在运行”状态;
  • 在 暂停 状态下,微型端口驱动程序完成停止微型端口适配器的发送和接收操作所需的任何操作。 驱动程序必须等待 NDIS 返回所有未完成的接收指示。 当微型端口适配器处于“正在运行”状态并且 NDIS 调用驱动程序的 MiniportPause 函数时,微型端口适配器将进入暂停状态。 微型端口驱动程序不能使暂停操作失败。 暂停操作完成后,微型端口适配器将进入“已暂停”状态;
初始化

当网络设备可用时,系统加载 NDIS 微型端口驱动程序以管理设备。每个微型端口驱动程序都必须提供 DriverEntry 函数。 系统在加载驱动程序后调用 DriverEntry 。 DriverEntry 将微型端口驱动程序的特征(一个数据结构,封转了NDIS的函数例程)注册到 NDIS (包括支持的 NDIS 版本和驱动程序入口点) 。

系统将两个参数传递给 DriverEntry:

  • 指向 I/O 系统创建的驱动程序对象的指针。
  • 指向注册表路径的指针,该路径指定特定于驱动程序的参数的存储位置。

在 DriverEntry 中,微型端口驱动程序在调用 NdisMRegisterMiniportDriver 函数时传递这两个指针。 微型端口驱动程序通过将入口点存储在 NDIS_MINIPORT_DRIVER_CHARACTERISTICS 结构中并将该结构传递给 NdisMRegisterMiniportDriver 来导出一组标准 MiniportXxx 函数。

微型端口驱动程序的 DriverEntry 返回由调用 NdisMRegisterMiniportDriver 返回的值。

微型端口驱动程序还会在 DriverEntry 中执行任何其他特定于驱动程序的初始化。 驱动程序在 MiniportInitializeEx 函数中执行特定于适配器的初始化。 

DriverEntry 可以在堆栈上分配 NDIS_MINIPORT_DRIVER_CHARACTERISTICS 结构,因为 NDIS 库将相关信息复制到其自己的存储。 DriverEntry 应在其成员中设置驱动程序提供的任何值之前,使用 NdisZeroMemory 清除此结构的内存。 MajorNdisVersion 和 MinorNdisVersion 成员必须包含驱动程序支持的 NDIS 的主要和次要版本。 在特征结构的每个 XxxHandler 成员中, DriverEntry 必须设置驱动程序提供的 MiniportXxx 函数的入口点,否则该成员必须为 NULL。

为了使微型端口驱动程序能够配置可选服务,NDIS 在微型端口驱动程序调用 NdisMRegisterMiniportDriver 的上下文中调用 MiniportSetOptions 函数。 

调用 NdisMRegisterMiniportDriver 的驱动程序必须做好准备,以便 NDIS 在 DriverEntry 返回后随时调用其 MiniportInitializeEx 函数。 此类驱动程序必须有足够的安装和配置信息存储在注册表中,或者可以通过调用 特定于 NdisXxx 总线类型的配置函数来设置驱动程序执行网络 I/O 操作所需的任何特定于 NIC 的资源。

微型端口驱动程序最终必须调用 NdisMDeregisterMiniportDriver ,以释放它通过调用 NdisMRegisterMiniportDriver 分配的资源。 如果在调用 NdisMRegisterMiniportDriver 成功后驱动程序初始化失败,驱动程序可以从 DriverEntry 中调用 NdisMDeregisterMiniportDriver。 否则,微型端口驱动程序必须释放其 MiniportDriverUnload 函数中分配的特定于驱动程序的资源。 换句话说,如果 NdisMRegisterMiniportDriver 不返回NDIS_STATUS_SUCCESS, 则 DriverEntry 必须在返回控制权之前释放它分配的任何资源。 如果发生这种情况,将不会加载驱动程序。

卸载

与 NDIS 微型端口驱动程序关联的驱动程序对象指定 Unload 例程。 删除驱动程序服务的所有设备时,系统会调用 Unload 例程。 NDIS 为微型端口驱动程序提供 Unload 例程。 NDIS 从 Unload 例程调用微型端口驱动程序的 MiniportDriverUnload 函数。

微型端口驱动程序必须从 MiniportDriverUnload 调用 NdisMDeregisterMiniportDriver。

微型端口驱动程序的 MiniportDriverUnload 函数还应释放任何特定于驱动程序的资源。 MiniportDriverUnload 返回后,系统将完成驱动程序卸载操作。

MiniportDriverUnload 函数的功能特定于驱动程序。 一般情况下, MiniportDriverUnload 应撤消在驱动程序初始化期间执行的操作。 

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

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

相关文章

redis基本数据结构与应用

文章目录 概要String结构Hash结构List结构Set结构Zset结构bitmap位图类型geo地理位置类型其他常用命令 概要 redis常用的5种不同数据结构类型之间的映射如下: 结构类型结构存储的值结构的读写能力STRING可以是字符串、整数或者浮点数key-value形式;对整…

JMH304-剑侠情缘2网络版+2017纹饰端+翅膀+单机+外网整理+各种副本

资源介绍: 藏剑-太虚-梁山-杀手堂种树地宫师门纹饰装备长流云阳套等等———– 做登录器联系站长 资源截图: 下载地址

.NET周刊【5月第4期 2024-05-26】

国内文章 开源低代码框架 ReZero API 正式版本发布 ,界面操作直接生成API https://www.cnblogs.com/sunkaixuan/p/18201175 ReZero是一款.NET6的中间件,采用MIT许可证开源,目的是降低.NET Core开发的门槛。它提供界面操作生成API的功能&am…

《Ai学习笔记》自然语言处理 (Natural Language Processing):常见机器阅读理解模型(上)02

Glove 词向量: 在机器理解中的词的表示: 词袋(bow,bag of words) one-hot 词向量 word2vec glove 目的:将一个词转换成一个向量 Word2vec 是一种用于生成词向量的工具包,由Google在2013年开源推出…

大规模语言模型的书籍分享

在当今人工智能领域,大规模语言模型成为了研究和应用的热点之一。它们以其大规模的参数和强大的性能表现,推动着机器学习和深度学习技术的发展。对于GPT 系列大规模语言模型的发展历程,有两点令人印象深刻。 第一点是可拓展的训练架构与学习范…

《TCP/IP网络编程》(第十二章)I/O复用(1)

本章将讨论实现并发服务器的第二种办法,基于I/O复用的服务器端构建。 I/O复用它允许单个进程或线程同时处理多个输入/输出(I/O)操作,而无需为每个I/O操作创建一个独立的线程或进程。这种技术可以显著提高应用程序的效率和性能&…

前端学习--React部分

文章目录 前端学习--React部分前言1.React简介1.1React的特点1.2引入文件1.3JSX🍉JSX简介与使用🍉JSX语法规则 1.4模块与组件🍉模块🍉组件 1.5安装开发者工具 2.React面向组件编程2.1创建组件🍉函数式组件&#x1f349…

Elasticsearch 认证模拟题 - 1

1、题目 定义一个数据流,满足 data-stream_*_*,数据首先分布在 data_hot,5分钟后移动到 data_warm,3分钟后到 data_cold,再过 8 分钟删除。 1.1 考点 生命周期索引模板数据流 1.2 答案 # 修改生命周期策略修改时间…

【算法】位运算算法——只出现一次的数字Ⅱ

题解:只出现一次的数字Ⅱ(位运算算法) 目录 1.题目2.题解:3.代码示例4.总结 1.题目 题目链接:LINK 要求:时间复杂度:O(N),空间复杂度:O(1) 2.题解: 3.代码示例 class Solution {…

Java设计模式 _行为型模式_中介者模式

一、中介者模式 1、中介者模式 中介者模式(Mediator Pattern)是一种行为型模式。主要通过一个中介类,该类通常处理不同类之间的通信,并支持松耦合,使代码易于维护。 2、实现思路 (1)、定义实体…

【Linux】-Kafka集群安装部署[18]

简介 Apache Kafka是一款分布式的、去中心化的、高吞吐低延迟、订阅模式的消息队列系统。 同RabbitMQ一样,Kafka也是消息队列。不过RabbitMQ多用于后端系统,因其更加专注于消息的延迟和容错。 Kafka多用于大数据体系,因其更加专注于数据的…

K210 数字识别 笔记

一、烧写固件 连接k210开发板,点开烧录固件工具,选中固件,并下载 二、模型训练 网站:MaixHub 1、上传文件 2、开始标记数据 添加9个标签,命名为1~9,按键盘w开始标记,键盘D可以下一张图片&…

解密Prompt系列15. LLM Agent之数据库应用设计:DIN C3 SQL-Palm BIRD

上一章我们主要讲搜索引擎和LLM的应用设计,这一章我们来唠唠大模型和DB数据库之间的交互方案。有很多数据平台已经接入,可以先去玩玩再来看下面的实现方案,推荐 [sql translate]:简单,文本到SQL,SQL到文本…

后端企业级开发之yaml数据序列化格式文件详解2024

yaml格式 数据格式 yaml 是一种数据序列化的格式 容易阅读 容易与脚本语言交互 以数据为核心 重数据轻格式 我们要知道他怎么书写 大小写敏感 属性层级关系使用多行描述 每行结尾使用冒号结束 使用缩进表示层级关系 同层级左侧对其 只运行使用空格 属性前面添加空格 #表…

面试二十六、c++语言级别的多线程编程

一、 多线程编程 ​​​​​ 这里的c语言级别的多线程和linux的有一定的区别,c语言级别提供的多线程比较严格,如果主线程结束了,但是子线程没有结束,进程就会异常终止,而linux不会,会继续执行。 二、模拟卖…

Window VScode配置Conda教程(成功版)

VScode配置Conda 参考博文:https://blog.csdn.net/qq_51831335/article/details/126757014Anaconda安装(注意勾选自动配置环境变量!) 官网:https://www.anaconda.com/download/success VScode配置 python插件安装安装 …

关于Java程序入口args参数

关于Java程序入口args参数 我们都知道一个java工程会有一个主程序入口,即我们常见到的如下代码 public static void main(String[] args) {// 中间程序 }但是很多人可能都不知道主程序入口中的String[] args后面的args会有怎么样一个使用场景呢? 其实在…

爬虫逆向实例小记——某数据知识管理网站-DES-ECB模式

aHR0cHM6Ly9rZC5uc2ZjLmNuL2ZpbmFsUHJvamVjdEluaXQ 注意:本文是逆向部分比较少,主要为了流程走通,限于代码搬运工。 第一步:分析页面 此网站经过请求响应,可以看出响应内容为加密内容。 第二步:判断加密类型 在XHR …

java.lang.NumberFormatException: For input string:

创建SpringBoot,Mybatis的项目时候,Service层调用Mapper层时候爆出了一个错误 发现报错是一个类型转换错误,经过排查后发现是因为mapper接收的实体类中没有写空参构造

Redis 中 List 数据结构详解

目录 List 用法 1. 增 2. 删 3. 查 内部编码 应用场景 前言 Redis 中的 List 和 Set 数据结构各有特点,适用于不同的应用场景。List 提供了有序的列表结构,适合用于消息队列和任务列表等场景;Set 提供了无序且不重复的集合结构&#…