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

1275 lines
28 KiB
C++

// Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
//***************************************************************************
//
// OLEMSClient.cpp
//
// Module: Class Navigator ActiveX Control
//
//
//***************************************************************************
#include "precomp.h"
#include <OBJIDL.H>
#include <nddeapi.h>
#include <initguid.h>
#include "wbemidl.h"
#include "MsgDlgExterns.h"
#include <genlex.h>
#include <opathlex.h>
#include <objpath.h>
#include "OLEMSClient.h"
#include "logindlg.h"
#define BUFF_SIZE 256
// *************************************************************************
// 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 (NULL, pInst);
ErrorMsg
(&csUserMsg, sc, NULL, TRUE, &csUserMsg, __FILE__,
__LINE__ - 9);
return _T("");
}
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)
{
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)
{
if (pcsParentClass)
{
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);
}
else
{
CString csUserMsg =
_T("An error occured creating the class ") + *pcsNewClass + _T(" .");
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 = _T("");
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)
{
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)
{
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: 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;
sc = pIWbemServices->CreateClassEnum
(NULL, WBEM_FLAG_DEEP | WBEM_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY, 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);
}
IWbemClassObject *pimcoInstances[N_INSTANCES];
IWbemClassObject **pInstanceArray =
reinterpret_cast<IWbemClassObject **> (&pimcoInstances);
for (int i = 0; i < N_INSTANCES; i++)
{
pimcoInstances[i] = NULL;
}
ULONG uReturned;
HRESULT hResult =
pIEnumWbemClassObject->Next(0,N_INSTANCES,pInstanceArray, &uReturned);
pIWbemClassObject = NULL;
while(hResult == S_OK || hResult == WBEM_S_TIMEDOUT || uReturned > 0)
{
#pragma warning( disable :4018 )
for (int c = 0; c < uReturned; c++)
#pragma warning( default : 4018 )
{
pIWbemClassObject = pInstanceArray[c];
cpaClasses.Add(reinterpret_cast<void *>(pIWbemClassObject));
pimcoInstances[c] = NULL;
pIWbemClassObject = NULL;
}
uReturned = 0;
hResult = pIEnumWbemClassObject->Next
(0,N_INSTANCES,pInstanceArray, &uReturned);
}
pIEnumWbemClassObject -> Release();
return (int) cpaClasses.GetSize();
}
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(IWbemClassObject *pimcoNew, CPtrArray *pcpaDeepEnum)
{
CString csClass = _T("__Class");
csClass = ::GetProperty(pimcoNew,&csClass);
for (int i = 0; i < pcpaDeepEnum->GetSize(); i++)
{
IWbemClassObject *pObject =
reinterpret_cast<IWbemClassObject *>(pcpaDeepEnum->GetAt(i));
CString csSuper = GetIWbemSuperClass(pObject);
if (csSuper.CompareNoCase(csClass) == 0)
{
return TRUE;
}
}
return FALSE;
}
BOOL HasSubclasses(IWbemServices * pIWbemServices, IWbemClassObject *pimcoClass, CString &rcsNamespace)
{
#ifdef _DEBUG
DWORD dFn1 = GetTickCount();
#endif
SCODE sc;
IEnumWbemClassObject * pIEnumWbemClassObject = NULL;
IWbemClassObject * pIWbemClassObject = NULL;
IWbemClassObject * pErrorObject = NULL;
CString csClass = _T("__Class");
csClass = ::GetProperty(pimcoClass,&csClass);
#ifdef _DEBUG
DWORD dEnum1 = GetTickCount();
#endif
BSTR bstrTemp = csClass.AllocSysString();
sc = pIWbemServices->CreateClassEnum
(bstrTemp, WBEM_FLAG_SHALLOW | WBEM_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY , NULL, &pIEnumWbemClassObject);
::SysFreeString(bstrTemp);
#ifdef _DEBUG
DWORD dEnum2 = GetTickCount();
#endif
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);
}
ULONG uReturned;
int i = 0;
pIWbemClassObject = NULL;
BOOL bStop = FALSE;
#ifdef _DEBUG
DWORD dNext1 = GetTickCount();
DWORD dNext2 = -1;
#endif
if (!bStop && S_OK == pIEnumWbemClassObject->Next(INFINITE, 1, &pIWbemClassObject, &uReturned) )
{
if (pIWbemClassObject)
{
#ifdef _DEBUG
dNext2 = GetTickCount();
#endif
pIWbemClassObject -> Release();
pIWbemClassObject = NULL;
i++;
}
if (i > 0)
{
bStop = TRUE;
}
}
#ifdef _DEBUG
if (dNext2 == -1)
{
dNext2 = GetTickCount();
}
DWORD dRel1 = GetTickCount();
#endif
pIEnumWbemClassObject -> Release();
#ifdef _DEBUG
#ifdef _DOTIMING
DWORD dRel2 = GetTickCount();
DWORD dFn2 = GetTickCount();
afxDump << "HasSubclasses function tick count for class " << csClass << " = " << dFn2 - dFn1 << "\n";
afxDump << " HasSubclasses CreateClassEnum tick count = " << dEnum2 - dEnum1 << "\n";
if (i == 0)
{
afxDump << " HasSubclasses Next tick count (zero objects returned) = " << dNext2 - dNext1 << "\n";
}
else
{
afxDump << " HasSubclasses Next tick count (" << i << " Next API calls) = " << dNext2 - dNext1 << "\n";
}
afxDump << " HasSubclasses Release tick count = " << dRel2 - dRel1 << "\n\n";
#endif
#endif
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 | WBEM_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY ,
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);
}
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;
BSTR bstrTemp;
if(pcsPropName != NULL) // Property Qualifier
{
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);
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(IWbemServices *pProv, IWbemClassObject *pClass)
{
CString csProp = _T("__Path");
return ::GetProperty(pClass,&csProp);
}
IWbemLocator *InitLocator()
{
IWbemLocator *pLocator = NULL;
SCODE sc = CoCreateInstance(CLSID_WbemLocator,
0,
CLSCTX_INPROC_SERVER,
IID_IWbemLocator,
(LPVOID *) &pLocator);
if (sc != S_OK)
{
CString csUserMsg =
_T("Cannot iniitalize the locator ");
ErrorMsg
(&csUserMsg, sc, NULL, TRUE, &csUserMsg, __FILE__, __LINE__ - 10);
return 0;
}
return pLocator;
}
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;
}
CStringArray *PathFromRoot (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 csaTmp;
for(ix[0] = lLower; ix[0] <= lUpper; ix[0]++)
{
sc = SafeArrayGetElement(var.parray,ix,&bstrClass);
CString csTmp = bstrClass;
csaTmp.Add(csTmp);
SysFreeString(bstrClass);
}
CStringArray *pcsaReturn = new CStringArray;
for (int i = (int) csaTmp.GetSize() - 1; i > -1; i--)
{
pcsaReturn->Add(csaTmp.GetAt(i));
}
CString csObject = GetIWbemClass(pObject);
pcsaReturn->Add(csObject);
VariantClear(&var);
return pcsaReturn;
}
//***************************************************************************
//
// 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("Class Explorer 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(pProv,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;
}
void MoveWindowToLowerLeftOfOwner(CWnd *pWnd)
{
CWnd *pOwner = pWnd->GetOwner();
RECT rectOwner;
pOwner->GetClientRect(&rectOwner);
pOwner->ClientToScreen(&rectOwner);
RECT rect;
pWnd->GetClientRect(&rect);
pWnd->ClientToScreen(&rect);
RECT rectMove;
rectMove.left = rectOwner.left;
rectMove.bottom = rectOwner.bottom;
rectMove.right = rectOwner.left + (rect.right - rect.left);
rectMove.top = rectOwner.top + (rectOwner.bottom - rect.bottom);
pWnd->MoveWindow(&rectMove,TRUE);
}
void CenterWindowInOwner(CWnd *pWnd,CRect &rectMove)
{
if (!pWnd)
{
return;
}
CWnd *pOwner = pWnd->GetOwner();
if (!pOwner)
{
return;
}
CRect rectOwner;
pOwner->GetWindowRect(&rectOwner);
CRect rect;
pWnd->GetWindowRect(&rect);
if (rectOwner.Width() < rect.Width())
{
long delta = (long) ((rectOwner.Width() - rect.Width()) * .5);
rectMove.left = rectOwner.left + delta;
rectMove.right = rectOwner.right - delta;
}
else
{
long delta = (long) ((rect.Width() - rectOwner.Width()) * .5);
rectMove.left = rectOwner.left - delta;
rectMove.right = rectOwner.right + delta;
}
if (rectOwner.Height() < rect.Height())
{
long delta = (long) ((rectOwner.Height() - rect.Height()) * .5);
rectMove.top = rectOwner.top + delta;
rectMove.bottom = rectOwner.bottom - delta;
}
else
{
long delta = (long) ((rect.Height() - rectOwner.Height()) * .5);
rectMove.top = rectOwner.top - delta;
rectMove.bottom = rectOwner.bottom + delta;
}
}