525 lines
13 KiB
C++
525 lines
13 KiB
C++
// Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
|
|
///////////////////////////////////////////////////////////////////
|
|
//
|
|
// RefClint.cpp : Refresher client implementation file
|
|
//
|
|
// CRefClient encapsulates the basic functionality of using a
|
|
// WMI high performance refresher.
|
|
//
|
|
///////////////////////////////////////////////////////////////////
|
|
|
|
#include <windows.h>
|
|
#include <stdio.h>
|
|
|
|
#include "RefClint.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,
|
|
};
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////
|
|
//
|
|
// CRefClient
|
|
//
|
|
///////////////////////////////////////////////////////////////////
|
|
|
|
|
|
CRefClient::CRefClient() :
|
|
m_pNameSpace(NULL), m_pRefresher(NULL), m_pConfig(NULL)
|
|
{
|
|
}
|
|
|
|
CRefClient::~CRefClient()
|
|
{
|
|
// Release the COM interfaces (if refresher members have not been manually
|
|
// removed, the refresher destructor should do so automatically)
|
|
// =======================================================================
|
|
|
|
if (NULL != m_pNameSpace)
|
|
m_pNameSpace->Release();
|
|
|
|
if (NULL != m_pRefresher)
|
|
m_pRefresher->Release();
|
|
|
|
if (NULL != m_pConfig)
|
|
m_pConfig->Release();
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////
|
|
//
|
|
// Helper methods
|
|
//
|
|
///////////////////////////////////////////////////////////////////
|
|
|
|
HRESULT CRefClient::SetHandles()
|
|
///////////////////////////////////////////////////////////////////
|
|
//
|
|
// SetHandles will initialize the IWbemObjectAccess handle values
|
|
// in the counter array.
|
|
//
|
|
// Returns a status code. Use the SUCCEEDED() and FAILED() macros
|
|
// to interpret results.
|
|
//
|
|
///////////////////////////////////////////////////////////////////
|
|
//ok
|
|
{
|
|
HRESULT hRes = WBEM_NO_ERROR;
|
|
|
|
IWbemClassObject* pObj = NULL;
|
|
IWbemObjectAccess* pAccess = NULL;
|
|
|
|
long lIndex;
|
|
|
|
// Get an IWbemObjectAccess interface to one of the sample objects
|
|
// ===============================================================
|
|
|
|
// Create a sample object
|
|
// ======================
|
|
|
|
BSTR strObj = SysAllocString( cwcsObjectPath );
|
|
|
|
hRes = m_pNameSpace->GetObject( strObj, 0, NULL, &pObj, NULL );
|
|
|
|
SysFreeString( strObj );
|
|
|
|
if ( FAILED( hRes ) )
|
|
goto cleanup;
|
|
|
|
// Get the alternate interface
|
|
// ===========================
|
|
|
|
hRes = pObj->QueryInterface( IID_IWbemObjectAccess, ( LPVOID* )&pAccess );
|
|
|
|
if ( FAILED( hRes ) )
|
|
goto cleanup;
|
|
|
|
// Set the access handles for all of the counter properties
|
|
// ========================================================
|
|
|
|
for ( lIndex = Ctr1; lIndex < NumCtrs; lIndex++ )
|
|
{
|
|
long lHandle;
|
|
|
|
hRes = pAccess->GetPropertyHandle( g_aCounters[lIndex].m_wcsName, NULL, &lHandle );
|
|
|
|
if ( FAILED( hRes ) )
|
|
goto cleanup;
|
|
|
|
g_aCounters[lIndex].m_lHandle = lHandle;
|
|
}
|
|
|
|
// Cleanup the object pointers
|
|
// ===========================
|
|
|
|
cleanup:
|
|
if ( NULL != pObj )
|
|
{
|
|
pObj->Release();
|
|
pObj = NULL;
|
|
}
|
|
|
|
if ( NULL != pAccess )
|
|
{
|
|
pAccess->Release();
|
|
pAccess = NULL;
|
|
}
|
|
|
|
if ( FAILED( hRes ) )
|
|
{
|
|
printf( "SetHandles() failed, 0x%x\n", hRes );
|
|
}
|
|
|
|
return hRes;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////
|
|
//
|
|
// Class method API
|
|
//
|
|
///////////////////////////////////////////////////////////////////
|
|
|
|
HRESULT CRefClient::Initialize(IWbemServices* pNameSpace)
|
|
///////////////////////////////////////////////////////////////////
|
|
//
|
|
// 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 hRes = 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
|
|
// ==========================================
|
|
|
|
hRes = CoCreateInstance( CLSID_WbemRefresher,
|
|
NULL,
|
|
CLSCTX_INPROC_SERVER,
|
|
IID_IWbemRefresher,
|
|
(void**) &m_pRefresher );
|
|
if ( FAILED( hRes ) )
|
|
return hRes;
|
|
|
|
hRes = m_pRefresher->QueryInterface( IID_IWbemConfigureRefresher,
|
|
(void**) &m_pConfig );
|
|
if ( FAILED( hRes ) )
|
|
return hRes;
|
|
|
|
// Set the access handles
|
|
// ======================
|
|
|
|
hRes = SetHandles();
|
|
|
|
return hRes;
|
|
}
|
|
|
|
HRESULT CRefClient::AddObjects()
|
|
///////////////////////////////////////////////////////////////////
|
|
//
|
|
// 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.
|
|
//
|
|
///////////////////////////////////////////////////////////////////
|
|
//ok
|
|
{
|
|
HRESULT hRes = WBEM_NO_ERROR;
|
|
|
|
long lIndex = 0;
|
|
WCHAR wcsObjName[256];
|
|
|
|
// Loop through all instances of Win32_BasicHiPerf 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", cwcsObjectPath, lIndex );
|
|
|
|
// Add the object
|
|
// ==============
|
|
|
|
hRes = m_pConfig->AddObjectByPath( m_pNameSpace, wcsObjName, 0, NULL, &pObj, &lID );
|
|
|
|
if ( FAILED( hRes ) )
|
|
{
|
|
printf( "AddObjectByPath() failed, 0x%x\n", hRes );
|
|
return hRes;
|
|
}
|
|
|
|
// Save the IWbemObjectAccess interface
|
|
// ====================================
|
|
|
|
hRes = pObj->QueryInterface( IID_IWbemObjectAccess, (void**) &pAccess );
|
|
hRes = pObj->Release();
|
|
|
|
m_Instances[lIndex].Set(pAccess, lID);
|
|
|
|
// Set does it's own AddRef()
|
|
// ==========================
|
|
|
|
pAccess->Release();
|
|
}
|
|
|
|
return hRes;
|
|
}
|
|
|
|
HRESULT CRefClient::RemoveObjects()
|
|
///////////////////////////////////////////////////////////////////
|
|
//
|
|
// 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 hRes = 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 hRes;
|
|
}
|
|
|
|
HRESULT CRefClient::ShowObjectData()
|
|
///////////////////////////////////////////////////////////////////
|
|
//
|
|
// 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 hRes = 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++)
|
|
{
|
|
printf(" Instance %i:\n", 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!
|
|
// ==========================================================================================
|
|
|
|
hRes = pAccess->ReadDWORD( g_aCounters[lCounter].m_lHandle, &dwVal);
|
|
if (FAILED(hRes))
|
|
{
|
|
printf("ShowInstanceData() failed, 0x%x", hRes);
|
|
return hRes;
|
|
}
|
|
|
|
printf(" %i ", dwVal);
|
|
|
|
pAccess->Release();
|
|
}
|
|
|
|
printf("\n");
|
|
}
|
|
|
|
return hRes;
|
|
}
|
|
|
|
HRESULT CRefClient::AddEnum()
|
|
///////////////////////////////////////////////////////////////////
|
|
//
|
|
// 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.
|
|
//
|
|
///////////////////////////////////////////////////////////////////
|
|
//ok
|
|
{
|
|
HRESULT hRes = WBEM_NO_ERROR;
|
|
|
|
IWbemHiPerfEnum* pEnum = NULL;
|
|
long lID;
|
|
|
|
// Add an enumerator to the refresher
|
|
// ==================================
|
|
|
|
hRes = m_pConfig->AddEnum( m_pNameSpace, cwcsObjectPath, 0, NULL, &pEnum, &lID );
|
|
|
|
m_Enum.Set(pEnum, lID);
|
|
|
|
// Set does it's own AddRef
|
|
// ========================
|
|
|
|
pEnum->Release();
|
|
|
|
if ( FAILED(hRes) )
|
|
{
|
|
printf( "AddEnum() failed, 0x%x\n", hRes );
|
|
}
|
|
|
|
return hRes;
|
|
}
|
|
|
|
HRESULT CRefClient::RemoveEnum()
|
|
///////////////////////////////////////////////////////////////////
|
|
//
|
|
// 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 hRes = WBEM_NO_ERROR;
|
|
|
|
// Remove the enumerator
|
|
// =====================
|
|
|
|
hRes = m_pConfig->Remove( m_Enum.GetID(), 0L );
|
|
|
|
m_Enum.Reset();
|
|
|
|
return hRes;
|
|
}
|
|
|
|
HRESULT CRefClient::ShowEnumeratorData()
|
|
///////////////////////////////////////////////////////////////////
|
|
//
|
|
// 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 hRes = 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
|
|
// ============================================
|
|
|
|
hRes = pEnum->GetObjects( 0L, dwNumObjects, apEnumAccess, &dwNumReturned );
|
|
|
|
// Is the buffer too small?
|
|
// ========================
|
|
|
|
if ( WBEM_E_BUFFER_TOO_SMALL == hRes )
|
|
{
|
|
// Increase the buffer size
|
|
// ========================
|
|
|
|
delete [] apEnumAccess;
|
|
|
|
apEnumAccess = new IWbemObjectAccess*[dwNumReturned];
|
|
dwNumObjects = dwNumReturned;
|
|
memset( apEnumAccess, 0, sizeof( apEnumAccess ));
|
|
|
|
if ( NULL != apEnumAccess )
|
|
{
|
|
hRes = pEnum->GetObjects( 0L, dwNumObjects, apEnumAccess, &dwNumReturned );
|
|
}
|
|
else
|
|
{
|
|
hRes = WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
|
|
}
|
|
|
|
// Print the result
|
|
// ================
|
|
|
|
if ( SUCCEEDED( hRes ) )
|
|
{
|
|
printf( "\tThe enumerator returned %i instances\n", dwNumReturned );
|
|
}
|
|
else
|
|
{
|
|
printf( "ShowEnumeratorData failed, 0x%x\n", hRes );
|
|
}
|
|
|
|
// 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 hRes;
|
|
}
|
|
|
|
HRESULT CRefClient::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 );
|
|
} |