WdfUsbTargetPipeReadSynchronously, fonction (wdfusb.h)

[S’applique à KMDF et UMDF]

La méthode WdfUsbTargetPipeReadSynchronously génère une demande de lecture et l’envoie de manière synchrone à un canal d’entrée USB spécifié.

Syntaxe

NTSTATUS WdfUsbTargetPipeReadSynchronously(
  [in]            WDFUSBPIPE                Pipe,
  [in, optional]  WDFREQUEST                Request,
  [in, optional]  PWDF_REQUEST_SEND_OPTIONS RequestOptions,
  [in, optional]  PWDF_MEMORY_DESCRIPTOR    MemoryDescriptor,
  [out, optional] PULONG                    BytesRead
);

Paramètres

[in] Pipe

Handle vers un objet de canal d’infrastructure obtenu en appelant WdfUsbInterfaceGetConfiguredPipe.

[in, optional] Request

Handle pour un objet de requête d’infrastructure. Ce paramètre est facultatif et peut être NULL. Pour plus d'informations, consultez la section Notes qui suit.

[in, optional] RequestOptions

Pointeur vers une structure de WDF_REQUEST_SEND_OPTIONS allouée par l’appelant qui spécifie des options pour la demande. Ce pointeur est facultatif et peut être NULL. Pour plus d'informations, consultez la section Notes qui suit.

[in, optional] MemoryDescriptor

Pointeur vers une structure de WDF_MEMORY_DESCRIPTOR allouée par l’appelant qui décrit la mémoire tampon qui recevra des données de l’appareil. La taille de la mémoire tampon doit être un multiple de la taille maximale des paquets du canal, sauf si le pilote a appelé WdfUsbTargetPipeSetNoMaximumPacketSizeCheck. Pour plus d’informations sur cette mémoire tampon, consultez la section Remarques suivante.

[out, optional] BytesRead

Pointeur vers un emplacement qui reçoit le nombre d’octets lus, si l’opération réussit. Ce paramètre est facultatif et peut être NULL.

Valeur retournée

WdfUsbTargetPipeReadSynchronously retourne la valeur d’achèvement status de la cible d’E/S si l’opération réussit. Sinon, cette méthode peut retourner l’une des valeurs suivantes :

Code de retour Description
STATUS_INFO_LENGTH_MISMATCH
La taille de la structure WDF_REQUEST_SEND_OPTIONS pointée par RequestOptions était incorrecte.
STATUS_INVALID_PARAMETER
Un paramètre non valide a été détecté.
STATUS_INSUFFICIENT_RESOURCES
La mémoire disponible était insuffisante.
STATUS_INVALID_DEVICE_REQUEST
L’IRQL de l’appelant n’était pas PASSIVE_LEVEL, un descripteur de mémoire non valide a été spécifié, le type du canal n’était pas valide, le sens de transfert n’était pas valide ou la demande d’E/S spécifiée était déjà mise en file d’attente vers une cible d’E/S.
STATUS_INVALID_BUFFER_SIZE
La taille de la mémoire tampon n’était pas un multiple de la taille maximale des paquets du canal.
STATUS_IO_TIMEOUT
Le pilote a fourni une valeur de délai d’attente et la demande n’a pas été effectuée dans le délai imparti.
STATUS_REQUEST_NOT_ACCEPTED
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 WdfUsbTargetPipeReadSynchronously pour envoyer des demandes de lecture de manière synchrone. Pour envoyer des demandes de lecture de manière asynchrone, utilisez WdfUsbTargetPipeFormatRequestForRead, suivi de WdfRequestSend.

Le canal spécifié par le paramètre Pipe doit être un canal d’entrée, et le type du canal doit être WdfUsbPipeTypeBulk ou WdfUsbPipeTypeInterrupt.

La méthode WdfUsbTargetPipeReadSynchronously ne retourne pas tant que la requête n’est pas terminée, sauf si le pilote fournit une valeur de délai d’attente dans la structure WDF_REQUEST_SEND_OPTIONS vers laquelle pointe le paramètre RequestOptions , ou si une erreur est détectée.

Vous pouvez transférer une demande d’E/S 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 d’E/S reçue par votre pilote dans une file d’attente d’E/S :

  1. Spécifiez le handle de la requête reçue pour le paramètre Request .
  2. Utilisez la mémoire tampon de sortie de la requête reçue pour le paramètre MemoryDescriptor de la méthode WdfUsbTargetPipeReadSynchronously.

    Le pilote doit appeler WdfRequestRetrieveOutputMemory pour obtenir un handle pour un objet de mémoire d’infrastructure qui représente la mémoire tampon de sortie de la requête, puis placer ce handle dans la structure WDF_MEMORY_DESCRIPTOR vers laquelle pointe MemoryDescriptor .

