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 来增加对象的引用计数,则驱动程序必须提供调用 WdfObjectDereferenceEvtCleanupCallback 回调函数。 此调用可确保对象的引用计数减为零,因此,框架可以调用驱动程序的 EvtDestroyCallback 回调函数,然后删除该对象。

如果驱动程序为对象提供 EvtCleanupCallback 回调函数和 EvtDestroyCallback 回调函数,则框架将首先调用 EvtCleanupCallback 回调函数。

在框架调用对象的 EvtCleanupCallback 回调函数后,驱动程序只能从其 EvtDestroyCallback 回调函数访问该对象。 但是,驱动程序不应尝试从其 EvtDestroyCallback 对对象调用方法。

当驱动程序创建对象时,它有时会分配特定于对象的内存缓冲区,并将缓冲区指针存储在对象的 上下文空间中。 驱动程序的 EvtCleanupCallbackEvtDestroyCallback 回调函数可以解除分配这些内存缓冲区。

通常,如果驱动程序不为对象调用 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 指定为 WdfMemoryCreateWdfLookasideListCreate
删除工作项对象时,无论是显式删除还是因为删除工作项的父对象,在调用工作项的 EvtCleanupCallback 回调函数之前,框架将等待工作项的 EvtWorkItem 回调函数的所有实例都已返回。 有关详细信息,请参阅 WdfWorkItemEnqueue

同样,当删除计时器对象时,无论是显式删除还是因为计时器的父对象被删除,那么在调用计时器的 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 请参见“备注”部分。

另请参阅

EvtDestroyCallback

WDF_OBJECT_ATTRIBUTES

WdfObjectDereference

WdfObjectReference

WdfWorkItemFlush