接上篇,既然要在驱动中使用C++,可以把内核中的锁操作封闭一下,通常不封闭的情况下,锁的获取和释放要成对出现,通过封装可以实现一行语句解决获取和释放的问题(类似应用层的lock_guard),代码奉上,有兴趣的可以自行扩展:
#pragma once
#include <ntddk.h>
class CMutexLock
{
public:
CMutexLock()
: m_inited(FALSE)
{
}
~CMutexLock() {}
void Init()
{
ExInitializeFastMutex(&m_mutex);
m_inited = TRUE;
}
void Lock()
{
if (m_inited)
ExAcquireFastMutex(&m_mutex);
}
void Unlock()
{
if (m_inited)
ExReleaseFastMutex(&m_mutex);
}
private:
BOOLEAN m_inited;
FAST_MUTEX m_mutex;
};
class CMutexGuard
{
public:
CMutexGuard(CMutexLock* lock)
: m_mutex_lock(lock)
{
m_mutex_lock->Lock();
}
~CMutexGuard()
{
m_mutex_lock->Unlock();
}
private:
CMutexLock* m_mutex_lock;
};
class CSpinLock
{
public:
CSpinLock()
: m_inited(FALSE)
{
}
~CSpinLock() {}
void Init()
{
KeInitializeSpinLock(&m_spin_lock);
m_inited = TRUE;
}
void Lock(KIRQL& old_irql)
{
if (m_inited)
{
KeAcquireSpinLock(&m_spin_lock, &old_irql);
}
}
void LockDpc()
{
if (m_inited)
{
KeAcquireSpinLockAtDpcLevel(&m_spin_lock);
}
}
void Unlock(KIRQL prev_irql)
{
if (m_inited)
{
KeReleaseSpinLock(&m_spin_lock, prev_irql);
}
}
void UnlockDpc()
{
if (m_inited)
{
KeReleaseSpinLockFromDpcLevel(&m_spin_lock);
}
}
private:
BOOLEAN m_inited;
KSPIN_LOCK m_spin_lock;
};
class CSpinlockGuard
{
public:
CSpinlockGuard(CSpinLock* lock)
: m_spin_lock(lock)
, m_old_irql(PASSIVE_LEVEL)
{
m_current_irql = KeGetCurrentIrql();
if (m_old_irql >= DISPATCH_LEVEL)
m_spin_lock->LockDpc();
else
m_spin_lock->Lock(m_old_irql);
}
~CSpinlockGuard()
{
if (m_current_irql >= DISPATCH_LEVEL)
m_spin_lock->UnlockDpc();
else
m_spin_lock->Unlock(m_old_irql);
}
private:
KIRQL m_old_irql;
KIRQL m_current_irql;
CSpinLock* m_spin_lock;
};
在代码中使用时只需类似如下操作即可:
CSpinLock g_test_lock;
g_test_lock.Init();
void TestFunc()
{
CSpinlockGuard guard(&g_test_lock);
.....
}