NDIS Filter开发-网络数据的传输

和NIC小端口驱动不同的是,无需考虑网络数据具体是如何传输的,只需要针对NBL进行处理即可。Filter驱动程序可以启动发送请求和接收指示,或“过滤”其他驱动程序的请求和指示。Filter模块堆叠在微型端口适配器上。

驱动程序堆栈中的Filter模块可以筛选与基础适配器关联的所有发送请求和接收指示。 这适用于适配器的所有协议绑定。

Filter驱动程序不直接支持基于 NDIS_PACKET 结构的旧发送和接收操作。 相反,NDIS 将接收来自旧微型端口驱动程序的指示转换为 NET_BUFFER 结构。 此外,NDIS 还处理从基于NET_BUFFER结构的发送请求到基于NDIS_PACKET结构的旧发送请求的所需转换。

Filter驱动程序缓冲区管理

Filter驱动程序创建缓冲区以复制从其他驱动程序获取的网络数据,或启动发送或接收操作。

如果Filter驱动程序不创建缓冲区,则驱动程序不会管理缓冲池。 此类驱动程序只是传递它从其他驱动程序接收的缓冲区。

创建缓冲区以支持发送或接收操作的Filter驱动程序必须管理 NET_BUFFER_LIST 结构池和 NET_BUFFER 结构池。

若要创建这些池,驱动程序会调用以下函数:

  • NdisAllocateNetBufferListPool
  • NdisAllocateNetBufferPool

Filter驱动程序可以使用以下函数从池中分配结构:

  • NdisAllocateNetBufferAndNetBufferList
  • NdisAllocateNetBufferList
  • NdisAllocateNetBuffer

调用 NdisAllocateNetBufferAndNetBufferList 比调用 NdisAllocateNetBufferList 和 NdisAllocateNetBuffer 更高效。 但是, NdisAllocateNetBufferAndNetBufferList 仅在NET_BUFFER_LIST结构上创建一个NET_BUFFER结构。 若要使用 NdisAllocateNetBufferAndNetBufferList,驱动程序必须在调用 NdisAllocateNetBufferListPool 时将 AllocateNetBuffer 参数设置为 TRUE。

源自发送请求的Filter驱动程序应确定基础驱动程序的上下文和回填空间要求。 Filter驱动程序使用重启属性来确定基础驱动程序的回填要求。 Filter驱动程序应确定处于 “正在重启” 状态的回填和上下文要求。 驱动程序应为整个堆栈分配足够的回填和上下文空间。 如有必要,Filter驱动程序可以释放池并将其重新分配为 “正在重启” 状态。

Filter驱动程序使用以下函数来释放池:

  • NdisFreeNetBufferListPool
  • NdisFreeNetBufferPool

Filter驱动程序使用以下函数释放从池中分配的结构:

  • NdisFreeNetBufferList
  • NdisFreeNetBuffer

在释放关联的NET_BUFFER_LIST结构之前,驱动程序应释放使用 NdisAllocateNetBuffer 分配NET_BUFFER结构。 当驱动程序为关联的NET_BUFFER_LIST结构调用 NdisFreeNetBufferList 时,将释放使用 NdisAllocateNetBufferAndNetBufferList 分配的NET_BUFFER结构。

从Filter驱动程序发送数据
发送Filter驱动程序启动的请求

Filter驱动程序可以启动发送请求或过滤驱动程序启动的发送请求。 当协议驱动程序调用 NdisSendNetBufferLists 函数时,NDIS 会将指定的 NET_BUFFER_LIST 结构提交到驱动程序堆栈中最顶层的Filter模块,下图演示了Filter驱动程序启动的发送操作。

Filter驱动程序调用 NdisFSendNetBufferLists 函数以发送 在NET_BUFFER_LIST 结构列表中定义的网络数据。

Filter驱动程序必须将它创建的每个NET_BUFFER_LIST结构的 SourceHandle 成员设置为它传递给 NdisFSendNetBufferLists 的 NdisFilterHandle 参数的相同值。 NDIS 驱动程序不应修改该驱动程序未源自NET_BUFFER_LIST结构的 SourceHandle 成员。

