ReactOS  0.4.15-dev-2700-g4b4ffa9
FxVerifierLock Class Reference

#include <fxverifierlock.hpp>

Inheritance diagram for FxVerifierLock:
Collaboration diagram for FxVerifierLock:

Public Member Functions

 ~FxVerifierLock (VOID)
 
VOID Lock (__out PKIRQL PreviousIrql, __in BOOLEAN AtDpc)
 
VOID Unlock (__in KIRQL PreviousIrql, __in BOOLEAN AtDpc)
 
KIRQL GetLockPreviousIrql (VOID)
 
- Public Member Functions inherited from FxGlobalsStump
 FxGlobalsStump (__in PFX_DRIVER_GLOBALS FxDriverGlobals)
 
PFX_DRIVER_GLOBALS GetDriverGlobals (VOID)
 
- Public Member Functions inherited from FxStump
PVOID operator new (__in size_t Size, __in PFX_DRIVER_GLOBALS FxDriverGlobals)
 
PVOID operator new (__in size_t Size, __in PFX_DRIVER_GLOBALS FxDriverGlobals, __in POOL_TYPE PoolType)
 
VOID operator delete (__in PVOID pointer)
 
PVOID operator new[] (__in size_t Size, __in PFX_DRIVER_GLOBALS FxDriverGlobals)
 
VOID operator delete[] (__in PVOID pointer)
 

Static Public Member Functions

_Must_inspect_result_ static __inline NTSTATUS CreateAndInitialize (__out FxVerifierLock **VerifierLock, __in PFX_DRIVER_GLOBALS FxDriverGlobals, __in FxObject *ParentObject, __in BOOLEAN UseMutex)
 
_Must_inspect_result_ static __inline NTSTATUS CreateAndInitialize (__out FxVerifierLock **VerifierLock, __in PFX_DRIVER_GLOBALS FxDriverGlobals, __in FxObject *ParentObject)
 
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)
 

Public Attributes

FxVerifierThreadTableEntry m_ThreadTableEntry
 

Static Public Attributes

static ULONG ThreadTableSize
 
static KSPIN_LOCK ThreadTableLock
 
static PLIST_ENTRY ThreadTable
 

Private Member Functions

 FxVerifierLock (PFX_DRIVER_GLOBALS FxDriverGlobals)
 
void InitializeLockOrder (VOID)
 
void FxVerifierLockDumpDetails (__in FxVerifierLock *Lock, __in PVOID curThread, __in FxVerifierLock *PerThreadList)
 
 FxVerifierLock (__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in FxObject *ParentObject)
 
_Must_inspect_result_ __inline NTSTATUS Initialize ()
 
 FxVerifierLock (__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in FxObject *ParentObject, __in BOOLEAN UseMutex)
 

Private Attributes

USHORT m_Type
 
USHORT m_Size
 
MxLock m_Lock
 
KIRQL m_OldIrql
 
MxPagedLock m_Mutex
 
FxObjectm_ParentObject
 
MxThread m_OwningThread
 
USHORT m_Order
 
BOOLEAN m_UseMutex
 
BOOLEAN m_CallbackLock
 
FxVerifierLockm_OwnedLink
 

Additional Inherited Members

- Protected Member Functions inherited from FxStump
 FxStump (VOID)
 

Detailed Description

Definition at line 259 of file fxverifierlock.hpp.

Constructor & Destructor Documentation

◆ FxVerifierLock() [1/3]

FxVerifierLock::FxVerifierLock ( PFX_DRIVER_GLOBALS  FxDriverGlobals)
inlineprivate

Definition at line 293 of file fxverifierlock.hpp.

295  :
296  FxGlobalsStump(FxDriverGlobals)
297  {
298  }
FxGlobalsStump(__in PFX_DRIVER_GLOBALS FxDriverGlobals)
Definition: fxstump.hpp:90

Referenced by CreateAndInitialize(), and FxVerifierLock().

◆ FxVerifierLock() [2/3]

FxVerifierLock::FxVerifierLock ( __in PFX_DRIVER_GLOBALS  FxDriverGlobals,
__in FxObject ParentObject 
)
inlineprivate

Definition at line 317 of file fxverifierlock.hpp.

320  :
321  FxGlobalsStump(FxDriverGlobals)
322  {
324  m_Size = sizeof(FxVerifierLock);
325 
326  m_ParentObject = ParentObject;
327 
329  m_OwnedLink = NULL;
331 
335 
336  m_UseMutex = FALSE;
338 
340  }
FxGlobalsStump(__in PFX_DRIVER_GLOBALS FxDriverGlobals)
Definition: fxstump.hpp:90
#define FALSE
Definition: types.h:117
FxVerifierLock * m_OwnedLink
FxObject * m_ParentObject
FxVerifierThreadTableEntry m_ThreadTableEntry
MxThread m_OwningThread
#define FX_LOCK_ORDER_UNKNOWN
FxVerifierLock * PerThreadDispatchLockList
FxVerifierLock(PFX_DRIVER_GLOBALS FxDriverGlobals)
void InitializeLockOrder(VOID)
#define NULL
Definition: types.h:112
FxVerifierLock * PerThreadPassiveLockList

◆ FxVerifierLock() [3/3]

FxVerifierLock::FxVerifierLock ( __in PFX_DRIVER_GLOBALS  FxDriverGlobals,
__in FxObject ParentObject,
__in BOOLEAN  UseMutex 
)
inlineprivate

Definition at line 372 of file fxverifierlock.hpp.

