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:

  1. Chame WdfSpinLockAcquire para adquirir um bloqueio de rotação.

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

  3. Chame WdfObjectReference para incrementar a contagem de referência do objeto de solicitação para que o objeto não possa ser excluído.

  4. Chame WdfSpinLockRelease para liberar o bloqueio de rotação.

  5. Chame WdfRequestCancelSentRequest.

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