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 |
---|---|
|
Un parámetro de entrada no es válido. |
|
El parámetro Length es cero. |
|
La solicitud ya se ha completado o no es válida. |
|
El subproceso actual no es el creador de la solicitud de E/S. |
|
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 :
- Llama a WdfRequestRetrieveUnsafeUserInputBuffer y WdfRequestRetrieveUnsafeUserOutputBuffer para obtener las direcciones virtuales de los búferes de lectura y escritura de la solicitud.
- 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(¶ms);
WdfRequestGetParameters(
Request,
¶ms
);
//
// 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) |