bool CNewComm::DoDynamicDiscovery(bool bDoGUI, CString * pcsOut) //DR00161 { bool bSoFarSoGood = true; HRESULT hr; IEnumCLSID* pIEnumCLSID = NULL; GUID CATID_ThisCategory[1]; int iNumberDiscovered = 0; int iClassFactoryIndex = 0; // Create the standard COM Category manager. if (bSoFarSoGood) { hr = ::CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_ALL, IID_ICatInformation, (void**)&m_pICatInformation) ; if (FAILED(hr)) { if (bDoGUI) AfxMessageBox("Could not create component category manager.") ; bSoFarSoGood = false; } } // Get the Category Registration interface. if (bSoFarSoGood) { hr = m_pICatInformation->QueryInterface(IID_ICatRegister, (void**)&m_pICatRegister); if (FAILED(hr)) { if (bDoGUI) AfxMessageBox("Attempt to query for ICatRegister failed."); bSoFarSoGood = false; } } //Ensure the MIC communications category has been established properly. if (bSoFarSoGood) { bool bGoodCategoryRegistration = TestRegistrationOfComponentCategory(); if (!bGoodCategoryRegistration) { if (bDoGUI) AfxMessageBox("Problem with MIC_CSO component category registration."); bSoFarSoGood = false; } } // Get the component CLSID enumerator for the MIC_CSO category if (bSoFarSoGood) { CATID_ThisCategory[0] = MIC_CSO_CATID; hr = m_pICatInformation->EnumClassesOfCategories( 1,CATID_ThisCategory,0,NULL,&pIEnumCLSID); if (FAILED(hr)) { if (bDoGUI) AfxMessageBox("ListCategoryMembers: EnumClassesOfCategories failed.") ; bSoFarSoGood = false; } } // Get the array of CLSID's in this MIC_CSO category if (bSoFarSoGood) { iNumberDiscovered = 0; for (iClassFactoryIndex = 0; iClassFactoryIndex < MAX_CLSIDS; iClassFactoryIndex++) { // Get the CLSID of the next component that is a member of this category. hr = pIEnumCLSID->Next( 1, &m_CLSID[iClassFactoryIndex], NULL); if (hr == S_OK) { //Get the class factory for this component CoGetClassObject( m_CLSID[iClassFactoryIndex],//CLSID associated with the class object CLSCTX_INPROC_SERVER, //In-process server NULL, //Instantiate class object on this machine. IID_IClassFactory, //Interface we are looking for (LPVOID *)&m_pClassFactory[iClassFactoryIndex]); //pointer to the interface //if this class factory fetching failed, process the failure //DR00199 if (m_pClassFactory[iClassFactoryIndex] == NULL) { char namestring[256]; //dgp 24 Oct 2006 GetFriendlyName(m_CLSID[iClassFactoryIndex], namestring, sizeof(namestring)); //dgp 24 Oct 2006 memset(&m_CLSID[iClassFactoryIndex], 0, sizeof(CLSID)); //get rid of the bad CLSID if (bDoGUI) { CString cs; cs.Format("CoGetClassObject fails for CSO component\nClass index: %d\n" //dgp 24 Oct 2006 "Class name: %s\n\n",iClassFactoryIndex,namestring); //dgp 24 Oct 2006 cs += m_csRegistrationAnomalyMessage; new CTimedMessageDialog( CString("MIC Setup Anomaly"), cs, g_iDlgCloseMillisec/1000); //seconds } } else { iNumberDiscovered++; } } //end if (hr == S_OK) } //end for MAX_CLSIDS if (0 == iNumberDiscovered) { if (bDoGUI) AfxMessageBox("Found NO component classes registered under category MIC_CSO."); bSoFarSoGood = false; } } //end sofarsogood //Instantiate a temporary object from each of the CSO component classes. //Get the type string from the object through its ICSO interface. //Display the type string in the pick list. //Destroy the temporary object. if (bSoFarSoGood) { if (bDoGUI) { BSTR bstrTypeString; char szTypeString[32]; for (int i = 0; i < MAX_CLSIDS; i++) { ASSERT(m_pTemporaryICSO == NULL); if (NULL != m_pClassFactory[i]) { hr = m_pClassFactory[i]->CreateInstance( NULL, IID_ICSO, (void **)&m_pTemporaryICSO); if (NULL != m_pTemporaryICSO) { hr = m_pTemporaryICSO->get_CSOTypeString(&bstrTypeString); Convert_BSTR_to_Character_String(bstrTypeString, szTypeString,32); ((CListBox*)GetDlgItem(IDC_COMMTYPE_LIST))->AddString(szTypeString); CleanUpTemporaryICSO(); } } } } else { BSTR bstrTypeString,bstrVersionString; char szTypeString[32],szVersionString[100]; CString csrn("\r\n"); CString cTab("\t"); if (pcsOut != NULL) pcsOut->Empty(); for (int i = 0; i < MAX_CLSIDS; i++) { ASSERT(m_pTemporaryICSO == NULL); if (NULL != m_pClassFactory[i]) { hr = m_pClassFactory[i]->CreateInstance( NULL, IID_ICSO, (void **)&m_pTemporaryICSO); if (NULL != m_pTemporaryICSO) { hr = m_pTemporaryICSO->get_CSOTypeString(&bstrTypeString); Convert_BSTR_to_Character_String(bstrTypeString, szTypeString,32); if (pcsOut) { hr = m_pTemporaryICSO->get_VersionString(&bstrVersionString); Convert_BSTR_to_Character_String(bstrVersionString, szVersionString,100); int l = 0; for (int k = 0; k < (signed)strlen(szVersionString); k++) { if (szVersionString[k] == ' ') { szVersionString[k] = '\t'; l++; if (l > 1) break; } } *pcsOut += (CString)szVersionString + csrn; } CleanUpTemporaryICSO(); } } } } } return bSoFarSoGood; }
HRESULT OPCEngine::unregisterServer(void) { _TRACE(TL_INF, TG_ENG, (_T("unregister server"))); HRESULT res; { ICatRegister *cr; ICatInformation *ci = NULL ; IEnumCLSID* enumCLSID = NULL ; CATID catIDs[2]; CLSID clsid ; if (SUCCEEDED(res = ::CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_ALL, IID_ICatRegister, (void **)&cr))) { // unregister server in categories catIDs[0] = CATID_OPCDAServer10; catIDs[1] = CATID_OPCDAServer20; res = cr->UnRegisterClassImplCategories(g_clsid, 2, catIDs); _TRACE(TL_INF, TG_ENG, (_T("unregister component implementations [0x%X]"), res)); // check if this server was the last in the category if (SUCCEEDED(res = cr->QueryInterface(IID_ICatInformation, (void**)&ci))) { // OPC DA Server V1.0A if (SUCCEEDED (res = ci->EnumClassesOfCategories(1, &catIDs[0], 0, NULL, &enumCLSID))) { res = enumCLSID->Next(1, &clsid, NULL) ; // if result is S_FALSE, there no components are in this category, so remove it. if (res == S_FALSE) { // unregister the component category res = cr->UnRegisterCategories(1, &catIDs[0]) ; _TRACE(TL_INF, TG_ENG, (_T("unregister DA V1.0A component category [0x%X]"), res)); } enumCLSID->Release(); } // OPC DA Server V2.0 if (SUCCEEDED (res = ci->EnumClassesOfCategories(1, &catIDs[1], 0, NULL, &enumCLSID))) { res = enumCLSID->Next(1, &clsid, NULL) ; // if result is S_FALSE, there no components are in this category, so remove it. if (res == S_FALSE) { // unregister the component category res = cr->UnRegisterCategories(1, &catIDs[1]) ; _TRACE(TL_INF, TG_ENG, (_T("unregister DA V2.0 component category [0x%X]"), res)); } enumCLSID->Release(); } ci->Release(); } cr->Release(); } CRegKey key, keyCLSID; DWORD ret; if (ret = keyCLSID.Open(HKEY_CLASSES_ROOT, _T("CLSID")) == ERROR_SUCCESS) { USES_CONVERSION; LPOLESTR wszClsid; LPTSTR clsid; StringFromCLSID(g_clsid, &wszClsid); clsid = W2T(wszClsid); CoTaskMemFree(wszClsid); if (ret = key.Open(keyCLSID, clsid) == ERROR_SUCCESS) { key.RecurseDeleteKey(_T("Implemented Categories")); key.Close(); } else res = HRESULT_FROM_WIN32(ret); keyCLSID.Close(); } else res = HRESULT_FROM_WIN32(ret); } // unregister COM Server object res = _Module.UnregisterServer(); return res; } // unregisterServer
// ************************************************************************** // DisplayComponentCatList () // // Description: // Construct a list of installed 1.0 and 2.0 OPC servers and insert into // tree control. // // Parameters: // HTREEITEM hParent Handle of parent tree control item. // CATID catid Catagory ID (CATID_OPCDAServer10 or // CATID_OPCDAServer20). // // Returns: // void // ************************************************************************** void CKServerGeneralPage::DisplayComponentCatList (HTREEITEM hParent, CATID catid) { HRESULT hr; // Make sure COM is initialized: hr = CoInitializeEx (NULL, COINIT_MULTITHREADED); if (SUCCEEDED (hr)) { ICatInformation *pCat = NULL; // Get component category manager: hr = CoCreateInstance (CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_SERVER, IID_ICatInformation, (void **)&pCat); // If succeeded, enumerate registered components: if (SUCCEEDED (hr)) { IEnumCLSID *pEnum = NULL; CATID arrcatid [1]; arrcatid [0] = catid; // Enumerate registered components based on clsid: hr = pCat->EnumClassesOfCategories ( sizeof (arrcatid) / sizeof (CATID), // number of catids in the array that follows arrcatid, // catid array 0, NULL, &pEnum); // clsid enumerator for registered components under this category // If succeeded, process results: if (SUCCEEDED (hr)) { GUID guid; ULONG fetched; // Loop over enumerated components. Call enemerator's next // member function to reference next component and get its // guid: while ((hr = pEnum->Next (1, &guid, &fetched)) == S_OK) { // Get the ProgID from the guid: WCHAR *wszProgID; hr = ProgIDFromCLSID (guid, &wszProgID); // If succeeded, add component to list: if (SUCCEEDED (hr)) { // ProgID string will be in UNICODE format. Convert to // ANSI format if this is and ANSI build. Insert component // into list: #ifdef _UNICODE m_pServerList->InsertItem (wszProgID, ILI_COMPONENT, ILI_COMPONENT, hParent); #else TCHAR szProgID [DEFBUFFSIZE]; _wcstombsz (szProgID, wszProgID, sizeof (szProgID) / sizeof (TCHAR)); m_pServerList->InsertItem (szProgID, ILI_COMPONENT, ILI_COMPONENT, hParent); #endif // It is up to us to free the Prog ID string memory: CoTaskMemFree (wszProgID); } } // Release our enumerator: pEnum->Release (); } // release our category mamager pCat->Release (); } // Uninitialize COM: CoUninitialize (); } }
void CPluginManager::EnumAllComponent() { HRESULT hr; ICatInformation* pCatInfo = NULL; hr = ::CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_ALL, IID_ICatInformation, (void**)&pCatInfo); if(FAILED(hr)) { return; } CATID IDs[1]; IDs[0] = CATID_Calc; IEnumCLSID *pIEnumCLSID = NULL; // Returns an enumerator for the component categories - "Calc" // that registered on the system hr = pCatInfo->EnumClassesOfCategories(1, IDs, 0, NULL, &pIEnumCLSID); if(FAILED(hr)) { return; } ClearListOfCalcComs(); int nComCnt = 0; CLSID clsid; while((hr = pIEnumCLSID->Next(1, &clsid, NULL)) == S_OK) { ICalc* pIcalc = NULL; HRESULT hr = ::CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, IID_ICalc, (void**)&pIcalc); if(FAILED(hr)) { continue; } BSTR pOpName; CALCCOMS* pComCalc = new CALCCOMS; pComCalc->clsid = clsid; pComCalc->iCalc = pIcalc; pComCalc->iCalc->GetOpName(&pOpName); pComCalc->strOpName = pOpName; pComCalc->nButtonID = IDC_COM_BUTTON_BEGIN + nComCnt; m_lstCaclComs.AddTail(pComCalc); nComCnt++; } if(pIEnumCLSID != NULL) { pIEnumCLSID->Release(); } if(pCatInfo != NULL) { pCatInfo->Release(); } }