/*++ Copyright (C) 1997-2001 Microsoft Corporation Module Name: Abstract: History: --*/ //*************************************************************************** // // REFRESH.CPP // // Contains a single sample global refresher // //*************************************************************************** #include "precomp.h" #include #include #include #include "refresh.h" //*************************************************************************** // // Local globals (!) // //*************************************************************************** static DWORD g_dwNumObjects = 0; static IWbemRefresher *g_pRefresher = 0; static IWbemClassObject *g_aObjects[MAX_OBJECTS]; static LONG g_aObjIDs[MAX_OBJECTS]; static IWbemConfigureRefresher *g_pCfgRef = 0; //*************************************************************************** // // CreateRefresher // //*************************************************************************** BOOL CreateRefresher() { if (g_pCfgRef != 0) { printf("Refresher already created\n"); return FALSE; } // Create an empty refresher. // =========================== DWORD dwRes = CoCreateInstance(CLSID_WbemRefresher, 0, CLSCTX_SERVER, IID_IWbemRefresher, (LPVOID *) &g_pRefresher); if (dwRes != S_OK) { printf("Failed to create a new refresher.\n"); return FALSE; } // Create the refresher manager. // ============================= dwRes = g_pRefresher->QueryInterface(IID_IWbemConfigureRefresher, (LPVOID *) &g_pCfgRef); if (dwRes) { g_pRefresher->Release(); g_pRefresher = 0; printf("Failed to create the refresher manager\n"); return FALSE; } return TRUE; } //*************************************************************************** // // Refresh // // Called to refresh all the objects in the refresher. // //*************************************************************************** // ok BOOL Refresh() { if (g_pRefresher == 0) { printf("No active refresher!\n"); return FALSE; } HRESULT hRes = g_pRefresher->Refresh(0); if (hRes) return FALSE; return TRUE; } //*************************************************************************** // // DestroyRefresher // //*************************************************************************** // ok BOOL DestroyRefresher() { if (g_pRefresher == 0) { printf("No active refresher!\n"); return FALSE; } g_pRefresher->Release(); g_pRefresher = 0; g_pCfgRef->Release(); g_pCfgRef = 0; for (DWORD i = 0; i < g_dwNumObjects; i++) { g_aObjIDs[i] = 0; g_aObjects[i]->Release(); g_aObjects[i] = 0; } g_dwNumObjects = 0; return TRUE; } //*************************************************************************** // // AddObject // // Adds an object to the refresher and returns its ID. The ID is // refresher specific (if more than one refresher is used, the // IDs can overlap). // // Parameters: // pSvc IWbemServices pointing to the correct namespace // pszPath The path to the object // // Return value: // TRUE on success, FALSE on fail. // //*************************************************************************** // ok BOOL AddObject( IN IWbemServices *pSvc, IN LPWSTR pszPath ) { LONG lObjId; if (g_pRefresher == 0) { printf("No active refresher!\n"); return FALSE; } // Make sure there is room. // ======================== if (g_dwNumObjects == MAX_OBJECTS) { printf("No more room in object array\n"); return FALSE; } // Add the object to the refresher. // ================================= IWbemClassObject *pRefreshableCopy = 0; HRESULT hRes = g_pCfgRef->AddObjectByPath( pSvc, pszPath, 0, 0, &pRefreshableCopy, &lObjId ); // See if we succeeded. // ==================== if (hRes) { printf("Failed to add object %S to refresher. WBEM error code = 0x%X\n", pszPath, hRes ); return FALSE; } // Record the object and its id. // ============================= g_aObjects[g_dwNumObjects] = pRefreshableCopy; g_aObjIDs[g_dwNumObjects] = lObjId; g_dwNumObjects++; // Keeps track of how many objects we have return TRUE; } //*************************************************************************** // // RemoveObject // // Removes an object from the refresher. // //*************************************************************************** // ok BOOL RemoveObject(IN LONG lObjId) { if (g_pRefresher == 0) { printf("No active refresher!\n"); return FALSE; } // Remove the obejct from our local bookkeeping. // ============================================= for (DWORD i = 0; i < g_dwNumObjects; i++) { if (g_aObjIDs[i] == lObjId) { g_aObjIDs[i] = 0; // Remove the ID g_aObjects[i]->Release(); // Release the object g_aObjects[i] = 0; // Zero it for purity // Remove this element from the two arrays. // ======================================== for (DWORD i2 = i; i2 < g_dwNumObjects - 1; i2++) { g_aObjIDs[i2] = g_aObjIDs[i2 + 1]; g_aObjects[i2] = g_aObjects[i2 + 1]; } g_dwNumObjects--; } } // Officially remove the object from the WBEM refresher. // ===================================================== HRESULT hRes = g_pCfgRef->Remove( lObjId, 0 ); if (hRes) { return FALSE; } return TRUE; } //*************************************************************************** // // ShowObjectList // // Shows all the objects in the refresher. // //*************************************************************************** BOOL ShowObjectList() { if (g_pRefresher == 0) { printf("No active refresher!\n"); return FALSE; } BSTR PropName = SysAllocString(L"__RELPATH"); for (DWORD i = 0; i < g_dwNumObjects; i++) { VARIANT v; VariantInit(&v); g_aObjects[i]->Get(PropName, 0, &v, 0, 0); printf("Object ID = %u Path = %S\n", g_aObjIDs[i], V_BSTR(&v)); VariantClear(&v); } SysFreeString(PropName); printf("---Total of %u object(s)\n", g_dwNumObjects); return TRUE; } //*************************************************************************** // // DumpObjectById // // Dumps the object's contents. // //*************************************************************************** BOOL DumpObjectById(LONG lObjId) { for (DWORD i = 0; i < g_dwNumObjects; i++) { if (g_aObjIDs[i] == lObjId) { DumpObject(g_aObjects[i]); return TRUE; } } return FALSE; } //*************************************************************************** // // DumpObject // // Dumps out the contents of the object. // //*************************************************************************** BOOL DumpObject(IWbemClassObject *pObj) { DWORD i; BSTR PropNames[64] = {0}; DWORD dwNumPropNames = 0; VARIANT v; VariantInit(&v); printf("----Object Dump----\n"); // Print out the object path to identify it. // ========================================= BSTR PropName = SysAllocString(L"__RELPATH"); pObj->Get(PropName, 0, &v, 0, 0); printf("Path = %S\n", V_BSTR(&v)); VariantClear(&v); SysFreeString(PropName); // Enumerate through the 'real' properties, ignoring // standard WBEM system properties. // ================================================= pObj->BeginEnumeration(WBEM_FLAG_NONSYSTEM_ONLY); BSTR bstrName = 0; LONG vt = 0; while (WBEM_NO_ERROR == pObj->Next(0, &bstrName, &v, &vt, 0)) { printf("Property = %S\t", bstrName); PropNames[dwNumPropNames++] = bstrName; // Save the name for later use switch (vt) { case VT_I4: printf("\tType = VT_I4\tValue = %d\n", V_I4(&v)); break; case VT_UI4: printf("\tType = VT_UI4\tValue = %u\n", V_I4(&v)); break; case VT_BSTR: printf("\tType = VT_BSTR\tValue = %S\n", V_BSTR(&v)); break; // Note that VARIANTs can't hold 64-bit integers, // so we have to use BSTRs for this. // ============================================== case VT_I8: printf("\tType = VT_I8\tValue = %S\n", V_BSTR(&v)); break; case VT_UI8: printf("\tType = VT_UI8\tValue = %S\n", V_BSTR(&v)); break; default: printf("\tType = complex\n"); } } pObj->EndEnumeration(); // Next, we can get the property values if we know the names // ahead of time through a more efficient access mechanism. // Since we saved all the property names, we can use these // to get handles to the properties of interest. In this // case, we get handles for all the properties. In real life, // you would just use this for properties of interest to // the end user. // ========================================================== IWbemObjectAccess *pAccess = 0; pObj->QueryInterface(IID_IWbemObjectAccess, (LPVOID *) &pAccess); LONG Handles[64] = {0}; LONG Types[64] = {0}; for (i = 0; i < dwNumPropNames; i++) { // Get handles for each of the properties. We actually // only have to do this once and could reuse the handles // in the future between refreshes for all instances of // this class. // ===================================================== pAccess->GetPropertyHandle(PropNames[i], &Types[i], &Handles[i]); } // We can now pull in the values by the handles. // Note that these handles can be 'saved' for use // with other instances or a newly refreshed generation // of the same instance. // ===================================================== DWORD dwValue; unsigned __int64 qwValue; for (i = 0; i < dwNumPropNames; i++) { switch (Types[i]) { case VT_I4: case VT_UI4: pAccess->ReadDWORD(Handles[i], &dwValue); printf("Property %S has value %u\n", PropNames[i], dwValue); break; case VT_I8: case VT_UI8: pAccess->ReadQWORD(Handles[i], &qwValue); printf("Property %S has value %lu\n", PropNames[i], qwValue); break; // Other types // =========== default: printf("Property %S is Non integral type.\n", PropNames[i]); // We could have used pAccess->ReadPropertyValue for this. } } // Done with the dump. Cleanup time. // ================================== pAccess->Release(); // Done with this interface for (i = 0; i < dwNumPropNames; i++) SysFreeString(PropNames[i]); // Free prop names // Go home. // ======== return TRUE; }