Registrieren von Kontexttypen

Ein Minifiltertreiber muss zuerst jeden Typ von Kontext registrieren, den er verwendet. Sobald ein Minifilter die von ihr verwendeten Kontexttypen registriert hat, kann er einen Kontext erstellen.

Schritte zum Registrieren eines Kontexttyps

Ein Minifilter ruft FltRegisterFilter aus seiner DriverEntry-Routine auf, um jeden typ von Kontext zu registrieren, den er verwendet. Vor dem Aufrufen von FltRegisterFilter führt der Minifilter-Treiber folgendes aus:

  • Erstellt ein Array mit FLT_CONTEXT_REGISTRATION Strukturen mit variabler Länge. Die Reihenfolge der Elemente in diesem Array spielt keine Rolle. Das letzte Element im Array muss jedoch {FLT_CONTEXT_END} sein.
  • Speichert einen Zeiger auf das erstellte Array im ContextRegistration-Member der FLT_REGISTRATION-Struktur . Der Minifilter übergibt diese Struktur im Registrierungsparameter von FltRegisterFilter.

Für jeden Kontexttyp, den der Minifiltertreiber verwendet, muss er mindestens eine Kontextdefinition bereitstellen. Die Definition erfolgt in Form einer FLT_CONTEXT_REGISTRATION-Struktur , in der jede Struktur den Typ, die Größe und andere Informationen für den Kontext definiert.

Wenn der Minifiltertreiber FltAllocateContext aufruft , um einen neuen Kontext zu erstellen, verwendet der Filter-Manager den Parameter Size sowie die Member Size und Flags der FLT_CONTEXT_REGISTRATION-Struktur, um die zu verwendende Kontextdefinition auszuwählen:

  • Für Kontexte mit fester Größe gibt das Size-Element der FLT_CONTEXT_REGISTRATION-Struktur die Größe des Teils der Kontextstruktur in Bytes an, der vom Minifiltertreiber definiert wird. Die maximale Größe für einen Kontext ist MAXUSHORT (64 KB). Null ist ein gültiger Größenwert. Der Filter-Manager implementiert Kontexte mit fester Größe mithilfe von Suchlisten. Der Filter-Manager erstellt zwei Suchlisten für jeden Größenwert: eine ausgelagerte und eine nicht ausgelagerte Liste.

  • Für Kontexte mit variabler Größe muss das Size-Element auf FLT_VARIABLE_SIZED_CONTEXTS festgelegt werden. Der Filter-Manager weist Kontexte mit variabler Größe direkt aus einem ausgelagerten oder nicht ausgelagerten Pool zu.

Im Flags-Element der FLT_CONTEXT_REGISTRATION-Struktur kann das FLTFL_CONTEXT_REGISTRATION_NO_EXACT_SIZE_MATCH-Flag angegeben werden. Wenn der Minifiltertreiber Kontexte mit fester Größe verwendet und dieses Flag angegeben wird, weist der Filter-Manager einen Kontext aus der Suchliste zu, wenn die Größe des Kontexts größer oder gleich der angeforderten Größe ist. Andernfalls muss die Größe des Kontexts der angeforderten Größe entsprechen.

Für einen bestimmten Kontexttyp kann der Minifiltertreiber bis zu drei Kontextdefinitionen mit fester Größe bereitstellen, die jeweils eine andere Größe und eine Variablengrößendefinition aufweisen. Weitere Informationen finden Sie unter FLT_CONTEXT_REGISTRATION.

Minifilter-Rückrufroutinen für die Kontextverwaltung

Der Minifiltertreiber kann optional die folgenden kontextbezogenen Rückrufroutinen bereitstellen, die in der FLT_REGISTRATION-Struktur gespeichert werden, die als Parameter an FltRegisterFilter übergeben wird:

Rückrufroutine BESCHREIBUNG
PFLT_CONTEXT_ALLOCATE_CALLBACK In sehr seltenen Fällen muss ein Minifilter möglicherweise eine eigene Rückrufroutine definieren, um Kontexte zuzuordnen, anstatt sich auf den Filter-Manager zu verlassen.
PFLT_CONTEXT_CLEANUP_CALLBACK Die Bereinigungsroutine eines Minifilters, die aufgerufen werden soll, bevor der Kontext freigegeben wird.
PFLT_CONTEXT_FREE_CALLBACK In sehr seltenen Fällen muss ein Minifilter möglicherweise eine eigene Rückrufroutine definieren, um Kontexte frei zu machen, anstatt sich auf den Filter-Manager zu verlassen.

Beispiel für den Kontextregistrierungscode

Das folgende Codebeispiel, das aus dem CTX-Beispiel-Minifiltertreiber stammt, zeigt ein Array von FLT_CONTEXT_REGISTRATION Strukturen, die zum Registrieren von instance-, Datei-, Stream- und Dateiobjektkontexten (Streamhandle) verwendet werden.

const FLT_CONTEXT_REGISTRATION contextRegistration[] =
{
    { FLT_INSTANCE_CONTEXT,              //ContextType
      0,                                 //Flags
      CtxContextCleanup,                 //ContextCleanupCallback
      CTX_INSTANCE_CONTEXT_SIZE,         //Size
      CTX_INSTANCE_CONTEXT_TAG           //PoolTag
    },
    { FLT_FILE_CONTEXT,                  //ContextType
      0,                                 //Flags
      CtxContextCleanup,                 //ContextCleanupCallback
      CTX_FILE_CONTEXT_SIZE,             //Size
      CTX_FILE_CONTEXT_TAG               //PoolTag
    },
    { FLT_STREAM_CONTEXT,                //ContextType
      0,                                 //Flags
      CtxContextCleanup,                 //ContextCleanupCallback
      CTX_STREAM_CONTEXT_SIZE,           //Size
      CTX_STREAM_CONTEXT_TAG             //PoolTag
    },
    { FLT_STREAMHANDLE_CONTEXT,          //ContextType
      0,                                 //Flags
      CtxContextCleanup,                 //ContextCleanupCallback
      CTX_STREAMHANDLE_CONTEXT_SIZE,     //Size
      CTX_STREAMHANDLE_CONTEXT_TAG       //PoolTag
    },
    { FLT_CONTEXT_END }
};