Abschließen von E/A-Anforderungen

Jeder frameworkbasierte Treiber muss schließlich jede E/A-Anforderung abschließen, die er vom Framework empfängt. Treiber vervollständigen Anforderungen, indem sie die WdfRequestComplete-, WdfRequestCompleteWithInformation- oder WdfRequestCompleteWithPriorityBoost-Methode des Anforderungsobjekts aufrufen.

Wann eine Anforderung abgeschlossen werden soll

Ein Treiber muss eine Anforderung abschließen, wenn er feststellt, dass einer der folgenden Fälle zutrifft:

  • Der angeforderte E/A-Vorgang wurde erfolgreich abgeschlossen.

  • Der angeforderte E/A-Vorgang wurde gestartet, war aber nicht erfolgreich, bevor er abgeschlossen wurde.

  • Der angeforderte E/A-Vorgang wird nicht unterstützt oder war zum Zeitpunkt des Empfangens ungültig und konnte nicht gestartet werden.

  • Der angeforderte E/A-Vorgang wurde abgebrochen.

Wenn der Treiber die E/A-Anforderung verarbeitet, indem er E/A-Aktivitäten auf dem Gerät erstellt, ruft der Treiber in der Regel WdfRequestComplete über seine EvtInterruptDpc - oder EvtDpcFunc-Rückruffunktion auf.

Wenn der Treiber eine nicht unterstützte oder anderweitig ungültige Anforderung empfängt, ruft er in der Regel WdfRequestComplete vom Anforderungshandler auf, der die Anforderung empfangen hat.

Wenn der E/A-Vorgang abgebrochen wurde, ruft der Treiber in der Regel WdfRequestComplete über seine EvtRequestCancel-Rückruffunktion auf.

Wenn der Treiber die E/A-Anforderung an ein E/A-Zielweiterleitet, schließt der Treiber die Anforderung ab, nachdem das E/A-Ziel die Anforderung wie folgt abgeschlossen hat:

  • Wenn Ihr Treiber die E/A-Anforderung synchron an das E/A-Ziel weiterleitet, wird der Aufruf des Treibers an das E/A-Ziel erst zurückgegeben, nachdem die Anforderung von einem Treiber auf niedrigerer Ebene abgeschlossen wurde (es sei denn, es tritt ein Fehler auf). Nachdem das E/A-Ziel zurückgegeben wurde, muss Ihr Treiber WdfRequestComplete aufrufen.

  • Wenn Ihr Treiber die E/A-Anforderung asynchron weiterleitet, soll Ihr Treiber benachrichtigt werden, wenn ein Treiber auf niedrigerer Ebene die Anforderung abgeschlossen hat. Wenn Ihr Treiber eine CompletionRoutine-Rückruffunktion registriert, ruft das Framework diese Rückruffunktion auf, nachdem das E/A-Ziel die Anforderung abgeschlossen hat. Die CompletionRoutine-Rückruffunktion ruft in der Regel WdfRequestComplete auf.

Um eine CompletionRoutine-Rückruffunktion zu registrieren, muss der Treiber WdfRequestSetCompletionRoutine aufrufen, bevor er die E/A-Anforderung an ein E/A-Ziel weiterleitet.

Wenn Ihr Treiber nicht benachrichtigt werden muss, wenn ein E/A-Ziel eine asynchron weitergeleitete E/A-Anforderung abschließt, muss der Treiber keine CompletionRoutine-Rückruffunktion registrieren. Stattdessen kann der Treiber beim Aufrufen von WdfRequestSend das WDF_REQUEST_SEND_OPTION_SEND_AND_FORGET-Flag festlegen. In diesem Fall ruft der Treiber WdfRequestComplete nicht auf.

Ein Treiber führt keine E/A-Anforderung durch, die er durch Aufrufen von WdfRequestCreate oder WdfRequestCreateFromIrp erstellt hat. Stattdessen muss der Treiber WdfObjectDelete aufrufen, um das Anforderungsobjekt zu löschen, in der Regel, nachdem ein E/A-Ziel die Anforderung abgeschlossen hat.

Beispielsweise kann ein Treiber eine Lese- oder Schreibanforderung für eine Datenmenge erhalten, die größer ist als die E/A-Ziele des Treibers gleichzeitig verarbeiten können. Der Treiber muss die Daten in mehrere kleinere Anforderungen unterteilen und diese kleineren Anforderungen an ein oder mehrere E/A-Ziele senden. Zu den Verfahren zur Behandlung dieser Situation gehören:

  • Aufrufen von WdfRequestCreate , um ein einzelnes zusätzliches Anforderungsobjekt zu erstellen, das eine kleinere Anforderung darstellt.

    Der Treiber kann diese Anforderung synchron an ein E/A-Ziel senden. Die CompletionRoutine-Rückruffunktion der kleineren Anforderung kann WdfRequestReuse aufrufen, damit der Treiber die Anforderung wiederverwenden und erneut an das E/A-Ziel senden kann. Nachdem das E/A-Ziel die letzte der kleineren Anforderungen abgeschlossen hat, kann die CompletionRoutine-RückruffunktionWdfObjectDelete aufrufen, um das vom Treiber erstellte Anforderungsobjekt zu löschen, und der Treiber kann WdfRequestComplete aufrufen, um die ursprüngliche Anforderung abzuschließen.

  • Aufrufen von WdfRequestCreate , um mehrere zusätzliche Anforderungsobjekte zu erstellen, die die kleineren Anforderungen darstellen.

    Die E/A-Ziele des Treibers können diese mehrere kleinere Anforderungen asynchron verarbeiten. Der Treiber kann eine CompletionRoutine-Rückruffunktion für jede der kleineren Anforderungen registrieren. Jedes Mal, wenn die CompletionRoutine-Rückruffunktion aufgerufen wird, kann sie WdfObjectDelete aufrufen, um ein vom Treiber erstelltes Anforderungsobjekt zu löschen. Nachdem das E/A-Ziel alle kleineren Anforderungen abgeschlossen hat, kann der Treiber WdfRequestComplete aufrufen, um die ursprüngliche Anforderung abzuschließen.

Bereitstellen von Vervollständigungsinformationen

Wenn ein Treiber eine Anforderung abschließt, kann er optional einige zusätzliche Informationen bereitstellen, auf die andere Treiber zugreifen können. Beispielsweise kann ein Treiber die Anzahl der Bytes angeben, die für eine Lese- oder Schreibanforderung übertragen wurden. Um diese Informationen bereitzustellen, kann der Treiber eine der folgenden Aktionen ausführen:

Abrufen von Abschlussinformationen

Um Informationen zu einer E/A-Anforderung zu erhalten, die ein anderer Treiber abgeschlossen hat, kann ein Treiber:

Wenn ein Treiber eine E/A-Anforderung synchron sendet, ruft er in der Regel WdfRequestGetStatus, WdfRequestGetCompletionParams und WdfRequestGetInformation auf, nachdem der synchrone Aufruf zurückgegeben wurde. Wenn ein Treiber eine E/A-Anforderung asynchron sendet, ruft er diese Methoden in der Regel aus einer CompletionRoutine-Rückruffunktion auf.

Weitere Informationen zum Abschließen von E/A-Anforderungen finden Sie unter Synchronisieren von Abbruch- und Vervollständigungscode.