/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // BVTREFRESH.CPP // // // Copyright (c)2000 Microsoft Corporation, All Rights Reserved // /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #include #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 ); }