Функция 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 .
Чтобы получить дескриптор целевого объекта ввода-вывода, драйвер может выполнить одно из следующих действий:
- Если драйвер использует общие целевые объекты ввода-вывода, он вызывает WdfDeviceGetIoTarget. Дополнительные сведения см. в разделе Инициализация общего целевого объекта ввода-вывода.
- Если драйвер использует специализированный целевой объект ввода-вывода, он вызывает один или несколько методов, определяемых специализированным целевым объектом. Например, драйвер для USB-устройства может вызывать WdfUsbTargetDeviceGetIoTarget или WdfUsbTargetPipeGetIoTarget.
В случае сбоя 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) |