// 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 #include #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 ); }