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 en 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 sección Comentarios que se muestra más adelante.

[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 podría devolver otros valores NTSTATUS.

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

Comentarios

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 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 de 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, consulte Acceso a los búferes de datos en controladores de Framework-Based.

Ejemplos

El siguiente ejemplo de código es una versión abreviada de la función de devolución de llamada EvtIoInCallerContext 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 a 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 de 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 Value
Plataforma de destino Universal
Versión mínima de KMDF 1.0
Encabezado wdfrequest.h (incluir Wdf.h)
Library 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