Verwenden von Speicherpuffern

Treiber verwenden in der Regel Speicherpuffer, um Daten an und aus dem Framework und andere Treiber zu übergeben oder Informationen lokal zu speichern. In diesem Thema werden Frameworkspeicherobjekte, Suchlisten, MDLs und lokale Puffer beschrieben.

Verwenden von Framework-Speicherobjekten

Das Framework verwendet Speicherobjekte , um die Speicherpuffer zu beschreiben, die ein Treiber vom Framework empfängt und an das Framework übergibt. Jedes Frameworkspeicherobjekt stellt einen Puffer dar.

Um ein Speicherobjekt zu erstellen, ruft Ihr Treiber eine der folgenden Objektmethoden auf:

Um ein Speicherobjekt abzurufen, das die Puffer einer empfangenen E/A-Anforderung darstellt, ruft Ihr Treiber WdfRequestRetrieveInputMemory und WdfRequestRetrieveOutputMemory auf. Weitere Informationen zum Abrufen der Puffer einer E/A-Anforderung finden Sie unter Zugreifen auf Datenpuffer in Framework-Based Treibern.

Um die Adresse und Größe des Puffers eines Speicherobjekts abzurufen, ruft Ihr Treiber WdfMemoryGetBuffer auf.

Um Daten in oder aus dem Puffer eines Speicherobjekts zu verschieben, ruft Ihr Treiber entweder WdfMemoryCopyFromBuffer oder WdfMemoryCopyToBuffer auf. Diese Objektmethoden überprüfen die Quell- und Zielgrößen und verhindern Pufferüberlauffehler.

Wenn Ihr Treiber ein Speicherobjekt erstellt, indem er WdfMemoryCreatePreallocated aufruft, kann er dem Speicherobjekt anschließend einen anderen Puffer zuweisen, indem er WdfMemoryAssignBuffer aufruft.

Wenn ein Treiber eine E/A-Anforderung an ein E/A-Ziel sendet, übergibt er in der Regel einen Eingabe- oder Ausgabepuffer an eine Framework-E/A-Zielobjektmethode. Der Treiber gibt den Puffer an, indem entweder eine WDF_MEMORY_DESCRIPTOR-Struktur übergeben wird , die den Puffer beschreibt, oder durch Übergeben eines Speicherobjekthandles. (E/A-Zielobjektmethoden, die E/A-Anforderungen synchron senden, erfordern eine WDF_MEMORY_DESCRIPTOR-Struktur , und Methoden zum asynchronen Senden von E/A-Anforderungen erfordern ein Speicherobjekthandle.)

Informationen dazu, wann ein Speicherpuffer gültig ist, finden Sie unter Speicherpufferlebenszyklus.

Verwenden von Lookaside-Listen

Wenn Ihr Treiber viele Puffer von ungefähr der gleichen Größe benötigt, sollten sie aus einer Suchliste zugeordnet werden. Der Treiber erstellt eine Suchliste, indem er WdfLookasideListCreate aufruft. Anschließend kann der Treiber Puffer aus der Lookaside-Liste abrufen, indem er WdfMemoryCreateFromLookaside aufruft.

Jedes Mal, wenn der Treiber WdfMemoryCreateFromLookaside aufruft, erstellt das Framework ein Speicherobjekt, ruft einen Puffer aus der Suchliste ab und weist dem -Objekt den Puffer zu. Wenn der Treiber eines dieser Speicherobjekte verwendet hat, ruft er WdfObjectDelete auf, wodurch das Speicherobjekt gelöscht und der Pufferspeicherplatz in die Suchliste zurückgegeben wird.

Das Betriebssystem verwaltet die Arbeitsspeicherressourcen, die der Suchliste zugewiesen sind. Wenn der Treiber einen Puffer aus der Lookaside-Liste anfordert, wenn keiner verfügbar ist, z. B. das erste Mal, wenn der Treiber WdfMemoryCreateFromLookaside aufruft, weist das System einen Puffer zu und weist ihn der Liste zu. Wenn der Treiber WdfObjectDelete aufruft (und der Pufferspeicherplatz in die Suchliste zurückgegeben wird), behält das System den jetzt nicht zugewiesenen Puffer in der Liste bei, bis der Treiber ihn erneut benötigt. Das System erhöht die Größe der Liste nach Bedarf. Beispielsweise erhalten Treiber, die häufiger Puffer anfordern, größere Suchlisten. Andererseits kann das System die Anzahl der Puffer in der Liste reduzieren, wenn der Treiber sie nicht alle verwendet.

Verwenden von MDLs

Einige Treiber verwenden Speicherdeskriptorlisten (MDLs), um Puffer zu beschreiben. Beispielsweise muss ein Treiber für ein DMA-Gerät (Direct Memory Access) eine MDL an die WdfDmaTransactionInitialize-Methode übergeben, wenn diese Methode aufgerufen wird.

Ein Treiber, der MDLs verwendet, kann eine MDL abrufen, die die Puffer einer empfangenen E/A-Anforderung darstellt, indem er WdfRequestRetrieveInputWdmMdl und WdfRequestRetrieveOutputWdmMdl aufruft.

Die meisten frameworkbasierten Treiber verwenden keine MDLs.

Zuweisung lokaler Puffer

Ein Treiber, der einen lokalen, internen Pufferspeicher benötigt, der nicht an das Framework übergeben wird, muss keine Speicherobjekte erstellen, um die Puffer darzustellen. Der Treiber kann ExAllocatePoolWithTag aufrufen, um interne Puffer zuzuweisen. Wenn der Treiber die Verwendung des Puffers abgeschlossen hat, muss er ExFreePoolWithTag aufrufen.

Treiber können jedoch auch Speicherobjekte für lokale Puffer verwenden. Ein Vorteil bei der Verwendung von Speicherpuffern anstelle des Aufrufs von ExAllocatePoolWithTag ist, dass das Framework Speicherobjekte und ihre Puffer automatisch löscht, wenn das übergeordnete Objekt jedes Objekts gelöscht wird.

Wichtig

Die in diesem Thema beschriebenen ExAllocatePool-DDIs sind in Windows 10 Version 2004 veraltet und wurden durch ExAllocatePool2 und ExAllocatePool3 ersetzt. Weitere Informationen finden Sie unter Aktualisieren veralteter ExAllocatePool-Aufrufe an ExAllocatePool2 und ExAllocatePool3.

Ausrichten von Puffern

Ihr Treiber kann die WDF_ALIGN_SIZE_UP - oder WDF_ALIGN_SIZE_DOWN-Funktion verwenden, um eine Puffergröße zu berechnen, die an einem angegebenen Ausrichtungsoffset ausgerichtet ist. Diese Berechnung ist nützlich, wenn Ihr Treiber mehrere zusammenhängende Puffer zuordnen muss, wenn jeder Puffer an einer Adressausrichtungsgrenze beginnen muss.