Emplacements de la pile d’E/S
Le gestionnaire d’E/S donne à chaque pilote d’une chaîne de pilotes en couches un emplacement de pile d’E/S pour chaque IRP qu’il configure. Chaque emplacement de pile d’E/S se compose d’une structure IO_STACK_LOCATION .
Le gestionnaire d’E/S crée un tableau d’emplacements de pile d’E/S pour chaque IRP, avec un élément de tableau correspondant à chaque pilote dans une chaîne de pilotes en couches. Chaque pilote possède l’un des emplacements de pile dans le paquet et appelle IoGetCurrentIrpStackLocation pour obtenir des informations spécifiques au pilote sur l’opération d’E/S.
Chaque pilote d’une telle chaîne est chargé d’appeler IoGetNextIrpStackLocation, puis de configurer l’emplacement de la pile d’E/S du pilote inférieur suivant. L’emplacement de la pile d’E/S d’un pilote de niveau supérieur peut également être utilisé pour stocker le contexte d’une opération afin que la routine IoCompletion du pilote puisse effectuer ses opérations de nettoyage.
La figure Traitement des IRP dans les pilotes en couches montre deux emplacements de pile d’E/S dans l’IRP d’origine, car elle montre deux pilotes, un pilote de système de fichiers et un pilote de périphérique de stockage de masse. Les IRP alloués par le pilote dans la figure Traitement des IRP dans les pilotes en couches n’ont pas d’emplacement de pile pour le FSD (File System Driver) qui les a créés. Tout pilote de niveau supérieur qui alloue des IRP pour les pilotes de niveau inférieur détermine également le nombre d’emplacements de pile d’E/S que les nouveaux IRP doivent avoir, en fonction de la valeur StackSize de l’objet de périphérique du pilote inférieur suivant.
La figure suivante montre plus en détail le contenu de l’IRP.
Comme le montre la figure, chaque emplacement de pile d’E/S spécifique au pilote dans un IRP contient les informations générales suivantes :
Code de fonction principale (IRP_MJ_XXX), indiquant l’opération de base que le pilote doit effectuer
Pour certains codes de fonction principaux gérés par des FSD, des pilotes SCSI de niveau supérieur et tous les pilotes PnP, un code de fonction secondaire (IRP_MN_XXX), indiquant les sous-cas de l’opération de base que le pilote doit effectuer
Ensemble d’arguments spécifiques à l’opération, tels que la longueur et l’emplacement de départ d’une mémoire tampon dans laquelle ou à partir duquel le pilote transfère des données
Pointeur vers l’objet de périphérique créé par le pilote, représentant l’appareil cible (physique, logique ou virtuel) pour l’opération demandée
Pointeur vers l’objet file, représentant un fichier, un appareil, un répertoire ou un volume ouvert
Un pilote de système de fichiers accède à l’objet de fichier via son emplacement de pile d’E/S dans les irps. Les autres pilotes ignorent généralement l’objet file.
Ensemble de codes de fonction principaux et secondaires IRP qu’un pilote particulier gère peut être spécifique au type de périphérique. Toutefois, les pilotes de niveau le plus bas et les pilotes intermédiaires (y compris les pilotes de fonction pnP et de filtre) gèrent généralement l’ensemble de requêtes de base suivant :
IRP_MJ_CREATE : ouvrez l’objet d’appareil cible, en indiquant qu’il est présent et disponible pour les opérations d’E/S
IRP_MJ_READ : transférer des données à partir de l’appareil
IRP_MJ_WRITE : transférer des données vers l’appareil
IRP_MJ_DEVICE_CONTROL : configurez (ou réinitialisez) l’appareil en fonction d’un code de contrôle d’E/S spécifique au type d’appareil (IOCTL) défini par le système.
IRP_MJ_CLOSE : fermez l’objet d’appareil cible
IRP_MJ_PNP : effectuez une opération de Plug-and-Play sur l’appareil. Une demande IRP_MJ_PNP est envoyée par le responsable PnP via le gestionnaire d’E/S.
IRP_MJ_POWER : effectuez une opération d’alimentation sur l’appareil. Une demande IRP_MJ_POWER est envoyée par le gestionnaire d’alimentation via le gestionnaire d’E/S.
Pour plus d’informations sur les principaux codes de fonction IRP que les pilotes doivent gérer, consultez Codes de fonction principaux IRP.
En général, le gestionnaire d’E/S envoie des IRP avec au moins deux emplacements de pile d’E/S aux pilotes de périphériques de stockage de masse, car un système de fichiers est superposé à d’autres pilotes pour les périphériques de stockage de masse. Le gestionnaire d’E/S envoie des irps avec un emplacement de pile unique à n’importe quel pilote qui n’a pas d’autre pilote en couche au-dessus.
Toutefois, le gestionnaire d’E/S prend en charge l’ajout d’un nouveau pilote à n’importe quelle chaîne de pilotes existants dans le système. Par exemple, un pilote miroir intermédiaire qui sauvegarde des données sur une partition de disque donnée peut être inséré entre une paire de pilotes, comme le pilote de système de fichiers et le pilote de niveau le plus bas indiqué dans la figure Traitement des IRP dans les pilotes en couches . Lorsque ce nouveau pilote s’attache à la pile de périphériques, le gestionnaire d’E/S ajuste le nombre d’emplacements de pile d’E/S dans tous les irP qu’il envoie au système de fichiers, au miroir et aux pilotes de niveau inférieur. Chaque IRP alloué par le système de fichiers dans la figure Traitement des IRP dans les pilotes en couches contient également un autre emplacement de pile d’E/S pour ce nouveau pilote miroir.
Notez que cette prise en charge de l’ajout de nouveaux pilotes à une chaîne existante implique certaines restrictions sur l’accès d’un pilote particulier aux emplacements de la pile d’E/S dans les IRP :
Un pilote de niveau supérieur dans une chaîne de pilotes en couches peut accéder en toute sécurité uniquement à ses propres emplacements et aux emplacements de pile d’E/S du pilote de niveau inférieur suivant dans n’importe quel IRP. Un tel pilote doit configurer l’emplacement de la pile d’E/S pour le pilote de niveau inférieur suivant dans les runtimes d’intégration. Toutefois, lors de la conception d’un tel pilote de niveau supérieur, vous ne pouvez pas prédire quand (ou si) un nouveau pilote sera ajouté à la chaîne existante juste en dessous de votre pilote.
Par conséquent, vous devez supposer que tout pilote ajouté ultérieurement gérera les mêmes codes de fonction principale IRP (IRP_MJ_XXX) que le pilote de niveau inférieur déplacé.
Le pilote de niveau le plus bas dans une chaîne de pilotes en couches peut accéder en toute sécurité uniquement à son propre emplacement de pile d’E/S dans n’importe quel IRP. Lors de la conception d’un tel pilote, vous ne pouvez pas prédire quand (ou si) un nouveau pilote sera ajouté à la chaîne existante au-dessus de votre pilote de périphérique.
Lors de la conception d’un pilote de niveau le plus bas, supposons que le pilote peut continuer à traiter les IRP à l’aide des informations transmises dans son propre emplacement de pile d’E/S, quelle que soit la source d’origine d’un IRP donné et quel que soit le nombre de pilotes superposés au-dessus.