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


Функция WdfUsbTargetDeviceFormatRequestForControlTransfer (wdfusb.h)

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

Метод WdfUsbTargetDeviceFormatRequestForControlTransfer создает запрос на передачу элемента управления USB, но не отправляет запрос.

Синтаксис

NTSTATUS WdfUsbTargetDeviceFormatRequestForControlTransfer(
  [in]           WDFUSBDEVICE                  UsbDevice,
  [in]           WDFREQUEST                    Request,
  [in]           PWDF_USB_CONTROL_SETUP_PACKET SetupPacket,
  [in, optional] WDFMEMORY                     TransferMemory,
  [in, optional] PWDFMEMORY_OFFSET             TransferOffset
);

Параметры

[in] UsbDevice

Дескриптор объекта USB-устройства, полученный при предыдущем вызове WdfUsbTargetDeviceCreateWithParameters.

[in] Request

Дескриптор объекта запроса платформы. Дополнительные сведения см. в разделе "Примечания".

[in] SetupPacket

Указатель на структуру WDF_USB_CONTROL_SETUP_PACKET , выделенную вызывающим объектом, которая описывает передачу элемента управления.

[in, optional] TransferMemory

Дескриптор объекта памяти платформы, который описывает входной или выходной буфер в зависимости от команды конкретного устройства. Этот указатель является необязательным и может иметь значение NULL. Дополнительные сведения см. в разделе "Примечания".

[in, optional] TransferOffset

Указатель на структуру, выделенную вызывающим объектом WDFMEMORY_OFFSET , которая предоставляет необязательные значения смещения и длины байтов. Платформа использует эти значения для определения начального адреса и длины в буфере, заданном TransferMemory . Если этот указатель имеет значение NULL, платформа использует весь буфер.

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

WdfUsbTargetDeviceFormatRequestForControlTransfer возвращает STATUS_SUCCESS, если операция выполнена успешно. В противном случае этот метод может возвращать одно из следующих значений:

Код возврата Описание
STATUS_INVALID_PARAMETER
Обнаружен недопустимый параметр.
STATUS_INSUFFICIENT_RESOURCES
Недостаточно памяти.
STATUS_INVALID_DEVICE_REQUEST
Указан недопустимый дескриптор памяти или указанный запрос ввода-вывода уже помещен в очередь в целевой объект ввода-вывода.
 

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

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

Комментарии

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

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

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

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

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

Чтобы создать новый запрос ввода-вывода и буфер, выполните приведенные ниже действия.
  1. Создайте объект запроса и укажите его дескриптор для параметра Request метода WdfUsbTargetDeviceFormatRequestForControlTransfer.

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

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

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

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

Несколько вызовов WdfUsbTargetDeviceFormatRequestForControlTransfer , использующих один и тот же запрос, не приводят к выделению дополнительных ресурсов. Таким образом, чтобы снизить вероятность того, что WdfRequestCreate вернет STATUS_INSUFFICIENT_RESOURCES, функция обратного вызова EvtDriverDeviceAdd драйвера может вызвать WdfRequestCreate для предварительного выделения одного или нескольких объектов запроса для устройства. Впоследствии драйвер может повторно использовать (вызвать WdfRequestReuse), переформатировать (вызвать WdfUsbTargetDeviceFormatRequestForControlTransfer) и повторно отправить (вызвать WdfRequestSend) каждый объект запроса, не рискуя STATUS_INSUFFICIENT_RESOURCES возвращаемое значение из последующего вызова WdfRequestCreate. Все последующие вызовы WdfUsbTargetDeviceFormatRequestForControlTransfer для повторно использованного объекта запроса будут возвращать STATUS_SUCCESS, если значения параметра не изменяются. (Если драйвер не вызывает один и тот же метод форматирования запросов каждый раз, могут быть выделены дополнительные ресурсы.)

Платформа задает флаг USBD_SHORT_TRANSFER_OK во внутренней urb. Установка этого флага позволяет, чтобы последний пакет передачи данных был меньше максимального размера пакета.

Сведения о получении сведений о состоянии после завершения запроса ввода-вывода см. в разделе Получение сведений о завершении.

Дополнительные сведения о методе WdfUsbTargetDeviceFormatRequestForControlTransfer и целевых объектах ВВОДА-вывода USB см. в разделе Usb I/O Targets.

Примеры

В следующем примере кода создается объект запроса и объект памяти, а затем инициализируется структура WDF_USB_CONTROL_SETUP_PACKET для передачи элемента управления "получение состояния". Далее в примере вызывается WdfUsbTargetDeviceFormatRequestForControlTransfer для форматирования запроса. Затем в примере задается функция обратного вызова CompletionRoutine и отправляется запрос в целевой объект ввода-вывода.

WDF_USB_CONTROL_SETUP_PACKET packet;
NTSTATUS status;
WDF_OBJECT_ATTRIBUTES attributes;
WDFMEMORY memHandle;

WDF_OBJECT_ATTRIBUTES_INIT(&attributes);

status = WdfRequestCreate(
                          &attributes,
                          WdfUsbTargetDeviceGetIoTarget(
                              UsbTargetDevice,
                              &request
                              )
                          );
if (!NT_SUCCESS(status)){
    return status;
}

WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
attributes.ParentObject = request;
status = WdfMemoryCreate(
                         &attributes,
                         NonPagedPool,
                         0,
                         sizeof(USHORT),
                         &memHandle,
                         NULL
                         );
if (!NT_SUCCESS(status)){
    return status;
}

WDF_USB_CONTROL_SETUP_PACKET_INIT_GET_STATUS(
                                             &packet,
                                             BmRequestToDevice,
                                             0
                                             );
status = WdfUsbTargetDeviceFormatRequestForControlTransfer(
                         UsbTargetDevice,
                         request,
                         &packet,
                         memHandle,
                         NULL
                         );
if (!NT_SUCCESS(status)){
    return status;
}
WdfRequestSetCompletionRoutine(
                               request,
                               MyCompletionRoutine,
                               NULL
                               );
if (WdfRequestSend(
                   request,
                   WdfUsbTargetDeviceGetIoTarget(UsbTargetDevice),
                   NULL
                   ) == FALSE) {
    status = WdfRequestGetStatus(request);
}

Требования

Требование Значение
Целевая платформа Универсальное
Минимальная версия 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), RequestForUrbXrb(kmdf), RequestSendAndForgetNoFormatting(kmdf), RequestSendAndForgetNoFormatting2(kmdf), UsbKmdfIrql(kmdf), UsbKmdfIrql2(kmdf), UsbKmdfIrqlExplicit(kmdf)

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

WDF_USB_CONTROL_SETUP_PACKET

WDF_USB_CONTROL_SETUP_PACKET_INIT_GET_STATUS

WdfUsbTargetDeviceSendControlTransferSynchronously