reactos/sdk/lib/drivers/wdf/shared/object/fxobjectapi.cpp

390 lines
7.9 KiB
C++
Raw Normal View History

/*++
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(&params);
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