Partager via


Envoi de demandes d’E/S de manière synchrone

Le tableau suivant répertorie les méthodes d’objet cible d’E/S que votre pilote peut appeler pour envoyer des demandes d’E/S de manière synchrone à une cible d’E/S. Pour plus d’informations sur l’utilisation de ces méthodes, consultez les pages de référence des méthodes.

Méthode Objectif

WdfIoTargetSendReadSynchronously

Envoie une demande de lecture

WdfIoTargetSendWriteSynchronously

Envoie une demande d’écriture

WdfIoTargetSendIoctlSynchronously

Envoie une demande de contrôle d’appareil

WdfIoTargetSendInternalIoctlSynchronously

Envoie une demande de contrôle d’appareil interne

WdfIoTargetSendInternalIoctlOthersSynchronously

Envoie une demande de contrôle d’appareil interne non standard

Vous pouvez également envoyer des requêtes de manière synchrone en appelant WdfRequestSend, mais vous devez d’abord mettre en forme la demande en suivant les règles décrites dans Envoi asynchrone de demandes d’E/S.

L’envoi de demandes d’E/S à une cible d’E/S de manière synchrone est plus simple à programmer que l’envoi de demandes d’E/S de manière asynchrone. Toutefois, vous devez utiliser les instructions suivantes pour vous aider à déterminer si les E/S synchrones sont appropriées pour votre pilote :

  • Vous pouvez utiliser des E/S synchrones si votre pilote n’envoie pas beaucoup de demandes d’E/S et si les performances du système ou des appareils ne sont pas réduites, car votre pilote attend que chaque demande d’E/S se termine.

  • Si votre pilote doit gérer de nombreuses demandes d’E/S dans de courtes périodes, vous ne pouvez probablement pas autoriser votre pilote à attendre que chaque requête se termine avant d’envoyer la requête suivante. Dans le cas contraire, votre pilote risque de perdre des données ou de réduire les performances de son appareil (et, éventuellement, de l’ensemble du système). Dans ce cas, les E/S asynchrones peuvent être le meilleur choix.

  • Les E/S synchrones sont utiles pour gérer les opérations qui doivent démarrer et se terminer sans activité simultanée supplémentaire. Ces opérations peuvent inclure la réinitialisation d’un canal USB ou des registres de périphériques de lecture.

  • La plupart du temps, votre pilote doit spécifier une valeur de délai d’attente lorsqu’il appelle une méthode d’objet qui envoie une requête d’E/S de manière synchrone. Si votre pilote ne spécifie pas de valeur de délai d’attente et si un périphérique ou un pilote de niveau inférieur ne répond pas, votre pilote peut se bloquer. Par conséquent, l’utilisateur peut rencontrer une application qui ne répond pas. En outre, d’autres pilotes peuvent ne pas être en mesure d’obtenir des ressources système, telles que des éléments de travail, si votre pilote ne les libère pas.

  • Si les pilotes situés au-dessus et en dessous du vôtre dans la pile nécessitent des opérations de manière synchrone, votre pilote doit utiliser des E/S synchrones. Par conséquent, vous devez en savoir plus sur les exigences des autres pilotes qui peuvent exister dans la pile de pilotes.

L’exemple suivant montre comment envoyer une demande de contrôle d’E/S synchrone (IOCTL) :

NTSTATUS                status;
    WDF_MEMORY_DESCRIPTOR   inputDesc, outputDesc;
    PWDF_MEMORY_DESCRIPTOR  pInputDesc = NULL, pOutputDesc = NULL;
    ULONG_PTR               bytesReturned;

    UNREFERENCED_PARAMETER(FileObject);

    if (InputBuffer) {
        WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&inputDesc,
                                    InputBuffer,
                                    InputBufferLength);
        pInputDesc = &inputDesc;
    }

    if (OutputBuffer) {
        WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&outputDesc,
                                    OutputBuffer,
                                    OutputBufferLength);
        pOutputDesc = &outputDesc;
    }

    status = WdfIoTargetSendIoctlSynchronously(
                        IoTarget,
                        WDF_NO_HANDLE, // Request
                        IoctlControlCode,
                        pInputDesc,
                        pOutputDesc,
                        NULL, // PWDF_REQUEST_SEND_OPTIONS
                        &bytesReturned);
    if (!NT_SUCCESS(status)) {
         DEBUGP(MP_ERROR,
        ("WdfIoTargetSendIoctlSynchronously failed 0x%x\n",
          status));
    }

    *BytesReadOrWritten = (ULONG)bytesReturned;