Windows內核讀寫自旋鎖EX_SPIN_LOCK

這玩意本來是在Vista SP1版本就存在了,但是某些傻x客戶還在堅持使用老舊的windows操作系統。可以使用下面的移植方案代替。

在微軟的實現上好像有一些調試用途或者什麼優化,移植不了,去掉了。

#ifndef _MY_EX_SPIN_LOCK
#define _MY_EX_SPIN_LOCK

typedef LONG    EX_SPIN_LOCK;

KIRQL NTAPI ExAcquireSpinLockExclusive(volatile EX_SPIN_LOCK *ExSpinLock);
KIRQL NTAPI ExAcquireSpinLockShared(volatile EX_SPIN_LOCK *ExSpinLock);
void NTAPI ExReleaseSpinLockExclusive(EX_SPIN_LOCK *ExSpinLock, KIRQL NewIrql);
void NTAPI ExReleaseSpinLockShared(EX_SPIN_LOCK *ExSpinLock, KIRQL NewIrql);

#endif // _MY_EX_SPIN_LOCK
#include <wdm.h>
#include "exspinlock.h"

VOID NTAPI ExpWaitForSpinLockExclusiveAndAcquire(volatile EX_SPIN_LOCK *ExSpinLock)
{
    while(*ExSpinLock < 0 || _interlockedbittestandset(ExSpinLock, 0x1Fu));
}

VOID NTAPI ExpWaitForSpinLockSharedAndAcquire(volatile EX_SPIN_LOCK *ExSpinLock)
{
    while(1)
    {
        if(*ExSpinLock >= 0)
        {
            EX_SPIN_LOCK Tmp = *ExSpinLock;

            if (_InterlockedCompareExchange(ExSpinLock, Tmp + 1, Tmp) == Tmp)
                break;
        }
    }
}

KIRQL NTAPI ExAcquireSpinLockExclusive(volatile EX_SPIN_LOCK *ExSpinLock)
{
    KIRQL OldIrql;

    OldIrql = KfRaiseIrql(DISPATCH_LEVEL);
    if(_interlockedbittestandset(ExSpinLock, 0x1Fu))
        ExpWaitForSpinLockExclusiveAndAcquire(ExSpinLock);
    while(*ExSpinLock != 0x80000000);
    return OldIrql;
}

KIRQL NTAPI ExAcquireSpinLockShared(volatile EX_SPIN_LOCK *ExSpinLock)
{
    KIRQL OldIrql;
    EX_SPIN_LOCK Tmp;

    OldIrql = KfRaiseIrql(DISPATCH_LEVEL);
    Tmp = *ExSpinLock & 0x7FFFFFFF;
    if(_InterlockedCompareExchange(ExSpinLock, Tmp + 1, Tmp) != Tmp )
    {
        ExpWaitForSpinLockSharedAndAcquire(ExSpinLock);
    }
    return OldIrql;
}

void NTAPI ExReleaseSpinLockExclusive(EX_SPIN_LOCK *ExSpinLock, KIRQL NewIrql)
{
    _InterlockedAnd(ExSpinLock, 0);
    KeLowerIrql(NewIrql);
}

void NTAPI ExReleaseSpinLockShared(EX_SPIN_LOCK *ExSpinLock, KIRQL NewIrql)
{
    _InterlockedExchangeAdd(ExSpinLock, 0xFFFFFFFF);
    KeLowerIrql(NewIrql);
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章