在调用 NdisFSendNetBufferLists 之前,Filter驱动程序可以设置随 NET_BUFFER_LIST_INFO 宏一起发送请求的信息。 基础驱动程序可以使用 NET_BUFFER_LIST_INFO 宏检索此信息。

Filter驱动程序一旦调用 NdisFSendNetBufferLists,就会放弃NET_BUFFER_LIST结构和所有关联资源的所有权。 NDIS 可以处理发送请求或将请求传递给基础驱动程序。

NDIS 调用 FilterSendNetBufferListsComplete 函数,将结构和数据返回到Filter驱动程序。 在将列表传递给 FilterSendNetBufferListsComplete 之前,NDIS 可以将多个发送请求中的结构和数据收集到NET_BUFFER_LIST结构的单个链接列表中

在 NDIS 调用 FilterSendNetBufferListsComplete 之前,发送请求的当前状态是未知的。 在 NDIS 将结构返回到 FilterSendNetBufferListsComplete 之前,Filter驱动程序绝不应尝试检查NET_BUFFER_LIST结构或任何关联数据。

FilterSendNetBufferListsComplete 执行完成发送操作所需的任何后处理。

当 NDIS 调用 FilterSendNetBufferListsComplete 时,Filter驱动程序将重新获得与 NetBufferLists 参数指定的NET_BUFFER_LIST结构关联的所有资源的所有权。 FilterSendNetBufferListsComplete 可以释放这些资源 ,例如,通过调用 NdisFreeNetBuffer 和 NdisFreeNetBufferList 函数 ,或者准备在后续调用 NdisFSendNetBufferLists 时重复使用。

NDIS 始终按照传递给 NdisFSendNetBufferLists 的Filter驱动程序确定的顺序向基础驱动程序提交Filter提供的网络数据。 但是,按指定顺序发送数据后,基础驱动程序可以按任意顺序返回缓冲区。

Filter驱动程序可以请求其发起的发送请求的环回。 若要请求环回,驱动程序在 NdisFSendNetBufferLists 的 SendFlags 参数中设置NDIS_SEND_FLAGS_CHECK_FOR_LOOPBACK标志。 NDIS 指示包含发送数据的已接收数据包。

注意 Filter驱动程序应跟踪其发起的发送请求,并确保在此类请求完成时不会调用 NdisFSendNetBufferListsComplete 函数。

过滤发送请求

下图说明了如何过滤由过度分配的驱动程序发起的发送请求:

NDIS 调用Filter驱动程序的 FilterSendNetBufferLists 函数来筛选过大驱动程序的发送请求。

Filter驱动程序不得修改从其他驱动程序接收的 NET_BUFFER_LIST 结构中的 SourceHandle 成员。

Filter驱动程序可以筛选数据并将筛选的数据发送到基础驱动程序。 对于提交到 FilterSendNetBufferLists 的每个NET_BUFFER结构,Filter驱动程序可以执行以下操作:

  • 通过调用 NdisFSendNetBufferLists 函数,将缓冲区传递到下一个基础驱动程序。 NDIS 保证上下文空间的可用性, 查看Filter驱动程序 NET_BUFFER_LIST_CONTEXT结构。 Filter驱动程序可以在调用 NdisFSendNetBufferLists 之前修改缓冲区内容。 筛选数据的处理与Filter驱动程序启动的发送操作一样进行;
  • 通过调用 NdisFSendNetBufferListsComplete 函数删除缓冲区;
  • 在本地数据结构中将缓冲区排队,供以后处理。 Filter驱动程序的设计决定了导致驱动程序处理排队缓冲区的原因。 一些示例包括超时后的处理或在收到特定缓冲区后进行处理。注意 如果驱动程序将发送请求排队以供以后处理,则必须支持发送取消请求。 有关发送取消请求的详细信息,请参阅 在Filter驱动程序中取消发送请求;
  • 复制缓冲区,并使用副本发起发送请求。 发送操作类似于Filter驱动程序发起的发送请求。 在这种情况下,驱动程序必须通过调用 NdisFSendNetBufferListsComplete 函数,将原始缓冲区返回到上置驱动程序;

