WdfUsbTargetPipeFormatRequestForWrite 函数 (wdfusb.h)
[适用于 KMDF 和 UMDF]
WdfUsbTargetPipeFormatRequestForWrite 方法为 USB 输出管道生成写入请求,但不发送请求。
语法
NTSTATUS WdfUsbTargetPipeFormatRequestForWrite(
[in] WDFUSBPIPE Pipe,
[in] WDFREQUEST Request,
[in, optional] WDFMEMORY WriteMemory,
[in, optional] PWDFMEMORY_OFFSET WriteOffset
);
参数
[in] Pipe
通过调用 WdfUsbInterfaceGetConfiguredPipe获取的框架管道对象的句柄。
[in] Request
框架请求对象的句柄。 有关详细信息,请参阅以下“备注”部分。
[in, optional] WriteMemory
框架内存对象的句柄。 此对象表示一个缓冲区,其中包含将发送到管道的数据。 有关此缓冲区的详细信息,请参阅以下“备注”部分。
[in, optional] WriteOffset
指向调用方分配的 WDFMEMORY_OFFSET 结构的指针,该结构提供可选的字节偏移量和长度值。 框架使用这些值来确定数据传输的写入缓冲区中的起始地址和长度。 如果此指针 NULL,则数据传输从缓冲区的开头开始,传输大小为缓冲区大小。
返回值
WdfUsbTargetPipeFormatRequestForWrite 如果作成功,则返回STATUS_SUCCESS。 否则,此方法可能会返回以下值之一:
返回代码 | 描述 |
---|---|
|
检测到无效参数。 |
|
内存不足。 |
|
指定了无效的内存描述符、管道的类型无效、传输方向无效或指定的 I/O 请求已排队到 I/O 目标。 |
|
指定的 Offset 参数的偏移量无效。 |
|
Request 参数表示的 I/O 请求数据包(IRP),不提供足够的 IO_STACK_LOCATION 结构,使驱动程序能够转发请求。 |
此方法还可以 返回其他NTSTATUS 值。
如果驱动程序提供无效的对象句柄,则会发生 bug 检查。
言论
使用 WdfUsbTargetPipeFormatRequestForWrite(后跟 WdfRequestSend)同步或异步发送写入请求。 或者,使用 WdfUsbTargetPipeWriteSynchronously 方法同步发送写入请求。
指定的管道必须是输出管道,管道的 类型 必须 WdfUsbPipeTypeBulk 或 WdfUsbPipeTypeInterrupt。
可以转发驱动程序在 I/O 队列中收到的 I/O 请求,也可以创建并发送新请求。 在任一情况下,框架都需要请求对象和一些缓冲区空间。
转发驱动程序在 I/O 队列中收到的 I/O 请求:
- 为 WdfUsbTargetPipeFormatRequestForWrite 方法的 Request 参数指定收到的请求的句柄。
-
将收到的请求的输入缓冲区用于 WdfUsbTargetPipeFormatRequestForWrite 方法的 WriteMemory 参数。
驱动程序必须调用 WdfRequestRetrieveInputMemory 以获取表示请求的输入缓冲区的框架内存对象的句柄,并将该句柄用作 WriteMemory的值。
驱动程序通常会将收到的 I/O 请求划分为发送到 I/O 目标的较小请求,因此驱动程序可能会创建新请求。
创建新的 I/O 请求:
-
创建新的请求对象,并为 WdfUsbTargetPipeFormatRequestForWrite 方法的 Request 参数提供其句柄。
调用 WdfRequestCreate 来预分配一个或多个请求对象。 可以通过调用 WdfRequestReuse来重复使用这些请求对象。 驱动程序的 EvtDriverDeviceAdd 回调函数可以预分配设备的请求对象。
-
提供缓冲区空间,并为 WdfUsbTargetPipeFormatRequestForWrite 方法的 WriteMemory 参数提供缓冲区的句柄。
驱动程序必须将此缓冲区空间指定为框架管理的内存的 WDFMEMORY 句柄。 驱动程序可以执行以下作之一:
- 如果希望驱动程序将新缓冲区传递到 I/O 目标,请调用 WdfMemoryCreate 或 WdfMemoryCreatePreallocated 创建新的内存缓冲区。
- 如果希望驱动程序将缓冲区的内容传递给 I/O 目标,请调用 WdfRequestRetrieveInputMemory 以获取表示收到的 I/O 请求缓冲区的内存对象的句柄。
多次调用 使用相同请求的 WdfUsbTargetPipeFormatRequestForWrite 不会导致额外的资源分配。 因此,为了减少 WdfRequestCreate 将返回STATUS_INSUFFICIENT_RESOURCES的可能性,驱动程序的 EvtDriverDeviceAdd 回调函数可以调用 WdfRequestCreate 来预分配设备的一个或多个请求对象。 驱动程序随后可以重复使用(调用 WdfRequestReuse)、重新设置(调用 WdfUsbTargetPipeFormatRequestForWrite),并重新发送(调用 WdfRequestSend)每个请求对象,而不会危及STATUS_INSUFFICIENT_RESOURCES从以后调用 WdfRequestCreate返回值。 如果参数值不更改,则对 WdfUsbTargetPipeFormatRequestForWrite 的所有后续调用都将返回STATUS_SUCCESS。 (如果驱动程序每次不调用相同的请求格式方法,可能会分配其他资源。
有关在 I/O 请求完成后获取状态信息的信息,请参阅 获取完成信息。
有关 WdfUsbTargetPipeFormatRequestForWrite 方法和 USB I/O 目标的详细信息,请参阅 USB I/O 目标。
例子
下面的代码示例来自 kmdf_fx2 示例驱动程序。 此示例是 EvtIoWrite 回调函数,该函数将写入请求转发到 USB 管道。 该示例调用 WdfRequestRetrieveInputMemory 获取请求的输入缓冲区,然后格式化写入请求,以便可以将请求发送到 USB 管道。 接下来,该示例注册 CompletionRoutine 回调函数。 最后,它将请求发送到 USB 管道。
VOID
OsrFxEvtIoWrite(
IN WDFQUEUE Queue,
IN WDFREQUEST Request,
IN size_t Length
)
{
NTSTATUS status;
WDFUSBPIPE pipe;
WDFMEMORY reqMemory;
PDEVICE_CONTEXT pDeviceContext;
if (Length > TEST_BOARD_TRANSFER_BUFFER_SIZE) {
status = STATUS_INVALID_PARAMETER;
goto Exit;
}
pDeviceContext = GetDeviceContext(WdfIoQueueGetDevice(Queue));
pipe = pDeviceContext->BulkWritePipe;
status = WdfRequestRetrieveInputMemory(
Request,
&reqMemory
);
if (!NT_SUCCESS(status)){
goto Exit;
}
status = WdfUsbTargetPipeFormatRequestForWrite(
pipe,
Request,
reqMemory,
NULL
);
if (!NT_SUCCESS(status)) {
goto Exit;
}
WdfRequestSetCompletionRoutine(
Request,
EvtRequestWriteCompletionRoutine,
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) |