FILTER_RECEIVE_NET_BUFFER_LISTS回调函数 (ndis.h)

NDIS 调用 FilterReceiveNetBufferLists 函数以请求筛选器驱动程序处理接收指示。

注意 必须使用 FILTER_RECEIVE_NET_BUFFER_LISTS 类型声明函数。 有关详细信息,请参阅以下示例部分。
 

语法

FILTER_RECEIVE_NET_BUFFER_LISTS FilterReceiveNetBufferLists;

void FilterReceiveNetBufferLists(
  [in] NDIS_HANDLE FilterModuleContext,
  [in] PNET_BUFFER_LIST NetBufferLists,
  [in] NDIS_PORT_NUMBER PortNumber,
  [in] ULONG NumberOfNetBufferLists,
  [in] ULONG ReceiveFlags
)
{...}

参数

[in] FilterModuleContext

筛选器模块上下文区域的句柄。 筛选器驱动程序在 FilterAttach 函数中创建并初始化了此上下文区域。

[in] NetBufferLists

基础驱动程序分配的 NET_BUFFER_LIST 结构的链接列表。 每个 NET_BUFFER_LIST 结构都包含一个 NET_BUFFER 结构。

[in] PortNumber

标识微型端口适配器端口的端口号。 微型端口适配器端口号是通过调用 NdisMAllocatePort 函数分配的。 零值标识微型端口适配器的默认端口。

[in] NumberOfNetBufferLists

NetBufferLists 中的结构链接列表中的NET_BUFFER_LIST结构数。

[in] ReceiveFlags

定义接收指示的属性的标志。 标志可以与 OR 操作结合使用。 若要清除所有标志,请将此成员设置为零。 此函数支持以下标志:

NDIS_RECEIVE_FLAGS_DISPATCH_LEVEL

指定当前 IRQL DISPATCH_LEVEL。 有关此标志的详细信息,请参阅 Dispatch IRQL Tracking

NDIS_RECEIVE_FLAGS_RESOURCES

指定 NDIS 在调用 FilterReceiveNetBufferLists 后立即回收NET_BUFFER_LIST结构和任何附加NET_BUFFER结构的所有权。

NDIS_RECEIVE_FLAGS_SINGLE_ETHER_TYPE

指定 NetBufferLists 列表中的所有NET_BUFFER_LIST结构 (EtherType) 具有相同的协议类型。

NDIS_RECEIVE_FLAGS_SINGLE_VLAN

指定 NetBufferLists 列表中的所有NET_BUFFER_LIST结构都属于同一 VLAN。

NDIS_RECEIVE_FLAGS_PERFECT_FILTERED

指定 NetBufferLists 列表中的所有NET_BUFFER_LIST结构仅包含与分配给微型端口适配器的数据包筛选器和多播地址列表匹配的数据。

NDIS_RECEIVE_FLAGS_SINGLE_QUEUE

指定 NetBufferLists 列表中的所有NET_BUFFER_LIST结构都属于同一 VM 队列。 如果在 的 Flags 成员中设置了NDIS_RECEIVE_QUEUE_PARAMETERS_PER_QUEUE_RECEIVE_INDICATION标志,微型端口驱动程序必须为队列上的所有接收指示设置此标志 分配 队列时NDIS_RECEIVE_QUEUE_PARAMETERS结构。

NDIS_RECEIVE_FLAGS_SHARED_MEMORY_INFO_VALID

指定 NetBufferLists 列表中的所有NET_BUFFER_LIST结构都包含有效的共享内存信息。 在接收 的NET_BUFFER_LIST上设置此标志时,NDIS 会将共享内存信息视为有效。 如果未设置此标志,NDIS 和驱动程序将忽略共享内存信息。 例如,修改数据包数据的中间驱动程序可以使用此标志确定是否应复制数据。 微型端口驱动程序可以使用 标志来确定如何在删除队列时释放与 VM 队列关联的内存。

NDIS_RECEIVE_FLAGS_MORE_NBLS

保留。

NDIS_RECEIVE_FLAGS_SWITCH_SINGLE_SOURCE

如果设置了此标志, 则NET_BUFFER_LIST 结构的链接列表中的所有数据包都源自同一 Hyper-V 可扩展交换机源端口。

