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 una funzione di callback evtRequestCancel definita dal driver, che il framework chiama se annulla la richiesta di I/O.

Valore restituito

nessuno

Osservazioni

Un controllo di bug si verifica se il driver fornisce un handle di oggetti non valido.

Dopo aver ricevuto una richiesta di I/O dal framework, il driver può chiamare WdfRequestMarkCancelable o, a partire dalla versione 1.9 di KMDF, WdfRequestMarkCancelableEx per rendere la richiesta annullabile .

Quando si chiama WdfRequestMarkCancelable, il driver deve specificare una funzione di callback EvtRequestCancel . Il framework chiama la funzione di callback se gestione I/O o un altro driver tenta di annullare la richiesta di I/O.

Scelta tra WdfRequestMarkCancelable e WdfRequestMarkCancelableEx

Se il driver usa la sincronizzazione automatica del 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 restituisceSTATUS_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 che WdfRequestMarkCancelableEx restituisce, la funzione di callback EvtRequestCancelcancel non verrà chiamata prima del rilascio dello spinlock. Pertanto, un deadlock non si verifica anche se la funzione di callback EvtRequestCancel 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 WdfRequestMarkCancelable e se la funzione di callback EvtRequestCancel del driver non è stata eseguita e denominata WdfRequestComplete, il driver deve chiamare WdfRequestUnmarkCancelable prima di chiama WdfRequestComplete all'esterno della funzione di callback EvtRequestCancel .

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 WdfRewardForwardToIoQueue.

  • Mentre la richiesta si trova nella seconda coda, il framework lo possiede e può annullarlo senza notificare il driver.

    Se il driver richiede la notifica di annullamento (in modo che possa deallocare qualsiasi risorsa che potrebbe essere stata allocata prima di chiamare WdfRequestForwardToIoQueue), il driver deve registrare una funzione di callback EvtIoCanceledOnQueue e deve usare memoria di contesto specifica della richiesta per archiviare informazioni sulle risorse della richiesta.

  • Dopo aver dequeuato la richiesta dalla seconda coda e recapitata al driver, il driver può chiamare WdfRequestMarkCancelable per abilitare l'annullamento.
Per altre informazioni su WdfRequestMarkCancelable, vedere Annullamento delle richieste di I/O.

Esempio

Nell'esempio di codice seguente vengono illustrate parti di due funzioni di callback:

  • Una funzione di callback EvtIoRead che esegue operazioni specifiche della richiesta,ad esempio la creazione di sottoquesthe da inviare a una destinazione di I/O, quindi consente l'annullamento della richiesta di I/O ricevuta.
  • Funzione di callback EvtRequestCancel che annulla una richiesta di I/O.
Il driver deve usare la sincronizzazione automatica del framework.
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
                       );
}

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 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( RequestCompletedLocal( kmdf)

Vedi anche

EvtRequestCancel

WdfRequestComplete

WdfRequestForwardToIoQueue

WdfRequestMarkCancelableEx

WdfRequestUnmarkCancelable