Pour plus d’informations sur le transfert d’une demande d’E/S, consultez Transfert de demandes d’E/S.

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 :

  1. Fournissez un handle de requête NULL dans le paramètre Request de la méthode WdfUsbTargetPipeReadSynchronously, ou créez un objet de requête et fournissez son handle :
    • Si vous fournissez un handle de requête NULL , l’infrastructure utilise un objet de requête interne. Cette technique est simple à utiliser, mais le pilote ne peut pas annuler la demande.
    • Si vous appelez WdfRequestCreate pour créer un ou plusieurs objets de requête, vous pouvez réutiliser ces objets de requête en appelant WdfRequestReuse. Cette technique permet à la fonction de rappel EvtDriverDeviceAdd de votre pilote de préallouer des objets de requête pour un appareil. En outre, un autre thread de pilote peut appeler WdfRequestCancelSentRequest pour annuler la demande, si nécessaire.

    Votre pilote peut spécifier un paramètre RequestOptions non NULL, que le pilote fournisse un paramètre non NULL ou un paramètre de requêteNULL. Vous pouvez, par exemple, utiliser le paramètre RequestOptions pour spécifier une valeur de délai d’attente.

  2. Fournissez de l’espace tampon pour le paramètre MemoryDescriptor de la méthode WdfUsbTargetPipeReadSynchronously.

    Votre pilote peut spécifier cet espace de mémoire tampon en tant que mémoire tampon allouée localement, en tant que handle WDFMEMORY ou en tant que MDL. Vous pouvez utiliser la méthode la plus pratique.

    Si nécessaire, l’infrastructure convertit la description de la mémoire tampon en une description correcte pour la méthode de la cible d’E/S pour accéder aux mémoires tampons de données.

    Les techniques suivantes sont disponibles :

    • Fournir une mémoire tampon locale

      Étant donné que WdfUsbTargetPipeReadSynchronously gère les demandes d’E/S de manière synchrone, le pilote peut créer des mémoires tampons de requête qui sont locales à la routine appelante, comme le montre l’exemple de code suivant.

      WDF_MEMORY_DESCRIPTOR  memoryDescriptor;
      MY_BUFFER_TYPE  myBuffer;
      WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&memoryDescriptor,
                                        (PVOID) &myBuffer,
                                        sizeof(myBuffer));
      
    • Fournir un handle WDFMEMORY

      Appelez WdfMemoryCreate ou WdfMemoryCreatePreallocated pour obtenir un handle pour la mémoire gérée par l’infrastructure, comme le montre l’exemple de code suivant.

      WDF_MEMORY_DESCRIPTOR  memoryDescriptor;
      WDFMEMORY  memoryHandle = NULL;
      status = WdfMemoryCreate(NULL,
                               NonPagedPool,
                               POOL_TAG,
                               MY_BUFFER_SIZE,
                               &memoryHandle,
                               NULL);
      WDF_MEMORY_DESCRIPTOR_INIT_HANDLE(&memoryDescriptor,
                                        memoryHandle,
                                        NULL);
      

      Le pilote peut également appeler WdfRequestRetrieveOutputMemory pour obtenir un handle pour un objet de mémoire d’infrastructure qui représente la mémoire tampon de sortie 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. Le pilote ne doit pas terminer la demande d’E/S reçue tant que la nouvelle requête que WdfUsbTargetPipeReadSynchronously envoie à la cible d’E/S n’a pas été supprimée, réutilisée ou reformatée. (WdfUsbTargetPipeReadSynchronously incrémente le nombre de références de l’objet mémoire. La suppression, la réutilisation ou la reformatage d’un objet de requête décrémentent le nombre de références de l’objet mémoire.)

    • Fournir un MDL

      Les pilotes peuvent obtenir la mdL associée à une demande d’E/S reçue en appelant WdfRequestRetrieveOutputWdmMdl.

L’infrastructure définit l’indicateur USBD_SHORT_TRANSFER_OK dans son URB interne. La définition de cet indicateur permet au dernier paquet d’un transfert de données d’être inférieur à la taille maximale du paquet.

Un pilote ne peut pas appeler WdfUsbTargetPipeReadSynchronously s’il a configuré un lecteur continu pour le canal.

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 la méthode WdfUsbTargetPipeReadSynchronously et les cibles d’E/S USB, consultez Cibles d’E/S USB.

Exemples

L’exemple de code suivant crée un objet de mémoire d’infrastructure, initialise une structure WDF_MEMORY_DESCRIPTOR et transmet la structure à WdfUsbTargetPipeReadSynchronously. Cet exemple spécifie NULL pour le handle d’objet de requête, de sorte que l’infrastructure crée un objet de requête pour la cible d’E/S.

WDFMEMORY  wdfMemory;
WDF_MEMORY_DESCRIPTOR  readBufDesc;
ULONG  BytesRead;

status = WdfMemoryCreate(
                         WDF_NO_OBJECT_ATTRIBUTES,
                         NonPagedPool,
                         0,
                         readSize,
                         &wdfMemory,
                         NULL
                         );
if (!NT_SUCCESS(status)){
    return ;
}

buffer = WdfMemoryGetBuffer(
                            wdfMemory,
                            NULL
                            );

WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(
                                  &readBufDesc,
                                  buffer,
                                  readSize
                                  );

status = WdfUsbTargetPipeReadSynchronously(
                                           Pipe,
                                           NULL,
                                           NULL,
                                           &readBufDesc,
                                           &BytesRead
                                           );

Configuration requise

Condition requise Valeur
Plateforme cible Universal
Version KMDF minimale 1.0
Version UMDF minimale 2.0
En-tête wdfusb.h (inclure Wdfusb.h)
Bibliothèque Wdf01000.sys (KMDF) ; WUDFx02000.dll (UMDF)
IRQL PASSIVE_LEVEL
Règles de conformité DDI DriverCreate(kmdf), InternalIoctlReqs(kmdf), IoctlReqs(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf), SyncReqSend(kmdf), UsbKmdfIrql(kmdf), UsbKmdfIrql2(kmdf), UsbKmdfIrqlExplicit(kmdf), WriteReqs(kmdf)

Voir aussi

WDF_MEMORY_DESCRIPTOR_INIT_BUFFER

WdfMemoryCreate

WdfUsbTargetPipeGetInformation