[适用于 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 回调函数,框架会在以下情况下调用回调函数:
- 请求处理程序 从 I/O 队列接收 I/O 请求, 驱动程序调用 WdfRequestForwardToIoQueue、WdfRequestForwardToParentDeviceIoQueue或 WdfRequestRequeue,以将请求重新排队到为其注册 EvtIoCanceledOnQueue 回调函数的 I/O 队列, 随后取消关联的 I/O作。
- 驱动程序的 EvtIoInCallerContext 回调函数接收 I/O 请求, 驱动程序调用 WdfDeviceEnqueueRequest 将请求传回框架,然后框架将请求置于 EvtIoCanceledOnQueue 回调函数注册的 I/O 队列中,随后取消关联的 I/O作。
通常,在 EvtIoCanceledOnQueue中,驱动程序 完成 I/O 请求,完成状态为STATUS_CANCELLED。
在某些情况下,驱动程序可能之前已将 I/O 请求重新排队到手动队列,可能等待信息。 例如,在其 请求处理程序之一中,驱动程序可能会放置与手动队列中挂起的 DMA 事务关联的 I/O 请求。 在这种情况下,驱动程序尝试在其 EvtIoCanceledOnQueue 回调中 取消 DMA 事务。 根据取消作的结果,驱动程序在 EvtIoCanceledOnQueue 或更高版本中以适当的状态完成请求。
该框架不会为框架从未传递到驱动程序的 I/O 请求调用驱动程序的 EvtIoCanceledOnQueue 回调函数。
框架在确定 I/O 请求已取消后立即调用 EvtIoCanceledOnQueue 回调函数,而不管驱动程序为 I/O 队列设置的 调度方法。 因此,框架可以调用 EvtIoCanceledOnQueue 回调函数:
- 队列中使用 顺序调度的请求,即使驱动程序当前拥有队列中的另一个请求也是如此。
- 驱动程序为其设置了 NumberOfPresentedRequests队列中的请求,即使驱动程序当前拥有最大请求数也是如此。
除非设备或驱动程序 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 (请参阅“备注”部分) |