Freigeben über


Abbrechen von E/A-Anforderungen in UMDF

Warnung

UMDF 2 ist die neueste Version von UMDF und ersetzt UMDF 1. Alle neuen UMDF-Treiber sollten mit UMDF 2 geschrieben werden. UMDF 1 werden keine neuen Features hinzugefügt, und die Unterstützung für UMDF 1 für neuere Versionen von Windows 10 ist eingeschränkt. Universelle Windows-Treiber müssen UMDF 2 verwenden.

Die archivierten UMDF 1-Beispiele finden Sie im Windows 11, Version 22H2 – Mai 2022 Treiberbeispiele Update.

Weitere Informationen finden Sie unter Erste Schritte mit UMDF.

Der derzeit laufende E/A-Vorgang eines Geräts (z. B. eine Anforderung zum Lesen mehrerer Blöcke von einem Datenträger) kann von einer Anwendung, dem System oder einem Treiber abgebrochen werden. Wenn der E/A-Vorgang eines Geräts abgebrochen wird, versucht der E/A-Manager, alle nicht verarbeiteten E/A-Anforderungen abzubrechen, die dem E/A-Vorgang zugeordnet sind. Die Gerätetreiber können sich registrieren, um benachrichtigt zu werden, wenn der E/A-Manager versucht, E/A-Anforderungen abzubrechen, und die Treiber können die Anforderungen, die sie besitzen, abbrechen, indem sie sie mit einer status von HRESULT_FROM_WIN32(ERROR_OPERATION_ABORTED) abschließen.

Das Framework übernimmt einen Teil der Abbrucharbeiten für frameworkbasierte Treiber. Wenn der E/A-Vorgang eines Geräts abgebrochen wird, schließt das Framework die folgenden E/A-Anforderungen ab, die dem abgebrochenen Vorgang zugeordnet sind, mit einer status von HRESULT_FROM_WIN32(ERROR_OPERATION_ABORTED):

  • Nicht zugestellte E/A-Anforderungen, die das Framework in der Standard-E/A-Warteschlange des Treibers platziert hat.

  • Nicht übermittelte E/A-Anforderungen, die das Framework an eine andere Warteschlange weitergeleitet hat, weil der Treiber IWDFIoQueue::ConfigureRequestDispatching aufgerufen hat.

Da das Framework diese Anforderungen abbricht, werden sie nicht an den Treiber übermittelt.

Nachdem das Framework eine E/A-Anforderung an den Treiber übermittelt hat, besitzt der Treiber die Anforderung, und das Framework kann sie nicht abbrechen. An diesem Punkt kann nur der Treiber die E/A-Anforderung abbrechen, aber das Framework muss den Treiber benachrichtigen, dass eine Anforderung abgebrochen werden soll. Treiber erhalten diese Benachrichtigung, indem sie eine IRequestCallbackCancel::OnCancel-Rückruffunktion bereitstellen.

Manchmal empfängt ein Treiber eine E/A-Anforderung von einer E/A-Warteschlange, aber anstatt die Anforderung zu verarbeiten, stellt der Treiber die Anforderung zur späteren Verarbeitung an dieselbe oder eine andere E/A-Warteschlange zurück. Beispielsweise kann das Framework eine E/A-Anforderung an einen der Anforderungshandler des Treibers übermitteln, und der Treiber ruft anschließend entweder IWDFIoRequest::ForwardToIoQueue auf, um die Anforderung in einer anderen Warteschlange zu platzieren, oder IWDFIoRequest2::Requeue , um die Anforderung wieder in derselben Warteschlange zu platzieren.

In diesen Fällen kann das Framework die E/A-Anforderung abbrechen, da sich die Anforderung in einer E/A-Warteschlange befindet. Wenn der Treiber jedoch eine Rückruffunktion für die E/A-Warteschlange registriert hat, in der sich die Anforderung befindet, ruft das Framework die Rückruffunktion auf, anstatt die Anforderung abzubrechen, wenn der zugeordnete E/A-Vorgang abgebrochen wird. Wenn das Framework die Rückruffunktion des Treibers aufruft, muss der Treiber die Anforderung abbrechen.

