Synchrones Senden von E/A-Anforderungen

In der folgenden Tabelle sind die E/A-Zielobjektmethoden aufgeführt, die Ihr Treiber aufrufen kann, um E/A-Anforderungen synchron an ein E/A-Ziel zu senden. Ausführliche Informationen zur Verwendung dieser Methoden finden Sie auf den Referenzseiten der Methoden.

Methode Zweck

WdfIoTargetSendReadSynchronous

Sendet eine Leseanforderung

WdfIoTargetSendWriteSynchronously

Sendet eine Schreibanforderung

WdfIoTargetSendIoctlSynchronly

Sendet eine Gerätesteuerungsanforderung

WdfIoTargetSendInternalIoctlSynchronly

Sendet eine interne Gerätesteuerungsanforderung

WdfIoTargetSendInternalIoctlOthersSynchronly

Sendet eine nicht standardmäßige interne Gerätesteuerungsanforderung

Sie können Anforderungen auch synchron senden, indem Sie WdfRequestSend aufrufen, aber Sie müssen die Anforderung zuerst formatieren, indem Sie die Regeln beachten, die unter Asynchrones Senden von E/A-Anforderungen beschrieben sind.

Das synchrone Senden von E/A-Anforderungen an ein E/A-Ziel ist einfacher zu programmieren als das asynchrone Senden von E/A-Anforderungen. Sie sollten jedoch die folgenden Richtlinien verwenden, um zu entscheiden, ob synchrone E/A für Ihren Treiber geeignet ist:

  • Sie können synchrone E/A-Vorgänge verwenden, wenn Ihr Treiber nicht viele E/A-Anforderungen sendet und wenn die System- oder Geräteleistung nicht beeinträchtigt ist, da Ihr Treiber auf den Abschluss jeder E/A-Anforderung wartet.

  • Wenn Ihr Treiber viele E/A-Anforderungen in kurzer Zeit verarbeiten muss, können Sie wahrscheinlich nicht zulassen, dass Ihr Treiber auf die Ausführung jeder Anforderung wartet, bevor sie die nächste Anforderung sendet. Andernfalls kann ihr Treiber Daten verlieren oder die Leistung des Geräts (und möglicherweise des gesamten Systems) beeinträchtigen. In solchen Fällen kann asynchrone E/A die bessere Wahl sein.

  • Synchrone E/A-Vorgänge sind nützlich für die Behandlung von Vorgängen, die ohne zusätzliche gleichzeitige Aktivität gestartet und beendet werden müssen. Solche Vorgänge können das Zurücksetzen einer USB-Pipe oder das Lesen von Geräteregistern umfassen.

  • In den meisten Fällen sollte Ihr Treiber einen Timeoutwert angeben, wenn er eine Objektmethode aufruft, die eine E/A-Anforderung synchron sendet. Wenn Ihr Treiber keinen Timeoutwert angibt und ein Gerät oder ein Treiber auf niedrigerer Ebene nicht reagiert, kann Ihr Treiber angehalten werden. Infolgedessen kann der Benutzer eine nicht reagierende Anwendung erleben. Darüber hinaus können andere Treiber möglicherweise keine Systemressourcen abrufen, z. B. Arbeitselemente, wenn Ihr Treiber diese nicht freigibt.

  • Wenn Treiber über und unter Ihrem Stapel Vorgänge synchron ausführen müssen, sollte Ihr Treiber synchronE E/A verwenden. Daher sollten Sie sich mit den Anforderungen anderer Treiber vertraut machen, die möglicherweise im Treiberstapel vorhanden sind.

Im folgenden Beispiel wird gezeigt, wie sie eine anforderung eines synchronen E/A-Steuerelements (IOCTL) senden:

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;