オブジェクト管理
このセクションでは、Windows フィルタリング プラットフォーム (WFP) API オブジェクトの種類の正しい使用方法について説明します。
セッション
WFP API はセッション指向であり、ほとんどの関数呼び出しはセッションのコンテキスト内で行われます。 FwpmEngineOpen0 を呼び出すことによって、新しいクライアント セッションが作成されます。 セッションは、クライアントが FwpmEngineClose0 を 呼び出すか、クライアント プロセスが終了したときに終了します。 セッションが意図的または RPC ランダウンによって破棄されると、基本フィルター エンジン (BFE) は最初に既存のトランザクションを中止します。
新しいセッションを作成するときに、呼び出し元は FWPM_SESSION_FLAG_DYNAMIC フラグを FwpmEngineOpen0 に渡すことで動的セッションを作成できます。 動的セッション中に追加されたオブジェクトは、セッションの終了時に自動的に削除されます。
トランザクション
WFP API はトランザクションであり、ほとんどの関数呼び出しはトランザクションのコンテキスト内で行われます。 呼び出し元は 、FwpmTransactionBegin0、 FwpmTransactionCommit0、 および FwpmTransactionAbort0 を 使用して、トランザクションを明示的に制御できます。 ただし、関数呼び出しが明示的なトランザクションの外部で行われた場合は、暗黙的なトランザクション内で実行されます。 トランザクションが進行中の場合、セッションが終了すると、トランザクションは自動的に中止されます。 暗黙的なトランザクションは強制的に中止されることはありません。
トランザクションは、読み取り専用または読み取り/書き込みのいずれかであり、厳密なアトミック整合性分離持続性 (ACID) セマンティクスを適用します。
各クライアント セッションで進行中のトランザクションは一度に 1 つだけです。 呼び出し元が最初のトランザクションをコミットまたは中止する前に 2 つ目のトランザクションを開始しようとすると、BFE はエラーを返します。
トランザクションの実行中に操作が失敗した場合、トランザクションの全体的な状態には影響しません。 たとえば、クライアントがトランザクションを開始し、 FwpmFilterAdd0 を 3 回正常に呼び出してから 4 回目の呼び出しが失敗したとします。 クライアントには、次のオプションが用意されました。
- トランザクションを中止します。その場合、フィルターは追加されません。
- トランザクションをコミットすると、最初の 3 つのフィルターが追加されます。
- 失敗した FwpmFilterAdd0 の再試行など、その他の操作を続行します。
トランザクションを開始すると、BFE はセッションの txnWaitTimeoutInMSec の有効期限が切れるまで待機してロックを取得します。 この時間内にロックが取得されない場合、ロックの取得 (および FwpmTransactionBegin0 呼び出し) は失敗します。 これにより、クライアントが無期限に応答できないのを防ぐことができます。 クライアントがロック タイムアウトを指定しなかった場合、既定値は 15 秒です。
各トランザクションには、ロック タイムアウトもあります。 これは、ロックを所有できる最大時間です。 所有者がこの時間内にロックを解放しない場合、トランザクションは強制的に中止され、ロックが解放されます。 ロック タイムアウトは構成できません。 カーネル モードの呼び出し元では無限であり、ユーザー モードの呼び出し元の場合は 1 時間です。 トランザクションが強制的に中止された場合、そのトランザクション内で行われた次の呼び出しは 、FWP_E_TXN_ABORTEDで失敗します。
オブジェクトの有効期間
オブジェクトには、次の 4 つの有効期間のいずれかを指定できます。
- Dynamic — 動的セッション ハンドルを使用して追加された場合にのみ、オブジェクトは動的です。 動的オブジェクトは、削除されるか、所有セッションが終了するまで存続します。
- Static — オブジェクトは既定で静的です。 静的オブジェクトは、削除されるか、BFE が停止するか、システムがシャットダウンされるまで存続します。
- 永続的 — 永続的なオブジェクトは、Fwpm*Add0 関数に適切なFWPM_*_FLAG_PERSISTENT フラグを渡すことによって作成されます。 永続オブジェクトは、削除されるまで存続します。
- 組み込み — 組み込みオブジェクトは BFE によって定義済みであり、追加または削除することはできません。 彼らは永遠に生きています。
カーネル モード レイヤーのフィルターは、 FwpmFilterAdd0 に適切なフラグを渡すことによって、ブート時フィルターとしてマークできます。 ブート時フィルターは、TCP/IP ドライバーの起動時にシステムに追加され、BFE の初期化が完了すると削除されます。 永続オブジェクトは、BFE の開始時に追加されます。
多くの場合、ポリシー プロバイダーは、プロバイダーが無効になっている場合に永続的なポリシーを適用したくない場合があります。 プロバイダーを追加するときに、呼び出し元はオプションの Windows サービス名を指定できます。 永続オブジェクトを追加する場合、呼び出し元は必要に応じて、そのオブジェクトを "所有" するプロバイダーを指定できます。 サービスの開始時に、BFE は、プロバイダーに関連付けられていないか、関連付けられているプロバイダーに Windows サービス名がない場合、または関連付けられた Windows サービスが自動開始に設定されている場合にのみ、システムに永続オブジェクトを追加します。
オブジェクトの関連付け
一部のオブジェクトには、他のオブジェクトへの参照があります。 たとえば、フィルターは常にレイヤーを参照し、吹き出しとプロバイダー コンテキストを参照できます。 オブジェクトは、有効期間が短い可能性があるオブジェクトを参照できません。 したがって、動的オブジェクトは、別のセッションから動的オブジェクトを参照することはできません。 静的オブジェクトは動的オブジェクトを参照できません。 永続オブジェクトは、動的オブジェクト、静的オブジェクト、または別のプロバイダーが所有する永続オブジェクトを参照できません。
オブジェクトを参照するすべてのオブジェクトが最初に削除されるまで、オブジェクトを削除することはできません。
LUID と GUID
すべてのユーザー モード WFP API オブジェクト (FWPM) はグローバル一意識別子 (GUID) で識別され、その GUIDで他のオブジェクトを参照します。 GUID は、オブジェクト型内でのみ一意である必要があります。 たとえば、フィルターとプロバイダー コンテキストは同じ GUID を持つことができますが、2 つのフィルターでは使用できません。 新しいオブジェクトを追加するときに、呼び出し元はオブジェクトの GUID を 割り当てるか、ゼロ初期化のままにして、BFE に GUID を割り当てることができます。
すべてのカーネル モード WFP API オブジェクト (FWPS) は、ローカル一意識別子 (LUID) によって識別され、その LUID によって他のオブジェクトを参照します。 GUID から LUID への切り替えにより、WFP は非ページ プールを節約し、実行時処理を最適化できます。 LUID の幅は、オブジェクトの種類と UINT16 から UINT64 までの範囲によって異なります。 LUIDは常に BFE によって割り当てられます。