有关详细信息,请参阅 Hyper-V 可扩展交换机发送和接收标志

注意如果NET_BUFFER_LIST结构链接列表中的每个数据包使用相同的源端口,则当接收请求完成时,扩展应在 FilterReturnNetBufferListsReturnFlags 参数中设置NDIS_RETURN_FLAGS_SWITCH_SINGLE_SOURCE标志。 如果扩展调用 NdisFReturnNetBufferLists 以返回它未源自或克隆的数据包,则必须在 ReturnFlags 参数中设置此标志。
 

NDIS_RECEIVE_FLAGS_SWITCH_DESTINATION_GROUP

如果设置了此标志, 则NET_BUFFER_LIST 结构链接列表中的所有数据包都将转发到同一可扩展交换机目标端口。

有关详细信息,请参阅 Hyper-V 可扩展交换机发送和接收标志

注意如果NET_BUFFER_LIST结构链接列表中的每个数据包使用相同的目标端口,则当接收请求完成时,扩展应在 FilterReturnNetBufferListsReturnFlags 参数中设置NDIS_RECEIVE_FLAGS_SWITCH_DESTINATION_GROUP标志。 如果扩展调用 NdisFReturnNetBufferLists 以返回它未源自或克隆的数据包,则必须在 ReturnFlags 参数中设置此标志。
 

返回值

备注

FilterReceiveNetBufferLists 是一个可选函数。 如果筛选器驱动程序不筛选接收指示,它可以在调用 时将此函数的入口点设置为 NULL NdisFRegisterFilterDriver 函数。

注意 提供 FilterReceiveNetBufferLists 函数的 筛选器驱动程序必须提供 FilterStatus 函数。
 
筛选器驱动程序可以从 FilterSetModuleOptions 函数调用 NdisSetOptionalHandlers 函数,为筛选器模块指定 FilterReceiveNetBufferLists 函数。

NDIS 调用 FilterReceiveNetBufferLists 来处理由基础驱动程序启动的接收指示。 NDIS 还可以调用此函数作为环回的结果。

如果筛选器驱动程序未指定 FilterReceiveNetBufferLists 函数,则 NDIS 会调用堆栈中指定 FilterReceiveNetBufferLists 函数的下一个较高筛选器驱动程序。 如果没有此类筛选器驱动程序,NDIS 会调用过度覆盖的驱动程序的 ProtocolReceiveNetBufferLists 函数。

如果未设置 ReceiveFlags 参数中的NDIS_RECEIVE_FLAGS_RESOURCES标志,筛选器驱动程序将保留NET_BUFFER_LIST结构的所有权,直到调用 NdisFReturnNetBufferLists 函数。

如果设置了 ReceiveFlags 参数中的NDIS_RECEIVE_FLAGS_RESOURCES标志,则筛选器驱动程序无法保留NET_BUFFER_LIST结构和关联的基础驱动程序分配的资源。 此标志可以指示基础驱动程序的接收资源不足。 FilterReceiveNetBufferLists 函数应尽快返回。 在返回之前, FilterReceiveNetBufferLists 函数可以将接收的数据复制到筛选器驱动程序分配的存储中,或通过调用 传递缓冲区 NdisFIndicateReceiveNetBufferLists 函数。

注意 如果设置了 NDIS_RECEIVE_FLAGS_RESOURCES 标志,筛选器驱动程序必须在链接列表中保留原始 NET_BUFFER_LIST 结构集。 例如,当设置此标志时,驱动程序可能会处理结构,并一次一个地在堆栈上指示它们,但在函数返回之前,它必须还原原始链接列表。
 