完成发送请求会继续上行驱动程序堆栈。 当微型端口驱动程序调用 NdisMSendNetBufferListsComplete 函数时,NDIS 将调用 FilterSendNetBufferListsComplete 函数以获取最低覆盖Filter模块。

发送操作完成后,Filter驱动程序将反转对Filter驱动程序在 FilterSendNetBufferLists 中对过度覆盖驱动程序的缓冲区描述符的修改。 驱动程序调用 NdisFSendNetBufferListsComplete 函数,以将NET_BUFFER_LIST结构的链接列表返回到上部驱动程序,并返回发送请求的最终状态。

当最顶层的Filter模块调用 NdisFSendNetBufferListsComplete 时,NDIS 将调用原始协议驱动程序的 ProtocolSendNetBufferListsComplete 函数。

不提供 FilterSendNetBufferLists 函数的Filter 驱动程序仍然可以启动发送请求。 如果此类驱动程序确实启动发送请求,则必须提供 FilterSendNetBufferListsComplete 函数,并且不得在驱动程序堆栈上传递完整事件。

Filter驱动程序可以传递或筛选过大驱动程序的环回请求。 若要传递环回请求,如果 NDIS 在 FilterSendNetBufferLists 的 SendFlags 参数中设置NDIS_SEND_FLAGS_CHECK_FOR_LOOPBACK,Filter驱动程序在调用 NdisFSendNetBufferLists 时在 SendFlags 参数中设置NDIS_SEND_FLAGS_CHECK_FOR_LOOPBACK。 NDIS 指示包含发送数据的已接收数据包。

通常,如果Filter驱动程序以 NDIS 无法提供标准服务(如环回 )的方式修改任何行为,则Filter驱动程序必须为 NDIS 提供该服务。 例如,修改硬件地址请求 ( OID_802_3_CURRENT_ADDRESS) 的Filter驱动程序应处理定向到新硬件地址的缓冲区的环回。 在这种情况下,NDIS 无法提供它通常提供的环回服务,因为Filter更改了地址。 此外,如果Filter驱动程序设置杂乱模式 ,例如OID_GEN_CURRENT_PACKET_FILTER),则它不应将其收到的额外数据传递给过度覆盖的驱动程序。

取消Filter驱动程序中的发送请求

Filter驱动程序可以取消发送由Filter驱动程序发起或由过度分配驱动程序发起的请求。

取消Filter驱动程序发送请求

下图说明了如何取消由Filter驱动程序发起的发送请求:

Filter驱动程序为它为发送操作创建的每个NET_BUFFER_LIST结构调用 NDIS_SET_NET_BUFFER_LIST_CANCEL_ID宏。 NDIS_SET_NET_BUFFER_LIST_CANCEL_ID 函数使用取消标识符标记指定的数据。

在将取消 ID 分配给网络数据之前,Filter驱动程序必须调用 NdisGeneratePartialCancelId 以获取它分配的每个取消 ID 的高序字节。 这可确保驱动程序不会重复系统中其他驱动程序分配的取消 ID。 驱动程序通常从 DriverEntry 例程调用 NdisGeneratePartialCancelId 一次。 但是,驱动程序可以通过多次调用 NdisGeneratePartialCancelId 来获取多个部分取消标识符。

若要取消标记NET_BUFFER_LIST结构中数据的挂起传输,Filter驱动程序会将取消 ID 传递给 NdisFCancelSendNetBufferLists 函数。 驱动程序可以通过调用 NDIS_GET_NET_BUFFER_LIST_CANCEL_ID 宏来获取 NET_BUFFER_LIST 结构的取消 ID。

如果Filter驱动程序使用相同的取消标识符标记所有NET_BUFFER_LIST结构,则只需调用 NdisFCancelSendNetBufferLists 即可取消所有挂起的传输。 如果Filter驱动程序使用唯一标识符标记NET_BUFFER_LIST结构的子组中的所有NET_BUFFER_LIST结构,则只需调用 NdisFCancelSendNetBufferLists 即可取消该子组中所有挂起的传输。

