reactos/sdk/lib/drivers/wdf/shared/inc/private/common/fxhandle.h

483 lines
11 KiB
C
Raw Normal View History

/*++
Copyright (c) Microsoft Corporation
Module Name:
fxhandle.h
Abstract:
Private interfaces for Driver Frameworks handle functions.
Author:
Environment:
Both kernel and user mode
Revision History:
--*/
#ifndef _WDFPHANDLE_H_
#define _WDFPHANDLE_H_
/**
Framework Object Memory Layout (x86 32 bit)
Note: The handle is XOR'ed with (-1) to scramble it
---------------------- handle + sizeof(ContextSize)
| |
| Drivers Context |
| Memory |
| |
WDFOBJECT handle -> ---------------------- this + sizeof(C++_OBJECT) + _extrasize + sizeof(FxContextHeader)
| |
| FxContextHeader |
| |
---------------------- this + sizeof(C++_OBJECT) + _extrasize (m_ObjectSize)
| |
| C++ Object |
| "extra" memory |
| |
|--------------------| this + sizeof(C++_OBJECT)
| |
| C++ Object |
| |
| |
Base Pool Allocation -> ---------------------- this
C++ this pointer
**/
struct FxContextHeader;
struct FxContextHeader {
//
// Backpointer to the object that this is a context for
//
FxObject* Object;
//
// Next context in the chain
//
FxContextHeader* NextHeader;
//
// Function to call when object is deleted
//
PFN_WDF_OBJECT_CONTEXT_CLEANUP EvtCleanupCallback;
//
// Function to call when the object's memory is destroyed
// when the last reference count goes to zero
//
PFN_WDF_OBJECT_CONTEXT_DESTROY EvtDestroyCallback;
//
// Type associated with this context
//
PCWDF_OBJECT_CONTEXT_TYPE_INFO ContextTypeInfo;
//
// Start of client's context
//
DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) ULONG_PTR Context[1];
};
//
// We want all the way up to the aligned field, but not the field itself
//
#define FX_CONTEXT_HEADER_SIZE FIELD_OFFSET(FxContextHeader, Context)
#define COMPUTE_RAW_OBJECT_SIZE(_rawObjectSize) \
((USHORT) WDF_ALIGN_SIZE_UP(_rawObjectSize, MEMORY_ALLOCATION_ALIGNMENT))
//
// Computes the size required for a fixed size object plus any extra buffer space
// it requires. The extra buffer space is aligned on a process natural boundary.
//
#define COMPUTE_OBJECT_SIZE(_rawObjectSize, _extraSize) \
(COMPUTE_RAW_OBJECT_SIZE(_rawObjectSize) + (USHORT) WDF_ALIGN_SIZE_UP(_extraSize, MEMORY_ALLOCATION_ALIGNMENT))
//
// Gets size of the context associated with the specified attributes structure.
//
size_t
FxGetContextSize(
__in_opt PWDF_OBJECT_ATTRIBUTES Attributes
);
//
// Computes the total size of an object taking into account its fixed size,
// any additional size after the fixed, and an object header, so the memory looks
// like:
//
// Object
// additional optional memory
// WDF_HANDLE_HEADER
//
_Must_inspect_result_
NTSTATUS
FxCalculateObjectTotalSize2(
__in PFX_DRIVER_GLOBALS FxDriverGlobals,
__in USHORT RawObjectSize,
__in USHORT ExtraSize,
__in size_t ContextSize,
__out size_t* Total
);
_Must_inspect_result_
NTSTATUS
FxCalculateObjectTotalSize(
__in PFX_DRIVER_GLOBALS FxDriverGlobals,
__in USHORT RawObjectSize,
__in USHORT ExtraSize,
__in_opt PWDF_OBJECT_ATTRIBUTES Attributes,
__out size_t* Total
);
PVOID
FxObjectHandleAlloc(
__in PFX_DRIVER_GLOBALS FxDriverGlobals,
__in POOL_TYPE PoolType,
__in size_t Size,
__in ULONG Tag,
__in_opt PWDF_OBJECT_ATTRIBUTES Attributes,
__in USHORT ExtraSize,
__in FxObjectType ObjectType
);
VOID
FxContextHeaderInit(
__in FxContextHeader* Header,
__in FxObject* Object,
__in_opt PWDF_OBJECT_ATTRIBUTES Attributes
);
PVOID
FxObjectAndHandleHeaderInit(
__in PFX_DRIVER_GLOBALS FxDriverGlobals,
__in PVOID AllocationStart,
__in USHORT ObjectSize,
__in_opt PWDF_OBJECT_ATTRIBUTES Attributes,
__in FxObjectType ObjectType
);
VOID
__inline
FxObjectHandleCreate(
__in FxObject* Object,
__out PWDFOBJECT Handle
)
{
#if FX_SUPER_DBG
if (Object->GetDriverGlobals()->FxVerifierHandle) {
ASSERT(Object->GetObjectSize() > 0);
ASSERT(Object == Object->GetContextHeader()->Object);
}
#endif
ASSERT((((ULONG_PTR) Object) & FxHandleFlagMask) == 0x0);
*Handle = Object->GetObjectHandle();
}
/*++
Routine Description:
Retrieves the object pointer from the handle if valid.
This does not change an objects reference count.
Arguments:
handle - The object handle created by WdfObjectCreateHandle
type - Type of the object from FxTypes.h
ppObj - Pointer to location to store the returned object.
Returns:
NTSTATUS
--*/
VOID
FxObjectHandleGetPtrQI(
__in FxObject* Object,
__out PVOID* PPObject,
__in WDFOBJECT Handle,
__in WDFTYPE Type,
__in WDFOBJECT_OFFSET Offset
);
_Must_inspect_result_
NTSTATUS
FxObjectAllocateContext(
__in FxObject* Object,
__in PWDF_OBJECT_ATTRIBUTES Attributes,
__in BOOLEAN AllowCallbacksOnly,
__deref_opt_out PVOID* Context
);
__inline
BOOLEAN
FxObjectCheckType(
__in FxObject* Object,
__in WDFTYPE Type
)
/*++
Routine Description:
Checks if the FxObject is of a the Type.
Arguments:
FxObject - the object being checked
Type - The type value to be checked
Returns:
TRUE if the Object is of the type 'Type'
FALSE otherwise
--*/
{
NTSTATUS status;
PVOID tmpObject;
FxQueryInterfaceParams params = {&tmpObject, Type, 0};
//
// Do a quick non virtual call for the type and only do the slow QI if
// the first types do not match
//
if (Object->GetType() == Type) {
return TRUE;
}
status = Object->QueryInterface(&params);
if (!NT_SUCCESS(status)) {
return FALSE;
}
return TRUE;
}
__inline
VOID
FxObjectHandleGetPtr(
__in PFX_DRIVER_GLOBALS FxDriverGlobals,
__in WDFOBJECT Handle,
__in WDFTYPE Type,
__out PVOID* PPObject
)
/*++
Routine Description:
Converts an externally facing WDF handle into its internal object.
Arguments:
FxDriverGlobals - caller's globals
Handle - handle to convert into an object
Type - required type of the underlying object
PPObject - pointer to receive the underlying object
--*/
{
WDFOBJECT_OFFSET offset;
FxObject* pObject;
if (Handle == NULL) {
FxVerifierBugCheck(FxDriverGlobals,
WDF_INVALID_HANDLE,
(ULONG_PTR) Handle,
Type);
/* NOTREACHED */
return;
}
offset = 0;
pObject = FxObject::_GetObjectFromHandle(Handle, &offset);
//
// The only DDI you can call on an object which has a ref count of zero is
// WdfObjectGetTypedContextWorker().
//
ASSERT(pObject->GetRefCnt() > 0);
//
// Do a quick non virtual call for the type and only do the slow QI if
// the first types do not match
//
if (pObject->GetType() == Type) {
*PPObject = pObject;
ASSERT(offset == 0x0);
return;
}
else {
FxObjectHandleGetPtrQI(pObject, PPObject, Handle, Type, offset);
}
}
__inline
VOID
FxObjectHandleGetPtrOffset(
__in PFX_DRIVER_GLOBALS FxDriverGlobals,
__in WDFOBJECT Handle,
__in WDFTYPE Type,
__out PVOID* PPObject,
__out PWDFOBJECT_OFFSET Offset
)
/*++
Routine Description:
This function probably should be removed and the optional Offset paramter
moved into the signature for FxObjectHandleGetPtr(). The distinction
between these 2 functions was important when both of them were *not*
FORCEINLINE functions (since there was an additional parameter to push onto
the stack). Now that they are both __inlined, there is no longer a
parameter to push, eliminating this optimization.
Arguments:
FxDriverGlobals - caller's globals
Handle - handle to convert into an object
Type - required type of the underlying object
PPObject - pointer to receive the underlying object
Offset - offset into the object which the handle resided. Nearly all objects
will have a zero offset
--*/
{
FxObject* pObject;
if (Handle == NULL) {
FxVerifierBugCheck(FxDriverGlobals,
WDF_INVALID_HANDLE,
(ULONG_PTR) Handle,
Type);
/* NOTREACHED */
return;
}
*Offset = 0;
pObject = FxObject::_GetObjectFromHandle(Handle, Offset);
//
// The only DDI you can call on an object which has a ref count of zero is
// WdfObjectGetTypedContextWorker().
//
ASSERT(pObject->GetRefCnt() > 0);
//
// Do a quick non virtual call for the type and only do the slow QI if
// the first types do not match
//
if (pObject->GetType() == Type) {
*PPObject = pObject;
ASSERT(*Offset == 0x0);
return;
}
else {
FxObjectHandleGetPtrQI(pObject, PPObject, Handle, Type, *Offset);
}
}
VOID
__inline
FxObjectHandleGetPtrAndGlobals(
__in PFX_DRIVER_GLOBALS CallersGlobals,
__in WDFOBJECT Handle,
__in WDFTYPE Type,
__out PVOID* PPObject,
__out PFX_DRIVER_GLOBALS* ObjectGlobals
)
/*++
Routine Description:
Converts an externally facing WDF handle into its internal object.
Arguments:
FxDriverGlobals - caller's globals
Handle - handle to convert into an object
Type - required type of the underlying object
PPObject - pointer to receive the underlying object
ObjectGlobals - pointer to receive the underlying object's globals.
--*/
{
//
// All FX_TYPEs except for IFX_TYPE_MEMORY derive from FxObject, so our cast
// below will work with all types but IFX_TYPE_MEMORY (in which case the caller
// should call FxObjectHandleGetPtr and then get the globals on their own
// from the IFxMemory interface).
//
ASSERT(Type != IFX_TYPE_MEMORY);
FxObjectHandleGetPtr(CallersGlobals,
Handle,
Type,
PPObject);
*ObjectGlobals = ((FxObject*) (*PPObject))->GetDriverGlobals();
}
VOID
__inline
FxObjectHandleGetGlobals(
__in PFX_DRIVER_GLOBALS CallersGlobals,
__in WDFOBJECT Handle,
__out PFX_DRIVER_GLOBALS* ObjectGlobals
)
/*++
Routine Description:
Converts an externally facing WDF handle into its internal object and
returns its globals.
Arguments:
FxDriverGlobals - caller's globals
Handle - handle to convert into an object
ObjectGlobals - pointer to receive the underlying object's globals.
--*/
{
PVOID pObject;
FxObjectHandleGetPtrAndGlobals(CallersGlobals,
Handle,
FX_TYPE_OBJECT,
&pObject,
ObjectGlobals);
UNREFERENCED_PARAMETER(pObject);
}
#endif // _WDFPHANDLE_H_