1 /*++
2 
3 Copyright (c) Microsoft Corporation
4 
5 Module Name:
6 
7     FxObjectApi.cpp
8 
9 Abstract:
10 
11 
12 Author:
13 
14 
15 Environment:
16 
17     kernel mode only
18 
19 Revision History:
20 
21 --*/
22 
23 #include "fxobjectpch.hpp"
24 
25 extern "C" {
26 
27 #if defined(EVENT_TRACING)
28 #include "FxObjectAPI.tmh"
29 #endif
30 
31 }
32 
33 
34 extern "C" {
35 
36 __drv_maxIRQL(DISPATCH_LEVEL)
37 WDFAPI
38 VOID
39 STDCALL
40 WDFEXPORT(WdfObjectReferenceActual)(
41     __in
42     PWDF_DRIVER_GLOBALS DriverGlobals,
43     __in
44     WDFOBJECT Object,
45     __in_opt
46     PVOID Tag,
47     __in
48     LONG Line,
49     __in
50     PSTR File
51     )
52 /*++
53 
54 Routine Description:
55     Adds an explicit reference that was taken on an object.
56 
57 Arguments:
58     Object - the object to reference
59     Tag - The tag used to track this reference.  If not matched on dereference,
60           a breakpoint is hit.  Tags are only tracked when enabled via the
61           registry or WDF verifier.
62     Line - the caller's line number making the call
63     File - the caller's file name making the call
64 
65 Return Value:
66     None.  We do not return the current reference count.
67 
68   --*/
69 {
70     DDI_ENTRY();
71 
72     FxPointerNotNull(GetFxDriverGlobals(DriverGlobals), Object);
73 
74     FxObject::_ReferenceActual(
75         Object,
76         Tag,
77         Line,
78         File
79         );
80 }
81 
82 __drv_maxIRQL(DISPATCH_LEVEL)
83 WDFAPI
84 VOID
85 STDCALL
86 WDFEXPORT(WdfObjectDereferenceActual)(
87     __in
88     PWDF_DRIVER_GLOBALS DriverGlobals,
89     __in
90     WDFOBJECT Object,
91     __in_opt
92     PVOID Tag,
93     __in
94     LONG Line,
95     __in
96     PSTR File
97     )
98 /*++
99 
100 Routine Description:
101     Removes an explicit reference that was taken on an object.
102 
103 Arguments:
104     Object - the object to dereference
105     Tag - The tag used when referencing the Object, if not matched, a breakpoint
106           is hit.  Tags are only tracked when enabled via the registry or
107           WDF verifier.
108     Line - the caller's line number making the call
109     File - the caller's file name making the call
110 
111 Return Value:
112     None.  We do not return the current reference count.
113 
114   --*/
115 {
116     DDI_ENTRY();
117 
118     FxPointerNotNull(GetFxDriverGlobals(DriverGlobals), Object);
119 
120     FxObject::_DereferenceActual(
121         Object,
122         Tag,
123         Line,
124         File
125         );
126 }
127 
128 FxCallbackLock*
129 FxGetCallbackLock(
130     FxObject* Object
131     )
132 
133 /*++
134 
135 Routine Description:
136 
137     This returns the proper FxCallbackLock pointer
138     for the object.
139 
140     It returns NULL if an FxCallbackLock is not valid
141     for the object.
142 
143 Arguments:
144 
145     Object - Pointer to object to retrieve the callback lock pointer for
146 
147 Returns:
148 
149     FxCallbackLock*
150 
151 --*/
152 
153 {
154     NTSTATUS status;
155     IFxHasCallbacks* ihcb;
156     FxQueryInterfaceParams params = { (PVOID*) &ihcb, FX_TYPE_IHASCALLBACKS, 0 };
157 
158     ihcb = NULL;
159 
160     //
161     // Query the object for the IFxHasCallbacks interface. Objects that
162     // have callback locks must support this interface.
163     //
164     status = Object->QueryInterface(&params);
165     if (!NT_SUCCESS(status)) {
166         return NULL;
167     }
168 
169     return ihcb->GetCallbackLockPtr(NULL);
170 }
171 
172 __drv_maxIRQL(DISPATCH_LEVEL)
173 WDFAPI
174 VOID
175 STDCALL
176 WDFEXPORT(WdfObjectAcquireLock)(
177     __in
178     PWDF_DRIVER_GLOBALS DriverGlobals,
179     __in
180     _Requires_lock_not_held_(_Curr_)
181     _Acquires_lock_(_Curr_)
182     WDFOBJECT Object
183     )
184 {
185     DDI_ENTRY();
186 
187     FxObject* pObject;
188     FxCallbackLock* pLock;
189     PFX_DRIVER_GLOBALS pFxDriverGlobals;
190     KIRQL irql;
191 
192     FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
193                                    Object,
194                                    FX_TYPE_OBJECT,
195                                    (PVOID*)&pObject,
196                                    &pFxDriverGlobals);
197 
198     //
199     // If Lock Verifier on, validate whether its correct to
200     // make this call
201     //
202     if (pFxDriverGlobals->FxVerifierLock) {
203         //
204         // Check IRQL Level, etc.
205         //
206     }
207 
208     //
209     // Get the CallbackLock for the object
210     //
211     pLock = FxGetCallbackLock(pObject);
212 
213     if (pLock == NULL) {
214         DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE,
215                             "Invalid to call on WDFOBJECT 0x%p", Object);
216         FxVerifierDbgBreakPoint(pFxDriverGlobals);
217         FxVerifierBugCheck(pFxDriverGlobals,
218                            WDF_INVALID_LOCK_OPERATION,
219                            (ULONG_PTR)Object,
220                            (ULONG_PTR)NULL
221                            );
222         return;
223     }
224 
225     pLock->Lock(&irql);
226     pLock->m_PreviousIrql = irql;
227 
228     return;
229 }
230 
231 
232 __drv_maxIRQL(DISPATCH_LEVEL)
233 WDFAPI
234 VOID
235 STDCALL
236 WDFEXPORT(WdfObjectReleaseLock)(
237     __in
238     PWDF_DRIVER_GLOBALS DriverGlobals,
239     __in
240     _Requires_lock_held_(_Curr_)
241     _Releases_lock_(_Curr_)
242     WDFOBJECT Object
243     )
244 {
245     DDI_ENTRY();
246 
247     PFX_DRIVER_GLOBALS pFxDriverGlobals;
248     FxObject* pObject;
249     FxCallbackLock* pLock;
250 
251     FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
252                                    Object,
253                                    FX_TYPE_OBJECT,
254                                    (PVOID*)&pObject,
255                                    &pFxDriverGlobals);
256 
257     //
258     // If Lock Verifier on, validate whether its correct to
259     // make this call
260     //
261     if (pFxDriverGlobals->FxVerifierLock) {
262         //
263         // Check IRQL Level, etc.
264         //
265     }
266 
267     //
268     // Get the CallbackLock for the object
269     //
270     pLock = FxGetCallbackLock(pObject);
271     if (pLock == NULL) {
272         DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE,
273                             "Invalid to call on WDFOBJECT 0x%p",Object);
274         FxVerifierDbgBreakPoint(pFxDriverGlobals);
275         FxVerifierBugCheck(pFxDriverGlobals,
276                            WDF_INVALID_LOCK_OPERATION,
277                            (ULONG_PTR)Object,
278                            (ULONG_PTR)NULL
279                            );
280         return;
281     }
282 
283     pLock->Unlock(pLock->m_PreviousIrql);
284 
285     return;
286 }
287 
288 __drv_maxIRQL(DISPATCH_LEVEL)
289 WDFAPI
290 VOID
291 STDCALL
292 WDFEXPORT(WdfObjectDelete)(
293     __in
294     PWDF_DRIVER_GLOBALS DriverGlobals,
295     __in
296     WDFOBJECT Object
297     )
298 {
299     DDI_ENTRY();
300 
301     PFX_DRIVER_GLOBALS pFxDriverGlobals;
302     FxObject* pObject;
303 
304     FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
305                                    Object,
306                                    FX_TYPE_OBJECT,
307                                    (PVOID*)&pObject,
308                                    &pFxDriverGlobals);
309 
310     //
311     // The object may not allow the Delete DDI
312     //
313     if (pObject->IsNoDeleteDDI()) {
314         DoTraceLevelMessage(
315             pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE,
316             "Attempt to Delete an Object Which does not allow WdfDeleteObject "
317             "Handle 0x%p, %!STATUS!",
318             Object, STATUS_CANNOT_DELETE);
319         FxVerifierDbgBreakPoint(pFxDriverGlobals);
320     }
321     else {
322         pObject->DeleteObject();
323     }
324 }
325 
326 _Must_inspect_result_
327 __drv_maxIRQL(DISPATCH_LEVEL)
328 WDFAPI
329 NTSTATUS
330 STDCALL
331 WDFEXPORT(WdfObjectQuery)(
332     __in
333     PWDF_DRIVER_GLOBALS DriverGlobals,
334     __in
335     WDFOBJECT Object,
336     __in
337     CONST GUID* Guid,
338     __in
339     ULONG QueryBufferLength,
340     __out_bcount(QueryBufferLength)
341     PVOID QueryBuffer
342     )
343 
344 /*++
345 
346 Routine Description:
347 
348     Query the object handle for specific information
349 
350     This allows dynamic extensions to DDI's.
351 
352     Currently, it is used to allow test hooks for verification
353     which are not available in a production release.
354 
355 Arguments:
356 
357     Object - Handle to object for the query
358 
359     Guid - GUID to represent the information/DDI to query for
360 
361     QueryBufferLength - Length of QueryBuffer to return data in
362 
363     QueryBuffer - Pointer to QueryBuffer
364 
365 Returns:
366 
367     NTSTATUS
368 
369 --*/
370 
371 {
372     DDI_ENTRY();
373 
374     FxObject* p;
375 
376     FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
377                          Object,
378                          FX_TYPE_OBJECT,
379                          (PVOID*)&p);
380 
381     return FxObject::_ObjectQuery(p,
382                                   Guid,
383                                   QueryBufferLength,
384                                   QueryBuffer);
385 }
386 
387 } // extern "C" for all functions
388 
389 
390