Функция WdfRequestSend (wdfrequest.h)

[Применимо к KMDF и UMDF]

Метод WdfRequestSend отправляет указанный запрос ввода-вывода в указанный целевой объект ввода-вывода.

Синтаксис

BOOLEAN WdfRequestSend(
  [in] WDFREQUEST                Request,
  [in] WDFIOTARGET               Target,
       PWDF_REQUEST_SEND_OPTIONS Options
);

Параметры

[in] Request

Дескриптор объекта запроса платформы.

[in] Target

Дескриптор целевого объекта ввода-вывода платформы. Дополнительные сведения о том, как получить этот дескриптор, см. в следующем разделе Примечания.

Options

Указатель на структуру WDF_REQUEST_SEND_OPTIONS , содержащую предоставленные вызывающим абонентом параметры запроса. Этот параметр является необязательным и может иметь значение NULL , если вы не хотите включать параметры запроса.

Возвращаемое значение

WdfRequestSend возвращает значение TRUE , если запрос был отправлен целевому объекту. В противном случае этот метод возвращает значение FALSE, а вызов WdfRequestGetStatus возвращает состояние, которое завершается сбоем теста NT_SUCCESS().

Ошибка проверка возникает, если драйвер предоставляет недопустимый дескриптор объекта.

Комментарии

Объект запроса, который драйвер указывает для параметра Request , может быть объектом запроса, который он получил или создал путем вызова метода WdfRequestCreate .

Чтобы получить дескриптор целевого объекта ввода-вывода, драйвер может выполнить одно из следующих действий:

По умолчанию WdfRequestSend асинхронно доставляет запрос целевому объекту, то есть возвращается немедленно, не дожидаясь завершения запроса. При необходимости запрос может быть доставлен синхронно. Это означает, что WdfRequestSend не возвращается, пока драйвер не завершит запрос. Чтобы отправить запрос синхронно, драйвер должен установить флаг WDF_REQUEST_SEND_OPTION_SYNCHRONOUS в структуре WDF_REQUEST_SEND_OPTIONS .

В случае сбоя WdfRequestSend или если драйвер устанавливает флаг WDF_REQUEST_SEND_OPTION_SYNCHRONOUS, драйвер может вызвать WdfRequestGetStatus сразу после вызова WdfRequestSend.

Если WdfRequestSend завершается успешно и драйвер не устанавливает флаг WDF_REQUEST_SEND_OPTION_SYNCHRONOUS, драйвер обычно вызывает WdfRequestGetStatus из функции обратного вызова CompletionRoutine .

Если драйвер отправляет запрос синхронно, рекомендуется установить значение времени ожидания в структуре WDF_REQUEST_SEND_OPTIONS и флаг времени ожидания в элементе Flags этой структуры.

Если драйвер предоставляет значение времени ожидания, он должен вызвать WdfRequestAllocateTimer перед вызовом WdfRequestSend. Это гарантирует, что WdfRequestSend не завершится ошибкой, если для выделения таймера недостаточно системных ресурсов.

Если драйвер задает флаг WDF_REQUEST_SEND_OPTION_SYNCHRONOUS , он должен вызвать WdfRequestSend в IRQL = PASSIVE_LEVEL. Если этот флаг не задан, драйвер должен вызвать этот метод в IRQL <= DISPATCH_LEVEL. WdfRequestSend отправляет запрос в IRQL вызывающего абонента.

Драйвер не может вызвать WdfRequestSend для отправки запроса ввода-вывода в USB-канал, если драйвер настроил непрерывное средство чтения для канала.

При отправке запроса к драйверу UMDF драйвер в режиме ядра должен следовать ограничениям IRQL, описанным в статье Поддержка клиентов Kernel-Mode в драйверах UMDF.

Дополнительные сведения о WdfRequestSend см. в разделе Пересылка запросов ввода-вывода.

Примеры

Следующий пример кода представляет собой сокращенную версию функции обратного вызова EvtIoWrite из примера драйвера kmdf_fx2 . Функция проверяет длину буфера запроса, получает дескриптор буфера, форматирует запрос для целевого USB-адреса и отправляет запрос.

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;
}

Требования

Требование Значение
Целевая платформа Универсальное
Минимальная версия KMDF 1,0
Минимальная версия UMDF 2,0
Верхняя часть wdfrequest.h (включая Wdf.h)
Библиотека Wdf01000.sys (KMDF); WUDFx02000.dll (UMDF)
IRQL См. раздел "Примечания".
Правила соответствия 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)

См. также раздел

CompletionRoutine

WDF_REQUEST_SEND_OPTIONS

WdfDeviceGetIoTarget

WdfRequestAllocateTimer

WdfRequestCreate

WdfRequestGetStatus