Removendo um dispositivo em um driver de função
Ao remover um dispositivo, um driver de função deve desfazer todas as operações executadas para adicionar e iniciar o dispositivo. Essa discussão inclui drivers de função para dispositivos periféricos e drivers de função para dispositivos de ônibus.
Um driver de função remove um dispositivo usando um procedimento como o seguinte em sua rotina DispatchPnP :
Este é um driver de função para um dispositivo de ônibus?
Nesse caso, possivelmente exclua quaisquer PDOs filho pendentes para dispositivos no barramento.
Se o motorista do ônibus lidou com uma solicitação de IRP_MN_SURPRISE_REMOVAL anterior para o dispositivo filho, mas o motorista ainda não recebeu a solicitação de IRP_MN_REMOVE_DEVICE subsequente, o motorista do ônibus deixa o PDO filho intacto. Posteriormente, quando todos os identificadores para o dispositivo filho forem fechados, o gerenciador PnP enviará o IRP de remoção para o dispositivo filho e o motorista do barramento excluirá o PDO filho nesse momento.
Se o motorista do ônibus lidou com uma solicitação de IRP_MN_REMOVE_DEVICE anterior para o dispositivo e não houve nenhuma solicitação de IRP_MN_SURPRISE_REMOVAL subsequente, o motorista do ônibus excluirá o PDO filho. Nesse caso, o gerenciador de PnP garante que qualquer função e drivers de filtro tenham sido removidos do dispositivo filho (FDO e DOs de filtro foram excluídos) antes de enviar um IRP de remoção para o dispositivo de barramento pai. O PDO filho ainda pode estar presente, portanto, o motorista do barramento deve excluir o PDO filho antes de remover o dispositivo de barramento.
O driver já lidou com uma solicitação de IRP_MN_SURPRISE_REMOVAL anterior para esse FDO?
Nesse caso, execute qualquer limpo restante e pule para a etapa 8, IoCallDriver.
Um driver normalmente mantém um sinalizador na extensão do dispositivo que indica se o driver lidou com uma solicitação de IRP_MN_SURPRISE_REMOVAL para o dispositivo.
Se o driver habilitou anteriormente o dispositivo para ativação, cancele a solicitação de IRP_MN_WAIT_WAKE .
Verifique se o dispositivo está inativo.
Se o dispositivo ainda não estiver inativo em resposta a um IRP_MN_QUERY_REMOVE_DEVICE anterior, o driver deverá marcar o dispositivo como não aceitando novas solicitações e deve concluir todas as solicitações enfileiradas nesse driver. O driver deve falhar em todas as solicitações pendentes que exijam acesso ao dispositivo.
Um driver pode usar as rotinas IoXxxRemoveLockXxx para contar E/S pendentes e definir um evento que indica que o processamento de remoção pode continuar.
Executar qualquer operação de desligamento.
Cada driver para o dispositivo executa suas operações de desligar, se houver, quando recebe a solicitação de IRP_MN_REMOVE_DEVICE . O proprietário da política de energia do dispositivo, normalmente o driver de função, não envia uma solicitação de IRP_MN_SET_POWER separada para definir o estado de energia do dispositivo como D3. O driver de barramento pai normalmente liga o slot e notifica o power manager com PoSetPowerState quando o driver de ônibus obtém o IRP de remoção. Para obter informações adicionais, consulte Gerenciamento de Energia.
Desabilite todas as interfaces de dispositivo chamando IoSetDeviceInterfaceState.
Libere todos os recursos de hardware para o dispositivo em uso pelo driver.
As operações exatas dependem do dispositivo e do driver, mas podem incluir a desconexão de uma interrupção com IoDisconnectInterrupt, a liberação de intervalos de endereços físicos com MmUnmapIoSpace e a liberação de portas de E/S.
Passe a solicitação de IRP_MN_REMOVE_DEVICE para o próximo driver.
Configure o local da pilha IRP para o próximo driver inferior com IoSkipCurrentIrpStackLocation e passe o IRP para o próximo driver com IoCallDriver.
Um driver não precisa esperar que os drivers subjacentes terminem suas operações de remoção antes de continuar com suas atividades de remoção.
Remova o objeto de dispositivo da pilha de dispositivos com IoDetachDevice.
Especifique um ponteiro para o próximo objeto de dispositivo inferior como o parâmetro TargetDevice . O driver recebe esse ponteiro da chamada para IoAttachDeviceToDeviceStack na rotina AddDevice do driver.
Limpe todas as alocações específicas do dispositivo, memória, eventos e assim por diante.
Libere o FDO com IoDeleteDevice.
Retorne da rotina DispatchPnP, propagando a status de retorno de IoCallDriver.
Um driver de função não especifica uma rotina IoCompletion para um IRP de remoção, nem conclui o IRP. A remoção de IRPs é concluída pelo motorista do ônibus pai.