📄 nonstubs.cpp
字号:
// NonStubs.cpp -- Implementations of selected kernel-mode functions
// Copyright (C) 1999 by Walter Oney
// All rights reserved
#include "stddcls.h"
#include "driver.h"
#include "NonStubs.h"
VOID CallbackWrapper(PIO_WORKITEM item);
///////////////////////////////////////////////////////////////////////////////
PIO_WORKITEM AllocateWorkItem(PDEVICE_OBJECT DeviceObject)
{ // AllocateWorkItem
PIO_WORKITEM item = (PIO_WORKITEM) ExAllocatePool(NonPagedPool, sizeof(IO_WORKITEM));
item->DeviceObject = DeviceObject;
return item;
} // AllocateWorkItem
///////////////////////////////////////////////////////////////////////////////
VOID CallbackWrapper(PIO_WORKITEM item)
{ // CallbackWrapper
(*item->Routine)(item->DeviceObject, item->Context);
ObDereferenceObject(item->DeviceObject);
} // CallbackWrapper
///////////////////////////////////////////////////////////////////////////////
VOID FreeWorkItem(PIO_WORKITEM item)
{ // FreeWorkItem
ExFreePool(item);
} // FreeWorkItem
///////////////////////////////////////////////////////////////////////////////
VOID QueueWorkItem(PIO_WORKITEM item, PIO_WORKITEM_ROUTINE Routine, WORK_QUEUE_TYPE QueueType, PVOID Context)
{ // QueueWorkItem
ExInitializeWorkItem(item, (PWORKER_THREAD_ROUTINE) CallbackWrapper, item);
item->Context = Context;
item->Routine = Routine;
ObReferenceObject(item->DeviceObject);
ExQueueWorkItem(item, QueueType);
} // QueueWorkItem
///////////////////////////////////////////////////////////////////////////////
NTSTATUS AcquireRemoveLock(PIO_REMOVE_LOCK p, PVOID tag, PCSTR file, ULONG line, ULONG size)
{ // AcquireRemoveLock
LONG count = InterlockedIncrement(&p->Common.IoCount);
ASSERT(count > 0);
if (p->Common.Removed)
{ // device is being removed
if (InterlockedDecrement(&p->Common.IoCount) == 0)
KeSetEvent(&p->Common.RemoveEvent, IO_NO_INCREMENT, FALSE);
return STATUS_DELETE_PENDING;
} // device is being removed
#ifdef DEBUG
if (size < sizeof(IO_REMOVE_LOCK))
return STATUS_SUCCESS;
ASSERT(p->Dbg.HighWatermark == 0 || count <= p->Dbg.HighWatermark);
PIO_REMOVE_LOCK_TRACKING_BLOCK t = (PIO_REMOVE_LOCK_TRACKING_BLOCK) ExAllocatePoolWithTag(NonPagedPool,
sizeof(IO_REMOVE_LOCK_TRACKING_BLOCK), p->Dbg.AllocateTag);
if (t)
{ // initialize tracking block
RtlZeroMemory(t, sizeof(IO_REMOVE_LOCK_TRACKING_BLOCK));
t->tag = tag;
t->file = file;
t->line = line;
t->locktime = Get_System_Time();
t->next = p->Dbg.Blocks;
p->Dbg.Blocks = t;
} // initialize tracking block
else
InterlockedIncrement(&p->Dbg.LowMemoryCount);
#endif // DEBUG
return STATUS_SUCCESS;
} // AcquireRemoveLock
///////////////////////////////////////////////////////////////////////////////
VOID ReleaseRemoveLock(PIO_REMOVE_LOCK p, PVOID tag, ULONG size)
{ // ReleaseRemoveLock
#ifdef DEBUG
if (size >= sizeof(IO_REMOVE_LOCK))
{ // check debug info
LONG curtime = Get_System_Time();
BOOLEAN found = FALSE;
PIO_REMOVE_LOCK_TRACKING_BLOCK t = p->Dbg.Blocks;
PIO_REMOVE_LOCK_TRACKING_BLOCK prev = NULL;
while (t)
{ // for each tracking block
if ((LONG) p->Dbg.MaxLockedTicks && (curtime - t->locktime) >= (LONG) p->Dbg.MaxLockedTicks)
{ // locked too long
KdPrint(("RemoveLock acquired from file %s, line %d (tag %X) has been locked too long\n", t->file, t->line, t->tag));
ASSERT(FALSE);
} // locked too long
if (!found && t->tag == tag)
{ // found the tracking block
found = TRUE;
PIO_REMOVE_LOCK_TRACKING_BLOCK next = t->next;
if (prev)
prev->next = next;
else
p->Dbg.Blocks = next;
ExFreePool(t);
t = next;
} // found the tracking block
else
prev = t, t = t->next;
} // for each tracking block
if (!found && InterlockedDecrement(&p->Dbg.LowMemoryCount) < 0)
{ // should have found it but didn't
InterlockedIncrement(&p->Dbg.LowMemoryCount);
KdPrint(("RemoveLock never acquired with tag %X\n", tag));
ASSERT(FALSE);
} // should have found it but didn't
} // check debug info
#endif // DEBUG
LONG count = InterlockedDecrement(&p->Common.IoCount);
ASSERT(count >= 0);
if (count == 0)
{ // device can be removed
ASSERT(p->Common.Removed);
KeSetEvent(&p->Common.RemoveEvent, IO_NO_INCREMENT, FALSE);
} // device can be removed
} // ReleaseRemoveLock
///////////////////////////////////////////////////////////////////////////////
VOID ReleaseRemoveLockAndWait(PIO_REMOVE_LOCK p, PVOID tag, ULONG size)
{ // ReleaseRemoveLockAndWait
p->Common.Removed = TRUE;
InterlockedDecrement(&p->Common.IoCount); // account for initialization to 1
ReleaseRemoveLock(p, tag, size);
KeWaitForSingleObject(&p->Common.RemoveEvent, Executive, KernelMode, FALSE, NULL);
#ifdef DEBUG
if (size >= sizeof(IO_REMOVE_LOCK))
ASSERT(p->Dbg.Blocks == NULL);
#endif // DEBUG
} // ReleaseRemoveLockAndWait
///////////////////////////////////////////////////////////////////////////////
VOID InitializeRemoveLock(PIO_REMOVE_LOCK p, ULONG tag, ULONG maxminutes, ULONG hwm, ULONG size)
{ // InitializeRemoveLock
RtlZeroMemory(p, size);
p->Common.IoCount = 1;
KeInitializeEvent(&p->Common.RemoveEvent, NotificationEvent, FALSE);
#ifdef DEBUG
if (size < sizeof(IO_REMOVE_LOCK))
return; // debugging fields not present
p->Dbg.Signature = 'COLR'; // RLOC
p->Dbg.HighWatermark = hwm;
p->Dbg.MaxLockedTicks = (LONGLONG) (maxminutes * 60 * 1000);
p->Dbg.AllocateTag = tag;
#endif // DEBUG
} // InitializeRemoveLock
///////////////////////////////////////////////////////////////////////////////
VOID ReuseIrp(PIRP Irp, NTSTATUS status)
{ // ReuseIrp
UCHAR flags = Irp->AllocationFlags;
CCHAR nstack = Irp->StackCount;
IoInitializeIrp(Irp, IoSizeOfIrp(nstack), nstack);
Irp->AllocationFlags = flags;
Irp->IoStatus.Status = status;
} // ReuseIrp
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -