2025-04-27 07:49:33 -04:00

467 lines
12 KiB
C++

// **************************************************************************
// Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
//
// File: Consumer.cpp
//
// Description:
// Event consumer implementation
//
// History:
//
// **************************************************************************
#include "stdafx.h"
#include "Consumer.h"
#include <objbase.h>
CConsumer::CConsumer(CListBox *pOutputList)
{
m_cRef = 0L;
m_pOutputList = pOutputList;
}
CConsumer::~CConsumer()
{
}
STDMETHODIMP CConsumer::QueryInterface(REFIID riid, LPVOID FAR *ppv)
{
*ppv=NULL;
if (riid == IID_IUnknown || riid == IID_IWbemUnboundObjectSink)
*ppv=this;
if (*ppv != NULL)
{
((LPUNKNOWN)*ppv)->AddRef();
return NOERROR;
}
return E_NOINTERFACE;
}
STDMETHODIMP_(ULONG) CConsumer::AddRef(void)
{
return ++m_cRef;
}
STDMETHODIMP_(ULONG) CConsumer::Release(void)
{
if (--m_cRef != 0L)
return m_cRef;
delete this;
return 0L;
}
STDMETHODIMP CConsumer::IndicateToConsumer(IWbemClassObject *pLogicalConsumer,
long lNumObjects,
IWbemClassObject **ppObjects)
{
// NOTE: If this routine returns a failure code, including GPFs from called routines,
// CIMOM will recreate the object and call here again. If you see this routine being
// called twice for every indication, it means this routine is returning a failure code
// somehow. Especially watch the AddRef()/Release() semantics for the embedded object.
// If they're too low, you'll return a GPF.
HRESULT hRes;
CString clMyBuff;
BSTR objName = NULL;
BSTR propName = NULL;
VARIANT pVal, vUnk;
IUnknown *pUnk = NULL;
IWbemClassObject *tgtInst = NULL;
VariantInit(&pVal);
VariantInit(&vUnk);
TRACE(_T("Indicate() called\n"));
objName = SysAllocString(L"TargetInstance");
propName = SysAllocString(L"Item");
// walk though the classObjects...
for (int i = 0; i < lNumObjects; i++)
{
// clear my output buffer.
clMyBuff.Empty();
// get what was added. This will be an embedded object (VT_UNKNOWN). All
// WMI interfaces are derived from IUnknown.
if ((hRes = ppObjects[i]->Get(objName, 0L,
&vUnk, NULL, NULL)) == S_OK)
{
//--------------------------------
// pull the IUnknown out of the various. Dont cast directly to to IWbemClassObject.
// it MIGHT work now but a suptle change later will break your code. The PROPER
// way is to go through QueryInterface and do all the right Release()'s.
pUnk = (IUnknown *)V_UNKNOWN(&vUnk);
//--------------------------------
// Even though you didn't use QI(), you just made a copy of a COM ptr so you
// better do the AddRef() that QI() would otherwise do for you.
pUnk->AddRef();
//--------------------------------
// ask for the IWbemClassObject which is the embedded object. This will be the
// instance that was created.
if(SUCCEEDED(pUnk->QueryInterface(IID_IWbemClassObject, (void **)&tgtInst)))
{
//--------------------------------
// done with it.
pUnk->Release();
//--------------------------------
// get the 'Item' property out of the embedded object.
if ((hRes = tgtInst->Get(propName, 0L,
&pVal, NULL, NULL)) == S_OK)
{
//--------------------------------
// done with it.
tgtInst->Release();
// compose a string for the listbox.
clMyBuff = _T("OfficeEquipment Instance added for: ");
clMyBuff += V_BSTR(&pVal);
// output the buffer.
m_pOutputList->AddString(clMyBuff);
}
else
{
TRACE(_T("Get() Item failed %s\n"), ErrorString(hRes));
}
}
else
{
TRACE(_T("QI() failed \n"));
}
}
else
{
TRACE(_T("Get() targetInst failed %s\n"), ErrorString(hRes));
m_pOutputList->AddString(_T("programming error"));
} //endif Get()
} // endfor
SysFreeString(propName);
SysFreeString(objName);
VariantClear(&pVal);
VariantClear(&vUnk);
TRACE(_T("walked indication list\n"));
return S_OK;
}
// **************************************************************************
//
// ErrorString()
//
// Description:
// Converts an HRESULT to a displayable string.
//
// Parameters:
// hRes (in) - HRESULT to be converted.
//
// Returns:
// ptr to displayable string.
//
// Globals accessed:
// None.
//
// Globals modified:
// None.
//
//===========================================================================
LPCTSTR CConsumer::ErrorString(HRESULT hRes)
{
TCHAR szBuffer2[19];
static TCHAR szBuffer[24];
LPCTSTR psz;
switch(hRes)
{
case WBEM_NO_ERROR:
psz = _T("WBEM_NO_ERROR");
break;
case WBEM_S_FALSE:
psz = _T("WBEM_S_FALSE");
break;
case WBEM_S_NO_MORE_DATA:
psz = _T("WBEM_S_NO_MORE_DATA");
break;
case WBEM_E_FAILED:
psz = _T("WBEM_E_FAILED");
break;
case WBEM_E_NOT_FOUND:
psz = _T("WBEM_E_NOT_FOUND");
break;
case WBEM_E_ACCESS_DENIED:
psz = _T("WBEM_E_ACCESS_DENIED");
break;
case WBEM_E_PROVIDER_FAILURE:
psz = _T("WBEM_E_PROVIDER_FAILURE");
break;
case WBEM_E_TYPE_MISMATCH:
psz = _T("WBEM_E_TYPE_MISMATCH");
break;
case WBEM_E_OUT_OF_MEMORY:
psz = _T("WBEM_E_OUT_OF_MEMORY");
break;
case WBEM_E_INVALID_CONTEXT:
psz = _T("WBEM_E_INVALID_CONTEXT");
break;
case WBEM_E_INVALID_PARAMETER:
psz = _T("WBEM_E_INVALID_PARAMETER");
break;
case WBEM_E_NOT_AVAILABLE:
psz = _T("WBEM_E_NOT_AVAILABLE");
break;
case WBEM_E_CRITICAL_ERROR:
psz = _T("WBEM_E_CRITICAL_ERROR");
break;
case WBEM_E_INVALID_STREAM:
psz = _T("WBEM_E_INVALID_STREAM");
break;
case WBEM_E_NOT_SUPPORTED:
psz = _T("WBEM_E_NOT_SUPPORTED");
break;
case WBEM_E_INVALID_SUPERCLASS:
psz = _T("WBEM_E_INVALID_SUPERCLASS");
break;
case WBEM_E_INVALID_NAMESPACE:
psz = _T("WBEM_E_INVALID_NAMESPACE");
break;
case WBEM_E_INVALID_OBJECT:
psz = _T("WBEM_E_INVALID_OBJECT");
break;
case WBEM_E_INVALID_CLASS:
psz = _T("WBEM_E_INVALID_CLASS");
break;
case WBEM_E_PROVIDER_NOT_FOUND:
psz = _T("WBEM_E_PROVIDER_NOT_FOUND");
break;
case WBEM_E_INVALID_PROVIDER_REGISTRATION:
psz = _T("WBEM_E_INVALID_PROVIDER_REGISTRATION");
break;
case WBEM_E_PROVIDER_LOAD_FAILURE:
psz = _T("WBEM_E_PROVIDER_LOAD_FAILURE");
break;
case WBEM_E_INITIALIZATION_FAILURE:
psz = _T("WBEM_E_INITIALIZATION_FAILURE");
break;
case WBEM_E_TRANSPORT_FAILURE:
psz = _T("WBEM_E_TRANSPORT_FAILURE");
break;
case WBEM_E_INVALID_OPERATION:
psz = _T("WBEM_E_INVALID_OPERATION");
break;
case WBEM_E_INVALID_QUERY:
psz = _T("WBEM_E_INVALID_QUERY");
break;
case WBEM_E_INVALID_QUERY_TYPE:
psz = _T("WBEM_E_INVALID_QUERY_TYPE");
break;
case WBEM_E_ALREADY_EXISTS:
psz = _T("WBEM_E_ALREADY_EXISTS");
break;
case WBEM_S_ALREADY_EXISTS:
psz = _T("WBEM_S_ALREADY_EXISTS");
break;
case WBEM_S_RESET_TO_DEFAULT:
psz = _T("WBEM_S_RESET_TO_DEFAULT");
break;
case WBEM_S_DIFFERENT:
psz = _T("WBEM_S_DIFFERENT");
break;
case WBEM_E_OVERRIDE_NOT_ALLOWED:
psz = _T("WBEM_E_OVERRIDE_NOT_ALLOWED");
break;
case WBEM_E_PROPAGATED_QUALIFIER:
psz = _T("WBEM_E_PROPAGATED_QUALIFIER");
break;
case WBEM_E_PROPAGATED_PROPERTY:
psz = _T("WBEM_E_PROPAGATED_PROPERTY");
break;
case WBEM_E_UNEXPECTED:
psz = _T("WBEM_E_UNEXPECTED");
break;
case WBEM_E_ILLEGAL_OPERATION:
psz = _T("WBEM_E_ILLEGAL_OPERATION");
break;
case WBEM_E_CANNOT_BE_KEY:
psz = _T("WBEM_E_CANNOT_BE_KEY");
break;
case WBEM_E_INCOMPLETE_CLASS:
psz = _T("WBEM_E_INCOMPLETE_CLASS");
break;
case WBEM_E_INVALID_SYNTAX:
psz = _T("WBEM_E_INVALID_SYNTAX");
break;
case WBEM_E_NONDECORATED_OBJECT:
psz = _T("WBEM_E_NONDECORATED_OBJECT");
break;
case WBEM_E_READ_ONLY:
psz = _T("WBEM_E_READ_ONLY");
break;
case WBEM_E_PROVIDER_NOT_CAPABLE:
psz = _T("WBEM_E_PROVIDER_NOT_CAPABLE");
break;
case WBEM_E_CLASS_HAS_CHILDREN:
psz = _T("WBEM_E_CLASS_HAS_CHILDREN");
break;
case WBEM_E_CLASS_HAS_INSTANCES:
psz = _T("WBEM_E_CLASS_HAS_INSTANCES");
break;
case WBEM_E_QUERY_NOT_IMPLEMENTED:
psz = _T("WBEM_E_QUERY_NOT_IMPLEMENTED");
break;
case WBEM_E_ILLEGAL_NULL:
psz = _T("WBEM_E_ILLEGAL_NULL");
break;
case WBEM_E_INVALID_QUALIFIER_TYPE:
psz = _T("WBEM_E_INVALID_QUALIFIER_TYPE");
break;
case WBEM_E_INVALID_PROPERTY_TYPE:
psz = _T("WBEM_E_INVALID_PROPERTY_TYPE");
break;
case WBEM_E_VALUE_OUT_OF_RANGE:
psz = _T("WBEM_E_VALUE_OUT_OF_RANGE");
break;
case WBEM_E_CANNOT_BE_SINGLETON:
psz = _T("WBEM_E_CANNOT_BE_SINGLETON");
break;
default:
_itot(hRes, szBuffer2, 16);
_tcscat(szBuffer, szBuffer2);
psz = szBuffer;
break;
}
return psz;
}
// **************************************************************************
//
// ValueToString()
//
// Description:
// Converts a variant to a displayable string.
//
// Parameters:
// pValue (in) - variant to be converted.
// pbuf (out) - ptr to receive displayable string.
//
// Returns:
// Same as pbuf.
//
// Globals accessed:
// None.
//
// Globals modified:
// None.
//
//===========================================================================
#define BLOCKSIZE (32 * sizeof(WCHAR))
#define CVTBUFSIZE (309+40) /* # of digits in max. dp value + slop */
LPWSTR CConsumer::ValueToString(VARIANT *pValue, WCHAR **pbuf)
{
DWORD iNeed = 0;
DWORD iVSize = 0;
DWORD iCurBufSize = 0;
WCHAR *vbuf = NULL;
WCHAR *buf = NULL;
switch (pValue->vt)
{
case VT_NULL:
buf = (WCHAR *)malloc(BLOCKSIZE);
wcscpy(buf, L"<null>");
break;
case VT_BOOL: {
VARIANT_BOOL b = pValue->boolVal;
buf = (WCHAR *)malloc(BLOCKSIZE);
if (!b) {
wcscpy(buf, L"FALSE");
} else {
wcscpy(buf, L"TRUE");
}
break;
}
case VT_UI1: {
BYTE b = pValue->bVal;
buf = (WCHAR *)malloc(BLOCKSIZE);
if (b >= 32) {
swprintf(buf, L"'%c' (%d, 0x%X)", b, b, b);
} else {
swprintf(buf, L"%d (0x%X)", b, b);
}
break;
}
case VT_I2: {
SHORT i = pValue->iVal;
buf = (WCHAR *)malloc(BLOCKSIZE);
swprintf(buf, L"%d (0x%X)", i, i);
break;
}
case VT_I4: {
LONG l = pValue->lVal;
buf = (WCHAR *)malloc(BLOCKSIZE);
swprintf(buf, L"%d (0x%X)", l, l);
break;
}
case VT_R4: {
float f = pValue->fltVal;
buf = (WCHAR *)malloc(CVTBUFSIZE * sizeof(WCHAR));
swprintf(buf, L"%10.4f", f);
break;
}
case VT_R8: {
double d = pValue->dblVal;
buf = (WCHAR *)malloc(CVTBUFSIZE * sizeof(WCHAR));
swprintf(buf, L"%10.4f", d);
break;
}
case VT_BSTR: {
LPWSTR pWStr = pValue->bstrVal;
buf = (WCHAR *)malloc((wcslen(pWStr) * sizeof(WCHAR)) + sizeof(WCHAR) + (2 * sizeof(WCHAR)));
swprintf(buf, L"\"%wS\"", pWStr);
break;
}
// the sample GUI is too simple to make it necessary to display
// these 'complicated' types--so ignore them.
case VT_DISPATCH: // Currently only used for embedded objects
case VT_BOOL|VT_ARRAY:
case VT_UI1|VT_ARRAY:
case VT_I2|VT_ARRAY:
case VT_I4|VT_ARRAY:
case VT_R4|VT_ARRAY:
case VT_R8|VT_ARRAY:
case VT_BSTR|VT_ARRAY:
case VT_DISPATCH | VT_ARRAY:
break;
default:
buf = (WCHAR *)malloc(BLOCKSIZE);
wcscpy(buf, L"<conversion error>");
}
*pbuf = buf;
return buf;
}