Обработка уведомлений вызовов

Модуль фильтрации вызывает функцию вызова notifyFn, чтобы уведомить драйвер вызова о событиях, связанных с вызовом.

Добавление фильтра

Если фильтр, указывающий выноску для действия фильтра, добавляется в подсистему фильтрации, подсистема фильтрации вызывает функцию notifyFn, передав FWPS_CALLOUT_NOTIFY_ADD_FILTER в параметре notifyType.

Драйвер обработчика может зарегистрировать выноску в обработчике фильтров после того, как фильтры, которые указывают выноску для действия фильтра, были уже добавлены в обработчик фильтров. В этой ситуации обработчик фильтров не вызывает функцию вызывать notifyFn, чтобы уведомить вынесение о любом из существующих фильтров.

Подсистема фильтров вызывает только функцию выноски уведомлятьFn, чтобы уведомить выноску, когда новые фильтры, указывающие выноску для действия фильтра, добавляются в обработчик фильтров. В этой ситуации функция выноски 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;
}