NDIS 调用基础驱动程序的取消发送函数。 中止挂起的传输后,基础驱动程序调用 send complete 函数 (例如 NdisMSendNetBufferListsComplete) ,以返回完成状态为NDIS_STATUS_SEND_ABORTED的NET_BUFFER_LIST结构。 NDIS 又调用Filter驱动程序的 FilterSendNetBufferListsComplete 函数。

在 FilterSendNetBufferListsComplete 中,Filter驱动程序可以在 CancelId 设置为 NULL 的情况下调用NDIS_SET_NET_BUFFER_LIST_CANCEL_ID。 这可以防止NET_BUFFER_LIST意外地再次使用过时的取消 ID。

取消发送由过度覆盖驱动程序发出的请求 

 下图说明了如何取消由过度分配的驱动程序发起的发送请求:

过度调用驱动程序 ( NdisFCancelSendNetBufferLists 或 NdisCancelSendNetBufferLists) 取消未完成的发送请求。 在发出发送请求之前,这些过度的驱动程序必须使用取消 ID 标记发送数据。

NDIS 调用Filter驱动程序的 FilterCancelSendNetBufferLists 函数来取消所有标有指定取消标识符的 NET_BUFFER_LIST 结构的传输。

FilterCancelSendNetBufferLists 执行以下操作:

  • 遍历指定Filter模块的已排队NET_BUFFER_LIST结构的Filter驱动程序列表,并调用 NDIS_GET_NET_BUFFER_LIST_CANCEL_ID 宏以获取每个结构的取消标识符。 Filter驱动程序将NDIS_GET_NET_BUFFER_LIST_CANCEL_ID返回的取消 ID 与 NDIS 传递给 FilterCancelSendNetBufferLists 的取消 ID 进行比较;
  • 从发送队列中删除 (取消链接) 其取消标识符与指定取消标识符匹配的所有NET_BUFFER_LIST结构;
  • 为所有未链接的NET_BUFFER_LIST结构调用 NdisFSendNetBufferListsComplete 函数以返回结构。 Filter驱动程序将NET_BUFFER_LIST结构的状态字段设置为NDIS_STATUS_SEND_ABORTED;
  • 调用 NdisFCancelSendNetBufferLists 函数,将取消发送请求传递给基础驱动程序。 Filter驱动程序传递它从过度的驱动程序收到的取消标识符。 取消操作与Filter驱动程序发起的取消发送操作一样继续;
在Filter驱动程序中接收数据

Filter驱动程序可以启动接收指示,也可以从基础驱动程序启动Filter接收指示。 当微型端口驱动程序调用 NdisMIndicateReceiveNetBufferLists 函数时,NDIS 会将指定的 NET_BUFFER_LIST 结构提交到驱动程序堆栈中最低的过度筛选模块。

接收Filter驱动程序启动的指示

下图演示了Filter驱动程序启动的接收指示。

Filter驱动程序调用 NdisFIndicateReceiveNetBufferLists 函数来指示收到的数据。 NdisFIndicateReceiveNetBufferLists 函数将堆栈上NET_BUFFER_LIST结构的指示列表传递给超载驱动程序。 Filter驱动程序从它在初始化期间创建的池中分配结构。

如果Filter驱动程序在 NdisFIndicateReceiveNetBufferLists 的 ReceiveFlags 参数中设置NDIS_RECEIVE_FLAGS_RESOURCES标志,则表示Filter驱动程序必须立即重新获得NET_BUFFER_LIST结构的所有权。 在这种情况下,NDIS 不会调用Filter驱动程序的 FilterReturnNetBufferLists 函数来返回 NET_BUFFER_LIST 结构。 Filter驱动程序在 NdisFIndicateReceiveNetBufferLists 返回后立即重新获得所有权。