筛选器驱动程序可以先筛选收到的数据,然后再将数据指示给过度覆盖的驱动程序。 对于提交到 FilterReceiveNetBufferLists 函数的每个缓冲区,筛选器驱动程序可以执行以下操作:
  • 通过调用 将缓冲区传递到下一个过度的驱动程序 NdisFIndicateReceiveNetBufferLists 函数。

    驱动程序可以在调用 NdisFIndicateReceiveNetBufferLists 之前修改缓冲区的内容。

    驱动程序可以更改 NDIS 传递给 FilterReceiveNetBufferLists的NDIS_RECEIVE_FLAGS_RESOURCES标志设置,或者直接将其传递给 NdisFIndicateReceiveNetBufferLists

  • 放弃缓冲区。 如果 NDIS 清除了 NDIS_RECEIVE_FLAGS_RESOURCES 标志,请调用 NdisFReturnNetBufferLists 函数以放弃缓冲区。 如果 NDIS 设置 NDIS_RECEIVE_FLAGS_RESOURCES 标志,则不执行任何操作,并从 FilterReceiveNetBufferLists 返回以放弃缓冲区。
  • 在本地数据结构中将缓冲区排队,供以后处理。 如果 NDIS 设置 FilterReceiveNetBufferLists的NDIS_RECEIVE_FLAGS_RESOURCES标志,则筛选器驱动程序必须在从 FilterReceiveNetBufferLists 返回之前创建一个副本。
  • 复制缓冲区,并使用副本生成接收指示。 接收指示类似于筛选器驱动程序启动的接收指示。 在这种情况下,驱动程序必须将原始缓冲区返回到基础驱动程序。
如果名为 NdisFIndicateReceiveNetBufferLists 的 筛选器驱动程序未设置 NDIS_RECEIVE_FLAGS_RESOURCES 标志,则 NDIS 将调用筛选器模块的 FilterReturnNetBufferLists 函数。 在其 FilterReturnNetBufferLists 函数中,筛选器驱动程序将撤消它在接收指示路径上的缓冲区上执行的操作。

如果筛选器模块处于 “已暂停” 状态,则筛选器驱动程序不得针对该筛选器模块发出任何接收指示。 筛选器驱动程序不得将其创建的缓冲区传递给 NdisFIndicateReceiveNetBufferLists。 但是,驱动程序可以传递来自基础驱动程序的接收指示。

NDIS 在 IRQL <= DISPATCH_LEVEL 调用 FilterReceiveNetBufferLists

示例

若要定义 FilterReceiveNetBufferLists 函数,必须首先提供一个函数声明来标识要定义的函数类型。 Windows 为驱动程序提供了一组函数类型。 使用函数类型声明函数可帮助 驱动程序的代码分析静态驱动程序验证程序 (SDV) 和其他验证工具查找错误,并且这是为 Windows 操作系统编写驱动程序的要求。

例如,若要定义名为“ MyReceiveNetBufferLists ”的 FilterReceiveNetBufferLists 函数,请使用 FILTER_RECEIVE_NET_BUFFER_LISTS 类型,如以下代码示例所示:

FILTER_RECEIVE_NET_BUFFER_LISTS MyReceiveNetBufferLists;

然后,按如下所示实现函数:

_Use_decl_annotations_
VOID
 MyReceiveNetBufferLists(
    NDIS_HANDLE  FilterModuleContext,
    PNET_BUFFER_LIST  NetBufferLists,
    NDIS_PORT_NUMBER  PortNumber,
    ULONG  NumberOfNetBufferLists,
    ULONG  ReceiveFlags
    )
  {...}

FILTER_RECEIVE_NET_BUFFER_LISTS函数类型在 Ndis.h 头文件中定义。 若要在运行代码分析工具时更准确地识别错误,请务必将 Use_decl_annotations 注释添加到函数定义。 Use_decl_annotations批注可确保使用应用于头文件中FILTER_RECEIVE_NET_BUFFER_LISTS函数类型的注释。 有关函数声明要求的详细信息,请参阅 使用 NDIS 驱动程序的函数角色类型声明函数

有关 Use_decl_annotations的信息,请参阅 批注函数行为

要求

要求
最低受支持的客户端 在 NDIS 6.0 及更高版本中受支持。
目标平台 Windows
标头 ndis.h (包括 Ndis.h)
IRQL <= DISPATCH_LEVEL

另请参阅

FilterAttach

FilterReturnNetBufferLists

FilterSetModuleOptions

NDIS_RECEIVE_QUEUE_PARAMETERS

NET_BUFFER

NET_BUFFER_LIST

NdisFIndicateReceiveNetBufferLists

NdisFRegisterFilterDriver

NdisFReturnNetBufferLists

NdisMAllocatePort

NdisSetOptionalHandlers

ProtocolReceiveNetBufferLists