Partilhar via


Tratamento de um pedido de IRP_MN_QUERY_REMOVE_DEVICE

O gerenciador PnP envia este IRP para informar os drivers que um dispositivo está prestes a ser removido da máquina e perguntar se o dispositivo pode ser removido sem interromper a máquina. 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 no IRQL PASSIVE_LEVEL no contexto de um thread do sistema.

Ele faz o seguinte antes de enviar este 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 aplicações que se registaram 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 CM_Register_Notification ou 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. Consulte Registo para Notificação da Chegada da Interface do Dispositivo e Remoção do Dispositivo para saber mais sobre como gerir estas notificações.

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

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

    Em resposta a esta notificação, um driver prepara-se para a remoção do dispositivo (fecha os manipuladores do dispositivo) ou rejeita a consulta.

  • Envia IRP_MN_QUERY_REMOVE_DEVICE IRPs para os drivers dos descendentes do dispositivo. Consulte abaixo para obter mais informações sobre como uma pilha de dispositivos lida com esse IRP.

  • (Windows 2000 e sistemas posteriores) Se um sistema de ficheiros estiver montado no dispositivo, o gestor PnP enviará um pedido de remoção para consulta ao sistema de ficheiros e a quaisquer filtros do sistema de ficheiros. 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 evitar que futuras criações sejam bem-sucedidas. Se um sistema de ficheiros montado não suportar um pedido de remoção por consulta, o gerenciador PnP não aceitará o pedido de remoção por consulta para o dispositivo.

Se todas as etapas acima forem bem-sucedidas, o gerenciador PnP enviará o 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 de dispositivos e, em seguida, por cada driver inferior seguinte. Um driver processa a remoção de IRPs na sua rotina DispatchPnP .

Um driver deve, em resposta a um IRP_MN_QUERY_REMOVE_DEVICE, fazer o seguinte:

  1. Determine se o dispositivo pode ser removido da máquina com segurança.

    Um controlador deve rejeitar um IRP de consulta para remoção se qualquer uma das seguintes condições for verdadeira:

    • Se remover o dispositivo pode resultar na perda de dados.

    • Se um componente tiver uma alça aberta para o dispositivo. (Este é um problema apenas no Windows 98/Me. O Windows 2000 e as versões posteriores do Windows monitorizam handles abertas e falham na consulta se houver handles abertas após a conclusão do IRP_MN_QUERY_REMOVE_DEVICE.)

    • Se um driver tiver sido notificado (por meio de um IRP IRP_MN_DEVICE_USAGE_NOTIFICATION) 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 no IRP de remoção de consulta.

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

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

  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 a esse estado se a consulta for cancelada (IRP_MN_CANCEL_REMOVE_DEVICE). O estado anterior é geralmente "iniciado", que é o estado no qual o dispositivo entra quando o controlador conclui com sucesso um pedido de IRP_MN_START_DEVICE.

    No entanto, outros estados anteriores são possíveis. Por exemplo, o utilizador pode ter desativado o dispositivo através do Gestor de dispositivos. Ou, em resposta a uma solicitação de IRP_MN_QUERY_CAPABILITIES, o controlador principal do barramento (ou um driver de filtro no driver de barramento) pode ter relatado que o hardware do dispositivo está desativado. Em ambos os casos, o driver para o dispositivo desativado pode receber uma solicitação de IRP_MN_QUERY_REMOVE_DEVICE antes de receber uma solicitação de IRP_MN_START_DEVICE.

  5. Finalize o IRP:

    Numa função ou num driver de filtro:

    • Defina Irp->IoStatus.Status para STATUS_SUCCESS.

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

    • Propagar o estado de IoCallDriver como o estado de retorno da rotina DispatchPnP .

    • Não preencha o IRP.

    Em um motorista de ônibus:

    • Defina Irp->IoStatus.Status para STATUS_SUCCESS.

    • Preencha o IRP (IoCompleteRequest) com IO_NO_INCREMENT.

    • Retorno da rotina DispatchPnP.

Se algum driver na pilha de dispositivos falhar um IRP_MN_QUERY_REMOVE_DEVICE, o gestor PnP enviará um IRP_MN_CANCEL_REMOVE_DEVICE para a pilha de dispositivos. Isso impede que os drivers exijam uma rotina de IoCompletion para um IRP de remoção de consulta para detetar se um driver inferior falhou no IRP.

Quando um driver tem sucesso com uma IRP_MN_QUERY_REMOVE_DEVICE e considera que o dispositivo está no estado de remoção pendente, o driver deve recusar quaisquer pedidos de criação subsequentes para o dispositivo. O driver processa todos os outros IRPs como de costume, até que o driver receba um IRP_MN_CANCEL_REMOVE_DEVICE ou um IRP_MN_REMOVE_DEVICE.