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

本地或远程 I/O 目标对象的句柄,该对象是从先前调用 WdfDeviceGetIoTargetWdfIoTargetCreate 或从专用 I/O 目标提供的方法获取的。

[in, optional] Request

框架请求对象的句柄。 此参数是可选的,可以为 NULL。 有关更多信息,请参见下面的“备注”部分。

[in] IoctlCode

I/O 控制代码 (IOCTL) I/O 目标支持。

[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 在内部设备控制请求完成后返回,返回值为请求的完成状态值。 否则,此方法可能会返回以下值之一:

返回代码 说明
STATUS_INVALID_PARAMETER
检测到无效的参数。
STATUS_INFO_LENGTH_MISMATCH
RequestOptions 参数指向的WDF_REQUEST_SEND_OPTIONS结构的大小不正确。
STATUS_INVALID_DEVICE_REQUEST
请求已排队到 I/O 目标。
STATUS_INSUFFICIENT_RESOURCES
框架无法 (内存) 分配系统资源。
STATUS_IO_TIMEOUT
驱动程序提供了超时值,但请求未在分配的时间内完成。
STATUS_REQUEST_NOT_ACCEPTED
请求参数表示的 I/O 请求数据包 (IRP) 不提供足够的IO_STACK_LOCATION结构来允许驱动程序转发请求。
 

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

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

注解

非标准内部设备控制请求使用 IOCTL 代码标识要执行的操作,但请求不使用其他内部设备控制请求使用的标准输入和输出缓冲区。 如果要创建一组交互驱动程序,可以定义这组驱动程序如何使用请求的参数: OtherArg1OtherArg2OtherArg4

没有名为 OtherArg3 的参数,因为框架将这些参数与驱动程序IO_STACK_LOCATION结构中 Other.Parameters 联合的 Argument1Argument2Argument4 成员相关联。 该联合中的 Argument3 成员从 IoctlCode 参数接收值,因此它不适用于其他驱动程序提供的值。

使用 WdfIoTargetSendInternalIoctlOthersSynchronously 方法同步发送非标准内部设备控制请求。 若要异步发送内部设备控制请求,请使用 WdfIoTargetFormatRequestForInternalIoctlOthers,后跟 WdfRequestSend

有关内部设备控制请求的详细信息,请参阅 使用 I/O 控制代码

WdfIoTargetSendInternalIoctlOthersSynchronously 方法在请求完成之前不会返回,除非驱动程序在 RequestOptions 参数的WDF_REQUEST_SEND_OPTIONS结构中提供超时值,或者除非检测到错误。

可以转发驱动程序在 I/O 队列中收到的非标准内部设备控制请求,也可以创建并发送新请求。 在任一情况下,框架都需要请求对象,并且可能需要一些上下文空间。

转发驱动程序在 I/O 队列中收到的非标准内部设备控制请求:

  1. WdfIoTargetSendInternalIoctlOthersSynchronously 方法的 Request 参数指定接收的请求句柄。
  2. 将收到的请求的上下文信息用于 WdfIoTargetSendInternalIoctlOthersSynchronously 方法的 OtherArg1OtherArg2OtherArg4 参数。

    若要获取这些参数值,驱动程序必须调用 WdfRequestGetParameters 并使用返回的 WDF_REQUEST_PARAMETERS 结构的 DeviceIoControl 成员。

有关转发 I/O 请求的详细信息,请参阅 转发 I/O 请求

驱动程序通常将收到的 I/O 请求划分为发送到 I/O 目标的较小请求,因此驱动程序可能会创建新请求。

创建新的 I/O 请求:

  1. WdfIoTargetSendInternalIoctlOthersSynchronously 方法的 Request 参数提供 NULL请求句柄,或创建新的请求对象并提供其句柄:
    • 如果提供 NULL 请求句柄,框架将使用内部请求对象。 此方法易于使用,但驱动程序无法取消请求。
    • 如果调用 WdfRequestCreate 来创建一个或多个请求对象,可以通过调用 WdfRequestReuse 重用这些请求对象。 此方法使驱动程序的 EvtDriverDeviceAdd 回调函数能够预分配设备的请求对象。 此外,如果需要,另一个驱动程序线程可以调用 WdfRequestCancelSentRequest 来取消请求。

    无论驱动程序提供非 NULL 还是 NULL 请求参数,驱动程序都可以指定非 NULLRequestOptions 参数。 例如,可以使用 RequestOptions 参数指定超时值。

  2. 如果请求需要,请为 WdfIoTargetSendInternalIoctlOthersSynchronously 方法的 OtherArg1OtherArg2OtherArg4 参数提供上下文空间。

    驱动程序可以将此上下文空间指定为本地分配的缓冲区、WDFMEMORY 句柄或内存描述符列表 (MDL) 。 可以使用最方便的方法。

    可以使用以下方法来指定缓冲区空间:

    • 提供本地缓冲区。

      由于 WdfIoTargetSendInternalIoctlOthersSynchronous 以 同步方式处理 I/O 请求,因此驱动程序可以创建调用例程本地的请求缓冲区,如以下代码示例所示。

      WDF_MEMORY_DESCRIPTOR  MemoryDescriptor;
      MY_BUFFER_TYPE  MyBuffer;
      WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&MemoryDescriptor,
                                        (PVOID) &MyBuffer,
                                        sizeof(MyBuffer));
      
    • 提供 WDFMEMORY 句柄。

      调用 WdfMemoryCreateWdfMemoryCreatePreallocated 以获取框架托管内存的句柄,如以下代码示例所示。

      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

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

有关 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)
Library 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)

另请参阅

EvtDriverDeviceAdd

IO_STACK_LOCATION

WDF_MEMORY_DESCRIPTOR

WDF_MEMORY_DESCRIPTOR_INIT_BUFFER

WDF_REQUEST_PARAMETERS

WDF_REQUEST_SEND_OPTIONS

WdfDeviceGetIoTarget

WdfIoTargetCreate

WdfIoTargetFormatRequestForInternalIoctlOthers

WdfMemoryCreate

WdfMemoryCreatePreallocated

WdfRequestCancelSentRequest

WdfRequestCompleteWithInformation

WdfRequestCreate

WdfRequestGetParameters

WdfRequestRetrieveInputWdmMdl

WdfRequestRetrieveOutputWdmMdl

WdfRequestReuse

WdfRequestSend