这篇文章并不是研究WDF对象的继承关系,只是借由FxDriver和FxObject引出本文的主题----WDF对象状态机。可是,为什么我们需要分析WDF对象状态机?大家是否记得在创建WDF框架对象时,可能需要为WDF对象指定WDF_OBJECT_ATTRIBUTES属性并设置EvtCleanupCallback/EvtDestroyCallback回调函数?当框架调用WdfObjectDereference减少引用计数时,会调用EvtCleanupCallback回调函数;更重要的是,当调用WdfObjectDelete时,会同时自子对象开始向父对象依次调用EvtCleanupCallback/EvtDestroyCallback,并最终释放WdfObject对象。为了实现上诉目标,WDF框架采用一种相对复杂的状态机机制,记录WdfObject对象从调用WdfObjectCreate时,开始进入状态机;调用operate::delete时,离开状态机及中间各个状态的迁移。本文的立意就是分析各状态之间的迁移~
我们以WdfDriverCreate为例,从调用WdfObjectCreate函数,也就是创建WdfObject进入状态机开始。
_Must_inspect_result_
__drv_maxIRQL(PASSIVE_LEVEL)
NTSTATUS
WDFEXPORT(WdfDriverCreate)(
PWDF_DRIVER_GLOBALS DriverGlobals,
MdDriverObject DriverObject,
PCUNICODE_STRING RegistryPath,
PWDF_OBJECT_ATTRIBUTES DriverAttributes,
PWDF_DRIVER_CONFIG DriverConfig,
WDFDRIVER* Driver
)
{
//...
// FxDriver stores the driver wide configuration
FxInitialize(pFxDriverGlobals, DriverObject, RegistryPath, DriverConfig);
// FxDriver stores the driver wide configuration
pDriver = new(pFxDriverGlobals, DriverAttributes)
FxDriver(DriverObject, DriverConfig, pFxDriverGlobals);
//...
}
由于FxDriver类及其父类FxNonPagedObject都没有重载operate new操作符,他们的公共基类FxObject重载了operate new操作符,因此上面的代码会进入公共基类的FxObject::operate new函数:
virtual
~FxObject(
VOID
);
PVOID
__inline
operator new(
__in size_t Size,
__in PFX_DRIVER_GLOBALS FxDriverGlobals,
__in FxObjectType Type
);
等等,是不是觉得参数数量对不上?咋一看,operate new有3个参数,在WdfDriverCreate中调用new操作符时只传了2个参数。其实,第一个参数Size由编译器在编译阶段计算出大小并传给operate::new(参考<竹林蹊径 第六章 内核驱动c++编程 第6.1.2节>)。调用operate::new操作符只是根据FxDriver对象的大小分配相应的内存,之后会调用FxDriver::FxDriver()构造函数初始化刚分配的内存块:
FxDriver::FxDriver(
__in MdDriverObject ArgDriverObject,
__in PWDF_DRIVER_CONFIG DriverConfig,
__in PFX_DRIVER_GLOBALS FxDriverGlobals
) :
FxNonPagedObject(FX_TYPE_DRIVER, sizeof(FxDriver), FxDriverGlobals), /*调用基类构造函数*/
m_DriverObject(ArgDriverObject), /*初始化*FxDriver!m_DriverObject成员/
m_CallbackMutexLock(FxDriverGlobals) /*初始化FxDriver!m_CallbackMutexLock成员*/
{/*FxDriver的构造函数*/}
FxDriver构造函数将m_DriverObject初始化为DriverEntry的参数,然后调用基类FxNonPagedObject::FxNonPagedObject()构造函数:
class FxNonPagedObject : public FxObject
{
public:
FxNonPagedObject(
__in WDFTYPE Type,
__in USHORT Size,
__in PFX_DRIVER_GLOBALS FxDriverGlobals
) :
FxObject(Type, Size, FxDriverGlobals)
{}
}
不过FxNonPagedObject::FxNonPagedObject()构造函数并没有做什么,只是把传入的参数原封不动的传给它的基类构造函数FxObject::FxObject();
FxObject::FxObject(
__in WDFTYPE Type,
__in USHORT Size,
__in PFX_DRIVER_GLOBALS FxDriverGlobals
) :
m_Type(Type),
m_ObjectSize((USHORT) WDF_ALIGN_SIZE_UP(Size, MEMORY_ALLOCATION_ALIGNMENT)),
m_Globals(FxDriverGlobals)
#if FX_CORE_MODE==FX_CORE_USER_MODE
#ifndef INLINE_WRAPPER_ALLOCATION
,m_COMWrapper(NULL)
#endif
#endif
{
//重点出现了
Construct(FALSE);
}
FxObject::FxObject()
构造函数将FxObject!m_Globals初始化为WDF框架驱动的全局变量pFxDriverGlobals。
上面简单捋了一下构造函数调用链,现在开始正题,设置WdfObject状态标志。
VOID
__inline
FxObject::Construct(
__in BOOLEAN Embedded
)
{
m_Refcnt = 1;
m_ObjectState = FxObjectStateCreated; //设置状态机
m_ObjectFlags = 0;
m_ParentObject = NULL;
InitializeListHead(&m_ChildListHead);
InitializeListHead(&m_ChildEntry);
m_DisposeSingleEntry.Next = NULL;
m_DeviceBase = NULL;
VerifyConstruct(m_Globals, Embedded);
}
Construct中设置m_ObjectState为
FxObjectStateCreated,至此,WdfObject正式被状态机管理。
这一篇比较简单,后面将分析调用WdfObjectDelete时,状态迁移,这是一个艰难的旅途。