IoBuildAsynchronousFsdRequest, fonction (wdm.h)
Le IoBuildAsynchronousFsdRequest routine alloue et configure un IRP à envoyer aux pilotes de niveau inférieur.
Syntaxe
__drv_aliasesMem PIRP IoBuildAsynchronousFsdRequest(
[in] ULONG MajorFunction,
[in] PDEVICE_OBJECT DeviceObject,
[in, out] PVOID Buffer,
[in, optional] ULONG Length,
[in, optional] PLARGE_INTEGER StartingOffset,
[in, optional] PIO_STATUS_BLOCK IoStatusBlock
);
Paramètres
[in] MajorFunction
Code de fonction principal à définir dans l’IRP. Ce code peut être IRP_MJ_PNP, IRP_MJ_READ, IRP_MJ_WRITE, IRP_MJ_FLUSH_BUFFERSou IRP_MJ_SHUTDOWN.
[in] DeviceObject
Pointeur vers l’objet de périphérique du pilote inférieur suivant. Cet objet représente l’appareil cible pour l’opération de lecture, d’écriture, de vidage ou d’arrêt.
[in, out] Buffer
Pointeur vers une mémoire tampon dans laquelle les données sont lues ou à partir desquelles les données sont écrites. La valeur de cet argument est NULL pour les demandes de vidage et d’arrêt.
[in, optional] Length
Longueur, en octets, de la mémoire tampon pointée par tampon. Pour les appareils tels que les disques, cette valeur doit être un multiple entier de la taille du secteur. À compter de Windows 8, la taille du secteur peut être de 4 096 ou 512 octets. Dans les versions antérieures de Windows, la taille du secteur est toujours de 512 octets. Ce paramètre est requis pour les demandes de lecture et d’écriture, mais doit être égal à zéro pour les demandes de vidage et d’arrêt.
[in, optional] StartingOffset
Pointeur vers le décalage de départ sur le média d’entrée/sortie. La valeur de cet argument est zéro pour les demandes de vidage et d’arrêt.
[in, optional] IoStatusBlock
Pointeur vers l’adresse d’un bloc d’état d’E/S dans lequel les to-be-appelés pilotes retournent l’état final de l’opération demandée.
Valeur de retour
IoBuildAsynchronousFsdRequest retourne un pointeur vers un IRP, ou un pointeur NULL si l’IRP ne peut pas être alloué.
Remarques
Les pilotes intermédiaires ou de niveau supérieur peuvent appeler IoBuildAsynchronousFsdRequest pour configurer les fournisseurs d’intégration pour les demandes envoyées aux pilotes de niveau inférieur. Le pilote appelant doit fournir une routine IoCompletion pour l’IRP, afin que l’IRP puisse être libérée avec IoFreeIrp. Pour plus d’informations sur la désallocation IRP, consultez Exemples.
L’IRP qui est généré contient uniquement suffisamment d’informations pour démarrer l’opération et terminer l’IRP. Aucune autre information de contexte n’est suivie, car une requête asynchrone est indépendante du contexte.
Les pilotes de niveau inférieur peuvent imposer des restrictions sur les paramètres fournis à cette routine. Par exemple, les pilotes de disque peuvent exiger que les valeurs fournies pour Longueur et StartingOffset être des multiples entiers de la taille du secteur de l’appareil.
Un pilote intermédiaire ou de niveau supérieur peut également appeler IoBuildDeviceIoControlRequest, IoAllocateIrp, ou IoBuildSynchronousFsdRequest pour configurer les requêtes qu’il envoie aux pilotes de niveau inférieur. Seul un pilote de niveau supérieur peut appeler IoMakeAssociatedIrp.
Lors d’un appel IoBuildAsynchronousFsdRequest, le gestionnaire d’E/S définit le membre Tail.Overlay.Thread de la structure IRP pointant vers l’objet thread de l’appelant, mais ne prend pas de référence comptée à l’objet thread pour le compte de l’appelant. Une fois que l’appelant a envoyé l’IRP au pilote du périphérique cible, ce pilote peut utiliser le membre Tail.Overlay.Thread pour accéder à l’objet thread. Par exemple, un pilote de stockage peut appeler l'IoSetHardErrorOrVerifyDevice routine et fournir un pointeur vers l’IRP en tant que paramètre d’entrée. Pendant cet appel, IoSetHardErrorOrVerifyDevice utilise le membre Tail.Overlay.Thread pour accéder à l’objet thread. Lorsque l’objet thread est accessible de cette façon, le pilote qui a appelé IoBuildAsynchronousFsdRequest pour allouer l’IRP est chargé de s’assurer que l’objet thread reste valide pendant que l’IRP est géré.
Pour conserver l’objet thread valide, le pilote qui appelle IoBuildAsynchronousFsdRequest peut prendre une référence comptée sur l’objet thread avant d’envoyer l’IRP. Par exemple, ce pilote peut appeler la routine ObReferenceObjectByPointerWithTag routine et fournir, comme paramètre Object, le pointeur d’objet de la Tail.Overlay.Thread membre de la structure IRP. Plus tard, la routine d’achèvement de ce pilote peut déréférer l’objet en appelant une routine telle que ObDereferenceObjectWithTag.
Un pilote peut appeler IoBuildAsynchronousFsdRequest dans un thread et envoyer l’IRP alloué par cet appel dans un autre thread. Avant d’envoyer l’IRP, ce pilote doit définir l'Tail.Overlay.Thread membre de l’IRP pour pointer vers l’objet thread pour le thread d’envoi. En règle générale, le pilote appelle la routine PsGetCurrentThread pour obtenir le pointeur de l’objet thread.
Un pilote qui appelle IoBuildAsynchronousFsdRequest pour allouer un IRP n’a pas nécessairement besoin de prendre une référence comptée sur l’objet thread pointé par le membre Tail.Overlay.Thread de l’IRP. Le pilote peut plutôt utiliser une autre technique pour garantir que cet objet thread reste valide pendant que l’IRP est géré. Par exemple, si le pilote a créé le thread, le thread peut attendre que l’IRP soit terminé pour se terminer.
Exemples
Avant d’appeler IoFreeIrp, une étape supplémentaire est nécessaire pour libérer la mémoire tampon d’un IRP créé par IoBuildAsynchronousFsdRequest si les valeurs suivantes sont toutes vraies :
La mémoire tampon a été allouée à partir du pool de mémoire système.
Dans l’objet appareil de l’appareil cible, l’indicateur de DO_DIRECT_IO est défini dans le champ DeviceObject->Flags.
Le champ Irp->MdlAddress n’est pas NULL.
Avant de libérer la mémoire tampon pour cet IRP, appelez la routine MmUnlockPages avec >MdlAddress comme valeur de paramètre. Cet appel décrémente le nombre de références supplémentaires qui IoBuildAsynchronousFsdRequest ajouté aux pages de pool dans le MDL. Dans le cas contraire, l’appel suivant à IoFreeMdl vérifiera les bogues, car le nombre de références pour ces pages de pool sera 2, et non 1. L’exemple de code suivant montre les appels MmUnlockPages, IoFreeMdlet IoFreeIrp appels pour ce cas :
if (((DeviceObject->Flags & DO_DIRECT_IO) == DO_DIRECT_IO) &&
(Irp->MdlAddress != NULL))
{
MmUnlockPages(Irp->MdlAddress);
}
IoFreeMdl(Irp->MdlAddress);
IoFreeIrp(Irp);
Exigences
Exigence | Valeur |
---|---|
plateforme cible | Universel |
d’en-tête | wdm.h (include Wdm.h, Ntddk.h, Ntifs.h) |
bibliothèque | NtosKrnl.lib |
DLL | NtosKrnl.exe |
IRQL | IRQL <= APC_LEVEL |
règles de conformité DDI | ForwardedAtBadIrqlFsdAsync(wdm), HwStorPortProhibitedDDIs(storport), IoBuildFsdComplete(wdm), IoBuildFsdForward(wdm), IoBuildFsdFree(wdm) |