Функция WdfUsbTargetPipeFormatRequestForRead (wdfusb.h)
[Применимо к KMDF и UMDF]
Метод WdfUsbTargetPipeFormatRequestForRead создает запрос на чтение для входного USB-канала, но не отправляет запрос.
Синтаксис
NTSTATUS WdfUsbTargetPipeFormatRequestForRead(
[in] WDFUSBPIPE Pipe,
[in] WDFREQUEST Request,
[in, optional] WDFMEMORY ReadMemory,
[in, optional] PWDFMEMORY_OFFSET ReadOffset
);
Параметры
[in] Pipe
Дескриптор объекта конвейера платформы, полученный путем вызова метода WdfUsbInterfaceGetConfiguredPipe.
[in] Request
Дескриптор объекта запроса платформы. Дополнительные сведения см. в разделе "Примечания".
[in, optional] ReadMemory
Дескриптор объекта памяти платформы. Этот объект представляет буфер, который будет получать данные из канала. Размер буфера должен быть кратным максимальному размеру пакета канала, если драйвер не вызвал WdfUsbTargetPipeSetNoMaximumPacketSizeCheck. Дополнительные сведения об этом буфере см. в следующем разделе Примечания.
[in, optional] ReadOffset
Указатель на структуру, выделенную вызывающим объектом WDFMEMORY_OFFSET , которая предоставляет необязательные значения смещения и длины байтов. Платформа использует эти значения для определения начального адреса и длины в буфере чтения для передачи данных. Если этот указатель имеет значение NULL, передача данных начинается в начале буфера, а размер передачи равен размеру буфера.
Возвращаемое значение
WdfUsbTargetPipeFormatRequestForRead возвращает STATUS_SUCCESS, если операция выполнена успешно. В противном случае этот метод может возвращать одно из следующих значений:
Код возврата | Описание |
---|---|
|
Обнаружен недопустимый параметр. |
|
Недостаточно памяти. |
|
Указан недопустимый дескриптор памяти, недопустимый тип канала, недопустимое направление передачи или указанный запрос ввода-вывода уже поставлен в очередь в целевой объект ввода-вывода. |
|
Недопустимое смещение, указанное параметром Offset . |
|
Размер буфера не был кратным максимальному размеру пакета канала. Размер буфера должен быть кратным максимальному размеру пакета канала, если драйвер не вызвал WdfUsbTargetPipeSetNoMaximumPacketSizeCheck. |
|
Пакет запроса ввода-вывода (IRP), который представляет параметр Request , не предоставляет достаточно IO_STACK_LOCATION структур, позволяющих драйверу пересылать запрос. |
Этот метод также может возвращать другие значения NTSTATUS.
Ошибка проверка возникает, если драйвер предоставляет недопустимый дескриптор объекта.
Комментарии
Используйте WdfUsbTargetPipeFormatRequestForRead, за которым следует WdfRequestSend, для отправки запросов на чтение синхронно или асинхронно. Кроме того, можно использовать метод WdfUsbTargetPipeReadSynchronously для синхронной отправки запросов на чтение.
Канал, который указывает параметр Pipe , должен быть входным каналом, а тип канала — WdfUsbPipeTypeBulk или WdfUsbPipeTypeInterrupt.
Вы можете переслать запрос ввода-вывода, полученный драйвером в очереди ввода-вывода, или создать и отправить новый запрос. В любом случае платформе требуется объект запроса и некоторое буферное пространство.
Чтобы переслать запрос ввода-вывода, полученный драйвером в очереди ввода-вывода, выполните приведенные далее действия.
- Укажите дескриптор полученного запроса для параметра Request метода WdfUsbTargetPipeFormatRequestForRead.
-
Используйте выходной буфер полученного запроса для параметра ReadMemory метода WdfUsbTargetPipeFormatRequestForRead.
Драйвер должен вызвать WdfRequestRetrieveOutputMemory , чтобы получить дескриптор объекта памяти платформы, который представляет выходной буфер запроса, и использовать этот дескриптор в качестве значения параметра ReadMemory .
Драйверы часто разделяют полученные запросы ввода-вывода на более мелкие запросы, отправляемые в целевой объект ввода-вывода, поэтому драйвер может создавать новые запросы.
Чтобы создать новый запрос ввода-вывода, выполните приведенные далее действия.
-
Создайте объект запроса и укажите его дескриптор для параметра Request метода WdfUsbTargetPipeFormatRequestForRead.
Вызовите WdfRequestCreate , чтобы предварительно выделить один или несколько объектов запроса. Эти объекты запроса можно повторно использовать, вызвав WdfRequestReuse. Функция обратного вызова EvtDriverDeviceAdd драйвера может предварительно выделить объекты запроса для устройства.
-
Укажите буферное пространство и укажите дескриптор буфера для параметра ReadMemory метода WdfUsbTargetPipeFormatRequestForRead.
Драйвер должен указать это буферное пространство в качестве дескриптора WDFMEMORY для памяти, управляемой платформой. Драйвер может выполнить одно из следующих действий:
- Вызовите WdfMemoryCreate или WdfMemoryCreatePreallocated , чтобы создать буфер памяти, если вы хотите, чтобы драйвер передал новый буфер целевому объекту ввода-вывода.
- Вызовите WdfRequestRetrieveOutputMemory , чтобы получить дескриптор объекта памяти, который представляет буфер полученного запроса ввода-вывода, если требуется, чтобы драйвер передал содержимое этого буфера целевому объекту ввода-вывода.
Несколько вызовов WdfUsbTargetPipeFormatRequestForRead , использующих один и тот же запрос, не приводят к выделению дополнительных ресурсов. Таким образом, чтобы снизить вероятность того, что WdfRequestCreate вернет STATUS_INSUFFICIENT_RESOURCES, функция обратного вызова EvtDriverDeviceAdd драйвера может вызвать WdfRequestCreate для предварительного выделения одного или нескольких объектов запроса для устройства. Впоследствии драйвер может повторно использовать (вызвать WdfRequestReuse), переформатировать (вызвать WdfUsbTargetPipeFormatRequestForRead) и повторно отправить (вызвать WdfRequestSend) каждый объект запроса, не рискуя STATUS_INSUFFICIENT_RESOURCES возвращаемое значение при последующем вызове WdfRequestCreate. Все последующие вызовы WdfUsbTargetPipeFormatRequestForRead для повторно использованного объекта запроса будут возвращать STATUS_SUCCESS, если значения параметров не изменяются. (Если драйвер не вызывает один и тот же метод форматирования запросов каждый раз, могут быть выделены дополнительные ресурсы.)
Платформа задает флаг USBD_SHORT_TRANSFER_OK во внутренней urb. Установка этого флага позволяет, чтобы последний пакет передачи данных был меньше максимального размера пакета.
Сведения о получении сведений о состоянии после завершения запроса ввода-вывода см. в разделе Получение сведений о завершении.
Дополнительные сведения о методе WdfUsbTargetPipeFormatRequestForRead и целевых объектах USB-ввода-вывода см. в статье Usb I/O Targets.
Примеры
Следующий пример кода получен из примера драйвера kmdf_fx2 . В этом примере показана функция обратного вызова EvtIoRead , которая пересылает запрос на чтение в USB-канал. В примере вызывается метод WdfRequestRetrieveOutputMemory для получения выходного буфера запроса, а затем он форматирует запрос на чтение таким образом, чтобы запрос можно было отправить в USB-канал. Далее в примере регистрируется функция обратного вызова CompletionRoutine . Наконец, он отправляет запрос в USB-канал.
VOID
OsrFxEvtIoRead(
IN WDFQUEUE Queue,
IN WDFREQUEST Request,
IN size_t Length
)
{
WDFUSBPIPE pipe;
NTSTATUS status;
WDFMEMORY reqMemory;
PDEVICE_CONTEXT pDeviceContext;
//
// First, validate input parameters.
//
if (Length > TEST_BOARD_TRANSFER_BUFFER_SIZE) {
status = STATUS_INVALID_PARAMETER;
goto Exit;
}
pDeviceContext = GetDeviceContext(WdfIoQueueGetDevice(Queue));
pipe = pDeviceContext->BulkReadPipe;
status = WdfRequestRetrieveOutputMemory(
Request,
&reqMemory
);
if (!NT_SUCCESS(status)){
goto Exit;
}
status = WdfUsbTargetPipeFormatRequestForRead(
pipe,
Request,
reqMemory,
NULL
);
if (!NT_SUCCESS(status)) {
goto Exit;
}
WdfRequestSetCompletionRoutine(
Request,
EvtRequestReadCompletionRoutine,
pipe
);
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 |
Верхняя часть | wdfusb.h (включая Wdfusb.h) |
Библиотека | Wdf01000.sys (KMDF); WUDFx02000.dll (UMDF) |
IRQL | <=DISPATCH_LEVEL |
Правила соответствия DDI | DriverCreate(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf), RequestFormattedValid(kmdf), RequestSendAndForgetNoFormatting(kmdf), RequestSendAndForgetNoFormatting2(kmdf), UsbKmdfIrql(kmdf), UsbKmdfIrql2(kmdf), UsbKmdfIrqlExplicit(kmdf) |
См. также раздел
WdfRequestCompleteWithInformation