Compartilhar via


Usar Remove Locks

As rotinas de remoção de bloqueio fornecem uma maneira de acompanhar o número de operações de E/S pendentes em um dispositivo e determinar quando é seguro desanexar e excluir o objeto de dispositivo de um driver. O sistema fornece essas rotinas aos gravadores de driver como uma alternativa à implementação de seu próprio mecanismo de rastreamento.

Um driver pode usar esse mecanismo para duas finalidades:

  1. Para garantir que a rotina DispatchPnP do driver não conclua uma solicitação IRP_MN_REMOVE_DEVICE enquanto o bloqueio for mantido (por exemplo, enquanto outra rotina de driver estiver acessando o dispositivo).

  2. Para contar o número de motivos pelos quais o driver não deve excluir seu objeto de dispositivo e para definir um evento quando essa contagem for zero.

Para inicializar um bloqueio de remoção, um driver deve alocar uma estrutura IO_REMOVE_LOCK em sua extensão de dispositivo e, em seguida, chamar IoInitializeRemoveLock. Um driver normalmente chama IoInitializeRemoveLock em sua rotina AddDevice , quando o driver inicializa o restante da extensão do dispositivo para um objeto de dispositivo.

O driver deve chamar IoAcquireRemoveLock sempre que iniciar uma operação de E/S. O driver deve chamar IoReleaseRemoveLock sempre que concluir uma operação de E/S. Um driver pode adquirir o bloqueio mais de uma vez. As rotinas de remoção de bloqueio mantêm uma contagem das aquisições pendentes do bloqueio. Cada chamada para IoAcquireRemoveLock incrementa a contagem e IoReleaseRemoveLock diminui a contagem.

O driver também deve chamar IoAcquireRemoveLock quando ele passa uma referência ao seu código (para temporizadores, DPCs, retornos de chamada e assim por diante). Em seguida, o driver deve chamar IoReleaseRemoveLock quando o evento for retornado.

Em seu código de expedição para IRP_MN_REMOVE_DEVICE, o driver deve adquirir o bloqueio mais uma vez e, em seguida, chamar IoReleaseRemoveLockAndWait. Essa rotina não retorna até que todas as aquisições pendentes da fechadura tenham sido liberadas. Para permitir que as operações de E/S enfileiradas sejam concluídas, cada driver deve chamar IoReleaseRemoveLockAndWait depois de passar a solicitação IRP_MN_REMOVE_DEVICE para o driver mais baixo e antes de liberar memória, chama IoDetachDevice ou chama IoDeleteDevice. Depois que IoReleaseRemoveLockAndWait tiver sido chamado para um bloqueio de remoção específico, todas as chamadas subsequentes para IoAcquireRemoveLock para o mesmo bloqueio de remoção falharão.

Depois que IoReleaseRemoveLockAndWait retornar, o driver deverá considerar que o dispositivo está em um estado no qual ele está pronto para ser removido e não pode executar operações de E/S. Portanto, o driver não deve chamar IoInitializeRemoveLock para reinicializar o bloqueio de remoção. A violação dessa regra enquanto o driver está sendo verificado pelo Verificador de Driver resultará em uma verificação de bug.

Como um driver armazena uma estrutura IO_REMOVE_LOCK na extensão de dispositivo de um objeto de dispositivo, o bloqueio de remoção é excluído quando o driver exclui a extensão do dispositivo durante o processamento de uma solicitação IRP_MN_REMOVE_DEVICE .