Sincronizzazione del codice di annullamento e completamento

Se il driver chiama WdfRequestMarkCancelable o WdfRequestMarkCancelableEx per rendere annullabile una richiesta di I/O, potrebbe verificarsi un problema di sincronizzazione. Ad esempio, il driver e il dispositivo possono eseguire operazioni di I/O del dispositivo in modo asincrono tramite le funzioni di callback EvtInterruptIsr e EvtInterruptDpc e EvtInterruptDpc e EvtRequestCancel potrebbero contenere chiamate a WdfRequestComplete.

Il driver deve chiamare WdfRequestComplete una sola volta per completare o annullare la richiesta. Tuttavia, se le funzioni di callback EvtInterruptDpc e EvtRequestCancel non vengono sincronizzate tra loro, il framework può chiamarne uno mentre l'altro è in esecuzione.

Evitare questo problema è facile se il driver usa la sincronizzazione automatica del framework, perché la sincronizzazione automatica garantisce che le funzioni di callback vengano chiamate una alla volta.

Se il driver non usa la sincronizzazione automatica del framework, può usare i blocchi del framework per sincronizzare il codice di annullamento e completamento.

Indipendentemente dal fatto che il driver usi la sincronizzazione automatica del framework o fornisca la propria sincronizzazione, la funzione di callback EvtRequestCancel del driver deve chiamare WdfRequestComplete per annullare una richiesta. La funzione di callback EvtInterruptDpc del driver deve chiamare WdfRequestUnmarkCancelable come indicato di seguito:

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

Questo codice garantisce che il driver non chiami WdfRequestComplete per completare la richiesta se il driver lo ha già chiamato per annullare la richiesta.

Per altre informazioni sulle regole che il driver deve seguire quando chiama WdfRequestUnmarkCancelable, vedere WdfRequestUnmarkCancelable.