376  :
377  FxGlobalsStump(FxDriverGlobals)
378  {
379 
381  m_Size = sizeof(FxVerifierLock);
382 
383  m_ParentObject = ParentObject;
384 
386  m_OwnedLink = NULL;
388 
392 
393  // Different verifier table
395 
396  if (UseMutex) {
397  m_UseMutex = TRUE;
398  }
399  else {
400  m_UseMutex = FALSE;
401  }
402 
404  }
#define TRUE
Definition: types.h:120
FxGlobalsStump(__in PFX_DRIVER_GLOBALS FxDriverGlobals)
Definition: fxstump.hpp:90
#define FALSE
Definition: types.h:117
FxVerifierLock * m_OwnedLink
FxObject * m_ParentObject
FxVerifierThreadTableEntry m_ThreadTableEntry
MxThread m_OwningThread
#define FX_LOCK_ORDER_UNKNOWN
FxVerifierLock * PerThreadDispatchLockList
FxVerifierLock(PFX_DRIVER_GLOBALS FxDriverGlobals)
void InitializeLockOrder(VOID)
#define NULL
Definition: types.h:112
FxVerifierLock * PerThreadPassiveLockList

◆ ~FxVerifierLock()

FxVerifierLock::~FxVerifierLock ( VOID  )
inline

Definition at line 480 of file fxverifierlock.hpp.

483  {
484  if (m_OwningThread != NULL) {
486  "Lock 0x%p is being destroyed while owned by "
487  "thread 0x%p, Owning Object 0x%p",
490  }
491  }
FxObject * m_ParentObject
MxThread m_OwningThread
#define TRACINGDEVICE
Definition: dbgtrace.h:58
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define NULL
Definition: types.h:112
PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxstump.hpp:98
FxVerifierDbgBreakPoint(pFxDriverGlobals)

Member Function Documentation

◆ AllocateThreadTable()

void FxVerifierLock::AllocateThreadTable ( __in PFX_DRIVER_GLOBALS  FxDriverGlobals)
static

Definition at line 937 of file fxverifierlock.cpp.

940 {
941  KIRQL oldIrql;
942  ULONG newEntries;
943  PLIST_ENTRY newTable;
944 
945  FxDriverGlobals->ThreadTableLock.Acquire(&oldIrql);
946 
947  if( FxDriverGlobals->ThreadTable != NULL ) {
948  FxDriverGlobals->ThreadTableLock.Release(oldIrql);
949  return;
950  }
951 
952  // Table must be kept as a power of 2 for hash algorithm
953  newEntries = VERIFIER_THREAD_HASHTABLE_SIZE;
954 
955  newTable = (PLIST_ENTRY) FxPoolAllocateWithTag(
956  FxDriverGlobals,
957  NonPagedPool,
958  sizeof(LIST_ENTRY) * newEntries,
959  FxDriverGlobals->Tag);
960 
961  if( newTable == NULL ) {
962  FxDriverGlobals->ThreadTableLock.Release(oldIrql);
964  "No Memory to allocate thread table");
965  return;
966  }
967 
968  for(ULONG index=0; index < newEntries; index++ ) {
969  InitializeListHead(&newTable[index]);
970  }
971 
972  FxDriverGlobals->ThreadTable = newTable;
973 
974  FxDriverGlobals->ThreadTableLock.Release(oldIrql);
975 
976  return;
977 }
struct _LIST_ENTRY * PLIST_ENTRY
UCHAR KIRQL
Definition: env_spec_w32.h:591
GLuint index
Definition: glext.h:6031
#define VERIFIER_THREAD_HASHTABLE_SIZE
#define TRACINGDEVICE
Definition: dbgtrace.h:58
Definition: typedefs.h:119
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1

Referenced by FxVerifierLockInitialize().

◆ CreateAndInitialize() [1/2]

_Must_inspect_result_ static __inline NTSTATUS FxVerifierLock::CreateAndInitialize ( __out FxVerifierLock **  VerifierLock,
__in PFX_DRIVER_GLOBALS  FxDriverGlobals,
__in FxObject ParentObject,
__in BOOLEAN  UseMutex 
)
inlinestatic

Definition at line 412 of file fxverifierlock.hpp.

418  {
420  FxVerifierLock * verifierLock;
421 
422  verifierLock = new (FxDriverGlobals) FxVerifierLock(FxDriverGlobals,
423  ParentObject,
424  UseMutex);
425  if (NULL == verifierLock) {
428  "Failed to allocate verifier lock, returning %!STATUS!",
429  status);
430  goto exit;
431  }
432 
433  status = verifierLock->Initialize();
434  if (!NT_SUCCESS(status)) {
435  delete verifierLock;
436  goto exit;
437  }
438 
439  *VerifierLock = verifierLock;
440 
441  exit:
442  return status;
443  }
_Must_inspect_result_ __inline NTSTATUS Initialize()
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
LONG NTSTATUS
Definition: precomp.h:26
#define TRACINGDEVICE
Definition: dbgtrace.h:58
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
FxVerifierLock(PFX_DRIVER_GLOBALS FxDriverGlobals)
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define NULL
Definition: types.h:112
void exit(int exitcode)
Definition: _exit.c:33
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

Referenced by FxNonPagedObject::FxNonPagedObject(), FxCallbackSpinLock::Initialize(), FxCallbackMutexLock::Initialize(), and FxLock::Initialize().

◆ CreateAndInitialize() [2/2]

_Must_inspect_result_ static __inline NTSTATUS FxVerifierLock::CreateAndInitialize ( __out FxVerifierLock **  VerifierLock,
__in PFX_DRIVER_GLOBALS  FxDriverGlobals,
__in FxObject ParentObject 
)
inlinestatic

Definition at line 449 of file fxverifierlock.hpp.

