1 /*++ 2 3 Copyright (c) Microsoft Corporation 4 5 Module Name: 6 7 FxSpinLockAPI.cpp 8 9 Abstract: 10 11 This module implements external APIS to access FxSpinLock 12 13 Author: 14 15 16 17 Environment: 18 19 Both kernel and user mode 20 21 Revision History: 22 23 --*/ 24 25 #include "fxsupportpch.hpp" 26 #include "fxspinlock.hpp" 27 28 extern "C" { 29 // #include "FxSpinLockAPI.tmh" 30 } 31 32 // 33 // Extern the entire file 34 // 35 extern "C" { 36 37 _Must_inspect_result_ 38 __drv_maxIRQL(DISPATCH_LEVEL) 39 NTSTATUS 40 STDCALL 41 WDFEXPORT(WdfSpinLockCreate)( 42 __in 43 PWDF_DRIVER_GLOBALS DriverGlobals, 44 __in_opt 45 PWDF_OBJECT_ATTRIBUTES SpinLockAttributes, 46 __out 47 WDFSPINLOCK* SpinLock 48 ) 49 { 50 DDI_ENTRY(); 51 52 PFX_DRIVER_GLOBALS pFxDriverGlobals; 53 NTSTATUS status; 54 FxSpinLock* pLock; 55 WDFSPINLOCK lock; 56 USHORT extra; 57 58 pFxDriverGlobals = GetFxDriverGlobals(DriverGlobals); 59 60 // 61 // Get the parent's globals if it is present 62 // 63 if (NT_SUCCESS(FxValidateObjectAttributesForParentHandle( 64 pFxDriverGlobals, SpinLockAttributes))) { 65 FxObject* pParent; 66 67 FxObjectHandleGetPtrAndGlobals(pFxDriverGlobals, 68 SpinLockAttributes->ParentObject, 69 FX_TYPE_OBJECT, 70 (PVOID*)&pParent, 71 &pFxDriverGlobals); 72 } 73 74 FxPointerNotNull(pFxDriverGlobals, SpinLock); 75 76 status = FxValidateObjectAttributes(pFxDriverGlobals, SpinLockAttributes); 77 if (!NT_SUCCESS(status)) { 78 return status; 79 } 80 81 if (pFxDriverGlobals->FxVerifierLock) { 82 extra = sizeof(FX_SPIN_LOCK_HISTORY); 83 } 84 else { 85 extra = 0; 86 } 87 88 *SpinLock = NULL; 89 90 pLock = new(pFxDriverGlobals, SpinLockAttributes, extra) 91 FxSpinLock(pFxDriverGlobals, extra); 92 93 if (pLock == NULL) { 94 return STATUS_INSUFFICIENT_RESOURCES; 95 } 96 97 status = pLock->Commit(SpinLockAttributes, (WDFOBJECT*)&lock); 98 99 if (NT_SUCCESS(status)) { 100 *SpinLock = lock; 101 } 102 else { 103 pLock->DeleteFromFailedCreate(); 104 } 105 106 return status; 107 } 108 109 __drv_raisesIRQL(DISPATCH_LEVEL) 110 __drv_maxIRQL(DISPATCH_LEVEL) 111 VOID 112 STDCALL 113 WDFEXPORT(WdfSpinLockAcquire)( 114 __in 115 PWDF_DRIVER_GLOBALS DriverGlobals, 116 __in 117 __drv_savesIRQL 118 _Requires_lock_not_held_(_Curr_) 119 _Acquires_lock_(_Curr_) 120 WDFSPINLOCK SpinLock 121 ) 122 { 123 DDI_ENTRY(); 124 125 PFX_DRIVER_GLOBALS pFxDriverGlobals; 126 FxSpinLock* pLock; 127 128 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), 129 SpinLock, 130 FX_TYPE_SPIN_LOCK, 131 (PVOID*) &pLock, 132 &pFxDriverGlobals); 133 134 if (pLock->IsInterruptLock()) { 135 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGERROR, 136 "WDFSPINLOCK %p is associated with an interrupt, " 137 "cannot be used for normal sync operations", 138 SpinLock); 139 FxVerifierDbgBreakPoint(pFxDriverGlobals); 140 return; 141 } 142 143 pLock->AcquireLock( 144 pFxDriverGlobals->FxVerifierLock ? _ReturnAddress() : NULL); 145 } 146 147 __drv_maxIRQL(DISPATCH_LEVEL) 148 __drv_minIRQL(DISPATCH_LEVEL) 149 VOID 150 STDCALL 151 WDFEXPORT(WdfSpinLockRelease)( 152 __in 153 PWDF_DRIVER_GLOBALS DriverGlobals, 154 __in 155 __drv_restoresIRQL 156 _Requires_lock_held_(_Curr_) 157 _Releases_lock_(_Curr_) 158 WDFSPINLOCK SpinLock 159 ) 160 { 161 DDI_ENTRY(); 162 163 PFX_DRIVER_GLOBALS pFxDriverGlobals; 164 FxSpinLock* pLock; 165 166 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), 167 SpinLock, 168 FX_TYPE_SPIN_LOCK, 169 (PVOID*) &pLock, 170 &pFxDriverGlobals); 171 172 if (pLock->IsInterruptLock()) { 173 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGERROR, 174 "WDFSPINLOCK %p is associated with an interrupt, " 175 "cannot be used for normal sync operations", 176 SpinLock); 177 FxVerifierDbgBreakPoint(pFxDriverGlobals); 178 return; 179 } 180 181 pLock->ReleaseLock(); 182 } 183 184 } // extern "C" 185