发送网络数据

下图演示了一个基本的发送操作,该操作涉及协议驱动程序、NDIS 和微型端口驱动程序。

显示具有协议驱动程序、NDIS 和微型端口驱动程序的基本 NDIS 发送操作的关系图。

协议驱动程序调用 NdisSendNetBufferLists 函数以发送绑定上的 NET_BUFFER_LIST 结构。 NDIS 调用微型端口驱动程序的 MiniportSendNetBufferLists 函数,将NET_BUFFER_LIST结构转发到基础微型端口驱动程序。

所有基于NET_BUFFER的发送操作都是异步的。 完成时,微型端口驱动程序使用适当的状态代码调用 NdisMSendNetBufferListsComplete 函数。 每个NET_BUFFER_LIST结构的发送可以单独完成。 每次微型端口驱动程序调用 NdisMSendNetBufferListsComplete 时,NDIS 都会调用协议驱动程序的 ProtocolSendNetBufferListsComplete 函数。

一旦 NDIS 调用协议驱动程序的 ProtocolSendNetBufferListsComplete 函数,协议驱动程序就可以回收NET_BUFFER_LIST结构以及所有相关结构和数据的所有权。

微型端口驱动程序或 NDIS 可以按任意顺序返回 NET_BUFFER_LIST 结构。 协议驱动程序保证未修改附加到每个 NET_BUFFER_LIST 结构的NET_BUFFER结构列表。

任何 NDIS 驱动程序都可以在NET_BUFFER_LIST结构中分离NET_BUFFER结构。 任何 NDIS 驱动程序还可以在NET_BUFFER结构中分离 MDL。 但是,驱动程序必须始终返回具有原始形式的NET_BUFFER结构和 MDL 的NET_BUFFER_LIST结构。 例如,中间驱动程序可以将NET_BUFFER_LIST分成两个新的NET_BUFFER_LIST结构,并将部分原始数据传递给下一个驱动程序。 但是,当中间驱动程序完成原始NET_BUFFER_LIST它必须返回包含原始NET_BUFFER结构和 MDL 的完整NET_BUFFER_LIST。

协议驱动程序将 NET_BUFFER_LIST 结构中的 SourceHandle 成员设置为 NDIS 在调用 NdisOpenAdapterEx 函数时提供的 NdisBindingHandle。 NDIS 使用 SourceHandle 成员将NET_BUFFER_LIST结构返回到发送NET_BUFFER_LIST结构的协议驱动程序。

中间驱动程序还会将 NET_BUFFER_LIST 结构中的 SourceHandle 成员设置为 NDIS 在调用 NdisOpenAdapterEx 时提供的 NdisBindingHandle 值。 如果中间驱动程序转发发送请求,则驱动程序必须在写入 SourceHandle 成员之前保存过度驱动程序提供的 SourceHandle 值。 当 NDIS 将转发NET_BUFFER_LIST结构返回到中间驱动程序时,中间驱动程序必须还原它保存的 SourceHandle