454  {
456  FxVerifierLock * verifierLock;
457 
458  verifierLock = new (FxDriverGlobals) FxVerifierLock(FxDriverGlobals,
459  ParentObject);
460  if (NULL == verifierLock) {
463  "Failed to allocate verifier lock, returning %!STATUS!",
464  status);
465  goto exit;
466  }
467 
468  status = verifierLock->Initialize();
469  if (!NT_SUCCESS(status)) {
470  delete verifierLock;
471  goto exit;
472  }
473 
474  *VerifierLock = verifierLock;
475 
476  exit:
477  return status;
478  }
_Must_inspect_result_ __inline NTSTATUS Initialize()
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
LONG NTSTATUS
Definition: precomp.h:26
#define TRACINGDEVICE
Definition: dbgtrace.h:58
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
FxVerifierLock(PFX_DRIVER_GLOBALS FxDriverGlobals)
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define NULL
Definition: types.h:112
void exit(int exitcode)
Definition: _exit.c:33
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

◆ DumpDetails()

void FxVerifierLock::DumpDetails ( __in FxVerifierLock Lock,
__in MxThread  curThread,
__in FxVerifierLock PerThreadList 
)
static

Definition at line 1005 of file fxverifierlock.cpp.

1010 {
1011  PFX_DRIVER_GLOBALS FxDriverGlobals = Lock->GetDriverGlobals();
1012 
1014 
1016  "Thread 0x%p Attempted to acquire lock on Object 0x%p, "
1017  "ObjectType 0x%x, at Level 0x%x out of sequence.",
1018  curThread,Lock->m_ParentObject,
1019  Lock->m_ParentObject->GetType(),
1020  Lock->m_Order);
1021 
1022  next = PerThreadList;
1023 
1025  "Highest Lock Currently held is level 0x%x for "
1026  "Object 0x%p, ObjectType 0x%x",
1027  next->m_Order,
1028  next->m_ParentObject,
1029  next->m_ParentObject->GetType());
1030 
1032  "List of Already Acquired Locks and Objects:");
1033 
1034  while( next != NULL ) {
1035 
1037  "Object 0x%p, ObjectType 0x%x, LockLevel 0x%x",
1038  next->m_ParentObject,
1039  next->m_ParentObject->GetType(),
1040  next->m_Order);
1041 
1042  next = next->m_OwnedLink;
1043  }
1044 
1045  FxVerifierDbgBreakPoint(FxDriverGlobals);
1046 
1047  return;
1048 }
#define TRACINGDEVICE
Definition: dbgtrace.h:58
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
static unsigned __int64 next
Definition: rand_nt.c:6
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define NULL
Definition: types.h:112
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:124
FxVerifierDbgBreakPoint(pFxDriverGlobals)

Referenced by Lock().

◆ FreeThreadTable()

void FxVerifierLock::FreeThreadTable ( __in PFX_DRIVER_GLOBALS  FxDriverGlobals)
static

Definition at line 980 of file fxverifierlock.cpp.

983 {
984  KIRQL oldIrql;
985 
986  UNREFERENCED_PARAMETER(FxDriverGlobals);
987 
988  FxDriverGlobals->ThreadTableLock.Acquire(&oldIrql);
989 
990  if( FxDriverGlobals->ThreadTable == NULL ) {
991  FxDriverGlobals->ThreadTableLock.Release(oldIrql);
992  return;
993  }
994 
995  FxPoolFree(FxDriverGlobals->ThreadTable);
996 
997  FxDriverGlobals->ThreadTable = NULL;
998 
999  FxDriverGlobals->ThreadTableLock.Release(oldIrql);
1000 
1001  return;
1002 }
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define NULL
Definition: types.h:112
void FxPoolFree(__in_xcount(ptr is at an offset from AllocationStart) PVOID ptr)
Definition: wdfpool.cpp:361

Referenced by FxVerifierLockDestroy().

◆ FxVerifierLockDumpDetails()

void FxVerifierLock::FxVerifierLockDumpDetails ( __in FxVerifierLock Lock,
__in PVOID  curThread,
__in FxVerifierLock PerThreadList 
)
private

◆ GetLockPreviousIrql()

KIRQL FxVerifierLock::GetLockPreviousIrql ( VOID  )

Definition at line 602 of file fxverifierlock.cpp.

603 {
604  return m_OldIrql;
605 }

◆ GetThreadTableEntry()

pFxVerifierThreadTableEntry FxVerifierLock::GetThreadTableEntry ( __in MxThread  curThread,
__in FxVerifierLock pLock,
__in BOOLEAN  LookupOnly 
)
static

Definition at line 652 of file fxverifierlock.cpp.

