EVT_WDF_OBJECT_CONTEXT_CLEANUP回调函数 (wdfobject.h)
[适用于 KMDF 和 UMDF]
驱动程序的 EvtCleanupCallback 事件回调函数删除驱动程序对对象的引用,以便可以删除该对象。
语法
EVT_WDF_OBJECT_CONTEXT_CLEANUP EvtWdfObjectContextCleanup;
void EvtWdfObjectContextCleanup(
[in] WDFOBJECT Object
)
{...}
参数
[in] Object
框架对象的句柄。
返回值
无
备注
驱动程序可以在 WDF_OBJECT_ATTRIBUTES 结构中指定 EvtCleanupCallback 回调函数。 此结构用作创建框架对象的所有框架方法(如 WdfDeviceCreate)的输入。
框架或驱动程序尝试删除对象时,框架会调用回调函数。
如果驱动程序已调用 WdfObjectReference 来增加对象的引用计数,则驱动程序必须提供调用 WdfObjectDereference 的 EvtCleanupCallback 回调函数。 此调用可确保对象的引用计数减为零,因此,框架可以调用驱动程序的 EvtDestroyCallback 回调函数,然后删除该对象。
如果驱动程序为对象提供 EvtCleanupCallback 回调函数和 EvtDestroyCallback 回调函数,则框架将首先调用 EvtCleanupCallback 回调函数。
在框架调用对象的 EvtCleanupCallback 回调函数后,驱动程序只能从其 EvtDestroyCallback 回调函数访问该对象。 但是,驱动程序不应尝试从其 EvtDestroyCallback 对对象调用方法。
当驱动程序创建对象时,它有时会分配特定于对象的内存缓冲区,并将缓冲区指针存储在对象的 上下文空间中。 驱动程序的 EvtCleanupCallback 或 EvtDestroyCallback 回调函数可以解除分配这些内存缓冲区。
通常,如果驱动程序不为对象调用 WdfObjectReference ,则对象的 EvtCleanupCallback 回调函数可以解除分配对象上下文分配。 在这种情况下,驱动程序不需要对象的 EvtDestroyCallback 回调函数。
删除对象时,框架还会删除该对象的子级。 除了一个例外,框架在调用子对象的 EvtCleanupCallback 例程之前调用其父对象的例程,因此当子对象的 EvtCleanupCallback 例程运行时,驱动程序可以保证父对象仍然存在。
此保证排序的例外情况适用于驱动程序在DISPATCH_LEVEL完成的 I/O 请求。 如果此类 I/O 请求对象具有一个或多个子级,并且必须在PASSIVE_LEVEL调用 其 EvtCleanupCallback 例程,则父请求可能会在其一个或多个子级之前删除。 如果对象必须等待某些内容完成或访问分页内存,则对象需要在PASSIVE_LEVEL处进行清理。
如果驱动程序在DISPATCH_LEVEL运行时尝试删除此类对象 (或此类对象的父对象) ,则框架会将 EvtCleanupCallback 排队到工作项,以便在PASSIVE_LEVEL稍后进行处理,然后调用父对象的清理回调而不确定是否已运行子对象的回调。
为了避免此行为可能导致的任何问题,驱动程序不应将请求对象设置为任何需要在PASSIVE_LEVEL清理的对象的父对象。 默认情况下,大多数对象的父对象为 WDFDEVICE,因此驱动程序应仅接受默认值。 通常,如果 WDFDEVICE 对象作为参数 (直接传递,或者作为结构) 的一部分传递给创建对象的方法,则 WDFDEVICE 是默认父级。 有关默认父级的完整列表,请参阅 Framework 对象的摘要。
如果上述异常不适用,框架会在调用父对象的 EvtCleanupCallback 回调函数之前调用子对象的 EvtCleanupCallback 回调函数。 接下来,如果子对象的引用计数为零,框架将调用子对象的 EvtDestroyCallback 回调函数。 最后,如果父对象的引用计数为零,框架将调用父对象的 EvtDestroyCallback 回调函数。
有关删除框架对象的详细信息,请参阅 框架对象生命周期。
通常,框架在 IRQL <= DISPATCH_LEVEL调用 EvtCleanupCallback 回调函数。 但是,在以下情况下,框架在 IRQL = PASSIVE_LEVEL调用回调函数:
- 对象的句柄类型为 WDFDEVICE、WDFDRIVER、WDFDPC、WDFINTERRUPT、WDFIOTARGET、WDFQUEUE、WDFSTRING、WDFTIMER 或 WDFWORKITEM。
- 对象的句柄类型为 WDFMEMORY 或 WDFLOOKASIDE,驱动程序已将 PoolType 参数的 PagedPool 指定为 WdfMemoryCreate 或 WdfLookasideListCreate。
同样,当删除计时器对象时,无论是显式删除还是因为计时器的父对象被删除,那么在调用计时器的 EvtCleanupCallback 回调函数之前,框架将等待计时器的 EvtTimerFunc 事件回调函数的所有实例都已返回。
从框架版本 1.9 开始, wdfroletypes.h 头文件包含 EvtCleanupCallback 回调函数的一些特定于对象的替代函数类型。 这些替代类型可帮助验证工具确定驱动程序是否正确使用回调函数。 使用下表确定要使用的函数类型。
对象类型 | 函数类型 |
---|---|
设备对象 | EVT_WDF_DEVICE_CONTEXT_CLEANUP |
I/O 队列对象 | EVT_WDF_IO_QUEUE_CONTEXT_CLEANUP_CALLBACK |
File 对象 | EVT_WDF_FILE_CONTEXT_CLEANUP_CALLBACK |
所有其他对象 | EVT_WDF_OBJECT_CONTEXT_CLEANUP |
要求
要求 | 值 |
---|---|
目标平台 | 通用 |
最低 KMDF 版本 | 1.0 |
最低 UMDF 版本 | 2.0 |
标头 | wdfobject.h (包括 Wdf.h) |
IRQL | 请参见“备注”部分。 |