Función WdfRequestSend (wdfrequest.h)
[Se aplica a KMDF y UMDF]
El método WdfRequestSend envía una solicitud de E/S especificada a un destino de E/S especificado.
Sintaxis
BOOLEAN WdfRequestSend(
[in] WDFREQUEST Request,
[in] WDFIOTARGET Target,
PWDF_REQUEST_SEND_OPTIONS Options
);
Parámetros
[in] Request
Identificador de un objeto de solicitud de marco.
[in] Target
Identificador de un objeto de destino de E/S de marco. Para obtener más información sobre cómo obtener este identificador, vea la siguiente sección Comentarios.
Options
Puntero a una estructura de WDF_REQUEST_SEND_OPTIONS que contiene las opciones de solicitud proporcionadas por el autor de la llamada. Este parámetro es opcional y puede ser NULL si no desea habilitar ninguna opción de solicitud.
Valor devuelto
WdfRequestSend devuelve TRUE si la solicitud se envió al destino. De lo contrario, este método devuelve FALSE y la llamada a WdfRequestGetStatus devuelve un estado que produce un error en una prueba de NT_SUCCESS().
Se produce una comprobación de errores si el controlador proporciona un identificador de objeto no válido.
Comentarios
El objeto de solicitud que el controlador especifica para el parámetro Request puede ser el que recibió o uno que creó llamando al método WdfRequestCreate .
Para obtener un identificador de un objeto de destino de E/S, el controlador puede realizar una de las siguientes acciones:
- Si el controlador usa destinos de E/S generales, llama a WdfDeviceGetIoTarget. Para obtener más información, consulte Inicialización de un destino de E/S general.
- Si el controlador usa un destino de E/S especializado, llama a uno o varios métodos que define el objeto de destino especializado. Por ejemplo, un controlador para un dispositivo USB puede llamar a WdfUsbTargetDeviceGetIoTarget o WdfUsbTargetPipeGetIoTarget.
Si se produce un error en WdfRequestSend o si el controlador establece la marca WDF_REQUEST_SEND_OPTION_SYNCHRONOUS, el controlador puede llamar a WdfRequestGetStatus inmediatamente después de llamar a WdfRequestSend.
Si WdfRequestSend se realiza correctamente y el controlador no establece la marca WDF_REQUEST_SEND_OPTION_SYNCHRONOUS, el controlador normalmente llama a WdfRequestGetStatus desde una función de devolución de llamada CompletionRoutine .
Si el controlador envía la solicitud de forma sincrónica, se recomienda que el controlador establezca un valor de tiempo de espera en la estructura WDF_REQUEST_SEND_OPTIONS y la marca de tiempo de espera en el miembro Flags de esta estructura.
Si el controlador proporciona un valor de tiempo de espera, debe llamar a WdfRequestAllocateTimer antes de llamar a WdfRequestSend. Esto garantiza que WdfRequestSend no producirá un error si no hay recursos del sistema suficientes para asignar un temporizador.
Si el controlador establece la marca WDF_REQUEST_SEND_OPTION_SYNCHRONOUS , debe llamar a WdfRequestSend en IRQL = PASSIVE_LEVEL. Si no se establece esta marca, el controlador debe llamar a este método en IRQL <= DISPATCH_LEVEL. WdfRequestSend envía la solicitud en el IRQL del autor de la llamada.
Un controlador no puede llamar a WdfRequestSend para enviar una solicitud de E/S a una canalización USB, si el controlador ha configurado un lector continuo para la canalización.
Al enviar una solicitud a un controlador UMDF, un controlador en modo kernel debe seguir las restricciones irQL descritas en Compatibilidad con clientes de Kernel-Mode en controladores UMDF.
Para obtener más información sobre WdfRequestSend, vea Reenvío de solicitudes de E/S.
Ejemplos
El ejemplo de código siguiente es una versión abreviada de una función de devolución de llamada EvtIoWrite del controlador de ejemplo de kmdf_fx2 . La función valida la longitud del búfer de la solicitud, obtiene un identificador para el búfer, da formato a la solicitud de un destino USB y envía la solicitud.
VOID
OsrFxEvtIoWrite(
IN WDFQUEUE Queue,
IN WDFREQUEST Request,
IN size_t Length
)
{
WDFUSBPIPE pipe;
NTSTATUS status;
WDFMEMORY reqMemory;
PDEVICE_CONTEXT pDeviceContext;
UNREFERENCED_PARAMETER(Queue);
//
// Check if the transfer size is valid.
//
if (Length > MAX_TRANSFER_BUFFER_SIZE) {
status = STATUS_INVALID_PARAMETER;
goto Exit;
}
//
// Get driver-defined context space from
// the device object. The driver stored the
// pipe handle there.
//
pDeviceContext = GetDeviceContext(WdfIoQueueGetDevice(Queue));
pipe = pDeviceContext->BulkWritePipe;
//
// Get a handle to a memory object that represents
// the input buffer.
//
status = WdfRequestRetrieveInputMemory(Request, &reqMemory);
if (!NT_SUCCESS(status)){
goto Exit;
}
//
// Format the request so it can be sent to a USB target.
//
status = WdfUsbTargetPipeFormatRequestForWrite(
pipe,
Request,
reqMemory,
NULL // Offsets
);
if (!NT_SUCCESS(status)) {
goto Exit;
}
//
// Set a CompletionRoutine callback function.
//
WdfRequestSetCompletionRoutine(
Request,
EvtRequestReadCompletionRoutine,
pipe
);
//
// Send the request. If an error occurs, complete the request.
//
if (WdfRequestSend(
Request,
WdfUsbTargetPipeGetIoTarget(pipe),
WDF_NO_SEND_OPTIONS
) == FALSE) {
status = WdfRequestGetStatus(Request);
goto Exit;
}
Exit:
if (!NT_SUCCESS(status)) {
WdfRequestCompleteWithInformation(
Request,
status,
0
);
}
return;
}
Requisitos
Requisito | Value |
---|---|
Plataforma de destino | Universal |
Versión mínima de KMDF | 1.0 |
Versión mínima de UMDF | 2.0 |
Encabezado | wdfrequest.h (incluir Wdf.h) |
Library | Wdf01000.sys (KMDF); WUDFx02000.dll (UMDF) |
IRQL | vea la sección Comentarios. |
Reglas de cumplimiento de DDI | DeferredRequestCompleted(kmdf), DriverCreate(kmdf), InvalidReqAccess(kmdf), InvalidReqAccessLocal(kmdf), KmdfIrql(kmdf), ReqCompletionRoutine(kmdf), ReqMarkCancelableSend(kmdf), ReqSendFail(kmdf), ReqSendWhileSpinlock(kmdf), RequestCompleted(kmdf), RequestCompletedLocal(kmdf), RequestFormattedValid(kmdf), RequestGetStatusValid(kmdf), RequestSendAndForgetNoFormatting(kmdf), RequestSendAndForgetNoFormatting2(kmdf), SyncReqSend2(kmdf), WdfRequestSendSyncAtDispatch(kmdf), WdfRequestSendSyncAtDispatch2(kmdf) |