Lidar com 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 para atualizar 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 aplicativos registrados para notificação no próprio 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 os manipuladores do dispositivo) ou recusa a consulta. Consulte Cadastro para notificação de chegada da interface de dispositivo e remoção de dispositivo para obter mais informações sobre como lidar com essas notificações.
Notifica todos os drivers em modo kernel registrados 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 de EventCategoryTargetDeviceChange.
Em resposta a essa notificação, um driver é preparado para a remoção do dispositivo (fecha os identificadores do dispositivo) ou recusa a consulta.
Envia IRPs IRP_MN_QUERY_REMOVE_DEVICE aos drivers dos descendentes do dispositivo. Veja a seguir mais informações sobre como uma pilha de dispositivos lida com esse IRP.
(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 no dispositivo, a solicitação de remoção normalmente falhará no sistema de arquivos. Caso contrário, o sistema de arquivos normalmente bloqueia o volume para impedir que criações de arquivos futuras tenham sucesso. Se um sistema de arquivos montado não der suporte a uma solicitação de remoção, o gerenciador PnP falhará na solicitação de remoção 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 IRP_MN_QUERY_REMOVE_DEVICE é identificada primeiro pelo driver superior na pilha do dispositivo e então por cada próximo driver inferior. Um driver identifica a remoção de IRPs em sua rotina de DispatchPnP.
Em resposta a um IRP_MN_QUERY_REMOVE_DEVICE, um driver deve fazer o seguinte:
Determine se o dispositivo pode ser removido do computador com segurança.
Um driver deve falhar um IRP (Pedido de Pacote de Solicitação) de remoção de consulta se qualquer uma das seguintes condiçõ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 rastreiam 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 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.
Caso o driver tenha 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.
Se o dispositivo não puder ser removido, haverá falha do IRP de remoção de consulta.
Defina Irp->IoStatus.Status como um status de erro adequado (normalmente STATUS_UNSUCCESSFUL), chame IoCompleteRequest com IO_NO_INCREMENT e retorne a partir da rotina do driver DispatchPnP. Não passe o IRP para o próximo driver inferior.
Se o driver tiver enviado uma solicitação IRP_MN_WAIT_WAKE para habilitar o dispositivo para despertar, cancele o IRP de suspensão-despertar.
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 em que o dispositivo entra quando o driver conclui com êxito uma solicitação de IRP_MN_START_DEVICE.
Porém, outros estados anteriores são possíveis. Por exemplo, o usuário pode ter desabilitado o dispositivo por meio do Gerenciador de Dispositivos. Ou, em resposta a uma solicitação IRP_MN_QUERY_CAPABILITIES, o driver de barramento principal (ou um driver de filtro no driver de barramento) pode ter relatado que o 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.
Conclua o IRP:
Em um driver de função ou 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 na camada inferior com IoCallDriver.
Propague o status a partir IoCallDriver como o status de retorno da rotina DispatchPnP.
Não conclua o IRP.
Em um motorista de ônibus:
Defina Irp->IoStatus.Status to STATUS_SUCCESS.
Conclua o IRP (IoCompleteRequest) com IO_NO_INCREMENT.
Retorne da rotina DispatchPnP.
Se algum driver na pilha de dispositivos falhar um IRP_MN_QUERY_REMOVE_DEVICE, o gerenciador 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 consulta para remoção, de modo a 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 recusar quaisquer solicitações subsequentes de criação para o dispositivo. O driver processa todos os outros IRPs normalmente, até que o driver receba um IRP_MN_CANCEL_REMOVE_DEVICE ou um IRP_MN_REMOVE_DEVICE.