Gestion d’une demande de IRP_MN_QUERY_REMOVE_DEVICE

Le gestionnaire PnP envoie cette IRP pour informer les pilotes qu’un appareil est sur le point d’être supprimé de l’ordinateur et pour demander si l’appareil peut être supprimé sans perturber l’ordinateur. Il envoie également cette IRP lorsqu’un utilisateur demande à mettre à jour les pilotes pour l’appareil.

Le gestionnaire PnP envoie cette IRP à IRQL PASSIVE_LEVEL dans le contexte d’un thread système.

Il effectue les opérations suivantes avant d’envoyer cette IRP aux pilotes d’un appareil :

  • Notifie toutes les applications en mode utilisateur qui se sont inscrites pour la notification sur l’appareil (ou un appareil associé).

    Cela inclut les applications inscrites pour notification sur l’appareil, sur l’un des descendants de l’appareil (appareil enfant, enfant de l’enfant, etc.) ou sur l’une des relations de suppression de l’appareil. Une application s’inscrit pour cette notification en appelant RegisterDeviceNotification.

    En réponse à cette notification, une application se prépare à la suppression de l’appareil (ferme les handles à l’appareil) ou échoue à la requête.

  • Notifie tous les pilotes en mode noyau inscrits pour notification sur l’appareil (ou un appareil associé).

    Cela inclut les pilotes inscrits pour notification sur l’appareil, sur l’un des descendants de l’appareil ou sur l’une des relations de suppression de l’appareil. Un pilote s’inscrit pour cette notification en appelant IoRegisterPlugPlayNotification avec une catégorie d’événement EventCategoryTargetDeviceChange.

    En réponse à cette notification, un pilote se prépare à la suppression de l’appareil (ferme les handles à l’appareil) ou échoue à la requête.

  • Envoie IRP_MN_QUERY_REMOVE_DEVICE irps aux pilotes des descendants de l’appareil.

  • (Systèmes Windows 2000 et versions ultérieures) Si un système de fichiers est monté sur l’appareil, le gestionnaire PnP envoie une demande de suppression de requête au système de fichiers et tout système de fichiers filtre. S’il existe des handles ouverts sur l’appareil, le système de fichiers échoue généralement à la demande de suppression de requête. Si ce n’est pas le cas, le système de fichiers verrouille généralement le volume pour empêcher les futures créations de réussir. Si un système de fichiers monté ne prend pas en charge une demande de suppression de requête, le gestionnaire PnP échoue à la demande de suppression de requête pour l’appareil.

Si toutes les étapes ci-dessus réussissent, le gestionnaire PnP envoie les IRP_MN_QUERY_REMOVE_DEVICE aux pilotes de l’appareil.

Une demande de IRP_MN_QUERY_REMOVE_DEVICE est gérée d’abord par le pilote supérieur de la pile de périphériques, puis par chaque pilote inférieur suivant. Un pilote gère la suppression des IRPs dans sa routine DispatchPnP .

En réponse à un IRP_MN_QUERY_REMOVE_DEVICE, un pilote doit effectuer les opérations suivantes :

  1. Déterminez si l’appareil peut être supprimé de l’ordinateur sans interrompre le fonctionnement.

    Un pilote doit échouer une IRP de suppression de requête si l’une des conditions suivantes est vraie :

    • Si la suppression de l’appareil peut entraîner la perte de données.

    • Si un composant a un handle ouvert sur l’appareil. (Il s’agit d’un problème sur Windows 98/Me uniquement. Windows 2000 et versions ultérieures de Windows effectuent le suivi des handles ouverts et échouent la requête s’il existe des handles ouverts une fois le IRP_MN_QUERY_REMOVE_DEVICE terminé.)

    • Si un pilote a été averti (via un IRP_MN_DEVICE_USAGE_NOTIFICATION IRP) que l’appareil se trouve dans le chemin d’accès pour un fichier de pagination, de vidage sur incident ou de mise en veille prolongée.

    • Si le pilote a une référence d’interface en suspens sur l’appareil. Autrement dit, le pilote a fourni une interface en réponse à une demande de IRP_MN_QUERY_INTERFACE et l’interface n’a pas été déréférée.

  2. Si l’appareil ne peut pas être supprimé, l’IRP de requête-suppression échoue.

    Définissez Irp-IoStatus.Status> sur une status d’erreur appropriée (généralement STATUS_UNSUCCESSFUL), appelez IoCompleteRequest avec IO_NO_INCREMENT et revenez à partir de la routine DispatchPnP du pilote. Ne passez pas l’IRP au pilote inférieur suivant.

  3. Si le pilote a précédemment envoyé une demande de IRP_MN_WAIT_WAKE pour activer l’appareil pour la mise en éveil, annulez l’IRP de veille d’attente.

  4. Enregistrez l’état PnP précédent de l’appareil.

    Un pilote doit enregistrer l’état PnP dans lequel se trouvait l’appareil lorsque le pilote a reçu la demande de IRP_MN_QUERY_REMOVE_DEVICE , car le pilote doit retourner l’appareil à cet état si la requête est annulée (IRP_MN_CANCEL_REMOVE_DEVICE). L’état précédent est généralement « démarré », c’est-à-dire l’état que l’appareil entre lorsque le pilote termine correctement une demande de IRP_MN_START_DEVICE .

    Toutefois, d’autres états précédents sont possibles. Par exemple, l’utilisateur a peut-être désactivé l’appareil via Gestionnaire de périphériques. Ou, en réponse à une demande de IRP_MN_QUERY_CAPABILITIES , le pilote de bus parent (ou un pilote de filtre sur le pilote de bus) peut avoir signalé que le matériel de l’appareil est désactivé. Dans les deux cas, le pilote de l’appareil désactivé peut recevoir une demande de IRP_MN_QUERY_REMOVE_DEVICE avant de recevoir une demande de IRP_MN_START_DEVICE .

  5. Terminez l’IRP :

    Dans un pilote de fonction ou de filtre :

    • Définissez Irp-IoStatus.Status> sur STATUS_SUCCESS.

    • Configurez l’emplacement de pile suivant avec IoSkipCurrentIrpStackLocation et passez l’IRP au pilote inférieur suivant avec IoCallDriver.

    • Propagez le status à partir d’IoCallDriver en tant que status de retour à partir de la routine DispatchPnP.

    • Ne terminez pas l’IRP.

    Dans un pilote de bus :

    • Définissez Irp-IoStatus.Status> sur STATUS_SUCCESS.

    • Terminez l’IRP (IoCompleteRequest) avec IO_NO_INCREMENT.

    • Retour à partir de la routine DispatchPnP .

Si un pilote de la pile d’appareils échoue à un IRP_MN_QUERY_REMOVE_DEVICE, le gestionnaire PnP envoie un IRP_MN_CANCEL_REMOVE_DEVICE à la pile d’appareils. Cela empêche les pilotes d’exiger une routine IoCompletion pour une IRP de suppression de requête afin de détecter si un pilote inférieur a échoué à l’IRP.

Une fois qu’un pilote réussit une IRP_MN_QUERY_REMOVE_DEVICE et qu’il considère que l’appareil est dans l’état en attente de suppression, le pilote doit échouer toutes les demandes de création ultérieures pour l’appareil. Le pilote traite tous les autres IIP comme d’habitude, jusqu’à ce qu’il reçoive un IRP_MN_CANCEL_REMOVE_DEVICE ou un IRP_MN_REMOVE_DEVICE.