Partilhar via


Manipulando uma solicitação de IRP_MN_QUERY_REMOVE_DEVICE

O gerenciador PnP envia esse IRP para informar aos drivers que um dispositivo está prestes a ser removido do computador e perguntar se o dispositivo pode ser removido sem interromper o computador. Ele também envia esse IRP quando um usuário solicita a atualização de drivers para o dispositivo.

O gerenciador PnP envia esse IRP em PASSIVE_LEVEL IRQL no contexto de um thread do sistema.

Ele faz o seguinte antes de enviar esse IRP para os drivers de um dispositivo:

  • Notifica todos os aplicativos de modo de usuário registrados para notificação no dispositivo (ou em um dispositivo relacionado).

    Isso inclui aplicativos registrados para notificação no dispositivo, em um dos descendentes do dispositivo (dispositivo filho, filho do filho e assim por diante) ou em uma das relações de remoção do dispositivo. Um aplicativo se registra para essa notificação chamando RegisterDeviceNotification.

    Em resposta a essa notificação, um aplicativo se prepara para a remoção do dispositivo (fecha identificadores para o dispositivo) ou falha na consulta.

  • Notifica todos os drivers de modo kernel que se registraram para notificação no dispositivo (ou em um dispositivo relacionado).

    Isso inclui drivers registrados para notificação no dispositivo, em um dos descendentes do dispositivo ou em uma das relações de remoção do dispositivo. Um driver registra essa notificação chamando IoRegisterPlugPlayNotification com uma categoria de evento eventCategoryTargetDeviceChange.

    Em resposta a essa notificação, um driver se prepara para a remoção do dispositivo (fecha identificadores para o dispositivo) ou falha na consulta.

  • Envia IRP_MN_QUERY_REMOVE_DEVICE IRPs para os drivers para os descendentes do dispositivo.

  • (Windows 2000 e sistemas posteriores) Se um sistema de arquivos for montado no dispositivo, o gerenciador PnP enviará uma solicitação de remoção de consulta para o sistema de arquivos e todos os filtros do sistema de arquivos. Se houver identificadores abertos para o dispositivo, o sistema de arquivos normalmente falhará na solicitação de remoção de consulta. Caso contrário, o sistema de arquivos normalmente bloqueia o volume para impedir que criações futuras sejam bem-sucedidas. Se um sistema de arquivos montado não der suporte a uma solicitação de remoção de consulta, o gerenciador PnP falhará na solicitação de remoção de consulta para o dispositivo.

Se todas as etapas acima forem bem-sucedidas, o gerenciador PnP enviará a IRP_MN_QUERY_REMOVE_DEVICE para os drivers do dispositivo.

Uma solicitação de IRP_MN_QUERY_REMOVE_DEVICE é tratada primeiro pelo driver superior na pilha do dispositivo e, em seguida, por cada próximo driver inferior. Um driver manipula a remoção de IRPs em sua rotina DispatchPnP .

Em resposta a um IRP_MN_QUERY_REMOVE_DEVICE, um driver deve fazer o seguinte:

  1. Determine se o dispositivo pode ser removido do computador sem interromper a operação.

    Um driver deverá falhar em um IRP de remoção de consulta se qualquer uma das seguintes opções for verdadeira:

    • Se a remoção do dispositivo puder resultar na perda de dados.

    • Se um componente tiver um identificador aberto para o dispositivo. (Esse é um problema somente no Windows 98/Me. O Windows 2000 e versões posteriores do Windows acompanham identificadores abertos e falham na consulta se houver identificadores abertos após a conclusão do IRP_MN_QUERY_REMOVE_DEVICE .)

    • Se um driver tiver sido notificado (por meio de um IRP_MN_DEVICE_USAGE_NOTIFICATION IRP) de que o dispositivo está no caminho para um arquivo de paginação, despejo de memória ou hibernação.

    • Se o driver tiver uma referência de interface pendente em relação ao dispositivo. Ou seja, o driver forneceu uma interface em resposta a uma solicitação de IRP_MN_QUERY_INTERFACE e a interface não foi desreferenciada.

  2. Se o dispositivo não puder ser removido, falhe o IRP de remoção de consulta.

    Defina Irp-IoStatus.Status> como um erro apropriado status (normalmente STATUS_UNSUCCESSFUL), chame IoCompleteRequest com IO_NO_INCREMENT e retorne da rotina DispatchPnP do driver. Não passe o IRP para o próximo driver inferior.

  3. Se o driver enviou anteriormente uma solicitação IRP_MN_WAIT_WAKE para habilitar o dispositivo para ativação, cancele o IRP de ativação de espera.

  4. Registre o estado PnP anterior do dispositivo.

    Um driver deve registrar o estado PnP em que o dispositivo estava quando o driver recebeu a solicitação de IRP_MN_QUERY_REMOVE_DEVICE porque o driver deve retornar o dispositivo para esse estado se a consulta for cancelada (IRP_MN_CANCEL_REMOVE_DEVICE). O estado anterior normalmente é "iniciado", que é o estado que o dispositivo insere quando o driver conclui com êxito uma solicitação de IRP_MN_START_DEVICE .

    No entanto, outros estados anteriores são possíveis. Por exemplo, o usuário pode ter desabilitado o dispositivo por meio de Gerenciador de Dispositivos. Ou, em resposta a uma solicitação de IRP_MN_QUERY_CAPABILITIES , o motorista do ônibus pai (ou um motorista de filtro no motorista do ônibus) pode ter relatado que o hardware do dispositivo está desabilitado. Em ambos os casos, o driver do dispositivo desabilitado pode receber uma solicitação IRP_MN_QUERY_REMOVE_DEVICE antes de receber uma solicitação de IRP_MN_START_DEVICE .

  5. Conclua o IRP:

    Em uma função ou driver de filtro:

    • Defina Irp-IoStatus.Status> como STATUS_SUCCESS.

    • Configure o próximo local de pilha com IoSkipCurrentIrpStackLocation e passe o IRP para o próximo driver inferior com IoCallDriver.

    • Propagar o status do IoCallDriver como o status de retorno da rotina DispatchPnP.

    • Não conclua o IRP.

    Em um motorista de ônibus:

    • Defina Irp-IoStatus.Status> como STATUS_SUCCESS.

    • Conclua o IRP (IoCompleteRequest) com IO_NO_INCREMENT.

    • Retorne da rotina DispatchPnP .

Se algum driver na pilha do dispositivo falhar em um IRP_MN_QUERY_REMOVE_DEVICE, o gerenciador PnP enviará um IRP_MN_CANCEL_REMOVE_DEVICE para a pilha do dispositivo. Isso impede que os drivers exijam uma rotina IoCompletion para um IRP de remoção de consulta para detectar se um driver inferior falhou com o IRP.

Depois que um driver tiver êxito em um IRP_MN_QUERY_REMOVE_DEVICE e considerar que o dispositivo está no estado de remoção pendente, o driver deve falhar em todas as solicitações de criação subsequentes para o dispositivo. O driver processa todos os outros IRPs como de costume, até que o driver receba uma IRP_MN_CANCEL_REMOVE_DEVICE ou um IRP_MN_REMOVE_DEVICE.