Funzione WdfRequestUnmarkCancelable (wdfrequest.h)
[Si applica a KMDF e UMDF]
Il metodo WdfRequestUnmarkCancelable disabilita l'annullamento di una richiesta di I/O specificata.
Sintassi
NTSTATUS WdfRequestUnmarkCancelable(
[in] WDFREQUEST Request
);
Parametri
[in] Request
Handle per un oggetto richiesta del framework.
Valore restituito
WdfRequestUnmarkCancelable restituisce STATUS_SUCCESS se l'operazione ha esito positivo. In caso contrario, questo metodo potrebbe restituire uno dei valori seguenti:
Codice restituito | Descrizione |
---|---|
|
Un parametro di input non è valido o la richiesta non è già annullabile. |
|
Il driver non è proprietario della richiesta. |
|
La richiesta è stata annullata. |
Questo metodo potrebbe anche restituire altri valori NTSTATUS.
Se il driver fornisce un handle di oggetto non valido, si verifica un controllo di bug.
Commenti
Un driver può chiamare WdfRequestUnmarkCancelable per disabilitare l'annullamento di una richiesta di I/O, se il driver precedentemente chiamato WdfRequestMarkCancelable o WdfRequestMarkCancelableEx per abilitare l'annullamento della richiesta.
Se WdfRequestUnmarkCancelable restituisce un valore diverso da STATUS_CANCELLED, la funzione di callback EvtRequestCancel del driver non verrà chiamata per la richiesta.
Se il driver precedentemente denominato WdfRequestMarkCancelable o WdfRequestMarkCancelableEx, la funzione di callback EvtRequestCancel del driver può chiamare WdfRequestComplete con un parametro Status di STATUS_CANCELLED. La funzione di callback EvtRequestCancel non deve chiamare WdfRequestUnmarkCancelable. Se il driver chiama WdfRequestComplete all'esterno della relativa funzione di callback EvtRequestCancel , il driver deve prima chiamare WdfRequestUnmarkCancelable.
Tuttavia, il driver non deve chiamare WdfRequestUnmarkCancelable dopo che EvtRequestCancel chiama WdfRequestComplete. Nella sezione Esempio seguente l'esempio archivia una copia locale dell'handle della richiesta e la cancella quando la funzione di callback EvtRequestCancel chiama WdfRequestComplete. Il driver non chiama WdfRequestUnmarkCancelable se la copia locale dell'handle di richiesta è stata cancellata. In questo esempio viene usata la sincronizzazione automatica del framework per sincronizzare le funzioni di callback.
Si noti che la chiamata a WdfObjectReference per aggiungere un riferimento aggiuntivo all'oggetto richiesta non consente al driver di chiamare WdfRequestUnmarkCancelable dopo che la funzione di callback EvtRequestCancel del driver chiama WdfRequestComplete.
Se WdfRequestUnmarkCancelable restituisce STATUS_CANCELLED e quindi EvtRequestCancel completa la richiesta, il driver non deve successivamente utilizzare l'oggetto richiesta.
Se WdfRequestUnmarkCancelable restituisce STATUS_CANCELLED, il driver non deve completare la richiesta prima che il framework chiami EvtRequestCancel. In caso contrario, il framework potrebbe chiamare EvtRequestCancel del driver con una richiesta non valida. Per esempi di codice correlati, vedere IWDFIoRequest::UnmarkCancelable.
Per altre informazioni su WdfRequestUnmarkCancelable, vedere Annullamento delle richieste di I/O.
Esempio
L'esempio di codice seguente fornisce versioni semplificate delle funzioni di callback EvtIoRead, EvtRequestCancel e EvtTimerFunc contenute nel driver di esempio ECHO . Questo esempio illustra come chiamare WdfRequestMarkCancelable, WdfRequestUnmarkCancelable e WdfRequestComplete in un driver che usa la sincronizzazione automatica del framework. L'esempio ECHO usa la sincronizzazione a livello di dispositivo.
Se il driver non usa la sincronizzazione automatica del framework, vedere i due esempi in IWDFIoRequest::UnmarkCancelable. Durante la scrittura per un driver UMDF, questi esempi illustrano le tecniche che è possibile usare per gestire la sincronizzazione tra il callback di annullamento e un altro thread che chiama la routine Unmark .
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;
}
Requisiti
Requisito | Valore |
---|---|
Piattaforma di destinazione | Universale |
Versione KMDF minima | 1.0 |
Versione UMDF minima | 2,0 |
Intestazione | wdfrequest.h (include Wdf.h) |
Libreria | Wdf01000.sys (KMDF); WUDFx02000.dll (UMDF) |
IRQL | <=DISPATCH_LEVEL |
Regole di conformità DDI | 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) |