windows-nt/Source/XPSP1/NT/admin/wmi/wbem/winmgmt/ntperfclient/refresh.cpp
2020-09-26 16:20:57 +08:00

493 lines
12 KiB
C++

/*++
Copyright (C) 1997-2001 Microsoft Corporation
Module Name:
Abstract:
History:
--*/
//***************************************************************************
//
// REFRESH.CPP
//
// Contains a single sample global refresher
//
//***************************************************************************
#include "precomp.h"
#include <stdio.h>
#include <wbemidl.h>
#include <wbemint.h>
#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;
}