The filter engine calls a callout's notifyFn callout function to notify the callout driver about events that are associated with the callout.
当发生与某个callout关联的事件时,过滤引擎调用这个callout的notifyFn函数通知callout driver。
Filter Addition
When a filter that specifies a callout for the filter's action is added to the filter engine, the filter engine calls the callout's notifyFn callout function, passing FWP_CALLOUT_NOTIFY_ADD_FILTER in the notifyType parameter.
当一个过滤器为其动作指定了一个callout时,并被添加进过滤引擎时,过滤引擎调用callout的notifyFn函数,参数noitifyType为FWP_CALLOUT_NOTIFY_ADD_FILTER。
A callout driver can register a callout with the filter engine after filters that specify the callout for the filter's action have already been added to the filter engine. In this situation, the filter engine does not call the callout's notifyFn callout function to notify the callout about any of the existing filters.
过滤器被加入过滤引擎后,callout driver依然可以为这个过滤器注册callout。这种情况下,过滤引擎不再调用callout的notifyFn函数。
The filter engine only calls the callout's notifyFn callout function to notify the callout when new filters that specify the callout for the filter's action are added to the filter engine. In this situation, a callout's notifyFn callout function might not get called for every filter in the filter engine that specifies the callout for the filter's action.
只有当新的过滤器指定了callout时,这个callout的notifyFn函数才会被调用。
If a callout driver registers a callout after the filter engine is started and the callout must receive information about every filter in the filter engine that specifies the callout for the filter's action, the callout driver must call the appropriate management functions to enumerate all the filters in the filter engine. The callout driver must sort through the resulting list of all the filters to find those filters that specify the callout for the filter's action. See Calling Other Windows Filtering Platform Functions for more information about calling these functions.
如果callout driver在过滤引擎启动后注册了一个callout,并且需要获取每一个为其action指定为这个callout的的每一个filter时,callout driver需要调用合理的管理函数枚举所有的过滤器并排序筛选。
Filter Deletion
When a filter that specifies a callout for the filter's action is deleted from the filter engine, the filter engine calls the callout's notifyFn callout function and passes FWP_CALLOUT_NOTIFY_DELETE_FILTER in the notifyType parameter and NULL in the filterKey parameter. The filter engine calls the callout's notifyFn callout function for every deleted filter in the filter engine that specifies the callout for the filter's action. This includes any filters that were added to the filter engine before the callout driver registered the callout with the filter engine. Therefore, a callout might receive filter delete notifications for filters for which it did not receive filter add notifications.
如果一个过滤器为其action指定了callout,则在这个过滤器删除时,过滤引擎调用notifyFn函数,并且notifyType参数值为FWP_CALLOUT_NOTIFY_DELETE_FILTER。过滤引擎在过滤器删除时会调用notifyFn函数,只要过滤器指定了这个callout,这包括在注册callout前就也添加到过滤引擎的过滤器,所以一个callout可能收到那些未收到添加通知的过滤器的删除通知。
If the callout's notifyFn callout function does not recognize the kind of notification that is passed in the notifyType parameter, it should ignore the notification and return STATUS_SUCCESS.
如果notifyFn函数不能识别notifyType函数,忽略通知并返回status_success。
A callout driver can specify a context to be associated with a filter when the filter is added to the filter engine. Such a context is opaque to the filter engine. The callout's classifyFn callout function can use this context to save state information for the next time that it is called by the filter engine. When the filter is deleted from the filter engine, the callout driver performs any necessary cleanup of the context.
当过滤器添加进过滤引擎时,callout driver可以指定上下文信息。classifyFn函数可以使用这些信息保存状态信息。
For example:
// 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 FWP_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 FWP_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 FWP_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;
}