Freigeben über


Synchronisieren von Abbruch- und Vervollständigungscode

Wenn Ihr Treiber WdfRequestMarkCancelable oder WdfRequestMarkCancelableEx aufruft , um eine E/A-Anforderung abzubrechen, besteht die Möglichkeit eines Synchronisierungsproblems. Der Treiber und das Gerät können beispielsweise Geräte-E/A-Vorgänge asynchron mithilfe der Rückruffunktionen EvtInterruptIsr und EvtInterruptDpc ausführen, und sowohl die Rückruffunktionen EvtInterruptDpc als auch evtRequestCancel können Aufrufe von WdfRequestComplete enthalten.

Der Treiber muss WdfRequestComplete nur einmal aufrufen, um die Anforderung abzuschließen oder abzubrechen. Wenn die Rückruffunktionen EvtInterruptDpc und EvtRequestCancel jedoch nicht miteinander synchronisiert sind, kann das Framework eine aufrufen, während das andere ausgeführt wird.

Dieses Problem zu vermeiden ist einfach, wenn Ihr Treiber die automatische Synchronisierung des Frameworks verwendet, da die automatische Synchronisierung sicherstellt, dass die Rückruffunktionen einzeln aufgerufen werden.

Wenn Ihr Treiber die automatische Synchronisierung des Frameworks nicht verwendet, kann er Frameworksperren verwenden, um Abbruch- und Vervollständigungscode zu synchronisieren.

Unabhängig davon, ob der Treiber die automatische Synchronisierung des Frameworks verwendet oder eine eigene Synchronisierung bereitstellt, muss die Rückruffunktion EvtRequestCancel des Treibers WdfRequestComplete aufrufen, um eine Anforderung abzubrechen. Die EvtInterruptDpc-Rückruffunktion des Treibers sollte WdfRequestUnmarkCancelable wie folgt aufrufen:

Status = WdfRequestUnmarkCancelable(Request);
if( Status != STATUS_CANCELLED ) {
    WdfRequestComplete(Request, RequestStatus);
    }

Dieser Code stellt sicher, dass der Treiber WdfRequestComplete nicht aufruft , um die Anforderung abzuschließen, wenn der Treiber sie bereits aufgerufen hat, um die Anforderung abzubrechen.

Weitere Informationen zu den Regeln, die Ihr Treiber befolgen muss, wenn er WdfRequestUnmarkCancelable aufruft, finden Sie unter WdfRequestUnmarkCancelable.