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

1431 lines
30 KiB
C++

// Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
#include "precomp.h"
#include "resource.h"
#include "path.h"
#include "hmomutil.h"
#include "hmmverr.h"
#include "utils.h"
#include "hmmvctl.h"
#include "globals.h"
#define MAX_STRING 1024
CSelection::CSelection(CWBEMViewContainerCtrl* phmmv)
{
m_phmmv = phmmv;
m_phmm = NULL;
m_pco = NULL;
m_varNamespace = _T("");
Clear();
}
CSelection::~CSelection()
{
if (m_pco) {
m_pco->Release();
}
if (m_phmm) {
m_phmm->Release();
}
}
SCODE CSelection::SetNamespace(LPCTSTR pszNamespace)
{
m_varNamespace = pszNamespace;
if ((m_varPath.vt == VT_BSTR) && (*m_varPath.bstrVal != NULL)) {
ConnectServer();
}
return S_OK;
}
//**********************************************************
// CSelection::IsSystemClass
//
// Check to see if the currently selected class is a system
// class.
//
// Parameters:
// [out] BOOL& bIsSystemClass
// Returns TRUE if the selected class is a system class.
//
// Returns:
// SCODE
// S_OK the __CLASS property could be read so that the
// test for system class could be performed. E_FAIL if
// there is no current object or the __CLASS property
// could not be read.
//
//***********************************************************
SCODE CSelection::IsSystemClass(BOOL& bIsSystemClass)
{
bIsSystemClass = FALSE;
if (m_pco == NULL) {
return E_FAIL;
}
COleVariant varClass;
CBSTR bsPropname;
bsPropname = _T("__CLASS");
SCODE sc = m_pco->Get((BSTR) bsPropname, 0, &varClass, NULL, NULL);
if (SUCCEEDED(sc)) {
if ((varClass.vt == VT_BSTR) && (varClass.bstrVal != NULL)) {
if (varClass.bstrVal[0] == L'_') {
if (varClass.bstrVal[1] == L'_') {
bIsSystemClass = TRUE;
}
}
}
return S_OK;
}
else {
return sc;
}
}
SCODE CSelection::GetNamespace(CString& sNamespace)
{
if (m_varNamespace.vt != VT_BSTR) {
sNamespace = "";
return E_FAIL;
}
sNamespace = m_varNamespace.bstrVal;
return S_OK;
}
void CSelection::Clear(BOOL bReleaseServices)
{
if (m_pco) {
m_pco->Release();
m_pco = NULL;
}
if (bReleaseServices) {
if (m_phmm) {
m_phmm->Release();
m_phmm = NULL;
}
m_varServerConnect = L"";
m_varNamespaceConnect = L"";
m_varNamespace = L"";
}
m_sPath = "";
m_varPath = L"";
m_sc = S_OK;
m_sClass = "";
m_sTitle = "";
m_bClassIsSingleton = FALSE;
m_bSingletonHasInstance = FALSE;
m_bObjectIsNewlyCreated = FALSE;
m_bIsEmbeddedObject = FALSE;
}
SCODE CSelection::SelectPath(BSTR bstrPath, BOOL bPartialPath)
{
CString sPath = bstrPath;
SCODE sc;
if (sPath.IsEmpty()) {
sc = SelectPath((LPCTSTR) sPath, TRUE, FALSE);
}
else {
sc = SelectPath((LPCTSTR) sPath, bPartialPath);
}
return sc;
}
void CSelection::GetNamespaceConnect(CString& sNamespaceConnect)
{
sNamespaceConnect.Empty();
if (m_varNamespaceConnect.vt != VT_BSTR) {
return;
}
sNamespaceConnect = m_varNamespaceConnect.bstrVal;
}
//******************************************************
// CSelection::SelectPath
//
// Select the specified path.
//
// Input:
// [in] LPCTSTR pszPath
//
// [in] BOOL bPartialPath
//
// [in] BOOL bTestPathFirst
// TRUE if the path should be tested for validity prior
// to selecting the object into this CSelection object.
// When this parameter is true, the caller is assured
// that the current object will not be corrupted if
// the path selection fails.
//
// [in] BOOL bRestoringContext
// TRUE if this is called to restore a context in the view context
// stack. When TRUE, error messages are suppressed if a not found
// error occurs.
//
// Returns:
// SCODE
//
//**********************************************************
SCODE CSelection::SelectPath(LPCTSTR pszPath, BOOL bPartialPath, BOOL bTestPathFirst, BOOL bRestoringContext)
{
if (bTestPathFirst) {
// Select the path into a new instance of CSelection
CSelection* pselClass = new CSelection(m_phmmv);
*pselClass = *this;
SCODE sc;
sc = pselClass->SelectPath(pszPath, bPartialPath, FALSE, bRestoringContext);
if (FAILED(sc)) {
// We could not select the object, so return the failure code without
// corrupting this object.
delete pselClass;
return sc;
}
// Copy the CSelection with the new object into this CSelection and
// return success.
*this = *pselClass;
delete pselClass;
return S_OK;
}
m_sc = S_OK;
if (m_pco != NULL) {
m_pco->Release();
m_pco = NULL;
}
if (!bPartialPath) {
Clear(FALSE);
}
m_sPath = pszPath;
m_varPath = pszPath;
if (m_sPath.IsEmpty()) {
return S_OK;
}
if (!bPartialPath) {
m_sc = ConnectServer();
if (FAILED(m_sc)) {
return m_sc;
}
}
m_sc = GetObjectFromPath(bRestoringContext);
if (FAILED(m_sc)) {
return m_sc;
}
return m_sc;
}
SCODE CSelection::SelectEmbeddedObject(IWbemServices* psvc, IWbemClassObject* pco, BOOL bExistsInDatabase)
{
Clear(FALSE);
if (m_phmm != NULL) {
m_phmm->Release();
}
if (psvc != NULL) {
psvc->AddRef();
}
m_phmm = psvc;
m_bIsEmbeddedObject = TRUE;
m_bObjectIsNewlyCreated = !bExistsInDatabase;
ASSERT(m_pco == NULL);
if (pco != NULL) {
pco->AddRef();
m_pco = pco;
}
GetObjectDescription();
return S_OK;
}
CSelection& CSelection::operator=(BSTR bstrPath)
{
SelectPath(bstrPath);
return *this;
}
CSelection& CSelection::operator=(LPCTSTR pszPath)
{
SCODE sc = SelectPath(pszPath);
return *this;
}
CSelection::operator LPCTSTR()
{
return (LPCTSTR) m_sPath;
}
CSelection::operator BSTR()
{
return m_varPath.bstrVal;
}
CSelection& CSelection::operator=(CSelection& selSrc)
{
Clear();
m_phmmv = selSrc.m_phmmv;
m_sc = selSrc.m_sc;
m_sPath = selSrc.m_sPath;
m_varPath = selSrc.m_varPath;
if (selSrc.m_pco) {
m_pco = selSrc.m_pco;
m_pco->AddRef();
}
else {
m_pco = NULL;
}
if (selSrc.m_phmm) {
m_phmm = selSrc.m_phmm;
m_phmm->AddRef();
}
else {
m_pco = NULL;
}
m_varServerConnect = selSrc.m_varServerConnect;
m_varNamespaceConnect = selSrc.m_varNamespaceConnect;
m_varNamespace = selSrc.m_varNamespace;
m_sClass = selSrc.m_sClass;
m_sTitle = selSrc.m_sTitle;
m_bObjectIsNewlyCreated = selSrc.m_bObjectIsNewlyCreated;
m_bIsClass = selSrc.m_bIsClass;
m_bClassIsSingleton = selSrc.m_bClassIsSingleton;
m_bSingletonHasInstance = selSrc.m_bSingletonHasInstance;
return *this;
}
IWbemServices* CSelection::GetHmmServices()
{
if (m_phmm == NULL) {
ConnectServer();
}
return m_phmm;
}
//**************************************************************
// CSelection::SingletonHasInstance
//
// Assuming that the current class is a singleton, check to see
// whether or not an instance already exisits.
//
// Parameters:
//
// Returns:
// TRUE if the singleton instance exists, FALSE if the singleton
// instance does not exist or a failure occurred.
//
//****************************************************************
BOOL CSelection::SingletonHasInstance()
{
if (!m_bIsClass) {
return FALSE;
}
COleVariant varClass;
SCODE sc = ClassFromPath(varClass, m_varPath.bstrVal);
if (FAILED(sc) || varClass.vt != VT_BSTR) {
return FALSE;
}
CString sPath;
sPath = varClass.bstrVal;
sPath += _T("=@");
BSTR bstrInstancePath = sPath.AllocSysString();
IWbemClassObject* pcoSingleton = NULL;
HRESULT hr = m_phmm->GetObject(bstrInstancePath, 0, NULL, &pcoSingleton, NULL);
::SysFreeString(bstrInstancePath);
sc = GetScode(hr);
if (SUCCEEDED(sc)) {
pcoSingleton->Release();
return TRUE;
}
return FALSE;
}
//*************************************************************
// CHmmvCtrl::ObjectIsClass
//
// Check to see whether or not an HMOM object is a class or
// an instance.
//
// Parameters:
// IWbemClassObject* pco
// Pointer to the HMOM object to examine.
//
// Returns:
// BOOL
// TRUE if the object is a class, FALSE otherwise.
//
//***********************************************************
BOOL CSelection::IsClass(IWbemClassObject* pco)
{
COleVariant varGenus;
CBSTR bsPropname;
bsPropname = _T("__GENUS");
SCODE sc = pco->Get((BSTR) bsPropname, 0, &varGenus, NULL, NULL);
ASSERT(SUCCEEDED(sc));
ASSERT(varGenus.vt == VT_I4);
if (varGenus.vt == VT_NULL) {
return FALSE;
}
else {
varGenus.ChangeType(VT_I4);
return varGenus.lVal == 1;
}
}
//******************************************************************
// CSelection::GetObjectFromPath
//
//
// Parameters:
// [in] BOOL bRestoringContext
// TRUE this method is invoked while trying to restore
// a context in the view context stack. This makes it possible
// to suppress errors when the object is not found.
//
// Returns:
// SCODE
// S_OK if the jump was completed, a failure code otherwise.
//
//******************************************************************
SCODE CSelection::GetObjectFromPath(BOOL bRestoringContext)
{
if (m_phmm == NULL) {
Clear();
return E_FAIL;
}
if (m_pco != NULL) {
m_pco->Release();
m_pco = NULL;
}
m_bObjectIsNewlyCreated = FALSE;
if (m_sPath.IsEmpty()) {
Clear();
return S_OK;
}
// Get the new object from HMOM
IWbemClassObject* pco = NULL;
SCODE sc;
CString sPath;
sPath = m_varPath.bstrVal;
TRACE(_T("CSelection::GetObjectFromPath sPath = %s\n"), sPath);
sc = m_phmm->GetObject(m_varPath.bstrVal, WBEM_FLAG_USE_AMENDED_QUALIFIERS, NULL, &m_pco, NULL);
if (FAILED(sc)) {
if ((sc = WBEM_E_NOT_FOUND) && bRestoringContext) {
return sc;
}
else {
CString sError(MAKEINTRESOURCE(IDS_ERR_INVALID_OBJECT_PATH));
TCHAR szMessage[MAX_STRING];
_stprintf(szMessage, (LPCTSTR) sError, (LPCTSTR) m_sPath);
HmmvErrorMsgStr(szMessage, sc, TRUE, NULL, _T(__FILE__), __LINE__);
Clear(FALSE);
return sc;
}
}
GetObjectDescription();
return sc;
}
//***************************************************************
// CSelection::SpawnInstance
//
// Create an instance of the specified class. This CSelection object
// will correspond to the new instance when sucessful.
//
// Parameters:
// [in] LPCTSTR pszClass
// The path to the new instance's class.
//
// [in] BOOL bPartialPath
// TRUE if the path consists of only the classname and does
// not contain the server and namespace, etc. When TRUE, it is
// assumed that the current server and namespace will be used.
//
// Returns:
// S_OK if the instance was created successfully, a failure code
// otherwise.
//
//*********************************************************************
SCODE CSelection::SpawnInstance(LPCTSTR pszClass, BOOL bPartialPath)
{
// First get the class so that we can use it to spawn
// an instance. This is done using a copy of the
// current CSelection object so that the current state
// of this CSelection is not trashed if things should
// fail.
CSelection* pselClass = new CSelection(m_phmmv);
*pselClass = *this;
SCODE sc;
sc = pselClass->SelectPath(pszClass, bPartialPath, FALSE);
if (FAILED(sc)) {
delete pselClass;
return sc;
}
// Spawn the instance and discard the CSelection for the class since
// the only thing we really wanted was the new instance anyway.
IWbemClassObject* pcoInst = NULL;
sc = pselClass->m_pco->SpawnInstance(0, &pcoInst);
if (FAILED(sc)) {
delete pselClass;
switch(sc) {
case WBEM_E_INCOMPLETE_CLASS:
HmmvErrorMsg(IDS_ERR_CREATE_INCOMPLETE_CLASS, sc, FALSE, NULL, _T(__FILE__), __LINE__);
break;
default:
HmmvErrorMsg(IDS_ERR_CREATE_INSTANCE_FAILED, sc, FALSE, NULL, _T(__FILE__), __LINE__);
break;
}
return sc;
}
// Copy the class selection to get its services pointer.
*this = *pselClass;
delete pselClass;
// Control comes here if we've sucessfully spawned the desired instance of
// the class. Now we need to make the current object point to this instance
// while retaining the HMM services pointer.
Clear(FALSE);
m_pco = pcoInst;
m_bObjectIsNewlyCreated = TRUE;
GetObjectDescription();
return S_OK;
}
//***************************************************************
// CSelection::SpawnInstance
//
// Create an instance of the specified class.
//
// Parameters:
// [out] CSelection** ppselDst
// A pointer to the selection object for the newly created
// instance is returned here.
//
// Returns:
// S_OK if the instance was created successfully, a failure code
// otherwise.
//
//*********************************************************************
SCODE CSelection::SpawnInstance(CSelection** ppselDst)
{
*ppselDst = NULL;
/*
#if 0
if (!m_bIsClass) {
return E_FAIL;
}
#endif //0
*/
CSelection* pselDst = new CSelection(m_phmmv);
pselDst->SetHmmServices(m_phmm);
SCODE sc;
sc = m_pco->SpawnInstance(0, &pselDst->m_pco);
if (FAILED(sc)) {
pselDst->m_pco = NULL;
switch(sc) {
case WBEM_E_INCOMPLETE_CLASS:
HmmvErrorMsg(IDS_ERR_CREATE_INCOMPLETE_CLASS, sc, FALSE, NULL, _T(__FILE__), __LINE__);
break;
default:
HmmvErrorMsg(IDS_ERR_CREATE_INSTANCE_FAILED, sc, FALSE, NULL, _T(__FILE__), __LINE__);
break;
}
delete pselDst;
return sc;
}
pselDst->m_bObjectIsNewlyCreated = TRUE;
pselDst->GetObjectDescription();
*ppselDst = pselDst;
return S_OK;
}
/*
#if 0
SCODE CSelection::SpawnInstanceOfClass(LPCTSTR pszClass)
{
return S_OK;
}
#endif //0
*/
SCODE CSelection::GetObjectDescription()
{
if (m_pco == NULL) {
return E_FAIL;
}
// Get the value of m_sClass
COleVariant varClass;
CBSTR bsPropname;
bsPropname = _T("__CLASS");
SCODE sc = m_pco->Get((BSTR) bsPropname, 0, &varClass, NULL, NULL);
ASSERT(SUCCEEDED(sc));
if (SUCCEEDED(sc)) {
m_sClass = varClass.bstrVal;
}
else {
m_sClass = _T("");
}
// Set the value of m_bIsclass;
COleVariant varGenus;
bsPropname = _T("__GENUS");
sc = m_pco->Get((BSTR) bsPropname, 0, &varGenus, NULL, NULL);
ASSERT(SUCCEEDED(sc));
ASSERT(varGenus.vt == VT_I4);
m_bIsClass = FALSE;
if (SUCCEEDED(sc) && (varGenus.vt==VT_I4)) {
varGenus.ChangeType(VT_I4);
m_bIsClass = (varGenus.lVal == 1);
}
// Set the Singleton flags.
if (m_bIsClass) {
m_bSingletonHasInstance = FALSE;
CBSTR bsPropname;
bsPropname = _T("Singleton");
m_bClassIsSingleton = GetBoolClassQualifier(sc, m_pco, (BSTR) bsPropname);
if (FAILED(sc)) {
m_bClassIsSingleton = FALSE;
}
if (m_bClassIsSingleton && (m_phmm!=NULL)) {
CString sSingletonPath;
sSingletonPath = m_sClass + _T("=@");
BSTR bstrSingletonPath = sSingletonPath.AllocSysString();
IWbemClassObject* pcoSingleton = NULL;
HRESULT hr = m_phmm->GetObject(bstrSingletonPath, WBEM_FLAG_USE_AMENDED_QUALIFIERS, NULL, &pcoSingleton, NULL);
::SysFreeString(bstrSingletonPath);
sc = GetScode(hr);
if (SUCCEEDED(sc)) {
pcoSingleton->Release();
m_bSingletonHasInstance = TRUE;
}
}
}
// Get the title of the current object
if (m_bObjectIsNewlyCreated) {
CBSTR bsClass(m_sClass);
m_sTitle.LoadString(IDS_NEW_INSTANCE_NAME_PREFIX);
m_sTitle += _T(" ");
m_sTitle = m_sTitle + m_sClass;
}
else {
COleVariant varTitle;
GetLabelFromPath(varTitle, m_varPath.bstrVal);
m_sTitle = varTitle.bstrVal;
}
return sc;
}
//*************************************************************
// CSelection::DeleteInstance
//
// Delete the selected instance.
//
// Parameters:
// None.
//
// Returns:
// Nothing.
//
//*************************************************************
SCODE CSelection::DeleteInstance()
{
if ((m_pco == NULL) || m_bIsClass || m_bIsEmbeddedObject) {
return E_FAIL;
}
SCODE sc = S_OK;
if (!m_bObjectIsNewlyCreated) {
sc = m_phmm->DeleteInstance(m_varPath.bstrVal, 0, NULL, NULL);
if (FAILED(sc)) {
// Failed to delete instance.
CString sFormat;
TCHAR szMessage[MAX_STRING];
sFormat.LoadString(IDS_ERR_DELETE_INSTANCE);
_stprintf(szMessage, (LPCTSTR) sFormat, (LPCTSTR) m_sTitle);
HmmvErrorMsgStr(szMessage, S_OK, TRUE, NULL, _T(__FILE__), __LINE__);
return E_FAIL;
}
}
m_pco->Release();
m_pco = NULL;
m_sPath.Empty();
m_varPath.Clear();
m_sClass.Empty();
m_sTitle.Empty();
return S_OK;
}
/*
#if 0
IWbemServices *CMultiViewCtrl::GetIWbemServices
(CString &rcsNamespace)
{
IUnknown *pServices = NULL;
BOOL bUpdatePointer= FALSE;
m_sc = S_OK;
m_bUserCancel = FALSE;
VARIANT varUpdatePointer;
VariantInit(&varUpdatePointer);
varUpdatePointer.vt = VT_I4;
if (bUpdatePointer == TRUE)
{
varUpdatePointer.lVal = 1;
}
else
{
varUpdatePointer.lVal = 0;
}
VARIANT varService;
VariantInit(&varService);
VARIANT varSC;
VariantInit(&varSC);
VARIANT varUserCancel;
VariantInit(&varUserCancel);
FireGetIWbemServices
((LPCTSTR)rcsNamespace, &varUpdatePointer, &varService, &varSC,
&varUserCancel);
if (varService.vt & VT_UNKNOWN)
{
pServices = reinterpret_cast<IWbemServices*>(varService.punkVal);
}
varService.punkVal = NULL;
VariantClear(&varService);
if (varSC.vt & VT_I4)
{
m_sc = varSC.lVal;
}
VariantClear(&varSC);
if (varUserCancel.vt & VT_BOOL)
{
m_bUserCancel = varUserCancel.boolVal;
}
VariantClear(&varUserCancel);
VariantClear(&varUpdatePointer);
IWbemServices *pRealServices = NULL;
if (m_sc == S_OK && !m_bUserCancel)
{
pRealServices = reinterpret_cast<IWbemServices *>(pServices);
}
return pRealServices;
}
#endif //0
*/
//*****************************************************************
// CSelection::SplitServerAndNamespace
//
// Given the namespace string passed in by the user, attempt to split
// the server name from the rest of the namespace.
//
// Normally ConnectServer gets the server and namespace from the object
// path, but when embedded objects are used, the namespace may be used
// to connect to the server since embedded objects have no path.
//
// Parameters:
// [out] COleVariant& varServer
// The server name is returned here.
//
// [out] COleVariant& varNamespace
// The namespace is returned here.
//
// [in] BSTR bstrNamespace
// The namespace string passed into the singleview control via
// the namespace automation property.
//
//
// Returns:
// SCODE
// S_OK if successful, otherwise E_FAIL. A failure code is returned
// if both a server and namespace couldn't be split out from the
// user's namespace string.
//
//******************************************************************
SCODE CSelection::SplitServerAndNamespace(COleVariant& varServer, COleVariant& varNamespace, BSTR bstrNamespace)
{
if (bstrNamespace[0] != '\\') {
return E_FAIL;
}
if (bstrNamespace[1] != '\\') {
return E_FAIL;
}
bstrNamespace += 2;
CString sNamespace;
sNamespace = bstrNamespace;
LPTSTR psz = sNamespace.GetBuffer(sNamespace.GetLength());
// Put a null just after the next backslash to mark the end of the
// server name. After this is done, the contents of the buffer can
// be treated as two strings. The first one is the server name and
// the second one is the namespace with the server prefix removed.
CString sServer;
while (*psz != '\\') {
++psz;
}
*psz = 0;
++psz;
varServer = sNamespace;
varNamespace = psz;
sServer.ReleaseBuffer();
return S_OK;
}
//*****************************************************************
// CSelection::ConnectServer
//
// Call this method to connect to the HMOM Server.
//
// Parameters:
// None.
//
// Returns:
// SCODE
// S_OK if successful, otherwise the HMOM status code.
//
//******************************************************************
SCODE CSelection::ConnectServer()
{
// Currently a fully qualified path must be specified.
COleVariant varServer;
COleVariant varNamespace;
SCODE sc;
sc = ServerAndNamespaceFromPath(varServer, varNamespace, m_varPath.bstrVal);
if (FAILED(sc)) {
if (m_varPath.vt==VT_BSTR && *m_varPath.bstrVal=='\\') {
// A fully specified path was given, but was in error.
return E_FAIL;
}
varServer.Clear();
varNamespace.Clear();
// Attempt to use the m_varNamespace value to get the server and namespace
if (m_varNamespace.vt != VT_BSTR) {
return E_FAIL;
}
if (*m_varNamespace.bstrVal != '\\') {
varNamespace = m_varNamespace;
}
else {
sc = SplitServerAndNamespace(varServer, varNamespace, m_varNamespace.bstrVal);
if (FAILED(sc)) {
return E_FAIL;
}
}
}
if (varServer.vt == VT_NULL || varServer.bstrVal ==NULL) {
varServer = ".";
}
if (varNamespace.vt == VT_NULL || varNamespace.bstrVal == NULL) {
if (m_varNamespace.vt == VT_NULL || m_varNamespace.bstrVal == NULL) {
return E_FAIL;
}
varNamespace = m_varNamespace;
}
// Release the current provider if we are already connected.
if (m_phmm != NULL) {
if (IsEqual(m_varServerConnect.bstrVal, varServer.bstrVal)) {
if (IsEqual(m_varNamespaceConnect.bstrVal, varNamespace.bstrVal)) {
// Already connected to the same server and namespace.
return S_OK;
}
}
m_phmm->Release();
m_phmm = NULL;
m_varNamespaceConnect.Clear();
m_varServerConnect.Clear();
}
m_varServerConnect = varServer;
m_varNamespaceConnect = varNamespace;
if (m_varNamespace.vt==VT_BSTR && *m_varNamespace.bstrVal == 0) {
m_varNamespace = m_varNamespaceConnect;
}
// varServer = L"root\\default";
CString sServicesPath;
sServicesPath = "\\\\";
sServicesPath += varServer.bstrVal;
if (*varNamespace.bstrVal) {
sServicesPath += "\\";
sServicesPath += varNamespace.bstrVal;
}
COleVariant varUpdatePointer;
COleVariant varService;
COleVariant varSC;
COleVariant varUserCancel;
varUpdatePointer.ChangeType(VT_I4);
varUpdatePointer.lVal = FALSE;
m_phmmv->GetWbemServices((LPCTSTR) sServicesPath, &varUpdatePointer, &varService, &varSC, &varUserCancel);
sc = E_FAIL;
if (varSC.vt & VT_I4)
{
sc = varSC.lVal;
}
BOOL bCanceled = FALSE;
if (varUserCancel.vt & VT_BOOL)
{
bCanceled = varUserCancel.boolVal;
}
if ((sc == S_OK) &&
!bCanceled &&
(varService.vt & VT_UNKNOWN)){
m_phmm = reinterpret_cast<IWbemServices*>(varService.punkVal);
}
varService.punkVal = NULL;
VariantClear(&varService);
return sc;
}
void CSelection::SetHmmServices(IWbemServices* phmm)
{
Clear();
m_phmm = phmm;
phmm->AddRef();
}
//************************************************************
// CSelection::UseClonedObject
//
// Call this method when it is desired to make a clone of an
// HMOM class object be the current "edited" version of the
// object.
//
// Parameters:
// IWbemClassObject* pcoClone
// Pointer to a clone of the current object that will become
// the new "current object".
//
// Returns:
// Nothing.
//
//*************************************************************
void CSelection::UseClonedObject(IWbemClassObject* pcoClone)
{
if (m_pco) {
m_pco->Release();
}
pcoClone->AddRef();
m_pco = pcoClone;
}
//**************************************************************
// CSelection::PathInCurrentNamespace
//
// Given a path, check to see if it lives in the current namespace.
//
// Parameters:
// [in] BSTR bstrPath
// The path to check.
//
// Returns:
// BOOL
// TRUE if the path is in the current namespace.
//
//**************************************************************
BOOL CSelection::PathInCurrentNamespace(BSTR bstrPath)
{
if (m_bIsEmbeddedObject) {
ASSERT(FALSE);
return FALSE;
}
BOOL bInSameNamespace = InSameNamespace(m_varNamespace.bstrVal, bstrPath);
return bInSameNamespace;
}
//********************************************************************
// CSelection::IsCurrentNamespace
//
// Check to see if the given server and namespace match the current
// namespace of the container.
//
// Parameters:
// [in] BSTR bstrServer
// The server name.
//
// [in] BSTR bstrNamespace
// The namespace.
//
// Returns:
// BOOL
// TRUE if the given server and namespace match the container's
// idea of the current namespace.
//
//********************************************************************
BOOL CSelection::IsCurrentNamespace(BSTR bstrServer, BSTR bstrNamespace)
{
if (m_bIsEmbeddedObject) {
ASSERT(FALSE);
return FALSE;
}
// Ignore the server since we don't have a good way to compare
// servers.
if (bstrNamespace == NULL) {
// Relative paths are assumed to reside in the same namespace.
return TRUE;
}
WCHAR ch1 = 0;
WCHAR ch2 = 0;
BSTR bstrCur = m_varNamespace.bstrVal;
while(TRUE) {
ch1 = *bstrNamespace++;
ch2 = *bstrCur++;
ch1 = towupper(ch1);
ch2 = towupper(ch2);
if ((ch1==0) || (ch1 != ch2)) {
break;
}
}
if (ch1==0 && ch2==0) {
return TRUE;
}
else {
return FALSE;
}
}
/*
#if 0
void GetPath(IWbemClassObject* pco)
{
CString sPath;
if (pco != NULL) {
// Get the full path to the object
CBSTR bsPropname;
bsPropname = "__RELPATH";
COleVariant varPath;
SCODE sc = pco->Get((BSTR) bsPropname, 0, &varPath, NULL, NULL);
ASSERT(SUCCEEDED(sc));
if (SUCCEEDED(sc)) {
sPath = varPath.bstrVal;
}
}
}
#endif //0
*/
SCODE CSelection::SaveClassObject()
{
if (m_pco == NULL) {
return E_FAIL;
}
SCODE sc;
IWbemCallResult* pResult = NULL;
if (m_bIsClass) {
sc = m_phmm->PutClass(m_pco, WBEM_FLAG_USE_AMENDED_QUALIFIERS, NULL, NULL);
}
else {
if (IsEmbeddedObject()) {
return S_OK;
}
if (m_bObjectIsNewlyCreated) {
sc = m_phmm->PutInstance(m_pco,
WBEM_FLAG_USE_AMENDED_QUALIFIERS | WBEM_FLAG_CREATE_ONLY,
NULL, &pResult);
if (sc == WBEM_E_ALREADY_EXISTS) {
TCHAR szMessage[MAX_STRING];
CString sFormat;
sFormat.LoadString(IDS_QUERY_REPLACE_OBJECT);
_stprintf(szMessage, (LPCTSTR) sFormat, (LPCTSTR) m_sTitle);
int iMsgBoxStatus = HmmvMessageBox(m_phmmv, szMessage, MB_YESNO | MB_SETFOREGROUND);
switch(iMsgBoxStatus) {
case IDYES:
sc = m_phmm->PutInstance(m_pco, WBEM_FLAG_USE_AMENDED_QUALIFIERS, NULL, NULL);
break;
case IDNO:
return S_OK;
break;
case IDCANCEL:
return E_FAIL;
}
}
}
else {
sc = m_phmm->PutInstance(m_pco, WBEM_FLAG_USE_AMENDED_QUALIFIERS, NULL, &pResult);
if (FAILED(sc)) {
pResult = NULL;
}
}
}
if (SUCCEEDED(sc)) {
CBSTR bsPropname;
// The "__PATH" property will only be defined if we "get" the
// object from the database after doing a PutInstance on it.
// Thus, we will get the object from the database now and the
// new copy will replace m_pco.
bsPropname = _T("__RELPATH");
COleVariant varRelpath;
if (pResult && m_bObjectIsNewlyCreated) {
pResult->GetResultString(0, &varRelpath.bstrVal);
pResult->Release();
pResult = NULL;
if ((varRelpath.bstrVal == NULL) || (varRelpath.bstrVal[0]==0)) {
sc = m_pco->Get((BSTR) bsPropname, 0, &varRelpath, NULL, NULL);
}
else {
varRelpath.vt = VT_BSTR;
}
sc = S_OK;
}
else {
sc = m_pco->Get((BSTR) bsPropname, 0, &varRelpath, NULL, NULL);
}
if (SUCCEEDED(sc)) {
// Get the new object from HMOM
IWbemClassObject* pcoNew = NULL;
CString sRelpath;
SCODE sc;
sc = m_phmm->GetObject(varRelpath.bstrVal, WBEM_FLAG_USE_AMENDED_QUALIFIERS, NULL, &pcoNew, NULL);
if (FAILED(sc)) {
CString sError(MAKEINTRESOURCE(IDS_ERR_INVALID_OBJECT_PATH));
TCHAR szMessage[MAX_STRING];
sRelpath = varRelpath.bstrVal;
_stprintf(szMessage, (LPCTSTR) sError, (LPCTSTR) sRelpath);
HmmvErrorMsgStr(szMessage, sc, TRUE, NULL, _T(__FILE__), __LINE__);
}
else {
m_pco->Release();
m_pco = pcoNew;
}
}
if (!m_bIsClass) {
bsPropname = _T("__PATH");
sc = m_pco->Get((BSTR) bsPropname,0, &m_varPath, NULL, NULL);
m_sPath = m_varPath.bstrVal;
if (m_bObjectIsNewlyCreated) {
// Update the title here.
COleVariant varTitle;
GetLabelFromPath(varTitle, m_varPath.bstrVal);
m_sTitle = varTitle.bstrVal;
}
}
m_bObjectIsNewlyCreated = FALSE;
}
else {
HmmvErrorMsg(IDS_ERR_OBJECT_UPDATE_FAILED, sc, TRUE, NULL, _T(__FILE__), __LINE__);
// Returning failure causes the save to be canceled.
return E_FAIL;
}
return S_OK;
}
BOOL CSelection::IsEmbeddedObject()
{
return m_bIsEmbeddedObject;
/*
#if 0
BOOL bHasServer = FALSE;
BOOL bHasNamespace = FALSE;
COleVariant varValue;
CIMTYPE cimtype;
CBSTR bsPropName;
bsPropName = "__SERVER";
SCODE sc = m_pco->Get((BSTR) bsPropName, 0, &varValue, &cimtype, NULL);
if (SUCCEEDED(sc) && (varValue.vt == VT_BSTR)) {
if (!IsEmptyString(varValue.bstrVal)) {
bHasServer = TRUE;
}
}
varValue.Clear();
bsPropName = "__NAMESPACE";
sc = m_pco->Get((BSTR) bsPropName, 0, &varValue, &cimtype, NULL);
if (SUCCEEDED(sc) && (varValue.vt == VT_BSTR)) {
if (!IsEmptyString(varValue.bstrVal)) {
bHasNamespace = TRUE;
}
}
varValue.Clear();
BOOL bIsEmbeddedInstance;
bIsEmbeddedInstance = !bHasServer && !bHasNamespace;
return bIsEmbeddedInstance ;
#endif //0
*/
}
BOOL CSelection::ClassObjectNeedsAssocTab()
{
if (m_pco == NULL) {
return FALSE;
}
if (m_bIsClass) {
return TRUE;
}
BOOL bIsEmbeddedInstance = IsEmbeddedObject();
return !bIsEmbeddedInstance;
}
BOOL CSelection::ClassObjectNeedsMethodsTab()
{
if (m_pco == NULL) {
return FALSE;
}
BOOL bIsEmbeddedObject = IsEmbeddedObject();
return !bIsEmbeddedObject;
}
SCODE CSelection::Refresh()
{
SCODE sc = S_OK;
if (m_bIsEmbeddedObject) {
return E_FAIL;
}
if (m_sPath.IsEmpty()) {
return E_FAIL;
}
CString sPath;
sPath = m_sPath;
sc = SelectPath(sPath);
return sc;
}
BOOL CSelection::ClassExists(LPCTSTR pszClass)
{
BOOL bClassExists = FALSE;
COleVariant varClass;
varClass = pszClass;
IWbemClassObject* pco = NULL;
SCODE sc;
sc = m_phmm->GetObject(varClass.bstrVal, 0, NULL, &pco, NULL);
if (SUCCEEDED(sc)) {
bClassExists = TRUE;
pco->Release();
}
return bClassExists;
}