/*++ Copyright (c) 2000 Microsoft Corporation Module Name: remlock.c Abstract: Common RemoveLock Authors: Jeff Midkiff Environment: kernel mode only Notes: Simple binary compatible RemoveLock definitions for Win9x & Win2k made to mimic the Win2k ONLY IoXxxRemoveLock functions. See the Win2k DDK for descriptions. Revision History: --*/ #include "remlock.h" #include "debug.h" #if !(DBG && WIN2K_LOCKS) #pragma alloc_text(PAGEWCE1, InitializeRemoveLock) #pragma alloc_text(PAGEWCE1, ReleaseRemoveLockAndWait) VOID InitializeRemoveLock( IN PREMOVE_LOCK Lock ) { PAGED_CODE(); if (Lock) { Lock->Removed = FALSE; Lock->IoCount = 1; KeInitializeEvent( &Lock->RemoveEvent, SynchronizationEvent, FALSE ); DbgDump(DBG_LOCKS, ("InitializeRemoveLock: %p, %d\n", Lock, Lock->IoCount)); } else { DbgDump(DBG_ERR, ("InitializeRemoveLock: Invalid Parameter\n")); TEST_TRAP(); } } NTSTATUS AcquireRemoveLock( IN PREMOVE_LOCK Lock, IN OPTIONAL PVOID Tag ) { LONG ioCount; NTSTATUS status; UNREFERENCED_PARAMETER(Tag); #if DBG if (!Lock) { status = STATUS_INVALID_PARAMETER; DbgDump(DBG_ERR, ("AcquireRemoveLock error: 0x%x\n", status )); TEST_TRAP(); } #endif // // Grab the remove lock // ioCount = InterlockedIncrement( &Lock->IoCount ); ASSERTMSG("AcquireRemoveLock - lock negative : \n", (ioCount > 0)); if ( !Lock->Removed ) { status = STATUS_SUCCESS; } else { if (0 == InterlockedDecrement( &Lock->IoCount ) ) { KeSetEvent( &Lock->RemoveEvent, 0, FALSE); } status = STATUS_DELETE_PENDING; TEST_TRAP(); } DbgDump(DBG_LOCKS, ("AcquireRemoveLock: %d, %p\n", Lock->IoCount, Tag)); return status; } VOID ReleaseRemoveLock( IN PREMOVE_LOCK Lock, IN OPTIONAL PVOID Tag ) { LONG ioCount; UNREFERENCED_PARAMETER(Tag); #if DBG if (!Lock) { DbgDump(DBG_ERR, ("ReleaseRemoveLock: Invalid Parameter\n")); TEST_TRAP(); } #endif ioCount = InterlockedDecrement( &Lock->IoCount ); ASSERT(0 <= ioCount); if (0 == ioCount) { ASSERT(Lock->Removed); TEST_TRAP(); // // The device needs to be removed. Signal the remove event // that it's safe to go ahead. // KeSetEvent(&Lock->RemoveEvent, IO_NO_INCREMENT, FALSE); } DbgDump(DBG_LOCKS, ("ReleaseRemoveLock: %d, %p\n", Lock->IoCount, Tag)); return; } VOID ReleaseRemoveLockAndWait( IN PREMOVE_LOCK Lock, IN OPTIONAL PVOID Tag ) { LONG ioCount; PAGED_CODE(); UNREFERENCED_PARAMETER(Tag); #if DBG if (!Lock) { DbgDump(DBG_ERR, ("ReleaseRemoveLockAndWait: Invalid Parameter\n")); TEST_TRAP(); } #endif DbgDump(DBG_LOCKS, ("ReleaseRemoveLockAndWait: %d, %p\n", Lock->IoCount, Tag)); Lock->Removed = TRUE; ioCount = InterlockedDecrement( &Lock->IoCount ); ASSERT (0 < ioCount); if (0 < InterlockedDecrement( &Lock->IoCount ) ) { DbgDump(DBG_LOCKS, ("ReleaseRemoveLockAndWait: waiting for %d IoCount...\n", Lock->IoCount)); // BUGBUG: may want a timeout here inside a loop KeWaitForSingleObject( &Lock->RemoveEvent, Executive, KernelMode, FALSE, NULL); DbgDump(DBG_LOCKS, ("....ReleaseRemoveLockAndWait: done!\n")); } return; } #endif // !(DBG && WIN2K_LOCKS) // EOF