657 {
658  ULONG Hash, Index;
661 
662  PFX_DRIVER_GLOBALS FxDriverGlobals = pLock->GetDriverGlobals();
663 
664  // Verifier is off, or an early memory allocation failure
665  if( FxDriverGlobals->ThreadTable == NULL ) {
666  return NULL;
667  }
668 
669  //
670  // Hash the KeCurrentThread() information into an table
671  // index.
672  //
673  // Hash takes into account that NT pool items don't use
674  // the lower 4 bits (16 byte boundries)
675  //
676 
677  Hash = (ULONG)((ULONG_PTR)curThread >> 4);
678  Hash = ((Hash >> 16) & 0x0000FFFF) ^ (Hash & 0x0000FFFF);
679 
680  //
681  // Hash table is maintained as a power of two
682  //
684 
685  head = &FxDriverGlobals->ThreadTable[Index];
686 
687  //
688  // Walk the list to see if our thread has an entry
689  //
690  next = head->Flink;
691  while( next != head ) {
693 
694  if( entry->m_ThreadTableEntry.Thread == curThread ) {
695 
696  //DoTraceLevelMessage(FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE,
697  // "Returning existing Entry 0x%p for Thread 0x%p, "
698  // "Lock 0x%p",
699  // &entry->m_ThreadTableEntry, curThread, pLock);
700 
701  return &entry->m_ThreadTableEntry;
702  }
703 
704  next = next->Flink;
705  }
706 
707  if( LookupOnly ) {
709  "Thread 0x%p does not have an entry",curThread);
710  FxVerifierDbgBreakPoint(FxDriverGlobals);
711  return NULL;
712  }
713 
714  //
715  // The current ETHREAD has no locks it currently holds, so it has
716  // no entry in the hash table.
717  //
718  // Use the supplied locks m_ThreadTableEntry to create an entry
719  // for this ETHREAD and the start of a new list of held locks.
720  //
721  pLock->m_ThreadTableEntry.Thread = curThread;
722  pLock->m_ThreadTableEntry.PerThreadPassiveLockList = NULL;
723  pLock->m_ThreadTableEntry.PerThreadDispatchLockList = NULL;
724 
725  InsertTailList(head, &pLock->m_ThreadTableEntry.HashChain);
726 
727 // DoTraceLevelMessage(FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE,
728 // "Returning new Entry 0x%p for Thread 0x%p, Lock 0x%p",
729 // &pLock->m_ThreadTableEntry, curThread, pLock);
730 
731  return &pLock->m_ThreadTableEntry;
732 }
static int Hash(const char *)
Definition: reader.c:2257
PLIST_ENTRY ThreadTable
Definition: fxglobals.h:400
struct outqueuenode * head
Definition: adnsresfilter.c:66
#define InsertTailList(ListHead, Entry)
uint32_t ULONG_PTR
Definition: typedefs.h:65
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
FxVerifierThreadTableEntry m_ThreadTableEntry
#define VERIFIER_THREAD_HASHTABLE_SIZE
#define TRACINGDEVICE
Definition: dbgtrace.h:58
_In_ WDFCOLLECTION _In_ ULONG Index
FxSpinLock * pLock
uint32_t entry
Definition: isohybrid.c:63
Definition: typedefs.h:119
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
static unsigned __int64 next
Definition: rand_nt.c:6
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1
FxVerifierDbgBreakPoint(pFxDriverGlobals)

Referenced by Lock(), and Unlock().

◆ Initialize()

_Must_inspect_result_ __inline NTSTATUS FxVerifierLock::Initialize ( )
inlineprivate

Definition at line 345 of file fxverifierlock.hpp.

347  {
349 
350  if (m_UseMutex) {
352 
353  if (!NT_SUCCESS(status)) {
355  "Unable to initialize paged lock for VerifierLock 0x%p "
356  "status %!STATUS!",
357  this, status);
358  return status;
359  }
360  }
361 
362  return STATUS_SUCCESS;
363  }
MxPagedLock m_Mutex
LONG NTSTATUS
Definition: precomp.h:26
#define TRACINGDEVICE
Definition: dbgtrace.h:58
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_Must_inspect_result_ __inline NTSTATUS Initialize()
Definition: mxpagedlockkm.h:52
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define STATUS_SUCCESS
Definition: shellext.h:65
static SERVICE_STATUS status
Definition: service.c:31
PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxstump.hpp:98
Definition: ps.c:97

Referenced by CreateAndInitialize().

◆ InitializeLockOrder()

void FxVerifierLock::InitializeLockOrder ( VOID  )
private

Definition at line 608 of file fxverifierlock.cpp.

609 {
612 
613  PFX_DRIVER_GLOBALS FxDriverGlobals = GetDriverGlobals();
614 
616 
617  if( m_CallbackLock ) {
619  }
620  else {
622  }
623 
624  while( p->ObjectType != 0 ) {
625 
626  if( p->ObjectType == ObjectType ) {
627  m_Order = p->ObjectLockOrder;
628  return;
629  }
630 
631  p++;
632  }
633 
635  "Object Type 0x%x does not have a lock order "
636  "defined in fx\\inc\\FxVerifierLock.hpp",
637  ObjectType);
638 
640 
641  return;
642 }
ObjectType
Definition: metafile.c:80
FxVerifierOrderMapping FxVerifierCallbackOrderTable[]
WDFTYPE GetType(VOID)
Definition: fxobject.hpp:742
FxObject * m_ParentObject
#define TRACINGDEVICE
Definition: dbgtrace.h:58
#define FX_LOCK_ORDER_UNKNOWN
FxVerifierOrderMapping FxVerifierOrderTable[]
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
unsigned short USHORT
Definition: pedump.c:61
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
GLfloat GLfloat p
Definition: glext.h:8902
PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxstump.hpp:98

Referenced by FxVerifierLock().

◆ Lock()

VOID FxVerifierLock::Lock ( __out PKIRQL  PreviousIrql,
__in BOOLEAN  AtDpc 
)

Definition at line 151 of file fxverifierlock.cpp.

