// Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved #include "precomp.h" #include "resource.h" #include "path.h" #include "icon.h" #include "hmomutil.h" #include "hmmverr.h" #include "utils.h" #include "SingleViewCtl.h" #include "globals.h" #define MAX_STRING 1024 CSelection::CSelection(CSingleViewCtrl* psv) { m_psv = psv; m_phmm = NULL; m_pco = NULL; m_ppict = NULL; Clear(); } CSelection::~CSelection() { if (m_pco) { m_pco->Release(); } if (m_phmm) { m_phmm->Release(); } delete m_ppict; } 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; } //*********************************************************** // CSelection::IsNamespaceLocalized() // // Localized namespace names start with "ms_" prefix. // We will assume that any namespace with such a prefix is localized: // there seems to be no really reliable way to tell :( // //*********************************************************** BOOL CSelection::IsNamespaceLocalized() { ASSERT (m_varNamespace.vt == VT_BSTR); CString tempNS = m_varNamespace.bstrVal; //find last backslash int lastBksl = tempNS.ReverseFind('\\'); if (lastBksl == -1) { //not found return FALSE; } //look at the part after the last backslash tempNS = tempNS.Right(tempNS.GetLength() - lastBksl - 1); CString prefix = tempNS.Left(3); if (!prefix.CompareNoCase(_T("ms_"))) { return TRUE; } else { return FALSE; } } 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""; } if (m_ppict) { delete m_ppict; m_ppict = NULL; } m_ppict = new CPictureHolder; m_ppict->CreateEmpty(); m_picon = NULL; m_sPath = ""; m_varPath = L""; m_sc = S_OK; m_sClass = ""; m_sTitle = ""; m_bClassIsSingleton = FALSE; m_bSingletonHasInstance = FALSE; m_bCanCreateInstance = FALSE; m_bCanDeleteInstance = 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; } //****************************************************** // 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_psv); *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; } UpdateCreateDeleteFlags(); 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; } UpdateCreateDeleteFlags(); 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_psv = selSrc.m_psv; 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_picon = selSrc.m_picon; if (m_picon) { delete m_ppict; m_ppict = new CPictureHolder; HICON hIcon = (HICON) *m_picon; BOOL bDidCreatePicture = m_ppict->CreateFromIcon(hIcon); } 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; m_bCanCreateInstance = selSrc.m_bCanCreateInstance; m_bCanDeleteInstance = selSrc.m_bCanDeleteInstance; 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; 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_psv); *pselClass = *this; SCODE sc; sc = pselClass->SelectPath(pszClass, bPartialPath, FALSE); if (FAILED(sc)) { delete pselClass; return sc; } if (!pselClass->m_bCanCreateInstance) { delete pselClass; return E_FAIL; } // 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_psv); 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; } } } BOOL bDidCreatePicture = FALSE; // Get the title of the current object CIconSource* pIconSource = m_psv->IconSource(); if (m_bObjectIsNewlyCreated) { CBSTR bsClass(m_sClass); m_picon = &pIconSource->LoadIcon((BSTR) bsClass, SMALL_ICON, FALSE); m_sTitle.LoadString(IDS_NEW_INSTANCE_NAME_PREFIX); m_sTitle += _T(" "); m_sTitle = m_sTitle + m_sClass; } else { m_picon = &pIconSource->LoadIcon(m_phmm, m_varPath.bstrVal, SMALL_ICON, m_bIsClass); COleVariant varTitle; GetLabelFromPath(varTitle, m_varPath.bstrVal); m_sTitle = varTitle.bstrVal; } HICON hIcon; hIcon = (HICON) *m_picon; delete m_ppict; m_ppict = new CPictureHolder; bDidCreatePicture = m_ppict->CreateFromIcon(hIcon); return sc; } LPPICTUREDISP CSelection::GetPictureDispatch() { return m_ppict->GetPictureDispatch(); } //************************************************************* // 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(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(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::GetWbemServicesForEmbeddedObject // // Get the WBEM services pointer for an embedded object. // // Paramters: // None. // // Returns: // IWbemServices* // The WBEM services pointer or NULL if one could not be // gotten. // //***************************************************************** IWbemServices* CSelection::GetWbemServicesForEmbeddedObject() { IWbemServices* psvc = GetHmmServices(); if (psvc != NULL) { // If we already have a services pointer, use it. return psvc; } // This instance of the SingleView control does not have a // services pointer. This means that the current instance // is editing an embedded object property in another instance // of the SingleView control, so propagate the request on up // a level in an attempt to find the services pointer from // an instance of the SingleView control that is higher up // in the hierarchy. The namespace path will be empty to // indicate that we want the services pointer for an embedded // object. COleVariant varUpdatePointer; COleVariant varService; COleVariant varSC; COleVariant varUserCancel; varUpdatePointer.ChangeType(VT_I4); varUpdatePointer.lVal = FALSE; CString sServicesPath; m_psv->GetWbemServices((LPCTSTR) sServicesPath, &varUpdatePointer, &varService, &varSC, &varUserCancel); SCODE sc = E_FAIL; if (varSC.vt & VT_I4) { sc = varSC.lVal; } BOOL bCanceled = FALSE; if (varUserCancel.vt & VT_BOOL) { bCanceled = varUserCancel.boolVal; } IWbemServices* phmm = NULL; if ((sc == S_OK) && !bCanceled && (varService.vt & VT_UNKNOWN)){ phmm = reinterpret_cast(varService.punkVal); } varService.punkVal = NULL; VariantClear(&varService); return phmm; } //***************************************************************** // 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_psv->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(varService.punkVal); } varService.punkVal = NULL; VariantClear(&varService); return sc; } void CSelection::UpdateCreateDeleteFlags() { BOOL bCanCreateT = m_bCanCreateInstance; BOOL bCanDeleteT = m_bCanDeleteInstance; m_bCanCreateInstance = FALSE; m_bCanDeleteInstance = FALSE; BOOL bClassIsAbstract = FALSE; BOOL bObjectIsClass = FALSE; BOOL bClassIsSingleton = FALSE; BOOL bSingletonHasInstance = FALSE; SCODE sc; if ((m_pco != NULL) && !m_bIsEmbeddedObject) { CBSTR bsQualName; bsQualName = _T("Singleton"); bClassIsSingleton = GetBoolClassQualifier(sc, m_pco, (BSTR) bsQualName); if (FAILED(sc)) { bClassIsSingleton = FALSE; } if (m_psv->CanEdit()) { bObjectIsClass = IsClass(m_pco); if (bObjectIsClass) { bClassIsAbstract = ClassIsAbstract(sc, m_pco); ASSERT(SUCCEEDED(sc)); if (bClassIsSingleton) { bSingletonHasInstance = SingletonHasInstance(); } } m_bCanCreateInstance = m_pco!=NULL /* && bObjectIsClass */ && !bClassIsAbstract; m_bCanDeleteInstance = m_pco!=NULL && !bObjectIsClass; if (bObjectIsClass && bClassIsSingleton) { if (bSingletonHasInstance) { m_bCanCreateInstance = FALSE; } else { m_bCanCreateInstance = TRUE; } } } } if (!bObjectIsClass) { if (bClassIsSingleton) { m_bCanCreateInstance = FALSE; } } if ((bCanCreateT != m_bCanCreateInstance) || (bCanDeleteT != m_bCanDeleteInstance)) { // Notify the view that a change occurred so that the create/delete // buttons can be updated. m_psv->NotifyViewModified(); } } 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_CREATE_ONLY | WBEM_FLAG_USE_AMENDED_QUALIFIERS, 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(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; }