WdfRequestMarkCancelableEx-Funktion (wdfrequest.h)
[Gilt für KMDF und UMDF]
Die WdfRequestMarkCancelableEx-Methode ermöglicht den Abbruch einer angegebenen E/A-Anforderung.
Syntax
NTSTATUS WdfRequestMarkCancelableEx(
[in] WDFREQUEST Request,
[in] PFN_WDF_REQUEST_CANCEL EvtRequestCancel
);
Parameter
[in] Request
Ein Handle für ein Frameworkanforderungsobjekt.
[in] EvtRequestCancel
Ein Zeiger auf eine vom Treiber definierte EvtRequestCancel-Rückruffunktion , die das Framework aufruft, wenn die E/A-Anforderung abgebrochen wird.
Rückgabewert
WdfRequestMarkCancelableEx gibt STATUS_SUCCESS zurück, wenn der Abbruch der angegebenen E/A-Anforderung erfolgreich aktiviert wird. Andernfalls gibt diese Methode möglicherweise einen der folgenden Werte zurück:
Rückgabecode | Beschreibung |
---|---|
|
Die E/A-Anforderung wurde abgebrochen. Weitere Informationen finden Sie unter Hinweise. |
|
|
Diese Methode gibt möglicherweise auch andere NTSTATUS-Werte zurück.
Eine Fehlerüberprüfung tritt auf, wenn der Treiber ein ungültiges Objekthandle bereitstellt.
Hinweise
Nachdem Ihr Treiber eine E/A-Anforderung vom Framework erhalten hat, kann der Treiber WdfRequestMarkCancelable oder ab KMDF-Version 1.9 WdfRequestMarkCancelableEx aufrufen, um die Anforderung abzubrechen. Informationen zur Auswahl zwischen den beiden Methoden finden Sie unter WdfRequestMarkCancelable.
Beim Aufrufen von WdfRequestMarkCancelableEx muss Ihr Treiber eine EvtRequestCancel-Rückruffunktion angeben. Das Framework ruft die Rückruffunktion auf, wenn der E/A-Manager oder ein anderer Treiber versucht, die E/A-Anforderung abzubrechen.
Wenn WdfRequestMarkCancelableEx einen Fehler zurückgibt, muss der Treiber die gleichen Abbruchaktivitäten wie die EvtRequestCancel-Rückruffunktion ausführen. Beispiel:
- Beenden Oder Beenden der Verarbeitung der Anforderung zusammen mit Unteranforderungen, die möglicherweise erstellt wurden.
- Rufen Sie WdfRequestComplete auf, und geben Sie den status Wert STATUS_CANCELLED an.
Da WdfRequestMarkCancelableEx nie EvtRequestCancel aufruft, ist diese Methode vor dem in den Hinweisen zu WdfRequestMarkCancelable beschriebenen Deadlockrisiko geschützt.
Verarbeiten einer Anforderung nach dem Aktivieren des Abbruchs
Nachdem ein Treiber WdfRequestMarkCancelableEx aufgerufen hat, um das Abbrechen zu aktivieren, kann die Anforderung abgebrochen werden, solange der Treiber das Anforderungsobjekt besitzt, es sei denn, der Treiber ruft WdfRequestUnmarkCancelable auf.Wenn ein Treiber WdfRequestMarkCancelableEx aufgerufen hat und die EvtRequestCancel-Rückruffunktion des Treibers nicht ausgeführt und WdfRequestComplete aufgerufen wurde, muss der Treiber WdfRequestUnmarkCancelable aufrufen, bevor er WdfRequestComplete außerhalb der EvtRequestCancel-Rückruffunktion aufruft .
Wenn der Treiber WdfRequestForwardToIoQueue aufruft, um die Anforderung an eine andere Warteschlange weiterzuleiten, gelten die folgenden Regeln:
-
E/A-Anforderungen können nicht abgebrochen werden, wenn Der Treiber sie an eine andere Warteschlange weiterleitet.
Im Allgemeinen sollte Ihr Treiber WdfRequestMarkCancelableEx nicht aufrufen, um das Abbrechen der Anforderung vor dem Aufruf von WdfRequestForwardToIoQueue zu aktivieren. Wenn der Treiber die Anforderung abbruchfähig macht, muss er WdfRequestUnmarkCancelable aufrufen, um den Abbruch zu deaktivieren, bevor WdfRequestForwardToIoQueue aufgerufen wird.
-
Während sich die Anforderung in der zweiten Warteschlange befindet, besitzt das Framework sie und kann sie abbrechen, ohne den Treiber zu benachrichtigen.
Wenn der Treiber eine Abbruchbenachrichtigung benötigt (damit er die Zuordnung aller Ressourcen aufheben kann, die er vor dem Aufrufen von WdfRequestForwardToIoQueue zugeordnet hat), sollte der Treiber eine EvtIoCanceledOnQueue-Rückruffunktion registrieren und den anforderungsspezifischen Kontextspeicher verwenden, um Informationen zu den Ressourcen der Anforderung zu speichern.
- Nachdem das Framework die Anforderung aus der zweiten Warteschlange entfernt und an den Treiber übermittelt hat, kann der Treiber WdfRequestMarkCancelableEx aufrufen, um das Abbrechen zu aktivieren.
Beispiele
Die folgenden Codebeispiele zeigen Teile von zwei Rückruffunktionen:
- Eine EvtIoRead-Rückruffunktion , die anforderungsspezifische Aufgaben ausführt (z. B. das Erstellen von Teilanforderungen zum Senden an ein E/A-Ziel), ermöglicht dann den Abbruch der empfangenen E/A-Anforderung.
- Eine EvtRequestCancel-Rückruffunktion , die eine E/A-Anforderung abbricht.
Beispiel 1: Ein Treiber, der die automatische Synchronisierung verwendet.
VOID
MyEvtIoRead(
IN WDFQUEUE Queue,
IN WDFREQUEST Request,
IN size_t Length
)
{
...
NTSTATUS status;
...
// Perform request-specific work here
// (such as creating subrequests
// to send to an I/O target).
...
status = WdfRequestMarkCancelableEx(
Request,
MyEvtRequestCancel
);
if (!NT_SUCCESS(status)) {
// Remove request-specific work here, because
// we don't want the work to be done if the
// request was canceled or an error occurred.
WdfRequestComplete (Request, status);
}
...
}
VOID
MyEvtRequestCancel(
IN WDFREQUEST Request
)
{
// Remove request-specific work here, because
// we don't want the work to be done if the
// request was canceled.
WdfRequestComplete(
Request,
STATUS_CANCELLED
);
}
Beispiel 2: Ein Treiber, der eine eigene Synchronisierung verwendet.
VOID
MyEvtIoRead(
IN WDFQUEUE Queue,
IN WDFREQUEST Request,
IN size_t Length
)
{
...
NTSTATUS status;
...
WdfSpinlockAcquire(MyCancelSpinLock);
// Perform request-specific work here
// (such as creating subrequests
// to send to an I/O target).
...
status = WdfRequestMarkCancelableEx(
Request,
MyEvtRequestCancel
);
if (!NT_SUCCESS(status)) {
// Remove request-specific work here, because
// we don't want the work to be done if the
// request was canceled or an error occurred.
}
WdfSpinlockRelease(MyCancelSpinLock);
if (!NT_SUCCESS(status)) {
WdfRequestComplete (
Request,
Status
);
}
...
}
VOID
MyEvtRequestCancel(
IN WDFREQUEST Request
)
{
WdfSpinlockAcquire(MyCancelSpinLock);
// Remove request-specific work here, because
// we don't want the work to be done if the
// request was canceled.
WdfSpinlockRelease(MyCancelSpinLock);
WdfRequestComplete (Request, STATUS_CANCELLED);
}
Anforderungen
Anforderung | Wert |
---|---|
Zielplattform | Universell |
KMDF-Mindestversion | 1.9 |
UMDF-Mindestversion | 2.0 |
Kopfzeile | wdfrequest.h (include Wdf.h) |
Bibliothek | Wdf01000.sys (KMDF); WUDFx02000.dll (UMDF) |
IRQL | <=DISPATCH_LEVEL |
DDI-Complianceregeln | DeferredRequestCompleted(kmdf), DriverCreate(kmdf), EvtIoStopCancel(kmdf), InvalidReqAccess(kmdf), InvalidReqAccessLocal(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf), MarkCancOnCancReqLocal(kmdf), ReqIsCancOnCancReq(kmdf), ReqMarkCancelableSend(kmdf), ReqNotCanceledLocal(kmdf), RequestCompleted(kmdf), RequestCompletedLocal( kmdf) |