// RemoveLock.cpp -- Portable implementation for remove-lock functions

#include "stddcls.h"

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

#pragma PAGEDCODE

VOID InitializeRemoveLock(PREMOVE_LOCK lock, ULONG tag, ULONG minutes, ULONG maxcount)
	{							// InitializeRemoveLock
	maxcount; minutes; tag;
	PAGED_CODE();
	KeInitializeEvent(&lock->evRemove, NotificationEvent, FALSE);
	lock->usage = 1;
	lock->removing = FALSE;
	}							// InitializeRemoveLock

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

#pragma LOCKEDCODE

NTSTATUS AcquireRemoveLock(PREMOVE_LOCK lock, PVOID tag)
	{							// AcquireRemoveLock
	tag;

	if (lock->removing)
	{						// removal in progress
		/* LONG usage = */ InterlockedIncrement(&lock->usage); // J2H commented out local "usage" var to fix C4189 warning/error
		if (InterlockedDecrement(&lock->usage) == 0)
		{
			KeSetEvent(&lock->evRemove, 0, FALSE);
		}
		return STATUS_DELETE_PENDING;
	}						// removal in progress
	return STATUS_SUCCESS;
	}							// AcquireRemoveLock

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

VOID ReleaseRemoveLock(PREMOVE_LOCK lock, PVOID tag)
	{							// ReleaseRemoveLock
	tag;
	if (InterlockedDecrement(&lock->usage) == 0)
		KeSetEvent(&lock->evRemove, 0, FALSE);
	}							// ReleaseRemoveLock

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

#pragma PAGEDCODE

VOID ReleaseRemoveLockAndWait(PREMOVE_LOCK lock, PVOID tag)
	{							// ReleaseRemoveLockAndWait
	PAGED_CODE();
	lock->removing = TRUE;
	ReleaseRemoveLock(lock, tag);
	ReleaseRemoveLock(lock, NULL);
	KeWaitForSingleObject(&lock->evRemove, Executive, KernelMode, FALSE, NULL);
	}							// ReleaseRemoveLockAndWait
