Sincronizando o cancelamento de solicitações enviadas
Quando um driver tenta cancelar uma solicitação de E/S encaminhada para um destino de E/S, o driver deve garantir que ele passe um identificador de solicitação válido para o método WdfRequestCancelSentRequest . O identificador de solicitação se tornará inválido se o destino de E/S concluir a solicitação, pois a função de retorno de chamada CompletionRoutine do driver chamará WdfRequestComplete (que tenta excluir o objeto de solicitação).
Para evitar esse problema, o driver pode acompanhar as solicitações que enviou para o destino de E/S criando, por exemplo, uma coleção de objetos de solicitação . O driver pode chamar WdfSpinLockAcquire para sincronizar o acesso à coleção.
Quando a função de retorno de chamada CompletionRoutine do driver é chamada, ela adquire o bloqueio, remove o identificador da solicitação concluída da coleção e chama WdfSpinLockRelease para liberar o bloqueio.
Antes de tentar cancelar uma solicitação que o driver encaminhou para um destino de E/S, o driver pode:
Chame WdfSpinLockAcquire para adquirir um bloqueio de rotação.
Localize o identificador do objeto de solicitação na coleção para garantir que a rotina de conclusão do driver não tenha concluído a solicitação e removido o identificador da coleção.
Chame WdfObjectReference para incrementar a contagem de referência do objeto de solicitação para que o objeto não possa ser excluído.
Chame WdfSpinLockRelease para liberar o bloqueio de rotação.
Chame WdfRequestCancelSentRequest.
Chame WdfObjectDereference para diminuir a contagem de referência do objeto.
Essa sequência garante que, se o destino de E/S concluir a solicitação antes que o driver chame WdfRequestCancelSentRequest, o identificador da solicitação ainda será válido (devido à contagem de referência incrementada) mesmo que a função de retorno de chamada CompletionRoutine do driver chame WdfRequestComplete.