155 {
156  MxThread curThread;
158  pFxVerifierThreadTableEntry perThreadList;
159  KIRQL oldIrql = PASSIVE_LEVEL;
160 
161  PFX_DRIVER_GLOBALS FxDriverGlobals = GetDriverGlobals();
162 
163  curThread = Mx::MxGetCurrentThread();
164 
165  //
166  // First check to see if the lock is already
167  // owned.
168  //
169  // This check is race free since this can only be set
170  // to our thread from under the spinlock, and is cleared
171  // before release.
172  //
173 
174  if( m_OwningThread == curThread ) {
175 
177  FxDriverGlobals, TRACE_LEVEL_FATAL, TRACINGDEVICE,
178  "Thread 0x%p already owns lock 0x%p for object 0x%p, WDFOBJECT 0x%p",
179  curThread, this, m_ParentObject, m_ParentObject->GetObjectHandle());
180 
181  FxVerifierBugCheck( FxDriverGlobals,
184  (ULONG_PTR) this);
185  }
186 
187  if( m_UseMutex ) {
188  // Get the Mutex
189  Mx::MxEnterCriticalRegion();
191 
192  *PreviousIrql = Mx::MxGetCurrentIrql();
193  }
194  else if (AtDpc) {
195  // Get the spinlock
196  m_Lock.AcquireAtDpcLevel();
198 
199  *PreviousIrql = m_OldIrql;
200  }
201  else {
202  // Try to force a thread switch to catch synchronization errors
204  LARGE_INTEGER sleepTime;
205 
206  sleepTime.QuadPart = 0;
208  }
209 
210  // Get the spinlock using a local since KeAcquireSpinLock might use this
211  // var as temp space while spinning and we would then corrupt it if
212  // the owning thread used it in the middle of the spin.
213  //
214  m_Lock.Acquire(PreviousIrql);
215  m_OldIrql = *PreviousIrql;
216  }
217 
218  // Lock the verifier lists
219  if (m_UseMutex) {
220  FxDriverGlobals->ThreadTableLock.Acquire(&oldIrql);
221  }
222  else {
223  FxDriverGlobals->ThreadTableLock.AcquireAtDpcLevel();
224  }
225 
226  m_OwningThread = curThread;
227 
228  // Get our per thread list from the thread table
229  perThreadList = FxVerifierLock::GetThreadTableEntry(curThread, this, FALSE);
230  if( perThreadList == NULL ) {
231 
232  if (m_UseMutex) {
233  FxDriverGlobals->ThreadTableLock.Release(oldIrql);
234  }
235  else {
236  FxDriverGlobals->ThreadTableLock.ReleaseFromDpcLevel();
237  }
238 
239  // Can't get an entry, so return
240  return;
241  }
242 
243  //
244  // There are seperately sorted lists for passive and dispatch
245  // level locks since dispatch level locks of a lower level can interrupt a
246  // higher passive level lock, giving a false report.
247  //
248  if( m_UseMutex ) {
249  head = perThreadList->PerThreadPassiveLockList;
250  }
251  else {
252  head = perThreadList->PerThreadDispatchLockList;
253  }
254 
255  if( head != NULL ) {
256 
257  // Validate current is > head
258  if( m_Order > head->m_Order ) {
259  m_OwnedLink = head;
260  //perThreadList->PerThreadLockList = this;
261  }
262  else if( m_Order == head->m_Order ) {
263 
264  // Place at head if the same lock level as current head
265  m_OwnedLink = head;
266  //perThreadList->PerThreadLockList = this;
267  }
268  else {
269 
270  // Lock violation, m_Order < head->m_Order
271  FxVerifierLock::DumpDetails(this, curThread, head);
272 
273  //
274  // Caller is feeling lucky and resumed so place it at the head
275  // to keep our lists intact
276  //
277  m_OwnedLink = head;
278  //perThreadList->PerThreadLockList = this;
279  }
280  }
281  else {
282  this->m_OwnedLink = NULL;
283  //perThreadList->PerThreadLockList = this;
284  }
285 
286  //
287  // Update to the next list head
288  //
289  if (m_UseMutex) {
290  perThreadList->PerThreadPassiveLockList = this;
291  FxDriverGlobals->ThreadTableLock.Release(oldIrql);
292  }
293  else {
294  perThreadList->PerThreadDispatchLockList = this;
295  FxDriverGlobals->ThreadTableLock.ReleaseFromDpcLevel();
296  }
297 
298  return;
299 }
MxPagedLock m_Mutex
struct outqueuenode * head
Definition: adnsresfilter.c:66
#define TRUE
Definition: types.h:120
static pFxVerifierThreadTableEntry GetThreadTableEntry(__in MxThread curThread, __in FxVerifierLock *pLock, __in BOOLEAN LookupOnly)
__inline VOID AcquireUnsafe()
Definition: mxpagedlockkm.h:78
#define FxVerifierBugCheck(FxDriverGlobals, Error,...)
Definition: fxverifier.h:58
uint32_t ULONG_PTR
Definition: typedefs.h:65
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define FALSE
Definition: types.h:117
#define TRACE_LEVEL_FATAL
Definition: storswtr.h:26
PVOID __inline GetObjectHandle(VOID)
Definition: fxobject.hpp:603
FxVerifierLock * m_OwnedLink
FxObject * m_ParentObject
MxThread m_OwningThread
#define TRACINGDEVICE
Definition: dbgtrace.h:58
static __inline KIRQL MxGetCurrentIrql()
Definition: mxgeneralkm.h:86
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
MxLock ThreadTableLock
Definition: fxglobals.h:398
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
static __inline MxThread MxGetCurrentThread()
Definition: mxgeneralkm.h:61
static void DumpDetails(__in FxVerifierLock *Lock, __in MxThread curThread, __in FxVerifierLock *PerThreadList)
FxVerifierLock * PerThreadDispatchLockList
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define NULL
Definition: types.h:112
FxVerifierLock * PerThreadPassiveLockList
#define ULONG_PTR
Definition: config.h:101
PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxstump.hpp:98
LONGLONG QuadPart
Definition: typedefs.h:114
static __inline VOID MxDelayExecutionThread(__in KPROCESSOR_MODE WaitMode, __in BOOLEAN Alertable, __in PLARGE_INTEGER Interval)
Definition: mxgeneralkm.h:209

