在Kernel Mode使用c++運算子new必須自已實做。--------------------------------------------------------------------------------------------------------------------------比較快的做法,限定為可分頁且不在memory上加Taginline  void* __cdecl operator new(size_t Size)  {    KIRQL irql = KeGetCurrentIrql();    // 呼叫 ExAllocatePoolWithTag的irql必須<= DISPATCH_LEVEL     ASSERT(irql <= DISPATCH_LEVEL);    if (irql == DISPATCH_LEVEL)  {     DbgPrint("A caller executing at DISPATCH_LEVEL must specify a NonPagedXxx value for   土地買賣PoolType ");      return NULL;   }    if (Size == 0)    {        return NULL;    }    return ExAllocatePoolWithTag(                            PagedPool,  // 在這裡限定使用PagedPool的memory                            static_cast (Size),  酒店工作                            NULL);   // 不指定Tag}比較麻煩的做法,但可選擇POOL_TYPE是否分頁和是否在分配的memory上加Taginline  void* __cdecl operator new(size_t Size, POOL_TYPE PoolType, ULONG PoolTag = NULL)  {    KIRQL irql = KeGetCurrentIrql();    // 檢查傳進來的PoolType是否合法    ASSERT(PoolType >=0 && PoolType < MaxPoolType);    ASSERT(irql <= DISPATCH_LEVEL);    // 在 烤肉>=  DISPATCH_LEVEL的時後,是不能發生page fault的    if (irql == DISPATCH_LEVEL)    {        ASSERT(PoolType == NonPagedPool);    }        if (Size == 0)    {        return NULL;    }    return ExAllocatePoolWithTag(                            PoolType,  辦公室出租                            static_cast (Size),                              PoolTag);  }刪除記憶體都呼叫ExFreePool就行了inline void __cdecl operator delete(void* Pointer)  {      ASSERT(Pointer != NULL);      情趣用品ExFreePool(Pointer);}---------------------------------------------------------------------------------------------------------------------------至於new[]和delete[]方法一模一樣,直接改函式名就行了。第一種的new使用方式和在User Mode時一樣,但第二種有點不同。執行範例// 先宣告一個簡單的Int 類別class CInt{  public:      explicit CInt()         : m_nValue(0)    {        KdPrint(("Constructor had been called...\n"));        Print();    }      explicit 房屋買賣CInt(int nValue)        : m_nValue(nValue)    {            KdPrint(("Constructor had been called...\n"));        Print();    }     ~CInt()     {         KdPrint(("Destructor had been called, Value=%d\n", m_nValue));    }    void Print()    {        KdPrint(("Value=%d\n",  m_nValue));    酒店經紀}    void Set(int nValue)    {        m_nValue = nValue;        Print();    }    operator int()     {         return m_nValue;    }  private:    int  m_nValue;};    // 第一種    CInt* pObj = new CInt(1);    DbgPrint("sizeof(pObj)=%d\n", sizeof(*pObj));    delete pObj;    // 第二種    pObj = new(NonPagedPool, 小型辦公室'1gaT') CInt(2);    DbgPrint("sizeof(pObj)=%d\n", sizeof(*pObj));    delete pObj;    // 第三種    CInt ObjAry[5];    for (int i=0; i<5; i++){        ObjAry[i].Set(i+3);    }    DbgPrint("sizeof(ObjAry)=%d\n", sizeof(ObjAry));執行結果Constructor had been called...Value=1sizeof(pObj)=4   Destructor had been called, Value=1Constructor had been called...Value=2sizeof(pObj)=4Destructor had been called, Value=2Constructor had been 借貸called...Value=0Constructor had been called...Value=0Constructor had been called...Value=0Constructor had been called...Value=0Constructor had been called...Value=0Value=3Value=4Value=5Value=6Value=7sizeof(ObjAry)=20Destructor had been called, Value=7Destructor had been called, Value=6Destructor had been called, Value=5Destructor had been called, Value=4Destructor had been called, Value=3---------------------------------------------------------------------------------------------------------------------------使用上要注意二點1. 因為Driver的程式的生命週期和User Mode的不同,無法當做全域變數使用。2.要注意Stack Overflow的問題,因信用貸款為在Kernel Mode分配到的Stack很小,約只有10幾K到幾十K, 不像User Mode的預設就是1 MB,要小心使用區域變數的空間和避免呼叫到太多層的函式。


.msgcontent .wsharing ul li { text-indent: 0; }



分享

Facebook
Plurk
YAHOO!

arrow
arrow
    全站熱搜

    fj23fjivfo 發表在 痞客邦 留言(0) 人氣()