Freigeben über


WdfRequestProbeAndLockUserBufferForRead-Funktion (wdfrequest.h)

[Gilt nur für KMDF]

Die WdfRequestProbeAndLockUserBufferForRead-Methode überprüft, ob der Benutzermoduspuffer einer E/A-Anforderung lesbar ist, und sperrt dann die physischen Speicherseiten des Puffers, damit Treiber im Treiberstapel den Puffer lesen können.

Syntax

NTSTATUS WdfRequestProbeAndLockUserBufferForRead(
  [in]  WDFREQUEST Request,
  [in]  PVOID      Buffer,
  [in]  size_t     Length,
  [out] WDFMEMORY  *MemoryObject
);

Parameter

[in] Request

Ein Handle für ein Frameworkanforderungsobjekt.

[in] Buffer

Ein Zeiger auf den Eingabepuffer der Anforderung. Weitere Informationen finden Sie im folgenden Abschnitt "Hinweise".

[in] Length

Die Länge des Eingabepuffers der Anforderung in Bytes.

[out] MemoryObject

Ein Zeiger auf einen Speicherort, der ein Handle auf ein Frameworkspeicherobjekt empfängt, das den Benutzereingabepuffer darstellt.

Rückgabewert

WdfRequestProbeAndLockUserBufferForRead gibt STATUS_SUCCESS zurück, wenn der Vorgang erfolgreich ist. Andernfalls gibt diese Methode möglicherweise einen der folgenden Werte zurück:

Rückgabecode Beschreibung
STATUS_INVALID_PARAMETER
Ein Eingabeparameter ist ungültig.
STATUS_INVALID_USER_BUFFER
Der Length-Parameter ist 0.
STATUS_INVALID_DEVICE_REQUEST
Die Anforderung wurde bereits abgeschlossen oder ist anderweitig ungültig.
STATUS_ACCESS_VIOLATION
Der aktuelle Thread ist nicht der Ersteller der E/A-Anforderung.
STATUS_INSUFFICIENT_RESOURCES
Es ist nicht genügend Arbeitsspeicher vorhanden, um den Vorgang abzuschließen.
 

Diese Methode kann auch andere NTSTATUS-Werte zurückgeben.

Eine Fehlerüberprüfung tritt auf, wenn der Treiber ein ungültiges Objekthandle bereitstellt.

Hinweise

Nur ein Treiber der obersten Ebene kann die WdfRequestProbeAndLockUserBufferForRead-Methode aufrufen, da die Methode den Prozesskontext des Prozesses erfordert, der die E/A-Anforderung erstellt hat.

Der Benutzereingabepuffer enthält in der Regel Informationen, die auf das Gerät geschrieben werden sollen.

Der Benutzermoduspuffer, den der Buffer-Parameter angibt, kann der Puffer sein, den WdfRequestRetrieveUnsafeUserInputBuffer abruft, oder es kann sich um einen anderen Benutzermodus-Eingabepuffer handeln. Beispielsweise kann ein E/A-Steuerelementcode, der die gepufferte Zugriffsmethode verwendet, eine Struktur mit einem eingebetteten Zeiger an einen Puffer im Benutzermodus übergeben. In einem solchen Fall kann der TreiberWdfRequestProbeAndLockUserBufferForRead verwenden, um ein Speicherobjekt für den Puffer abzurufen.

Die Pufferlänge, die der Length-Parameter angibt, darf nicht größer als die tatsächliche Größe des Puffers sein. Andernfalls können Treiber auf Arbeitsspeicher außerhalb des Puffers zugreifen, was ein Sicherheitsrisiko darstellt.

Wenn WdfRequestProbeAndLockUserBufferForRead STATUS_SUCCESS zurückgibt, empfängt der Treiber ein Handle für ein Frameworkspeicherobjekt, das den Benutzermoduspuffer darstellt. Um auf den Puffer zuzugreifen, muss der Treiber WdfMemoryGetBuffer aufrufen.

Das Frameworkspeicherobjekt wird automatisch freigegeben, wenn der Treiber WdfRequestComplete aufruft.

Weitere Informationen zu WdfRequestProbeAndLockUserBufferForRead finden Sie unter Zugreifen auf Datenpuffer in Framework-Based Drivers.

Beispiele

