Обработка выносок уведомления
Подсистема фильтрации вызывает функцию выноски notifyFn , чтобы уведомить драйвер выноски о событиях, связанных с выноской.
Добавление фильтра
Когда фильтр, указывающий выноску для действия фильтра, добавляется в подсистему фильтров, модуль фильтрации вызывает функцию выноски notifyFn выноски выноски, передавая FWPS_CALLOUT_NOTIFY_ADD_FILTER в параметре notifyType .
Драйвер выноски может зарегистрировать выноску в подсистеме фильтров после того, как фильтры, указывающие выноску для действия фильтра, уже были добавлены в подсистему фильтров. В этом случае подсистема фильтров не вызывает функцию выноски notifyFn для уведомления выноски о существующих фильтрах.
Подсистема фильтров вызывает функцию выноски notifyFn только для уведомления выноски, когда новые фильтры, указывающие выноску для действия фильтра, добавляются в подсистему фильтров. В этом случае функция выноски notifyFn может не вызываться для каждого фильтра в подсистеме фильтров, который задает выноску для действия фильтра.
Если драйвер выноски регистрирует выноску после запуска подсистемы фильтров и выноска должна получать сведения о каждом фильтре в подсистеме фильтрации, указывающей выноску для действия фильтра, драйвер выноски должен вызвать соответствующие функции управления для перечисления всех фильтров в подсистеме фильтрации. Драйвер выноски должен отсортировать результирующий список всех фильтров, чтобы найти те фильтры, которые указывают выноску для действия фильтра. Дополнительные сведения о вызове этих функций см. в статье Вызов других функций платформы фильтрации Windows .
Удаление фильтра
Когда фильтр, указывающий выноску для действия фильтра, удаляется из подсистемы фильтров, модуль фильтрации вызывает функцию выноски notifyFn выноски и передает FWPS_CALLOUT_NOTIFY_DELETE_FILTER в параметре notifyType и NULL в параметре filterKey . Модуль фильтрации вызывает функцию выноски 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;
}