Referenced by FxNonPagedObject::_Acquires_lock_(), FxLock::_When_(), FxCallbackSpinLock::Lock(), and FxCallbackMutexLock::Lock().

◆ ReleaseOrReplaceThreadTableEntry()

void FxVerifierLock::ReleaseOrReplaceThreadTableEntry ( __in MxThread  curThread,
__in FxVerifierLock pLock 
)
static

Definition at line 823 of file fxverifierlock.cpp.

857 {
858  ULONG Hash, Index;
860  FxVerifierLock* pNewLock = NULL;
861 
862  PFX_DRIVER_GLOBALS FxDriverGlobals = pLock->GetDriverGlobals();
863 
864  if( pLock->m_ThreadTableEntry.Thread == NULL ) {
865 
866  // This locks entry is not used for hash chaining
867  //DoTraceLevelMessage(FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE,
868  // "Entry 0x%p Not currently part of the hash chain",
869  // pLock);
870 
871  return;
872  }
873 
874  // It should be the current thread
875  if( pLock->m_ThreadTableEntry.Thread != curThread ) {
877  "OldEntry Thread 0x%p not Current! 0x%p",
878  pLock,curThread);
879  FxVerifierDbgBreakPoint(FxDriverGlobals);
880  }
881 
882  Hash = (ULONG)((ULONG_PTR)curThread >> 4);
883  Hash = ((Hash >> 16) & 0x0000FFFF) ^ (Hash & 0x0000FFFF);
884 
886 
887  head = &FxDriverGlobals->ThreadTable[Index];
888 
889  // Remove old entry
890  RemoveEntryList(&pLock->m_ThreadTableEntry.HashChain);
891 
892  //
893  // If both lock lists are NULL, we can just release the entry
894  //
895  if( (pLock->m_ThreadTableEntry.PerThreadPassiveLockList == NULL) &&
896  (pLock->m_ThreadTableEntry.PerThreadDispatchLockList == NULL) ) {
897 
898  //DoTraceLevelMessage(FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE,
899  // "Releasing entry for lock 0x%p for Thread 0x%p",
900  // pLock, curThread);
901 
902  // This is now an unused entry
903  pLock->m_ThreadTableEntry.Thread = NULL;
904  pLock->m_ThreadTableEntry.PerThreadPassiveLockList = NULL;
905  pLock->m_ThreadTableEntry.PerThreadDispatchLockList = NULL;
906 
907  return;
908  }
909 
910  //DoTraceLevelMessage(FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE,
911  // "Replacing Lock 0x%p, for Thread 0x%p",
912  // pLock, curThread);
913  if( pLock->m_ThreadTableEntry.PerThreadPassiveLockList != NULL ) {
914  pNewLock = pLock->m_ThreadTableEntry.PerThreadPassiveLockList;
915  }
916  else {
917  pNewLock = pLock->m_ThreadTableEntry.PerThreadDispatchLockList;
918  }
919 
920  ASSERT(pNewLock != NULL);
921  ASSERT(pNewLock->m_ThreadTableEntry.Thread == NULL);
924 
925  // Copy the old lock structures table to the next one
926  pNewLock->m_ThreadTableEntry.Thread = pLock->m_ThreadTableEntry.Thread;
927  pNewLock->m_ThreadTableEntry.PerThreadPassiveLockList = pLock->m_ThreadTableEntry.PerThreadPassiveLockList;
928  pNewLock->m_ThreadTableEntry.PerThreadDispatchLockList = pLock->m_ThreadTableEntry.PerThreadDispatchLockList;
929 
930  // Insert new entry at the end of thelist
932 
933  return;
934 }
static int Hash(const char *)
Definition: reader.c:2257
PLIST_ENTRY ThreadTable
Definition: fxglobals.h:400
struct outqueuenode * head
Definition: adnsresfilter.c:66
#define InsertTailList(ListHead, Entry)
uint32_t ULONG_PTR
Definition: typedefs.h:65
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
FxVerifierThreadTableEntry m_ThreadTableEntry
#define VERIFIER_THREAD_HASHTABLE_SIZE
#define TRACINGDEVICE
Definition: dbgtrace.h:58
#define ASSERT(a)
Definition: mode.c:44
_In_ WDFCOLLECTION _In_ ULONG Index
FxSpinLock * pLock
Definition: typedefs.h:119
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
FxVerifierLock * PerThreadDispatchLockList
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1
FxVerifierLock * PerThreadPassiveLockList
FxVerifierDbgBreakPoint(pFxDriverGlobals)

Referenced by Unlock().

◆ Unlock()

void FxVerifierLock::Unlock ( __in KIRQL  PreviousIrql,
__in BOOLEAN  AtDpc 
)

Definition at line 302 of file fxverifierlock.cpp.

