Partager via


Passage d’IRPs PnP dans la pile d’appareils

Le gestionnaire PnP utilise les irps pour diriger les pilotes vers le démarrage, l’arrêt et la suppression des appareils, et pour interroger les pilotes sur leurs appareils. Tous les IIP PnP ont le code de fonction principal IRP_MJ_PNP, et tous les pilotes PnP doivent fournir une routine DispatchPnP pour traiter ce code de fonction. Le gestionnaire PnP initialise Irp-IoStatus.Status> pour STATUS_NOT_SUPPORTED lorsqu’il envoie un IRP. Pour plus d’informations, consultez DispatchPnP Routines.

Pour obtenir la liste des IIP mineurs PnP, consultez Plug-and-Play IPR mineurs.

Tous les pilotes d’un appareil doivent avoir la possibilité de répondre à un IRP PnP, sauf si un pilote de la pile échoue à l’IRP. (Voir la figure suivante.)

diagramme illustrant le passage d’un irp plug-and-play dans la pile de l’appareil.

Aucun pilote pour un appareil ne peut supposer qu’il s’agit du seul pilote qui répondra à un IRP PnP. Prenons l’exemple d’un pilote de fonction qui répond à une demande de IRP_MN_QUERY_CAPABILITIES et termine l’IRP sans le transmettre au pilote inférieur suivant. Aucune des fonctionnalités prises en charge par les pilotes inférieurs, telles qu’un ID de instance unique ou des fonctionnalités de gestion de l’alimentation prises en charge par le pilote de bus parent, n’est signalée.

Un IRP PnP remonte la pile des appareils lorsque le pilote de bus parent appelle IoCompleteRequest et que le gestionnaire d’E/S appelle toutes les routines IoCompletion inscrites par le pilote de fonction ou les pilotes de filtre.

Un pilote de fonction ou de filtre doit effectuer les opérations suivantes lorsqu’il reçoit un IRP PnP :

  • Si le pilote effectue des actions en réponse à l’IRP :
    1. Effectuez les actions appropriées.
    2. Définissez Irp-IoStatus.Status> sur un status approprié, comme STATUS_SUCCESS. Définissez Irp-IoStatus.Information>, le cas échéant pour l’IRP.
    3. Configurez l’emplacement de pile suivant avec IoSkipCurrentIrpStackLocation ou IoCopyCurrentIrpStackLocationToNext. Appelez cette dernière routine si vous définissez une routine IoCompletion .
    4. Définissez une routine IoCompletion , si nécessaire.
    5. Ne terminez pas l’IRP. (N’appelez pas IoCompleteRequest.) Le pilote de bus parent termine l’IRP.
  • Si le pilote n’effectue pas d’actions pour cet IRP, il se prépare simplement à passer l’IRP au pilote suivant :
    1. Appelez IoSkipCurrentIrpStackLocation pour supprimer son emplacement de pile de l’IRP.
    2. Ne définissez aucun champ dans Irp-IoStatus>.
    3. Ne définissez pas de routine IoCompletion .
    4. Ne terminez pas l’IRP. (N’appelez pas IoCompleteRequest.) Le pilote de bus parent termine l’IRP.

Si un pilote de fonction ou de filtre n’a pas échoué l’IRP, il transmet l’IRP au pilote inférieur suivant avec IoCallDriver. Un pilote a un pointeur vers le pilote inférieur suivant ; ce pointeur a été retourné à partir de l’appel IoAttachDeviceToDeviceStack dans la routine AddDevice du pilote supérieur.

Le pilote de bus parent effectue l’IRP après avoir effectué des tâches pour répondre à l’IRP. Une fois que le pilote de bus a appelé IoCompleteRequest, le gestionnaire d’E/S appelle toutes les routines IoCompletion inscrites par la fonction ou les pilotes de filtre pour l’appareil.