/*++ Copyright (c) Microsoft Corporation Module Name: FxWmiInstance.hpp Abstract: This module implements the WMI instance object Author: Environment: Both kernel and user mode Revision History: --*/ #ifndef _FXWMIINSTANCE_H_ #define _FXWMIINSTANCE_H_ class FxWmiInstance : public FxNonPagedObject { friend FxWmiProvider; friend FxWmiIrpHandler; public: FxWmiInstance( __in PFX_DRIVER_GLOBALS FxDriverGlobals, __in USHORT ObjectSize, __in FxWmiProvider* Provider ); ~FxWmiInstance(); CfxDevice* GetDevice( VOID ) { return m_Provider->GetDevice(); } FxWmiProvider* GetProvider( VOID ) { return m_Provider; } _Must_inspect_result_ NTSTATUS FireEvent( __in_bcount_opt(EventBufferSize) PVOID EventBuffer, __inout ULONG EventBufferSize ); BOOLEAN IsEnabled( __in WDF_WMI_PROVIDER_CONTROL Control ) { return m_Provider->IsEnabled(Control); } WDFWMIINSTANCE GetHandle( VOID ) { return (WDFWMIINSTANCE) GetObjectHandle(); } virtual BOOLEAN IsQueryInstanceSupported( VOID ) =0; virtual _Must_inspect_result_ __drv_sameIRQL __drv_maxIRQL(PASSIVE_LEVEL) NTSTATUS QueryInstance( __in ULONG OutBufferSize, __out_bcount_part(OutBufferSize, *BufferUsed) PVOID OutBuffer, __out PULONG BufferUsed ) =0; virtual BOOLEAN IsSetInstanceSupported( VOID ) =0; virtual _Must_inspect_result_ __drv_sameIRQL __drv_maxIRQL(PASSIVE_LEVEL) NTSTATUS SetInstance( __in ULONG InBufferSize, __in_bcount(InBufferSize) PVOID InBuffer ) =0; virtual BOOLEAN IsSetItemSupported( VOID ) =0; virtual _Must_inspect_result_ __drv_sameIRQL __drv_maxIRQL(PASSIVE_LEVEL) NTSTATUS SetItem( __in ULONG DataItemId, __in ULONG InBufferSize, __in_bcount(InBufferSize) PVOID InBuffer ) =0; virtual BOOLEAN IsExecuteMethodSupported( VOID ) =0; virtual _Must_inspect_result_ __drv_sameIRQL __drv_maxIRQL(PASSIVE_LEVEL) NTSTATUS ExecuteMethod( __in ULONG MethodId, __in ULONG InBufferSize, __inout ULONG OutBufferSize, __drv_when(InBufferSize >= OutBufferSize, __inout_bcount(InBufferSize)) __drv_when(InBufferSize < OutBufferSize, __inout_bcount(OutBufferSize)) PVOID Buffer, __out PULONG BufferUsed ) =0; // begin FxObject overrides virtual BOOLEAN Dispose( VOID ); // end FxObject overrides protected: // // List entry used by FxWmiProvider to hold the list of WMI instances // LIST_ENTRY m_ListEntry; // // Pointer to the parent provider // FxWmiProvider* m_Provider; }; struct FxWmiInstanceQueryInstanceCallback : public FxCallback { PFN_WDF_WMI_INSTANCE_QUERY_INSTANCE m_Method; FxWmiInstanceQueryInstanceCallback( __in PFX_DRIVER_GLOBALS FxDriverGlobals ) : FxCallback(FxDriverGlobals), m_Method(NULL) { } ~FxWmiInstanceQueryInstanceCallback() { } _Must_inspect_result_ __drv_sameIRQL __drv_maxIRQL(PASSIVE_LEVEL) NTSTATUS Invoke( __in WDFDEVICE Device, __in WDFWMIINSTANCE WmiInstance, __inout ULONG OutBufferSize, __out_bcount(OutBufferSize) PVOID OutBuffer, __out PULONG BufferUsed ) { NTSTATUS status; UNREFERENCED_PARAMETER(Device); if (m_Method != NULL) { CallbackStart(); status = m_Method(WmiInstance, OutBufferSize, OutBuffer, BufferUsed); CallbackEnd(); } else { status = STATUS_UNSUCCESSFUL; } return status; } }; struct FxWmiInstanceSetInstanceCallback : public FxCallback { PFN_WDF_WMI_INSTANCE_SET_INSTANCE m_Method; FxWmiInstanceSetInstanceCallback( PFX_DRIVER_GLOBALS FxDriverGlobals ) : FxCallback(FxDriverGlobals), m_Method(NULL) { } ~FxWmiInstanceSetInstanceCallback() { } _Must_inspect_result_ __drv_sameIRQL __drv_maxIRQL(PASSIVE_LEVEL) NTSTATUS Invoke( __in WDFDEVICE Device, __in WDFWMIINSTANCE WmiInstance, __in ULONG InBufferSize, __in_bcount(InBufferSize) PVOID InBuffer ) { NTSTATUS status; UNREFERENCED_PARAMETER(Device); if (m_Method != NULL) { CallbackStart(); status = m_Method(WmiInstance, InBufferSize, InBuffer); CallbackEnd(); } else { status = STATUS_WMI_READ_ONLY; } return status; } }; struct FxWmiInstanceSetItemCallback : public FxCallback { PFN_WDF_WMI_INSTANCE_SET_ITEM m_Method; FxWmiInstanceSetItemCallback( PFX_DRIVER_GLOBALS FxDriverGlobals ) : FxCallback(FxDriverGlobals), m_Method(NULL) { } ~FxWmiInstanceSetItemCallback() { } _Must_inspect_result_ __drv_sameIRQL __drv_maxIRQL(PASSIVE_LEVEL) NTSTATUS Invoke( __in WDFDEVICE Device, __in WDFWMIINSTANCE WmiInstance, __in ULONG DataItemId, __in ULONG InBufferSize, __in_bcount(InBufferSize) PVOID InBuffer ) { NTSTATUS status; UNREFERENCED_PARAMETER(Device); if (m_Method != NULL) { CallbackStart(); status = m_Method(WmiInstance, DataItemId, InBufferSize, InBuffer); CallbackEnd(); } else { status = STATUS_WMI_READ_ONLY; } return status; } }; struct FxWmiInstanceExecuteMethodCallback : public FxCallback { PFN_WDF_WMI_INSTANCE_EXECUTE_METHOD m_Method; FxWmiInstanceExecuteMethodCallback( PFX_DRIVER_GLOBALS FxDriverGlobals ) : FxCallback(FxDriverGlobals), m_Method(NULL) { } ~FxWmiInstanceExecuteMethodCallback() { } _Must_inspect_result_ __drv_sameIRQL __drv_maxIRQL(PASSIVE_LEVEL) NTSTATUS Invoke( __in WDFDEVICE Device, __in WDFWMIINSTANCE WmiInstance, __in ULONG MethodId, __in ULONG InBufferSize, __inout ULONG OutBufferSize, __drv_when(InBufferSize >= OutBufferSize, __inout_bcount(InBufferSize)) __drv_when(InBufferSize < OutBufferSize, __inout_bcount(OutBufferSize)) PVOID Buffer, __out PULONG BufferUsed ) { NTSTATUS status; UNREFERENCED_PARAMETER(Device); if (m_Method != NULL) { CallbackStart(); status = m_Method(WmiInstance, MethodId, InBufferSize, OutBufferSize, Buffer, BufferUsed); CallbackEnd(); } else { status = STATUS_WMI_GUID_NOT_FOUND; } return status; } }; class FxWmiInstanceExternal : public FxWmiInstance { public: FxWmiInstanceExternal( __in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PWDF_WMI_INSTANCE_CONFIG Config, __in FxWmiProvider* Provider ); VOID SetContextForQueryLength( __in ULONG ContextSize ) { m_ContextLength = ContextSize; } static _Must_inspect_result_ NTSTATUS _Create( __in PFX_DRIVER_GLOBALS FxDriverGlobals, __in FxWmiProvider* Provider, __in PWDF_WMI_INSTANCE_CONFIG WmiInstanceConfig, __in_opt PWDF_OBJECT_ATTRIBUTES InstanceAttributes, __out WDFWMIINSTANCE* WmiInstance, __out FxWmiInstanceExternal** Instance ); protected: virtual BOOLEAN IsQueryInstanceSupported( VOID ); virtual _Must_inspect_result_ __drv_sameIRQL __drv_maxIRQL(PASSIVE_LEVEL) NTSTATUS QueryInstance( __inout ULONG OutBufferSize, __out_xcount(OutBuffer->size) PVOID OutBuffer, __out PULONG BufferUsed ); virtual BOOLEAN IsSetInstanceSupported( VOID ); virtual _Must_inspect_result_ __drv_sameIRQL __drv_maxIRQL(PASSIVE_LEVEL) NTSTATUS SetInstance( __in ULONG InBufferSize, __in_bcount(InBufferSize) PVOID InBuffer ); virtual BOOLEAN IsSetItemSupported( VOID ); virtual _Must_inspect_result_ __drv_sameIRQL __drv_maxIRQL(PASSIVE_LEVEL) NTSTATUS SetItem( __in ULONG DataItemId, __in ULONG InBufferSize, __in_bcount(InBufferSize) PVOID InBuffer ); virtual BOOLEAN IsExecuteMethodSupported( VOID ); virtual _Must_inspect_result_ __drv_sameIRQL __drv_maxIRQL(PASSIVE_LEVEL) NTSTATUS ExecuteMethod( __in ULONG MethodId, __in ULONG InBufferSize, __inout ULONG OutBufferSize, __drv_when(InBufferSize >= OutBufferSize, __inout_bcount(InBufferSize)) __drv_when(InBufferSize < OutBufferSize, __inout_bcount(OutBufferSize)) PVOID Buffer, __out PULONG BufferUsed ); protected: // // Attributes associated with this instance // FxWmiInstanceQueryInstanceCallback m_QueryInstanceCallback; FxWmiInstanceSetInstanceCallback m_SetInstanceCallback; FxWmiInstanceSetItemCallback m_SetItemCallback; FxWmiInstanceExecuteMethodCallback m_ExecuteMethodCallback; ULONG m_ContextLength; BOOLEAN m_UseContextForQuery; }; typedef _Must_inspect_result_ __drv_sameIRQL __drv_maxIRQL(PASSIVE_LEVEL) NTSTATUS (*PFN_FX_WMI_INSTANCE_QUERY_INSTANCE)( __in CfxDevice* Device, __in FxWmiInstanceInternal* Instance, __inout ULONG OutBufferSize, __out_bcount(OutBufferSize) PVOID OutBuffer, __out PULONG BufferUsed ); typedef _Must_inspect_result_ __drv_sameIRQL __drv_maxIRQL(PASSIVE_LEVEL) NTSTATUS (*PFN_FX_WMI_INSTANCE_SET_INSTANCE)( __in CfxDevice* Device, __in FxWmiInstanceInternal* Instance, __in ULONG InBufferSize, __in_bcount(InBufferSize) PVOID InBuffer ); typedef _Must_inspect_result_ __drv_sameIRQL __drv_maxIRQL(PASSIVE_LEVEL) NTSTATUS (*PFN_FX_WMI_INSTANCE_SET_ITEM)( __in CfxDevice* Device, __in FxWmiInstanceInternal* Instance, __in ULONG DataItemId, __in ULONG InBufferSize, __in_bcount(InBufferSize) PVOID InBuffer ); typedef _Must_inspect_result_ __drv_sameIRQL __drv_maxIRQL(PASSIVE_LEVEL) NTSTATUS (*PFN_FX_WMI_INSTANCE_EXECUTE_METHOD)( __in CfxDevice* Device, __in FxWmiInstanceInternal* Instance, __in ULONG MethodId, __in ULONG InBufferSize, __inout ULONG OutBufferSize, __drv_when(InBufferSize >= OutBufferSize, __inout_bcount(InBufferSize)) __drv_when(InBufferSize < OutBufferSize, __inout_bcount(OutBufferSize)) PVOID Buffer, __out PULONG BufferUsed ); struct FxWmiInstanceInternalCallbacks { FxWmiInstanceInternalCallbacks( VOID ) { RtlZeroMemory(this, sizeof(*this)); } // // Callback when caller wants to query the entire data item's buffer. // PFN_FX_WMI_INSTANCE_QUERY_INSTANCE QueryInstance; // // Callback when caller wants to set the entire data item's buffer. // PFN_FX_WMI_INSTANCE_SET_INSTANCE SetInstance; // // Callback when caller wants to set a single field in the data item's buffer // PFN_FX_WMI_INSTANCE_SET_ITEM SetItem; // // Callback when caller wants to execute a method on the data item. // PFN_FX_WMI_INSTANCE_EXECUTE_METHOD ExecuteMethod; }; class FxWmiInstanceInternal : public FxWmiInstance { public: FxWmiInstanceInternal( __in PFX_DRIVER_GLOBALS FxDriverGlobals, __in FxWmiInstanceInternalCallbacks* Callbacks, __in FxWmiProvider* m_Provider ); protected: virtual BOOLEAN IsQueryInstanceSupported( VOID ); virtual _Must_inspect_result_ __drv_sameIRQL __drv_maxIRQL(PASSIVE_LEVEL) NTSTATUS QueryInstance( __inout ULONG OutBufferSize, __out_bcount(OutBufferSize) PVOID OutBuffer, __out PULONG BufferUsed ); virtual BOOLEAN IsSetInstanceSupported( VOID ); virtual _Must_inspect_result_ __drv_sameIRQL __drv_maxIRQL(PASSIVE_LEVEL) NTSTATUS SetInstance( __in ULONG InBufferSize, __in_bcount(InBufferSize) PVOID InBuffer ); virtual BOOLEAN IsSetItemSupported( VOID ); virtual _Must_inspect_result_ __drv_sameIRQL __drv_maxIRQL(PASSIVE_LEVEL) NTSTATUS SetItem( __in ULONG DataItemId, __in ULONG InBufferSize, __in_bcount(InBufferSize) PVOID InBuffer ); virtual BOOLEAN IsExecuteMethodSupported( VOID ); virtual _Must_inspect_result_ __drv_sameIRQL __drv_maxIRQL(PASSIVE_LEVEL) NTSTATUS ExecuteMethod( __in ULONG MethodId, __in ULONG InBufferSize, __inout ULONG OutBufferSize, __drv_when(InBufferSize >= OutBufferSize, __inout_bcount(InBufferSize)) __drv_when(InBufferSize < OutBufferSize, __inout_bcount(OutBufferSize)) PVOID Buffer, __out PULONG BufferUsed ); protected: PFN_FX_WMI_INSTANCE_QUERY_INSTANCE m_QueryInstance; PFN_FX_WMI_INSTANCE_SET_INSTANCE m_SetInstance; PFN_FX_WMI_INSTANCE_SET_ITEM m_SetItem; PFN_FX_WMI_INSTANCE_EXECUTE_METHOD m_ExecuteMethod; }; #endif // _FXWMIINSTANCE_H_