📄 plghand2.cpp
字号:
Plugin2Handler::PluginDLL* pPluginDll = NULL; if( !( pPluginDll = new Plugin2Handler::PluginDLL( pszDllName, pMountPoint, this ) ) ) { return MEMORY_ERROR; } pPluginDll->AddRef(); CHXString sFileWithPath = pPathBuffer->GetBuffer(); UINT32 len = sFileWithPath.GetLength(); if(len && sFileWithPath.GetAt(len - 1) != Plugin2Handler::zm_cDirectorySeperator) sFileWithPath += Plugin2Handler::zm_cDirectorySeperator; sFileWithPath += pszDllName; if (NO_ERRORS==Stat(sFileWithPath, &stat_stuct)) { pPluginDll->SetFileSize((INT32)stat_stuct.st_size); } result = pPluginDll->Load(m_pContext); if (NO_ERRORS != result ) { goto cleanup; } // Set the hash if (pPathBuffer) { IHXBuffer* pNewChecksum = ChecksumFile( pszDllName, pPathBuffer ); if (pNewChecksum) { HX_RELEASE(pPathBuffer); pPluginDll->SetHash((char*)pNewChecksum->GetBuffer()); HX_RELEASE(pNewChecksum); } } // Remove this DLL from the list of supported DLL (based on GUIDs) RemoveDLLFromGUIDSupportLists(pszDllName); // ReconnectDLL() replaces one PluginDLL object with another PluginDLL; however, // both of these PluginDLL objects refer to the same DLL. This ensures that // only one PluginDLL object per DLL is in the m_PluginDLLList. ReconnectDLL(pszDllName, pPluginDll); for(i=0;i<pPluginDll->GetNumPlugins();i++) { Plugin* pPlugin = NULL; // create a new plugin object if (!(pPlugin = new Plugin(m_pContext))) { return MEMORY_ERROR; } // Setup plugin information pPlugin->AddRef(); pPlugin->SetDLL(pPluginDll); pPlugin->SetIndex((UINT16)i); pPlugin->SetInfoNeedsRefresh(TRUE); IUnknown* pUnk = NULL; if( NO_ERRORS != pPlugin->GetPlugin( pUnk ) ) { // This plugin doesn't work. Delete it. HX_RELEASE( pPlugin ); } else { IHXPluginNamespace* pPluginNamespace = NULL; if (SUCCEEDED(pUnk->QueryInterface(IID_IHXPluginNamespace, (void**) &pPluginNamespace))) { /* * Memory for the IHXBuffer is allocated in the plugin */ IHXBuffer* pBuffer = NULL; if (SUCCEEDED(pPluginNamespace->GetPluginNamespace(pBuffer))) { pPluginDll->SetNamespace(pBuffer); HX_RELEASE(pBuffer); } HX_RELEASE(pPluginNamespace); } IHXComponentPlugin* pIIterator = NULL; if( SUCCEEDED( pUnk->QueryInterface( IID_IHXComponentPlugin, (void**) &pIIterator ) ) ) { // We don't need this. HX_RELEASE( pPlugin ); LoadPluginsFromComponentDLL( pPluginDll, pIIterator ); HX_RELEASE( pIIterator ); } else { IHXPlugin* pIHXPlugin; if( SUCCEEDED( pUnk->QueryInterface(IID_IHXPlugin, (void**)&pIHXPlugin ) ) ) { pPlugin->GetValuesFromDLL(pIHXPlugin); m_PluginList.AddTail(pPlugin); // Print out some log info about the plugin we just loaded { const char *pDesc, *pCopy, *pURL; ULONG32 ulVersionNumber = 0; BOOL junk; pIHXPlugin->GetPluginInfo(junk, pDesc, pCopy, pURL, ulVersionNumber); ReportError( HXLOG_INFO, pszDllName, pDesc ); } // At this point since we have the HXPlugin we should query it to see if // it supports any of the GUIDs which have been enumerated so far. UINT32 nNumGUIDs = GetNumSupportedGUIDs(); for(; nNumGUIDs; nNumGUIDs--) { CHXString pszGUID; GUID theGUID; GetGUIDForIndex(nNumGUIDs-1, pszGUID); CHXuuid::HXUuidFromString(pszGUID, (uuid_tt*)&theGUID); IUnknown* pQueryUnk; if (HXR_OK == pIHXPlugin->QueryInterface(theGUID, (void**)&pQueryUnk)) { AddSupportForGUID(pszGUID, pPluginDll, i); HX_RELEASE(pQueryUnk); } }// if this is a required plugin, validate it // XXXAH this could be a problem// if (IsPluginRequired(pDesc, pPlugin))// {// bValidated = ValidateRequiredPlugin(pIHXPlugin, pPlugin);// } pIHXPlugin->Release(); } } } HX_RELEASE( pUnk ); }cleanup: HX_RELEASE(pPathBuffer); if (result != NO_ERRORS) { HX_RELEASE( pPluginDll ); } return result;}void Plugin2Handler::LoadPluginsFromComponentDLL( Plugin2Handler::PluginDLL* pPluginDll, IHXComponentPlugin* pIIterator ){ IHXPlugin* pIHXPlugin = NULL; if( SUCCEEDED( pIIterator->QueryInterface(IID_IHXPlugin, (void**)&pIHXPlugin ) ) ) { // XXXHP - this is now done in the PluginDLL::Load() method // pIHXPlugin->InitPlugin( m_pContext ); for( UINT32 index = 0; index < pIIterator->GetNumComponents(); index++ ) { IHXValues* pIValues = NULL; if( SUCCEEDED( pIIterator->GetComponentInfoAtIndex( index, pIValues ) ) ) { IHXBuffer* pBuffer = NULL; if (SUCCEEDED(pIValues->GetPropertyCString(PLUGIN_COMPONENT_NAME, pBuffer))) { IHXBuffer* pNamespace = pPluginDll->GetNamespace(); if (pNamespace) { CHXString TempNamespace = pNamespace->GetBuffer(); TempNamespace += NAMESPACE_SEPARATOR; TempNamespace += pBuffer->GetBuffer(); IHXBuffer* pTempBuffer = new CHXBuffer(); pTempBuffer->AddRef(); pTempBuffer->Set((BYTE*)(const char*)TempNamespace, TempNamespace.GetLength()+1); pIValues->SetPropertyCString(PLUGIN_COMPONENT_NAME, pTempBuffer); HX_RELEASE(pTempBuffer); HX_RELEASE(pNamespace); } HX_RELEASE(pBuffer); } // create a new plugin object Plugin* pPlugin = new Plugin( m_pContext ); HX_ASSERT( pPlugin ); // Setup plugin object pPlugin->AddRef(); pPlugin->SetDLL( pPluginDll ); // XXXP - this isn't necessary, the Plugin is initialized with an index of 0 if no index is found. // pPlugin->SetIndex( (UINT16) 0 ); pPlugin->SetInfoNeedsRefresh( TRUE ); // XXXND FIX I don't like this specialized interface. // This gets the basic info from pIHXPlugin, and the rest from pValues pPlugin->InitializeComponentPlugin( pIHXPlugin, pIValues ); // Put in plugin list m_PluginList.AddTail(pPlugin); // Stick CLSID in map AddPluginToIndices( pPlugin ); HX_RELEASE( pIValues ); } } HX_RELEASE (pIHXPlugin); }}STDMETHODIMP Plugin2Handler::ReloadPlugins(){ // now we have to tell all other players that they should also // reload their plugins. IHXShutDownEverything* pShutDown = NULL ; if (HXR_OK == m_pContext->QueryInterface(IID_IHXShutDownEverything, (void**) &pShutDown)) { pShutDown->AskAllOtherPlayersToReload(); HX_RELEASE(pShutDown); } // This will re-initialize all the MountPoints return ReloadPluginsNoPropagate();}///////////////////////////////////////////////////////////////////////////////// These functions will find all plugins which are different// then those loaded into the registry.// It will then load them into memory, get their data, and unload them.// It will return HXR_FAIL if some DLL has different values within the// registry, and is presently in memory (how could this happen??)// If anyone was keeping an index to a loaded DLL and assuming that it// would remain constant ... that won't work!!HX_RESULT Plugin2Handler::ReloadPluginsNoPropagate(){ HX_LOG_BLOCK( "Plugin2Handler::ReloadPluginsNoPropagate" ); HX_RESULT result = HXR_OK; // Reload them all. for(CHXMapStringToOb::Iterator mp = m_MountPoints.Begin(); mp!=m_MountPoints.End(); ++mp) { PluginMountPoint* pMountPoint = (PluginMountPoint*) *mp; if( FAILED( ReloadPluginsNoPropagate( pMountPoint ) ) ) { result = HXR_FAIL; } } return result;}HX_RESULT Plugin2Handler::ReloadPluginsNoPropagate( PluginMountPoint* pMountPoint ){ HX_LOG_BLOCK( "Plugin2Handler::ReloadPluginsNoPropagate(PluginMP*)" );#ifndef _STATICALLY_LINKED CFindFile* pFileFinder = NULL;#else CStaticFindFile* pFileFinder = NULL;#endif IHXBuffer* pPathBuffer = NULL; char* pszPluginDir = NULL; ULONG32 nPluginDirLen = 0; char* pszDllName = 0; IHXBuffer* pNewChecksum = 0; BOOL bRegIsDirty = FALSE; BOOL bContinue; // if we have no context do not proceed. if (!m_pContext) { return INVALID_CONTEXT; } // If this is the 1st time, load everything into the registry.#ifndef _STATICALLY_LINKED pPathBuffer = pMountPoint->Path(); if (!pPathBuffer) { return HXR_FAIL; } pPathBuffer->Get((UCHAR*&)pszPluginDir, nPluginDirLen); if (!nPluginDirLen) { return HXR_FAIL; }#else pszPluginDir="";#endif pFileFinder =#ifndef _STATICALLY_LINKED CFindFile::CreateFindFile#else CStaticFindFile::CreateFindFile#endif (pszPluginDir, 0, Plugin2Handler::zm_pszFileExtension); if (NULL == pFileFinder) { pPathBuffer->Release(); HX_DELETE(pFileFinder); return HXR_FAIL; } pszDllName = pFileFinder->FindFirst(); BOOL bDLLIsDirty = FALSE; while (pszDllName) { // See if this file exists in our list of pluginDLLs BOOL bFound = FALSE; CHXSimpleList::Iterator i; Plugin2Handler::PluginDLL* pDLL = NULL; bFound = m_FileNameMap.Lookup(pszDllName, (void*&)pDLL); // If it was not found it may a misc DLL -- ie not an // RMA DLL. Thus, we should ignore it. bContinue = FALSE; if (!bFound) { for(i=m_MiscDLLList.Begin();i!=m_MiscDLLList.End(); ++i) { Plugin2Handler::OtherDLL* pOther = (Plugin2Handler::OtherDLL*) *i; if (!stricmp(pOther->m_filename, pszDllName)) { // ok we have a match does the checksum match? if (pNewChecksum = ChecksumFile(pszDllName, pPathBuffer)) { if (!strcmp((char*)pNewChecksum->GetBuffer(), pOther->m_fileChecksum)) bContinue = TRUE; HX_RELEASE(pNewChecksum); } } } } if (bContinue) { pszDllName = pFileFinder->FindNext(); continue; } if (bFound) { if (pNewChecksum = ChecksumFile(pszDllName, pPathBuffer)) { if (!strcasecmp(pDLL->GetHash(), (const char*)pNewChecksum->GetBuffer())) { pszDllName = pFileFinder->FindNext(); pNewChecksum->Release(); continue; // old checksum == new checksum. no changes. } pNewChecksum->Release(); pNewChecksum = NULL; } // Delete all Plugins which are associated with this PluginDLL. LISTPOSITION pPos = NULL; if ( m_PluginList.GetCount() ) { LISTPOSITION pPos = m_PluginList.GetHeadPosition(); while (pPos) { // save off current position for delete LISTPOSITION posAt = pPos; Plugin2Handler::Plugin* pPlugin = (Plugin2Handler::Plugin*)m_PluginList.GetNext(pPos); HX_ASSERT(pPlugin); if ( pPlugin && pPlugin->GetDLL() == pDLL ) { RemovePluginFromIndices( pPlugin ); m_PluginList.RemoveAt( posAt ); HX_RELEASE( pPlugin ); } } } // Remove the pluginDLL from the PluginDLL list. pPos = m_PluginDLLList.Find(pDLL); if (pPos) { m_PluginDLLList.RemoveAt(pPos); m_FileNameMap.RemoveKey(pszDllName); // Since this PluginDLL was unloaded, no need to keep // it in the list of PluginDLLs which export CanUnload2(). LISTPOSITION posCanUnload = m_CanUnload2DllList.Find( pDLL ); if ( posCanUnload ) { m_CanUnload2DllList.RemoveAt( posCanUnload ); } } bDLLIsDirty = TRUE; } else { bDLLIsDirty = TRUE; } if (bDLLIsDirty) { // if we got here we have a new dll. Plugin2Handler::Errors loadResult; loadResult = LoadDLL( pszDllName, pMountPoint ); if (loadResult!= NO_ERRORS) { // The DLL had one of the following problems: // (1) the DLL was unloadable // (2) the DLL did not have an HXCreateInstance // (3) an instance could not be created. // (4) It did not implement the PLUGIN interface // if it was case 2,3,4 then we can safely never attempt to // load the DLL again. However if it was (1) then we must attempt // to load the DLL ever time through since it was possibly unloadable due // to an imp-lib that will be satisfied lated (without modifing the // dll). Jeeze. That comment is UNREADABLE. I have to take effective written // english again! if (loadResult!=CANT_OPEN_DLL) { Plugin2Handler::OtherDLL* pDLLData = new Plugin2Handler::OtherDLL; pDLLData->m_filename = pszDllName; pDLLData->m_pMountPoint = pMountPoint; pNewChecksum = ChecksumFile(pszDllName, pPathBuffer); if (pNewChecksum) { pDLLData->m_fileChecksum = (char*)pNewChecksum->GetBuffer(); HX_RELEASE(pNewChecksum); bRegIsDirty=TRUE; m_MiscDLLList.AddTail(pDLLData); } else { HX_DELETE(pDLLData);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -