NDIS协议驱动(一)

Microsoft Windows 操作系统使用基于 1978 年国际标准化组织 (ISO) 开发的七层网络模型的网络体系结构。

ISO 开放系统互连 (OSI) 参考模型将网络描述为“一系列协议层,具有分配给每个层的一组特定函数。 每个层都向更高层提供特定的服务,同时阻止这些层了解服务实现方式的详细信息。 每对相邻层之间定义完善的接口定义了由下层到较高层提供的服务以及访问这些服务的方式。”

下图演示了 OSI 模型:

Windows 网络驱动程序 实现 OSI 模型的底层四层。但是注意,windows本身对这四层的也分成了几个层:

物理层: 物理层是 OSI 模型的最低层。 此层管理非结构化原始位流通过物理介质的接收和传输。 它描述了与物理介质的电气/光学、机械和功能接口。 物理层承载所有较高层的信号。在 Windows 中,网络接口卡 (NIC) 实现物理层、其收发器和 NIC 连接到的介质。

数据链接层: 数据链接层在物理地址之间发送帧,负责物理层中发生的错误检测和恢复。数据链接层由电气和电子工程师协会 (IEEE) 进一步划分为两个子层:媒体访问控制 (MAC) 和逻辑链接控制 (LLC) 。

1. MAC: MAC 子层管理对物理层的访问、检查帧错误和管理接收帧的地址识别。在 Windows 网络体系结构中,MAC 子层在 NIC 中实现。 NIC 由称为微型端口驱动程序的软件设备 驱动程序控制。 Windows 支持微型端口驱动程序的多种变体,包括 WDM 微型端口驱动程序、微型端口调用管理器 (MFM) 和微型端口中间驱动程序。

2. LLC: LLC 子层提供从一个节点到另一个节点的数据帧的无错误传输。 LLC 子层建立和终止逻辑链接、控制帧流、序列帧、确认帧和重新传输未确认的帧。 LLC 子层使用帧确认和重新传输,通过指向上述层的链接提供几乎无错误的传输。在 Windows 中,称为 协议驱动程序的软件驱动程序 实现 LLC 子层。

网络层: 网络层控制子网的操作。 此层根据以下内容确定数据应采用的物理路径:

  • 网络状况
  • 服务优先级
  • 其他因素,例如路由、流量控制、帧碎片和重新组装、逻辑到物理地址映射以及使用情况;

协议驱动程序实现网络层。

传输层: 传输层可确保按顺序传递消息,且不会丢失或重复。 此层使较高层协议免于担心与对等方进行数据传输。协议堆栈中需要最少的传输层,其中包括提供虚拟线路功能的可靠网络或 LLC 子层。 例如,由于适用于 Windows 的 NetBEUI 传输驱动程序是符合 OSI 的 LLC 子层,因此其传输层功能最少。 如果协议堆栈不包含 LLC 子层,并且网络层不可靠或支持与 TCP/IP 的 IP 层或 NWLink 的 IPX 层) 一样 数据报,则传输层应包括帧排序和确认,以及重新传输未确认的帧。在 Windows 网络体系结构中, 协议驱动程序(有时称为传输驱动程序)实现传输层。

综合下来我们可以看出,NDIS协议层驱动非常重要。 

 NDIS协议驱动简介

NDIS 协议驱动程序在其下边缘导出一组 ProtocolXxx 函数。 此类协议驱动程序与 NDIS 通信以发送和接收网络数据。 协议驱动程序绑定到在其上边缘导出 MiniportXxx 接口的基础微型端口 驱动程序或中间驱动程序。

中间驱动程序的微型端口驱动程序上边缘 (虚拟微型端口) 不管理物理设备。NDIS微型端口驱动程序管理物理设备。

