通知コールアウトの処理

フィルター エンジンは、吹き出しに関連付けられているイベントについてコールアウト ドライバーに通知する吹き出しの notifyFn 吹き出し関数を呼び出します。

フィルターの追加

フィルターのアクションの吹き出しを指定するフィルターがフィルター エンジンに追加されると、フィルター エンジンは吹き出しの notifyFn 関数を呼び出し、notifyType パラメーターに FWPS_CALLOUT_NOTIFY_ADD_FILTER を渡します。

吹き出しドライバーは、フィルターのアクションの吹き出しを指定するフィルターが既にフィルター エンジンに追加された後、フィルター エンジンに吹き出しを登録できます。 この状況では、フィルター エンジンは、既存のフィルターについて吹き出しに通知する吹き出しの notifyFn 吹き出し関数を呼び出しません。

フィルター エンジンは、吹き出しの notifyFn 吹き出し関数のみを呼び出して、フィルターのアクションの吹き出しを指定する新しいフィルターがフィルター エンジンに追加されたときに吹き出しを通知します。 このような状況では、吹き出しの notifyFn 吹き出し関数は、フィルターのアクションの吹き出しを指定するフィルター エンジン内のすべてのフィルターに対して呼び出されない場合があります。

吹き出しドライバーは、フィルター エンジンの起動後に吹き出しを登録し、吹き出しが、フィルターのアクションの吹き出しを指定するフィルター エンジン内のすべてのフィルターに関する情報を受信する必要がある場合、吹き出しドライバーは、フィルター エンジン内のすべてのフィルターを列挙する適切な管理機能を呼び出す必要があります。 吹き出しドライバーは、フィルターのアクションの吹き出しを指定するフィルターを見つけるために、すべてのフィルターの結果の一覧を並べ替える必要があります。 これらの関数の呼び出しの詳細については、「他の Windows フィルタリング プラットフォーム関数の呼び出し」を参照してください。

フィルターの削除

フィルターのアクションの吹き出しを指定するフィルターがフィルター エンジンから削除されると、フィルター エンジンは吹き出しの notifyFn 吹き出し関数を呼び出し、FWPS_CALLOUT_NOTIFY_DELETE_FILTER を notifyType パラメーターに渡し、NULLfilterKey パラメーターに渡します。 フィルター エンジンは、フィルター のアクションの吹き出しを指定するフィルター エンジン内のすべての削除されたフィルターに対して、吹き出しの 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;
}