接收网络数据

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

说明基本网络接收操作的关系图。

微型端口驱动程序调用 NdisMIndicateReceiveNetBufferLists 函数,以指示更高级别驱动程序 NET_BUFFER 结构。 每个NET_BUFFER结构通常应附加到单独的 NET_BUFFER_LIST 结构。 这样,协议驱动程序就可以创建NET_BUFFER_LIST结构的原始列表的子集,并将其转发到不同的客户端。 某些驱动程序(例如本机 IEEE 802.11 微型端口驱动程序)可能会将多个NET_BUFFER结构附加到NET_BUFFER_LIST结构。

链接所有NET_BUFFER_LIST结构后,微型端口驱动程序会将指向列表中第一个NET_BUFFER_LIST结构的指针传递给 NdisMIndicateReceiveNetBufferLists 函数。 NDIS 检查NET_BUFFER_LIST结构,并调用与NET_BUFFER_LIST结构关联的每个协议驱动程序的 ProtocolReceiveNetBufferLists 函数。 NDIS 传递列表的子集,该子集仅包含与每个协议驱动程序的正确绑定关联的NET_BUFFER_LIST结构。 NDIS 将 NET_BUFFER_LIST 结构中指定的 NetBufferListFrameType 值与每个协议驱动程序注册的帧类型匹配。

如果设置了传递给协议驱动程序的 ProtocolReceiveNetBufferLists 函数的 ReceiveFlags 参数中的NDIS_RECEIVE_FLAGS_RESOURCES标志,则 NDIS 会在 ProtocolReceiveNetBufferLists 调用返回后立即重新获得NET_BUFFER_LIST结构的所有权。

注意 如果设置了NDIS_RECEIVE_FLAGS_RESOURCES标志,则协议驱动程序必须在链接列表中保留原始NET_BUFFER_LIST结构集。 例如,设置此标志时,驱动程序可能会处理这些结构,并指示它们一次上堆栈一个,但在函数返回之前,它必须还原原始链接列表。

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

如果微型端口驱动程序在接收资源上运行不足,则可以在调用 NdisMIndicateReceiveNetBufferLists 时在 ReceiveFlags 参数中设置NDIS_RECEIVE_FLAGS_RESOURCES标志。 在这种情况下,驱动程序可以在 NdisMIndicateReceiveNetBufferLists 返回后立即回收所有指示NET_BUFFER_LIST结构和嵌入NET_BUFFER结构的所有权。 指示设置了NDIS_RECEIVE_FLAGS_RESOURCES标志的NET_BUFFER结构会强制协议驱动程序复制数据,因此应避免这样做。 微型端口驱动程序应检测即将耗尽接收资源的时间,并采取任何必要的步骤来避免这种情况。

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

注意 如果微型端口驱动程序指示NET_BUFFER_LIST结构并设置了NDIS_RECEIVE_FLAGS_RESOURCES标志,这并不意味着 NDIS 会向具有相同状态的协议驱动程序指示NET_BUFFER_LIST结构。 例如,NDIS 可以复制设置了 NDIS_RECEIVE_FLAGS_RESOURCES 标志的NET_BUFFER_LIST结构,并在清除标志的情况下指示复制到协议驱动程序。

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

微型端口驱动程序应将 NET_BUFFER_LIST 结构中的 SourceHandle 成员设置为 NDIS 在 MiniportInitializeEx 函数中提供给微型端口驱动程序的 MiniportAdapterHandle 筛选器驱动程序必须将筛选器驱动程序源自的每个NET_BUFFER_LIST结构的 SourceHandle 成员设置为筛选器的 NdisFilterHandle ,NDIS 在 FilterAttach 函数中提供给筛选器驱动程序。 筛选器驱动程序不得修改任何非筛选器驱动程序产生的NET_BUFFER_LIST结构中的 SourceHandle 成员。

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