📄 hxpluginmanager.cpp
字号:
if(bWriteArchive)
{
SaveToArchive(strArchiveFile);
}
return hr;
}
///////////////////////////////////////////////////////////////////////////////
//
HX_RESULT HXPluginManager::ReloadPlugins( const char* pMountPoint )
{
CFindFile* pFileFinder = NULL;
IHXBuffer* pPathBuffer = NULL;
HX_RESULT hr = HXR_FAIL;
HX_ASSERT(m_pContext);
if (m_pContext)
{
#if defined(_STATICALLY_LINKED) && !defined(HELIX_CONFIG_CONSOLIDATED_CORE)
const char* const pszPluginDir = "";
pFileFinder = CStaticFindFile::CreateFindFile(pszPluginDir,0, OS_DLL_PATTERN_STRING);
#else
const char* const pszPluginDir = pMountPoint;
pFileFinder = CFindFile::CreateFindFile(pszPluginDir, 0, OS_DLL_PATTERN_STRING);
#endif
if (pFileFinder)
{
hr = ReloadPluginsWithFindFile(pMountPoint, pFileFinder, pPathBuffer, pszPluginDir);
HX_DELETE(pFileFinder);
}
}
return hr;
}
STDMETHODIMP HXPluginManager::FindIndexUsingValues(IHXValues* pValues,REF(UINT32) unIndex)
{
return HXR_NOTIMPL;
}
STDMETHODIMP HXPluginManager::GetInstance (UINT32 index, REF(IUnknown*) pUnknown)
{
pUnknown = NULL;
LISTPOSITION pPos = m_plugins.FindIndex(index);
if (pPos)
{
HXPlugin* pPlugin = (HXPlugin*) m_plugins.GetAt(pPos);
if (pPlugin)
{
return pPlugin->GetInstance(pUnknown);
}
}
return HXR_FAIL;
}
STDMETHODIMP HXPluginManager::FindIndexUsingStrings (char* PropName1,
char* PropVal1,
char* PropName2,
char* PropVal2,
char* PropName3,
char* PropVal3,
REF(UINT32) unIndex)
{
return HXR_NOTIMPL;
}
STDMETHODIMP HXPluginManager::FindPluginUsingValues(IHXValues* pValues,REF(IUnknown*) pUnk)
{
return FindPluginUsingValues( pValues, pUnk, NULL );
}
HX_RESULT HXPluginManager::FindGroupOfPluginsUsingStrings(char* PropName1,
char* PropVal1,
char* PropName2,
char* PropVal2,
char* PropName3,
char* PropVal3,
REF(HXPluginEnumerator*) pEnumerator)
{
DPRINTF(D_INFO, ("HXPluginManager()::FindGroupOfPluginsUsingStrings(): '%s' = '%s', etc.\n", PropName1, PropVal1));
// PropName and PropVal have to to valid tuple
if ((PropName1 && !PropVal1) ||
(PropName2 && !PropVal2) ||
(PropName3 && !PropVal3) ||
(!PropName1 && PropVal1) ||
(!PropName2 && PropVal2) ||
(!PropName3 && PropVal3))
return HXR_FAIL;
IHXValues* pValues;
HX_RESULT retVal = HXR_FAIL;
CHXHeader* pHeader = new CHXHeader;
pHeader->QueryInterface(IID_IHXValues, (void**)&pValues);
AddToValues(pValues, PropName1, PropVal1, eString);
AddToValues(pValues, PropName2, PropVal2, eString);
AddToValues(pValues, PropName3, PropVal3, eString);
retVal = FindGroupOfPluginsUsingValues(pValues, pEnumerator);
pValues->Release();
return retVal;
}
HX_RESULT HXPluginManager::FindGroupOfPluginsUsingValues(IHXValues* pValues,
REF(HXPluginEnumerator*) pEnumerator)
{
HX_RESULT hr = HXR_FAIL;
pEnumerator = NULL;
for(CHXSimpleList::Iterator iter = m_plugins.Begin();
iter != m_plugins.End(); ++iter)
{
HXPlugin* pPlugin = (HXPlugin*) *iter;
if (pPlugin->DoesMatch(pValues))
{
if (!pEnumerator)
{
pEnumerator = new HXPluginEnumerator();
if(pEnumerator)
{
hr = HXR_OK;
}
else
{
hr = HXR_OUTOFMEMORY;
break;
}
}
pEnumerator->Add(pPlugin);
}
}
return hr;
}
// IHXPluginHandler3
STDMETHODIMP
HXPluginManager::RegisterContext( IUnknown* pContext )
{
HX_ASSERT(pContext);
if( !pContext )
{
return HXR_INVALID_PARAMETER;
}
if( m_pContext )
{
return HXR_UNEXPECTED;
}
m_pContext = pContext;
m_pContext->AddRef();
m_pContext->QueryInterface(IID_IHXCommonClassFactory, (void**)&m_pClassFactory);
return HXR_OK;
}
// IHXPluginHandler3
STDMETHODIMP
HXPluginManager::AddPluginMountPoint( const char* pName, UINT32 majorVersion, UINT32 minorVersion, IHXBuffer* pPath )
{
DPRINTF(D_INFO, ("HXPluginManager()::AddPluginMountPoint(): name = '%s'\n", pName));
const char* pMPKey = pName ? pName : (const char*) pPath->GetBuffer();
// Make sure this mount point is in the list
CHXString strMountPoint;
if( !m_mountPoints.Lookup(pMPKey, strMountPoint) && pPath )
{
strMountPoint = (const char*)pPath->GetBuffer();
// Put new mount point in list
m_mountPoints.SetAt( pMPKey, strMountPoint );
}
// Load information from registry, and sync DLLs that aren't up to date
return ReloadPlugins( strMountPoint );
}
// IHXPluginHandler3
STDMETHODIMP
HXPluginManager::RefreshPluginMountPoint( const char* pName )
{
HX_RESULT result = HXR_FAIL;
CHXString strMountPoint;
if( m_mountPoints.Lookup( pName, strMountPoint ) )
{
result = ReloadPlugins( strMountPoint );
}
return result;
}
// IHXPluginHandler3
STDMETHODIMP
HXPluginManager::RemovePluginMountPoint( const char* pName )
{
HX_RESULT hr = HXR_FAIL;
CHXString strMountPoint;
if( m_mountPoints.Lookup( pName, strMountPoint ) )
{
// Clean up plugin dlls associated with mountpoint
LISTPOSITION listPos = m_pluginDlls.GetHeadPosition();
while( listPos )
{
LISTPOSITION curPos = listPos;
HXPluginDLL* pLibrary = (HXPluginDLL*) m_pluginDlls.GetNext( listPos );
if( pLibrary && ( pLibrary->GetMountPoint() == strMountPoint ) )
{
m_pluginDlls.RemoveAt( curPos );
pLibrary->Unload(); // just in case; this should be last ref
HX_RELEASE( pLibrary );
}
}
// Clean up 'other' dlls associated with mountpoint
listPos = m_otherDlls.GetHeadPosition();
while( listPos )
{
LISTPOSITION curPos = listPos;
HXOtherDLL* pLibrary = (HXOtherDLL*) m_otherDlls.GetNext( listPos );
if( pLibrary && ( pLibrary->GetMountPoint() == strMountPoint ) )
{
m_otherDlls.RemoveAt( curPos );
HX_RELEASE( pLibrary );
}
}
m_mountPoints.RemoveKey( pName );
// Plugin list must be rebuilt
RebuildPluginList();
hr = HXR_OK;
}
return hr;
}
//
// called every time dll list has been altered (we could be more efficient in many cases)
//
void HXPluginManager::RebuildPluginList()
{
DPRINTF(D_INFO, ("HXPluginManager()::RebuildPluginList()\n"));
CHXSimpleList::Iterator iter;
// clean up (now invalid) plugin list
for(iter = m_plugins.Begin(); iter != m_plugins.End(); ++iter)
{
HXPlugin* pPlugin = (HXPlugin*) *iter;
pPlugin->Release();
}
m_plugins.RemoveAll();
// rebuild list of plugins we can instanciate
for(iter = m_pluginDlls.Begin(); iter != m_pluginDlls.End(); ++iter)
{
HXPluginDLL* pLibrary = (HXPluginDLL*) *iter;
pLibrary->AddPlugins(m_plugins);
}
}
STDMETHODIMP
HXPluginManager::FindImplementationFromClassID( REFGUID GUIDClassID, REF(IUnknown*) pIUnknownInstance,
IUnknown* pIUnkOuter, IUnknown* pContext )
{
DPRINTF(D_INFO, ("HXPluginManager()::FindImplementationFromClassID()\n"));
HX_RESULT rc = HXR_OK;
IUnknown* pUnknown = NULL;
IHXPlugin* pPlugin = NULL;
IHXCommonClassFactory* pFactory = NULL;
IHXPluginSearchEnumerator* pPluginEnumerator = NULL;
// a much simpler version than Plugin2Handler, it's not as efficient as Plugin2Handler but it
// should be good enough for static build.
pIUnknownInstance = NULL;
rc = FindGroupOfPluginsUsingStrings(PLUGIN_CLASS, PLUGIN_CLASS_FACTORY_TYPE,
NULL, NULL, NULL, NULL, pPluginEnumerator);
if (SUCCEEDED(rc))
{
while (HXR_OK == pPluginEnumerator->GetNextPlugin(pUnknown, NULL) && pUnknown)
{
if (HXR_OK == pUnknown->QueryInterface(IID_IHXPlugin, (void**)&pPlugin))
{
pPlugin->InitPlugin(pContext);
if (HXR_OK == pUnknown->QueryInterface(IID_IHXCommonClassFactory, (void**)&pFactory))
{
if (HXR_OK == pFactory->CreateInstance(GUIDClassID, (void**)&pIUnknownInstance) &&
pIUnknownInstance)
{
break;
}
HX_RELEASE(pIUnknownInstance);
}
HX_RELEASE(pFactory);
}
HX_RELEASE(pPlugin);
HX_RELEASE(pUnknown);
}
if (!pIUnknownInstance)
{
rc = HXR_FAILED;
}
}
// cleanup
HX_RELEASE(pFactory);
HX_RELEASE(pPlugin);
HX_RELEASE(pUnknown);
HX_RELEASE(pPluginEnumerator);
return rc;
}
STDMETHODIMP
HXPluginManager::FindCLSIDFromName( const char* pName, REF(IHXBuffer*) pCLSID )
{
return HXR_NOTIMPL;
}
STDMETHODIMP
HXPluginManager::FindGroupOfPluginsUsingValues( IHXValues* pValues,
REF(IHXPluginSearchEnumerator*) pIEnumerator)
{
return HXR_NOTIMPL;
}
STDMETHODIMP
HXPluginManager::FindGroupOfPluginsUsingStrings( char* PropName1, char* PropVal1,
char* PropName2, char* PropVal2,
char* PropName3, char* PropVal3,
REF(IHXPluginSearchEnumerator*) pIEnumerator)
{
DPRINTF(D_INFO, ("HXPluginManager()::FindGroupOfPluginsUsingStrings()\n"));
// Regardless of how the API can be used, the reality is that this function
// is essentially the highest level point of access for the core when
// starting playback of a new stream, so this is a great time to unload
// all our dead dlls.
// But the memory efficiency of DLL unloading comes at the expense of
// setup time, so we probably only want to do this on platforms where
// memory optimization is our highest priority.
#if defined(HELIX_CONFIG_UNLOAD_DEAD_DLLS)
UnloadDeadDLLs();
#endif
// Initialize out params
pIEnumerator = NULL;
// Use the internal function to build up an enumerator object
HXPluginEnumerator* pEnumerator = NULL;
HX_RESULT result = FindGroupOfPluginsUsingStrings( PropName1, PropVal1,
PropName2, PropVal2, PropName3, PropVal3, pEnumerator );
// If we have our enumerator, get the appropriate interface
if( SUCCEEDED( result ) )
{
result = pEnumerator->QueryInterface( IID_IHXPluginSearchEnumerator,
(void**) &pIEnumerator );
}
return result;
}
STDMETHODIMP
HXPluginManager::FindPluginUsingValues( IHXValues* pCriteria,
REF(IUnknown*) pIUnkResult,
IUnknown* pIUnkOuter )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -