取消筛选器驱动程序中的发送请求

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

取消筛选器驱动程序发送请求

下图说明了如何取消由筛选器驱动程序发起的发送请求。

显示取消由筛选器驱动程序发起的发送请求的过程的流程图。

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

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

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

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

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

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

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

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

显示取消由过度分配的驱动程序发起的发送请求的过程的流程图。

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

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

FilterCancelSendNetBufferLists 执行以下操作:

  1. 遍历指定筛选器模块的已排队NET_BUFFER_LIST结构的筛选器驱动程序列表,并调用 NDIS_GET_NET_BUFFER_LIST_CANCEL_ID 宏以获取每个结构的取消标识符。 筛选器驱动程序将NDIS_GET_NET_BUFFER_LIST_CANCEL_ID返回的取消 ID 与 NDIS 传递给 FilterCancelSendNetBufferLists 的取消 ID 进行比较。

  2. 从发送队列中删除 (取消链接) 其取消标识符与指定取消标识符匹配的所有NET_BUFFER_LIST结构。

  3. 为所有未链接的NET_BUFFER_LIST结构调用 NdisFSendNetBufferListsComplete 函数以返回结构。 筛选器驱动程序将NET_BUFFER_LIST结构的状态字段设置为NDIS_STATUS_SEND_ABORTED。

  4. 调用 NdisFCancelSendNetBufferLists 函数,将取消发送请求传递给基础驱动程序。 筛选器驱动程序传递它从过度的驱动程序收到的取消标识符。 取消操作与筛选器驱动程序发起的取消发送操作一样继续。