云计算百科
云计算领域专业知识百科平台

NDIS 库 (ndis.sys) 驱动程序分析

NDIS 库 (ndis.sys) 驱动程序分析

目录

  • 概述
  • 框架结构
  • 核心数据结构
  • 核心模块分析
  • 工作流程图
  • 数据流图
  • 初始化序列
  • 关键函数分析
  • 构建配置

  • 1. 概述

    NDIS (Network Driver Interface Specification) 是微软定义的网络驱动接口规范,是 Windows 网络体系结构的核心组件。ReactOS 的 NDIS 库 (ndis.sys) 是一个遵循 NDIS 5.1 规范的实现,位于 d:\\reactos\\drivers\\network\\ndis\\ 目录下。

    1.1 设计思想与架构哲学

    NDIS 的设计核心思想是分层抽象 + 集中调度。

    在传统的网络驱动实现中,协议栈(如 TCP/IP)需要直接与硬件驱动交互,这要求每个协议驱动都必须了解每种网卡驱动的内部细节,导致严重的耦合问题。NDIS 的解决办法是引入一个中间抽象层——即 ndis.sys 本身——位于协议驱动和微型端口驱动之间,承担以下核心角色:

    • 调度器角色:管理所有数据包的发送/接收序列化,通过工作项队列避免竞态条件
    • 绑定器角色:维护协议→适配器、适配器→协议的动态绑定关系,支持即插即用热插拔
    • 适配器角色:为上层的协议驱动和下层的微型端口驱动提供统一的函数调用约定,使两边都不需要知道对方的具体实现细节

    这种设计的核心价值在于:微型端口驱动只需要实现 10-15 个标准回调函数(Init/Halt/Send/SendPackets/QueryInfo/SetInfo/Reset/ISR/HandleInterrupt/EnableInterrupt/DisableInterrupt/TransferData/ReturnPacket/CheckForHang),而协议驱动也只需要实现类似数量的回调(BindAdapter/UnbindAdapter/SendComplete/ReceiveHandler/StatusHandler/PnPEventHandler 等)。所有复杂的调度、同步、绑定管理、PnP 协调都由 NDIS 库统一处理。

    1.2 主要功能

    • 为协议驱动(如 TCP/IP)和微型端口驱动(如 e1000、rtl8139)提供标准化的通信接口
    • 管理网络数据包的发送和接收流程
    • 协调即插即用 (PnP) 事件和电源管理事件
    • 提供配置管理(注册表操作)
    • 提供内存管理(包括 DMA 共享内存)
    • 提供计时器和同步原语
    • 通过工作项队列实现序列化和异步调度

    1.3 与 Linux 网络驱动架构的差异

    ReactOS 的 TCP/IP 协议栈 (tcpip.sys) 实际上是从 Linux 内核 2.4.20 移植而来(见 [tcpcore.h](file:///d:/reactos/drivers/network/tcpip/include/tcpcore.h) 的注释 Ported from linux kernel 2.4.20),但在 NDIS 框架下运行时,两者呈现出截然不同的设计哲学。

    对比维度Windows NDIS 设计Linux 网络驱动设计
    核心架构 三层严格分层:协议驱动 → NDIS 库 → 微型端口驱动。NDIS 作为独立的内核模块存在,承担调度和管理职责 两层轻量架构:协议栈直接调用 net_device_ops 中的函数指针,没有独立的"中间库层",驱动模型由内核统一框架提供
    数据包表示 NDIS_PACKET + NDIS_BUFFER (MDL):基于 Windows MDL (Memory Descriptor List) 机制,包描述符和数据分离,通过 MDL 链支持 Scatter/Gather I/O struct sk_buff:统一的缓冲区结构,使用 head/data/tail/end 四个指针灵活管理协议头空间,支持克隆 (skb_clone)、共享、分片 (skb_shinfo),内联了全套操作函数
    发送模型 异步回调驱动:MiniportSend[Packets] 返回 NDIS_STATUS_PENDING 表示异步,发送完成后调用 NdisMSendComplete() 回调协议。NDIS 库负责任何必要的序列化和排队 同步+流量控制:dev->hard_start_xmit(skb) 同步发送,返回 NETDEV_TX_OK 或 NETDEV_TX_BUSY。驱动通过 netif_stop_queue()/netif_wake_queue() 控制上层是否继续发送
    接收模型 推模式 (Push):微型端口通过 NdisMIndicateReceivePacket 将数据推送给 NDIS,NDIS 遍历绑定协议列表逐层推送。有传统 ReceiveHandler 和新式 ReceivePacketHandler 两种方式 NAPI 轮询 (Poll)(Linux 2.6+):中断上半部关闭中断,注册 NAPI 结构到轮询列表;softIRQ 上下文中通过 poll(napi, budget) 批量轮询接收,减少高负载下的中断开销
    协议绑定 NDIS 集中管理:NDIS 维护全局 ProtocolListHead 和每个适配器的 ProtocolListHead,通过 ndisBindMiniportsToProtocol() 从注册表读取绑定配置。支持多个协议绑定到同一适配器 内核统一管理:通过 dev_add_pack() 注册 packet_type 到全局 ptype_all/ptype_base 哈希表,内核网络栈在接收时根据协议类型分发给不同处理函数
    中断处理 ISR + DPC 两阶段:MiniportISR(在 DIRQL 上运行,仅判断中断归属和是否需要 DPC)→ HandleDeferredProcessing DPC(在 DISPATCH_LEVEL 上运行,调用 MiniportHandleInterrupt + MiniportEnableInterrupt) hardIRQ + softIRQ 两阶段:硬中断(仅做最小处理,如获取数据)→ softIRQ(NET_RX_SOFTIRQ/NET_TX_SOFTIRQ 中做实际协议处理,不在驱动中完成,而是交给内核协议栈)
    序列化模型 可配置序列化:通过 NDIS_ATTRIBUTE_DESERIALIZE 标志位区分串行化/反串行化两种模式。串行化模式下 NDIS 保证每次只有一个请求到达微型端口;反串行化模式下驱动自行管理并发 驱动自行管理:内核不提供统一的序列化机制,驱动使用自旋锁、RCU、per-CPU 变量等标准内核同步机制自行管理并发。ndo_start_xmit 可能在多个 CPU 上同时调用
    配置/OID 管理 统一的 OID 机制:所有查询/设置操作通过 MiniportQueryInformation/MiniportSetInformation 一个回调入口,通过 NDIS_OID 枚举值(如 OID_GEN_MAC_OPTIONS、OID_802_3_CURRENT_ADDRESS)区分操作类型。NDIS 提供 NdisReadConfiguration、NdisOpenConfiguration 等注册表封装 分散的接口:通过多个 net_device_ops 函数实现(ndo_do_ioctl、ndo_get_stats、ndo_set_mac_address 等),或通过 ethtool_ops 实现。没有统一的 OID 枚举体系
    PnP/电源管理 NDIS 内置支持:NDIS 通过 NdisIAddDevice(创建设备)、NdisIPnPStartDevice(启动设备,调用 MiniportInitialize)、NdisIPnPStopDevice(停止设备,调用 MiniportHalt)完整地封装了 PnP 流程。电源事件通过 NetEventSetPower/NetEventQueryPower PnP 事件通知协议 内核驱动模型:使用标准的 struct device_driver 模型,probe/remove 函数由内核在总线枚举时调用,电源管理通过 dev_pm_ops 实现
    DMA 管理 NDIS 封装:NdisMInitializeScatterGatherDma 初始化 DMA 通道,NdisMAllocateSharedMemory 分配共享内存,GetScatterGatherList/PutScatterGatherList 管理 Scatter/Gather 列表。NDIS 在内部分配 DMA_ADAPTER 和 DMA_OPERATIONS 通用 DMA API:dma_alloc_coherent()、dma_map_single()、dma_map_sg() 等。在 PCI 驱动中使用 pci_alloc_consistent() 等封装。由内核通用 DMA 层统一管理
    兼容性 NDIS 版本化兼容:通过编译宏 (NDIS40/NDIS50/NDIS51) 和不同大小的 MiniportCharacteristics 结构支持 NDIS 3.0/4.0/5.0/5.1 的二进制兼容。30stubs.c、40stubs.c、50stubs.c 提供桩函数 内核版本绑定:驱动必须针对特定内核版本编译,net_device_ops 结构在不同内核版本间有较大差异,不保证二进制兼容性
    工作项延迟处理 NDIS 工作项队列:MiniQueueWorkItem + MiniportWorker 实现串行化的工作项调度,支持 NdisWorkItemSend、NdisWorkItemRequest、NdisWorkItemResetRequested 等工作类型,通过内核 IoQueueWorkItem 实现 workqueue/tasklet:Linux 内核提供通用的 work_struct + schedule_work() 和 tasklet 机制,驱动根据自己的需要使用这些通用机制,没有 NDIS 这样专门针对网络驱动的专用工作项队列

    1.4 NDIS 这样设计的优缺点

    优点:

  • 驱动开发简化:微型端口驱动只需关注硬件操作本身,填写标准回调函数表即可。发送/接收的序列化、协议绑定管理、PnP 协调等复杂工作由 NDIS 代劳
  • 二进制兼容性好:同一份微型端口驱动编译后在支持 NDIS 5.x 的 Windows 版本上均可运行,降低维护成本
  • 统一的配置管理:通过 OID 机制和 NdisReadConfiguration 封装,驱动不需要直接与注册表打交道
  • 版本平滑演进:通过不断扩展 MiniportCharacteristics 结构大小而不是修改函数签名,保持了向后的二进制兼容性
  • 热插拔支持完善:PnP 事件经过 NDIS 统一调度后转发给协议驱动,确保所有绑定协议都能正确响应设备插拔
  • 缺点:

  • 性能开销:相比 Linux 的轻量模型,额外的 NDIS 层带来了函数调用开销和上下文切换(尤其在工作项队列场景)
  • 灵活性受限:驱动必须在 NDIS 的框架内工作,无法绕过 NDIS 层直接操作协议栈
  • 缺少 NAPI 等效的轮询机制:NDIS 5.1 仅支持中断驱动的推模式,高负载下可能产生大量中断(Linux NAPI 在 Linux 2.6 中引入以解决此问题)
  • 依赖注册表:绑定配置和参数配置强依赖注册表,嵌入式场景下不够灵活
  • 1.5 支持的 NDIS 版本

    通过构建宏定义,支持 NDIS 3.0/4.0/5.0/5.1 的兼容性:

    -DNDIS_WRAPPER
    -DNDIS51
    -DNDIS51_MINIPORT
    -DNDIS_MINIPORT_DRIVER
    -DNDIS_LEGACY_DRIVER=1
    -DNDIS_LEGACY_MINIPORT=1
    -DNDIS_LEGACY_PROTOCOL=1


    2. 框架结构

    2.1 分层架构

    NDIS 采用标准的三层网络驱动架构:

    +————————————–+
    | 协议驱动 (Protocol) |
    | tcpip.sys, ppp.sys, etc. |
    +————————————–+
    | NdisSend / NdisReceive etc.
    v
    +————————————–+
    | NDIS 库 (ndis.sys) |
    | – 数据包调度 |
    | – 协议/微型端口绑定管理 |
    | – 配置管理 |
    | – 中断处理 |
    | – PnP/电源管理 |
    +————————————–+
    | MiniportXxx callbacks
    v
    +————————————–+
    | 微型端口驱动 (Miniport) |
    | e1000.sys, rtl8139.sys, etc. |
    +————————————–+

    2.2 模块组织

    NDIS 库由以下源文件组成:

    源文件功能
    main.c 驱动入口点 DriverEntry,初始化全局列表和锁
    miniport.c 微型端口支持(初始化、发送/接收完成、请求处理、工作项队列、PnP 事件处理)
    protocol.c 协议驱动支持(协议注册、适配器打开/关闭、发送/请求转发)
    buffer.c 数据包/缓冲区管理(NDIS_PACKET、NDIS_BUFFER 操作)
    config.c 注册表配置读写(NdisOpenConfiguration、NdisReadConfiguration 等)
    memory.c 内存管理(含 DMA 共享内存分配/释放)
    io.c 中断服务例程 (ISR) 和 DPC 处理
    hardware.c PCI 配置空间读写、资源分配
    control.c 读写锁同步
    efilter.c 以太网帧过滤
    object.c NDIS 6.0 通用对象接口
    workitem.c NDIS 6.0 工作项接口
    time.c 计时器管理
    string.c 字符串操作
    misc.c 杂项(互锁操作、字符串比较)
    cl.c 面向连接客户端
    cm.c 呼叫管理器
    co.c 面向连接支持
    30stubs.c NDIS 3.0 兼容性桩函数
    40stubs.c NDIS 4.0 兼容性桩函数
    50stubs.c NDIS 5.0 兼容性桩函数

    2.3 关键调用约定

    协议驱动 -> NdisSend() -> ProSend() -> proSendPacketToMiniport() -> MiniportSend[Packets]Handler
    协议驱动 -> NdisRequest() -> ProRequest() -> MiniDoRequest() -> MiniportQueryInfo/SetInfoHandler
    微型端口 -> NdisMSendComplete() -> MiniSendComplete() -> ProtocolSendCompleteHandler
    微型端口 -> NdisMIndicateStatus() -> MiniStatus() -> ProtocolStatusHandler


    3. 核心数据结构

    3.1 逻辑适配器 (LOGICAL_ADAPTER)

    定义在 [miniport.h](file:///d:/reactos/drivers/network/ndis/include/miniport.h#L87-L99):

    typedef struct _LOGICAL_ADAPTER
    {
    NDIS_MINIPORT_BLOCK NdisMiniportBlock; // NDIS 定义的标准字段
    PNDIS_MINIPORT_WORK_ITEM WorkQueueHead; // 工作队列头
    PNDIS_MINIPORT_WORK_ITEM WorkQueueTail; // 工作队列尾
    LIST_ENTRY ListEntry; // 全局适配器链表
    LIST_ENTRY MiniportListEntry; // 微型端口驱动链表的入口
    LIST_ENTRY ProtocolListHead; // 绑定到此适配器的协议链表
    ULONG MediumHeaderSize; // 介质头大小(如 Ethernet=14)
    HARDWARE_ADDRESS Address; // 硬件地址 (MAC)
    ULONG AddressLength; // 硬件地址长度
    PMINIPORT_BUGCHECK_CONTEXT BugcheckContext; // 关机回调上下文
    } LOGICAL_ADAPTER, *PLOGICAL_ADAPTER;

    3.2 微型端口驱动块 (NDIS_M_DRIVER_BLOCK)

    typedef struct _NDIS_M_DRIVER_BLOCK {
    LIST_ENTRY ListEntry; // 全局链表入口
    KSPIN_LOCK Lock; // 保护自旋锁
    NDIS_MINIPORT_CHARACTERISTICS MiniportCharacteristics; // 微型端口特性(函数指针表)
    WORK_QUEUE_ITEM WorkItem; // 工作项
    PDRIVER_OBJECT DriverObject; // 驱动对象
    LIST_ENTRY DeviceList; // 该驱动创建的适配器列表
    PUNICODE_STRING RegistryPath; // 注册表路径
    } NDIS_M_DRIVER_BLOCK;

    3.3 协议绑定 (PROTOCOL_BINDING)

    定义在 [protocol.h](file:///d:/reactos/drivers/network/ndis/include/protocol.h#L10-L16):

    typedef struct _PROTOCOL_BINDING {
    LIST_ENTRY ListEntry; // 全局链表入口
    KSPIN_LOCK Lock; // 保护自旋锁
    NDIS_PROTOCOL_CHARACTERISTICS Chars; // 协议特性(函数指针表)
    WORK_QUEUE_ITEM WorkItem; // 工作项
    LIST_ENTRY AdapterListHead; // 已绑定的适配器列表
    } PROTOCOL_BINDING, *PPROTOCOL_BINDING;

    3.4 适配器绑定 (ADAPTER_BINDING)

    typedef struct _ADAPTER_BINDING {
    NDIS_OPEN_BLOCK NdisOpenBlock; // NDIS 定义的标准字段
    LIST_ENTRY ListEntry; // 全局链表入口
    LIST_ENTRY ProtocolListEntry; // 协议绑定的适配器链表入口
    LIST_ENTRY AdapterListEntry; // 逻辑适配器的协议链表入口
    KSPIN_LOCK Lock; // 保护自旋锁
    PPROTOCOL_BINDING ProtocolBinding; // 对应的协议
    PLOGICAL_ADAPTER Adapter; // 对应的适配器
    } ADAPTER_BINDING, *PADAPTER_BINDING;

    3.5 工作项 (NDIS_MINIPORT_WORK_ITEM)

    支持的工作项类型:

    工作项类型用途
    NdisWorkItemSend 发送数据包
    NdisWorkItemSendLoopback 回环发送
    NdisWorkItemReturnPackets 归还数据包
    NdisWorkItemResetRequested 适配器重置
    NdisWorkItemResetInProgress 重置进行中
    NdisWorkItemMiniportCallback 微型端口回调
    NdisWorkItemRequest 查询/设置请求
    NdisMaxWorkItems 用于遍历所有类型

    3.6 全局链表结构

    全局协议列表 (ProtocolListHead)

    +——————-+
    | PROTOCOL_BINDING | —- AdapterListHead –> [ADAPTER_BINDING] -> [ADAPTER_BINDING]
    +——————-+

    全局微型端口列表 (MiniportListHead)

    +——————-+
    | NDIS_M_DRIVER_BLOCK| —- DeviceList –> [LOGICAL_ADAPTER] -> [LOGICAL_ADAPTER]
    +——————-+

    全局适配器列表 (AdapterListHead)

    +——————-+
    | LOGICAL_ADAPTER | —- ProtocolListHead –> [ADAPTER_BINDING] -> [ADAPTER_BINDING]
    +——————-+


    4. 核心模块分析

    4.1 主入口 (main.c)

    DriverEntry 函数执行以下初始化:

  • 初始化全局协议列表 ProtocolListHead 和对应的自旋锁
  • 初始化全局微型端口列表 MiniportListHead 和对应的自旋锁
  • 初始化全局适配器列表 AdapterListHead 和对应的自旋锁
  • 注册卸载处理函数 MainUnload
  • 初始化取消 ID 计数器
  • 4.2 微型端口管理 (miniport.c)

    这是 NDIS 库中最大的模块,负责:

    4.2.1 微型端口注册 (NdisMRegisterMiniport)
    • 验证 MiniportCharacteristics 版本(3.0/4.0/5.0/5.1)
    • 验证必需的函数指针(Halt, Initialize, Reset 必须提供)
    • 复制特性到全局结构
    • 注册 AddDevice 回调 (NdisIAddDevice)
    • 注册通用 IRP 处理器 (NdisGenericIrpHandler)
    4.2.2 PnP 设备管理

    设备创建 (NdisIAddDevice):

  • 从注册表读取 Export 名称
  • 调用 IoCreateDevice 创建 FILE_DEVICE_PHYSICAL_NETCARD 设备
  • 初始化 LOGICAL_ADAPTER 结构
  • 注册网络设备接口 (GUID_DEVINTERFACE_NET)
  • 附加到设备栈
  • 初始化计时器和 DPC(用于检测挂起)
  • 设备启动 (NdisIPnPStartDevice):

  • 将适配器加入全局列表
  • 打开注册表键,读取总线类型/编号/槽号
  • 设置回调处理函数
  • 调用 MiniportInitialize
  • 查询 MAC 选项、硬件地址、lookahead 大小、最大发送包数
  • 创建以太网过滤器 (EthCreateFilter)
  • 启动挂起检测计时器
  • 绑定所有协议到新适配器
  • 设备停止 (NdisIPnPStopDevice):

  • 从全局列表移除适配器
  • 取消计时器
  • 调用 MiniportHalt
  • 释放资源(内存、过滤器)
  • 4.2.3 工作项队列

    NDIS 使用工作项队列来序列化对微型端口的操作:

    MiniQueueWorkItem() → 入队(尾插法)
    MiniDequeueWorkItem() → 出队(头删法)
    MiniportWorker() → 工作线程处理
    MiniWorkItemComplete() → 完成并检查是否有后续工作项

    工作类型包括发送、请求、重置等,通过 MiniportWorker 统一调度。

    4.3 协议管理 (protocol.c)

    4.3.1 协议注册 (NdisRegisterProtocol)
  • 验证协议版本/特性
  • 分配 PROTOCOL_BINDING 结构
  • 复制特性(含大写化协议名)
  • 调用 ndisBindMiniportsToProtocol 绑定适配器
  • 发送 NetEventBindsComplete PnP 事件
  • 加入全局协议列表
  • 4.3.2 协议-适配器绑定 (ndisBindMiniportsToProtocol)

    绑定过程:

  • 构造注册表路径 \\Registry\\Machine\\…\\Services\\{Protocol}\\Linkage
  • 读取 Bind 值(REG_MULTI_SZ 格式)
  • 遍历每个设备名,检查是否已启动和是否已绑定
  • 构造每适配器的参数路径
  • 调用协议驱动的 BindAdapterHandler
  • 4.3.3 适配器打开 (NdisOpenAdapter)
  • 通过名称查找适配器 (MiniLocateDevice)
  • 检查介质类型匹配
  • 分配 ADAPTER_BINDING 结构
  • 设置处理函数(Request, Reset, Send, SendPackets, TransferData)
  • 将绑定加入协议和适配器的链表
  • 4.4 缓冲区管理 (buffer.c)

    NDIS 缓冲区体系基于 MDL (Memory Descriptor List):

    NDIS_PACKET
    ├── Private.Head → NDIS_BUFFER (MDL) → NDIS_BUFFER (MDL) → …
    ├── Private.Tail → NDIS_BUFFER (MDL)
    ├── Reserved[0..3] (协议/微型端口保留)
    ├── WrapperReserved[0..3]
    └── 包扩展数据 (NDIS_PACKET_OOB_DATA + NDIS_PACKET_EXTENSION)

    关键操作:

    • NdisAllocateBuffer → 调用 IoAllocateMdl + MmBuildMdlForNonPagedPool
    • NdisAllocatePacketPoolEx → 预分配池,通过空闲链表管理
    • CopyBufferChainToBuffer → 遍历 MDL 链复制到连续缓冲区
    • CopyPacketToBuffer → 从数据包复制到缓冲区

    4.5 中断处理 (io.c)

    中断处理分为两个阶段:

    硬件中断

    MiniportISR() ← ISR 阶段(高 IRQL)
    ├── InterruptRecognized = TRUE
    └── QueueMiniportHandleInterrupt = TRUE

    HandleDeferredProcessing() ← DPC 阶段(DISPATCH_LEVEL)
    ├── MiniportHandleInterrupt()
    └── MiniportEnableInterrupt()

    4.6 配置管理 (config.c)

    NDIS 对注册表的操作提供了资源跟踪机制:

    • NdisOpenConfiguration / NdisOpenProtocolConfiguration → 打开注册表键
    • NdisReadConfiguration → 读取配置值(支持 Integer/HexInteger/String/MultiString/Binary)
    • NdisWriteConfiguration → 写入配置值
    • NdisCloseConfiguration → 关闭并释放所有跟踪资源

    资源跟踪通过 MINIPORT_CONFIGURATION_CONTEXT 和 MINIPORT_RESOURCE 链表实现。

    4.7 以太网过滤 (efilter.c)

    当微型端口指示接收到数据时,EthFilterDprIndicateReceive 被调用,它会:

  • 检查以太网过滤器
  • 调用 MiniIndicateData 将数据传递给绑定的协议

  • 5. 工作流程图

    5.1 驱动初始化流程

    #mermaid-svg-AENlTMH9UNBwsCkq{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-AENlTMH9UNBwsCkq .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-AENlTMH9UNBwsCkq .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-AENlTMH9UNBwsCkq .error-icon{fill:#552222;}#mermaid-svg-AENlTMH9UNBwsCkq .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-AENlTMH9UNBwsCkq .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-AENlTMH9UNBwsCkq .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-AENlTMH9UNBwsCkq .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-AENlTMH9UNBwsCkq .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-AENlTMH9UNBwsCkq .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-AENlTMH9UNBwsCkq .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-AENlTMH9UNBwsCkq .marker{fill:#333333;stroke:#333333;}#mermaid-svg-AENlTMH9UNBwsCkq .marker.cross{stroke:#333333;}#mermaid-svg-AENlTMH9UNBwsCkq svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-AENlTMH9UNBwsCkq p{margin:0;}#mermaid-svg-AENlTMH9UNBwsCkq .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-AENlTMH9UNBwsCkq .cluster-label text{fill:#333;}#mermaid-svg-AENlTMH9UNBwsCkq .cluster-label span{color:#333;}#mermaid-svg-AENlTMH9UNBwsCkq .cluster-label span p{background-color:transparent;}#mermaid-svg-AENlTMH9UNBwsCkq .label text,#mermaid-svg-AENlTMH9UNBwsCkq span{fill:#333;color:#333;}#mermaid-svg-AENlTMH9UNBwsCkq .node rect,#mermaid-svg-AENlTMH9UNBwsCkq .node circle,#mermaid-svg-AENlTMH9UNBwsCkq .node ellipse,#mermaid-svg-AENlTMH9UNBwsCkq .node polygon,#mermaid-svg-AENlTMH9UNBwsCkq .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-AENlTMH9UNBwsCkq .rough-node .label text,#mermaid-svg-AENlTMH9UNBwsCkq .node .label text,#mermaid-svg-AENlTMH9UNBwsCkq .image-shape .label,#mermaid-svg-AENlTMH9UNBwsCkq .icon-shape .label{text-anchor:middle;}#mermaid-svg-AENlTMH9UNBwsCkq .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-AENlTMH9UNBwsCkq .rough-node .label,#mermaid-svg-AENlTMH9UNBwsCkq .node .label,#mermaid-svg-AENlTMH9UNBwsCkq .image-shape .label,#mermaid-svg-AENlTMH9UNBwsCkq .icon-shape .label{text-align:center;}#mermaid-svg-AENlTMH9UNBwsCkq .node.clickable{cursor:pointer;}#mermaid-svg-AENlTMH9UNBwsCkq .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-AENlTMH9UNBwsCkq .arrowheadPath{fill:#333333;}#mermaid-svg-AENlTMH9UNBwsCkq .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-AENlTMH9UNBwsCkq .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-AENlTMH9UNBwsCkq .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-AENlTMH9UNBwsCkq .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-AENlTMH9UNBwsCkq .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-AENlTMH9UNBwsCkq .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-AENlTMH9UNBwsCkq .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-AENlTMH9UNBwsCkq .cluster text{fill:#333;}#mermaid-svg-AENlTMH9UNBwsCkq .cluster span{color:#333;}#mermaid-svg-AENlTMH9UNBwsCkq div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-AENlTMH9UNBwsCkq .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-AENlTMH9UNBwsCkq rect.text{fill:none;stroke-width:0;}#mermaid-svg-AENlTMH9UNBwsCkq .icon-shape,#mermaid-svg-AENlTMH9UNBwsCkq .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-AENlTMH9UNBwsCkq .icon-shape p,#mermaid-svg-AENlTMH9UNBwsCkq .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-AENlTMH9UNBwsCkq .icon-shape .label rect,#mermaid-svg-AENlTMH9UNBwsCkq .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-AENlTMH9UNBwsCkq .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-AENlTMH9UNBwsCkq .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-AENlTMH9UNBwsCkq :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    协议驱动注册

    PnP 设备启动

    微型端口驱动注册

    DriverEntry

    初始化全局列表和锁

    NdisMInitializeWrapper

    分配 NDIS_M_DRIVER_BLOCK

    保存 DriverObject 和 RegistryPath

    加入全局 MiniportListHead

    NdisMRegisterMiniport

    验证 Characteristics

    注册 AddDevice = NdisIAddDevice

    注册 MajorFunction = NdisGenericIrpHandler

    IRP_MN_START_DEVICE

    NdisIPnPStartDevice

    加入全局 AdapterListHead

    打开注册表读取总线信息

    设置内部回调处理器

    调用 MiniportInitialize

    查询 MAC 能力(OID 查询)

    创建以太网过滤器

    启动挂起检测计时器

    绑定所有协议到本适配器

    NdisRegisterProtocol

    验证协议版本

    分配 PROTOCOL_BINDING

    ndisBindMiniportsToProtocol

    读取 Bind 注册表值

    对每个设备调用 BindAdapterHandler

    协议调用 NdisOpenAdapter

    创建 ADAPTER_BINDING

    加入协议和适配器列表

    5.2 数据包发送流程

    #mermaid-svg-Qva2PI8ZFsmfbTwT{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Qva2PI8ZFsmfbTwT .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Qva2PI8ZFsmfbTwT .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Qva2PI8ZFsmfbTwT .error-icon{fill:#552222;}#mermaid-svg-Qva2PI8ZFsmfbTwT .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Qva2PI8ZFsmfbTwT .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Qva2PI8ZFsmfbTwT .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Qva2PI8ZFsmfbTwT .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Qva2PI8ZFsmfbTwT .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Qva2PI8ZFsmfbTwT .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Qva2PI8ZFsmfbTwT .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Qva2PI8ZFsmfbTwT .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Qva2PI8ZFsmfbTwT .marker.cross{stroke:#333333;}#mermaid-svg-Qva2PI8ZFsmfbTwT svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Qva2PI8ZFsmfbTwT p{margin:0;}#mermaid-svg-Qva2PI8ZFsmfbTwT .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-Qva2PI8ZFsmfbTwT .cluster-label text{fill:#333;}#mermaid-svg-Qva2PI8ZFsmfbTwT .cluster-label span{color:#333;}#mermaid-svg-Qva2PI8ZFsmfbTwT .cluster-label span p{background-color:transparent;}#mermaid-svg-Qva2PI8ZFsmfbTwT .label text,#mermaid-svg-Qva2PI8ZFsmfbTwT span{fill:#333;color:#333;}#mermaid-svg-Qva2PI8ZFsmfbTwT .node rect,#mermaid-svg-Qva2PI8ZFsmfbTwT .node circle,#mermaid-svg-Qva2PI8ZFsmfbTwT .node ellipse,#mermaid-svg-Qva2PI8ZFsmfbTwT .node polygon,#mermaid-svg-Qva2PI8ZFsmfbTwT .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Qva2PI8ZFsmfbTwT .rough-node .label text,#mermaid-svg-Qva2PI8ZFsmfbTwT .node .label text,#mermaid-svg-Qva2PI8ZFsmfbTwT .image-shape .label,#mermaid-svg-Qva2PI8ZFsmfbTwT .icon-shape .label{text-anchor:middle;}#mermaid-svg-Qva2PI8ZFsmfbTwT .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-Qva2PI8ZFsmfbTwT .rough-node .label,#mermaid-svg-Qva2PI8ZFsmfbTwT .node .label,#mermaid-svg-Qva2PI8ZFsmfbTwT .image-shape .label,#mermaid-svg-Qva2PI8ZFsmfbTwT .icon-shape .label{text-align:center;}#mermaid-svg-Qva2PI8ZFsmfbTwT .node.clickable{cursor:pointer;}#mermaid-svg-Qva2PI8ZFsmfbTwT .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-Qva2PI8ZFsmfbTwT .arrowheadPath{fill:#333333;}#mermaid-svg-Qva2PI8ZFsmfbTwT .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Qva2PI8ZFsmfbTwT .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Qva2PI8ZFsmfbTwT .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Qva2PI8ZFsmfbTwT .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Qva2PI8ZFsmfbTwT .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Qva2PI8ZFsmfbTwT .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-Qva2PI8ZFsmfbTwT .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Qva2PI8ZFsmfbTwT .cluster text{fill:#333;}#mermaid-svg-Qva2PI8ZFsmfbTwT .cluster span{color:#333;}#mermaid-svg-Qva2PI8ZFsmfbTwT div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Qva2PI8ZFsmfbTwT .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Qva2PI8ZFsmfbTwT rect.text{fill:none;stroke-width:0;}#mermaid-svg-Qva2PI8ZFsmfbTwT .icon-shape,#mermaid-svg-Qva2PI8ZFsmfbTwT .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Qva2PI8ZFsmfbTwT .icon-shape p,#mermaid-svg-Qva2PI8ZFsmfbTwT .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-Qva2PI8ZFsmfbTwT .icon-shape .label rect,#mermaid-svg-Qva2PI8ZFsmfbTwT .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Qva2PI8ZFsmfbTwT .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Qva2PI8ZFsmfbTwT .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Qva2PI8ZFsmfbTwT :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    Miniport Layer

    NDIS Library

    Protocol Layer

    协议发送数据包

    NdisSend / NdisSendPackets

    ProSend / ProSendPackets

    是回环包?

    目标MAC == 本机MAC?

    使用 DMA?

    ProIndicatePacket 回环处理

    GetScatterGatherList → DMA

    proSendPacketToMiniport

    ScatterGatherSendPacket 回调

    proSendPacketToMiniport

    WorkItemSend 正忙?

    入队 MiniQueueWorkItem

    MiniIsBusy?

    入队工作项

    直接调用微型端口

    反序列化?

    SendPacketsHandler/SendHandler

    提升到 DISPATCH_LEVEL 再调用

    硬件发送

    发送完成中断

    NdisMSendComplete

    MiniSendComplete

    释放 Scatter/Gather List

    调用 ProtocolSendCompleteHandler

    MiniWorkItemComplete 检查后续工作

    5.3 数据包接收流程

    #mermaid-svg-ro1A9uyE1FpkAo28{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-ro1A9uyE1FpkAo28 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-ro1A9uyE1FpkAo28 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-ro1A9uyE1FpkAo28 .error-icon{fill:#552222;}#mermaid-svg-ro1A9uyE1FpkAo28 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-ro1A9uyE1FpkAo28 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-ro1A9uyE1FpkAo28 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-ro1A9uyE1FpkAo28 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-ro1A9uyE1FpkAo28 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-ro1A9uyE1FpkAo28 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-ro1A9uyE1FpkAo28 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-ro1A9uyE1FpkAo28 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-ro1A9uyE1FpkAo28 .marker.cross{stroke:#333333;}#mermaid-svg-ro1A9uyE1FpkAo28 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-ro1A9uyE1FpkAo28 p{margin:0;}#mermaid-svg-ro1A9uyE1FpkAo28 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-ro1A9uyE1FpkAo28 .cluster-label text{fill:#333;}#mermaid-svg-ro1A9uyE1FpkAo28 .cluster-label span{color:#333;}#mermaid-svg-ro1A9uyE1FpkAo28 .cluster-label span p{background-color:transparent;}#mermaid-svg-ro1A9uyE1FpkAo28 .label text,#mermaid-svg-ro1A9uyE1FpkAo28 span{fill:#333;color:#333;}#mermaid-svg-ro1A9uyE1FpkAo28 .node rect,#mermaid-svg-ro1A9uyE1FpkAo28 .node circle,#mermaid-svg-ro1A9uyE1FpkAo28 .node ellipse,#mermaid-svg-ro1A9uyE1FpkAo28 .node polygon,#mermaid-svg-ro1A9uyE1FpkAo28 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-ro1A9uyE1FpkAo28 .rough-node .label text,#mermaid-svg-ro1A9uyE1FpkAo28 .node .label text,#mermaid-svg-ro1A9uyE1FpkAo28 .image-shape .label,#mermaid-svg-ro1A9uyE1FpkAo28 .icon-shape .label{text-anchor:middle;}#mermaid-svg-ro1A9uyE1FpkAo28 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-ro1A9uyE1FpkAo28 .rough-node .label,#mermaid-svg-ro1A9uyE1FpkAo28 .node .label,#mermaid-svg-ro1A9uyE1FpkAo28 .image-shape .label,#mermaid-svg-ro1A9uyE1FpkAo28 .icon-shape .label{text-align:center;}#mermaid-svg-ro1A9uyE1FpkAo28 .node.clickable{cursor:pointer;}#mermaid-svg-ro1A9uyE1FpkAo28 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-ro1A9uyE1FpkAo28 .arrowheadPath{fill:#333333;}#mermaid-svg-ro1A9uyE1FpkAo28 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-ro1A9uyE1FpkAo28 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-ro1A9uyE1FpkAo28 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ro1A9uyE1FpkAo28 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-ro1A9uyE1FpkAo28 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ro1A9uyE1FpkAo28 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-ro1A9uyE1FpkAo28 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-ro1A9uyE1FpkAo28 .cluster text{fill:#333;}#mermaid-svg-ro1A9uyE1FpkAo28 .cluster span{color:#333;}#mermaid-svg-ro1A9uyE1FpkAo28 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-ro1A9uyE1FpkAo28 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-ro1A9uyE1FpkAo28 rect.text{fill:none;stroke-width:0;}#mermaid-svg-ro1A9uyE1FpkAo28 .icon-shape,#mermaid-svg-ro1A9uyE1FpkAo28 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ro1A9uyE1FpkAo28 .icon-shape p,#mermaid-svg-ro1A9uyE1FpkAo28 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-ro1A9uyE1FpkAo28 .icon-shape .label rect,#mermaid-svg-ro1A9uyE1FpkAo28 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ro1A9uyE1FpkAo28 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-ro1A9uyE1FpkAo28 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-ro1A9uyE1FpkAo28 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    Packet Return

    Receive Indication

    DPC Stage

    Hardware

    传统 ReceiveHandler

    Packet ReceivePacketHandler

    网卡接收数据

    硬件中断

    MiniportISR

    排队 DPC

    HandleDeferredProcessing DPC

    MiniportHandleInterrupt

    MiniportEnableInterrupt

    数据包指示方式?

    EthFilterDprIndicateReceive

    MiniIndicateReceivePacket

    MiniIndicateData

    遍历 ProtocolListHead

    调用协议 ReceiveHandler

    遍历协议设置 WrapperReserved 引用计数

    协议有 ReceivePacketHandler?

    协议 ReceivePacketHandler

    增加包引用计数

    复制数据到 LookaheadBuffer

    调用协议 ReceiveHandler

    反序列化?

    引用计数 == 0?

    立即调用 ReturnPacketHandler

    协议后来调用 NdisReturnPackets

    引用计数 == 0?

    设置 NDIS_STATUS_SUCCESS

    设置 NDIS_STATUS_PENDING

    5.4 请求处理流程 (OID 查询/设置)

    #mermaid-svg-dGPvbkzYbgquOAiX{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-dGPvbkzYbgquOAiX .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-dGPvbkzYbgquOAiX .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-dGPvbkzYbgquOAiX .error-icon{fill:#552222;}#mermaid-svg-dGPvbkzYbgquOAiX .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-dGPvbkzYbgquOAiX .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-dGPvbkzYbgquOAiX .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-dGPvbkzYbgquOAiX .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-dGPvbkzYbgquOAiX .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-dGPvbkzYbgquOAiX .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-dGPvbkzYbgquOAiX .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-dGPvbkzYbgquOAiX .marker{fill:#333333;stroke:#333333;}#mermaid-svg-dGPvbkzYbgquOAiX .marker.cross{stroke:#333333;}#mermaid-svg-dGPvbkzYbgquOAiX svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-dGPvbkzYbgquOAiX p{margin:0;}#mermaid-svg-dGPvbkzYbgquOAiX .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-dGPvbkzYbgquOAiX .cluster-label text{fill:#333;}#mermaid-svg-dGPvbkzYbgquOAiX .cluster-label span{color:#333;}#mermaid-svg-dGPvbkzYbgquOAiX .cluster-label span p{background-color:transparent;}#mermaid-svg-dGPvbkzYbgquOAiX .label text,#mermaid-svg-dGPvbkzYbgquOAiX span{fill:#333;color:#333;}#mermaid-svg-dGPvbkzYbgquOAiX .node rect,#mermaid-svg-dGPvbkzYbgquOAiX .node circle,#mermaid-svg-dGPvbkzYbgquOAiX .node ellipse,#mermaid-svg-dGPvbkzYbgquOAiX .node polygon,#mermaid-svg-dGPvbkzYbgquOAiX .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-dGPvbkzYbgquOAiX .rough-node .label text,#mermaid-svg-dGPvbkzYbgquOAiX .node .label text,#mermaid-svg-dGPvbkzYbgquOAiX .image-shape .label,#mermaid-svg-dGPvbkzYbgquOAiX .icon-shape .label{text-anchor:middle;}#mermaid-svg-dGPvbkzYbgquOAiX .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-dGPvbkzYbgquOAiX .rough-node .label,#mermaid-svg-dGPvbkzYbgquOAiX .node .label,#mermaid-svg-dGPvbkzYbgquOAiX .image-shape .label,#mermaid-svg-dGPvbkzYbgquOAiX .icon-shape .label{text-align:center;}#mermaid-svg-dGPvbkzYbgquOAiX .node.clickable{cursor:pointer;}#mermaid-svg-dGPvbkzYbgquOAiX .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-dGPvbkzYbgquOAiX .arrowheadPath{fill:#333333;}#mermaid-svg-dGPvbkzYbgquOAiX .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-dGPvbkzYbgquOAiX .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-dGPvbkzYbgquOAiX .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-dGPvbkzYbgquOAiX .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-dGPvbkzYbgquOAiX .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-dGPvbkzYbgquOAiX .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-dGPvbkzYbgquOAiX .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-dGPvbkzYbgquOAiX .cluster text{fill:#333;}#mermaid-svg-dGPvbkzYbgquOAiX .cluster span{color:#333;}#mermaid-svg-dGPvbkzYbgquOAiX div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-dGPvbkzYbgquOAiX .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-dGPvbkzYbgquOAiX rect.text{fill:none;stroke-width:0;}#mermaid-svg-dGPvbkzYbgquOAiX .icon-shape,#mermaid-svg-dGPvbkzYbgquOAiX .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-dGPvbkzYbgquOAiX .icon-shape p,#mermaid-svg-dGPvbkzYbgquOAiX .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-dGPvbkzYbgquOAiX .icon-shape .label rect,#mermaid-svg-dGPvbkzYbgquOAiX .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-dGPvbkzYbgquOAiX .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-dGPvbkzYbgquOAiX .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-dGPvbkzYbgquOAiX :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    NdisRequestQueryInformation

    NdisRequestSetInformation

    协议调用 NdisRequest

    ProRequest

    MiniIsBusy?

    入队工作项 NdisWorkItemRequest

    MiniDoRequest

    有 CoRequestHandler?

    请求类型

    MiniportQueryInformationHandler

    MiniportSetInformationHandler

    MiniportCoRequestHandler

    状态 == PENDING?

    等待 MiniRequestComplete

    直接完成

    MiniRequestComplete

    调用 RequestCompleteHandler

    MiniWorkItemComplete

    5.5 适配器重置流程

    #mermaid-svg-K4bXZDTKrdVgaPvU{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-K4bXZDTKrdVgaPvU .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-K4bXZDTKrdVgaPvU .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-K4bXZDTKrdVgaPvU .error-icon{fill:#552222;}#mermaid-svg-K4bXZDTKrdVgaPvU .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-K4bXZDTKrdVgaPvU .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-K4bXZDTKrdVgaPvU .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-K4bXZDTKrdVgaPvU .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-K4bXZDTKrdVgaPvU .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-K4bXZDTKrdVgaPvU .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-K4bXZDTKrdVgaPvU .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-K4bXZDTKrdVgaPvU .marker{fill:#333333;stroke:#333333;}#mermaid-svg-K4bXZDTKrdVgaPvU .marker.cross{stroke:#333333;}#mermaid-svg-K4bXZDTKrdVgaPvU svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-K4bXZDTKrdVgaPvU p{margin:0;}#mermaid-svg-K4bXZDTKrdVgaPvU .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-K4bXZDTKrdVgaPvU .cluster-label text{fill:#333;}#mermaid-svg-K4bXZDTKrdVgaPvU .cluster-label span{color:#333;}#mermaid-svg-K4bXZDTKrdVgaPvU .cluster-label span p{background-color:transparent;}#mermaid-svg-K4bXZDTKrdVgaPvU .label text,#mermaid-svg-K4bXZDTKrdVgaPvU span{fill:#333;color:#333;}#mermaid-svg-K4bXZDTKrdVgaPvU .node rect,#mermaid-svg-K4bXZDTKrdVgaPvU .node circle,#mermaid-svg-K4bXZDTKrdVgaPvU .node ellipse,#mermaid-svg-K4bXZDTKrdVgaPvU .node polygon,#mermaid-svg-K4bXZDTKrdVgaPvU .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-K4bXZDTKrdVgaPvU .rough-node .label text,#mermaid-svg-K4bXZDTKrdVgaPvU .node .label text,#mermaid-svg-K4bXZDTKrdVgaPvU .image-shape .label,#mermaid-svg-K4bXZDTKrdVgaPvU .icon-shape .label{text-anchor:middle;}#mermaid-svg-K4bXZDTKrdVgaPvU .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-K4bXZDTKrdVgaPvU .rough-node .label,#mermaid-svg-K4bXZDTKrdVgaPvU .node .label,#mermaid-svg-K4bXZDTKrdVgaPvU .image-shape .label,#mermaid-svg-K4bXZDTKrdVgaPvU .icon-shape .label{text-align:center;}#mermaid-svg-K4bXZDTKrdVgaPvU .node.clickable{cursor:pointer;}#mermaid-svg-K4bXZDTKrdVgaPvU .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-K4bXZDTKrdVgaPvU .arrowheadPath{fill:#333333;}#mermaid-svg-K4bXZDTKrdVgaPvU .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-K4bXZDTKrdVgaPvU .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-K4bXZDTKrdVgaPvU .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-K4bXZDTKrdVgaPvU .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-K4bXZDTKrdVgaPvU .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-K4bXZDTKrdVgaPvU .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-K4bXZDTKrdVgaPvU .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-K4bXZDTKrdVgaPvU .cluster text{fill:#333;}#mermaid-svg-K4bXZDTKrdVgaPvU .cluster span{color:#333;}#mermaid-svg-K4bXZDTKrdVgaPvU div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-K4bXZDTKrdVgaPvU .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-K4bXZDTKrdVgaPvU rect.text{fill:none;stroke-width:0;}#mermaid-svg-K4bXZDTKrdVgaPvU .icon-shape,#mermaid-svg-K4bXZDTKrdVgaPvU .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-K4bXZDTKrdVgaPvU .icon-shape p,#mermaid-svg-K4bXZDTKrdVgaPvU .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-K4bXZDTKrdVgaPvU .icon-shape .label rect,#mermaid-svg-K4bXZDTKrdVgaPvU .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-K4bXZDTKrdVgaPvU .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-K4bXZDTKrdVgaPvU .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-K4bXZDTKrdVgaPvU :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    协议调用 NdisReset

    ProReset

    MiniReset

    MiniIsBusy?

    入队重置工作项

    NdisMIndicateStatus RESET_START

    调用 MiniportResetHandler

    状态 == PENDING?

    等待 MiniResetComplete

    执行寻址重置

    NdisMIndicateStatus RESET_END

    MiniWorkItemComplete


    6. 数据流图

    6.1 发送数据流

    协议驱动 NDIS 库 微型端口驱动
    +——–+ +———–+ +————+
    | TCP/IP | | ndis.sys | | e1000.sys |
    +——–+ +———–+ +————+
    | | |
    |— NdisSend(Packet) ———->| |
    | | |
    | +—–+—–+ |
    | | ProSend() | |
    | +—–+—–+ |
    | | |
    | +—–v—–+ |
    | | 检查回环 |—如果目标=本机MAC–+ |
    | +—–+—–+ | |
    | | | |
    | +—–v—–+ v |
    | | DMA? |—是–> Scatter/Gather |
    | +—–+—–+ | |
    | | | |
    | +—–v—–+ | |
    | | 发送到 | | |
    | | 微型端口 |<——————+ |
    | +—–+—–+ |
    | | |
    | +—–v—–+ |
    | | 序列化/ | |
    | | 工作项队列 | |
    | +—–+—–+ |
    | | |
    | +——- MiniportSend ———>|
    | | (或 SendPackets) |
    | | |
    | | +—v—+
    | | | 硬件 |
    | | | 发送 |
    | | +—v—+
    | | |
    | |<——- NdisMSendComplete —+
    | | |
    | +—–v—–+ |
    | |MiniSendComplete |
    | +—–+—–+ |
    | | |
    |<—— SendCompleteHandler —-+ |

    6.2 接收数据流

    硬件 NDIS 库 协议驱动
    +——–+ +———–+ +——–+
    | 网卡 | | ndis.sys | | TCP/IP |
    +——–+ +———–+ +——–+
    | | |
    |— 硬件中断 ——————>| |
    | | |
    | +—–v—–+ |
    | | MiniportISR| |
    | +—–+—–+ |
    | | |
    | +—–v—–+ |
    | | DPC 处理 | |
    | +—–+—–+ |
    | | |
    |<– MiniportHandleInterrupt —-+ |
    | | |
    |— MiniportTransferData[可选] ->| |
    | (或 NdisMIndicateReceivePacket)| |
    | | |
    | +—–v—–+ |
    | | 以太网 | |
    | | 过滤器检查 | |
    | +—–+—–+ |
    | | |
    | +—–v——+ |
    | | 遍历协议列表 | |
    | +—–+——+ |
    | | |
    | +——- ReceiveHandler ——–>|
    | | (或 ReceivePacketHandler)|
    | | |
    | | +—v—+
    | | | 协议 |
    | | | 处理 |
    | | | 数据 |
    | | +—v—+
    | | |
    |<— NdisReturnPackets ———+<— 协议归还数据包 ————+

    6.3 OID 查询/设置数据流

    协议驱动 NDIS 库 微型端口驱动
    +——–+ +———–+ +————+
    | TCP/IP | | ndis.sys | | e1000.sys |
    +——–+ +———–+ +————+
    | | |
    |— NdisRequest(Request) ——>| |
    | (OID_GEN_xxx…) | |
    | +—–v—–+ |
    | | ProRequest| |
    | +—–+—–+ |
    | | |
    | +—–v——+ |
    | | MiniDoRequest| |
    | +—–+——+ |
    | | |
    | +—–v——+ |
    | | 根据请求类型 | |
    | +—–+——+ |
    | | |
    | +————+————-+ |
    | | | |
    | +——–v——+ +——–v——+ |
    | |QueryInfoHandler| |SetInfoHandler | |
    | +——–+——+ +——–+——+ |
    | | | |
    | +—— 微型端口执行 ——-+–> [硬件查询] |
    | | (OID 处理) | |
    | | | |
    | +—— NdisM[Query/Set] –+ |
    | | InformationComplete| |
    | | | |
    | +———-v———-+ |
    | | MiniRequestComplete | |
    | +———-+———-+ |
    | | |
    |<——— RequestCompleteHandler –+ |


    7. 初始化序列

    7.1 完整的系统启动-网络初始化序列

    Phase 1: NDIS 自身初始化
    =========================
    1. 系统加载 ndis.sys
    2. DriverEntry() 调用
    – 初始化 ProtocolListHead, MiniportListHead, AdapterListHead
    – 初始化对应的自旋锁

    Phase 2: 微型端口驱动加载
    =========================
    3. 系统加载 e1000.sys 等微型端口驱动
    4. DriverEntry 调用:
    a. NdisMInitializeWrapper() – 在全局 MiniportListHead 注册驱动块
    b. NdisMRegisterMiniport() – 注册微型端口特性
    – 验证函数指针
    – 注册 AddDevice = NdisIAddDevice
    – 注册 MajorFunction = NdisGenericIrpHandler

    Phase 3: PnP 枚举设备
    =====================
    5. PnP 管理器枚举 PCI 总线上的网络设备
    6. NdisIAddDevice() 调用:
    a. 读取注册表 Export 名称
    b. IoCreateDevice() 创建设备对象
    c. 初始化 LOGICAL_ADAPTER
    d. 注册网络设备接口
    e. IoAttachDeviceToDeviceStack() 附加到设备栈
    f. 初始化挂起检测 DPC 和计时器

    7. IRP_MN_START_DEVICE 到达:
    a. NdisIPnPStartDevice() 调用
    b. 打开注册表读取配置
    c. 设置内部处理函数钩子
    d. 调用 MiniportInitialize() – 微型端口初始化硬件
    e. 查询 MAC 能力 (OID_GEN_MAC_OPTIONS, OID_802_3_CURRENT_ADDRESS 等)
    f. 创建以太网过滤器
    g. 启动挂起检测计时器 (默认每2秒检查)
    h. 绑定所有已注册协议到本适配器

    Phase 4: 协议驱动加载
    =====================
    8. 系统加载 tcpip.sys 等协议驱动
    9. DriverEntry 调用:
    a. NdisRegisterProtocol() – 注册协议特性
    b. ndisBindMiniportsToProtocol() – 读取 Linkage\\Bind 键
    c. 对每个适配器调用 BindAdapterHandler
    d. BindAdapterHandler 调用 NdisOpenAdapter()
    – MiniLocateDevice() 查找适配器
    – 检查介质类型
    – 分配 ADAPTER_BINDING
    – 建立双向链表关系

    Phase 5: 协议就绪
    =================
    10. NdisCompleteBindAdapter() 确认绑定完成
    11. 协议驱动发送 NetEventBindsComplete PnP 事件
    12. 网络协议栈开始正常收发数据


    8. 关键函数分析

    8.1 发送路径关键函数

    函数位置功能
    NdisSend [protocol.c](file:///d:/reactos/drivers/network/ndis/ndis/protocol.c#L1272-L1285) 协议入口,委托给 ProSend
    ProSend [protocol.c](file:///d:/reactos/drivers/network/ndis/ndis/protocol.c#L472-L574) 检查回环 → DMA → 调用 proSendPacketToMiniport
    proSendPacketToMiniport [protocol.c](file:///d:/reactos/drivers/network/ndis/ndis/protocol.c#L388-L470) 检查繁忙→序列化/非序列化→调用微型端口
    MiniSendComplete [miniport.c](file:///d:/reactos/drivers/network/ndis/ndis/miniport.c#L529-L579) 释放 Scatter/Gather 列表→回调协议SendCompleteHandler
    MiniQueueWorkItem [miniport.c](file:///d:/reactos/drivers/network/ndis/ndis/miniport.c#L980-L1046) 尾部插入工作项
    MiniportWorker [miniport.c](file:///d:/reactos/drivers/network/ndis/ndis/miniport.c#L1222-L1379) 工作线程调度器,处理各种工作类型

    8.2 接收路径关键函数

    函数位置功能
    MiniIndicateData [miniport.c](file:///d:/reactos/drivers/network/ndis/ndis/miniport.c#L175-L251) 遍历协议列表,调用每个协议的 ReceiveHandler
    MiniIndicateReceivePacket [miniport.c](file:///d:/reactos/drivers/network/ndis/ndis/miniport.c#L292-L432) 处理 Packet 数组指示,管理引用计数
    NdisReturnPackets [miniport.c](file:///d:/reactos/drivers/network/ndis/ndis/miniport.c#L256-L290) 递减引用计数,减到0时调用 ReturnPacketHandler
    EthFilterDprIndicateReceive [efilter.c](file:///d:/reactos/drivers/network/ndis/ndis/efilter.c#L69-L99) 以太网接收到入口,过滤后传递到 MiniIndicateData

    8.3 请求处理关键函数

    函数位置功能
    NdisRequest [protocol.c](file:///d:/reactos/drivers/network/ndis/ndis/protocol.c#L1239-L1252) 协议入口,委托给 ProRequest
    ProRequest [protocol.c](file:///d:/reactos/drivers/network/ndis/ndis/protocol.c#L307-L345) 填充 MacBlock → 检查繁忙→MiniDoRequest
    MiniDoRequest [miniport.c](file:///d:/reactos/drivers/network/ndis/ndis/miniport.c#L1106-L1179) 分发到 QueryInformation/SetInformation/CoRequest Handler
    MiniQueryInformation [miniport.c](file:///d:/reactos/drivers/network/ndis/ndis/miniport.c#L804-L862) 同步/异步包装器,通过事件等待完成
    MiniRequestComplete [miniport.c](file:///d:/reactos/drivers/network/ndis/ndis/miniport.c#L480-L527) 请求完成处理,通知协议或信号事件

    8.4 注册和绑定关键函数

    函数位置功能
    NdisMRegisterMiniport [miniport.c](file:///d:/reactos/drivers/network/ndis/ndis/miniport.c#L2709-L2861) 注册微型端口特性
    NdisRegisterProtocol [protocol.c](file:///d:/reactos/drivers/network/ndis/ndis/protocol.c#L1112-L1232) 注册协议特性并绑定适配器
    NdisOpenAdapter [protocol.c](file:///d:/reactos/drivers/network/ndis/ndis/protocol.c#L762-L874) 协议打开一个适配器建立绑定
    ndisBindMiniportsToProtocol [protocol.c](file:///d:/reactos/drivers/network/ndis/ndis/protocol.c#L906-L1107) 将协议绑定到所有适配器
    MiniLocateDevice [miniport.c](file:///d:/reactos/drivers/network/ndis/ndis/miniport.c#L689-L753) 按名称在全局列表查找适配器

    8.5 缓冲区管理关键函数

    函数位置功能
    NdisAllocatePacketPoolEx [buffer.c](file:///d:/reactos/drivers/network/ndis/ndis/buffer.c#L447-L521) 分配数据包池,创建空闲链表
    NdisDprAllocatePacketNonInterlocked [buffer.c](file:///d:/reactos/drivers/network/ndis/ndis/buffer.c#L683-L728) 无锁分配,从空闲链表取一个
    NdisAllocateBuffer [buffer.c](file:///d:/reactos/drivers/network/ndis/ndis/buffer.c#L336-L364) 分配 MDL 作为 NDIS 缓冲区
    NdisGetFirstBufferFromPacket [buffer.c](file:///d:/reactos/drivers/network/ndis/ndis/buffer.c#L871-L910) 遍历数据包获取第一个缓冲区和总长度
    CopyBufferChainToBuffer [buffer.c](file:///d:/reactos/drivers/network/ndis/ndis/buffer.c#L113-L169) 从 MDL 链复制到连续缓冲区

    8.6 中断处理关键函数

    函数位置功能
    ServiceRoutine [io.c](file:///d:/reactos/drivers/network/ndis/ndis/io.c#L49-L79) ISR,调用 MiniportISR 判断中断来源
    HandleDeferredProcessing [io.c](file:///d:/reactos/drivers/network/ndis/ndis/io.c#L16-L47) DPC,调用 MiniportHandleInterrupt+EnableInterrupt

    9. 构建配置

    9.1 CMakeLists.txt

    add_definitions(
    -DNDIS_WRAPPER
    -DNDIS51
    -DNDIS51_MINIPORT
    -DNDIS_MINIPORT_DRIVER
    -DNDIS_LEGACY_DRIVER=1
    -DNDIS_LEGACY_MINIPORT=1
    -DNDIS_LEGACY_PROTOCOL=1)

    add_library(ndis MODULE …)
    set_module_type(ndis kernelmodedriver)
    add_importlibs(ndis ntoskrnl hal)

    9.2 输出

    编译结果为 reactos/system32/drivers/ndis.sys,链接 ntoskrnl 和 hal。

    9.3 版本声明

    NDIS_VERSION = 0x00050001 (= NDIS 5.1)


    附录 A:NDIS 协议驱动特性结构

    typedef struct _NDIS_PROTOCOL_CHARACTERISTICS {
    UCHAR MajorNdisVersion; // NDIS 主版本
    UCHAR MinorNdisVersion; // NDIS 次版本
    USHORT Reserved; // 保留
    NDIS_STRING Name; // 协议名称
    OPEN_ADAPTER_COMPLETE_HANDLER OpenAdapterCompleteHandler;
    CLOSE_ADAPTER_COMPLETE_HANDLER CloseAdapterCompleteHandler;
    SEND_COMPLETE_HANDLER SendCompleteHandler;
    TRANSFER_DATA_COMPLETE_HANDLER TransferDataCompleteHandler;
    RECEIVE_HANDLER ReceiveHandler;
    RECEIVE_COMPLETE_HANDLER ReceiveCompleteHandler;
    STATUS_HANDLER StatusHandler;
    STATUS_COMPLETE_HANDLER StatusCompleteHandler;
    BIND_ADAPTER_HANDLER BindAdapterHandler;
    UNBIND_ADAPTER_HANDLER UnbindAdapterHandler;
    PNP_EVENT_HANDLER PnPEventHandler; // NDIS 5.0
    RECEIVE_PACKET_HANDLER ReceivePacketHandler; // NDIS 5.0
    SEND_COMPLETE_HANDLER SendCompleteHandler;
    ...
    } NDIS_PROTOCOL_CHARACTERISTICS;

    附录 B:NDIS 微型端口驱动特性结构

    typedef struct _NDIS_MINIPORT_CHARACTERISTICS {
    UCHAR MajorNdisVersion;
    UCHAR MinorNdisVersion;
    USHORT Filler;
    UINT Reserved;
    CHECK_FOR_HANG_HANDLER CheckForHangHandler;
    DISABLE_INTERRUPT_HANDLER DisableInterruptHandler;
    ENABLE_INTERRUPT_HANDLER EnableInterruptHandler;
    HALT_HANDLER HaltHandler;
    HANDLE_INTERRUPT_HANDLER HandleInterruptHandler;
    INITIALIZE_HANDLER InitializeHandler;
    ISR_HANDLER ISRHandler;
    QUERY_INFORMATION_HANDLER QueryInformationHandler;
    RESET_HANDLER ResetHandler;
    SEND_HANDLER SendHandler; // NDIS 3.0/4.0
    SET_INFORMATION_HANDLER SetInformationHandler;
    TRANSFER_DATA_HANDLER TransferDataHandler;
    RETURN_PACKET_HANDLER ReturnPacketHandler; // NDIS 4.0
    SEND_PACKETS_HANDLER SendPacketsHandler; // NDIS 4.0
    ...
    } NDIS_MINIPORT_CHARACTERISTICS;


    附录 C:参考文档

    • NDIS 5.1 规范 (MSDN)
    • [ddk/ndis.h](file:///d:/reactos/sdk/include/ddk/ndis.h) — NDIS DDK 头文件
    • [ddk/ndisguid.h](file:///d:/reactos/sdk/include/ddk/ndisguid.h) — NDIS GUID 定义
    • [psdk/ntddndis.h](file:///d:/reactos/sdk/include/psdk/ntddndis.h) — NDIS IOCTL 定义
    赞(0)
    未经允许不得转载:网硕互联帮助中心 » NDIS 库 (ndis.sys) 驱动程序分析
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!