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

2185 lines
49 KiB
C++

// Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
//***************************************************************************
//
// util.cpp
//
// Module: RegEvent ActiveX Control
//
//
//***************************************************************************
#include "precomp.h"
//#include <OBJIDL.H>
#include <nddeapi.h>
#include <initguid.h>
#include "wbemidl.h"
#include <genlex.h>
#include "MsgDlgExterns.h"
#include <opathlex.h>
#include <objpath.h>
#include "util.h"
#include "logindlg.h"
// *************************************************************************
// Safe array utilities
//
// VT_BSTR for strings
SCODE MakeSafeArray(SAFEARRAY FAR ** pRet, VARTYPE vt, int iLen)
{
SAFEARRAYBOUND rgsabound[1];
rgsabound[0].lLbound = 0;
rgsabound[0].cElements = iLen;
*pRet = SafeArrayCreate(vt,1, rgsabound);
return (*pRet == NULL) ? 0x80000001 : S_OK;
}
SCODE PutStringInSafeArray
(SAFEARRAY FAR * psa,CString *pcs, int iIndex)
{
long ix[2];
ix[1] = 0;
ix[0] = iIndex;
long i = iIndex;
HRESULT hResult = SafeArrayPutElement(psa,&i,pcs -> AllocSysString());
return GetScode(hResult);
}
BOOL GetErrorObjectText
(IWbemClassObject *pErrorObject, CString &rcsDescription)
{
if (!pErrorObject)
{
rcsDescription.Empty();
return FALSE;
}
CString csProp = _T("Description");
CString csDescription = GetBSTRProperty(pErrorObject,&csProp);
if (csDescription.IsEmpty() || csDescription.GetLength() == 0)
{
rcsDescription.Empty();
return FALSE;
}
else
{
rcsDescription = csDescription;
return TRUE;
}
}
CString GetBSTRProperty
(IWbemServices * pProv, IWbemClassObject * pInst,
CString *pcsProperty)
{
SCODE sc;
VARIANTARG var;
VariantInit(&var);
long lType;
long lFlavor;
BSTR bstrTemp = pcsProperty -> AllocSysString ( );
sc = pInst->Get(bstrTemp,0,&var,&lType,&lFlavor);
::SysFreeString(bstrTemp);
if(sc != S_OK)
{
CString csUserMsg;
csUserMsg = _T("Cannot get property value ");
csUserMsg += _T(" for object ");
csUserMsg += GetIWbemFullPath (pInst);
ErrorMsg
(&csUserMsg, sc, NULL, TRUE, &csUserMsg, __FILE__,
__LINE__ - 9);
return "";
}
CString csOut;
if (var.vt == VT_BSTR)
csOut = var.bstrVal;
VariantClear(&var);
return csOut;
}
//***************************************************************************
//
// CreateSimpleClass
//
// Purpose: This creates a new class with a class name and parent.
//
//***************************************************************************
IWbemClassObject *CreateSimpleClass
(IWbemServices * pProv, CString *pcsNewClass, CString *pcsParentClass, int &nError,
CString &csError )
{
IWbemClassObject *pNewClass = NULL;
IWbemClassObject *pParentClass = NULL;
IWbemClassObject *pErrorObject = NULL;
SCODE sc;
BSTR bstrTemp = pcsNewClass->AllocSysString();
sc = pProv -> GetObject
(bstrTemp ,0,NULL, &pNewClass,NULL);
::SysFreeString(bstrTemp);
if (sc == S_OK)
{
pNewClass->Release();
CString csUserMsg =
_T("An error occured creating the class ") + *pcsNewClass;
csUserMsg +=
_T(": Class ") + *pcsNewClass;
csUserMsg += _T(" already exists");
ErrorMsg
(&csUserMsg, sc, NULL, TRUE, &csUserMsg, __FILE__, __LINE__ - 9);
return NULL;
}
pcsParentClass =
pcsParentClass->GetLength()==0? NULL: pcsParentClass;
if (pcsParentClass)
{
BSTR bstrTemp = pcsParentClass->AllocSysString();
sc = pProv -> GetObject
(bstrTemp,0,NULL, &pParentClass,NULL);
::SysFreeString(bstrTemp);
}
else
{
sc = pProv -> GetObject
(NULL,0,NULL, &pParentClass,NULL);
}
if (sc != S_OK)
{
CString csUserMsg =
_T("An error occured creating the class ") + *pcsNewClass;
csUserMsg +=
_T(": Cannot create the new class because the parent class object \"") + *pcsParentClass + _T("\" does not exist.");
ErrorMsg
(&csUserMsg, sc, pErrorObject, TRUE, &csUserMsg, __FILE__, __LINE__ - 8);
ReleaseErrorObject(pErrorObject);
return NULL;
}
ReleaseErrorObject(pErrorObject);
if (pcsParentClass)
{
sc = pParentClass->SpawnDerivedClass(0,&pNewClass);
}
else
{
pNewClass = pParentClass;
pNewClass->AddRef();
sc = S_OK;
}
if (sc != S_OK)
{
pParentClass->Release();
CString csUserMsg =
_T("An error occured creating the class ") + *pcsNewClass;
if (pcsParentClass)
{
csUserMsg +=
_T(": Cannot spawn derived class of ") + *pcsParentClass;
}
else
{
csUserMsg +=
_T(": Cannot spawn derived class");
}
ErrorMsg
(&csUserMsg, S_OK, NULL, TRUE, &csUserMsg, __FILE__, __LINE__ - 9);
return NULL;
}
pParentClass->Release();
CString csTmp;
// Init class __Class Property
csTmp = L"__Class";
SetProperty (pProv, pNewClass, &csTmp,pcsNewClass );
pErrorObject = NULL;
sc = pProv->PutClass(pNewClass,0,NULL,NULL);
if (sc != S_OK)
{
CString csUserMsg=
_T("An error occured creating the class ") + *pcsNewClass;
csUserMsg += _T(": Cannot PutClass on ") + *pcsNewClass;
ErrorMsg
(&csUserMsg, sc, pErrorObject, TRUE, &csUserMsg, __FILE__, __LINE__ - 8);
ReleaseErrorObject(pErrorObject);
return NULL;
}
else
{
ReleaseErrorObject(pErrorObject);
pNewClass->Release();
pNewClass = NULL;
BSTR bstrTemp = pcsNewClass->AllocSysString();
sc = pProv -> GetObject
( bstrTemp ,0,NULL,&pNewClass,NULL);
::SysFreeString(bstrTemp);
if (sc != S_OK)
{
CString csUserMsg=
_T("An error occured creating the class ") + *pcsNewClass;
csUserMsg +=
_T(": Cannot get the new class.\"") ;
ErrorMsg
(&csUserMsg, sc, pErrorObject, TRUE, &csUserMsg, __FILE__, __LINE__ - 21);
ReleaseErrorObject(pErrorObject);
return NULL;
}
ReleaseErrorObject(pErrorObject);
return pNewClass;
}
}
//***************************************************************************
//
// DeleteAClass
//
// Purpose: This deletes a class.
//
//***************************************************************************
BOOL DeleteAClass
(IWbemServices * pProv, CString *pcsClass)
{
SCODE sc;
IWbemClassObject *pErrorObject = NULL;
BSTR bstrTemp = pcsClass->AllocSysString();
sc = pProv -> DeleteClass(bstrTemp,0,NULL,NULL);
::SysFreeString(bstrTemp);
if (sc != S_OK)
{
CString csUserMsg =
_T("Cannot delete class ") + *pcsClass;
ErrorMsg
(&csUserMsg, sc, pErrorObject, TRUE, &csUserMsg, __FILE__, __LINE__ - 6);
ReleaseErrorObject(pErrorObject);
return FALSE;
}
else
{
ReleaseErrorObject(pErrorObject);
return TRUE;
}
}
//***************************************************************************
//
// ReparentAClass
//
// Purpose: Clone a class and change its superclass..
//
//***************************************************************************
IWbemClassObject *ReparentAClass
(IWbemServices * pProv, IWbemClassObject *pimcoParent, IWbemClassObject *pimcoChild)
{
IWbemClassObject *pimcoClone = NULL;
IWbemClassObject *pErrorObject = NULL;
SCODE sc;
sc = pimcoChild -> Clone(&pimcoClone);
if (sc != S_OK)
{
CString csUserMsg =
_T("Cannot clone class ");
CString csProp = _T("__Class");
CString csClass;
csClass = ::GetProperty(pimcoChild,&csProp);
csUserMsg += csClass;
ErrorMsg
(&csUserMsg, sc, NULL, TRUE, &csUserMsg, __FILE__, __LINE__ - 10);
return FALSE;
}
CString csProp = _T("__Class");
CString csParentClass;
if (pimcoParent)
{
csParentClass = ::GetProperty(pimcoParent,&csProp);
}
else
csParentClass = "";
csProp = _T("__SuperClass");
BOOL bReturn = ::SetProperty (pProv, pimcoClone, &csProp, &csParentClass);
if (bReturn)
{
sc = pProv -> PutClass(pimcoClone, 0, NULL,NULL);
if (sc != S_OK)
{
CString csUserMsg =
_T("Cannot PutClass ");
ErrorMsg
(&csUserMsg, sc, pErrorObject, TRUE, &csUserMsg, __FILE__, __LINE__ - 6);
ReleaseErrorObject(pErrorObject);
return NULL;
}
else
{
ReleaseErrorObject(pErrorObject);
return pimcoClone;
}
}
else
{
return FALSE;
}
}
//***************************************************************************
//
// RenameAClass
//
// Purpose: Clone a class and change its naem.
//
//***************************************************************************
IWbemClassObject *RenameAClass
(IWbemServices * pProv, IWbemClassObject *pimcoClass, CString *pcsNewName,
BOOL bDeleteOriginal)
{
IWbemClassObject *pimcoClone = NULL;
IWbemClassObject *pErrorObject = NULL;
SCODE sc;
sc = pimcoClass -> Clone(&pimcoClone);
if (sc != S_OK)
{
CString csUserMsg =
_T("An error occured renaming a class: ");
csUserMsg +=
_T("Cannot clone class ");
CString csProp = _T("__Class");
CString csClass;
csClass = ::GetProperty(pimcoClass,&csProp);
csUserMsg += csClass;
ErrorMsg
(&csUserMsg, sc, NULL, TRUE, &csUserMsg, __FILE__, __LINE__ - 10);
return FALSE;
}
CString csProp = _T("__Class");
SetProperty (pProv, pimcoClone, &csProp, pcsNewName);
sc = pProv -> PutClass(pimcoClone, 0, NULL,NULL);
if (sc != S_OK)
{
CString csUserMsg=
_T("An error occured renaming a class: ");
csUserMsg +=
_T("Cannot PutClass ");
ErrorMsg
(&csUserMsg, sc, pErrorObject, TRUE, &csUserMsg, __FILE__, __LINE__ - 6);
ReleaseErrorObject(pErrorObject);
return NULL;
}
else
{
ReleaseErrorObject(pErrorObject);
}
if (bDeleteOriginal)
{
CString csDelete;
csProp = _T("__Class");
csDelete = ::GetProperty(pimcoClass,&csProp);
pimcoClass -> Release();
BOOL bReturn = DeleteAClass
(pProv, &csDelete);
if (!bReturn)
{
CString csUserMsg =
_T("An error occured renaming a class: ");
csUserMsg +=
_T("Cannot delete the original class ");
ErrorMsg
(&csUserMsg, S_OK, NULL, TRUE, &csUserMsg, __FILE__, __LINE__ - 7);
return NULL;
}
}
return pimcoClone;
}
BOOL SetProperty
(IWbemServices * pProv, IWbemClassObject * pInst,
CString *pcsProperty, CString *pcsPropertyValue)
{
SCODE sc;
VARIANTARG var;
VariantInit(&var);
var.vt = VT_BSTR;
var.bstrVal = pcsPropertyValue -> AllocSysString ( );
if(var.bstrVal == NULL)
{
return WBEM_E_FAILED;
}
BSTR bstrTemp = pcsProperty -> AllocSysString ( );
sc = pInst->Put(bstrTemp ,0,&var,NULL);
::SysFreeString(bstrTemp);
if (sc != S_OK)
{
CString csUserMsg =
_T("Cannot Put " + *pcsProperty);
ErrorMsg
(&csUserMsg, sc, NULL, TRUE, &csUserMsg, __FILE__, __LINE__ - 6);
}
VariantClear(&var);
return TRUE;
}
BOOL SetProperty
(IWbemServices * pProv, IWbemClassObject * pInst,
CString *pcsProperty, long lValue)
{
SCODE sc;
VARIANTARG var;
VariantInit(&var);
var.vt = VT_I4;
var.lVal = lValue;
BSTR bstrTemp = pcsProperty -> AllocSysString ( );
sc = pInst->Put(bstrTemp ,0,&var,NULL);
::SysFreeString(bstrTemp);
if (sc != S_OK)
{
CString csUserMsg =
_T("Cannot Put " + *pcsProperty);
ErrorMsg
(&csUserMsg, sc, NULL, TRUE, &csUserMsg, __FILE__, __LINE__ - 6);
}
VariantClear(&var);
return TRUE;
}
CString GetProperty
(IWbemClassObject * pInst, CString *pcsProperty, BOOL bQuietly)
{
SCODE sc;
CString csOut;
VARIANTARG var;
VariantInit(&var);
long lType;
long lFlavor;
BSTR bstrTemp = pcsProperty -> AllocSysString ( );
sc = pInst->Get( bstrTemp ,0,&var,&lType,&lFlavor);
::SysFreeString(bstrTemp);
if (sc != S_OK)
{
if (!bQuietly)
{
CString csUserMsg =
_T("Cannot get a property ");
ErrorMsg
(&csUserMsg, sc, NULL, TRUE, &csUserMsg, __FILE__, __LINE__ - 6);
}
return csOut;
}
if (var.vt == VT_BSTR)
csOut = var.bstrVal;
VariantClear(&var);
return csOut;
}
//***************************************************************************
// Function: GetClasses
// Purpose: Gets classes in the database.
//***************************************************************************
SCODE GetClasses(IWbemServices * pIWbemServices, CString *pcsParent,
CPtrArray &cpaClasses, CString &rcsNamespace)
{
SCODE sc;
IEnumWbemClassObject *pIEnumWbemClassObject = NULL;
IWbemClassObject *pIWbemClassObject = NULL;
IWbemClassObject *pErrorObject = NULL;
//CString csClass = pcsParent ? *pcsParent: _T("");
if (pcsParent)
{
BSTR bstrTemp = pcsParent->AllocSysString();
sc = pIWbemServices->CreateClassEnum
(bstrTemp,
WBEM_FLAG_SHALLOW, NULL, &pIEnumWbemClassObject);
::SysFreeString(bstrTemp);
}
else
{
sc = pIWbemServices->CreateClassEnum
(NULL,
WBEM_FLAG_SHALLOW, NULL, &pIEnumWbemClassObject);
}
if (sc != S_OK)
{
CString csUserMsg =
_T("Cannot create a class enumeration ");
ErrorMsg
(&csUserMsg, sc, pErrorObject, TRUE, &csUserMsg, __FILE__, __LINE__ - 8);
ReleaseErrorObject(pErrorObject);
return sc;
}
else
{
ReleaseErrorObject(pErrorObject);
SetEnumInterfaceSecurity(rcsNamespace,pIEnumWbemClassObject, pIWbemServices);
}
sc = pIEnumWbemClassObject->Reset();
ULONG uReturned;
int i = 0;
pIWbemClassObject = NULL;
while (S_OK == pIEnumWbemClassObject->Next(INFINITE, 1, &pIWbemClassObject, &uReturned) )
{
cpaClasses.Add(reinterpret_cast<void *>(pIWbemClassObject));
i++;
pIWbemClassObject = NULL;
}
pIEnumWbemClassObject -> Release();
return sc;
}
//***************************************************************************
// Function: GetAllClasses
// Purpose: Gets all classes in the database.
//***************************************************************************
int GetAllClasses(IWbemServices * pIWbemServices, CPtrArray &cpaClasses, CString &rcsNamespace)
{
SCODE sc;
IEnumWbemClassObject *pIEnumWbemClassObject = NULL;
IWbemClassObject *pIWbemClassObject = NULL;
IWbemClassObject *pErrorObject = NULL;
//CString csClass = _T("");
sc = pIWbemServices->CreateClassEnum
(NULL, WBEM_FLAG_DEEP, NULL, &pIEnumWbemClassObject);
if (sc != S_OK)
{
CString csUserMsg= _T("Cannot get all classes ");
ErrorMsg
(&csUserMsg, sc, pErrorObject, TRUE, &csUserMsg, __FILE__, __LINE__ - 8);
ReleaseErrorObject(pErrorObject);
return 0;
}
else
{
ReleaseErrorObject(pErrorObject);
SetEnumInterfaceSecurity(rcsNamespace,pIEnumWbemClassObject, pIWbemServices);
}
sc = pIEnumWbemClassObject->Reset();
ULONG uReturned;
int i = 0;
pIWbemClassObject = NULL;
while (S_OK == pIEnumWbemClassObject->Next(INFINITE, 1, &pIWbemClassObject, &uReturned) )
{
cpaClasses.Add(reinterpret_cast<void *>(pIWbemClassObject));
i++;
pIWbemClassObject = NULL;
}
pIEnumWbemClassObject -> Release();
return i;
}
CStringArray *GetAllClassPaths(IWbemServices * pIWbemServices, CString &rcsNamespace)
{
CPtrArray cpaClasses;
int nClasses=
GetAllClasses(pIWbemServices, cpaClasses, rcsNamespace);
CStringArray *pcsaClassNames = new CStringArray;
for (int i = 0; i < nClasses; i++)
{
IWbemClassObject *pClass =
reinterpret_cast<IWbemClassObject *>
(cpaClasses.GetAt(i));
CString csProp = _T("__Path");
CString csClass = ::GetProperty(pClass,&csProp);
pcsaClassNames->Add(csClass);
pClass->Release();
}
return pcsaClassNames;
}
//***************************************************************************
// Function: HasSubclasses
// Purpose: Predicate to tell if a class has any subclasses.
//***************************************************************************
BOOL HasSubclasses(IWbemServices * pIWbemServices, IWbemClassObject *pimcoClass, CString &rcsNamespace)
{
SCODE sc;
IEnumWbemClassObject * pIEnumWbemClassObject = NULL;
IWbemClassObject * pIWbemClassObject = NULL;
IWbemClassObject * pErrorObject = NULL;
CString csClass = _T("__Class");
csClass = ::GetProperty(pimcoClass,&csClass);
BSTR bstrTemp = csClass.AllocSysString();
sc = pIWbemServices->CreateClassEnum
(bstrTemp, WBEM_FLAG_SHALLOW, NULL, &pIEnumWbemClassObject);
::SysFreeString(bstrTemp);
if (sc != S_OK)
{
CString csUserMsg=
_T("Cannot create a class enumeration ");
ErrorMsg
(&csUserMsg, sc, pErrorObject, TRUE, &csUserMsg, __FILE__, __LINE__ - 7);
ReleaseErrorObject(pErrorObject);
return FALSE;
}
else
{
ReleaseErrorObject(pErrorObject);
SetEnumInterfaceSecurity(rcsNamespace,pIEnumWbemClassObject, pIWbemServices);
}
sc = pIEnumWbemClassObject->Reset();
ULONG uReturned;
int i = 0;
pIWbemClassObject = NULL;
BOOL bStop = FALSE;
if (!bStop && S_OK == pIEnumWbemClassObject->Next(INFINITE, 1, &pIWbemClassObject, &uReturned) )
{
if (pIWbemClassObject)
{
pIWbemClassObject -> Release();
pIWbemClassObject = NULL;
i++;
}
if (i > 0)
{
bStop = TRUE;;
}
}
pIEnumWbemClassObject -> Release();
return i > 0? TRUE : FALSE;
}
//***************************************************************************
// Function: HasSubclasses
// Purpose: Predicate to tell if a class has any subclasses.
//***************************************************************************
BOOL HasSubclasses(IWbemServices * pIWbemServices, CString *pcsClass, CString &rcsNamespace)
{
SCODE sc;
IEnumWbemClassObject *pIEnumWbemClassObject = NULL;
IWbemClassObject *pIWbemClassObject = NULL;
IWbemClassObject *pErrorObject = NULL;
BSTR bstrTemp = pcsClass -> AllocSysString();
sc = pIWbemServices->CreateClassEnum
(bstrTemp, WBEM_FLAG_SHALLOW,
NULL,&pIEnumWbemClassObject);
::SysFreeString(bstrTemp);
if (sc != S_OK)
{
CString csUserMsg =
_T("Cannot create a class enumeration ");
ErrorMsg
(&csUserMsg, sc, pErrorObject, TRUE, &csUserMsg, __FILE__, __LINE__ - 7);
ReleaseErrorObject(pErrorObject);
return FALSE;
}
else
{
ReleaseErrorObject(pErrorObject);
SetEnumInterfaceSecurity(rcsNamespace,pIEnumWbemClassObject, pIWbemServices);
}
sc = pIEnumWbemClassObject->Reset();
ULONG uReturned;
int i = 0;
pIWbemClassObject = NULL;
BOOL bStop = FALSE;
if (!bStop && S_OK == pIEnumWbemClassObject->Next(INFINITE,1, &pIWbemClassObject, &uReturned) )
{
if (pIWbemClassObject)
{
pIWbemClassObject -> Release();
pIWbemClassObject = NULL;
i++;
}
if (i > 0)
{
bStop = TRUE;
}
}
pIEnumWbemClassObject -> Release();
return i > 0? TRUE : FALSE;
}
//***************************************************************************
//
// GetAttribBool
//
// Purpose: gets an Boolean Qualifier.
//
//***************************************************************************
long GetAttribBool
(IWbemClassObject * pClassInt,CString *pcsPropName, CString *pcsAttribName,
BOOL &bReturn)
{
SCODE sc;
IWbemQualifierSet *pAttribSet = NULL;
if(pcsPropName != NULL) // Property Qualifier
{
BSTR bstrTemp = pcsPropName -> AllocSysString();
sc = pClassInt->GetPropertyQualifierSet(bstrTemp,
&pAttribSet);
::SysFreeString(bstrTemp);
}
else // A class Qualifier
sc = pClassInt->GetQualifierSet(&pAttribSet);
if (sc != S_OK)
{
bReturn = FALSE;
return S_OK;
}
VARIANTARG var;
VariantInit(&var);
BSTR bstrTemp = pcsAttribName -> AllocSysString();
sc = pAttribSet->Get(bstrTemp, 0, &var, NULL);
::SysFreeString(bstrTemp);
if (sc == S_OK)
bReturn = V_BOOL(&var);
else
bReturn = FALSE;
pAttribSet->Release();
VariantClear(&var);
return sc;
}
//***************************************************************************
//
// GetAttribBSTR
//
// Purpose: gets an BSTR Qualifier.
//
//***************************************************************************
long GetAttribBSTR
(IWbemClassObject * pClassInt,CString *pcsPropName, CString *pcsAttribName,
CString &csReturn)
{
SCODE sc;
IWbemQualifierSet *pAttribSet = NULL;
if(pcsPropName != NULL) // Property Qualifier
{
BSTR bstrTemp = pcsPropName -> AllocSysString();
sc = pClassInt->GetPropertyQualifierSet(bstrTemp,
&pAttribSet);
::SysFreeString(bstrTemp);
}
else // A class Qualifier
sc = pClassInt->GetQualifierSet(&pAttribSet);
if (sc != S_OK)
{
csReturn.Empty();
return sc;
}
VARIANTARG var;
VariantInit(&var);
BSTR bstrTemp = pcsAttribName -> AllocSysString();
sc = pAttribSet->Get(bstrTemp, 0, &var, NULL);
::SysFreeString(bstrTemp);
if (sc == S_OK && var.vt == VT_BSTR)
{
csReturn = var.bstrVal;
}
else
{
csReturn.Empty();
}
pAttribSet->Release();
VariantClear(&var);
return sc;
}
//***************************************************************************
//
// GetIWbemFullPath
//
// Purpose: Returns the complete path of the object.
//
//***************************************************************************
CString GetIWbemFullPath(IWbemClassObject *pClass)
{
CString csProp = _T("__Path");
return ::GetProperty(pClass,&csProp,TRUE);
}
CString GetIWbemRelativePath(IWbemClassObject *pClass)
{
CString csProp = _T("__RelPath");
return ::GetProperty(pClass,&csProp,TRUE);
}
BOOL WbemObjectIdentity(CString &rcsWbem1, CString &rcsWbem2)
{
if (rcsWbem1.CompareNoCase(rcsWbem2) == 0)
{
return TRUE;
}
else
{
return FALSE;
}
}
int StringInArray
(CStringArray *pcsaArray, CString *pcsString, int nIndex)
{
int nSize = (int) pcsaArray->GetSize();
for (int i = nIndex; i < nSize; i++)
{
if (pcsString->CompareNoCase(pcsaArray->GetAt(i)) == 0)
{
return i;
}
}
return -1;
}
CString GetBSTRProperty
(IWbemClassObject * pInst, CString *pcsProperty)
{
SCODE sc;
CString csOut;
VARIANTARG var;
VariantInit(&var);
long lType;
long lFlavor;
BSTR bstrTemp = pcsProperty -> AllocSysString ( );
sc = pInst->Get(bstrTemp ,0,&var,&lType,&lFlavor);
::SysFreeString(bstrTemp);
if (sc != S_OK)
{
return csOut;
}
if (var.vt == VT_BSTR)
csOut = var.bstrVal;
VariantClear(&var);
return csOut;
}
CString GetIWbemSuperClass(IWbemClassObject *pClass)
{
CString csProp = _T("__SuperClass");
return GetBSTRProperty(pClass,&csProp);
}
CString GetIWbemClass(IWbemClassObject *pClass)
{
CString csProp = _T("__Class");
return GetBSTRProperty(pClass,&csProp);
}
IWbemClassObject *GetClassObject (IWbemServices *pProv,CString *pcsClass,BOOL bQuiet)
{
IWbemClassObject *pClass = NULL;
IWbemClassObject *pErrorObject = NULL;
BSTR bstrTemp = pcsClass -> AllocSysString();
SCODE sc =
pProv->GetObject
(bstrTemp,0,NULL, &pClass,NULL);
::SysFreeString(bstrTemp);
if (sc != S_OK && bQuiet == FALSE)
{
CString csUserMsg=
_T("Cannot get class ") + *pcsClass;
ErrorMsg
(&csUserMsg, sc, pErrorObject, TRUE, &csUserMsg, __FILE__, __LINE__ - 7);
ReleaseErrorObject(pErrorObject);
return NULL;
}
ReleaseErrorObject(pErrorObject);
return pClass;
}
//***************************************************************************
//
// ObjectIdentity
//
// Purpose: Predicate to tell if two class objects are the
// same com object.
//
//***************************************************************************
BOOL ClassIdentity(IWbemClassObject *piWbem1, IWbemClassObject *piWbem2)
{
return (GetIWbemClass(piWbem1).CompareNoCase(GetIWbemClass(piWbem2)) == 0);
}
void ReleaseErrorObject(IWbemClassObject *&rpErrorObject)
{
if (rpErrorObject)
{
rpErrorObject->Release();
rpErrorObject = NULL;
}
}
void ErrorMsg
(CString *pcsUserMsg, SCODE sc, IWbemClassObject *pErrorObject, BOOL bLog,
CString *pcsLogMsg, char *szFile, int nLine, UINT uType)
{
CString csCaption = _T("Event Registration Message");
BOOL bErrorObject = sc != S_OK;
BSTR bstrTemp1 = csCaption.AllocSysString();
BSTR bstrTemp2 = pcsUserMsg->AllocSysString();
DisplayUserMessage
(bstrTemp1,bstrTemp2,
sc,bErrorObject,uType);
::SysFreeString(bstrTemp1);
::SysFreeString(bstrTemp2);
if (bLog)
{
LogMsg(pcsLogMsg, szFile, nLine);
}
}
void LogMsg
(CString *pcsLogMsg, char *szFile, int nLine)
{
}
BOOL ObjectInDifferentNamespace
(IWbemServices *pProv, CString *pcsNamespace, IWbemClassObject *pObject)
{
BOOL bHasServer = FALSE;
TCHAR c1 = (*pcsNamespace)[0];
TCHAR c2 = (*pcsNamespace)[1];
if (c1 == '\\' && c2 == '\\')
{
bHasServer = TRUE;
}
CString csNamespace;
CString csPath = GetIWbemFullPath(pObject);
CObjectPathParser parser;
ParsedObjectPath* pParsedPath = NULL;
BSTR bstrTemp = csPath.AllocSysString();
int nStatus = parser.Parse(bstrTemp, &pParsedPath);
::SysFreeString(bstrTemp);
if (nStatus == 0)
{
if (pParsedPath->m_dwNumNamespaces > 0)
{
if(pParsedPath->m_pServer && bHasServer)
{
csNamespace = _T("\\\\");
csNamespace += pParsedPath->m_pServer;
csNamespace += _T("\\");
}
for (unsigned int i = 0; i < pParsedPath->m_dwNumNamespaces; i++)
{
csNamespace += pParsedPath->m_paNamespaces[i];
if (i < pParsedPath->m_dwNumNamespaces - 1)
{
csNamespace += _T("\\");
}
}
}
}
if (pParsedPath)
{
parser.Free(pParsedPath);
}
return csNamespace.CompareNoCase(*pcsNamespace) != 0;
}
CString GetHmomWorkingDirectory()
{
CString csHmomWorkingDir;
HKEY hkeyLocalMachine;
LONG lResult;
lResult = RegConnectRegistry(NULL, HKEY_LOCAL_MACHINE, &hkeyLocalMachine);
if (lResult != ERROR_SUCCESS) {
return "";
}
HKEY hkeyHmomCwd;
lResult = RegOpenKeyEx(
hkeyLocalMachine,
_T("SOFTWARE\\Microsoft\\Wbem\\CIMOM"),
0,
KEY_READ | KEY_QUERY_VALUE,
&hkeyHmomCwd);
if (lResult != ERROR_SUCCESS) {
RegCloseKey(hkeyLocalMachine);
return "";
}
unsigned long lcbValue = 1024;
LPTSTR pszWorkingDir = csHmomWorkingDir.GetBuffer(lcbValue);
unsigned long lType;
lResult = RegQueryValueEx(
hkeyHmomCwd,
_T("Working Directory"),
NULL,
&lType,
(unsigned char*) (void*) pszWorkingDir,
&lcbValue);
csHmomWorkingDir.ReleaseBuffer();
RegCloseKey(hkeyHmomCwd);
RegCloseKey(hkeyLocalMachine);
if (lResult != ERROR_SUCCESS)
{
csHmomWorkingDir.Empty();
}
return csHmomWorkingDir;
}
int GetPropNames(IWbemClassObject * pClass, CString *&pcsReturn)
{
SCODE sc;
long ix[2] = {0,0};
long lLower, lUpper;
SAFEARRAY * psa = NULL;
VARIANTARG var;
VariantInit(&var);
CString csNull;
sc = pClass->GetNames(NULL,0,NULL,&psa);
if(sc != S_OK)
{
CString csUserMsg;
csUserMsg = _T("Cannot get property names ");
csUserMsg += _T(" for object ");
csUserMsg += GetIWbemFullPath (pClass);
ErrorMsg
(&csUserMsg, S_OK, NULL, TRUE, &csUserMsg, __FILE__,
__LINE__ - 10);
}
else
{
int iDim = SafeArrayGetDim(psa);
int i;
sc = SafeArrayGetLBound(psa,1,&lLower);
sc = SafeArrayGetUBound(psa,1,&lUpper);
pcsReturn = new CString [(lUpper - lLower) + 1];
for(ix[0] = lLower, i = 0; ix[0] <= lUpper; ix[0]++, i++)
{
BOOL bClsidSetForProp = FALSE;
BSTR PropName;
sc = SafeArrayGetElement(psa,ix,&PropName);
pcsReturn[i] = PropName;
SysFreeString(PropName);
}
}
SafeArrayDestroy(psa);
return (lUpper - lLower) + 1;
}
//***************************************************************************
//
// GetAllKeyPropValuePairs
//
// Purpose: For an object get a all key value pairs for that object.
//
//***************************************************************************
CStringArray *GetAllKeyPropValuePairs(IWbemClassObject *pObject)
{
CStringArray *pcsaReturn = new CStringArray;
CString csQualifier = _T("singleton");
BOOL bReturn;
SCODE sc = GetAttribBool
(pObject,NULL, &csQualifier, bReturn);
if (sc == S_OK)
{
if (bReturn == TRUE)
{
CString csTmp = GetIWbemClass(pObject);
pcsaReturn->Add(csTmp);
csTmp = _T("@");
pcsaReturn->Add(csTmp);
return pcsaReturn;
}
}
long ix[2] = {0,0};
long lLower, lUpper;
SAFEARRAY * psa = NULL;
int nProps;
CString *pcsProps;
nProps = GetPropNames(pObject, pcsProps);
int i;
IWbemQualifierSet * pAttrib = NULL;
CString csTmp;
CString csAttrib = _T("key");
COleVariant covValue;
for (i = 0; i < nProps; i++)
{
BSTR bstrTemp = pcsProps[i].AllocSysString();
sc = pObject -> GetPropertyQualifierSet(bstrTemp,
&pAttrib);
::SysFreeString(bstrTemp);
if (sc == S_OK && pAttrib)
{
sc = pAttrib->GetNames(0,&psa);
if(sc == S_OK)
{
int iDim = SafeArrayGetDim(psa);
sc = SafeArrayGetLBound(psa,1,&lLower);
sc = SafeArrayGetUBound(psa,1,&lUpper);
BSTR AttrName;
for(ix[0] = lLower; ix[0] <= lUpper; ix[0]++)
{
sc = SafeArrayGetElement(psa,ix,&AttrName);
csTmp = AttrName;
if (csAttrib.CompareNoCase(csTmp) == 0)
{
pcsaReturn->Add(pcsProps[i]);
covValue = GetProperty (pObject, &pcsProps[i]);
if (covValue.vt != VT_NULL)
{
covValue.ChangeType(VT_BSTR);
CString csValue = covValue.bstrVal;
pcsaReturn->Add(csValue);
}
else
{
pcsaReturn->Add(_T("<empty>"));
}
}
SysFreeString(AttrName);
}
}
pAttrib -> Release();
pAttrib = NULL;
}
}
SafeArrayDestroy(psa);
delete [] pcsProps;
return pcsaReturn;
}
//***************************************************************************
// Function: GetInstances
// Purpose: Gets class instances in the database.
//***************************************************************************
SCODE GetInstances( IWbemServices *pServices, CString *pcsClass,
CPtrArray &cpaInstances, BOOL bDeep)
{
SCODE sc;
IEnumWbemClassObject *pIEnumWbemInstObject = NULL;
IWbemClassObject *pIWbemInstObject = NULL;
IWbemClassObject *pErrorObject = NULL;
long lFlag = bDeep? WBEM_FLAG_DEEP: WBEM_FLAG_SHALLOW;
BSTR bstrTemp = pcsClass -> AllocSysString();
sc = pServices->CreateInstanceEnum
(bstrTemp,
lFlag, NULL, &pIEnumWbemInstObject);
::SysFreeString(bstrTemp);
if(sc != S_OK)
{
CString csUserMsg= _T("Cannot get instance enumeration ");
csUserMsg += _T(" for class ");
csUserMsg += *pcsClass;
ErrorMsg
(&csUserMsg, sc, pErrorObject, TRUE, &csUserMsg, __FILE__,
__LINE__ - 11);
ReleaseErrorObject(pErrorObject);
return sc;
}
ReleaseErrorObject(pErrorObject);
sc = pIEnumWbemInstObject->Reset();
ULONG uReturned;
while (S_OK == pIEnumWbemInstObject->Next(INFINITE, 1, &pIWbemInstObject, &uReturned) )
{
cpaInstances.Add(pIWbemInstObject);
pIWbemInstObject = NULL;
}
pIEnumWbemInstObject -> Release();
return sc;
}
//***************************************************************************
//
// BuildOBJDBGetRefQuery
//
// Purpose: Build an OBJDB "GetRef" query string suitable to pass to
// ExecQuery.
//
//***************************************************************************
CString BuildOBJDBGetRefQuery
(IWbemServices *pProv, CString *pcsTarget,
CString *pcsResultClass, CString *pcsRoleFilter,
CString *pcsReqAttrib, BOOL bClassOnly)
{
CString csReturn = _T("references of {");
csReturn += *pcsTarget;
csReturn += _T("}");
if (
(pcsResultClass && !pcsResultClass->IsEmpty()) ||
(pcsRoleFilter && !pcsRoleFilter -> IsEmpty()) ||
(pcsReqAttrib && !pcsReqAttrib -> IsEmpty()) ||
bClassOnly
)
csReturn += _T(" where");
if (pcsResultClass && !pcsResultClass->IsEmpty())
{
csReturn += _T(" ResultClass=");
csReturn += *pcsResultClass;
}
if (pcsRoleFilter && !pcsRoleFilter -> IsEmpty())
{
csReturn += _T(" Role=");
csReturn += *pcsRoleFilter;
}
if (pcsReqAttrib && !pcsReqAttrib -> IsEmpty())
{
csReturn += _T(" RequiredQualifier=");
csReturn += *pcsReqAttrib;
}
if (bClassOnly)
{
csReturn += _T(" ClassDefsOnly");
}
return csReturn;
}
//***************************************************************************
//
// BuildOBJDBGetAssocsQuery
//
// Purpose: Build an OBJDB "GetAssoc" query string suitable to pass to
// ExecQuery.
//
//***************************************************************************
CString BuildOBJDBGetAssocsQuery
(IWbemServices *pProv, CString *pcsTargetPath,
CString *pcsAssocClass, CString *pcsResultClass,
CString *pcsMyRoleFilter, CString *pcsReqAttrib,
CString *pcsReqAssocAttrib, CString *pcsResultRole,
BOOL bClassOnly)
{
pcsTargetPath;
pcsAssocClass;
pcsResultClass;
CString csReturn = _T("associators of {");
csReturn += *pcsTargetPath;
csReturn += _T("}");
if ((pcsResultClass && !pcsResultClass->IsEmpty()) ||
(pcsMyRoleFilter && !pcsMyRoleFilter -> IsEmpty()) ||
!pcsAssocClass->IsEmpty() ||
(pcsReqAttrib && !pcsReqAttrib -> IsEmpty()) ||
(pcsReqAssocAttrib && !pcsReqAssocAttrib -> IsEmpty()) ||
bClassOnly)
csReturn += " where";
if (pcsAssocClass && !pcsAssocClass->IsEmpty())
{
csReturn += _T(" AssocClass=");
csReturn += *pcsAssocClass;
}
if (pcsResultClass && !pcsResultClass->IsEmpty())
{
csReturn += _T(" ResultClass=");
csReturn += *pcsResultClass;
}
if (pcsMyRoleFilter && !pcsMyRoleFilter -> IsEmpty())
{
csReturn += _T(" Role=");
csReturn += *pcsMyRoleFilter;
}
if (pcsResultRole && !pcsResultRole -> IsEmpty())
{
csReturn += _T(" ResultRole=");
csReturn += *pcsResultRole;
}
if (pcsReqAttrib && !pcsReqAttrib -> IsEmpty())
{
csReturn += _T(" RequiredQualifier=");
csReturn += *pcsReqAttrib;
}
if (pcsReqAssocAttrib && !pcsReqAssocAttrib -> IsEmpty())
{
csReturn += _T(" RequiredAssocAttrib=");
csReturn += *pcsReqAssocAttrib;
}
if (bClassOnly)
{
csReturn += _T(" ClassDefsOnly");
}
return csReturn;
}
//***************************************************************************
//
// ExecOBJDBQuery
//
// Purpose: Execute an OBJDB query and return class enumeration. The caller
// must release the enumeration when done with it.
//
//***************************************************************************
IEnumWbemClassObject *ExecOBJDBQuery
(IWbemServices * pProv, CString &csQuery)
{
IEnumWbemClassObject *pemcoResult = NULL;
IWbemClassObject *pErrorObject = NULL;
CString csQueryType = _T("WQL");
BSTR bstrTemp1 = csQueryType.AllocSysString();
BSTR bstrTemp2 = csQuery.AllocSysString();
SCODE sc = pProv -> ExecQuery(bstrTemp1,bstrTemp2
,0,NULL,&pemcoResult);
::SysFreeString(bstrTemp1);
::SysFreeString(bstrTemp2);
if (sc == S_OK)
{
ReleaseErrorObject(pErrorObject);
return pemcoResult;
}
else
{
CString csUserMsg;
CString csErrorAsHex;
csErrorAsHex.Format(_T("0x%x"),sc);
csUserMsg = _T("ExecQuery failure: ");
csUserMsg += csErrorAsHex;
csUserMsg += _T(" for query: ");
csUserMsg += csQuery;
ErrorMsg
(&csUserMsg, sc, pErrorObject, TRUE, &csUserMsg, __FILE__,
__LINE__ - 28);
ReleaseErrorObject(pErrorObject);
return NULL;
}
}
//***********************************************************
// CComparePaths::CompareNoCase
//
//
// Do a case insensitive comparison of two wide strings. This
// compare works even when one or both of the string pointers are
// NULL. A NULL pointer is taken to be less than any real string,
// even an empty one.
//
// Parameters:
// [in] LPWSTR pws1
// Pointer to the first string. This pointer can be NULL.
//
// [in] LPWSTR pws2
// Pointer to the second string. This pointer can be NULL.
//
// Returns:
// int
// Greater than zero if string1 is greater than string2.
// Zero if the two strings are equal.
// Less than zero if string 1 is less than string2.
//
//**************************************************************
int CComparePaths::CompareNoCase(LPWSTR pws1, LPWSTR pws2)
{
// Handle the case where one, or both of the string pointers are NULL
if (pws1 == NULL) {
if (pws2 == NULL) {
return 0; // Two null strings are equal
}
else {
return -1; // A null string is less than any real string.
}
}
if (pws2 == NULL) {
if (pws1 != NULL) {
return 1; // Any string is greater than a null string.
}
}
ASSERT(pws1 != NULL);
ASSERT(pws2 != NULL);
int iResult;
iResult = _wcsicmp( pws1, pws2);
return iResult;
}
//***************************************************************
// CComparePath::NormalizeKeyArray
//
// The key array is normalized by sorting the KeyRef's by key name.
// After two key arrays are sorted, they can be compared without
// by iterating through the list of keys and comparing corresponding
// array entries rather than trying searching the arrays for corresponding
// key names and then comparing the key values.
//
// Parameters:
// [in, out] ParsedObjectPath& path
// The parsed object path containing the key array to sort.
//
// Returns:
// Nothing. (The key array is sorted as a side effect).
//
//*****************************************************************
void CComparePaths::NormalizeKeyArray(ParsedObjectPath& path)
{
// Do a simple bubble sort where the "KeyRefs" with the smallest
// names are bubbled towards the top and the the KeyRefs with the
// largest names are bubbled toward the bottom.
for (DWORD dwKey1 = 0; dwKey1 < path.m_dwNumKeys; ++dwKey1) {
for (DWORD dwKey2 = dwKey1 + 1; dwKey2 < path.m_dwNumKeys; ++dwKey2) {
ASSERT(path.m_paKeys[dwKey1] != NULL);
KeyRef* pkr1 = path.m_paKeys[dwKey1];
ASSERT(pkr1 != NULL);
ASSERT(path.m_paKeys[dwKey2] != NULL);
KeyRef* pkr2 = path.m_paKeys[dwKey2];
ASSERT(pkr2 != NULL);
int iResult = CompareNoCase(pkr1->m_pName, pkr2->m_pName);
if (iResult > 0) {
// Swap the two keys;
path.m_paKeys[dwKey1] = pkr2;
path.m_paKeys[dwKey2] = pkr2;
}
}
}
}
//***********************************************************************
// CComparePaths::KeyValuesAreEqual
//
// Compare two key values to determine whether or not they are equal.
// To be equal, they must both be of the same type and their values
// must also be equal.
//
// Parameters:
// [in] VARAINT& variant1
// The first key value.
//
// [in] VARIANT& variant2
// The second key value.
//
// Returns:
// TRUE if the two values are the same, FALSE otherwise.
//
//**********************************************************************
BOOL CComparePaths::KeyValuesAreEqual(VARIANT& v1, VARIANT& v2)
{
ASSERT(v1.vt == v2.vt);
ASSERT(v1.vt==VT_BSTR || v1.vt == VT_I4);
ASSERT(v2.vt==VT_BSTR || v2.vt == VT_I4);
// Key values should always be VT_BSTR or VT_I4. We special case these
// two types to be efficient and punt on all the other types.
BOOL bIsEqual;
switch(v1.vt) {
case VT_BSTR:
if (v2.vt == VT_BSTR) {
bIsEqual = IsEqual(v1.bstrVal, v2.bstrVal);
return bIsEqual;
}
else {
return FALSE;
}
break;
case VT_I4:
if (v2.vt == VT_I4) {
bIsEqual = (v1.lVal == v2.lVal);
return bIsEqual;
}
else {
return FALSE;
}
break;
}
ASSERT(FALSE);
COleVariant var1;
COleVariant var2;
var1 = v1;
var2 = v2;
bIsEqual = (var1 == var2);
return bIsEqual;
}
//*******************************************************************
// CComparePaths::PathsRefSameObject
//
// Compare two parsed object paths to determine whether or not they
// they reference the same object. Note that the sever name and namespaces
// are not compared if they are missing from one of the paths.
//
// Parameters:
// [in] ParsedObjectPath* ppath1
// The first parsed path.
//
// [in] ParsedObjectPath* ppath2
// The second parsed path.
//
// Returns:
// BOOL
// TRUE if the two paths reference the same object, FALSE otherwise.
//
//*******************************************************************
BOOL CComparePaths::PathsRefSameObject(
/* in */ ParsedObjectPath* ppath1,
/* in */ ParsedObjectPath* ppath2)
{
if (ppath1 == ppath2) {
return TRUE;
}
if (ppath1==NULL || ppath2==NULL) {
return FALSE;
}
#if 0
// Check to see if a server name is specified for either path
// if so, the server name count is 1, otherwise zero.
UINT iNamespace1 = 0;
if (ppath1->m_pServer!=NULL) {
if (!IsEqual(ppath1->m_pServer, L".")) {
iNamespace1 = 1;
}
}
UINT iNamespace2 = 0;
if (ppath1->m_pServer!=NULL) {
if (!IsEqual(ppath2->m_pServer, L".")) {
iNamespace2 = 1;
}
}
// Relative paths don't specify a server, so we assume that the server
// for a relative path and any other path match and no further comparison is
// necessary.
if (iNamespace1!=0 && iNamespace2!=0) {
if (!IsEqual(ppath1->m_pServer, ppath2->m_pServer)) {
return FALSE;
}
}
// Relative paths don't specify name spaces, so we assume that the name spaces
// for a relative path and any other path match and no further comparison is
// necessary. Of course, this assumes that the namespace for a relative path
// is indeed the same as the other path.
if (ppath1->m_dwNumNamespaces!=0 && ppath2->m_dwNumNamespaces!=0) {
// Check to see if one of the namespaces are different.
if ((ppath1->m_dwNumNamespaces - iNamespace1) != (ppath2->m_dwNumNamespaces - iNamespace2)) {
return FALSE;
}
while((iNamespace1 < ppath1->m_dwNumNamespaces) && (iNamespace2 < ppath2->m_dwNumNamespaces)) {
if (!IsEqual(ppath1->m_paNamespaces[iNamespace1], ppath2->m_paNamespaces[iNamespace2])) {
return FALSE;
}
++iNamespace1;
++iNamespace2;
}
}
#endif //0
// Check to see if the classes are different.
if (!IsEqual(ppath1->m_pClass, ppath2->m_pClass)) {
return FALSE;
}
// Check to see if any of the keys are different.
if (ppath1->m_dwNumKeys != ppath2->m_dwNumKeys) {
return FALSE;
}
KeyRef* pkr1;
KeyRef* pkr2;
// Handle single keys as a special case since "Class="KeyValue"" should
// be identical to "Class.keyName="KeyValue""
if ((ppath1->m_dwNumKeys==1) && (ppath2->m_dwNumKeys==1)) {
pkr1 = ppath1->m_paKeys[0];
pkr2 = ppath2->m_paKeys[0];
if (!IsEqual(pkr1->m_pName, pkr2->m_pName)) {
if (pkr1->m_pName!=NULL && pkr2->m_pName!=NULL) {
return FALSE;
}
}
if (KeyValuesAreEqual(pkr1->m_vValue, pkr2->m_vValue)) {
return TRUE;
}
else {
return FALSE;
}
}
NormalizeKeyArray(*ppath1);
NormalizeKeyArray(*ppath2);
for (DWORD dwKeyIndex = 0; dwKeyIndex < ppath1->m_dwNumKeys; ++dwKeyIndex) {
ASSERT(ppath1->m_paKeys[dwKeyIndex] != NULL);
ASSERT(ppath2->m_paKeys[dwKeyIndex] != NULL);
pkr1 = ppath1->m_paKeys[dwKeyIndex];
pkr2 = ppath2->m_paKeys[dwKeyIndex];
if (!IsEqual(pkr1->m_pName, pkr2->m_pName)) {
return FALSE;
}
if (!KeyValuesAreEqual(pkr1->m_vValue, pkr2->m_vValue)) {
return FALSE;
}
}
return TRUE;
}
//**************************************************************
// CComparePaths::PathsRefSameObject
//
// Check to see if two object paths point to the same object.
//
// Parameters:
// BSTR bstrPath1
// The first object path.
//
// BSTR bstrPath2
// The second object path.
//
// Returns:
// BOOL
// TRUE if the two paths reference the same object in
// the database, FALSE otherwise.
//
//**************************************************************
BOOL CComparePaths::PathsRefSameObject(BSTR bstrPath1, BSTR bstrPath2)
{
CObjectPathParser parser;
ParsedObjectPath* pParsedPath1 = NULL;
ParsedObjectPath* pParsedPath2 = NULL;
int nStatus1;
int nStatus2;
nStatus1 = parser.Parse(bstrPath1, &pParsedPath1);
nStatus2 = parser.Parse(bstrPath2, &pParsedPath2);
BOOL bRefSameObject = FALSE;
if (nStatus1==0 && nStatus2==0) {
bRefSameObject = PathsRefSameObject(pParsedPath1, pParsedPath2);
}
if (pParsedPath1) {
parser.Free(pParsedPath1);
}
if (pParsedPath2) {
parser.Free(pParsedPath2);
}
return bRefSameObject;
}
CPtrArray *SemiSyncEnum
(IEnumWbemClassObject *pEnum, BOOL &bCancel,
HRESULT &hResult, int nRes)
{
if (!pEnum)
return NULL;
CPtrArray *pcpaObjects = new CPtrArray;
IWbemClassObject *pObject = NULL;
ULONG uReturned = 0;
hResult = S_OK;
IWbemClassObject **pimcoInstances = new IWbemClassObject *[nRes];
int i;
for (i = 0; i < nRes; i++)
{
pimcoInstances[i] = NULL;
}
hResult =
pEnum->Next(0,nRes,pimcoInstances, &uReturned);
int cInst = 0;
BOOL bDone = FALSE;
while(!bDone &&
(hResult == S_OK || hResult == WBEM_S_TIMEDOUT || uReturned > 0))
{
#pragma warning( disable :4018 )
for (int i = 0; i < uReturned; i++)
#pragma warning( default : 4018 )
{
pcpaObjects->Add(reinterpret_cast<void *>(pimcoInstances[i]));
pimcoInstances[i] = NULL;
}
cInst += uReturned;
uReturned = 0;
if (cInst < nRes)
{
hResult = pEnum->Next
(0,nRes - cInst,pimcoInstances, &uReturned);
}
else
{
bDone = TRUE;
}
}
delete[]pimcoInstances;
return pcpaObjects;
}
CString GetClass(CString *pcsPath)
{
CObjectPathParser parser;
ParsedObjectPath* pParsedPath = NULL;
BSTR bstrTemp = pcsPath->AllocSysString();
int nStatus = parser.Parse(bstrTemp, &pParsedPath);
::SysFreeString(bstrTemp);
if (nStatus == 0)
{
if (pParsedPath)
{
CString csClass = pParsedPath->m_pClass;
parser.Free(pParsedPath);
return csClass;
}
}
return _T("");
}
BOOL ArePathsEqual (CString csPath1, CString csPath2)
{
CComparePaths ccpParser;
BSTR bstrTemp1 = csPath1.AllocSysString();
BSTR bstrTemp2 = csPath2.AllocSysString();
BOOL bReturn = ccpParser.PathsRefSameObject
(bstrTemp1,bstrTemp2);
::SysFreeString(bstrTemp1);
::SysFreeString(bstrTemp2);
return bReturn;
}
CString GetPropertyNameByAttrib(IWbemClassObject *pObject , CString *pcsAttrib)
{
SCODE sc;
long ix[2] = {0,0};
long lLower, lUpper;
SAFEARRAY * psa = NULL;
int nProps;
CString *pcsProps;
nProps = GetPropNames(pObject, pcsProps);
int i;
IWbemQualifierSet * pAttrib = NULL;
CString csTmp;
CString csReturn;
BOOL bBreak = FALSE;
for (i = 0; i < nProps; i++)
{
BSTR bstrTemp = pcsProps[i].AllocSysString();
sc = pObject -> GetPropertyQualifierSet(bstrTemp,
&pAttrib);
::SysFreeString(bstrTemp);
if (sc == S_OK)
{
sc = pAttrib->GetNames(0,&psa);
if(sc == S_OK)
{
int iDim = SafeArrayGetDim(psa);
sc = SafeArrayGetLBound(psa,1,&lLower);
sc = SafeArrayGetUBound(psa,1,&lUpper);
BSTR AttrName;
for(ix[0] = lLower; ix[0] <= lUpper; ix[0]++)
{
sc = SafeArrayGetElement(psa,ix,&AttrName);
csTmp = AttrName;
if (pcsAttrib -> CompareNoCase(csTmp) == 0)
{
csReturn = pcsProps[i];
bBreak = TRUE;
}
SysFreeString(AttrName);
}
}
pAttrib -> Release();
if (bBreak)
break;
}
}
SafeArrayDestroy(psa);
delete [] pcsProps;
return csReturn;
}
BOOL IsClassAbstract(IWbemClassObject* pObject)
{
CString csQualifier = _T("abstract");
BOOL bReturn;
long sc = GetAttribBool
(pObject,NULL, &csQualifier, bReturn);
if (sc == S_OK)
{
if (bReturn)
{
return TRUE;
}
}
return FALSE;
}
BOOL IsObjectOfClass(CString &csClass, IWbemClassObject *pObject)
{
CString csObjectClass = GetIWbemClass(pObject);
if (csClass.CompareNoCase((LPCTSTR) csObjectClass) == 0)
{
return TRUE;
}
CStringArray *pcsaDerivation = ClassDerivation (pObject);
BOOL bIsSublcass = FALSE;
for (int i = 0; i < pcsaDerivation->GetSize(); i++)
{
if (csClass.CompareNoCase((LPCTSTR) pcsaDerivation->GetAt(i)) == 0)
{
bIsSublcass = TRUE;
}
}
delete pcsaDerivation;
return bIsSublcass;
}
CStringArray *ClassDerivation (IWbemClassObject *pObject)
{
SCODE sc;
VARIANTARG var;
VariantInit(&var);
long lType;
long lFlavor;
CString csProp = _T("__derivation");
BSTR bstrTemp = csProp.AllocSysString ( );
sc = pObject->Get(bstrTemp ,0,&var,&lType,&lFlavor);
::SysFreeString(bstrTemp);
if (sc != S_OK)
{
return NULL;
}
long ix[2] = {0,0};
long lLower, lUpper;
int iDim = SafeArrayGetDim(var.parray);
sc = SafeArrayGetLBound(var.parray,1,&lLower);
sc = SafeArrayGetUBound(var.parray,1,&lUpper);
BSTR bstrClass;
CStringArray *pcsaReturn = new CStringArray;
for(ix[0] = lLower; ix[0] <= lUpper; ix[0]++)
{
sc = SafeArrayGetElement(var.parray,ix,&bstrClass);
CString csTmp = bstrClass;
pcsaReturn->Add(csTmp);
SysFreeString(bstrClass);
}
VariantClear(&var);
return pcsaReturn;
}
//HRESULT ConfigureSecurity(IWbemServices *pServices)
//{
/*IUnknown *pUnknown = dynamic_cast<IUnknown *>(pServices);
return ConfigureSecurity(pUnknown);*/
// return S_OK;
//}
//HRESULT ConfigureSecurity(IEnumWbemClassObject *pEnum)
//{
/*IUnknown *pUnknown = dynamic_cast<IUnknown *>(pEnum);
return ConfigureSecurity(pUnknown);*/
// return S_OK;
//}
//HRESULT ConfigureSecurity(IUnknown *pUnknown)
//{
/*IClientSecurity* pCliSec;
if(FAILED(pUnknown->QueryInterface(IID_IClientSecurity, (void**)&pCliSec)))
{
// no security --- probably not a proxy
return S_OK;
}
HRESULT hRes =
pCliSec->SetBlanket(pUnknown, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE,
NULL, RPC_C_AUTHN_LEVEL_NONE, RPC_C_IMP_LEVEL_IMPERSONATE,
NULL, EOAC_NONE);
pCliSec->Release();
return hRes;*/
// return S_OK;
//}