395 lines
9.9 KiB
C++
395 lines
9.9 KiB
C++
//////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
// BasicHiPerf.h
|
|
|
|
//
|
|
|
|
// Module: WMI high performance provider sample code
|
|
|
|
//
|
|
|
|
// This is the skeleton code implementation of a high performance
|
|
|
|
// provider. This file includes the provider and refresher code
|
|
|
|
//
|
|
|
|
// In this example, we are using a single object scenario. The
|
|
|
|
// provider provides one type of object called Win32_BasicHiPerf.
|
|
|
|
// There is a static number of instances available, specified by
|
|
|
|
// NUM_INSTANCES and maintained by the CHiPerfProvider class.
|
|
|
|
// When a refresher is created, it has two local caches: one
|
|
|
|
// for the instances that it contains, and another for the
|
|
|
|
// enumerators. Since there is only one class, only one enumerator
|
|
|
|
// should be necessary, but there can be up to MAX_ENUMERATORS
|
|
|
|
// enumerators added to a given refresher. The members of a refresher
|
|
|
|
// are given IDs. The IDs for the enumerators are essentially array
|
|
|
|
// indecies into the enumerator array. The IDs for the objects are
|
|
|
|
// stored in an array that maps the unique ID to one of the cached
|
|
|
|
// objects. The enumerator IDs are within the range of 0 to
|
|
|
|
// MAX_ENUMERATORS - 1, and the objects will have IDs equal or greater
|
|
|
|
// than MAX_ENUMERATORS.
|
|
|
|
//
|
|
|
|
// The actual counter data is simulated by the CSampleDataSource
|
|
|
|
// which maintains a set of CSampleInstances. Periodically, the
|
|
|
|
// CSampleInstance counter values are updated. The objects in the
|
|
|
|
// refresher are only updated on a refresh.
|
|
|
|
//
|
|
|
|
// History:
|
|
|
|
// a-dcrews 12-Jan-99 Created
|
|
|
|
// a-dcrews 10-Mar-99 Added data source simulation
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// Copyright (c) Microsoft Corporation, All Rights Reserved
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
#ifndef _HIPERFPROV_H_
|
|
#define _HIPERFPROV_H_
|
|
|
|
#define UNICODE
|
|
#define _UNICODE
|
|
|
|
#include <tchar.h>
|
|
#include <wbemprov.h>
|
|
|
|
class CRefresher;
|
|
class CRefCacheElement;
|
|
|
|
//////////////////////////////////////////////////////////////
|
|
//
|
|
//
|
|
// Constants and globals
|
|
//
|
|
//
|
|
//////////////////////////////////////////////////////////////
|
|
|
|
#define NUM_OBJECTS 1
|
|
#define NUM_INSTANCES 5
|
|
#define MAX_INSTANCES 128
|
|
#define MAX_ENUMERATORS 10
|
|
|
|
#define SAMPLE_CLASS _T("Win32_BasicHiPerf")
|
|
|
|
#define PROP_DWORD 0x0001L
|
|
#define PROP_QWORD 0x0002L
|
|
#define PROP_VALUE 0x0004L
|
|
|
|
// This enumeration is used to reference the counters. It
|
|
// matchs the number of counters in the mof definition of
|
|
// the Win32_BasicHiPerf object.
|
|
|
|
const enum CounterHandles
|
|
{
|
|
ctr1 = 0,
|
|
ctr2,
|
|
ctr3,
|
|
ctr4,
|
|
ctr5,
|
|
NumCtrs
|
|
};
|
|
|
|
//////////////////////////////////////////////////////////////
|
|
//
|
|
// CCacheMapEl
|
|
//
|
|
// The IDs assigned to objects added to the refresher are
|
|
// mapped to the actual object cache index using an array
|
|
// of CCacheMapEls. The generation of unique IDs is controlled
|
|
// by the static member m_lGenID.
|
|
//
|
|
//////////////////////////////////////////////////////////////
|
|
|
|
class CCacheMapEl
|
|
{
|
|
static long m_lGenID;
|
|
|
|
// The unique ID of the object passed back to the caller
|
|
// =====================================================
|
|
long m_lUID;
|
|
|
|
// The index of the object in the instance cache
|
|
// =============================================
|
|
long m_lIndex;
|
|
|
|
public:
|
|
CCacheMapEl(long lIndex) : m_lIndex(lIndex), m_lUID(m_lGenID++)
|
|
{}
|
|
|
|
long GetUID() {return m_lUID;}
|
|
};
|
|
|
|
//////////////////////////////////////////////////////////////
|
|
//
|
|
// CSampleInstance
|
|
//
|
|
// This class is a representation of a real data instance.
|
|
// The counter values correspond directly to WMI object
|
|
// parameters.
|
|
//
|
|
//////////////////////////////////////////////////////////////
|
|
|
|
class CSampleInstance
|
|
{
|
|
// The counter values
|
|
// ==================
|
|
DWORD m_aCounter[NumCtrs];
|
|
|
|
// The lock mechanism
|
|
// ==================
|
|
CRITICAL_SECTION CS;
|
|
|
|
public:
|
|
CSampleInstance();
|
|
CSampleInstance(const CSampleInstance &aInst);
|
|
~CSampleInstance();
|
|
|
|
DWORD Lock(bool bLock);
|
|
|
|
DWORD SetCounter(long lCtr, DWORD dwVal);
|
|
DWORD GetCounter(long lCtr, DWORD* pdwVal);
|
|
};
|
|
|
|
//////////////////////////////////////////////////////////////
|
|
//
|
|
// CSampleDataSource
|
|
//
|
|
// This class is a representation of a real data source.
|
|
// Instance data counters are periodically updated, and their
|
|
// values may be retrieved to update the refresher.
|
|
//
|
|
//////////////////////////////////////////////////////////////
|
|
|
|
class CSampleDataSource
|
|
{
|
|
// The IWbemObjectAccess counter handles
|
|
// =====================================
|
|
long m_alHandle[NumCtrs];
|
|
|
|
// The array of instances
|
|
// ======================
|
|
CSampleInstance m_aInstance[NUM_INSTANCES];
|
|
|
|
// The data source control members (mocks changes in counter values)
|
|
// =================================================================
|
|
HANDLE m_hThread;
|
|
|
|
// The thread termination event
|
|
// ============================
|
|
HANDLE m_hQuit;
|
|
|
|
|
|
DWORD SetHandles(IWbemClassObject* pSampleClass);
|
|
|
|
DWORD Simulate();
|
|
|
|
static unsigned __stdcall CSampleDataSource::ThreadEntry(void* pArgs);
|
|
|
|
public:
|
|
CSampleDataSource();
|
|
virtual ~CSampleDataSource();
|
|
|
|
DWORD Initialize(IWbemClassObject* pSampleClass);
|
|
|
|
DWORD UpdateInstance(IWbemObjectAccess* pObj);
|
|
};
|
|
|
|
//////////////////////////////////////////////////////////////
|
|
//
|
|
// CHiPerfProvider
|
|
//
|
|
// The provider maintains a single IWbemClassObject to be used
|
|
// as a template to spawn instances for the Refresher as well
|
|
// as QueryInstances. It also maintains the static sample
|
|
// data source which provides all data to the instances.
|
|
//
|
|
//////////////////////////////////////////////////////////////
|
|
|
|
class CHiPerfProvider : public IWbemProviderInit, public IWbemHiPerfProvider
|
|
{
|
|
long m_lRef;
|
|
|
|
// Our mock data source
|
|
// ====================
|
|
|
|
static CSampleDataSource* m_pSampleDS;
|
|
|
|
// An instance template (used for QueryInstances)
|
|
// ==============================================
|
|
|
|
IWbemClassObject* m_pTemplate;
|
|
|
|
public:
|
|
CHiPerfProvider();
|
|
~CHiPerfProvider();
|
|
|
|
// Standard COM methods
|
|
// ====================
|
|
|
|
STDMETHODIMP QueryInterface(REFIID riid, void** ppv);
|
|
STDMETHODIMP_(ULONG) AddRef();
|
|
STDMETHODIMP_(ULONG) Release();
|
|
|
|
// IWbemProviderInit COM interface
|
|
// ===============================
|
|
|
|
STDMETHODIMP Initialize(
|
|
/* [unique][in] */ LPWSTR wszUser,
|
|
/* [in] */ long lFlags,
|
|
/* [in] */ LPWSTR wszNamespace,
|
|
/* [unique][in] */ LPWSTR wszLocale,
|
|
/* [in] */ IWbemServices __RPC_FAR *pNamespace,
|
|
/* [in] */ IWbemContext __RPC_FAR *pCtx,
|
|
/* [in] */ IWbemProviderInitSink __RPC_FAR *pInitSink );
|
|
|
|
// IWbemHiPerfProvider COM interfaces
|
|
// ==================================
|
|
|
|
STDMETHODIMP QueryInstances(
|
|
/* [in] */ IWbemServices __RPC_FAR *pNamespace,
|
|
/* [string][in] */ WCHAR __RPC_FAR *wszClass,
|
|
/* [in] */ long lFlags,
|
|
/* [in] */ IWbemContext __RPC_FAR *pCtx,
|
|
/* [in] */ IWbemObjectSink __RPC_FAR *pSink );
|
|
|
|
STDMETHODIMP CreateRefresher(
|
|
/* [in] */ IWbemServices __RPC_FAR *pNamespace,
|
|
/* [in] */ long lFlags,
|
|
/* [out] */ IWbemRefresher __RPC_FAR *__RPC_FAR *ppRefresher );
|
|
|
|
STDMETHODIMP CreateRefreshableObject(
|
|
/* [in] */ IWbemServices __RPC_FAR *pNamespace,
|
|
/* [in] */ IWbemObjectAccess __RPC_FAR *pTemplate,
|
|
/* [in] */ IWbemRefresher __RPC_FAR *pRefresher,
|
|
/* [in] */ long lFlags,
|
|
/* [in] */ IWbemContext __RPC_FAR *pContext,
|
|
/* [out] */ IWbemObjectAccess __RPC_FAR *__RPC_FAR *ppRefreshable,
|
|
/* [out] */ long __RPC_FAR *plId );
|
|
|
|
STDMETHODIMP StopRefreshing(
|
|
/* [in] */ IWbemRefresher __RPC_FAR *pRefresher,
|
|
/* [in] */ long lId,
|
|
/* [in] */ long lFlags );
|
|
|
|
STDMETHODIMP CreateRefreshableEnum(
|
|
/* [in] */ IWbemServices* pNamespace,
|
|
/* [in, string] */ LPCWSTR wszClass,
|
|
/* [in] */ IWbemRefresher* pRefresher,
|
|
/* [in] */ long lFlags,
|
|
/* [in] */ IWbemContext* pContext,
|
|
/* [in] */ IWbemHiPerfEnum* pHiPerfEnum,
|
|
/* [out] */ long* plId);
|
|
|
|
STDMETHODIMP GetObjects(
|
|
/* [in] */ IWbemServices* pNamespace,
|
|
/* [in] */ long lNumObjects,
|
|
/* [in,size_is(lNumObjects)] */ IWbemObjectAccess** apObj,
|
|
/* [in] */ long lFlags,
|
|
/* [in] */ IWbemContext* pContext);
|
|
};
|
|
|
|
|
|
//////////////////////////////////////////////////////////////
|
|
//
|
|
// CRefresher
|
|
//
|
|
// The refresher maintains an object and an enumerator cache.
|
|
// When an enumerator is added to the refrehser, it is added
|
|
// to the enumerator cache, and the index of the array is
|
|
// passed back as a unique ID. The refresher creates a cache
|
|
// of all instances during its initialization. When an object
|
|
// is added to the refresher, a mapping to the object is
|
|
// created between the unique ID and the index of the object
|
|
// in the cache. This allows the objects to be reused and
|
|
// facilitates the management of objects that have been added
|
|
// multiple times.
|
|
//
|
|
//////////////////////////////////////////////////////////////
|
|
|
|
class CRefresher : public IWbemRefresher
|
|
{
|
|
// COM reference counter
|
|
// =====================
|
|
|
|
long m_lRef;
|
|
|
|
// A pointer to the sample data source
|
|
// ===================================
|
|
|
|
CSampleDataSource* m_pDS;
|
|
|
|
// The enumerators that have been added to the refresher
|
|
// =====================================================
|
|
|
|
IWbemHiPerfEnum* m_apEnumerator[MAX_ENUMERATORS];
|
|
|
|
// The instances that have been added to the refresher
|
|
// ===================================================
|
|
|
|
CCacheMapEl* m_apInstMap[MAX_INSTANCES];
|
|
IWbemObjectAccess* m_apInstances[NUM_INSTANCES];
|
|
|
|
// The parent provider
|
|
// ===================
|
|
|
|
CHiPerfProvider* m_pProvider;
|
|
|
|
public:
|
|
CRefresher(CHiPerfProvider* pProvider, CSampleDataSource* pDS);
|
|
virtual ~CRefresher();
|
|
|
|
DWORD Initialize(IWbemClassObject* pSampleClass);
|
|
|
|
// Instance management functions
|
|
// =============================
|
|
|
|
DWORD AddObject(IWbemObjectAccess *pObj, IWbemObjectAccess **ppReturnObj, long *plId);
|
|
DWORD RemoveObject(long lId);
|
|
|
|
// Enumerator management functions
|
|
// ===============================
|
|
|
|
DWORD AddEnum(IWbemHiPerfEnum *pHiPerfEnum, long *plId);
|
|
DWORD RemoveEnum(long lId);
|
|
|
|
// COM methods
|
|
// ===========
|
|
|
|
STDMETHODIMP QueryInterface(REFIID riid, void** ppv);
|
|
STDMETHODIMP_(ULONG) AddRef();
|
|
STDMETHODIMP_(ULONG) Release();
|
|
|
|
STDMETHODIMP Refresh(/* [in] */ long lFlags);
|
|
};
|
|
|
|
|
|
#endif // _HIPERFPROV_H_
|