windows-nt/Source/XPSP1/NT/admin/wmi/wbem/bvt/whistler/bvtrefresh.cpp
2020-09-26 16:20:57 +08:00

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 );
}