WdfRequestSend function (wdfrequest.h)
[Applies to KMDF and UMDF]
The WdfRequestSend method sends a specified I/O request to a specified I/O target.
Syntax
BOOLEAN WdfRequestSend(
[in] WDFREQUEST Request,
[in] WDFIOTARGET Target,
PWDF_REQUEST_SEND_OPTIONS Options
);
Parameters
[in] Request
A handle to a framework request object.
[in] Target
A handle to a framework I/O target object. For more information about how to obtain this handle, see the following Remarks section.
Options
A pointer to a WDF_REQUEST_SEND_OPTIONS structure that contains caller-supplied request options. This parameter is optional and can be NULL if you do not want to enable any request options.
Return value
WdfRequestSend returns TRUE if the request was sent to the target. Otherwise, this method returns FALSE, and calling WdfRequestGetStatus returns a status that fails an NT_SUCCESS() test.
A bug check occurs if the driver supplies an invalid object handle.
Remarks
The request object that the driver specifies for the Request parameter can be one that it received or one that it created by calling the WdfRequestCreate method.
To obtain a handle to an I/O target object, the driver can do one of the following:
- If the driver is using general I/O targets, it calls WdfDeviceGetIoTarget. For more information, see Initializing a General I/O Target.
- If the driver is using a specialized I/O target, it calls one or more methods that the specialized target object defines. For example, a driver for a USB device can call WdfUsbTargetDeviceGetIoTarget or WdfUsbTargetPipeGetIoTarget.
If WdfRequestSend fails, or if your driver sets the WDF_REQUEST_SEND_OPTION_SYNCHRONOUS flag, the driver can call WdfRequestGetStatus immediately after calling WdfRequestSend.
If WdfRequestSend succeeds and your driver does not set the WDF_REQUEST_SEND_OPTION_SYNCHRONOUS flag, the driver typically calls WdfRequestGetStatus from within a CompletionRoutine callback function.
If the driver sends the request synchronously, we recommend that the driver set a time-out value in the WDF_REQUEST_SEND_OPTIONS structure and the time-out flag in the Flags member of this structure.
If the driver supplies a time-out value, it should call WdfRequestAllocateTimer before calling WdfRequestSend. This ensures that WdfRequestSend will not fail if there are insufficient system resources to allocate a timer.
If the driver sets the WDF_REQUEST_SEND_OPTION_SYNCHRONOUS flag, it must call WdfRequestSend at IRQL = PASSIVE_LEVEL. If this flag is not set, the driver must call this method at IRQL <= DISPATCH_LEVEL. WdfRequestSend sends the request at the caller's IRQL.
A driver cannot call WdfRequestSend to send an I/O request to a USB pipe, if the driver has configured a continuous reader for the pipe.
When sending a request to a UMDF driver, a kernel-mode driver must follow the IRQL restrictions outlined in Supporting Kernel-Mode Clients in UMDF Drivers.
For more information about WdfRequestSend, see Forwarding I/O Requests.
Examples
The following code example is a shortened version of an EvtIoWrite callback function from the kmdf_fx2 sample driver. The function validates the request's buffer length, obtains a handle to the buffer, formats the request for a USB target, and sends the request.
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;
}
Requirements
Requirement | Value |
---|---|
Target Platform | Universal |
Minimum KMDF version | 1.0 |
Minimum UMDF version | 2.0 |
Header | wdfrequest.h (include Wdf.h) |
Library | Wdf01000.sys (KMDF); WUDFx02000.dll (UMDF) |
IRQL | See Remarks section. |
DDI compliance rules | 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) |