框架对象上下文空间
对象上下文空间 是驱动程序可以分配和分配给对象的额外、不可分页的内存空间。 每个基于框架的驱动程序都可以为驱动程序接收或创建的每个框架对象创建一个或多个特定于对象的上下文空间。
基于框架的驱动程序应在数据所属对象的上下文空间中按值或指针存储所有特定于对象的数据。
例如,USB 设备的驱动程序可能会为其框架设备对象创建上下文空间。 在上下文空间中,驱动程序可能会存储设备特定的信息,例如设备的 USB_DEVICE_DESCRIPTOR 和 USB_CONFIGURATION_DESCRIPTOR 结构,以及表示设备接口管道的 集合对象的 句柄。
框架不会将框架对象从一个驱动程序传递到另一个驱动程序,因此不能使用对象的上下文空间在两个驱动程序之间传递数据。
若要定义对象的上下文空间,必须创建一个或多个结构。 每个结构表示单独的上下文空间。 驱动程序将使用每个结构成员来存储一段特定于对象的信息。 此外,驱动程序必须要求框架为每个结构生成 访问器方法 。 此访问器方法接受对象句柄作为输入,并返回对象的上下文空间的地址。
每当驱动程序调用对象创建方法(如 WdfDeviceCreate)时,该方法会选择性地分配上下文空间。 所有对象创建方法都接受可选的 WDF_OBJECT_ATTRIBUTES 结构作为输入。 此结构描述希望框架为对象分配的上下文空间。
若要在驱动程序调用对象的创建方法后向对象添加额外的上下文空间,驱动程序可以调用 WdfObjectAllocateContext 方法,该方法与对象创建方法一样,接受 WDF_OBJECT_ATTRIBUTES 结构作为输入。
当框架为对象分配上下文空间时,它还对上下文空间进行零初始化。
当框架或驱动程序删除框架对象时,框架将删除该对象的所有上下文空间。
如果驱动程序使用上下文空间来存储指向驱动程序在创建对象时分配的缓冲区的指针,则驱动程序应提供 一个 EvtCleanupCallback 函数,该函数在删除对象时解除分配缓冲区。
若要为驱动程序创建的对象定义对象的上下文空间结构和访问器方法,驱动程序必须使用以下步骤:
定义描述要存储的数据的结构。 例如,如果要为驱动程序的设备对象创建上下文数据,驱动程序可能会定义一个名为 MY_DEVICE_CONTEXT 的结构。
使用 WDF_DECLARE_CONTEXT_TYPE 宏或 WDF_DECLARE_CONTEXT_TYPE_WITH_NAME 宏。 这两个宏都执行以下操作:
- 创建并初始化 WDF_OBJECT_CONTEXT_TYPE_INFO 结构。
- 定义一个访问器方法,驱动程序稍后将使用该方法访问对象的上下文空间。 访问器方法的返回值是指向对象的上下文空间的指针。
WDF_DECLARE_CONTEXT_TYPE宏根据结构的名称创建访问器方法的名称。 例如,如果上下文结构的名称MY_DEVICE_CONTEXT,则宏将创建一个名为 WdfObjectGet_MY_DEVICE_CONTEXT 的访问器方法。
使用 WDF_DECLARE_CONTEXT_TYPE_WITH_NAME 宏可以指定访问器方法的名称。 例如,可以将 GetMyDeviceContext 指定为设备对象的上下文访问器方法的名称。
调用 WDF_OBJECT_ATTRIBUTES_INIT 以初始化对象的 WDF_OBJECT_ATTRIBUTES 结构。
使用 WDF_OBJECT_ATTRIBUTES_SET_CONTEXT_TYPE 宏将 WDF_OBJECT_ATTRIBUTES 结构的 ContextTypeInfo 成员设置为 WDF_OBJECT_CONTEXT_TYPE_INFO 结构的地址。
调用对象创建方法,例如 WdfDeviceCreate。
驱动程序创建对象后,驱动程序可以随时调用 WdfObjectAllocateContext ,以向对象添加额外的上下文空间。
由于步骤 1 和步骤 2 定义全局数据结构并创建驱动程序可调用的例程,因此驱动程序必须在声明全局数据的驱动程序区域中完成这些步骤,通常为头文件。 这些步骤不得从驱动程序的例程中完成。
驱动程序必须从创建对象的驱动程序例程(例如调用 WdfDeviceCreate 的 EvtDriverDeviceAdd 回调函数)中完成步骤 3、4 和 5。
框架可以代表驱动程序创建两种类型的对象(框架请求对象和框架文件对象)。 驱动程序可以通过分别调用 WdfDeviceInitSetRequestAttributes 和 WdfDeviceInitSetFileObjectConfig 来注册这些对象的上下文空间。 驱动程序还可以调用 WdfObjectAllocateContext 来为这些对象分配上下文空间。
创建对象后,驱动程序可以通过使用以下任一技术获取指向对象的上下文空间的指针:
使用 WDF_DECLARE_CONTEXT_TYPE 或 WDF_DECLARE_CONTEXT_TYPE_WITH_NAME 宏调用在上述过程中的步骤 2 中创建的上下文访问器方法。
调用 WdfObjectGetTypedContext,提供驱动程序定义的上下文结构的名称。
如果驱动程序具有上下文空间指针,则可以通过调用 WdfObjectContextGetObject 找到上下文空间所属的对象。