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
STATUS_CANCELLED
Die E/A-Anforderung wurde abgebrochen. Weitere Informationen finden Sie unter Hinweise.
STATUS_INVALID_DEVICE_REQUEST
  • Der Treiber besitzt nicht die E/A-Anforderung.
  • Die E/A-Anforderung kann bereits abgebrochen werden.
 

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:

  1. Beenden Oder Beenden der Verarbeitung der Anforderung zusammen mit Unteranforderungen, die möglicherweise erstellt wurden.
  2. Rufen Sie WdfRequestComplete auf, und geben Sie den status Wert STATUS_CANCELLED an.
Weitere Informationen zur Implementierung finden Sie in den folgenden Codebeispielen.

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.
Weitere Informationen zu WdfRequestMarkCancelableEx finden Sie unter Abbrechen von E/A-Anforderungen.

Beispiele

Die folgenden Codebeispiele zeigen Teile von zwei Rückruffunktionen:

Im ersten Beispiel verwendet der Treiber die automatische Synchronisierung des Frameworks. Im zweiten Beispiel stellt der Treiber mithilfe von Spinlocks eine eigene Synchronisierung bereit.

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)

Weitere Informationen

EvtRequestCancel

WdfRequestComplete

WdfRequestForwardToIoQueue

WdfRequestMarkCancelable

WdfRequestUnmarkCancelable