/*++ 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(¶ms); 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_