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(¶ms); 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