#include <ntddk.h>
//
//	Acquire spin-lock at IRQL <= HIGH_LEVEL
//
void IsrAcquireSpinLock(KSPIN_LOCK *Lock, KIRQL *oldIrql)
{
	KIRQL tmpIrql;

	// validate arguments
	if(Lock == 0 || oldIrql == 0)
		return;

	// Raise IRQL
	KeRaiseIrql(HIGH_LEVEL, &tmpIrql);

	// Try to aquire the lock
	while(InterlockedExchange(Lock, 1) != 0);

	*oldIrql = tmpIrql;
}

//
//	Release spin-lock at IRQL == HIGH_LEVEL
//
void IsrReleaseSpinLock(KSPIN_LOCK *Lock, KIRQL oldIrql)
{
	// Free the lock
	InterlockedExchange(Lock, 0);
	
	// Restore IRQL
	KeLowerIrql(oldIrql);
}

//
//	Initialize spin-lock at IRQL == ANY
//
void IsrInitializeSpinLock(KSPIN_LOCK *Lock)
{
	// Set lock to "free" state (must be zero)
	InterlockedExchange(Lock, 0);
}
