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

📄 spinlock.cpp

📁 一本在讲述USB驱动程式的书 及其范例原码
💻 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 + -