/*++ Copyright (c) Microsoft Corporation Module Name: FxLock.hpp Abstract: This is the C++ header for the FxLock This represents a container for handling locking Author: Revision History: --*/ #ifndef _FXLOCK_H_ #define _FXLOCK_H_ /** * This is the base lock object implementation * * This is intended to be embedded in an FxNonPagedObject * rather than forcing a separate allocation for * non-verifier mode. * * In order to reduce the runtime memory cost of * building in verifier support for a retail version, * a single pointer it stored to FxVerifierLock * if verifier is on. If this pointer is != NULL, * lock calls are proxied to this lock function, * leaving our internal spinlock redundent. * * The decision is to minimize the non-verifier * memory footprint so we do not have to compile * it out for retail builds, but always have it * available through a driver debug setting. */ class FxLock { private: MxLock m_lock; // For Verifier FxVerifierLock* m_Verifier; public: FxLock( VOID ) { m_lock.Initialize(); m_Verifier = NULL; } VOID Initialize( __in FxObject * ParentObject ); ~FxLock() { if (m_Verifier != NULL) { delete m_Verifier; } } _When_(this->m_Verifier == NULL, _Acquires_lock_(this->m_lock)) inline VOID Lock( __out PKIRQL PreviousIrql ) { if (m_Verifier != NULL) { m_Verifier->Lock(PreviousIrql, FALSE); } // else if (PreviousIrql == NULL) { // KeAcquireSpinLockAtDpcLevel(&m_lock); // } else { m_lock.Acquire(PreviousIrql); } } _When_(this->m_Verifier == NULL, _Releases_lock_(this->m_lock)) inline void Unlock( __in KIRQL PreviousIrql ) { if (m_Verifier != NULL) { m_Verifier->Unlock(PreviousIrql, FALSE); } // else if (AtDpc) { // KeReleaseSpinLockFromDpcLevel(&m_lock); // } else { m_lock.Release(PreviousIrql); } } _When_(this->m_Verifier == NULL, _Acquires_lock_(this->m_lock)) inline VOID LockAtDispatch( VOID ) { if (m_Verifier != NULL) { KIRQL previousIrql; m_Verifier->Lock(&previousIrql, TRUE); } else { m_lock.AcquireAtDpcLevel(); } } _When_(this->m_Verifier == NULL, _Releases_lock_(this->m_lock)) inline void UnlockFromDispatch( VOID ) { if (m_Verifier != NULL) { m_Verifier->Unlock(DISPATCH_LEVEL, TRUE); } else { m_lock.ReleaseFromDpcLevel(); } } }; #endif // _FXLOCK_H_