1 /*++ 2 3 Copyright (c) Microsoft Corporation 4 5 Module Name: 6 7 FxCallbackMutexLock.hpp 8 9 Abstract: 10 11 This is the C++ header for the FxCallbackMutexLock 12 13 This represents a container for handling locking 14 when we callback into the device driver at thread 15 level. 16 17 Author: 18 19 20 21 22 Revision History: 23 24 25 --*/ 26 27 #ifndef _FXCALLBACKMUTEXLOCK_H_ 28 #define _FXCALLBACKMUTEXLOCK_H_ 29 30 extern "C" { 31 // #include "FxCallbackMutexLock.hpp.tmh" 32 } 33 34 class FxCallbackMutexLock : public FxCallbackLock { 35 36 private: 37 38 39 40 41 42 43 44 MxPagedLock m_Lock; 45 46 public: 47 48 FxCallbackMutexLock( 49 PFX_DRIVER_GLOBALS FxDriverGlobals 50 ) : 51 FxCallbackLock(FxDriverGlobals) 52 { 53 m_Lock.Initialize(); 54 } 55 56 virtual 57 ~FxCallbackMutexLock() 58 { 59 if (m_Verifier) { 60 delete m_Verifier; 61 } 62 } 63 64 virtual 65 void 66 Initialize( 67 FxObject* ParentObject 68 ) 69 { 70 PFX_DRIVER_GLOBALS fxDriverGlobals; 71 72 m_Verifier = NULL; 73 fxDriverGlobals = GetDriverGlobals(); 74 75 if (fxDriverGlobals->FxVerifierLock) { 76 77 // 78 // VerifierLock CreateAndInitialize failure is not fatal, 79 // we just won't track anything 80 // 81 (void) FxVerifierLock::CreateAndInitialize(&m_Verifier, 82 fxDriverGlobals, 83 ParentObject, 84 TRUE); 85 } 86 } 87 88 virtual 89 void 90 Lock( 91 __out PKIRQL PreviousIrql 92 ) 93 { 94 MxThread cur = Mx::MxGetCurrentThread(); 95 96 if (m_OwnerThread == cur) { 97 PFX_DRIVER_GLOBALS fxDriverGlobals; 98 99 fxDriverGlobals = GetDriverGlobals(); 100 m_RecursionCount++; 101 102 // 103 // For now we have decided not to allow this. 104 // 105 106 107 108 109 110 111 112 // 113 DoTraceLevelMessage(fxDriverGlobals, TRACE_LEVEL_FATAL, TRACINGDEVICE, 114 "Recursive acquire of callback lock 0x%p", this); 115 116 FxVerifierBugCheck(fxDriverGlobals, 117 WDF_RECURSIVE_LOCK, 118 (ULONG_PTR)this); 119 } 120 else { 121 if (m_Verifier != NULL) { 122 m_Verifier->Lock(PreviousIrql, FALSE); 123 } 124 else { 125 Mx::MxEnterCriticalRegion(); 126 m_Lock.AcquireUnsafe(); 127 } 128 m_OwnerThread = cur; 129 } 130 } 131 132 virtual 133 void 134 Unlock( 135 __in KIRQL PreviousIrql 136 ) 137 { 138 CheckOwnership(); 139 140 if (m_RecursionCount > 0) { 141 m_RecursionCount--; 142 } 143 else { 144 m_OwnerThread = NULL; 145 if (m_Verifier) { 146 m_Verifier->Unlock(PreviousIrql, FALSE); 147 } 148 else { 149 m_Lock.ReleaseUnsafe(); 150 Mx::MxLeaveCriticalRegion(); 151 } 152 } 153 } 154 155 _Must_inspect_result_ 156 virtual 157 BOOLEAN 158 IsOwner( 159 VOID 160 ) 161 { 162 MxThread cur = Mx::MxGetCurrentThread(); 163 164 if (m_OwnerThread == cur) { 165 return TRUE; 166 } 167 else { 168 return FALSE; 169 } 170 } 171 }; 172 173 #endif // _FXCALLBACKMUTEXLOCK_H_ 174