
這篇文章并不是研究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時,狀态遷移,這是一個艱難的旅途。