mirror of
https://github.com/reactos/reactos.git
synced 2025-03-10 10:14:44 +00:00

Not all files are included, but these are necessary to compile cdrom driver. So far it can only be statically linked with drivers, a proper implementation requires wdfldr helper driver
562 lines
18 KiB
C++
562 lines
18 KiB
C++
/*++
|
|
|
|
Copyright (c) Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
FxVerifierLock.hpp
|
|
|
|
Abstract:
|
|
|
|
This is the C++ header for the verifier FxLock
|
|
|
|
This separate object allows the verifier overhead
|
|
to only be allocated when WdfVerifierLock is on.
|
|
|
|
Author:
|
|
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
Made it mode agnostic
|
|
|
|
New failure paths:
|
|
m_Mutex/m_Lock initialize
|
|
To enforce initialization hidden constructors
|
|
Callers are forced to use CreateAndInitialize methods
|
|
|
|
--*/
|
|
|
|
#ifndef _FXVERIFIERLOCK_HPP_
|
|
#define _FXVERIFIERLOCK_HPP_
|
|
|
|
extern "C" {
|
|
#if defined(EVENT_TRACING)
|
|
#include "FxVerifierLock.hpp.tmh"
|
|
#endif
|
|
}
|
|
|
|
/**
|
|
* These define the lock order used by verifier
|
|
* for basic objects internal to the driver frameworks.
|
|
*
|
|
* Higher numbers are "lower" locks in the hierachy, which means
|
|
* a lock can be acquired if its number greater than or equal
|
|
* to the current one.
|
|
*
|
|
* Correct Order:
|
|
*
|
|
* FX_LOCK_ORDER_DRIVER -> FX_LOCK_ORDER_QUEUE -> FX_LOCK_ORDER_REQUEST
|
|
*
|
|
* Incorrect Order:
|
|
*
|
|
* FX_LOCK_ORDER_DRIVER -> FX_LOCK_ORDER_QUEUE -> FX_LOCK_ORDER_DEVICE
|
|
*
|
|
* FX_LOCK_ORDER_UNKNOWN represents an object who has not (yet)
|
|
* defined a lock order. It has the highest number, meaning it
|
|
* can be acquired holding any other locks, including itself.
|
|
* At some point in time, this will cause a verifier break point,
|
|
* otherwise we can not fully test the frameworks.
|
|
*
|
|
* FX_LOCK_ORDER_NONE is a statement by the object that it will
|
|
* not use its Lock/Unlock routines. Use of locks on this object
|
|
* under verifier will cause a verifier breakpoint.
|
|
*
|
|
* There is a table mapping these from FX_TYPE_* to the lock orders
|
|
* define here in fx\core\FxVerifierLock.cpp
|
|
*
|
|
*/
|
|
|
|
//
|
|
// These locks are driver frameworks "internal" object
|
|
// locks and are not intended to be held across callbacks
|
|
// to the driver.
|
|
//
|
|
// They are acquired and released as the result of driver
|
|
// calls into the frameworks, which may be holding a driver
|
|
// callback lock.
|
|
//
|
|
#define FX_LOCK_ORDER_NONE 0x0000
|
|
#define FX_LOCK_ORDER_UNKNOWN 0xFFFF
|
|
|
|
#define FX_LOCK_ORDER_PACKAGE_PDO 0x1000
|
|
#define FX_LOCK_ORDER_PACKAGE_FDO 0x1000
|
|
#define FX_LOCK_ORDER_WMI_IRP_HANDLER 0x1000
|
|
#define FX_LOCK_ORDER_PACKAGE_GENERAL 0x1000
|
|
|
|
#define FX_LOCK_ORDER_IO_TARGET 0x1000
|
|
|
|
#define FX_LOCK_ORDER_WMI_PROVIDER 0x1001
|
|
#define FX_LOCK_ORDER_WMI_INSTANCE 0x1002
|
|
|
|
#define FX_LOCK_ORDER_DMA_ENABLER 0x1000
|
|
#define FX_LOCK_ORDER_DMA_TRANSACTION 0x1001
|
|
#define FX_LOCK_ORDER_COMMON_BUFFER 0x1001
|
|
|
|
//
|
|
// A USB device owns a bunch of pipes, so make sure that device can acquire a
|
|
// pipe lock while locked, but not vice versa
|
|
//
|
|
#define FX_LOCK_ORDER_USB_DEVICE_IO_TARGET 0x1000
|
|
#define FX_LOCK_ORDER_USB_PIPE_IO_TARGET 0x1001
|
|
|
|
|
|
#define FX_LOCK_ORDER_DRIVER 0x1010
|
|
#define FX_LOCK_ORDER_DEVICE 0x1020
|
|
#define FX_LOCK_ORDER_MP_DEVICE 0x1020
|
|
#define FX_LOCK_ORDER_DEFAULT_IRP_HANDLER 0x1030
|
|
#define FX_LOCK_ORDER_QUEUE 0x1030
|
|
#define FX_LOCK_ORDER_PACKAGE_IO 0x1031
|
|
#define FX_LOCK_ORDER_REQUEST 0x1040
|
|
#define FX_LOCK_ORDER_IRPQUEUE 0x1051
|
|
#define FX_LOCK_ORDER_TIMER 0x1059
|
|
#define FX_LOCK_ORDER_DPC 0x1060
|
|
#define FX_LOCK_ORDER_WORKITEM 0x1060
|
|
#define FX_LOCK_ORDER_CLEANUPLIST 0x1060
|
|
#define FX_LOCK_ORDER_INTERRUPT 0x1060
|
|
#define FX_LOCK_ORDER_FILEOBJECT 0x1060
|
|
#define FX_LOCK_ORDER_DEVICE_LIST 0x1061
|
|
#define FX_LOCK_ORDER_COLLECTION 0x1070 // collection can be used in any
|
|
// of the above object's callbacks
|
|
#define FX_LOCK_ORDER_USEROBJECT 0x2000
|
|
|
|
// dispose list is very far down in the list because pretty much any item can
|
|
// be added to the dispose list while that object's lock is being held
|
|
#define FX_LOCK_ORDER_DISPOSELIST 0x8000
|
|
|
|
#define FX_LOCK_ORDER_SYSTEMWORKITEM FX_LOCK_ORDER_UNKNOWN
|
|
#define FX_LOCK_ORDER_SYSTEMTHREAD FX_LOCK_ORDER_UNKNOWN // No lock level
|
|
|
|
//
|
|
// These are the device driver callback locks
|
|
// used to synchronize callback to the device
|
|
// driver. They are "higher" than the internal
|
|
// frameworks locks since an internal frameworks lock
|
|
// should not be held when these are acquired.
|
|
//
|
|
// (which should only be due to FxCallback.Invoke to a driver
|
|
// event handler)
|
|
//
|
|
// This means they must have a lower number than the internal frameworks
|
|
// locks.
|
|
//
|
|
// They may be held when a device driver is calling into a frameworks
|
|
// DDI while in an event callback handler.
|
|
//
|
|
// These levels enforce not only the level of locks acquired
|
|
// and released by and for the driver, but also the rules
|
|
// about holding internal frameworks locks when calling into
|
|
// a driver. If a frameworks bug is holding a frameworks lock
|
|
// when it goes to do a callback, the attempt to acquire the
|
|
// lower numbered lock will raise the error.
|
|
//
|
|
#define FX_CALLBACKLOCK_ORDER_DRIVER 0x10
|
|
#define FX_CALLBACKLOCK_ORDER_DEVICE 0x20
|
|
#define FX_CALLBACKLOCK_ORDER_PACKAGE 0x30
|
|
#define FX_CALLBACKLOCK_ORDER_QUEUE 0x31
|
|
|
|
#define FX_VERIFIER_LOCK_ENTRY(FX_OBJECT_TYPE, FX_LOCK_ORDER) { FX_OBJECT_TYPE, FX_LOCK_ORDER }
|
|
|
|
// Internal FxLock spinlock entries
|
|
#define FX_VERIFIER_LOCK_ENTRIES() \
|
|
FX_VERIFIER_LOCK_ENTRY(FX_TYPE_DRIVER, FX_LOCK_ORDER_DRIVER), \
|
|
FX_VERIFIER_LOCK_ENTRY(FX_TYPE_DEVICE, FX_LOCK_ORDER_DEVICE), \
|
|
FX_VERIFIER_LOCK_ENTRY(FX_TYPE_MP_DEVICE, FX_LOCK_ORDER_MP_DEVICE), \
|
|
FX_VERIFIER_LOCK_ENTRY(FX_TYPE_PACKAGE_IO, FX_LOCK_ORDER_PACKAGE_IO), \
|
|
FX_VERIFIER_LOCK_ENTRY(FX_TYPE_WMI_INSTANCE, FX_LOCK_ORDER_WMI_INSTANCE), \
|
|
FX_VERIFIER_LOCK_ENTRY(FX_TYPE_WMI_PROVIDER, FX_LOCK_ORDER_WMI_PROVIDER), \
|
|
FX_VERIFIER_LOCK_ENTRY(FX_TYPE_QUEUE, FX_LOCK_ORDER_QUEUE), \
|
|
FX_VERIFIER_LOCK_ENTRY(FX_TYPE_REQUEST, FX_LOCK_ORDER_REQUEST), \
|
|
FX_VERIFIER_LOCK_ENTRY(FX_TYPE_IRPQUEUE, FX_LOCK_ORDER_IRPQUEUE), \
|
|
FX_VERIFIER_LOCK_ENTRY(FX_TYPE_PACKAGE_PDO, FX_LOCK_ORDER_PACKAGE_PDO), \
|
|
FX_VERIFIER_LOCK_ENTRY(FX_TYPE_PACKAGE_FDO, FX_LOCK_ORDER_PACKAGE_FDO), \
|
|
FX_VERIFIER_LOCK_ENTRY(FX_TYPE_WMI_IRP_HANDLER, FX_LOCK_ORDER_WMI_IRP_HANDLER), \
|
|
FX_VERIFIER_LOCK_ENTRY(FX_TYPE_PACKAGE_GENERAL, FX_LOCK_ORDER_PACKAGE_GENERAL), \
|
|
FX_VERIFIER_LOCK_ENTRY(FX_TYPE_DMA_ENABLER, FX_LOCK_ORDER_DMA_ENABLER), \
|
|
FX_VERIFIER_LOCK_ENTRY(FX_TYPE_DMA_TRANSACTION, FX_LOCK_ORDER_DMA_TRANSACTION), \
|
|
FX_VERIFIER_LOCK_ENTRY(FX_TYPE_COMMON_BUFFER, FX_LOCK_ORDER_COMMON_BUFFER), \
|
|
FX_VERIFIER_LOCK_ENTRY(FX_TYPE_IO_TARGET, FX_LOCK_ORDER_IO_TARGET), \
|
|
FX_VERIFIER_LOCK_ENTRY(FX_TYPE_IO_TARGET_SELF, FX_LOCK_ORDER_IO_TARGET), \
|
|
FX_VERIFIER_LOCK_ENTRY(FX_TYPE_IO_TARGET_USB_DEVICE,FX_LOCK_ORDER_USB_DEVICE_IO_TARGET),\
|
|
FX_VERIFIER_LOCK_ENTRY(FX_TYPE_IO_TARGET_USB_PIPE, FX_LOCK_ORDER_USB_PIPE_IO_TARGET), \
|
|
FX_VERIFIER_LOCK_ENTRY(FX_TYPE_DPC, FX_LOCK_ORDER_DPC), \
|
|
FX_VERIFIER_LOCK_ENTRY(FX_TYPE_WORKITEM, FX_LOCK_ORDER_WORKITEM), \
|
|
FX_VERIFIER_LOCK_ENTRY(FX_TYPE_SYSTEMTHREAD, FX_LOCK_ORDER_SYSTEMTHREAD), \
|
|
FX_VERIFIER_LOCK_ENTRY(FX_TYPE_CLEANUPLIST, FX_LOCK_ORDER_CLEANUPLIST), \
|
|
FX_VERIFIER_LOCK_ENTRY(FX_TYPE_INTERRUPT, FX_LOCK_ORDER_INTERRUPT), \
|
|
FX_VERIFIER_LOCK_ENTRY(FX_TYPE_TIMER, FX_LOCK_ORDER_TIMER), \
|
|
FX_VERIFIER_LOCK_ENTRY(FX_TYPE_FILEOBJECT, FX_LOCK_ORDER_FILEOBJECT), \
|
|
FX_VERIFIER_LOCK_ENTRY(FX_TYPE_CHILD_LIST, FX_LOCK_ORDER_DEVICE_LIST), \
|
|
FX_VERIFIER_LOCK_ENTRY(FX_TYPE_SYSTEMWORKITEM, FX_LOCK_ORDER_SYSTEMWORKITEM), \
|
|
FX_VERIFIER_LOCK_ENTRY(FX_TYPE_DEFAULT_IRP_HANDLER, FX_LOCK_ORDER_DEFAULT_IRP_HANDLER), \
|
|
FX_VERIFIER_LOCK_ENTRY(FX_TYPE_COLLECTION, FX_LOCK_ORDER_COLLECTION), \
|
|
FX_VERIFIER_LOCK_ENTRY(FX_TYPE_DISPOSELIST, FX_LOCK_ORDER_DISPOSELIST), \
|
|
FX_VERIFIER_LOCK_ENTRY(FX_TYPE_USEROBJECT, FX_LOCK_ORDER_USEROBJECT), \
|
|
FX_VERIFIER_LOCK_ENTRY(0, 0)
|
|
|
|
// Device Driver Callback lock entries
|
|
#define FX_VERIFIER_CALLBACKLOCK_ENTRIES() \
|
|
FX_VERIFIER_LOCK_ENTRY(FX_TYPE_DRIVER, FX_CALLBACKLOCK_ORDER_DRIVER), \
|
|
FX_VERIFIER_LOCK_ENTRY(FX_TYPE_DEVICE, FX_CALLBACKLOCK_ORDER_DEVICE), \
|
|
FX_VERIFIER_LOCK_ENTRY(FX_TYPE_PACKAGE_IO, FX_CALLBACKLOCK_ORDER_PACKAGE), \
|
|
FX_VERIFIER_LOCK_ENTRY(FX_TYPE_QUEUE, FX_CALLBACKLOCK_ORDER_QUEUE), \
|
|
FX_VERIFIER_LOCK_ENTRY(0, 0)
|
|
|
|
//
|
|
// Mapping table structure between Fx object types and lock orders
|
|
//
|
|
struct FxVerifierOrderMapping {
|
|
USHORT ObjectType;
|
|
USHORT ObjectLockOrder;
|
|
};
|
|
|
|
typedef struct FxVerifierOrderMapping *pFxVerifierOrderMapping;
|
|
//
|
|
// This must be a power of two for hash algorithm
|
|
//
|
|
// Table size is dependent on the number of active threads
|
|
// in the frameworks at a given time. This can not execeed
|
|
// the number of (virtual due to hyperthreading) CPU's in the system.
|
|
//
|
|
// Setting this number lower just increases collisions, but does
|
|
// not impede correct function.
|
|
//
|
|
#define VERIFIER_THREAD_HASHTABLE_SIZE 64
|
|
|
|
|
|
//
|
|
// This structure is used by verifier hash table implementation
|
|
// for linking records per thread
|
|
//
|
|
struct FxVerifierThreadTableEntry {
|
|
MxThread Thread;
|
|
FxVerifierLock* PerThreadPassiveLockList;
|
|
FxVerifierLock* PerThreadDispatchLockList;
|
|
LIST_ENTRY HashChain;
|
|
};
|
|
|
|
typedef struct FxVerifierThreadTableEntry *pFxVerifierThreadTableEntry;
|
|
/*
|
|
* This lock performs the same actions as the base
|
|
* FxLock, but provides additional tracking of lock
|
|
* order to help detect and debug
|
|
* deadlock and recursive lock situations.
|
|
*
|
|
* It does not inherit from FxLock since this would
|
|
* cause a recursion chain.
|
|
*
|
|
* Since lock verification is already more costly than
|
|
* basic lock use, this verifier lock supports both the
|
|
* FAST_MUTEX and SpinLock modes in order to utilize common
|
|
* code to support verification of FxCallback locks.
|
|
*
|
|
* FxVerifierLocks are only allocated when WdfVerifierLock
|
|
* is turned on.
|
|
*/
|
|
|
|
class FxVerifierLock : public FxGlobalsStump {
|
|
|
|
private:
|
|
// Standard NT pool object identification
|
|
USHORT m_Type;
|
|
USHORT m_Size;
|
|
|
|
// Spinlock to perform our lock functionality
|
|
MxLock m_Lock;
|
|
KIRQL m_OldIrql;
|
|
|
|
// Fast Mutex for thread level verifier locks
|
|
MxPagedLock m_Mutex;
|
|
|
|
//
|
|
// Verifier per lock working values, protected
|
|
// by our m_Lock
|
|
//
|
|
FxObject* m_ParentObject;
|
|
MxThread m_OwningThread;
|
|
USHORT m_Order;
|
|
|
|
// True if its a Mutex based (thread context) lock
|
|
BOOLEAN m_UseMutex;
|
|
|
|
// True if its used as a Callback lock
|
|
BOOLEAN m_CallbackLock;
|
|
|
|
//
|
|
// This is the link for the per thread lock chain.
|
|
//
|
|
FxVerifierLock* m_OwnedLink;
|
|
|
|
private:
|
|
FxVerifierLock(
|
|
PFX_DRIVER_GLOBALS FxDriverGlobals
|
|
) :
|
|
FxGlobalsStump(FxDriverGlobals)
|
|
{
|
|
}
|
|
|
|
void
|
|
InitializeLockOrder(
|
|
VOID
|
|
);
|
|
|
|
void
|
|
FxVerifierLockDumpDetails(
|
|
__in FxVerifierLock* Lock,
|
|
__in PVOID curThread,
|
|
__in FxVerifierLock* PerThreadList
|
|
);
|
|
|
|
private:
|
|
//
|
|
// This constructor is used by internal object
|
|
// locks, which always use a spinlock.
|
|
//
|
|
FxVerifierLock(
|
|
__in PFX_DRIVER_GLOBALS FxDriverGlobals,
|
|
__in FxObject* ParentObject
|
|
) :
|
|
FxGlobalsStump(FxDriverGlobals)
|
|
{
|
|
m_Type = FX_TYPE_VERIFIERLOCK;
|
|
m_Size = sizeof(FxVerifierLock);
|
|
|
|
m_ParentObject = ParentObject;
|
|
|
|
m_OwningThread = NULL;
|
|
m_OwnedLink = NULL;
|
|
m_Order = FX_LOCK_ORDER_UNKNOWN;
|
|
|
|
m_ThreadTableEntry.Thread = NULL;
|
|
m_ThreadTableEntry.PerThreadPassiveLockList = NULL;
|
|
m_ThreadTableEntry.PerThreadDispatchLockList = NULL;
|
|
|
|
m_UseMutex = FALSE;
|
|
m_CallbackLock = FALSE;
|
|
|
|
InitializeLockOrder();
|
|
}
|
|
|
|
_Must_inspect_result_
|
|
__inline
|
|
NTSTATUS
|
|
Initialize(
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
|
|
if (m_UseMutex) {
|
|
status = m_Mutex.Initialize();
|
|
|
|
if (!NT_SUCCESS(status)) {
|
|
DoTraceLevelMessage(GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGDEVICE,
|
|
"Unable to initialize paged lock for VerifierLock 0x%p "
|
|
"status %!STATUS!",
|
|
this, status);
|
|
return status;
|
|
}
|
|
}
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
//
|
|
// This constructor is used by the Callback lock
|
|
// functions when verifer is on.
|
|
//
|
|
// The lock utlizes the callback lock order table entries to
|
|
// set its level.
|
|
//
|
|
FxVerifierLock(
|
|
__in PFX_DRIVER_GLOBALS FxDriverGlobals,
|
|
__in FxObject* ParentObject,
|
|
__in BOOLEAN UseMutex
|
|
) :
|
|
FxGlobalsStump(FxDriverGlobals)
|
|
{
|
|
|
|
m_Type = FX_TYPE_VERIFIERLOCK;
|
|
m_Size = sizeof(FxVerifierLock);
|
|
|
|
m_ParentObject = ParentObject;
|
|
|
|
m_OwningThread = NULL;
|
|
m_OwnedLink = NULL;
|
|
m_Order = FX_LOCK_ORDER_UNKNOWN;
|
|
|
|
m_ThreadTableEntry.Thread = NULL;
|
|
m_ThreadTableEntry.PerThreadPassiveLockList = NULL;
|
|
m_ThreadTableEntry.PerThreadDispatchLockList = NULL;
|
|
|
|
// Different verifier table
|
|
m_CallbackLock = TRUE;
|
|
|
|
if (UseMutex) {
|
|
m_UseMutex = TRUE;
|
|
}
|
|
else {
|
|
m_UseMutex = FALSE;
|
|
}
|
|
|
|
InitializeLockOrder();
|
|
}
|
|
|
|
public:
|
|
|
|
_Must_inspect_result_
|
|
__inline
|
|
static
|
|
NTSTATUS
|
|
CreateAndInitialize(
|
|
__out FxVerifierLock ** VerifierLock,
|
|
__in PFX_DRIVER_GLOBALS FxDriverGlobals,
|
|
__in FxObject* ParentObject,
|
|
__in BOOLEAN UseMutex
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
FxVerifierLock * verifierLock;
|
|
|
|
verifierLock = new (FxDriverGlobals) FxVerifierLock(FxDriverGlobals,
|
|
ParentObject,
|
|
UseMutex);
|
|
if (NULL == verifierLock) {
|
|
status = STATUS_INSUFFICIENT_RESOURCES;
|
|
DoTraceLevelMessage(FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE,
|
|
"Failed to allocate verifier lock, returning %!STATUS!",
|
|
status);
|
|
goto exit;
|
|
}
|
|
|
|
status = verifierLock->Initialize();
|
|
if (!NT_SUCCESS(status)) {
|
|
delete verifierLock;
|
|
goto exit;
|
|
}
|
|
|
|
*VerifierLock = verifierLock;
|
|
|
|
exit:
|
|
return status;
|
|
}
|
|
|
|
_Must_inspect_result_
|
|
__inline
|
|
static
|
|
NTSTATUS
|
|
CreateAndInitialize(
|
|
__out FxVerifierLock ** VerifierLock,
|
|
__in PFX_DRIVER_GLOBALS FxDriverGlobals,
|
|
__in FxObject* ParentObject
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
FxVerifierLock * verifierLock;
|
|
|
|
verifierLock = new (FxDriverGlobals) FxVerifierLock(FxDriverGlobals,
|
|
ParentObject);
|
|
if (NULL == verifierLock) {
|
|
status = STATUS_INSUFFICIENT_RESOURCES;
|
|
DoTraceLevelMessage(FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE,
|
|
"Failed to allocate verifier lock, returning %!STATUS!",
|
|
status);
|
|
goto exit;
|
|
}
|
|
|
|
status = verifierLock->Initialize();
|
|
if (!NT_SUCCESS(status)) {
|
|
delete verifierLock;
|
|
goto exit;
|
|
}
|
|
|
|
*VerifierLock = verifierLock;
|
|
|
|
exit:
|
|
return status;
|
|
}
|
|
|
|
~FxVerifierLock(
|
|
VOID
|
|
)
|
|
{
|
|
if (m_OwningThread != NULL) {
|
|
DoTraceLevelMessage(GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGDEVICE,
|
|
"Lock 0x%p is being destroyed while owned by "
|
|
"thread 0x%p, Owning Object 0x%p",
|
|
this, m_OwningThread, m_ParentObject);
|
|
FxVerifierDbgBreakPoint(GetDriverGlobals());
|
|
}
|
|
}
|
|
|
|
VOID
|
|
Lock(
|
|
__out PKIRQL PreviousIrql,
|
|
__in BOOLEAN AtDpc
|
|
);
|
|
|
|
VOID
|
|
Unlock(
|
|
__in KIRQL PreviousIrql,
|
|
__in BOOLEAN AtDpc
|
|
);
|
|
|
|
KIRQL
|
|
GetLockPreviousIrql(
|
|
VOID
|
|
);
|
|
|
|
//
|
|
// Instance data needed for the hash table chaining
|
|
//
|
|
FxVerifierThreadTableEntry m_ThreadTableEntry;
|
|
|
|
//
|
|
// Static data and methods for hash table chaining
|
|
//
|
|
static ULONG ThreadTableSize;
|
|
|
|
static KSPIN_LOCK ThreadTableLock;
|
|
|
|
static PLIST_ENTRY ThreadTable;
|
|
|
|
static
|
|
void
|
|
AllocateThreadTable(
|
|
__in PFX_DRIVER_GLOBALS FxDriverGlobals
|
|
);
|
|
|
|
static
|
|
void
|
|
FreeThreadTable(
|
|
__in PFX_DRIVER_GLOBALS FxDriverGlobals
|
|
);
|
|
|
|
static
|
|
void
|
|
DumpDetails(
|
|
__in FxVerifierLock* Lock,
|
|
__in MxThread curThread,
|
|
__in FxVerifierLock* PerThreadList
|
|
);
|
|
|
|
static
|
|
pFxVerifierThreadTableEntry
|
|
GetThreadTableEntry(
|
|
__in MxThread curThread,
|
|
__in FxVerifierLock* pLock,
|
|
__in BOOLEAN LookupOnly
|
|
);
|
|
|
|
static
|
|
void
|
|
ReleaseOrReplaceThreadTableEntry(
|
|
__in MxThread curThread,
|
|
__in FxVerifierLock* pLock
|
|
);
|
|
};
|
|
|
|
#endif // _FXVERIFIERLOCK_HPP_
|
|
|
|
|