EVT_WDF_IO_QUEUE_IO_CANCELED_ON_QUEUE回调函数 (wdfio.h)

[适用于 KMDF 和 UMDF]

驱动程序的 EvtIoCanceledOnQueue 事件回调函数通知驱动程序,它必须完成框架已从 I/O 队列中删除的 I/O 请求。

语法

EVT_WDF_IO_QUEUE_IO_CANCELED_ON_QUEUE EvtWdfIoQueueIoCanceledOnQueue;

void EvtWdfIoQueueIoCanceledOnQueue(
  [in] WDFQUEUE Queue,
  [in] WDFREQUEST Request
)
{...}

参数

[in] Queue

I/O 队列对象的句柄。

[in] Request

请求对象的句柄。

返回值

没有

注解

驱动程序在调用 WdfIoQueueCreate 方法时注册 EvtIoCanceledOnQueue 回调函数。 有关调用 WdfIoQueueCreate的详细信息,请参阅 创建 I/O 队列

如果驱动程序为 I/O 队列注册 EvtIoCanceledOnQueue 回调函数,框架会在以下情况下调用回调函数:

在框架调用 EvtIoCanceledOnQueue 回调函数后,驱动程序 拥有 请求对象,并且必须 使用适当的状态代码完成 请求(EvtIoCanceledOnQueue 或更高版本)。 当框架调用 EvtIoCanceledOnQueue时,请求仍与 I/O 队列关联,但驱动程序无法重新排队请求。 即使驱动程序未在 EvtIoCanceledOnQueue中完成请求,请求的所有权仍与驱动程序保持一样。 如果驱动程序在 EvtIoCanceledOnQueue 返回后完成请求,则它无法调用 WdfIoQueueFindRequestWdfIoQueueRetrieveFoundRequest 重新获取请求的所有权,因为驱动程序已拥有请求的所有权。

通常,在 EvtIoCanceledOnQueue中,驱动程序 完成 I/O 请求,完成状态为STATUS_CANCELLED。

在某些情况下,驱动程序可能之前已将 I/O 请求重新排队到手动队列,可能等待信息。 例如,在其 请求处理程序之一中,驱动程序可能会放置与手动队列中挂起的 DMA 事务关联的 I/O 请求。 在这种情况下,驱动程序尝试在其 EvtIoCanceledOnQueue 回调中 取消 DMA 事务。 根据取消作的结果,驱动程序在 EvtIoCanceledOnQueue 或更高版本中以适当的状态完成请求。

该框架不会为框架从未传递到驱动程序的 I/O 请求调用驱动程序的 EvtIoCanceledOnQueue 回调函数。

框架在确定 I/O 请求已取消后立即调用 EvtIoCanceledOnQueue 回调函数,而不管驱动程序为 I/O 队列设置的 调度方法。 因此,框架可以调用 EvtIoCanceledOnQueue 回调函数:

  • 队列中使用 顺序调度的请求,即使驱动程序当前拥有队列中的另一个请求也是如此。
  • 驱动程序为其设置了 NumberOfPresentedRequests队列中的请求,即使驱动程序当前拥有最大请求数也是如此。
有关 EvtIoCanceledOnQueue 回调函数的详细信息,请参阅 取消 I/O 请求

除非设备或驱动程序 WDF_OBJECT_ATTRIBUTES 结构的 ExecutionLevel 成员设置为 WdfExecutionLevelPassive,否则可以在 IRQL <= DISPATCH_LEVEL 调用 EvtIoCanceledOnQueue 回调函数。

如果 IRQL PASSIVE_LEVEL,则框架会在 关键区域调用回调函数

例子

若要定义 EvtIoCanceledOnQueue 回调函数,必须首先提供一个函数声明,用于标识要定义的回调函数的类型。 Windows 为驱动程序提供一组回调函数类型。 使用回调函数类型声明函数有助于 驱动程序代码分析静态驱动程序验证程序(SDV)和其他验证工具查找错误,这是为 Windows作系统编写驱动程序的要求。

若要定义 EvtIoCanceledOnQueue 回调函数,必须先提供 SDV 和其他验证工具所需的函数声明。 以下示例摘自 PCMCIA 智能卡驱动程序 示例。

EVT_WDF_IO_QUEUE_IO_CANCELED_ON_QUEUE PscrEvtIoCanceledOnQueue;

PCMCIA 智能卡驱动程序 示例中,驱动程序使用手动队列来存储挂起的智能卡通知请求。 驱动程序提供 EvtIoCanceledOnQueue 回调函数,驱动程序在其中清除通知字段并完成请求。

_Use_decl_annotations_
VOID
PscrEvtIoCanceledOnQueue(
    WDFQUEUE  Queue,
    WDFREQUEST  Request
    )

{
    PDEVICE_EXTENSION DeviceExtension;
    PSMARTCARD_EXTENSION smartcardExtension;

    DeviceExtension = GetDeviceExtension(WdfIoQueueGetDevice(Queue));
    smartcardExtension = (PSMARTCARD_EXTENSION) &DeviceExtension->SmartcardExtension;

    //KdPrint(("Cancelled on queue 0x%x\n", WdfRequestWdmGetIrp(Request)));

    InterlockedExchangePointer(
                             &(smartcardExtension->OsData->NotificationIrp),
                             NULL
                             );

    WdfRequestComplete(Request, STATUS_CANCELLED);
}

EVT_WDF_IO_QUEUE_IO_CANCELED_ON_QUEUE 函数类型在 Wdfio.h 头文件中定义。 若要在运行代码分析工具时更准确地识别错误,请务必将 Use_decl_annotations 注释添加到函数定义。 Use_decl_annotations 批注可确保使用应用于头文件中 EVT_WDF_IO_QUEUE_IO_CANCELED_ON_QUEUE 函数类型的批注。 有关函数声明要求的详细信息,请参阅 使用 KMDF 驱动程序的函数角色类型声明函数。 有关 Use_decl_annotations的信息,请参阅 批注函数行为

要求

要求 价值
目标平台 普遍
最低 KMDF 版本 1.0
最低 UMDF 版本 2.0
标头 wdfio.h (包括 Wdf.h)
IRQL <= DISPATCH_LEVEL (请参阅“备注”部分)

另请参阅

WdfIoQueueCreate

WdfRequestForwardToIoQueue