如果Filter驱动程序未在 NdisFIndicateReceiveNetBufferLists 的 ReceiveFlags 参数中设置NDIS_RECEIVE_FLAGS_RESOURCES标志,则 NDIS 会将指示的NET_BUFFER_LIST结构返回到Filter驱动程序的 FilterReturnNetBufferLists 函数。 在这种情况下,Filter驱动程序将放弃所指示结构的所有权,直到 NDIS 将它们返回到 FilterReturnNetBufferLists。

注意 Filter驱动程序应跟踪它启动的接收指示,并确保它在接收操作完成时不调用 NdisFReturnNetBufferLists 函数。

过滤接收指示

下图演示了基础驱动程序启动的过滤接收指示:

NDIS 调用Filter驱动程序的 FilterReceiveNetBufferLists 函数来处理来自基础驱动程序的接收指示。 NDIS 在基础驱动程序调用接收指示函数后调用 FilterReceiveNetBufferLists , (例如 ,NdisMIndicateReceiveNetBufferLists) 来指示接收的网络数据或环回数据。

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

如果设置了 ReceiveFlags 参数中的NDIS_RECEIVE_FLAGS_RESOURCES标志,则Filter驱动程序无法保留NET_BUFFER_LIST结构和关联的基础驱动程序分配的资源。 此标志可以指示基础驱动程序的接收资源不足。 FilterReceiveNetBufferLists 函数应尽快返回。

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

Filter驱动程序可以先对收到的数据执行筛选操作,然后再将数据指示给过度覆盖的驱动程序。 对于提交到 FilterReceiveNetBufferLists 函数的每个缓冲区,Filter驱动程序可以执行以下操作:

  • 通过调用 NdisFIndicateReceiveNetBufferLists,将其传递给下一个过度覆盖的驱动程序。 驱动程序可以修改缓冲区的内容。 NDIS 保证上下文空间的可用性, 通过查看 NET_BUFFER_LIST_CONTEXT结构;Filter驱动程序可以更改 NDIS 传递到 FilterReceiveNetBufferLists 的状态,也可以直接将其传递给 NdisFIndicateReceiveNetBufferLists。注意即使 NDIS 在 FilterReceiveNetBufferLists 的ReceiveFlags 参数中设置了 NDIS_RECEIVE_FLAGS_RESOURCES 标志,Filter驱动程序也可以使用 NdisFIndicateReceiveNetBufferLists 传递缓冲区。 在这种情况下,Filter驱动程序不得从 FilterReceiveNetBufferLists 返回,直到它重新获得缓冲区的所有权;
  • 放弃缓冲区。 如果 NDIS 清除 FilterReceiveNetBufferLists 的 ReceiveFlags 参数中的NDIS_RECEIVE_FLAGS_RESOURCES标志,请调用 NdisFReturnNetBufferLists 函数以放弃缓冲区。 如果 NDIS 在 FilterReceiveNetBufferLists 的 ReceiveFlags 参数中设置NDIS_RECEIVE_FLAGS_RESOURCES标志,则不执行任何操作,并从 FilterReceiveNetBufferLists 返回以放弃缓冲区;
  • 在本地数据结构中将缓冲区排队,供以后处理。 如果 NDIS 在 FilterReceiveNetBufferLists 的 ReceiveFlags 参数中设置NDIS_RECEIVE_FLAGS_RESOURCES标志,则Filter驱动程序必须在从 FilterReceiveNetBufferLists 返回之前创建副本;
  • 复制缓冲区,并使用副本生成接收指示。 接收指示类似于Filter驱动程序启动的接收指示。 在这种情况下,驱动程序必须将原始缓冲区返回到基础驱动程序;

NdisFIndicateReceiveNetBufferLists 函数将指示的NET_BUFFER_LIST结构列表传递到驱动程序堆栈上到过度覆盖的驱动程序。 接收操作的继续方式类似于Filter驱动程序发起的接收操作。

如果过分驱动程序保留了缓冲区的所有权,NDIS 会为Filter模块调用 FilterReturnNetBufferLists 函数。 在其 FilterReturnNetBufferLists 函数中,Filter驱动程序将撤消它在接收指示路径上的缓冲区上执行的操作。

