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
指定的内存描述符无效,或者指定的 I/O 请求已排队到 I/O 目标。
 

此方法还可能返回其他 NTSTATUS 值

如果驱动程序提供无效的对象句柄,则会发生 bug 检查。

注解

使用 WdfUsbTargetDeviceFormatRequestForControlTransfer,然后使用 WdfRequestSend 以同步或异步方式发送 USB 控制传输请求。 或者,使用 WdfUsbTargetDeviceSendControlTransferSynchronously 方法以同步方式发送请求。

可以转发驱动程序在 I/O 队列中收到的 I/O 请求,也可以创建并发送新请求。 在任一情况下,框架都需要请求对象,并且可能需要一些缓冲区空间,具体取决于控制传输的类型。

转发驱动程序在 I/O 队列中收到的 I/O 请求:

  1. WdfUsbTargetDeviceFormatRequestForControlTransfer 方法的 Request 参数指定接收的请求句柄。
  2. 将收到的请求的输入或输出缓冲区用于 TransferMemory 参数。

    驱动程序必须调用 WdfRequestRetrieveInputMemoryWdfRequestRetrieveOutputMemory 以获取表示请求输入或输出缓冲区的框架内存对象的句柄,并使用该句柄作为 TransferMemory 的值。

创建新的 I/O 请求和新缓冲区:
  1. 创建新的请求对象,并为 WdfUsbTargetDeviceFormatRequestForControlTransfer 方法的 Request 参数提供其 柄。

    调用 WdfRequestCreate 以预分配一个或多个请求对象。 可以通过调用 WdfRequestReuse 重用这些请求对象。 驱动程序的 EvtDriverDeviceAdd 回调函数可以预分配设备的请求对象。

  2. 提供缓冲区空间,并为 WdfUsbTargetDeviceFormatRequestForControlTransfer 方法的 TransferMemory 参数提供缓冲区的句柄。

    驱动程序必须将此缓冲区空间指定为框架托管内存的 WDFMEMORY 句柄。 驱动程序可以执行以下任一操作:

    请注意,如果驱动程序调用 WdfRequestRetrieveInputMemoryWdfRequestRetrieveOutputMemory 并将内存句柄传递给 WdfUsbTargetDeviceFormatRequestForControlTransfer,则在驱动程序删除、重用或重新格式化新的驱动程序创建的请求对象之前,驱动程序不得完成收到的 I/O 请求。 (WdfUsbTargetDeviceFormatRequestForControlTransfer 递增内存对象的引用计数。删除、重用或重新格式化请求对象会递减内存对象的引用 count.)
调用 WdfUsbTargetDeviceFormatRequestForControlTransfer 以格式化 I/O 请求后,驱动程序必须调用 WdfRequestSend 以同步或异步方式将请求 () 发送到 I/O 目标。

对使用同一请求的 WdfUsbTargetDeviceFormatRequestForControlTransfer 的多次调用不会导致额外的资源分配。 因此,为了降低 WdfRequestCreate 返回STATUS_INSUFFICIENT_RESOURCES的可能性,驱动程序的 EvtDriverDeviceAdd 回调函数可以调用 WdfRequestCreate 来预分配设备的一个或多个请求对象。 驱动程序随后可以重复使用 (调用 WdfRequestReuse) ,重新格式化 (调用 WdfUsbTargetDeviceFormatRequestForControlTransfer) ,并重新发送 (调用 WdfRequestSend) 每个请求对象,而不会STATUS_INSUFFICIENT_RESOURCES WdfRequestCreate 的后续调用返回值。 如果参数值不更改,对 WdfUsbTargetDeviceFormatRequestForControlTransfer 的所有后续调用都将返回STATUS_SUCCESS。 (如果驱动程序不每次调用相同的请求格式设置方法,则可能会分配其他资源。)

框架在其内部 URB 中设置USBD_SHORT_TRANSFER_OK标志。 设置此标志允许数据传输的最后一个数据包小于最大数据包大小。

有关在 I/O 请求完成后获取状态信息的信息,请参阅 获取完成信息

有关 WdfUsbTargetDeviceFormatRequestForControlTransfer 方法和 USB I/O 目标的详细信息,请参阅 USB I/O 目标

示例

下面的代码示例创建一个请求对象和一个内存对象,然后初始化“获取状态”控件传输 的WDF_USB_CONTROL_SETUP_PACKET 结构。 接下来,该示例调用 WdfUsbTargetDeviceFormatRequestForControlTransfer 来设置请求的格式。 然后,该示例设置 一个 CompletionRoutine 回调函数,并将请求发送到 I/O 目标。

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)
Library Wdf01000.sys (KMDF) ;WUDFx02000.dll (UMDF)
IRQL <=DISPATCH_LEVEL
DDI 符合性规则 DriverCreate (kmdf) KmdfIrql (kmdf) KmdfIrql2 (kmdf) 、 KmdfIrqlExplicit (kmdf) , RequestFormattedValid (kmdf) RequestForUrbXrb (kmdf) RequestSendAndForgetNoFormatting (kmdf) RequestSendAndForgetNoFormatting 2 (kmdf) UsbKmdfIrql (kmdf) UsbKmdfIrql2 (kmdf) 、 UsbKmdfIrqlExplicit (kmdf)

另请参阅

WDF_USB_CONTROL_SETUP_PACKET

WDF_USB_CONTROL_SETUP_PACKET_INIT_GET_STATUS

WdfUsbTargetDeviceSendControlTransferSynchronously