处理通知标注

筛选器引擎调用标注的 notifyFn 标注函数,以通知标注驱动程序与标注关联的事件。

筛选器添加

将指定筛选器操作标注的筛选器添加到筛选器引擎时,筛选器引擎将调用标注的 notifyFn 标注函数,并在 notifyType 参数中传递FWPS_CALLOUT_NOTIFY_ADD_FILTER。

在为筛选器操作指定标注的筛选器已添加到筛选器引擎后,标注驱动程序可以使用筛选器引擎注册标注。 在这种情况下,筛选器引擎不会调用标注的 notifyFn 标注函数来通知标注任何现有筛选器。

当为筛选器操作指定标注的新筛选器添加到筛选器引擎时,筛选器引擎仅调用标注的 notifyFn 标注函数来通知标注。 在这种情况下,对于筛选器引擎中指定筛选器操作的标注的每个筛选器,标注的 notifyFn 标注函数可能不会被调用。

如果标注驱动程序在启动筛选器引擎后注册标注,并且标注必须接收筛选器引擎中指定筛选器操作标注的每个筛选器的相关信息,则标注驱动程序必须调用相应的管理功能来枚举筛选器引擎中的所有筛选器。 标注驱动程序必须对所有筛选器的结果列表进行排序,以查找指定筛选器操作标注的筛选器。 有关 调用这些函数的详细信息,请参阅调用其他 Windows 筛选平台 函数。

筛选器删除

从筛选器引擎中删除指定筛选器操作标注的筛选器时,筛选器引擎将调用标注的 notifyFn 标注函数,并在 notifyType 参数中传递FWPS_CALLOUT_NOTIFY_DELETE_FILTER,在 filterKey 参数中传递 NULL。 筛选器引擎为筛选器引擎中的每个已删除筛选器调用标注的 notifyFn 标注函数,该筛选器引擎指定筛选器操作的标注。 这包括在标注驱动程序向筛选器引擎注册标注之前添加到筛选器引擎的任何筛选器。 因此,对于未接收筛选器添加通知的筛选器,标注可能会收到筛选器删除通知。

如果标注的 notifyFn 标注函数无法识别 notifyType 参数中传递的通知类型,则应忽略通知并返回STATUS_SUCCESS。

将筛选器添加到筛选器引擎时,标注驱动程序可以指定要与筛选器关联的上下文。 此类上下文对筛选器引擎是不透明的。 标注的 classifyFn 标注函数可以使用此上下文保存状态信息,以便下次由筛选器引擎调用它。 从筛选器引擎中删除筛选器时,标注驱动程序将执行上下文的任何必要清理。

例如:

// Context structure to be associated with the filters
typedef struct FILTER_CONTEXT_ {
  .
  .  // Driver-specific content
  .
} FILTER_CONTEXT, *PFILTER_CONTEXT;

// Memory pool tag for filter context structures
#define FILTER_CONTEXT_POOL_TAG 'fcpt'

// notifyFn callout function
NTSTATUS NTAPI
 NotifyFn(
    IN FWPS_CALLOUT_NOTIFY_TYPE  notifyType,
    IN const GUID  *filterKey,
    IN const FWPS_FILTER0  *filter
    )
{
  PFILTER_CONTEXT context;

 ASSERT(filter != NULL);

  // Switch on the type of notification
 switch(notifyType) {

    // A filter is being added to the filter engine
 case FWPS_CALLOUT_NOTIFY_ADD_FILTER:

      // Allocate the filter context structure
 context =
        (PFILTER_CONTEXT)ExAllocatePoolWithTag(
 NonPagedPool,
 sizeof(FILTER_CONTEXT),
          FILTER_CONTEXT_POOL_TAG
          );

      // Check the result of the memory allocation
 if (context == NULL) {

        // Return error
 return STATUS_INSUFFICIENT_RESOURCES;
      }

      // Initialize the filter context structure
      ...

      // Associate the filter context structure with the filter
 filter->context = (UINT64)context;

 break;

    // A filter is being removed from the filter engine
 case FWPS_CALLOUT_NOTIFY_DELETE_FILTER:

      // Get the filter context structure from the filter
 context = (PFILTER_CONTEXT)filter->context;

 // Check whether the filter has a context
 if (context) {

        // Cleanup the filter context structure
        ...

        // Free the memory for the filter context structure
 ExFreePoolWithTag(
 context,
          FILTER_CONTEXT_POOL_TAG
          );

      }
 break;

    // Unknown notification
 default:

      // Do nothing
 break;
  }

 return STATUS_SUCCESS;
}