306 {
307  MxThread curThread;
308  pFxVerifierThreadTableEntry perThreadList;
309  KIRQL oldIrql;
310 
311  PFX_DRIVER_GLOBALS FxDriverGlobals = GetDriverGlobals();
312 
313  // Only from DISPATCH_LEVEL or below
314  curThread = Mx::MxGetCurrentThread();
315 
316  if( curThread != m_OwningThread ) {
318  "Thread 0x%p Is Attempting to release a Lock 0x%p "
319  "for Object 0x%p it does not own!",
320  curThread,this,m_ParentObject);
321  FxVerifierDbgBreakPoint(FxDriverGlobals);
322  return;
323  }
324 
325  // Lock the verifier lists
326  FxDriverGlobals->ThreadTableLock.Acquire(&oldIrql);
327 
328  // Get our per thread list from the thread table
330  if( perThreadList == NULL ) {
331 
332  // Can't get our entry, so release the spinlock and return
334  "Unlock: Can't get per thread entry for thread %p",
335  curThread);
336 
338 
339  FxDriverGlobals->ThreadTableLock.Release(oldIrql);
340 
341  if (m_UseMutex) {
343  Mx::MxLeaveCriticalRegion();
344  }
345  else if (AtDpc) {
346  m_Lock.ReleaseFromDpcLevel();
347  }
348  else {
349  m_Lock.Release(PreviousIrql);
350 
351  // Try to force a thread switch to catch synchronization errors
353  LARGE_INTEGER sleepTime;
354 
355  sleepTime.QuadPart = 0;
357  }
358  }
359  return;
360  }
361 
362  if( m_UseMutex ) {
363  if( perThreadList->PerThreadPassiveLockList == NULL ) {
364  // Problem with verifier
366  "Thread has entry, but no locks recorded as "
367  "held for passive!");
369  "this 0x%p, perThreadList 0x%p",
370  this, perThreadList);
371  FxVerifierDbgBreakPoint(FxDriverGlobals);
372 
374 
375  FxDriverGlobals->ThreadTableLock.Release(oldIrql);
376 
378  Mx::MxLeaveCriticalRegion();
379 
380  return;
381  }
382  }
383  else {
384  if( perThreadList->PerThreadDispatchLockList == NULL ) {
385  // Problem with verifier
387  "Thread has entry, but no locks recorded as held "
388  "for dispatch!");
390  "this 0x%p, perThreadList 0x%p",
391  this, perThreadList);
392  FxVerifierDbgBreakPoint(FxDriverGlobals);
393 
395 
396  FxDriverGlobals->ThreadTableLock.Release(oldIrql);
397 
398  if (AtDpc) {
399  m_Lock.ReleaseFromDpcLevel();
400  }
401  else {
402  m_Lock.Release(PreviousIrql);
403 
404  // Try to force a thread switch to catch synchronization errors
406  LARGE_INTEGER sleepTime;
407 
408  sleepTime.QuadPart = 0;
410  }
411  }
412 
413  return;
414  }
415  }
416 
417  if( m_UseMutex ) {
418 
419  // Common case is a nested release
420  if( perThreadList->PerThreadPassiveLockList == this ) {
421 
422  perThreadList->PerThreadPassiveLockList = this->m_OwnedLink;
423  m_OwnedLink = NULL;
424 
425  ReleaseOrReplaceThreadTableEntry(curThread, this);
426 
427 
428 
429 
430 
431 
432 
433 
434 
435 
436 
437 
438 
439 
440 
441 
442 
443 
444 
445 
446 
447 
448  }
449  else {
450  //
451  // Releasing out of order does not deadlock as
452  // long as all acquires are in order, but its
453  // not commmon
454  //
456  FxVerifierLock* prev = NULL;
457 
458  // Skip the first entry checked by the above if
459  prev = perThreadList->PerThreadPassiveLockList;
460  next = perThreadList->PerThreadPassiveLockList->m_OwnedLink;
461 
462  while( next != NULL ) {
463 
464  if( next == this ) {
465  prev->m_OwnedLink = m_OwnedLink;
466  m_OwnedLink = NULL;
467 
468  //
469  // The perThreadList entry may, or may not be the
470  // data structure in this lock. Sinse we are releasing
471  // the lock, this entry can no longer be referenced if
472  // so.
473  //
474  ReleaseOrReplaceThreadTableEntry(curThread, this);
475 
476 // FxVerifierLock::ReplaceThreadTableEntry(curThread, this, perThreadList->PerThreadPassiveLockList);
477 
478  break;
479  }
480 
481  prev = next;
482  next = next->m_OwnedLink;
483  }
484 
485  if( next == NULL ) {
486  // Somehow the entry is gone
488  "Record entry for VerifierLock 0x%p is missing "
489  "on list 0x%p for Thread 0x%p",
490  this,perThreadList,m_OwningThread);
491  FxVerifierDbgBreakPoint(FxDriverGlobals);
492  }
493  }
494  }
495  else {
496 
497  // Common case is a nested release
498  if( perThreadList->PerThreadDispatchLockList == this ) {
499 
500  perThreadList->PerThreadDispatchLockList = this->m_OwnedLink;
501  m_OwnedLink = NULL;
502 
503  ReleaseOrReplaceThreadTableEntry(curThread, this);
504 
505 
506 
507 
508 
509 
510 
511 
512 
513 
514 
515 
516 
517 
518 
519 
520 
521 
522 
523 
524 
525 
526  }
527  else {
528  //
529  // Releasing out of order does not deadlock as
530  // long as all acquires are in order, but its
531  // not commmon
532  //
534  FxVerifierLock* prev = NULL;
535 
536  // Skip the first entry checked by the above if
537  prev = perThreadList->PerThreadDispatchLockList;
538  next = perThreadList->PerThreadDispatchLockList->m_OwnedLink;
539 
540  while( next != NULL ) {
541 
542  if( next == this ) {
543  prev->m_OwnedLink = m_OwnedLink;
544  m_OwnedLink = NULL;
545 
546  //
547  // The perThreadList entry may, or may not be the
548  // data structure in this lock. Sinse we are releasing
549  // the lock, this entry can no longer be referenced if
550  // so.
551  //
552  ReleaseOrReplaceThreadTableEntry(curThread, this);
553 
554 // FxVerifierLock::ReplaceThreadTableEntry(curThread, this, perThreadList->PerThreadDispatchLockList);
555 
556  break;
557  }
558 
559  prev = next;
560  next = next->m_OwnedLink;
561  }
562 
563  if( next == NULL ) {
564  // Somehow the entry is gone
566  "Record entry for VerifierLock 0x%p is missing "
567  "on list 0x%p for Thread 0x%p",
568  this,perThreadList,m_OwningThread);
569  FxVerifierDbgBreakPoint(FxDriverGlobals);
570  }
571  }
572 
573  }
574 
576 
577  FxDriverGlobals->ThreadTableLock.Release(oldIrql);
578 
579  if (m_UseMutex) {
581  Mx::MxLeaveCriticalRegion();
582  }
583  else if (AtDpc) {
584  m_Lock.ReleaseFromDpcLevel();
585  }
586  else {
587  m_Lock.Release(PreviousIrql);
588 
589  // Try to force a thread switch to catch synchronization errors
591  LARGE_INTEGER sleepTime;
592 
593  sleepTime.QuadPart = 0;
595  }
596  }
597 
598  return;
599 }
MxPagedLock m_Mutex
#define TRUE
Definition: types.h:120
static pFxVerifierThreadTableEntry GetThreadTableEntry(__in MxThread curThread, __in FxVerifierLock *pLock, __in BOOLEAN LookupOnly)
__inline VOID ReleaseUnsafe()
UCHAR KIRQL
Definition: env_spec_w32.h:591
FxVerifierLock * m_OwnedLink
FxObject * m_ParentObject
MxThread m_OwningThread
#define TRACINGDEVICE
Definition: dbgtrace.h:58
static __inline KIRQL MxGetCurrentIrql()
Definition: mxgeneralkm.h:86
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
MxLock ThreadTableLock
Definition: fxglobals.h:398
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
static __inline MxThread MxGetCurrentThread()
Definition: mxgeneralkm.h:61
static unsigned __int64 next
Definition: rand_nt.c:6
FxVerifierLock * PerThreadDispatchLockList
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define NULL
Definition: types.h:112
static void ReleaseOrReplaceThreadTableEntry(__in MxThread curThread, __in FxVerifierLock *pLock)
FxVerifierLock * PerThreadPassiveLockList
PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxstump.hpp:98
FxVerifierDbgBreakPoint(pFxDriverGlobals)
LONGLONG QuadPart
Definition: typedefs.h:114
static __inline VOID MxDelayExecutionThread(__in KPROCESSOR_MODE WaitMode, __in BOOLEAN Alertable, __in PLARGE_INTEGER Interval)
Definition: mxgeneralkm.h:209

