⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kmisc.h

📁 三星2440原版bsp
💻 H
📖 第 1 页 / 共 2 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//
/*++


Module Name:

   Kmisc.h

Abstract:

    This module contains misc kernel classes like lists, queues, spinlocks...



    Husni Roukbi

  Notes:


Environment:

   Kernel mode only


Revision History:

--*/

#ifndef __KMISC_H__
#define __KMISC_H__

///////////////////////////////
// Defines
///////////////////////////////

#if ! (defined (UNDER_CE) || defined (WINCE_EMULATION))
#define IRP_LE_OFFSET  ((ULONG_PTR) ( & ((IRP* ) 0)->Tail.Overlay.ListEntry))    // IRP list entry filed offset is 88 bytes

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// CBaseObj class will be the base class for objects queued in the CxList classes.
//
// Rules for using this base obeject:
// 1) derived object should use SELF_DESTRUCT.
// 2) Use AddRef() right after you reference an object and Release(0 when you are done with the object reference.
// 3) Never delete this object or its derived objects directly. RefCount is incremented to one in constructor. 
//     Hence, a call to Release() that has no match to AddRef() will trigger deletion 
//     of this object and its derived objects. 
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

class CBaseObj 
{
public:

    virtual SELF_DESTRUCT   
    CBaseObj() {m_RefCount = 1; m_pEvent = NULL;}
    virtual LONG AddRef() ;
    virtual LONG Release();

private:

	LONG        m_RefCount;	   // reference count

protected:
    virtual ~CBaseObj();       // will be called only from selfdestruct().
    PKEVENT  m_pEvent;         // cache an event ptr  waiting for this object to be deleted.
};

inline CBaseObj::~CBaseObj()
{
    ASSERT (m_RefCount == 0);
//    _DbgPrintF(DBG_PNP_INFO,("Deleting CBaseObj"));
}

inline LONG CBaseObj::AddRef()
{							
	return  InterlockedIncrement(&m_RefCount);
}	
					
inline LONG CBaseObj::Release() 
{	
    LONG RefCount;

    if ((RefCount = InterlockedDecrement(&m_RefCount)) == 0) {
//        ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
        //
        // Cache the event pointer is case something is blocked on
        // object deletion.
        //
        PKEVENT pEvent = m_pEvent;

        //
        // Call destructor on the parent object.
        //
        SelfDestruct();
        //
        // Set the close event if there is one.  
        //
        if (pEvent) {
            KeSetEvent(pEvent,IO_NO_INCREMENT,FALSE);
        }
    }
    return RefCount;
}			

//
// Smart pointer class.  This class makes the assumptiont that the T* being
// assigned to it ALREADY has an AddRef called against it.  This means that this
// class will only call T::Release() on pT, never T::AddRef().  This is especially
// important to remember when doing an assinment or contructing this ptr;
//
template<class T> class SmartPtr {
public:
    SmartPtr() : pT(NULL) {}
    SmartPtr(T* pT) : pT(pT) {}
    
    ~SmartPtr()
    {
        if (pT != NULL) {
            pT->Release();
        }
    }

        operator T*()       { return pT;            }
    T*  operator ->() const { return pT;            }
    T&  operator *()        { return *pT;           }
    T** operator &()        { return &pT;           }

    bool operator!=(const T* pRightT) const { return pT != pRightT; }
    bool operator! (void)             const { return pT == NULL;    }
    bool operator==(const T* pRightT) const { return pT == pRightT; }
    bool operator< (const T* pRightT) const { return pT < pRightT;  }

    T*&  operator= (T* pNewT)
    {
        if (pT != NULL) {
            pT->Release();
        }
        pT = pNewT;

        return pT;
    }

    T* Detach() 
    {
        T* p = pT;
        pT = NULL;
        return p;
    }

protected:
    //
    // do not want these functions to be invoked
    //
    SmartPtr(const SmartPtr<T>& lp) { ASSERT(FALSE); }

    T*& operator=(const SmartPtr<T>& pNewT) 
    {
        ASSERT(FALSE);
        return pT; 
    }

    T* pT;
};
#endif // UNDER_CE

template<class T> class NoRefObject {
public:
    void AddRef(T* pT)  {}
    void Release(T* pT) {}
};

template<class T> class RefObject {
public:
    void AddRef(T* pT)  { pT->AddRef(); }
    void Release(T* pT) { pT->Release(); }
};


