EvtCleanupCallback
来源:互联网 发布:付费语音问答源码 编辑:程序博客网 时间:2024/06/03 14:58
EvtCleanupCallback
一个驱动程序的EvtCleanupCallback事件回调函数移除/清除驱动程序的引用计数,因此该对象可以被删除。
语法
EVT_WDF_OBJECT_CONTEXT_CLEANUP EvtCleanupCallback;VOID EvtCleanupCallback( __in WDFOBJECT Object){ ... }
参数
- Object [in]
指向框架对象的句柄
返回值
无评论
驱动程序可以在WDF_OBJECT_ATTRIBUTES结构体中指定一个EvtCleanupCallback的回调函数。这个结构体是用来作为框架创建框架对象方法的输入参数,框架对象创建如WdfDeviceCreate。
当框架或设备删除对象时调用EvtCleanupCallback回调函数。
如果驱动程序调用了WdfObjectReference增加对象引用计数,那么驱动程序必须提供一个EvtCleanupCallback回调函数,并调用WdfObjectDereference。这个调用保证当对象引用计数减少到0时,会导致框架调用驱动程序的EvtDestroyCallback回调函数删除对象。
如果驱动程序同时支持EvtCleanupCallback和EvtDestroyCallback回调函数,框架将先调用EvtCleanupCallback回调函数,然后在调用EvtDestroyCallback回调函数。
当框架调用了对象的EvtCleanupCallback回调函数后,驱动程序只能通过EvtDestroyCallback回调函数访问该对象。尽管如此,驱动程序不应该试图通过EvtDestroyCallback回调函数去调用对象的方法.
当驱动程序创建一个对象时,有时分配了指定对象内存缓冲区并把缓冲区指针存储在上下文空间(context space)中。驱动程序的EvtCleanupCallback和EvtDestroyCallback回调函数可以删除这些内存。
典型的,如果你的驱动程序不调用对象WdfObjectReference时,这个对象EvtCleanupCallback回调函数可以删除对象上下文空间。在这种情况下,驱动程序不需要为这个对象定义EvtDestroyCallback回调函数。
当对象被删除时,框架也会把该对象的子对象也删除。但有一个例外,框架调用父对象的EvtDestroyCallback函数之前调用了子对象的EvtDestroyCallback函数,因此驱动程序需要保证当调用子对象的EvtCleanupCallback函数正在运行时父对象仍然存在。
这个类外保证适用于I/O序列请求驱动在IRQL =DISPATCH_LEVEL完成(The exception to this guaranteed ordering applies to I/O requests that the driver completes at DISPATCH_LEVEL)。如果这样的I/O请求对象拥有一个或更多子对象的EvtCleanupCallback函数被调用必须在IRQL =PASSIVE_LEVEL被调用L,父对象的请求可能在任何子对象的请求之前被删除。对象请求清除在运行界别为PASSIVE_LEVEL,如果它需要访问也内存必须等待其他事情完成( An object requires cleanup at PASSIVE_LEVEL if it must wait for something to complete or if it accesses paged memory.)。
当对象运行在DISPATCH_LEVEL级别时如果驱动试图删除对象(或该对象的父对象),框架队列的EvtCleanupCallback稍后在PASSIVE_LEVEL进行处理工作,然后父对象调用清理回调(EvtCleanupCallback)而不需要确认是否子对象的回调函数是否在运行(If the driver attempts to delete such an object (or the parent of such an object) while it is running at DISPATCH_LEVEL, the framework queues theEvtCleanupCallback to a work item for later processing at PASSIVE_LEVEL and then calls the cleanup callback for the parent object without determining whether the callbacks for the children have run)。
为了避免可能造成这种行为的任何问题,驱动程序不应该设置请求对象为任何其他对象的父对象在PASSIVE_LEVEL级别请求清理。默认情况下WDFDEVICE是绝大多数对象的父对象,因此驱动程序应该仅仅接受默认设置。通常,如果DEFDEVICE对象作为参数传递给其他对象的创建方法时,WDFDEVICE就是默认的父对象。对于默认父的完整列表,见Summary of Framework Objects。
如果上述异常不适用(不是发生上面的异常),框架调用父对象的EvtCleanupCallback回调函数之前调用子对象的EvtCleanupCallback回调函数。然后,如果子对象引用计数为0,框架调用子对象的EvtDestroyCallback回调函数。最后,如果度对象引用计数为0,框架调用用父对象的EvtDestroyCallback回调函数。
For more information about deleting framework objects, see Framework Object Life Cycle.
典型的,框架在IRQL<=DISPATCH_LEVEL时调用回调EvtCleanupCallback函数。尽管如此,框架在调用IRQL = PASSIVE_LEVEL时调用回调函数情况如下:
* 对象句柄类型是WDFDEVICE, WDFDRIVER, WDFDPC, WDFINTERRUPT, WDFIOTARGET, WDFQUEUE, WDFSTRING, WDFTIMER, or WDFWORKITEM。
* 对象句柄类型是WDFMEMORY or WDFLOOKASIDE,并且驱动制定了PagedPool for thePoolType parameter toWdfMemoryCreate or WdfLookasideListCreate。
从框架版本为1.9开始,wdfroletypes.h头文件包含了一些选择(the wdfroletypes.h header file contains some alternative),EvtCleanupCallback函数的指定类型对象、函数类型。这些替代类型可帮助验证工具以确定驱动程序是否正确使用回调函数,使用下标来确定使用哪种类型函数。
Device object
EVT_WDF_DEVICE_CONTEXT_CLEANUP
I/O queue object
EVT_WDF_IO_QUEUE_CONTEXT_CLEANUP_CALLBACK
File object
EVT_WDF_FILE_CONTEXT_CLEANUP_CALLBACK
All other objects
EVT_WDF_OBJECT_CONTEXT_CLEANUP
示例
The function type is declared in Wdfobject.h, as follows:
typedef VOID (EVT_WDF_OBJECT_CONTEXT_CLEANUP)( IN WDFOBJECT Object );
To define an EvtCleanupCallback callback function that is named MyCleanupCallback, you must first provide a function declaration that SDV and other verification tools require, as follows:
EVT_WDF_OBJECT_CONTEXT_CLEANUP MyCleanupCallback;
Then, implement your callback function as follows:
VOID MyCleanupCallback ( IN WDFOBJECTObject ) {...}
另请参见
- WdfObjectDereference
- WdfObjectReference
- WDF_OBJECT_ATTRIBUTES
- EvtDestroyCallback