Referenced by FxNonPagedObject::_Releases_lock_(), FxNonPagedObject::_Requires_lock_held_(), FxLock::_When_(), FxCallbackSpinLock::Unlock(), and FxCallbackMutexLock::Unlock().

Member Data Documentation

◆ m_CallbackLock

BOOLEAN FxVerifierLock::m_CallbackLock
private

Definition at line 285 of file fxverifierlock.hpp.

Referenced by FxVerifierLock(), and InitializeLockOrder().

◆ m_Lock

MxLock FxVerifierLock::m_Lock
private

Definition at line 267 of file fxverifierlock.hpp.

Referenced by Lock(), and Unlock().

◆ m_Mutex

MxPagedLock FxVerifierLock::m_Mutex
private

Definition at line 271 of file fxverifierlock.hpp.

Referenced by Initialize(), Lock(), and Unlock().

◆ m_OldIrql

KIRQL FxVerifierLock::m_OldIrql
private

Definition at line 268 of file fxverifierlock.hpp.

Referenced by GetLockPreviousIrql(), and Lock().

◆ m_Order

USHORT FxVerifierLock::m_Order
private

Definition at line 279 of file fxverifierlock.hpp.

Referenced by FxVerifierLock(), InitializeLockOrder(), and Lock().

◆ m_OwnedLink

FxVerifierLock* FxVerifierLock::m_OwnedLink
private

Definition at line 290 of file fxverifierlock.hpp.

Referenced by FxVerifierLock(), Lock(), and Unlock().

◆ m_OwningThread

MxThread FxVerifierLock::m_OwningThread
private

Definition at line 278 of file fxverifierlock.hpp.

Referenced by FxVerifierLock(), Lock(), Unlock(), and ~FxVerifierLock().

◆ m_ParentObject

FxObject* FxVerifierLock::m_ParentObject
private

◆ m_Size

USHORT FxVerifierLock::m_Size
private

Definition at line 264 of file fxverifierlock.hpp.

Referenced by FxVerifierLock().

◆ m_ThreadTableEntry

FxVerifierThreadTableEntry FxVerifierLock::m_ThreadTableEntry

◆ m_Type

USHORT FxVerifierLock::m_Type
private

Definition at line 263 of file fxverifierlock.hpp.

Referenced by FxVerifierLock().

◆ m_UseMutex

BOOLEAN FxVerifierLock::m_UseMutex
private

Definition at line 282 of file fxverifierlock.hpp.

Referenced by FxVerifierLock(), Initialize(), Lock(), and Unlock().

◆ ThreadTable

PLIST_ENTRY FxVerifierLock::ThreadTable
static

Definition at line 522 of file fxverifierlock.hpp.

◆ ThreadTableLock

KSPIN_LOCK FxVerifierLock::ThreadTableLock
static

Definition at line 520 of file fxverifierlock.hpp.

◆ ThreadTableSize

ULONG FxVerifierLock::ThreadTableSize
static

Definition at line 518 of file fxverifierlock.hpp.


The documentation for this class was generated from the following files: