ReactOS 0.4.16-dev-226-g79f2289
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 }

◆ 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
331
335
338
340 }
FxVerifierThreadTableEntry m_ThreadTableEntry
FxVerifierLock * m_OwnedLink
MxThread m_OwningThread
FxObject * m_ParentObject
void InitializeLockOrder(VOID)
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
@ FX_TYPE_VERIFIERLOCK
Definition: fxtypes.h:65
#define FX_LOCK_ORDER_UNKNOWN
FxVerifierLock * PerThreadDispatchLockList
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
388
392
393 // Different verifier table
395
396 if (UseMutex) {
398 }
399 else {
401 }
402
404 }
#define TRUE
Definition: types.h:120

◆ ~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 }
#define TRACINGDEVICE
Definition: dbgtrace.h:58
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
FxVerifierDbgBreakPoint(pFxDriverGlobals)
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxstump.hpp:98

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
954
955 newTable = (PLIST_ENTRY) FxPoolAllocateWithTag(
956 FxDriverGlobals,
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}
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define NonPagedPool
Definition: env_spec_w32.h:307
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define VERIFIER_THREAD_HASHTABLE_SIZE
GLuint index
Definition: glext.h:6031
Definition: typedefs.h:120
struct _LIST_ENTRY * PLIST_ENTRY
uint32_t ULONG
Definition: typedefs.h:59

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 
)
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 }
LONG NTSTATUS
Definition: precomp.h:26
_Must_inspect_result_ __inline NTSTATUS Initialize()
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define exit(n)
Definition: config.h:202
Definition: ps.c:97
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158

◆ CreateAndInitialize() [2/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 }

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

◆ 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}
static unsigned __int64 next
Definition: rand_nt.c:6
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:127

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}
void FxPoolFree(__in_xcount(ptr is at an offset from AllocationStart) PVOID ptr)
Definition: wdfpool.cpp:361
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317

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{
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}
struct outqueuenode * head
Definition: adnsresfilter.c:66
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
static int Hash(const char *)
Definition: reader.c:2257
#define InsertTailList(ListHead, Entry)
FxSpinLock * pLock
uint32_t entry
Definition: isohybrid.c:63
PLIST_ENTRY ThreadTable
Definition: fxglobals.h:400
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
_In_ WDFCOLLECTION _In_ ULONG Index

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
_Must_inspect_result_ __inline NTSTATUS Initialize()
Definition: mxpagedlockkm.h:52
#define STATUS_SUCCESS
Definition: shellext.h:65

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}
WDFTYPE GetType(VOID)
Definition: fxobject.hpp:742
FxVerifierOrderMapping FxVerifierCallbackOrderTable[]
FxVerifierOrderMapping FxVerifierOrderTable[]
GLfloat GLfloat p
Definition: glext.h:8902
ObjectType
Definition: metafile.c:81
unsigned short USHORT
Definition: pedump.c:61

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 ) {
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
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 //
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}
PVOID __inline GetObjectHandle(VOID)
Definition: fxobject.hpp:603
static void DumpDetails(__in FxVerifierLock *Lock, __in MxThread curThread, __in FxVerifierLock *PerThreadList)
static pFxVerifierThreadTableEntry GetThreadTableEntry(__in MxThread curThread, __in FxVerifierLock *pLock, __in BOOLEAN LookupOnly)
__inline VOID AcquireUnsafe()
Definition: mxpagedlockkm.h:78
static __inline MxThread MxGetCurrentThread()
Definition: mxgeneralkm.h:61
static __inline KIRQL MxGetCurrentIrql()
Definition: mxgeneralkm.h:86
static __inline VOID MxDelayExecutionThread(__in KPROCESSOR_MODE WaitMode, __in BOOLEAN Alertable, __in PLARGE_INTEGER Interval)
Definition: mxgeneralkm.h:209
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
#define FxVerifierBugCheck(FxDriverGlobals, Error,...)
Definition: fxverifier.h:58
#define KernelMode
Definition: asm.h:34
#define TRACE_LEVEL_FATAL
Definition: storswtr.h:26
MxLock ThreadTableLock
Definition: fxglobals.h:398
LONGLONG QuadPart
Definition: typedefs.h:114
@ WDF_RECURSIVE_LOCK
Definition: wdfbugcodes.h:59

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

◆ ReleaseOrReplaceThreadTableEntry()

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

Definition at line 823 of file fxverifierlock.cpp.

857{
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}
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define ASSERT(a)
Definition: mode.c:44

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;
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;
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;
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;
539
540 while( next != NULL ) {
541
542 if( next == this ) {
543 prev->m_OwnedLink = m_OwnedLink;
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}
static void ReleaseOrReplaceThreadTableEntry(__in MxThread curThread, __in FxVerifierLock *pLock)
__inline VOID ReleaseUnsafe()

Referenced by FxNonPagedObject::_Releases_lock_(), FxNonPagedObject::_Requires_lock_held_(), FxLock::_When_(), FxCallbackMutexLock::Unlock(), and FxCallbackSpinLock::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: