427 lines
11 KiB
C++
427 lines
11 KiB
C++
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// BVTREFRESH.CPP
|
|
//
|
|
//
|
|
// Copyright (c)2000 Microsoft Corporation, All Rights Reserved
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
#include <bvt.h>
|
|
#include "BVTRefresh.h"
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////
|
|
//
|
|
// Counter data
|
|
//
|
|
// These structures are used as a matter of convienience and
|
|
// clarity. A real client should enumerate the properties
|
|
// of an object in order to determine the number and names
|
|
// of the counter properties.
|
|
//
|
|
///////////////////////////////////////////////////////////////////
|
|
// The number of counter properties for Win32_BasicHiPerf
|
|
|
|
enum
|
|
{
|
|
Ctr1,
|
|
Ctr2,
|
|
Ctr3,
|
|
Ctr4,
|
|
Ctr5,
|
|
NumCtrs
|
|
};
|
|
|
|
// The names and handles (set by SetHandles()) for a Win32_BasicHiPerf object
|
|
|
|
struct CCounterData
|
|
{
|
|
WCHAR m_wcsName[256];
|
|
long m_lHandle;
|
|
} g_aCounters[] =
|
|
{
|
|
L"Counter1", 0,
|
|
L"Counter2", 0,
|
|
L"Counter3", 0,
|
|
L"Counter4", 0,
|
|
L"Counter5", 0,
|
|
};
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////
|
|
//
|
|
// CRefresher
|
|
//
|
|
///////////////////////////////////////////////////////////////////
|
|
CRefresher::CRefresher() : m_pNameSpace(NULL), m_pRefresher(NULL), m_pConfig(NULL)
|
|
{
|
|
}
|
|
|
|
CRefresher::~CRefresher()
|
|
{
|
|
SAFE_RELEASE_PTR(m_pNameSpace);
|
|
SAFE_RELEASE_PTR(m_pRefresher);
|
|
SAFE_RELEASE_PTR(m_pConfig);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////
|
|
//
|
|
// Helper methods
|
|
//
|
|
///////////////////////////////////////////////////////////////////
|
|
|
|
///////////////////////////////////////////////////////////////////
|
|
//
|
|
// SetHandles will initialize the IWbemObjectAccess handle values
|
|
// in the counter array.
|
|
//
|
|
// Returns a status code. Use the SUCCEEDED() and FAILED() macros
|
|
// to interpret results.
|
|
//
|
|
///////////////////////////////////////////////////////////////////
|
|
HRESULT CRefresher::SetHandles(WCHAR * wcsClass)
|
|
{
|
|
HRESULT hr = WBEM_NO_ERROR;
|
|
|
|
IWbemClassObject* pObj = NULL;
|
|
long lIndex;
|
|
|
|
// Get an IWbemObjectAccess interface to one of the sample objects
|
|
// ===============================================================
|
|
|
|
hr = m_pNameSpace->GetObject( CBSTR(wcsClass), 0, NULL, &pObj, NULL );
|
|
if ( SUCCEEDED( hr ) )
|
|
{
|
|
|
|
// Get the alternate interface
|
|
// ===========================
|
|
IWbemObjectAccess* pAccess = NULL;
|
|
hr = pObj->QueryInterface( IID_IWbemObjectAccess, ( LPVOID* )&pAccess );
|
|
if( SUCCEEDED(hr))
|
|
{
|
|
|
|
// Set the access handles for all of the counter properties
|
|
// ========================================================
|
|
for ( lIndex = Ctr1; lIndex < NumCtrs; lIndex++ )
|
|
{
|
|
long lHandle;
|
|
hr = pAccess->GetPropertyHandle( g_aCounters[lIndex].m_wcsName, NULL, &lHandle );
|
|
if( SUCCEEDED(hr))
|
|
{
|
|
g_aCounters[lIndex].m_lHandle = lHandle;
|
|
}
|
|
}
|
|
}
|
|
SAFE_RELEASE_PTR(pAccess);
|
|
}
|
|
|
|
SAFE_RELEASE_PTR(pObj);
|
|
return hr;
|
|
}
|
|
///////////////////////////////////////////////////////////////////
|
|
//
|
|
// Class method API
|
|
//
|
|
///////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////
|
|
//
|
|
// Initialize will create the refresher and configuration manager
|
|
// and set the IWbemObjectAccess handles which are used to access
|
|
// property values of the instances.
|
|
//
|
|
// Returns a status code. Use the SUCCEEDED() and FAILED() macros
|
|
// to interpret results.
|
|
//
|
|
///////////////////////////////////////////////////////////////////
|
|
HRESULT CRefresher::Initialize(IWbemServices* pNameSpace, WCHAR * wcsClass)
|
|
{
|
|
HRESULT hr = WBEM_NO_ERROR;
|
|
|
|
// Copy the namespace pointer
|
|
// ==========================
|
|
|
|
if ( NULL == pNameSpace )
|
|
{
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
}
|
|
|
|
m_pNameSpace = pNameSpace;
|
|
m_pNameSpace->AddRef();
|
|
|
|
// Create the refresher and refresher manager
|
|
// ==========================================
|
|
|
|
hr = CoCreateInstance( CLSID_WbemRefresher, NULL, CLSCTX_INPROC_SERVER, IID_IWbemRefresher, (void**) &m_pRefresher );
|
|
if ( SUCCEEDED(hr))
|
|
{
|
|
hr = m_pRefresher->QueryInterface( IID_IWbemConfigureRefresher, (void**) &m_pConfig );
|
|
if( SUCCEEDED(hr))
|
|
{
|
|
// Set the access handles
|
|
// ======================
|
|
hr = SetHandles(wcsClass);
|
|
}
|
|
}
|
|
return hr;
|
|
}
|
|
///////////////////////////////////////////////////////////////////
|
|
//
|
|
// AddObject will add a set of objects to the refresher. The
|
|
// method will update m_aInstances with the instance data.
|
|
//
|
|
// Returns a status code. Use the SUCCEEDED() and FAILED() macros
|
|
// to interpret results.
|
|
//
|
|
///////////////////////////////////////////////////////////////////
|
|
HRESULT CRefresher::AddObjects(WCHAR * wcsClass)
|
|
{
|
|
HRESULT hr = WBEM_NO_ERROR;
|
|
|
|
long lIndex = 0;
|
|
WCHAR wcsObjName[256];
|
|
|
|
// Loop through all instances of the class and add them to the refresher
|
|
// =============================================================================
|
|
|
|
for ( lIndex = 0; lIndex < clNumInstances; lIndex++ )
|
|
{
|
|
IWbemClassObject* pObj = NULL;
|
|
IWbemObjectAccess* pAccess = NULL;
|
|
long lID;
|
|
|
|
// Set the object path (e.g. Win32_BasicHiPerf=1)
|
|
// ==============================================
|
|
|
|
swprintf( wcsObjName, L"%s=%i", wcsClass, lIndex );
|
|
|
|
// Add the object
|
|
// ==============
|
|
hr = m_pConfig->AddObjectByPath( m_pNameSpace, wcsObjName, 0, NULL, &pObj, &lID );
|
|
if ( SUCCEEDED( hr ) )
|
|
{
|
|
|
|
// Save the IWbemObjectAccess interface
|
|
// ====================================
|
|
hr = pObj->QueryInterface( IID_IWbemObjectAccess, (void**) &pAccess );
|
|
SAFE_RELEASE_PTR(pObj);
|
|
m_Instances[lIndex].Set(pAccess, lID);
|
|
|
|
// Set does it's own AddRef()
|
|
// ==========================
|
|
SAFE_RELEASE_PTR(pAccess);
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
///////////////////////////////////////////////////////////////////
|
|
//
|
|
// RemoveObjects calls Remove() on the refresher's configuration
|
|
// manager to remove all of the objects from the refresher.
|
|
//
|
|
// Returns a status code. Use the SUCCEEDED() and FAILED() macros
|
|
// to interpret results.
|
|
//
|
|
///////////////////////////////////////////////////////////////////
|
|
HRESULT CRefresher::RemoveObjects()
|
|
{
|
|
HRESULT hr = WBEM_NO_ERROR;
|
|
|
|
long lInstance = 0;
|
|
|
|
// Remove the instances
|
|
// ====================
|
|
|
|
for ( lInstance = 0; lInstance < clNumInstances; lInstance++ )
|
|
{
|
|
m_pConfig->Remove( m_Instances[lInstance].GetID(), 0L );
|
|
|
|
m_Instances[lInstance].Reset();
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
///////////////////////////////////////////////////////////////////
|
|
//
|
|
// ShowInstanceData will output all of the counter data for all
|
|
// of the instances within the refresher.
|
|
//
|
|
// Returns a status code. Use the SUCCEEDED() and FAILED() macros
|
|
// to interpret results.
|
|
//
|
|
///////////////////////////////////////////////////////////////////
|
|
HRESULT CRefresher::EnumerateObjectData()
|
|
{
|
|
HRESULT hr = WBEM_NO_ERROR;
|
|
|
|
long lInstance;
|
|
long lCounter;
|
|
|
|
// Cycle through all of the instances and print all the counter data
|
|
// =================================================================
|
|
|
|
// Instance loop
|
|
// =============
|
|
|
|
for (lInstance = 0; lInstance < clNumInstances; lInstance++)
|
|
{
|
|
// Counter loop
|
|
// ============
|
|
|
|
for (lCounter = Ctr1; lCounter < NumCtrs; lCounter++)
|
|
{
|
|
DWORD dwVal;
|
|
IWbemObjectAccess* pAccess = m_Instances[lInstance].GetMember();
|
|
|
|
// Read the counter property value using the high performance IWbemObjectAccess->ReadDWORD().
|
|
// NOTE: Remember to never to this while a refresh is in process!
|
|
// ==========================================================================================
|
|
|
|
hr = pAccess->ReadDWORD( g_aCounters[lCounter].m_lHandle, &dwVal);
|
|
if (FAILED(hr))
|
|
{
|
|
break;
|
|
}
|
|
SAFE_RELEASE_PTR(pAccess);
|
|
}
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////
|
|
//
|
|
// AddEnum will add an enumerator to the refresher. The
|
|
// function will return a status code. The enumerator class member
|
|
// will updated.
|
|
//
|
|
// Returns a status code. Use the SUCCEEDED() and FAILED() macros
|
|
// to interpret results.
|
|
//
|
|
///////////////////////////////////////////////////////////////////
|
|
HRESULT CRefresher::AddEnum(WCHAR * wcsClass)
|
|
{
|
|
HRESULT hr = WBEM_NO_ERROR;
|
|
|
|
IWbemHiPerfEnum* pEnum = NULL;
|
|
long lID;
|
|
|
|
// Add an enumerator to the refresher
|
|
// ==================================
|
|
|
|
hr = m_pConfig->AddEnum( m_pNameSpace,wcsClass, 0, NULL, &pEnum, &lID );
|
|
|
|
m_Enum.Set(pEnum, lID);
|
|
|
|
// Set does it's own AddRef
|
|
// ========================
|
|
SAFE_RELEASE_PTR(pEnum);
|
|
return hr;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////
|
|
//
|
|
// RemoveEnum calls Remove() on the refresher's configuration
|
|
// manager to remove the enumerator from the refresher.
|
|
//
|
|
// Returns a status code. Use the SUCCEEDED() and FAILED() macros
|
|
// to interpret results.
|
|
//
|
|
///////////////////////////////////////////////////////////////////
|
|
HRESULT CRefresher::RemoveEnum()
|
|
{
|
|
HRESULT hr = WBEM_NO_ERROR;
|
|
|
|
// Remove the enumerator
|
|
// =====================
|
|
|
|
hr = m_pConfig->Remove( m_Enum.GetID(), 0L );
|
|
|
|
m_Enum.Reset();
|
|
|
|
return hr;
|
|
}
|
|
///////////////////////////////////////////////////////////////////
|
|
//
|
|
// ShowEnumeratorData will output the number of instances within
|
|
// an enumerator. Property values from the instances may obtained
|
|
// using the standard WMI methods.
|
|
//
|
|
// Returns a status code. Use the SUCCEEDED() and FAILED() macros
|
|
// to interpret results.
|
|
//
|
|
///////////////////////////////////////////////////////////////////
|
|
HRESULT CRefresher::EnumerateEnumeratorData()
|
|
{
|
|
HRESULT hr = WBEM_NO_ERROR;
|
|
|
|
DWORD dwNumReturned = clNumInstances;
|
|
DWORD dwNumObjects = 0;
|
|
|
|
IWbemObjectAccess** apEnumAccess = NULL;
|
|
|
|
IWbemHiPerfEnum* pEnum = m_Enum.GetMember();
|
|
|
|
// Fetch the instances from the enumerator
|
|
// =======================================
|
|
// Try to get the instances from the enumerator
|
|
// ============================================
|
|
hr = pEnum->GetObjects( 0L, dwNumObjects, apEnumAccess, &dwNumReturned );
|
|
|
|
// Is the buffer too small?
|
|
// ========================
|
|
|
|
if ( WBEM_E_BUFFER_TOO_SMALL == hr )
|
|
{
|
|
// Increase the buffer size
|
|
// ========================
|
|
|
|
delete [] apEnumAccess;
|
|
|
|
apEnumAccess = new IWbemObjectAccess*[dwNumReturned];
|
|
dwNumObjects = dwNumReturned;
|
|
memset( apEnumAccess, 0, sizeof( apEnumAccess ));
|
|
|
|
if ( NULL != apEnumAccess )
|
|
{
|
|
hr = pEnum->GetObjects( 0L, dwNumObjects, apEnumAccess, &dwNumReturned );
|
|
}
|
|
else
|
|
{
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
}
|
|
|
|
|
|
// Release the objects from the enumerator's object array
|
|
// ======================================================
|
|
|
|
for ( DWORD nCtr = 0; nCtr < dwNumReturned; nCtr++ )
|
|
{
|
|
if (NULL != apEnumAccess[nCtr])
|
|
{
|
|
apEnumAccess[nCtr]->Release();
|
|
apEnumAccess[nCtr] = NULL;
|
|
}
|
|
}
|
|
|
|
if ( NULL != apEnumAccess )
|
|
delete [] apEnumAccess;
|
|
|
|
pEnum->Release();
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CRefresher::Refresh()
|
|
///////////////////////////////////////////////////////////////////
|
|
//
|
|
// Refresh simply calls the IWbemRefresher->Refresh() method to
|
|
// update all members of the refresher.
|
|
//
|
|
// Returns a status code. Use the SUCCEEDED() and FAILED() macros
|
|
// to interpret results.
|
|
//
|
|
///////////////////////////////////////////////////////////////////
|
|
{
|
|
return m_pRefresher->Refresh( 0L );
|
|
} |