当最低层Filter模块指示它已使用缓冲区完成时,NDIS 会将缓冲区返回到微型端口驱动程序。 如果 NDIS 清除 FilterReceiveNetBufferLists 的 ReceiveFlags 参数中的 NDIS_RECEIVE_FLAGS_RESOURCES 标志,则Filter驱动程序会调用 NdisFReturnNetBufferLists 以返回缓冲区。 如果 NDIS 在 FilterReceiveNetBufferLists 的 ReceiveFlags 参数中设置NDIS_RECEIVE_FLAGS_RESOURCES标志,则从 FilterReceiveNetBufferLists 返回将返回缓冲区。

  • 13
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Filter Drivers主要包括以下特性:   1) 一个Filter Drivers实例叫Filter Module。Filter Module附加在一个适配器的微端口驱动上, 来自相同或不同Filter Drivers的多个Filter Module都可以被堆叠在一个网络适配器上   2) 在Filter Module被安装到驱动栈时,之上的协议驱动和之下的微端口驱动都不需要提供额外的支持功能   3) 因为Filter Module不像中间层驱动(intermediate driver)那样提供一个虚拟的微口,也不与某个设备对象联结,所以在微端口适配器(miniport adapter)之上的Filter Module 功能相当于一个修过过版本的微端口适配器(miniport adapter)。(原文:Because filter drivers do not implement virtual miniports like an intermediate driver, filter drivers are not associated with a device object. A miniport adapter with overlying filter modules functions as a modified version of the miniport adapter.)   4) NDIS使用配置信息来到决定一个Filter Module附加到一个网络适配器栈上的顺序   5) 在不用拆除整驱动栈的情况下,NDIS可以动态的插入、删除Filter Module或进行重新配置   6) 当NDIS重起驱动栈的时候协议驱动可以获得在栈上的Filter Module列表   7) Filter Drivers可以过滤下层网络适配器上绝大部分的通信。Filter Module不联结某特定的绑定(Filter modules are not associated with any particular binding between overlying protocol drivers and the miniport adapter.)   8) Filter Drivers 可以选择为过滤服务也可以选择为分流的不过滤服务,选择为哪一种是可以动态配置的(Filter drivers can select the services that are filtered and can be bypassed for the services that are not filtered. The selection of the services that are bypassed and the services that are filtered can be reconfigured dynamically.)   9) NDIS 保证有效的上下文空间,也不就是说Filter Drivers不要需要通代码COPY缓冲区来获得上下文空间  
USB虚拟NDIS网络适配器是一种用于USB设备的网络适配器。它可以将USB设备(如手机、无线网卡等)转换为虚拟的网络设备,在计算机上创建一个虚拟的网络连接端口。 USB虚拟NDIS网络适配器的主要作用是为USB设备提供网络连接功能,使得这些设备可以通过USB接口连接到计算机,并通过计算机的网络连接功能来进行网络通信。 使用USB虚拟NDIS网络适配器,用户可以通过将USB设备连接到计算机上,实现与其他计算机或网络的通信。这种适配器在无线网络通信方面尤为重要,因为它可以将无线网卡或手机等设备转换为可用于无线网络连接的网络设备。 使用USB虚拟NDIS网络适配器时,用户必须先安装适配器的驱动程序,以确保计算机可以正确地识别和使用适配器。安装驱动程序后,用户可以通过计算机的网络设置界面,设置和配置网络连接,实现与其他设备或网络的通信。 USB虚拟NDIS网络适配器的好处是它的便携性和灵活性。用户可以随时随地将USB设备插入计算机,无需使用额外的网络线缆或设备,即可实现网络连接。这对于需要经常移动或需要应急联网的用户来说非常方便。 总的来说,USB虚拟NDIS网络适配器是一种通过USB接口为设备提供网络连接功能的适配器。它的使用简便、灵活便携,使用户能够随时随地实现网络通信,特别适用于无线网络通信。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值