/*++ Copyright (c) Microsoft Corporation Module Name: FxObjectApi.cpp Abstract: Author: Environment: kernel mode only Revision History: --*/ #include "fxobjectpch.hpp" extern "C" { #if defined(EVENT_TRACING) #include "FxObjectAPI.tmh" #endif } extern "C" { __drv_maxIRQL(DISPATCH_LEVEL) WDFAPI VOID STDCALL WDFEXPORT(WdfObjectReferenceActual)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFOBJECT Object, __in_opt PVOID Tag, __in LONG Line, __in PSTR File ) /*++ Routine Description: Adds an explicit reference that was taken on an object. Arguments: Object - the object to reference Tag - The tag used to track this reference. If not matched on dereference, a breakpoint is hit. Tags are only tracked when enabled via the registry or WDF verifier. Line - the caller's line number making the call File - the caller's file name making the call Return Value: None. We do not return the current reference count. --*/ { DDI_ENTRY(); FxPointerNotNull(GetFxDriverGlobals(DriverGlobals), Object); FxObject::_ReferenceActual( Object, Tag, Line, File ); } __drv_maxIRQL(DISPATCH_LEVEL) WDFAPI VOID STDCALL WDFEXPORT(WdfObjectDereferenceActual)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFOBJECT Object, __in_opt PVOID Tag, __in LONG Line, __in PSTR File ) /*++ Routine Description: Removes an explicit reference that was taken on an object. Arguments: Object - the object to dereference Tag - The tag used when referencing the Object, if not matched, a breakpoint is hit. Tags are only tracked when enabled via the registry or WDF verifier. Line - the caller's line number making the call File - the caller's file name making the call Return Value: None. We do not return the current reference count. --*/ { DDI_ENTRY(); FxPointerNotNull(GetFxDriverGlobals(DriverGlobals), Object); FxObject::_DereferenceActual( Object, Tag, Line, File ); } FxCallbackLock* FxGetCallbackLock( FxObject* Object ) /*++ Routine Description: This returns the proper FxCallbackLock pointer for the object. It returns NULL if an FxCallbackLock is not valid for the object. Arguments: Object - Pointer to object to retrieve the callback lock pointer for Returns: FxCallbackLock* --*/ { NTSTATUS status; IFxHasCallbacks* ihcb; FxQueryInterfaceParams params = { (PVOID*) &ihcb, FX_TYPE_IHASCALLBACKS, 0 }; ihcb = NULL; // // Query the object for the IFxHasCallbacks interface. Objects that // have callback locks must support this interface. // status = Object->QueryInterface(¶ms); if (!NT_SUCCESS(status)) { return NULL; } return ihcb->GetCallbackLockPtr(NULL); } __drv_maxIRQL(DISPATCH_LEVEL) WDFAPI VOID STDCALL WDFEXPORT(WdfObjectAcquireLock)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in _Requires_lock_not_held_(_Curr_) _Acquires_lock_(_Curr_) WDFOBJECT Object ) { DDI_ENTRY(); FxObject* pObject; FxCallbackLock* pLock; PFX_DRIVER_GLOBALS pFxDriverGlobals; KIRQL irql; FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), Object, FX_TYPE_OBJECT, (PVOID*)&pObject, &pFxDriverGlobals); // // If Lock Verifier on, validate whether its correct to // make this call // if (pFxDriverGlobals->FxVerifierLock) { // // Check IRQL Level, etc. // } // // Get the CallbackLock for the object // pLock = FxGetCallbackLock(pObject); if (pLock == NULL) { DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE, "Invalid to call on WDFOBJECT 0x%p", Object); FxVerifierDbgBreakPoint(pFxDriverGlobals); FxVerifierBugCheck(pFxDriverGlobals, WDF_INVALID_LOCK_OPERATION, (ULONG_PTR)Object, (ULONG_PTR)NULL ); return; } pLock->Lock(&irql); pLock->m_PreviousIrql = irql; return; } __drv_maxIRQL(DISPATCH_LEVEL) WDFAPI VOID STDCALL WDFEXPORT(WdfObjectReleaseLock)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in _Requires_lock_held_(_Curr_) _Releases_lock_(_Curr_) WDFOBJECT Object ) { DDI_ENTRY(); PFX_DRIVER_GLOBALS pFxDriverGlobals; FxObject* pObject; FxCallbackLock* pLock; FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), Object, FX_TYPE_OBJECT, (PVOID*)&pObject, &pFxDriverGlobals); // // If Lock Verifier on, validate whether its correct to // make this call // if (pFxDriverGlobals->FxVerifierLock) { // // Check IRQL Level, etc. // } // // Get the CallbackLock for the object // pLock = FxGetCallbackLock(pObject); if (pLock == NULL) { DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE, "Invalid to call on WDFOBJECT 0x%p",Object); FxVerifierDbgBreakPoint(pFxDriverGlobals); FxVerifierBugCheck(pFxDriverGlobals, WDF_INVALID_LOCK_OPERATION, (ULONG_PTR)Object, (ULONG_PTR)NULL ); return; } pLock->Unlock(pLock->m_PreviousIrql); return; } __drv_maxIRQL(DISPATCH_LEVEL) WDFAPI VOID STDCALL WDFEXPORT(WdfObjectDelete)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFOBJECT Object ) { DDI_ENTRY(); PFX_DRIVER_GLOBALS pFxDriverGlobals; FxObject* pObject; FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), Object, FX_TYPE_OBJECT, (PVOID*)&pObject, &pFxDriverGlobals); // // The object may not allow the Delete DDI // if (pObject->IsNoDeleteDDI()) { DoTraceLevelMessage( pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE, "Attempt to Delete an Object Which does not allow WdfDeleteObject " "Handle 0x%p, %!STATUS!", Object, STATUS_CANNOT_DELETE); FxVerifierDbgBreakPoint(pFxDriverGlobals); } else { pObject->DeleteObject(); } } _Must_inspect_result_ __drv_maxIRQL(DISPATCH_LEVEL) WDFAPI NTSTATUS STDCALL WDFEXPORT(WdfObjectQuery)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFOBJECT Object, __in CONST GUID* Guid, __in ULONG QueryBufferLength, __out_bcount(QueryBufferLength) PVOID QueryBuffer ) /*++ Routine Description: Query the object handle for specific information This allows dynamic extensions to DDI's. Currently, it is used to allow test hooks for verification which are not available in a production release. Arguments: Object - Handle to object for the query Guid - GUID to represent the information/DDI to query for QueryBufferLength - Length of QueryBuffer to return data in QueryBuffer - Pointer to QueryBuffer Returns: NTSTATUS --*/ { DDI_ENTRY(); FxObject* p; FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), Object, FX_TYPE_OBJECT, (PVOID*)&p); return FxObject::_ObjectQuery(p, Guid, QueryBufferLength, QueryBuffer); } } // extern "C" for all functions