天天看點

Wdf架構之WdfObject狀态機(1)

Wdf架構之WdfObject狀态機(1)

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

繼續閱讀