192 lines
3.6 KiB
C
192 lines
3.6 KiB
C
|
/*++
|
||
|
|
||
|
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
|