Passage des IIP dans la pile des pilotes

Quand la routine de répartition d’un pilote reçoit un IRP, elle doit appeler IoGetCurrentIrpStackLocation afin qu’elle puisse case activée son propre emplacement de pile d’E/S et déterminer que tous les paramètres sont valides. Si le pilote ne peut pas satisfaire et terminer la demande lui-même, il peut effectuer l’une des opérations suivantes :

  • Transmettez l’IRP pour un traitement ultérieur par les pilotes de niveau inférieur.

  • Créez un ou plusieurs nouveaux IRP et passez-les à des pilotes de niveau inférieur.

Un pilote de niveau supérieur doit transmettre une demande d’E/S à un pilote inférieur suivant comme suit :

  1. Si le pilote transmet l’IRP d’entrée au pilote de niveau inférieur suivant, la routine de répartition doit appeler IoSkipCurrentIrpStackLocation ou IoCopyCurrentIrpStackLocationToNext pour configurer l’emplacement de pile d’E/S du pilote inférieur suivant.

    Si le pilote appelle IoAllocateIrp pour allouer un ou plusieurs irps supplémentaires pour les pilotes inférieurs, la routine de répartition doit initialiser l’emplacement de la pile d’E/S du pilote inférieur suivant en suivant les étapes décrites dans Traitement des IRP dans un pilote Intermediate-Level.

    La routine de répartition peut modifier certains paramètres dans l’emplacement de la pile d’E/S du pilote inférieur suivant pour certaines demandes. Par exemple, un pilote de niveau supérieur peut modifier les paramètres d’une demande de transfert volumineuse lorsque l’appareil sous-jacent présente une limite de capacité de transfert connue, et réutiliser l’IRP pour envoyer des demandes de transfert partiel au pilote de périphérique sous-jacent.

  2. Appelez IoSetCompletionRoutine.

    Si la routine de répartition transmet un IRP reçu au pilote inférieur suivant, la définition d’une routine IoCompletion est facultative, mais utile, car la routine peut effectuer des tâches telles que la détermination du nombre de pilotes inférieurs à la demande, la réutilisation de l’IRP pour les transferts partiels, la mise à jour de l’état que le pilote maintient s’il effectue le suivi des IRP et la nouvelle tentative d’une requête retournée avec une erreur.

    Si la routine de répartition a alloué de nouveaux IRP, la définition d’une routine IoCompletion est nécessaire, car la routine doit libérer chaque IRP une fois que les pilotes inférieurs l’ont terminé.

    Pour plus d’informations sur les routines IoCompletion , consultez Terminer les irps.

  3. Appelez IoCallDriver avec chaque IRP à traiter par des pilotes inférieurs.

  4. Retourne une valeur NTSTATUS appropriée, telle que :

    • STATUS_PENDING

      Le pilote retourne généralement STATUS_PENDING si l’IRP d’entrée est une requête asynchrone, telle que IRP_MJ_READ ou IRP_MJ_WRITE.

    • Résultat de l’appel à IoCallDriver

      Le pilote retourne fréquemment le résultat de l’appel à IoCallDriver si l’IRP d’entrée est une requête synchrone, telle que IRP_MJ_CREATE.

Un pilote de périphérique de niveau le plus bas transmet toute IRP qu’il ne peut pas effectuer dans sa routine de distribution à d’autres routines de pilotes comme suit :

  1. Appelez IoMarkIrpPending avec l’IRP d’entrée.

  2. Appelez IoStartPacket pour transmettre ou mettre en file d’attente l’IRP à la routine StartIo du pilote, sauf si le pilote gère sa propre file d’attente IRP interne, comme décrit dans Files d’attente IRP gérées par le pilote.

    Si le pilote n’a pas de routine StartIo mais qu’il gère les IRP annulables, il doit soit inscrire une routine Cancel , soit implémenter une file d’attente IRP d’annulation sécurisée. Pour plus d’informations sur les routines d’annulation , consultez Annulation des irps.

  3. Retournez STATUS_PENDING.