Objektverwaltung

In diesem Abschnitt wird die richtige Verwendung von WFP-API-Objekttypen (Windows Filtering Platform) behandelt.

Sitzungen

Die WFP-API ist sitzungsorientiert, und die meisten Funktionsaufrufe werden im Kontext einer Sitzung ausgeführt. Durch Aufrufen von FwpmEngineOpen0 wird eine neue Clientsitzung erstellt. Die Sitzung endet entweder, wenn der Client FwpmEngineClose0 aufruft oder der Clientprozess beendet wird. Wenn eine Sitzung entweder absichtlich oder durch den RPC-Rundown zerstört wird, bricht die Basisfilterungs-Engine (BFE) zunächst jede vorhandene Transaktion ab.

Beim Erstellen einer neuen Sitzung kann der Aufrufer eine dynamische Sitzung erstellen, indem er das FWPM_SESSION_FLAG_DYNAMIC-Flag an FwpmEngineOpen0 übergibt. Alle Objekte, die während einer dynamischen Sitzung hinzugefügt werden, werden automatisch gelöscht, wenn die Sitzung endet.

Transaktionen

Die WFP-API ist transaktional, und die meisten Funktionsaufrufe werden im Kontext einer Transaktion ausgeführt. Aufrufer können FwpmTransactionBegin0, FwpmTransactionCommit0 und FwpmTransactionAbort0 verwenden, um Transaktionen explizit zu steuern. Wenn ein Funktionsaufruf jedoch außerhalb einer expliziten Transaktion erfolgt, wird er innerhalb einer impliziten Transaktion ausgeführt. Wenn eine Transaktion ausgeführt wird und eine Sitzung beendet wird, wird sie automatisch abgebrochen. Implizite Transaktionen werden nie gewaltsam abgebrochen.

Transaktionen sind entweder schreibgeschützt oder lese-/schreibgeschützt und erzwingen strenge Atomic Consistent Isolated Durable (ACID)-Semantik.

Für jede Clientsitzung kann jeweils nur eine Transaktion ausgeführt werden. Wenn der Aufrufer versucht, eine zweite Transaktion zu starten, bevor der committ oder die erste abbricht, gibt BFE einen Fehler zurück.

Wenn ein Vorgang im Verlauf einer Transaktion fehlschlägt, wirkt sich dies nicht auf den Gesamtzustand der Transaktion aus. Angenommen, der Client beginnt eine Transaktion und ruft fwpmFilterAdd0 dreimal erfolgreich auf, bevor ein vierter Aufruf fehlschlägt. Der Client hat jetzt folgende Optionen:

  • Die Transaktion wird abgebrochen. In diesem Fall wird keiner der Filter hinzugefügt.
  • Commit für die Transaktion, in diesem Fall werden die ersten drei Filter hinzugefügt.
  • Fahren Sie mit weiteren Vorgängen fort, einschließlich möglicherweise erneuter Wiederholung des fehlgeschlagenen FwpmFilterAdd0.

Beim Starten einer Transaktion wartet BFE, bis der txnWaitTimeoutInMSec der Sitzung abläuft, um die Sperre zu erhalten. Wenn die Sperre innerhalb dieses Zeitraums nicht abgerufen wird, schlagen die Sperre (und der FwpmTransactionBegin0-Aufruf ) fehl. Dadurch wird verhindert, dass Clients auf unbestimmte Zeit nicht reagieren. Wenn der Client kein Sperrtimeout angegeben hat, beträgt er standardmäßig 15 Sekunden.

Jede Transaktion verfügt außerdem über ein Sperrtimeout. Dies ist die maximale Zeit, für die sie die Sperre besitzen kann. Wenn der Besitzer die Sperre innerhalb dieser Zeit nicht losgibt, wird die Transaktion gewaltsam abgebrochen, sodass die Sperre aufgehoben wird. Das Sperrtimeout ist nicht konfigurierbar. Es ist unendlich für Aufrufer im Kernelmodus und eine Stunde für Aufrufer im Benutzermodus. Wenn eine Transaktion gewaltsam abgebrochen wird, schlägt der nächste Aufruf innerhalb dieser Transaktion mit FWP_E_TXN_ABORTED fehl.

