WdfRequestUnmarkCancelable-Funktion (wdfrequest.h)
[Gilt für KMDF und UMDF]
Die WdfRequestUnmarkCancelable-Methode deaktiviert den Abbruch einer angegebenen E/A-Anforderung.
Syntax
NTSTATUS WdfRequestUnmarkCancelable(
[in] WDFREQUEST Request
);
Parameter
[in] Request
Ein Handle für ein Frameworkanforderungsobjekt.
Rückgabewert
WdfRequestUnmarkCancelable gibt STATUS_SUCCESS zurück, wenn der Vorgang erfolgreich ist. Andernfalls gibt diese Methode möglicherweise einen der folgenden Werte zurück:
Rückgabecode | Beschreibung |
---|---|
|
Ein Eingabeparameter ist ungültig, oder die Anforderung kann bereits nicht abgebrochen werden. |
|
Der Treiber besitzt die Anforderung nicht. |
|
Die Anforderung wurde abgebrochen. |
Diese Methode kann auch andere NTSTATUS-Werte zurückgeben.
Eine Fehlerüberprüfung tritt auf, wenn der Treiber ein ungültiges Objekthandle bereitstellt.
Hinweise
Ein Treiber kann WdfRequestUnmarkCancelable aufrufen, um den Abbruch einer E/A-Anforderung zu deaktivieren, wenn der Treiber zuvor WdfRequestMarkCancelable oder WdfRequestMarkCancelableEx aufgerufen hat, um den Abbruch der Anforderung zu aktivieren.
Wenn WdfRequestUnmarkCancelable einen anderen Wert als STATUS_CANCELLED zurückgibt, wird die Rückruffunktion EvtRequestCancel des Treibers für die Anforderung nicht aufgerufen.
Wenn der Treiber zuvor WdfRequestMarkCancelable oder WdfRequestMarkCancelableEx aufgerufen hat, kann die EvtRequestCancel-Rückruffunktion des Treibers WdfRequestComplete mit dem Statusparameter STATUS_CANCELLED aufrufen. Die Rückruffunktion EvtRequestCancel muss WdfRequestUnmarkCancelable nicht aufrufen. Wenn der Treiber WdfRequestComplete außerhalb seiner EvtRequestCancel-Rückruffunktion aufruft , muss der Treiber zuerst WdfRequestUnmarkCancelable aufrufen.
Der Treiber darf jedoch WdfRequestUnmarkCancelable nicht aufrufen, nachdem EvtRequestCancelWdfRequestComplete aufgerufen hat. Im folgenden Beispielabschnitt speichert das Beispiel eine lokale Kopie des Anforderungshandles und löscht sie dann, wenn die Rückruffunktion EvtRequestCancelWdfRequestComplete aufruft. Der Treiber ruft WdfRequestUnmarkCancelable nicht auf, wenn die lokale Kopie des Anforderungshandles gelöscht wurde. In diesem Beispiel wird die automatische Synchronisierung des Frameworks verwendet, um die Rückruffunktionen zu synchronisieren.
Beachten Sie, dass das Aufrufen von WdfObjectReference , um einen zusätzlichen Verweis auf das Anforderungsobjekt hinzuzufügen, ihrem Treiber nicht das Aufrufen von WdfRequestUnmarkCancelable ermöglicht, nachdem die EvtRequestCancel-Rückruffunktion des Treibers WdfRequestComplete aufgerufen hat.
Wenn WdfRequestUnmarkCancelable STATUS_CANCELLED zurückgibt und evtRequestCancel die Anforderung abgeschlossen hat, darf der Treiber das Anforderungsobjekt anschließend nicht verwenden.
Wenn WdfRequestUnmarkCancelable STATUS_CANCELLED zurückgibt, darf der Treiber die Anforderung nicht abschließen, bevor das Framework EvtRequestCancel aufruft. Andernfalls kann das Framework den EvtRequestCancel des Treibers mit einer ungültigen Anforderung aufrufen. Verwandte Codebeispiele finden Sie unter IWDFIoRequest::UnmarkCancelable.
Weitere Informationen zu WdfRequestUnmarkCancelable finden Sie unter Abbrechen von E/A-Anforderungen.
Beispiele
Im folgenden Codebeispiel werden vereinfachte Versionen der Rückruffunktionen EvtIoRead, EvtRequestCancel und EvtTimerFunc bereitgestellt, die der ECHO-Beispieltreiber enthält. In diesem Beispiel wird gezeigt, wie WdfRequestMarkCancelable, WdfRequestUnmarkCancelable und WdfRequestComplete in einem Treiber aufgerufen werden, der die automatische Synchronisierung des Frameworks verwendet. (Im ECHO-Beispiel wird die Synchronisierung auf Geräteebene verwendet.)
Wenn Ihr Treiber die automatische Synchronisierung des Frameworks nicht verwendet, lesen Sie die beiden Beispiele unter IWDFIoRequest::UnmarkCancelable. Während der Erstellung für einen UMDF-Treiber veranschaulichen diese Beispiele Techniken, mit denen Sie die Synchronisierung zwischen dem Rückruf zum Abbrechen und einem anderen Thread verwalten können, der die Unmarking-Routine aufruft.
VOID
EchoEvtIoRead(
IN WDFQUEUE Queue,
IN WDFREQUEST Request,
IN size_t Length
)
{
PQUEUE_CONTEXT queueContext = QueueGetContext(Queue);
// Prepare for read operation here.
// (See the Echo sample driver for details.)
...
// Enable cancellation.
WdfRequestMarkCancelable(
Request,
EchoEvtRequestCancel
);
// Save the request handle. We'll clear it after
// we call WdfRequestComplete.
queueContext->CurrentRequest = Request;
return
}
VOID
EchoEvtRequestCancel(
IN WDFREQUEST Request
)
{
PQUEUE_CONTEXT queueContext =
QueueGetContext(WdfRequestGetIoQueue(Request));
WdfRequestComplete(
Request,
STATUS_CANCELLED,
);
// Clear the request handle so EchEvtTimerFunc will
// know that we called WdfRequestComplete.
queueContext->CurrentRequest = NULL;
return;
}
VOID
EchoEvtTimerFunc(
IN WDFTIMER Timer
)
{
NTSTATUS Status;
WDFREQUEST Request;
WDFQUEUE queue;
PQUEUE_CONTEXT queueContext;
// Retrieve our saved copy of the request handle.
queue = WdfTimerGetParentObject(Timer);
queueContext = QueueGetContext(queue);
Request = queueContext->CurrentRequest;
// We cannot call WdfRequestUnmarkCancelable
// after a request completes, so check here to see
// if EchoEvtRequestCancel cleared our saved
// request handle.
if( Request != NULL ) {
Status = WdfRequestUnmarkCancelable(Request);
if(Status != STATUS_CANCELLED) {
queueContext->CurrentRequest = NULL;
Status = queueContext->CurrentStatus;
WdfRequestComplete(
Request,
Status
);
}
}
return;
}
Anforderungen
Anforderung | Wert |
---|---|
Zielplattform | Universell |
KMDF-Mindestversion | 1.0 |
UMDF-Mindestversion | 2.0 |
Kopfzeile | wdfrequest.h (einschließen von Wdf.h) |
Bibliothek | Wdf01000.sys (KMDF); WUDFx02000.dll (UMDF) |
IRQL | <=DISPATCH_LEVEL |
DDI-Complianceregeln | CompleteCanceledReq(kmdf), DeferredRequestCompleted(kmdf), DriverCreate(kmdf), EvtIoStopCancel(kmdf), InvalidReqAccess(kmdf), InvalidReqAccessLocal(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf), MarkCancOnCancReqLocal(kmdf), ReqIsCancOnCancReq(kmdf), ReqMarkCancelableSend(kmdf), ReqNotCanceledLocal(kmdf) |