Funzione WdfRequestMarkCancelable (wdfrequest.h)
[Si applica a KMDF e UMDF]
Il metodo WdfRequestMarkCancelable consente l'annullamento di una richiesta di I/O specificata.
Sintassi
void WdfRequestMarkCancelable(
[in] WDFREQUEST Request,
[in] PFN_WDF_REQUEST_CANCEL EvtRequestCancel
);
Parametri
[in] Request
Handle per un oggetto richiesta framework.
[in] EvtRequestCancel
Puntatore a un driver definito EvtRequestCancel funzione di callback, che il framework chiama se annulla la richiesta di I/O.
Valore restituito
Nessuno
Osservazioni
Se il driver fornisce un handle di oggetto non valido, si verifica un controllo di bug.
Dopo che il driver ha ricevuto una richiesta di I/O dal framework, il driver può chiamare WdfRequestMarkCancelable oppure, a partire da KMDF versione 1.9, WdfRequestMarkCancelableEx per rendere annullabile la richiesta.
Quando si chiama WdfRequestMarkCancelable, il driver deve specificare un EvtRequestCancel funzione di callback. Il framework chiama la funzione di callback se il gestore di I/O o un altro driver sta tentando di annullare la richiesta di I/O.
Scelta tra WdfRequestMarkCancelable e WdfRequestMarkCancelableEx
Se il driver usa la sincronizzazione automatica framework, il driver può chiamare WdfRequestMarkCancelable o WdfRequestMarkCancelableEx.Se il driver non usa la sincronizzazione automatica, deve chiamare WdfRequestMarkCancelableEx anziché WdfRequestMarkCancelable per i motivi seguenti:
- Se la richiesta specificata è già stata annullata, WdfRequestMarkCancelable chiama la funzione di callback evtRequestCancel del driver prima di restituire. Se il driver acquisisce uno spinlock prima di chiamare WdfRequestMarkCancelable e tenta di acquisire lo stesso spinlock all'interno di EvtRequestCancel, lo stesso thread tenta di acquisire lo stesso spinlock due volte, causando un deadlock.
- Tuttavia, poiché WdfRequestMarkCancelableEx non chiama mai EvtRequestCancel, questo scenario non si verifica. Se la richiesta è già stata annullata, WdfRequestMarkCancelableEx restituisce STATUS_CANCELLED. Se il driver acquisisce uno spinlock (che imposta IRQL su DISPATCH_LEVEL) prima di chiamare WdfRequestMarkCancelableEx e rilascia lo spinlock (che imposta irQL su PASSIVE_LEVEL) dopo WdfRequestMarkCancelableEx, la funzione di callback EvtRequestCancel non verrà chiamata prima del rilascio dello spinlock. Pertanto, un deadlock non si verifica anche se la EvtRequestCancel funzione di callback usa lo stesso spinlock.
Elaborazione di una richiesta dopo l'abilitazione dell'annullamento
Dopo che un driver chiama WdfRequestMarkCancelable per abilitare l'annullamento, la richiesta rimane annullabile mentre il driver possiede l'oggetto richiesta, a meno che il driver non chiami WdfRequestUnmarkCancelable.Se un driver ha chiamato WdfRequestMarkCancelablee se il driver EvtRequestCancel funzione di callback non è stata eseguita e chiamata WdfRequestComplete, il driver deve chiamare WdfRequestUnmarkCancelable prima di chiamare WdfRequestComplete all'esterno della EvtRequestCancel funzione di callback.
Se il driver chiama WdfRequestForwardToIoQueue per inoltrare la richiesta a una coda diversa, si applicano le regole seguenti:
-
Le richieste di I/O non possono essere annullabili quando il driver li inoltra a una coda diversa.
In genere, il driver non deve chiamare WdfRequestMarkCancelable per abilitare l'annullamento della richiesta prima di chiamare WdfRequestForwardToIoQueue. Se il driver rende annullabile la richiesta, deve chiamare WdfRequestUnmarkCancelable per disabilitare l'annullamento prima di chiamare WdfRequestForwardToIoQueue.
-
Mentre la richiesta si trova nella seconda coda, il framework lo possiede e può annullarlo senza notificare al driver.
Se il driver richiede una notifica di annullamento (in modo che possa deallocare qualsiasi risorsa allocata prima di chiamare WdfRequestForwardToIoQueue), il driver deve registrare un EvtIoCanceledOnQueue funzione di callback e deve usare la memoria del contesto specifica della richiesta per archiviare informazioni sulle risorse della richiesta.
- Dopo che il framework ha annullato la richiesta dalla seconda coda e l'ha recapitata al driver, il driver può chiamare WdfRequestMarkCancelable per abilitare l'annullamento.
Esempi
L'esempio di codice seguente illustra le parti di due funzioni di callback:
- Un EvtIoRead funzione di callback che esegue operazioni specifiche della richiesta ,ad esempio la creazione di sottoquery da inviare a una destinazione di I/O, quindi consente l'annullamento della richiesta di I/O ricevuta.
- Una EvtRequestCancel funzione di callback che annulla una richiesta di I/O.
VOID
MyEvtIoRead(
IN WDFQUEUE Queue,
IN WDFREQUEST Request,
IN size_t Length
)
{
...
// Perform request-specific work here
// (such as creating subrequests
// to send to an I/O target).
...
WdfRequestMarkCancelable(
Request,
MyEvtRequestCancel
);
}
...
}
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
);
}
Fabbisogno
Requisito | Valore |
---|---|
piattaforma di destinazione | Universale |
versione minima di KMDF | 1.0 |
versione minima di UMDF | 2.0 |
intestazione | wdfrequest.h (include Wdf.h) |
libreria | Wdf01000.sys (KMDF); WUDFx02000.dll (UMDF) |
IRQL | <=DISPATCH_LEVEL |
regole di conformità DDI | 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) |