Zusammenfassend lässt sich sagen, dass das Framework beim Abbrechen eines E/A-Vorgangs immer alle zugeordneten E/A-Anforderungen abbricht, die nie an den Treiber übermittelt wurden. Wenn der Treiber eine Anforderung empfängt und diese dann erneut ausgibt, bricht das Framework die Anforderung ab (wenn sich die Anforderung in der Warteschlange befindet), es sei denn, der Treiber stellt eine Rückruffunktion für die E/A-Warteschlange bereit.

Aufrufen von MarkCancelable

Ein Treiber kann IWDFIoRequest::MarkCancelable aufrufen, um eine IRequestCallbackCancel::OnCancel-Rückruffunktion zu registrieren. Wenn der Treiber MarkCancelable aufgerufen hat und der der Anforderung zugeordnete E/A-Vorgang abgebrochen wird, ruft das Framework die OnCancel-Rückruffunktion des Treibers auf, damit der Treiber die E/A-Anforderung abbrechen kann.

Ein Treiber sollte MarkCancelable aufrufen, wenn er eine Anforderung für eine relativ lange Zeit besitzt. Beispielsweise muss ein Treiber warten, bis ein Gerät reagiert, oder er muss auf niedrigere Treiber warten, um eine Reihe von Anforderungen abzuschließen, die der Treiber beim Empfangen einer einzelnen Anforderung erstellt hat.

Wenn ein Treiber MarkCancelable nicht aufruft oder ein Treiber IWDFIoRequest::UnmarkCancelable nach dem Aufruf von MarkCancelable aufruft, ist dem Treiber der Abbruch nicht bekannt und verarbeitet die Anforderung daher wie üblich.

Aufrufen von IsCanceled

Wenn ein Treiber markCancelable nicht aufgerufen hat, um eine OnCancel-Rückruffunktion zu registrieren, kann er IWDFIoRequest2::IsCanceled aufrufen, um festzustellen, ob der E/A-Manager versucht hat, eine E/A-Anforderung abzubrechen. Wenn IsCanceledTRUE zurückgibt, sollte der Treiber die Anforderung abbrechen.

Beispielsweise kann ein Treiber, der eine große Lese- oder Schreibanforderung empfängt, die in mehrere kleinere Anforderungen unterteilt wird, IsCanceled aufrufen, nachdem das E/A-Ziel des Treibers jede der kleineren Anforderungen abgeschlossen hat, wenn der Treiber für die empfangene Anforderung nicht MarkCancelable aufgerufen hat.

Abbrechen der Anforderung

Das Abbrechen einer E/A-Anforderung kann folgendes umfassen:

  • Beenden eines laufenden E/A-Vorgangs.

  • Die Anforderung wird nicht an ein E/A-Ziel weitergeleitet.

  • Aufrufen von IWDFIoRequest::CancelSentRequest , um eine Anforderung abzubrechen, die der Treiber zuvor an ein E/A-Ziel gesendet hatte.

Wenn ein Treiber eine E/A-Anforderung für ein Anforderungsobjekt abbricht, das der Treiber vom Framework empfangen hat, muss der Treiber die Anforderung immer abschließen, indem er IWDFIoRequest::Complete oder IWDFIoRequest::CompleteWithInformation mit dem CompletionStatus-Parameter HRESULT_FROM_WIN32(ERROR_OPERATION_ABORTED) aufruft. (Wenn der Treiber IWDFDevice::CreateRequest aufgerufen hat, um ein Anforderungsobjekt zu erstellen, ruft der Treiber IWDFObject::D eleteWdfObject auf, anstatt die Anforderung abzuschließen.)