Objektlebensdauer

Objekte können eine von vier möglichen Lebensdauern haben:

  • Dynamisch: Ein Objekt ist nur dynamisch, wenn es mithilfe eines dynamischen Sitzungshandles hinzugefügt wird. Dynamische Objekte werden live ausgeführt, bis sie gelöscht oder die besitzende Sitzung beendet wird.
  • Statisch: Objekte sind standardmäßig statisch. Statische Objekte werden aktiv, bis sie gelöscht, BFE beendet oder das System heruntergefahren wird.
  • Persistent: Persistente Objekte werden erstellt, indem das entsprechende FWPM_*_FLAG_PERSISTENT-Flag an eine Fwpm*Add0-Funktion übergeben wird. Persistente Objekte werden solange gespeichert, bis sie gelöscht werden.
  • Integriert: Integrierte Objekte werden von BFE vordefiniert und können nicht hinzugefügt oder gelöscht werden. Sie leben für immer.

Filter in Kernelmodusebenen können als Startzeitfilter gekennzeichnet werden, indem das entsprechende Flag an FwpmFilterAdd0 übergeben wird. Startzeitfilter werden dem System hinzugefügt, wenn der TCP/IP-Treiber gestartet wird, und werden entfernt, wenn BFE die Initialisierung abgeschlossen hat. Persistente Objekte werden hinzugefügt, wenn BFE gestartet wird.

In vielen Fällen möchte ein Richtlinienanbieter möglicherweise nicht, dass seine persistente Richtlinie erzwungen wird, wenn der Anbieter deaktiviert wurde. Beim Hinzufügen eines Anbieters kann der Aufrufer einen optionalen Windows-Dienstnamen angeben. Beim Hinzufügen persistenter Objekte kann der Aufrufer optional den Anbieter angeben, der dieses Objekt "besitzt". Beim Dienststart fügt BFE dem System nur persistente Objekte hinzu, wenn sie keinem Anbieter zugeordnet sind oder der zugehörige Anbieter keinen Windows-Dienstnamen hat oder der zugehörige Windows-Dienst auf automatischen Start festgelegt ist.

Objektzuordnungen

Einige Objekte weisen Verweise auf andere Objekte auf. Beispielsweise verweist ein Filter immer auf eine Ebene und kann auf eine Legende und einen Anbieterkontext verweisen. Objekte können nicht auf Objekte verweisen, die möglicherweise eine kürzere Lebensdauer haben. Daher kann ein dynamisches Objekt nicht auf ein dynamisches Objekt aus einer anderen Sitzung verweisen. Ein statisches Objekt kann nicht auf ein dynamisches Objekt verweisen. Ein persistentes Objekt kann nicht auf ein dynamisches Objekt, ein statisches Objekt oder ein persistentes Objekt verweisen, das einem anderen Anbieter gehört.

Ein Objekt kann erst gelöscht werden, wenn alle Objekte, die darauf verweisen, zuerst gelöscht wurden.

LUIDs und GUIDs

Alle WFP-API-Objekte (User Mode WFP API Objects, FWPM) werden durch einen globalen eindeutigen Bezeichner (GUID) identifiziert und verweisen mit ihren GUIDsauf andere Objekte. Die GUID muss nur innerhalb des Objekttyps eindeutig sein. Beispielsweise können ein Filter und ein Anbieterkontext dieselbe GUID aufweisen, aber zwei Filter nicht. Beim Hinzufügen eines neuen Objekts können Aufrufer die GUID des Objekts zuweisen oder null initialisiert lassen und BFE die GUID zuweisen lassen.

Alle Kernelmodus-WFP-API-Objekte (FWPS) werden durch einen lokal eindeutigen Bezeichner (LUID) identifiziert und verweisen mit ihrer LUID auf andere Objekte. Der Wechsel von GUID zu LUID ermöglicht es WFP, den nicht ausgelagerten Pool zu sparen und die Laufzeitverarbeitung zu optimieren. Die Breite der LUID hängt vom Objekttyp ab und reicht von UINT16 bis UINT64. LUIDs werden immer von BFE zugewiesen.