Gestion des files d’attente d’E/S
Démarrage d’une file d’attente d’E/S
Lorsqu’un pilote appelle WdfIoQueueCreate pour créer une file d’attente d’E/S, l’infrastructure permet automatiquement à la file d’attente de recevoir des demandes d’E/S et de les remettre à un pilote.
Les pilotes appellent généralement WdfIoQueueCreate à partir d’une fonction de rappel EvtDriverDeviceAdd . L’infrastructure peut commencer à remettre des demandes d’E/S au pilote après le retour de la fonction de rappel EvtDriverDeviceAdd du pilote.
Si votre pilote utilise des files d’attente d’E/S gérées par l’alimentation , l’infrastructure ne peut pas commencer à remettre des demandes à votre pilote tant que l’appareil n’est pas entré dans son état de fonctionnement et que l’infrastructure a appelé la fonction de rappel EvtDeviceD0Entry du pilote.
Arrêt et redémarrage d’une file d’attente d’E/S
Votre pilote peut appeler WdfIoQueueStop ou WdfIoQueueStopSynchronously pour empêcher temporairement l’infrastructure de remettre des demandes d’E/S à partir d’une file d’attente d’E/S. Pour reprendre la remise des demandes d’E/S, le pilote appelle WdfIoQueueStart.
Si votre pilote utilise des files d’attente d’E/S gérées par l’alimentation, l’infrastructure arrête automatiquement les files d’attente d’un appareil lorsque l’appareil quitte son état de fonctionnement (D0), et l’infrastructure redémarre les files d’attente lorsque l’état de l’appareil revient à D0.
Ajout de requêtes à une file d’attente d’E/S
Lorsque le système envoie une demande de contrôle d’E/S de lecture, d’écriture ou de périphérique à un pilote, l’infrastructure place la demande dans une file d’attente d’E/S. Le pilote peut contrôler les types de requêtes que l’infrastructure stocke dans chaque file d’attente en appelant WdfDeviceConfigureRequestDispatching.
Un pilote peut également remettre en file d’attente les demandes qu’il a reçues de l’infrastructure, en appelant WdfRequestForwardToIoQueue.
Obtention de requêtes à partir d’une file d’attente d’E/S
Si un pilote spécifie la méthode de distribution séquentielle ou parallèle pour une file d’attente d’E/S, il reçoit les demandes dans les gestionnaires de requêtes.
Si un pilote spécifie la méthode de répartition manuelle ou séquentielle, il peut obtenir des requêtes en appelant WdfIoQueueRetrieveNextRequest ou WdfIoQueueRetrieveRequestByFileObject.
Recherche d’une demande d’E/S
Si un pilote spécifie la méthode de distribution manuelle d’une file d’attente d’E/S, il peut utiliser les étapes suivantes pour rechercher des demandes particulières dans la file d’attente :
Appelez WdfIoQueueFindRequest pour rechercher une demande qui correspond aux critères spécifiés par le pilote.
Appelez WdfIoQueueRetrieveFoundRequest pour récupérer la requête que WdfIoQueueFindRequest a localisée.
Purge ou drainage d’une file d’attente d’E/S
Purger une file d’attente d’E/S signifie arrêter l’insertion des demandes d’E/S dans la file d’attente et annuler toutes les demandes qui se trouvent déjà dans la file d’attente.
Le drainage d’une file d’attente d’E/S signifie l’arrêt de l’insertion des demandes d’E/S dans la file d’attente, tout en autorisant la remise de toutes les demandes qui se trouvent déjà dans la file d’attente au pilote.
En règle générale, les pilotes vident ou vident leurs files d’attente uniquement si les files d’attente ne sont pas gérées par l’alimentation. Pour les files d’attente d’E/S gérées par l’alimentation, les pilotes peuvent fournir des fonctions de rappel EvtIoStop et EvtIoResume .
Si certaines files d’attente de votre pilote ne sont pas gérées par l’alimentation, vous pouvez vider ou vider une file d’attente si son périphérique ou canal d’E/S associé devient indisponible. En règle générale, vous videz une file d’attente au lieu de vider une file d’attente, sauf s’il existe une probabilité élevée que chaque requête contienne des informations très importantes. Par exemple, un pilote pour un périphérique réseau peut vider ses files d’attente, tandis qu’un pilote pour un périphérique de stockage videra probablement ses files d’attente.
Si vous souhaitez que votre pilote vide ou vide une file d’attente d’E/S, il peut appeler l’une des méthodes d’objet file d’attente suivantes :
WdfIoQueuePurge ou WdfIoQueuePurgeSynchronously, pour arrêter la mise en file d’attente des demandes d’E/S dans une file d’attente d’E/S et pour annuler les demandes non traitées.
WdfIoQueueDrain ou WdfIoQueueDrainSynchronously, pour arrêter la mise en file d’attente des demandes d’E/S dans une file d’attente d’E/S tout en autorisant la remise et le traitement des demandes déjà en file d’attente.
Soyez prudent lorsque vous appelez WdfIoQueueDrain et WdfIoQueueDrainSynchronously. Étant donné qu’une opération de drainage attend que les demandes soient terminées, vous ne devez vider une file d’attente que si vous êtes certain que les demandes en attente de la file d’attente se termineront en temps opportun. Si vous ne savez pas combien de temps les demandes d’E/S devront être effectuées et qu’il est acceptable d’annuler les demandes en attente, envisagez de vider la file d’attente.
Déplacement des demandes d’une file d’attente d’E/S vers une autre
Une fois que votre pilote a reçu une demande d’E/S, vous souhaiterez peut-être qu’il la refile dans une autre file d’attente d’E/S. Pour ce faire, le pilote appelle WdfRequestForwardToIoQueue ou WdfRequestForwardToParentDeviceIoQueue, qui ajoute la requête à la fin d’une file d’attente spécifiée. Finalement, l’infrastructure remet à nouveau la demande au pilote à l’aide de la méthode de distribution de la file d’attente spécifiée. Pour plus d’informations sur le déplacement des demandes d’E/S d’une file d’attente d’E/S vers une autre, consultez Demandes d’E/S de nouvelle file d’attente.
Interception d’une demande d’E/S avant sa mise en file d’attente
Il est possible pour un pilote d’intercepter une demande d’E/S avant que l’infrastructure place la requête dans une file d’attente d’E/S. Pour intercepter les demandes d’E/S, le pilote doit appeler WdfDeviceInitSetIoInCallerContextCallback pour inscrire une fonction de rappel EvtIoInCallerContext .
L’infrastructure associe la fonction de rappel EvtIoInCallerContext à un appareil. Par conséquent, le framework appelle la fonction de rappel EvtIoInCallerContext chaque fois qu’il reçoit une demande que le système envoie à l’appareil.
En règle générale, lorsqu’une fonction de rappel EvtIoInCallerContext reçoit une demande, elle effectue un traitement préliminaire pour la requête. Ensuite, la fonction de rappel appelle WdfDeviceEnqueueRequest, ce qui renvoie la requête à l’infrastructure. L’infrastructure peut ensuite placer la requête dans la file d’attente d’E/S appropriée, comme elle l’aurait fait s’il n’avait pas appelé la fonction de rappel EvtIoInCallerContext .
La principale raison pour laquelle un pilote peut fournir une fonction de rappel EvtIoInCallerContext est que le pilote doit gérer les opérations d’E/S qui prennent en charge la méthode d’E/S appelée ni mise en mémoire tampon ni E/S directe. Pour cette méthode d’E/S, le pilote doit accéder aux mémoires tampons reçues dans le contexte de processus de l’initiateur de la demande d’E/S. Pour plus d’informations, consultez Accès aux mémoires tampons de données dans les pilotes Framework-Based.
Obtention des propriétés de la file d’attente d’E/S
Pour obtenir les propriétés d’un objet de file d’attente d’infrastructure, le pilote peut appeler les méthodes suivantes :
WdfIoQueueGetDevice, pour obtenir un handle pour l’objet d’appareil auquel appartient l’objet file d’attente.
WdfIoQueueGetState, pour obtenir des informations d’état sur la file d’attente.