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_
__drv_maxIRQL(DISPATCH_LEVEL)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)
__drv_maxIRQL(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)
__drv_minIRQL(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