Поделиться через


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

Подсистема фильтрации вызывает функцию выноски 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;
}