#if ! (defined (UNDER_CE) || defined (WINCE_EMULATION))
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// CKSpinLock wraps around spinlocks and hides dispatch level vs. passive level issues..
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

class CKSpinLock
{
public:
    SELF_DESTRUCT

    CKSpinLock(void);
    ~CKSpinLock(void);

    void Lock()     { AcquireSpinLock();}
    void Unlock()   { ReleaseSpinLock();}

	KIRQL _AcquireSpinLock(void);
    void AcquireSpinLock(void);
    void ReleaseSpinLock(void);
    operator PKSPIN_LOCK () { return &m_SpinLock; }

private:
    KSPIN_LOCK m_SpinLock;
    KIRQL            m_OldIrql;
};

//
// inline functions for CKSpinLock
//

inline CKSpinLock::CKSpinLock(void)
{
	KeInitializeSpinLock(&m_SpinLock);
}

inline CKSpinLock::~CKSpinLock(void)
{
}

inline void CKSpinLock::AcquireSpinLock(void)
{
    m_OldIrql = _AcquireSpinLock();
}

inline KIRQL CKSpinLock::_AcquireSpinLock(void)
{
    if (KeGetCurrentIrql() < DISPATCH_LEVEL) {
        KIRQL  Irql;
	    KeAcquireSpinLock(&m_SpinLock, &Irql);
        return Irql;
	}
	else {
		KeAcquireSpinLockAtDpcLevel(&m_SpinLock);
        return DISPATCH_LEVEL;
	}
}

inline void CKSpinLock::ReleaseSpinLock(void)
{
    if (m_OldIrql < DISPATCH_LEVEL) {
        KeReleaseSpinLock(&m_SpinLock, m_OldIrql); 
    }
    else {
        KeReleaseSpinLockFromDpcLevel(&m_SpinLock);
    }
}
////////////////////////////////////////////////////////////////////////////////////////////
class CFastMutex
{
public:
    SELF_DESTRUCT

    CFastMutex() { ExInitializeFastMutex(&m_FastMutex); }
    ~CFastMutex() {}

    void Lock()     { AcquireMutex(); }
    void Unlock()   { ReleaseMutex(); }

    void AcquireMutex();
    void ReleaseMutex();

private:
    FAST_MUTEX  m_FastMutex;
};

inline void CFastMutex::AcquireMutex()
{
    KeEnterCriticalRegion();
    ExAcquireFastMutexUnsafe(&m_FastMutex);
}

inline void CFastMutex::ReleaseMutex()
{
    ExReleaseFastMutexUnsafe(&m_FastMutex);
    KeLeaveCriticalRegion();
}

////////////////////////////////////////////////////////////////////////////////////////////
class CSemaphore
{
public:
    SELF_DESTRUCT

    CSemaphore(LONG Count = 1, LONG Limit = MAXLONG) ;
    ~CSemaphore() {}
    BOOLEAN ReleaseSem(KPRIORITY Increment = 0,LONG Adjustment = 1, BOOLEAN bWait = FALSE);
    void AcquireSem();
    BOOLEAN ReadState();

    void Lock()     { AcquireSem(); }
    void Unlock()   { ReleaseSem(); }

private:
    KSEMAPHORE m_Semaphore;
};

inline CSemaphore::CSemaphore(LONG Count , LONG Limit) 
{
	KeInitializeSemaphore(&m_Semaphore, Count, Limit);
}

inline void CSemaphore::AcquireSem() 
{ 
    ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
    KeWaitForSingleObject((PVOID) &m_Semaphore,Executive,KernelMode,FALSE,NULL);
}

inline BOOLEAN CSemaphore::ReleaseSem(KPRIORITY Increment, LONG Adjustment, BOOLEAN bWait)
{
    if ( bWait) {
        ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
    }
    else {
        ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
    }
 
	return (BOOLEAN) KeReleaseSemaphore(&m_Semaphore,Increment, Adjustment, bWait); 
}

inline BOOLEAN CSemaphore::ReadState()
{
	return (BOOLEAN) KeReadStateSemaphore( &m_Semaphore );
}
#endif // defined (UNDER_CE) || defined (WINCE_EMULATION)

class NoRealLock {
public:
    SELF_DESTRUCT

    void Lock();
    void Unlock();
};

#if (defined (UNDER_CE) || defined (WINCE_EMULATION))
class CSemaphore

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -