Suppression d’un périphérique dans un pilote de fonction
Lors de la suppression d’un appareil, un pilote de fonction doit annuler toutes les opérations qu’il a effectuées pour ajouter et démarrer l’appareil. Cette discussion inclut les pilotes de fonction pour les périphériques et les pilotes de fonction pour les périphériques de bus.
Un pilote de fonction supprime un appareil à l’aide d’une procédure telle que la suivante dans sa routine DispatchPnP :
S’agit-il d’un pilote de fonction pour un périphérique de bus ?
Si c’est le cas, supprimez éventuellement les PPO enfants en attente pour les appareils sur le bus.
Si le pilote de bus a géré une demande de IRP_MN_SURPRISE_REMOVAL précédente pour le périphérique enfant, mais que le pilote n’a pas encore reçu la demande de IRP_MN_REMOVE_DEVICE suivante, le pilote de bus laisse l’AOP enfant intact. À un moment ultérieur, lorsque tous les handles de l’appareil enfant sont fermés, le gestionnaire PnP envoie l’IRP de suppression pour l’appareil enfant et le pilote de bus supprime l’AOP enfant à ce moment-là.
Si le pilote de bus a géré une demande de IRP_MN_REMOVE_DEVICE précédente pour l’appareil et qu’aucune demande de IRP_MN_SURPRISE_REMOVAL ultérieure n’a été effectuée, le pilote de bus supprime l’AOP enfant. Dans ce cas, le gestionnaire PnP s’assure que tous les pilotes de fonction et de filtre ont été supprimés de l’appareil enfant (FDO et DOS de filtre ont été supprimés) avant d’envoyer un IRP de suppression au périphérique de bus parent. L’AOP enfant étant toujours présent, le pilote de bus doit supprimer l’AOP enfant avant de supprimer le périphérique de bus.
Le pilote a-t-il déjà géré une demande de IRP_MN_SURPRISE_REMOVAL précédente pour ce FDO ?
Si c’est le cas, effectuez les propre restants et passez à l’étape 8, IoCallDriver.
Un pilote gère généralement un indicateur dans l’extension de périphérique qui indique si le pilote a géré une demande de IRP_MN_SURPRISE_REMOVAL pour l’appareil.
Si le pilote a précédemment activé l’appareil pour la mise en éveil, annulez la demande IRP_MN_WAIT_WAKE .
Vérifiez que l’appareil est inactif.
Si l’appareil n’est pas déjà inactif en réponse à une IRP_MN_QUERY_REMOVE_DEVICE antérieure, le pilote doit marquer l’appareil comme n’acceptant pas de nouvelles demandes et doit terminer toutes les demandes mises en file d’attente dans ce pilote. Le pilote doit échouer toutes les demandes en attente qui nécessitent l’accès à l’appareil.
Un pilote peut utiliser les routines IoXxxRemoveLockXxx pour compter les E/S en attente et pour définir un événement indiquant que le traitement de la suppression peut continuer.
Effectuez toutes les opérations de mise hors tension.
Chaque pilote de l’appareil effectue ses opérations d’arrêt, le cas échéant, lorsqu’il reçoit la demande de IRP_MN_REMOVE_DEVICE . Le propriétaire de la stratégie d’alimentation de l’appareil, généralement le pilote de fonction, n’envoie pas de demande de IRP_MN_SET_POWER distincte pour définir l’état d’alimentation du périphérique sur D3. Le pilote de bus parent met généralement hors tension l’emplacement et avertit le gestionnaire d’alimentation avec PoSetPowerState quand le pilote de bus obtient l’IRP de suppression. Pour plus d’informations, consultez Gestion de l’alimentation.
Désactivez les interfaces d’appareil en appelant IoSetDeviceInterfaceState.
Libérez toutes les ressources matérielles pour l’appareil utilisé par le pilote.
Les opérations exactes dépendent de l’appareil et du pilote, mais peuvent inclure la déconnexion d’une interruption avec IoDisconnectInterrupt, la libération de plages d’adresses physiques avec MmUnmapIoSpace et la libération des ports d’E/S.
Transmettez la requête IRP_MN_REMOVE_DEVICE au pilote suivant.
Configurez l’emplacement de pile IRP pour le pilote inférieur suivant avec IoSkipCurrentIrpStackLocation et transmettez l’IRP au pilote suivant avec IoCallDriver.
Un pilote n’est pas obligé d’attendre que les pilotes sous-jacents terminent leurs opérations de suppression avant de poursuivre ses activités de suppression.
Supprimez l’objet d’appareil de la pile d’appareils avec IoDetachDevice.
Spécifiez un pointeur vers l’objet d’appareil inférieur suivant en tant que paramètre TargetDevice . Le pilote reçoit un tel pointeur de l’appel à IoAttachDeviceToDeviceStack dans la routine AddDevice du pilote.
Nettoyez les allocations, la mémoire, les événements, etc. spécifiques à l’appareil.
Libérez le FDO avec IoDeleteDevice.
Retour à partir de la routine DispatchPnP, en propageant le retour status à partir d’IoCallDriver.
Un pilote de fonction ne spécifie pas de routine IoCompletion pour une suppression d’IRP, ni ne termine l’IRP. La suppression des IRP est effectuée par le pilote de bus parent.