Compartir a través de


Función WdfRequestProbeAndLockUserBufferForRead (wdfrequest.h)

[Solo se aplica a KMDF]

El método WdfRequestProbeAndLockUserBufferForRead comprueba que se puede leer el búfer del modo de usuario de una solicitud de E/S y, a continuación, bloquea las páginas de memoria física del búfer para que los controladores de la pila de controladores puedan leer el búfer.

Sintaxis

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

Parámetros

[in] Request

Identificador de un objeto de solicitud de marco.

[in] Buffer

Puntero al búfer de entrada de la solicitud. Para obtener más información, vea la siguiente sección Comentarios.

[in] Length

Longitud, en bytes, del búfer de entrada de la solicitud.

[out] MemoryObject

Puntero a una ubicación que recibe un identificador de un objeto de memoria de marco que representa el búfer de entrada del usuario.

Valor devuelto

WdfRequestProbeAndLockUserBufferForRead devuelve STATUS_SUCCESS si la operación se realiza correctamente. De lo contrario, este método podría devolver uno de los siguientes valores:

Código devuelto Descripción
STATUS_INVALID_PARAMETER
Un parámetro de entrada no es válido.
STATUS_INVALID_USER_BUFFER
El parámetro Length es cero.
STATUS_INVALID_DEVICE_REQUEST
La solicitud ya se ha completado o no es válida.
STATUS_ACCESS_VIOLATION
El subproceso actual no es el creador de la solicitud de E/S.
STATUS_INSUFFICIENT_RESOURCES
No hay memoria suficiente para completar la operación.
 

Este método también puede devolver otros valores de NTSTATUS.

Se produce una comprobación de errores si el controlador proporciona un identificador de objeto no válido.

Observaciones

Solo un controlador de nivel superior puede llamar al método WdfRequestProbeAndLockUserBufferForRead, ya que el método requiere el contexto de proceso del proceso que creó la solicitud de E/S.

El búfer de entrada del usuario normalmente contiene información que se va a escribir en el dispositivo.

El búfer en modo de usuario que especifica el parámetro buffer de puede ser el búfer que WdfRequestRetrieveUnsafeUserInputBuffer recupera o puede ser un búfer de entrada en modo de usuario diferente. Por ejemplo, un código de control de E/S que usa el método de acceso almacenado en búfer podría pasar una estructura que contiene un puntero incrustado a un búfer en modo de usuario. En tal caso, el controlador puede usarWdfRequestProbeAndLockUserBufferForRead para obtener un objeto de memoria para el búfer.

La longitud del búfer que especifica el parámetro Length no debe ser mayor que el tamaño real del búfer. De lo contrario, los controladores pueden acceder a la memoria fuera del búfer, lo que supone un riesgo de seguridad.

Si WdfRequestProbeAndLockUserBufferForRead devuelve STATUS_SUCCESS, el controlador recibe un identificador de un objeto de memoria del marco que representa el búfer en modo de usuario. Para acceder al búfer, el controlador debe llamar a WdfMemoryGetBuffer.

El objeto de memoria del marco se libera automáticamente cuando el controlador llama a WdfRequestComplete.

Para obtener más información sobre WdfRequestProbeAndLockUserBufferForRead, vea acceder a búferes de datos en controladores de Framework-Based.

Ejemplos

El ejemplo de código siguiente es una versión abreviada del EvtIoInCallerContext función de devolución de llamada que contiene el controlador de ejemplo NONPNP. Cuando la función de devolución de llamada recibe una solicitud de E/S, determina si la solicitud contiene un código de control de E/S con un tipo de transferencia de METHOD_NEITHER. Si la solicitud contiene este tipo de código de control de E/S, la función :

  1. Llama WdfRequestRetrieveUnsafeUserInputBuffer y WdfRequestRetrieveUnsafeUserOutputBuffer para obtener las direcciones virtuales de los búferes de lectura y escritura de la solicitud.
  2. Llama a WdfRequestProbeAndLockUserBufferForRead y WdfRequestProbeAndLockUserBufferForWrite para sondear y bloquear los búferes y obtener un identificador para un objeto de memoria del marco que representa cada búfer.
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;
}

Requisitos

Requisito Valor
de la plataforma de destino de Universal
versión mínima de KMDF 1.0
encabezado de wdfrequest.h (incluya Wdf.h)
biblioteca de Wdf01000.sys (consulte Control de versiones de la biblioteca de marcos).
irQL PASSIVE_LEVEL
reglas de cumplimiento de DDI DriverCreate(kmdf), InvalidReqAccess(kmdf), InvalidReqAccessLocal(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf)

Consulte también

WdfMemoryGetBuffer

WdfRequestProbeAndLockUserBufferForWrite

WdfRequestRetrieveUnsafeUserInputBuffer