Поделиться через


Функция 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, если операция выполнена успешно. В противном случае этот метод может возвращать одно из следующих значений:

Код возврата Описание
STATUS_INVALID_PARAMETER
Обнаружен недопустимый параметр.
STATUS_INSUFFICIENT_RESOURCES
Недостаточно памяти.
STATUS_INVALID_DEVICE_REQUEST
Указан недопустимый дескриптор памяти, недопустимый тип канала, недопустимое направление передачи или указанный запрос ввода-вывода уже поставлен в очередь в целевой объект ввода-вывода.
STATUS_INTEGER_OVERFLOW
Недопустимое смещение, указанное параметром Offset .
STATUS_INVALID_BUFFER_SIZE
Размер буфера не был кратным максимальному размеру пакета канала. Размер буфера должен быть кратным максимальному размеру пакета канала, если драйвер не вызвал WdfUsbTargetPipeSetNoMaximumPacketSizeCheck.
STATUS_REQUEST_NOT_ACCEPTED
Пакет запроса ввода-вывода (IRP), который представляет параметр Request , не предоставляет достаточно IO_STACK_LOCATION структур, позволяющих драйверу пересылать запрос.
 

Этот метод также может возвращать другие значения NTSTATUS.

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

Комментарии

Используйте WdfUsbTargetPipeFormatRequestForRead, за которым следует WdfRequestSend, для отправки запросов на чтение синхронно или асинхронно. Кроме того, можно использовать метод WdfUsbTargetPipeReadSynchronously для синхронной отправки запросов на чтение.

Канал, который указывает параметр Pipe , должен быть входным каналом, а тип канала — WdfUsbPipeTypeBulk или WdfUsbPipeTypeInterrupt.

Вы можете переслать запрос ввода-вывода, полученный драйвером в очереди ввода-вывода, или создать и отправить новый запрос. В любом случае платформе требуется объект запроса и некоторое буферное пространство.

Чтобы переслать запрос ввода-вывода, полученный драйвером в очереди ввода-вывода, выполните приведенные далее действия.

  1. Укажите дескриптор полученного запроса для параметра Request метода WdfUsbTargetPipeFormatRequestForRead.
  2. Используйте выходной буфер полученного запроса для параметра ReadMemory метода WdfUsbTargetPipeFormatRequestForRead.

    Драйвер должен вызвать WdfRequestRetrieveOutputMemory , чтобы получить дескриптор объекта памяти платформы, который представляет выходной буфер запроса, и использовать этот дескриптор в качестве значения параметра ReadMemory .

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

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

Чтобы создать новый запрос ввода-вывода, выполните приведенные далее действия.

  1. Создайте объект запроса и укажите его дескриптор для параметра Request метода WdfUsbTargetPipeFormatRequestForRead.

    Вызовите WdfRequestCreate , чтобы предварительно выделить один или несколько объектов запроса. Эти объекты запроса можно повторно использовать, вызвав WdfRequestReuse. Функция обратного вызова EvtDriverDeviceAdd драйвера может предварительно выделить объекты запроса для устройства.

  2. Укажите буферное пространство и укажите дескриптор буфера для параметра ReadMemory метода WdfUsbTargetPipeFormatRequestForRead.

    Драйвер должен указать это буферное пространство в качестве дескриптора WDFMEMORY для памяти, управляемой платформой. Драйвер может выполнить одно из следующих действий:

    • Вызовите WdfMemoryCreate или WdfMemoryCreatePreallocated , чтобы создать буфер памяти, если вы хотите, чтобы драйвер передал новый буфер целевому объекту ввода-вывода.
    • Вызовите WdfRequestRetrieveOutputMemory , чтобы получить дескриптор объекта памяти, который представляет буфер полученного запроса ввода-вывода, если требуется, чтобы драйвер передал содержимое этого буфера целевому объекту ввода-вывода.
    Обратите внимание, что если драйвер вызывает WdfRequestRetrieveOutputMemory и передает дескриптор памяти в WdfUsbTargetPipeFormatRequestForRead, драйвер не должен завершить полученный запрос ввода-вывода до тех пор, пока драйвер не удалит, повторно использует или переформатирует новый созданный драйвером объект запроса. (WdfUsbTargetPipeFormatRequestForRead увеличивает число ссылок объекта памяти. Удаление, повторное использование или переформатирование объекта запроса уменьшает количество ссылок на объект памяти.)
После вызова WdfUsbTargetPipeFormatRequestForRead для форматирования запроса ввода-вывода драйвер должен вызвать WdfRequestSend для отправки запроса (синхронно или асинхронно) целевому объекту ввода-вывода.

Несколько вызовов 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)

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

WDFMEMORY_OFFSET

WdfRequestCompleteWithInformation

WdfRequestGetStatus

WdfRequestSend

WdfRequestSetCompletionRoutine

WdfUsbInterfaceGetConfiguredPipe