WdfIoTargetSendWriteSynchronously, fonction (wdfiotarget.h)

[S’applique à KMDF et UMDF]

La méthode WdfIoTargetSendWriteSynchronously génère une demande d’écriture et l’envoie de manière synchrone à une cible d’E/S.

Syntaxe

NTSTATUS WdfIoTargetSendWriteSynchronously(
  [in]            WDFIOTARGET               IoTarget,
  [in, optional]  WDFREQUEST                Request,
  [in, optional]  PWDF_MEMORY_DESCRIPTOR    InputBuffer,
  [in, optional]  PLONGLONG                 DeviceOffset,
  [in, optional]  PWDF_REQUEST_SEND_OPTIONS RequestOptions,
  [out, optional] PULONG_PTR                BytesWritten
);

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, optional] Request

Handle d’un objet de requête d’infrastructure. Ce paramètre est facultatif et peut être NULL. Pour plus d’informations sur ce paramètre, consultez la section Remarques suivante.

[in, optional] InputBuffer

Pointeur vers une structure de WDF_MEMORY_DESCRIPTOR allouée à l’appelant qui décrit la mémoire tampon qui contient les données qui seront écrites sur l’appareil. Ce paramètre est facultatif et peut être NULL. Pour plus d’informations sur ce paramètre, consultez la section Remarques suivante.

[in, optional] DeviceOffset

Pointeur vers un emplacement qui spécifie un décalage de départ pour le transfert. La cible d’E/S (c’est-à-dire le pilote inférieur suivant) définit comment utiliser cette valeur. Par exemple, les pilotes de la pile de pilotes d’un disque peuvent spécifier un décalage par rapport au début du disque. La cible d’E/S obtient ces informations dans le membre Parameters.Write.DeviceOffset de la structure WDF_REQUEST_PARAMETERS de la demande. Ce pointeur est facultatif. La plupart des pilotes définissent ce pointeur sur NULL.

[in, optional] RequestOptions

Pointeur vers une structure de WDF_REQUEST_SEND_OPTIONS allouée par l’appelant qui spécifie les options de la demande. Ce pointeur est facultatif et peut avoir la valeur NULL. Pour plus d’informations sur ce paramètre, consultez la section Remarques suivante.

[out, optional] BytesWritten

Pointeur vers un emplacement qui reçoit le nombre d’octets écrits, si l’opération réussit. Ce pointeur est facultatif et peut avoir la valeur NULL.

Valeur retournée

Si l’opération réussit, WdfIoTargetSendWriteSynchronously retourne une fois la demande d’E/S terminée, et la valeur de retour correspond à la valeur d’achèvement de la demande status. Sinon, cette méthode peut retourner l’une des valeurs suivantes :

Code de retour Description
STATUS_INVALID_PARAMETER
Un paramètre non valide a été détecté.
STATUS_INFO_LENGTH_MISMATCH
La taille de la structure WDF_REQUEST_SEND_OPTIONS vers laquelle le paramètre RequestOptions pointait était incorrecte.
STATUS_INVALID_DEVICE_REQUEST
La demande d’E/S était déjà mise en file d’attente vers une cible d’E/S.
STATUS_INSUFFICIENT_RESOURCES
L’infrastructure n’a pas pu allouer de ressources système (généralement de la mémoire).
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 demande 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 WdfIoTargetSendWriteSynchronously pour envoyer des demandes d’écriture de manière synchrone. Pour envoyer des demandes d’écriture de manière asynchrone, utilisez la méthode WdfIoTargetFormatRequestForWrite , suivie de la méthode WdfRequestSend .

WdfIoTargetSendWriteSynchronously ne retourne pas tant que la demande n’est pas terminée, sauf si le pilote fournit une valeur de délai d’attente dans la structure WDF_REQUEST_SEND_OPTIONS du 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 que votre pilote a reçue dans une file d’E/S :

  1. Spécifiez le handle de la requête reçue pour le paramètre Request de la méthode WdfIoTargetSendWriteSynchronously.
  2. Utilisez la mémoire tampon d’entrée de la demande reçue pour le paramètre InputBuffer de la méthode WdfIoTargetSendWriteSynchronously.

    Le pilote doit appeler WdfRequestRetrieveInputMemory pour obtenir un handle sur un objet de mémoire framework qui représente la mémoire tampon d’entrée de la requête, puis placer ce handle dans la structure WDF_MEMORY_DESCRIPTOR que le pilote fournit pour le paramètre InputBuffer .

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, afin que votre pilote puisse en créer de nouvelles.

