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

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

diagram illustrating a basic condis receive operation, which involves a protocol driver, ndis, and a miniport driver.

如上图所示,微型端口驱动程序调用 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结构的所有权。 如果微型端口驱动程序指示设置了NDIS_RECEIVE_FLAGS_RESOURCES标志的NET_BUFFER结构,协议驱动程序必须复制数据,因此应避免以这种方式使用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