windows-nt/Source/XPSP1/NT/drivers/wdm/usb/driver/wceusbsh/remlock.c
2020-09-26 16:20:57 +08:00

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