在 CoNDIS 驱动程序中接收 NET_BUFFER 结构

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

说明涉及协议驱动程序、NDIS 和微型端口驱动程序的基本 CoNDIS 接收操作的关系图。

如上图所示,微型端口驱动程序调用 NdisMCoIndicateReceiveNetBufferLists 函数,以指示 NET_BUFFER 结构过度覆盖驱动程序。 在大多数微型端口驱动程序中,每个NET_BUFFER结构都附加到单独的 NET_BUFFER_LIST 结构,因此协议驱动程序可以创建NET_BUFFER_LIST结构的原始列表的子集,并将其转发到不同的客户端。 但是,附加到NET_BUFFER_LIST的NET_BUFFER结构的数量取决于驱动程序。

微型端口驱动程序链接所有NET_BUFFER_LIST结构后,微型端口驱动程序会将指向列表中第一个NET_BUFFER_LIST结构的指针传递给 NdisMCoIndicateReceiveNetBufferLists 函数。 NDIS 检查NET_BUFFER_LIST结构,并调用与指定的虚拟连接关联的协议驱动程序的 ProtocolCoReceiveNetBufferLists 函数 (VC) 。 NDIS 传递列表的子集,该子集仅包含与每个协议驱动程序的正确绑定关联的NET_BUFFER_LIST结构。

如果在协议驱动程序的 ProtocolCoReceiveNetBufferLists 函数的 CoReceiveFlags 参数中设置了NDIS_RECEIVE_FLAGS_STATUS_RESOURCES标志,则 NDIS 在 ProtocolCoReceiveNetBufferLists 返回后立即重新获得NET_BUFFER_LIST结构的所有权。

如果未在协议驱动程序的 ProtocolCoReceiveNetBufferLists 函数的 CoReceiveFlags 参数中设置NDIS_RECEIVE_FLAGS_STATUS_RESOURCES标志,则协议驱动程序可以保留NET_BUFFER_LIST结构的所有权。 在这种情况下,协议驱动程序必须通过调用 NdisReturnNetBufferLists 函数返回NET_BUFFER_LIST结构。

如果微型端口驱动程序在接收资源上运行不足,则可以在 NdisMCoIndicateReceiveNetBufferLists 函数的 CoReceiveFlags 参数中设置NDIS_RECEIVE_FLAGS_STATUS_RESOURCES标志。 在这种情况下,驱动程序可以在 NdisMCoIndicateReceiveNetBufferLists 返回后立即回收所有指示NET_BUFFER_LIST结构和嵌入NET_BUFFER结构的所有权。 如果微型端口驱动程序指示NET_BUFFER结构并设置了NDIS_RECEIVE_FLAGS_RESOURCES标志,则协议驱动程序必须复制数据,因此应避免以这种方式使用 NDIS_RECEIVE_FLAGS_RESOURCES。 微型端口驱动程序应检测其接收资源不足的情况,并应完成避免这种情况所需的任何步骤。

NDIS 在协议驱动程序调用 NdisReturnNetBufferLists 后,调用微型端口驱动程序的 MiniportReturnNetBufferLists 函数。

注意 如果微型端口驱动程序指示具有给定状态 的NET_BUFFER_LIST 结构,则 NDIS 不需要向具有相同状态的过度驱动程序指示NET_BUFFER_LIST结构。 例如,NDIS 可以复制设置了NDIS_RECEIVE_FLAGS_RESOURCES标志的NET_BUFFER_LIST结构,并将副本指示到清除了此标志的过度驱动程序。

NDIS 可以任意顺序和任意组合将NET_BUFFER_LIST结构返回到微型端口驱动程序。 也就是说,NDIS 通过调用 MiniportReturnNetBufferLists 返回到微型端口驱动程序的NET_BUFFER_LIST结构的链接列表可以具有以前对 NdisMCoIndicateReceiveNetBufferLists 的不同调用NET_BUFFER_LIST结构。

微型端口驱动程序必须将 NET_BUFFER_LIST 结构中的 SourceHandle 成员设置为与 NdisMCoIndicateReceiveNetBufferListsNdisVcHandle 参数相同的值。 以便 NDIS 可以将NET_BUFFER_LIST结构返回到正确的微型端口驱动程序。

中间驱动程序还会将 NET_BUFFER_LIST 结构中的 SourceHandle 成员设置为 NdisVcHandle 值。 如果中间驱动程序转发接收指示,则驱动程序必须在写入 SourceHandle 成员之前保存基础驱动程序提供的 SourceHandle 值。 当 NDIS 将转发NET_BUFFER_LIST结构返回到中间驱动程序时,中间驱动程序必须还原它保存的 SourceHandle