协议驱动程序始终使用 NDIS 提供的函数来与基础 NDIS 驱动程序通信以发送和接收网络数据。 例如,具有无连接下边缘 (与无连接媒体的基础驱动程序通信的协议驱动程序(如以太网) )必须调用 NdisSendNetBufferLists 以将网络数据发送到基础 NDIS 驱动程序。 协议驱动程序可以调用 NdisOidRequest 来查询或设置基础无连接驱动程序支持的 OID。 具有面向连接的下边缘 (与面向连接的媒体的基础驱动程序通信的协议驱动程序必须调用 NdisCoSendNetBufferLists 以将网络数据发送到较低级别的 NDIS 驱动程序。 它还可以调用 NdisCoOidRequest 来查询或设置面向连接的基础驱动程序支持的 OID。

NDIS 还提供一组 NdisXxx 函数,用于隐藏基础操作系统的详细信息。 例如,协议驱动程序可以调用 NdisInitializeEvent 来创建用于同步的事件,并调用 NdisInitializeListHead 来创建链接列表。 使用此类函数的 NDIS 版本的协议驱动程序在 Microsoft 操作系统中更易于移植。 但是,协议驱动程序还可以调用内核模式支持例程,例如 IoCreateDevice。

初始化协议驱动程序

系统在加载驱动程序后调用协议驱动程序的 DriverEntry 例程。 协议驱动程序作为系统服务加载。 它们可以在微型端口驱动程序加载之前、期间或之后的任何时间加载。

协议驱动程序分配驱动程序资源并在 DriverEntry 中注册 ProtocolXxx 函数。 这包括 CoNDIS 客户端和独立的调用管理器。 若要将其 ProtocolXxx 函数注册到 NDIS,协议驱动程序会调用 NdisRegisterProtocolDriver 函数。

如果驱动程序成功注册为 NDIS 协议驱动程序,则 DriverEntry 返回STATUS_SUCCESS或其等效NDIS_STATUS_SUCCESS。 如果 DriverEntry 无法通过传播 由 NdisXxx 函数或内核模式支持例程返回的错误状态来初始化,驱动程序将不会保持加载状态。 DriverEntry 必须同步执行;也就是说,它不能返回STATUS_PENDING或其等效NDIS_STATUS_PENDING。

NDIS 协议驱动程序的 DriverEntry 函数必须调用 NdisRegisterProtocolDriver 函数。 若要向 NDIS 库注册驱动程序的 ProtocolXxx 入口点,协议驱动程序会初始化 NDIS_PROTOCOL_DRIVER_CHARACTERISTICS 结构并将其传递给 NdisRegisterProtocolDriver。

调用 NdisRegisterProtocolDriver 的驱动程序必须准备好立即调用其任何 ProtocolXxx 函数。

NDIS 协议驱动程序提供以下 ProtocolXxx 函数,这些函数是旧版驱动程序提供的函数的更新版本:

  • ProtocolSetOptions
  • ProtocolBindAdapterEx
  • ProtocolUnbindAdapterEx
  • ProtocolOpenAdapterCompleteEx
  • ProtocolCloseAdapterCompleteEx
  • ProtocolNetPnPEvent
  • ProtocolUninstall

NDIS 协议驱动程序为发送和接收操作提供以下 ProtocolXxx 函数:

  • ProtocolReceiveNetBufferLists
  • ProtocolSendNetBufferListsComplete

所有类型的 NDIS 协议驱动程序都应注册功能齐全的 ProtocolBindAdapterEx 和 ProtocolUnbindAdapterEx 函数,以支持即插即用 (PnP) 。 通常, DriverEntry 函数应在返回状态值为 STATUS_SUCCESS 或 NDIS_STATUS_SUCCESS 的控件之前立即调用 NdisRegisterProtocolDriver 。

除 NDIS 定义的 ProtocolXxx 函数外,导出一组标准内核模式驱动程序例程的任何协议驱动程序都必须在传递给其 DriverEntry 函数的给定驱动程序对象中设置这些驱动程序例程的入口点。 

如果尝试分配驱动程序执行网络 I/O 操作所需的资源失败, DriverEntry 应在返回状态为STATUS_SUCCESS或NDIS_STATUS_SUCCESS以外的控制之前释放它已分配的所有资源。

如果在成功调用 NdisRegisterProtocolDriver 后发生错误,驱动程序必须在 DriverEntry 返回之前调用 NdisDeregisterProtocolDriver 函数。

为了允许协议驱动程序配置可选服务,NDIS 在协议驱动程序调用 NdisRegisterProtocolDriver 的上下文中调用 ProtocolSetOptions 函数。

CoNDIS 客户端驱动程序必须从 ProtocolSetOptions 函数调用 NdisSetOptionalHandlers 函数。 驱动程序初始化NDIS_CO_CLIENT_OPTIONAL_HANDLERS结构,并在 NdisSetOptionalHandlers 的 OptionalHandlers 参数中传递它。

CoNDIS 独立调用管理器还必须从 ProtocolSetOptions 函数调用 NdisSetOptionalHandlers 函数。 驱动程序初始化NDIS_CO_CALL_MANAGER_OPTIONAL_HANDLERS结构,并在 NdisSetOptionalHandlers 的 OptionalHandlers 参数中传递它。

MMC 不是协议驱动程序。 因此,它们必须从 MiniportSetOptions 函数调用 NdisSetOptionalHandlers 函数。 MCM 初始化NDIS_CO_CALL_MANAGER_OPTIONAL_HANDLERS结构,并在 NdisSetOptionalHandlers 的 OptionalHandlers 参数中传递它。

若要注销 NDIS,协议驱动程序从其 Unload 例程调用 NdisDeregisterProtocolDriver。

若要在卸载协议驱动程序之前执行清理操作,协议驱动程序可以注册 ProtocolUninstall 函数。 ProtocolUninstall 函数是可选的。 例如,中间驱动程序的协议下边缘可能需要 ProtocolUninstall 函数。 在 NDIS 调用其 MiniportDriverUnload 函数之前,中间驱动程序可以在 ProtocolUninstall 中释放其协议边缘资源。

协议绑定状态和操作

对于驱动程序管理的每个绑定,NDIS 协议驱动程序必须支持以下操作状态:

  • 未绑定:“未绑定”状态是绑定的初始状态。 在此状态下,协议驱动程序等待 NDIS 调用 ProtocolBindAdapterEx 函数;
  • 打开:在“打开”状态下,协议驱动程序为绑定分配资源并尝试打开适配器;
  • 运行:在“正在运行”状态下,协议驱动程序对绑定执行发送和接收处理;
  • 关闭:在“关闭”状态下,协议驱动程序关闭对适配器的绑定,然后释放绑定的资源;
  • 暂停:在暂停状态下,协议驱动程序完成停止绑定的发送和接收操作所需的任何操作。在“暂停”状态下,协议驱动程序不对绑定执行发送或接收操作;
  • 重新启动:在“正在重启”状态下,协议驱动程序完成重启绑定的发送和接收操作所需的任何操作;

在下表中,标题表示绑定状态,事件列在第一列中。 表中的其余条目指定在某个状态内发生事件后绑定进入的下一个状态。 空条目表示无效的事件/状态组合:

 

注意 上表中列出的事件是 NDIS 协议绑定的主要事件。 当信息可用时,其他事件将添加到此表。

主要绑定事件的定义如下:

ProtocolBindAdapterEx:NDIS 调用驱动程序的 ProtocolBindAdapterEx 函数后,绑定进入“打开”状态。 有关详细信息,请参阅 绑定到适配器。

绑定失败:如果协议驱动程序无法绑定到适配器,绑定将返回到“未绑定”状态。

绑定已完成:如果驱动程序成功打开适配器,绑定将进入“已暂停”状态。 驱动程序完成绑定操作。

ProtocolUnbindAdapterEx:NDIS 调用驱动程序的 ProtocolUnbindAdapterEx hander 后,绑定进入 “关闭 ”状态。 

取消绑定已完成:驱动程序完成取消绑定操作后,绑定将进入“未绑定”状态。

PnP 暂停:NDIS 向协议驱动程序发送网络即插即用 (PnP) 暂停事件通知后,绑定进入暂停状态。 有关详细信息 ,请参阅暂停绑定。

暂停已完成:驱动程序完成停止发送和接收操作所需的所有操作后,暂停操作完成,绑定处于“已暂停”状态。在暂停操作完成之前,驱动程序必须等待其所有未完成的发送请求完成。

PnP 重启:NDIS 向协议驱动程序发送网络 PnP 重启事件通知后,绑定将进入“正在重启”状态。 有关详细信息,请参阅 重启绑定。

重启已完成:驱动程序准备好处理发送和接收操作后,重启操作完成,绑定处于“正在运行”状态。

重启失败:如果 NDIS 向协议驱动程序发送网络 PnP 重启事件通知,并且重启尝试失败,则绑定将返回到“已暂停”状态。

发送和接收操作:协议驱动程序必须处理处于“正在运行”和“暂停”状态的发送和接收操作。 

OID 请求:协议驱动程序可以启动 OID 请求,以在基础驱动程序中设置或查询信息。 协议驱动程序可以从所有状态(未绑定和打开)启动 OID 请求。

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

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

相关文章

中国区 AWS 控制台集成 ADFS 登录

前言 本文将使用一台 Windows Server 2019 服务器实现自建 AD ADFS 环境集成到中国区 AWS 控制台进行单点登录. 参考文档: https://aws.amazon.com/cn/blogs/china/adfs-bjs/ 配置 AD 生产环境建议先给本地连接设置静态 IP 地址, 不设置也没事儿, 后面配置功能的时候会有 W…

设计模式11——代理模式

写文章的初心主要是用来帮助自己快速的回忆这个模式该怎么用,主要是下面的UML图可以起到大作用,在你学习过一遍以后可能会遗忘,忘记了不要紧,只要看一眼UML图就能想起来了。同时也请大家多多指教。 代理模式(Proxy&am…

git工作流程

以财务开发为例子: 1. 新建分支 1.1. upstream新建分支:finance-feature 1.2. origin新建对应分支:finance-feature 1.3 新建本地分支 git branch finance-feature 注: 同步远程分支:git fetch upstream feature…

【设计模式】JAVA Design Patterns——Command(事务模式)

🔍目的 将请求封装为对象,从而使你可以将具有不同请求的客户端参数化,队列或记录请求,并且支持可撤销操作。 🔍解释 真实世界例子 有一个巫师在地精上施放咒语。咒语在地精上一一执行。第一个咒语使地精缩小&#xff0…

群晖NAS安装web服务器和搭建PHP环境

文章目录 安装Web Station 和 PHP配置PHP配置新站点(虚拟主机):配置nginx 安装MariaDB修改数据库配置配置远程连接远程连接 最近折腾了一台群晖NAS,并搭建了一套web服务器,关于其中的一些设置,和传统的Linu…

力扣HOT100 - 31. 下一个排列

解题思路: 数字是逐步增大的 步骤如下: class Solution {public void nextPermutation(int[] nums) {int i nums.length - 2;while (i > 0 && nums[i] > nums[i 1]) i--;if (i > 0) {int j nums.length - 1;while (j > 0 &&…

基于51单片机多功能太阳能充电器设计

1 绪论1.1 本课题研究背景及现状 当代社会随着一些不可再生资源如煤炭,石油等日益减少,使得各国社会经济越来越受能源问题的约制,因此许多国家开始逐渐的实行“阳光计划”,开发洁净的能源如太阳能,用以成为本国经济发…

javaEE—图书管理系统(基础代码版)

前言: 本篇博客是集合了javaEE所学的知识构建的一个基础框架,讲述着面向对象的过程是如何做到多对象交互协作完成框架的构建的。利用了数组,接口,类和对象,抽象类,Object类等知识来完成。 后续会加入数据…

BGP选路实验

编写实验报告: 1、拓扑信息 2、要求及分析 3、配置命令 4、测试 1、拓扑信息 2、要求及分析 1、使用preval策略,确保R4通过R2到达192.168.10.0/24 2、使用AS Path策略,确保R4通过R3到达192.168.11.0/24 3、配置MED策略,确保R4…

嵌入式UI开发-lvgl+wsl2+vscode系列:1、资料收集以及Windows下WSL2模拟环境运行示例demo

文章目录 一、前言二、资料收集三、Windows下WSL2上编译运行lvgl的demo程序1、lvgl简介2、lvgl特性3、配置要求4、Windows下vscodewsl2模拟环境搭建4.1、安装vscodewsl24.2、下载获取项目:4.3、安装显卡驱动4.4、下载lvgl并编译运行示例demo 四、最后 一、前言 UI界…

leetcode437 路径总和III-哈希表+前缀和

题目 给定一个二叉树的根节点 root ,和一个整数 targetSum ,求该二叉树里节点值之和等于 targetSum 的 路径 的数目。 路径 不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节…

专为汽车内容打造的智能剪辑解决方案

汽车内容创作已成为越来越多车主和汽车爱好者热衷的活动。然而,如何高效、便捷地将行车途中的精彩瞬间转化为高质量的视频作品,一直是困扰着广大用户的一大难题。美摄科技凭借其深厚的视频处理技术和智能分析能力,推出了专为汽车内容记录而生…

探索python循环逻辑的魅力:从无限到有限

新书上架~👇全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我👆,收藏下次不迷路┗|`O′|┛ 嗷~~ 目录 一、引言:循环逻辑的初步认识 二、无限循环:持续运转的引擎 三、有…

JavaWeb-JS

目录 学习重点 什么是 JavaScript? Web标准 JS的引入方式 JS的基本语法 JS的函数 JS的对象 JS事件监听 学习重点 js 引入方式 js 基础语法 js 函数 js 对象 js 事件监听 什么是 JavaScript? Web标准 Web 标准也称为网页标准 ,由一系列的标准组成&#xff0…

安泰电子:功率放大器的选择方法有哪些

选择适合的功率放大器是实现电子系统中的关键步骤之一。以下是一些选择功率放大器的常用方法和考虑因素: 功率需求:首先确定你的系统需要多大的功率输出。功率输出需求通常由被驱动设备的功率要求决定。计算出所需功率后,选择一个具有适当功率…

Java数组详解

Java数组详解 📚 Java数组详解:一篇文章搞懂Java中的数组知识摘要引言1. 数组的定义与创建📦1.1 数组的定义1.2 数组的创建及初始化数组不进行初始化时的默认值 2. 数组的遍历🔍2.1 使用for循环2.2 使用增强for循环2.3 使用Arrays…

斐讯N1刷OpenWRT并安装内网穿透服务实现远程管理旁路由

文章目录 前言1. 制作刷机固件U盘1.1 制作刷机U盘需要准备以下软件:1.2 制作步骤 2. N1盒子降级与U盘启动2.1 N1盒子降级2.2 N1盒子U盘启动设置2.3 使用U盘刷入OpenWRT2.4 OpenWRT后台IP地址修改2.5 设置旁路由&无线上网 3. 安装cpolar内网穿透3.1 下载公钥3.2 …

wordpress主题给网站增加一个版权声明区块代码分享

在数字化时代,网络上的信息传播变得越来越便捷,给人们生活和工作带来了极大的便利。然而,在这个过程中也产生了很多版权问题。为了更好地保护自己的版权,许多网站开始在其网页上添加版权声明。本文将探讨在网站上添加版权声明的重…

scala完整笔记-5万字一周入门到精通系列(一)

scala完整笔记-5万字一周入门到精通写在开篇 1.scala学习前一定要具备了解一些java基本知识,无需精通;如果从未接触java,最好熟悉一门编程语言,否则相对还是学习起来相对吃力且很难学懂 2.本篇主要以代码示例为主,很多…

亲测使用frp获得访问者真实ip

怎么访问都只有127.0.0.1这个内网ip,获取不到访问者的真实ip 1.打开frp的配置文件(一般是frpc.toml,无需设置frps.toml) 在每一个tcp协议中添加 transport.proxyProtocolVersion "v2" 实例: # frpc.toml [[proxies]] name "web" …