WdfIoTargetFormatRequestForIoctl, fonction (wdfiotarget.h)
[S’applique à KMDF et UMDF]
La méthode WdfIoTargetFormatRequestForIoctl génère une demande de contrôle d’appareil pour une cible d’E/S, mais n’envoie pas la requête.
Syntaxe
NTSTATUS WdfIoTargetFormatRequestForIoctl(
[in] WDFIOTARGET IoTarget,
[in] WDFREQUEST Request,
[in] ULONG IoctlCode,
[in, optional] WDFMEMORY InputBuffer,
[in, optional] PWDFMEMORY_OFFSET InputBufferOffset,
[in, optional] WDFMEMORY OutputBuffer,
[in, optional] PWDFMEMORY_OFFSET OutputBufferOffset
);
Paramètres
[in] IoTarget
Handle vers un objet cible d’E/S local ou distant qui a été obtenu à partir d’un appel précédent à WdfDeviceGetIoTarget ou WdfIoTargetCreate, ou à partir d’une méthode qu’une cible d’E/S spécialisée fournit.
[in] Request
Handle pour un objet de requête d’infrastructure. Pour plus d'informations, consultez la section Notes qui suit.
[in] IoctlCode
Code de contrôle d’E/S (IOCTL) pris en charge par la cible d’E/S.
[in, optional] InputBuffer
Handle pour un objet de mémoire d’infrastructure. Cet objet représente une mémoire tampon qui contient les données qui seront envoyées à la cible d’E/S. Pour plus d'informations, consultez la section Notes qui suit.
[in, optional] InputBufferOffset
Pointeur vers une structure de WDFMEMORY_OFFSET allouée par l’appelant qui fournit des valeurs facultatives de décalage d’octets et de longueur. L’infrastructure utilise ces valeurs pour déterminer l’adresse et la longueur de début, dans la mémoire tampon d’entrée, pour le transfert de données. Si ce pointeur a la valeur NULL, le transfert de données commence au début de la mémoire tampon d’entrée, et la taille du transfert correspond à la taille de la mémoire tampon.
[in, optional] OutputBuffer
Handle pour un objet de mémoire d’infrastructure. Cet objet représente une mémoire tampon qui recevra des données de la cible d’E/S. Pour plus d'informations, consultez la section Notes qui suit.
[in, optional] OutputBufferOffset
Pointeur vers une structure de WDFMEMORY_OFFSET allouée par l’appelant qui fournit des valeurs facultatives de décalage d’octets et de longueur. Le framework utilise ces valeurs pour déterminer l’adresse et la longueur de début, dans la mémoire tampon de sortie, pour le transfert de données. Si ce pointeur a la valeur NULL, le transfert de données commence au début de la mémoire tampon de sortie, et la taille du transfert correspond à la taille de la mémoire tampon.
Valeur retournée
WdfIoTargetFormatRequestForIoctl retourne STATUS_SUCCESS si l’opération réussit. Sinon, cette méthode peut retourner l’une des valeurs suivantes :
Code de retour | Description |
---|---|
|
Un paramètre non valide a été détecté. |
|
La longueur de transfert était supérieure à la longueur de la mémoire tampon, ou la demande d’E/S était déjà mise en file d’attente vers une cible d’E/S. |
|
L’infrastructure n’a pas pu allouer de ressources système (généralement de la mémoire). |
|
Le paquet de demandes d’E/S (IRP) que représente le paramètre Request ne fournit pas suffisamment de structures IO_STACK_LOCATION pour permettre au pilote de transférer la requête. |
Cette méthode peut également retourner d’autres valeurs NTSTATUS.
Un bogue case activée se produit si le pilote fournit un handle d’objet non valide.
Remarques
Utilisez la méthode WdfIoTargetFormatRequestForIoctl , suivie de la méthode WdfRequestSend , pour envoyer des demandes de contrôle d’appareil de manière synchrone ou asynchrone. Vous pouvez également utiliser la méthode WdfIoTargetSendIoctlSynchronously pour envoyer des demandes de contrôle d’appareil de manière synchrone.
Pour plus d’informations sur les demandes de contrôle d’appareil, consultez Utilisation des codes de contrôle d’E/S.
Vous pouvez transférer une demande de contrôle d’appareil que votre pilote a reçue dans une file d’attente d’E/S, ou vous pouvez créer et envoyer une nouvelle demande. Dans les deux cas, l’infrastructure nécessite un objet de requête et un espace de mémoire tampon.
Pour transférer une demande de contrôle de périphérique que votre pilote a reçue dans une file d’attente d’E/S :
- Spécifiez le handle de la requête reçue pour le paramètre Request de la méthode WdfIoTargetFormatRequestForIoctl.
-
Utilisez la mémoire tampon d’entrée de la requête reçue pour le paramètre InputBuffer de la méthode WdfIoTargetFormatRequestForIoctl.
Le pilote doit appeler WdfRequestRetrieveInputMemory pour obtenir un handle pour un objet de mémoire d’infrastructure qui représente la mémoire tampon d’entrée de la requête, et il doit utiliser ce handle comme valeur pour InputBuffer.
-
Utilisez la mémoire tampon de sortie de la requête reçue pour le paramètre OutputBuffer de la méthode WdfIoTargetFormatRequestForIoctl.
Le pilote doit appeler WdfRequestRetrieveOutputMemory pour obtenir un handle pour la mémoire tampon de sortie de la requête, et il doit utiliser ce handle comme valeur pour OutputBuffer.
Les pilotes divisent souvent les demandes d’E/S reçues en demandes plus petites qu’ils envoient à une cible d’E/S, de sorte que votre pilote peut créer de nouvelles demandes.
Pour créer une demande d’E/S :
-
Créez un objet de requête et fournissez son handle pour le paramètre Request de la méthode WdfIoTargetFormatRequestForIoctl.
Appelez WdfRequestCreate pour préallouer un ou plusieurs objets de requête. Vous pouvez réutiliser ces objets de requête en appelant WdfRequestReuse. La fonction de rappel EvtDriverDeviceAdd de votre pilote peut préallouer des objets de requête pour un appareil.
-
Fournissez de l’espace tampon et fournissez le handle de la mémoire tampon pour les paramètres InputBuffer et OutputBuffer de la méthode WdfIogetFormatRequestForIoctl.
Votre pilote doit spécifier cet espace de mémoire tampon en tant que handles WDFMEMORY pour la mémoire gérée par l’infrastructure. Votre pilote peut effectuer l’une des opérations suivantes :
- Appelez WdfMemoryCreate ou WdfMemoryCreatePreallocated pour créer une mémoire tampon, si vous souhaitez que le pilote passe une nouvelle mémoire tampon à la cible d’E/S.
- Appelez WdfRequestRetrieveInputMemory ou WdfRequestRetrieveOutputMemory pour obtenir un handle à l’objet mémoire qui représente la mémoire tampon d’une requête d’E/S reçue, si vous souhaitez que le pilote passe le contenu de cette mémoire tampon à la cible d’E/S.
Les appels multiples à WdfIoTargetFormatRequestForIoctl qui utilisent la même requête ne provoquent pas d’allocations de ressources supplémentaires. Par conséquent, pour réduire le risque que WdfRequestCreate retourne STATUS_INSUFFICIENT_RESOURCES, la fonction de rappel EvtDriverDeviceAdd de votre pilote peut appeler WdfRequestCreate pour préallouer un ou plusieurs objets de requête pour un appareil. Le pilote peut ensuite réutiliser (appeler WdfRequestReuse), reformat (appeler WdfIoTargetFormatRequestForIoctl) et renvoyer (appeler WdfRequestSend) chaque objet de requête sans risquer un STATUS_INSUFFICIENT_RESOURCES valeur de retour d’un appel ultérieur à WdfRequestCreate. Tous les appels suivants à WdfIoTargetFormatRequestForIoctl pour l’objet de requête réutilisé retournent STATUS_SUCCESS, si les valeurs de paramètre ne changent pas. (Si le pilote n’appelle pas la même méthode de mise en forme des demandes à chaque fois, des ressources supplémentaires peuvent être allouées. En outre, si le code de contrôle d’E/S spécifie un type de transfert de METHOD_BUFFERED, l’infrastructure doit allouer une mémoire tampon système pour chaque requête et cette allocation peut échouer en raison de ressources mémoire insuffisantes.)
Pour plus d’informations sur l’obtention d’informations status après la fin d’une demande d’E/S, consultez Obtention d’informations d’achèvement.
Pour plus d’informations sur WdfIoTargetFormatRequestForIoctl, consultez Envoi de demandes d’E/S à des cibles d’E/S générales.
Pour plus d’informations sur les cibles d’E/S, consultez Utilisation de cibles d’E/S.
Exemples
Le code suivant réutilise un objet de requête préalloué et des objets mémoire préalloués. L’exemple affecte des mémoires tampons d’entrée et de sortie aux objets mémoire, met en forme l’objet de requête, inscrit une fonction de rappel CompletionRoutine et envoie la demande à une cible d’E/S.
NTSTATUS
NICSendOidRequestToTargetAsync(
IN WDFIOTARGET IoTarget,
IN WDFREQUEST Request,
IN PFILE_OBJECT FileObject,
IN ULONG IoctlControlCode,
IN OUT PVOID InputBuffer,
IN ULONG InputBufferLength,
IN OUT PVOID OutputBuffer,
IN ULONG OutputBufferLength,
OUT PULONG BytesReadOrWritten
)
{
NTSTATUS status;
PREQUEST_CONTEXT reqContext;
WDF_REQUEST_REUSE_PARAMS params;
WDFMEMORY inputMem, outputMem;
WDF_REQUEST_REUSE_PARAMS_INIT(
¶ms,
WDF_REQUEST_REUSE_NO_FLAGS,
STATUS_SUCCESS
);
status = WdfRequestReuse(Request, ¶ms);
if (!NT_SUCCESS(status)){
return status;
}
reqContext = GetRequestContext(Request);
inputMem = outputMem = NULL;
if (InputBuffer != NULL) {
status = WdfMemoryAssignBuffer(
reqContext->InputMemory,
InputBuffer,
InputBufferLength
);
if (!NT_SUCCESS(status)) {
return status;
}
inputMem = reqContext->InputMemory;
}
if (OutputBuffer != NULL) {
status = WdfMemoryAssignBuffer(
reqContext->OutputMemory,
OutputBuffer,
OutputBufferLength
);
if (!NT_SUCCESS(status)) {
return status;
}
outputMem = reqContext->OutputMemory;
}
status = WdfIoTargetFormatRequestForIoctl(
IoTarget,
Request,
IoctlControlCode,
inputMem,
NULL,
outputMem,
NULL
);
if (!NT_SUCCESS(status)) {
return status;
}
WdfRequestSetCompletionRoutine(
Request,
NICSendOidRequestToTargetAsyncCompletionRoutine,
BytesReadOrWritten
);
if (WdfRequestSend(
Request,
IoTarget,
WDF_NO_SEND_OPTIONS
) == FALSE) {
status = WdfRequestGetStatus(Request);
}
return status;
}
Configuration requise
Condition requise | Valeur |
---|---|
Plateforme cible | Universal |
Version KMDF minimale | 1.0 |
Version UMDF minimale | 2.0 |
En-tête | wdfiotarget.h (inclure Wdf.h) |
Bibliothèque | Wdf01000.sys (KMDF) ; WUDFx02000.dll (UMDF) |
IRQL | <=DISPATCH_LEVEL |
Règles de conformité DDI | DriverCreate(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf), RequestFormattedValid(kmdf), RequestSendAndForgetNoFormatting(kmdf), RequestSendAndForgetNoFormatting2(kmdf) |
Voir aussi
WdfIoTargetFormatRequestForInternalIoctl
WdfIoTargetSendIoctlSynchronously