Pour créer une demande d’E/S :

  1. Fournissez un handle de requête NULL pour le paramètre Request de la méthode WdfIoTargetSendWriteSynchronously, 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 de requête non NULL ou NULL. 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 InputBuffer de la méthode WdfIoTargetSendWriteSynchronously.

    Votre pilote peut spécifier cet espace tampon en tant que mémoire tampon allouée localement, en tant que handle WDFMEMORY ou en tant que liste de descripteurs de mémoire (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 d’accès aux mémoires tampons de données de la cible d’E/S.

    Les techniques suivantes pour spécifier l’espace tampon sont disponibles :

    • Fournissez une mémoire tampon locale.

      Étant donné que WdfIoTargetSendWriteSynchronously 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));
      
    • Fournissez 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 WdfRequestRetrieveInputMemory pour obtenir un handle à un objet de mémoire framework qui représente la mémoire tampon d’entrée d’une demande d’E/S reçue, si vous souhaitez que le pilote transmette 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 demande envoyée par WdfIoTargetSendWriteSynchronously à la cible d’E/S n’a pas été supprimée, réutilisée ou reformatée. (WdfIoTargetSendWriteSynchronously incrémente le nombre de références de l’objet mémoire. La suppression, la réutilisation ou le reformatage d’un objet de requête décrémente le nombre de références de l’objet mémoire.)

    • Fournissez une MDL.

      Les pilotes peuvent obtenir le MDL associé à une demande d’E/S reçue en appelant WdfRequestRetrieveInputWdmMdl.

Certaines cibles d’E/S acceptent les demandes d’écriture qui ont une mémoire tampon de longueur nulle. Pour ces cibles d’E/S, votre pilote peut spécifier NULL pour le paramètre InputBuffer .

Pour plus d’informations sur l’obtention d’informations status après la fin d’une demande d’E/S, consultez Obtention des informations d’achèvement.

Pour plus d’informations sur WdfIoTargetSendWriteSynchronously, 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 des cibles d’E/S.

Exemples

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

WDF_MEMORY_DESCRIPTOR  MemoryDescriptor;
WDFMEMORY  MemoryHandle = NULL;
ULONG_PTR  bytesWritten = NULL;

status = WdfMemoryCreate(
                         NULL,
                         NonPagedPool,
                         POOL_TAG,
                         MY_BUFFER_SIZE,
                         &MemoryHandle,
                         NULL
                         );
WDF_MEMORY_DESCRIPTOR_INIT_HANDLE(
                                  &MemoryDescriptor,
                                  MemoryHandle,
                                  NULL
                                  );
status = WdfIoTargetSendWriteSynchronously(
                                          ioTarget,
                                          NULL,
                                          &MemoryDescriptor,
                                          NULL,
                                          NULL,
                                          &bytesWritten
                                          );
 

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 <=PASSIVE_LEVEL
Règles de conformité DDI DeferredRequestCompleted(kmdf), DriverCreate(kmdf), InternalIoctlReqs(kmdf), IoctlReqs(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf), ReadReqs(kmdf), RequestCompleted(kmdf), RequestCompletedLocal(kmdf), SyncReqSend(kmdf)

Voir aussi

EvtDriverDeviceAdd

WDF_MEMORY_DESCRIPTOR

WDF_MEMORY_DESCRIPTOR_INIT_HANDLE

WDF_REQUEST_PARAMETERS

WDF_REQUEST_SEND_OPTIONS

WdfDeviceGetIoTarget

WdfIoTargetCreate

WdfIoTargetFormatRequestForWrite

WdfMemoryCreate

WdfMemoryCreatePreallocated

WdfRequestCancelSentRequest

WdfRequestCreate

WdfRequestRetrieveInputMemory

WdfRequestRetrieveInputWdmMdl

WdfRequestReuse

WdfRequestSend