Das folgende Codebeispiel ist eine verkürzte Version der Rückruffunktion EvtIoInCallerContext , die der NONPNP-Beispieltreiber enthält. Wenn die Rückruffunktion eine E/A-Anforderung empfängt, bestimmt sie, ob die Anforderung einen E/A-Steuerelementcode mit einem Übertragungstyp von METHOD_NEITHER enthält. Wenn die Anforderung einen solchen E/A-Steuerungscode enthält, die Funktion:

  1. Ruft WdfRequestRetrieveUnsafeUserInputBuffer und WdfRequestRetrieveUnsafeUserOutputBuffer auf, um die virtuellen Adressen der Lese- und Schreibpuffer der Anforderung abzurufen.
  2. Ruft WdfRequestProbeAndLockUserBufferForRead und WdfRequestProbeAndLockUserBufferForWrite auf, um die Puffer zu testen und zu sperren und ein Handle für ein Frameworkspeicherobjekt abzurufen, das jeden Puffer darstellt.
VOID
NonPnpEvtIoInCallerContext(
    IN WDFDEVICE  Device,
    IN WDFREQUEST Request
    )
{
    NTSTATUS  status = STATUS_SUCCESS;
    PREQUEST_CONTEXT  reqContext = NULL;
    WDF_OBJECT_ATTRIBUTES  attributes;
    WDF_REQUEST_PARAMETERS  params;
    size_t  inBufLen, outBufLen;
    PVOID  inBuf, outBuf;

    WDF_REQUEST_PARAMETERS_INIT(&params);
    WdfRequestGetParameters(
                            Request,
                            &params
                            );

    //
    // Check to see whether the driver received a METHOD_NEITHER I/O control code.
    // If not, just send the request back to the framework.
    //
    if(!(params.Type == WdfRequestTypeDeviceControl &&
            params.Parameters.DeviceIoControl.IoControlCode ==
                                    IOCTL_NONPNP_METHOD_NEITHER)) {
        status = WdfDeviceEnqueueRequest(
                                         Device,
                                         Request
                                         );
        if( !NT_SUCCESS(status) ) {
            goto End;
        }
        return;
    }

    //
    // The I/O control code is METHOD_NEITHER.
    // First, retrieve the virtual addresses of 
    // the input and output buffers.
    //
    status = WdfRequestRetrieveUnsafeUserInputBuffer(
                                                     Request,
                                                     0,
                                                     &inBuf,
                                                     &inBufLen
                                                     );
    if(!NT_SUCCESS(status)) {
        goto End;
    }
    status = WdfRequestRetrieveUnsafeUserOutputBuffer(
                                                      Request,
                                                      0,
                                                      &outBuf,
                                                      &outBufLen
                                                      );
    if(!NT_SUCCESS(status)) {
       goto End;
    }

    //
    // Next, allocate context space for the request, so that the
    // driver can store handles to the memory objects that will
    // be created for input and output buffers.
    //
    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes,
                                        REQUEST_CONTEXT);
    status = WdfObjectAllocateContext(
                                      Request,
                                      &attributes,
                                      &reqContext
                                      );
    if(!NT_SUCCESS(status)) {
        goto End;
    }

    //
    // Next, probe and lock the read and write buffers.
    //
    status = WdfRequestProbeAndLockUserBufferForRead(
                                                     Request,
                                                     inBuf,
                                                     inBufLen,
                                                     &reqContext->InputMemoryBuffer
                                                     );
    if(!NT_SUCCESS(status)) {
        goto End;
    }

    status = WdfRequestProbeAndLockUserBufferForWrite(
                                                      Request,
                                                      outBuf,
                                                      outBufLen,
                                                      &reqContext->OutputMemoryBuffer
                                                      );
    if(!NT_SUCCESS(status)) {
        goto End;
    }

    //
    // Finally, return the request to the framework.
    //
    status = WdfDeviceEnqueueRequest(
                                     Device,
                                     Request
                                     );
    if(!NT_SUCCESS(status)) {
        goto End;
    }
    return;

End:
    WdfRequestComplete(
                       Request,
                       status
                       );
    return;
}

Anforderungen

Anforderung Wert
Zielplattform Universell
KMDF-Mindestversion 1.0
Kopfzeile wdfrequest.h (einschließen von Wdf.h)
Bibliothek Wdf01000.sys (siehe Versionierung der Frameworkbibliothek.)
IRQL PASSIVE_LEVEL
DDI-Complianceregeln DriverCreate(kmdf), InvalidReqAccess(kmdf), InvalidReqAccessLocal(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf)

Weitere Informationen

WdfMemoryGetBuffer

WdfRequestProbeAndLockUserBufferForWrite

WdfRequestRetrieveUnsafeUserInputBuffer