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

📄 spinlock.cpp

📁 Programming the Microsoft Windows Driver Model(2nd)
💻 CPP
字号:
// spinlock.cpp -- platform-portable spinlock functions

// Copyright (C) 2002 by Walter Oney

// All rights reserved



#include "stddcls.h"

#include "driver.h"				// used only for def'n of DRIVERNAME

#include "spinlock.h"



typedef VOID (FASTCALL *KEACQUIREINSTACKQUEUEDSPINLOCK)(PKSPIN_LOCK, PKLOCK_QUEUE_HANDLE);

typedef VOID (FASTCALL *KEACQUIREINSTACKQUEUEDSPINLOCKATDPCLEVEL)(PKSPIN_LOCK, PKLOCK_QUEUE_HANDLE);

typedef VOID (FASTCALL *KERELEASEINSTACKQUEUEDSPINLOCK)(PKLOCK_QUEUE_HANDLE);

typedef VOID (FASTCALL *KERELEASEINSTACKQUEUEDSPINLOCKFROMDPCLEVEL)(PKLOCK_QUEUE_HANDLE);



KEACQUIREINSTACKQUEUEDSPINLOCK pKeAcquireInStackQueuedSpinLock;

KEACQUIREINSTACKQUEUEDSPINLOCKATDPCLEVEL pKeAcquireInStackQueuedSpinLockAtDpcLevel;

KERELEASEINSTACKQUEUEDSPINLOCK pKeReleaseInStackQueuedSpinLock;

KERELEASEINSTACKQUEUEDSPINLOCKFROMDPCLEVEL pKeReleaseInStackQueuedSpinLockFromDpcLevel;



PVOID GetSystemRoutineAddress(PCWSTR name);



BOOLEAN UseQueuedLocks = FALSE;



///////////////////////////////////////////////////////////////////////////////

// InitializeSpinLockFunctionPointers is called from DriverEntry to decide

// whether to use in-stack queued spin locks or regular spin locks. This function

// calls MmGetSystemRoutineAddress, which does not exist in Win98/Me. Consequently,

// you'd need to use WDMSTUB with your driver in those systems.



#pragma PAGEDCODE



void InitializeSpinLockFunctionPointers()

	{							// InitializeSpinLockFunctionPointers

	pKeAcquireInStackQueuedSpinLock = (KEACQUIREINSTACKQUEUEDSPINLOCK) GetSystemRoutineAddress(L"KeAcquireInStackQueuedSpinLock");

	pKeAcquireInStackQueuedSpinLockAtDpcLevel = (KEACQUIREINSTACKQUEUEDSPINLOCKATDPCLEVEL) GetSystemRoutineAddress(L"KeAcquireInStackQueuedSpinLockAtDpcLevel");

	pKeReleaseInStackQueuedSpinLock = (KERELEASEINSTACKQUEUEDSPINLOCK) GetSystemRoutineAddress(L"KeReleaseInStackQueuedSpinLock");

	pKeReleaseInStackQueuedSpinLockFromDpcLevel = (KERELEASEINSTACKQUEUEDSPINLOCKFROMDPCLEVEL) GetSystemRoutineAddress(L"KeReleaseInStackQueuedSpinLockFromDpcLevel");



	if (pKeAcquireInStackQueuedSpinLock

		&& pKeAcquireInStackQueuedSpinLockAtDpcLevel

		&& pKeReleaseInStackQueuedSpinLock

		&& pKeReleaseInStackQueuedSpinLockFromDpcLevel)



		{

		KdPrint((DRIVERNAME " - Using in-stack queued spin locks\n"));

		UseQueuedLocks = TRUE;

		}



	else

		{

		KdPrint((DRIVERNAME " - Using regular spin locks\n"));

		UseQueuedLocks = FALSE;

		}

	}							// InitializeSpinLockFunctionPointers



///////////////////////////////////////////////////////////////////////////////



#pragma LOCKEDCODE



void AcquireSpinLock(PKSPIN_LOCK lock, PKLOCK_QUEUE_HANDLE qh)

	{							// AcquireSpinLock

	ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);



	if (UseQueuedLocks)											

		(*pKeAcquireInStackQueuedSpinLock)(lock, qh);

	else

		{

		qh->LockQueue.Lock = lock;

		KeAcquireSpinLock(lock, &qh->OldIrql);

		}

	}							// AcquireSpinLock



///////////////////////////////////////////////////////////////////////////////



#pragma LOCKEDCODE



void ReleaseSpinLock(PKLOCK_QUEUE_HANDLE qh)

	{							// ReleaseSpinLock

	ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);

	if (UseQueuedLocks)

		(*pKeReleaseInStackQueuedSpinLock)(qh);

	else

		KeReleaseSpinLock(qh->LockQueue.Lock, qh->OldIrql);

	}							// ReleaseSpinLock



///////////////////////////////////////////////////////////////////////////////



#pragma LOCKEDCODE



void AcquireSpinLockAtDpcLevel(PKSPIN_LOCK lock, PKLOCK_QUEUE_HANDLE qh)

	{							// AcquireSpinLockAtDpcLevel

	ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);

	if (UseQueuedLocks)

		(*pKeAcquireInStackQueuedSpinLockAtDpcLevel)(lock, qh);

	else

		{

		qh->LockQueue.Lock= lock;

		qh->OldIrql = DISPATCH_LEVEL;

		KeAcquireSpinLockAtDpcLevel(lock);

		}

	}							// AcquireSpinLockAtDpcLevel



///////////////////////////////////////////////////////////////////////////////



#pragma LOCKEDCODE



void ReleaseSpinLockAtDpcLevel(PKLOCK_QUEUE_HANDLE qh)

	{							// ReleaseSpinLockAtDpcLevel

	ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);

	if (UseQueuedLocks)

		(*pKeReleaseInStackQueuedSpinLockFromDpcLevel)(qh);

	else

		KeReleaseSpinLockFromDpcLevel(qh->LockQueue.Lock);

	}							// ReleaseSpinLockAtDpcLevel



///////////////////////////////////////////////////////////////////////////////



#pragma PAGEDCODE



PVOID GetSystemRoutineAddress(PCWSTR name)

	{							// GetSystemRoutineAddress

	UNICODE_STRING us;

	RtlInitUnicodeString(&us, name);

	return MmGetSystemRoutineAddress(&us);

	}							// GetSystemRoutineAddress

⌨️ 快捷键说明

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