天天看点

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时,状态迁移,这是一个艰难的旅途。

继续阅读