WdfIoTargetSendInternalIoctlOthersSynchronously 函数 (wdfiotarget.h)
[仅适用于 KMDF]
WdfIoTargetSendInternalIoctlOthersSynchronously 方法生成非标准内部设备控制请求,并将其同步发送到 I/O 目标。
语法
NTSTATUS WdfIoTargetSendInternalIoctlOthersSynchronously(
[in] WDFIOTARGET IoTarget,
[in, optional] WDFREQUEST Request,
[in] ULONG IoctlCode,
[in, optional] PWDF_MEMORY_DESCRIPTOR OtherArg1,
[in, optional] PWDF_MEMORY_DESCRIPTOR OtherArg2,
[in, optional] PWDF_MEMORY_DESCRIPTOR OtherArg4,
[in, optional] PWDF_REQUEST_SEND_OPTIONS RequestOptions,
[out, optional] PULONG_PTR BytesReturned
);
参数
[in] IoTarget
从先前调用 WdfDeviceGetIoTarget 或 WdfIoTargetCreate或从专用 I/O 目标提供的方法获取的本地或远程 I/O 目标对象的句柄。
[in, optional] Request
框架请求对象的句柄。 此参数是可选的,可以 NULL。 有关详细信息,请参阅以下“备注”部分。
[in] IoctlCode
I/O 目标支持的 I/O 控制代码(IOCTL)。
[in, optional] OtherArg1
指向描述包含上下文信息的内存缓冲区的 WDF_MEMORY_DESCRIPTOR 结构的指针。 此参数是可选的,可以 NULL。
[in, optional] OtherArg2
指向描述包含上下文信息的内存缓冲区的WDF_MEMORY_DESCRIPTOR结构的指针。 此参数是可选的,可以 NULL。
[in, optional] OtherArg4
指向描述包含上下文信息的内存缓冲区的WDF_MEMORY_DESCRIPTOR结构的指针。 此参数是可选的,可以 NULL。
[in, optional] RequestOptions
指向调用方分配 WDF_REQUEST_SEND_OPTIONS 结构的指针,该结构指定请求的选项。 此指针是可选的,可以 NULL。 有关详细信息,请参阅以下“备注”部分。
[out, optional] BytesReturned
指向接收信息(例如传输的字节数)的位置的指针,另一个驱动程序通过调用 WdfRequestCompleteWithInformation完成请求时提供的信息。 此指针是可选的,可以 NULL。
返回值
如果操作成功,WdfIoTargetSendInternalIoctlOthersSynchronously 内部设备控制请求完成后返回,返回值为请求的完成状态值。 否则,此方法可能会返回以下值之一:
返回代码 | 描述 |
---|---|
|
检测到无效参数。 |
|
RequestOptions 参数指向的 WDF_REQUEST_SEND_OPTIONS 结构的大小不正确。 |
|
请求已排队到 I/O 目标。 |
|
框架无法分配系统资源(通常是内存)。 |
|
驱动程序提供了超时值,请求未在分配的时间内完成。 |
|
Request 参数表示的 I/O 请求数据包(IRP),不提供足够的 IO_STACK_LOCATION 结构,使驱动程序能够转发请求。 |
此方法还可以返回其他
如果驱动程序提供无效的对象句柄,则会发生 bug 检查。
言论
非标准内部设备控制请求使用 IOCTL 代码来标识要执行的操作,但请求不使用其他内部设备控制请求使用的标准输入和输出缓冲区。 如果要创建一组交互驱动程序,则可以定义此组驱动程序如何使用请求的参数:OtherArg1、OtherArg2,以及 OtherArg4。
没有 OtherArg3 的参数,因为框架将这些参数与 Argument1、Argument2相关联,Argument4 driver 的 Other.Parameters 联合的成员在驱动程序的 IO_STACK_LOCATION 结构中。 该联合中的 Argument3 成员从 IoctlCode 参数接收值,因此它不适用于其他驱动程序提供的值。
使用 WdfIoTargetSendInternalIoctlOthersSynchronously 方法同步发送非标准内部设备控制请求。 若要异步发送内部设备控制请求,请使用 WdfIoTargetFormatRequestForInternalIoctlOthers,后跟 WdfRequestSend。
有关内部设备控制请求的详细信息,请参阅 使用 I/O 控制代码。
WdfIoTargetSendInternalIoctlOthersSynchronously 方法在请求完成之前不会返回,除非驱动程序在 RequestOptions 参数的 WDF_REQUEST_SEND_OPTIONS 结构中提供超时值,或者除非检测到错误。
可以转发驱动程序在 I/O 队列中收到的非标准内部设备控制请求,也可以创建并发送新请求。 在任一情况下,框架都需要请求对象,并且可能需要一些上下文空间。
转发驱动程序在 I/O 队列中收到的非标准内部设备控制请求:
- 为 WdfIoTargetSendInternalIoctlOthersSynchronously 方法的 Request 参数指定收到的请求的句柄。
-
对 WdfIoTargetSendInternalIoctlOthersSynchronously 方法的 OtherArg1、OtherArg2和OtherArg4 参数使用收到的请求的上下文信息。
若要获取这些参数值,驱动程序必须调用 WdfRequestGetParameters,并使用返回 WDF_REQUEST_PARAMETERS 结构的 DeviceIoControl 成员。
驱动程序通常会将收到的 I/O 请求划分为发送到 I/O 目标的较小请求,因此驱动程序可能会创建新请求。
创建新的 I/O 请求:
-
为 WdfIoTargetSendInternalIoctlOthersSynchronously 方法的 Request 参数提供 NULL 请求句柄,或者创建新的请求对象并提供其句柄:
- 如果提供 NULL 请求句柄,框架将使用内部请求对象。 此方法易于使用,但驱动程序无法取消请求。
- 如果调用 WdfRequestCreate 来创建一个或多个请求对象,可以通过调用 WdfRequestReuse来重复使用这些请求对象。 通过此方法,驱动程序的 EvtDriverDeviceAdd 回调函数可以预分配设备的请求对象。 此外,另一个驱动程序线程可以根据需要调用 WdfRequestCancelSentRequest 以取消请求。
驱动程序可以指定非NULLRequestOptions 参数,无论驱动程序提供非NULL 还是 NULLRequest 参数。 例如,可以使用 RequestOptions 参数指定超时值。
-
提供 WdfIoTargetSendInternalIoctlOthersSynchronously 方法的 OtherArg1、OtherArg2的上下文空间,并 OtherArg4 参数(如果请求需要这些参数)。
驱动程序可以将此上下文空间指定为本地分配的缓冲区、WDFMEMORY 句柄或内存描述符列表(MDL)。 可以使用哪种方法最方便。
可以使用以下方法来指定缓冲区空间:
-
提供本地缓冲区。
由于 WdfIoTargetSendInternalIoctlOthersSynchronously 同步处理 I/O 请求,因此驱动程序可以创建本地调用例程的请求缓冲区,如以下代码示例所示。
WDF_MEMORY_DESCRIPTOR MemoryDescriptor; MY_BUFFER_TYPE MyBuffer; WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&MemoryDescriptor, (PVOID) &MyBuffer, sizeof(MyBuffer));
-
提供 WDFMEMORY 句柄。
调用 WdfMemoryCreate 或 WdfMemoryCreatePreallocated 以获取框架托管内存的句柄,如以下代码示例所示。
WDF_MEMORY_DESCRIPTOR MemoryDescriptor; WDFMEMORY MemoryHandle = NULL; status = WdfMemoryCreate(NULL, NonPagedPool, POOL_TAG, MY_BUFFER_SIZE, &MemoryHandle, NULL); WDF_MEMORY_DESCRIPTOR_INIT_HANDLE(&MemoryDescriptor, MemoryHandle, NULL);
-
提供 MDL。
驱动程序可以通过调用 WdfRequestRetrieveInputWdmMdl 和 WdfRequestRetrieveOutputWdmMdl来获取与收到的 I/O 请求关联的 MDL。
-
提供本地缓冲区。
有关 WdfIoTargetSendInternalIoctlOthersSynchronously的详细信息,请参阅 向常规 I/O 目标发送 I/O 请求。
有关 I/O 目标的详细信息,请参阅 使用 I/O 目标。
例子
下面的代码示例初始化 IEEE 1394 IRB 结构,使用结构的地址初始化 WDF_MEMORY_DESCRIPTOR 结构,然后调用 WdfIoTargetSendInternalIoctlOthersSynchronously。
WDF_MEMORY_DESCRIPTOR descriptor;
IRB Irb;
Irb.FunctionNumber = REQUEST_ALLOCATE_ADDRESS_RANGE;
Irb.Flags = 0;
Irb.u.AllocateAddressRange.Mdl = pAsyncAddressData->pMdl;
Irb.u.AllocateAddressRange.fulFlags = fulFlags;
Irb.u.AllocateAddressRange.nLength = nLength;
Irb.u.AllocateAddressRange.MaxSegmentSize = MaxSegmentSize;
Irb.u.AllocateAddressRange.fulAccessType = fulAccessType;
Irb.u.AllocateAddressRange.fulNotificationOptions = fulNotificationOptions;
Irb.u.AllocateAddressRange.Callback = NULL;
Irb.u.AllocateAddressRange.Context = NULL;
Irb.u.AllocateAddressRange.Required1394Offset = *Required1394Offset;
Irb.u.AllocateAddressRange.FifoSListHead = NULL;
Irb.u.AllocateAddressRange.FifoSpinLock = NULL;
Irb.u.AllocateAddressRange.AddressesReturned = 0;
Irb.u.AllocateAddressRange.p1394AddressRange = pAsyncAddressData->AddressRange;
Irb.u.AllocateAddressRange.DeviceExtension = deviceExtension;
WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(
&descriptor,
&Irb,
sizeof (IRB)
);
ntStatus = WdfIoTargetSendInternalIoctlOthersSynchronously(
IoTarget,
NULL,
IOCTL_1394_CLASS,
&descriptor,
NULL,
NULL,
NULL,
NULL
);
要求
要求 | 价值 |
---|---|
目标平台 | 普遍 |
最低 KMDF 版本 | 1.0 |
标头 | wdfiotarget.h (包括 Wdf.h) |
库 | Wdf01000.sys(请参阅框架库版本控制。 |
IRQL | PASSIVE_LEVEL |
DDI 符合性规则 | DeferredRequestCompleted(kmdf),DriverCreate(kmdf),IoctlReqs(kmdf),KmdfIrql(kmdf), KmdfIrql2(kmdf)、KmdfIrqlExplicit(kmdf)、ReadReqs(kmdf)、RequestCompleted(kmdf)、RequestCompletedLocal(kmdf)、WriteReqs(kmdf) |
另请参阅
WDF_MEMORY_DESCRIPTOR_INIT_BUFFER
WdfIoTargetFormatRequestForInternalIoctlOthers
WdfRequestCompleteWithInformation