Résumé des routines de répartition en lecture/écriture
Gardez à l’esprit les points suivants lors de l’implémentation d’une routine DispatchRead, DispatchWrite ou DispatchReadWrite :
Il incombe au pilote de niveau supérieur d’une chaîne de pilotes en couches de case activée les paramètres des irps entrants en lecture/écriture pour la validité avant de configurer l’emplacement de pile d’E/S du pilote de niveau inférieur suivant dans un IRP.
Les pilotes intermédiaires et les pilotes de niveau inférieur peuvent généralement s’appuyer sur le pilote de niveau le plus élevé de leur chaîne pour transmettre les demandes de transfert avec des paramètres valides. Toutefois, n’importe quel pilote peut effectuer des vérifications d’intégrité sur les paramètres dans son emplacement de pile d’E/S d’un IRP, et chaque pilote de périphérique doit case activée les paramètres pour les conditions susceptibles de violer les restrictions imposées par son appareil.
Si une routine DispatchReadWrite termine une IRP avec une erreur, elle doit définir le membre État de l’emplacement de la pile d’E/S avec une valeur de type NTSTATUS appropriée, définir le membre Information sur zéro et appeler IoCompleteRequest avec l’IRP et un PriorityBoost de IO_NO_INCREMENT.
Si un pilote utilise des E/S mises en mémoire tampon, il peut avoir besoin de définir une structure pour contenir les données à transférer et peut avoir besoin de mettre en mémoire tampon un certain nombre de ces structures en interne.
Si un pilote utilise des E/S directes, il peut être nécessaire de case activée si la MDL sur Irp-MdlAddress> décrit une mémoire tampon contenant trop de données (ou trop de sauts de page) pour que l’appareil sous-jacent puisse gérer en une seule opération de transfert. Dans ce cas, le pilote doit fractionner la demande de transfert d’origine en une séquence d’opérations de transfert plus petites.
Un pilote de classe étroitement couplé peut fractionner une telle requête dans sa routine DispatchReadWrite pour son pilote de port sous-jacent. Les pilotes de classe SCSI, en particulier pour les périphériques de stockage de masse, sont nécessaires pour ce faire. Pour plus d’informations sur la configuration requise pour les pilotes SCSI, consultez Pilotes de stockage.
La routine DispatchReadWrite d’un pilote de périphérique de niveau inférieur doit différer le fractionnement d’une demande de transfert volumineuse en transferts partiels jusqu’à ce qu’une autre routine de pilote supprime l’IRP pour configurer l’appareil pour le transfert.
Si un pilote de périphérique de niveau inférieur met en file d’attente un IRP en lecture/écriture pour un traitement ultérieur par ses propres routines, il doit appeler IoMarkIrpPending avant de mettre en file d’attente l’IRP. La routine DispatchReadWrite doit également retourner le contrôle avec STATUS_PENDING dans ces circonstances.
Si la routine DispatchReadWrite transmet une IRP aux pilotes inférieurs, elle doit configurer l’emplacement de la pile d’E/S pour le pilote inférieur suivant dans l’IRP. Le fait que le pilote de niveau supérieur définit également une routine IoCompletion dans l’IRP avant de la transmettre avec IoCallDriver dépend de la conception du pilote et de ceux qui y sont superposés.
Toutefois, un pilote de niveau supérieur doit appeler IoSetCompletionRoutine avant d’appeler IoCallDriver s’il alloue des ressources, telles que des irps ou de la mémoire. Sa routine IoCompletion doit libérer toutes les ressources allouées par le pilote lorsque les pilotes inférieurs ont terminé la demande, mais avant que la routine IoCompletion appelle IoCompleteRequest avec l’IRP d’origine.
Si un pilote de niveau supérieur alloue des IRP pour des pilotes inférieurs qui peuvent inclure un pilote de périphérique de média amovible sous-jacent, le pilote d’allocation doit établir le contexte de thread dans chaque IRP qu’il alloue.