📄 basehand.cpp
字号:
#if !defined(_STATICALLY_LINKED) || defined(HELIX_CONFIG_CONSOLIDATED_CORE)
HX_RELEASE(pPathBuffer);
#endif
return retVal;
}
STDMETHODIMP BaseHandler::FindIndexUsingValues (IHXValues* pValues,
REF(UINT32) unIndex)
{
return HXR_NOTIMPL;
}
STDMETHODIMP BaseHandler::GetInstance (UINT32 index, REF(IUnknown*) pUnknown)
{
pUnknown = NULL;
LISTPOSITION pPos = m_PluginList.FindIndex(index);
if (pPos)
{
BaseHandler::Plugin* pPlugin = (BaseHandler::Plugin*) m_PluginList.GetAt(pPos);
if (pPlugin)
{
Errors retVal = pPlugin->GetInstance(pUnknown);
if (retVal== NO_ERRORS)
{
return HXR_OK;
}
}
}
return HXR_FAIL;
}
STDMETHODIMP BaseHandler::FindIndexUsingStrings (char* PropName1,
char* PropVal1,
char* PropName2,
char* PropVal2,
char* PropName3,
char* PropVal3,
REF(UINT32) unIndex)
{
return HXR_NOTIMPL;
}
STDMETHODIMP BaseHandler::FindPluginUsingValues (IHXValues* pValues,
REF(IUnknown*) pUnk)
{
return FindPluginUsingValues( pValues, pUnk, NULL );
}
HX_RESULT BaseHandler::FindGroupOfPluginsUsingStrings(char* PropName1,
char* PropVal1,
char* PropName2,
char* PropVal2,
char* PropName3,
char* PropVal3,
REF(CPluginEnumerator*) pEnumerator)
{
// 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 BaseHandler::FindGroupOfPluginsUsingValues(IHXValues* pValues,
REF(CPluginEnumerator*) pEnumerator)
{
CHXSimpleList::Iterator i = m_PluginList.Begin();
pEnumerator = NULL;
for(; i!= m_PluginList.End(); ++i)
{
BaseHandler::Plugin* pPlugin = (BaseHandler::Plugin*) *i;
if (pPlugin->DoesMatch(pValues))
{
if (!pEnumerator)
{
pEnumerator = new CPluginEnumerator();
}
pEnumerator->Add(pPlugin);
}
}
if (!pEnumerator)
{
return HXR_FAIL;
}
return HXR_OK;
}
/********************************************************************
*
* IHXPluginHandler3
*
********************************************************************/
STDMETHODIMP
BaseHandler::RegisterContext( IUnknown* pContext )
{
if( !pContext )
{
return INVALID_CONTEXT;
}
if( m_pContext )
{
return HXR_UNEXPECTED;
}
m_pContext = pContext;
m_pContext->AddRef();
return HXR_OK;
}
STDMETHODIMP
BaseHandler::AddPluginMountPoint( const char* pName, UINT32 majorVersion, UINT32 minorVersion, IHXBuffer* pPath )
{
HX_LOG_BLOCK( "BaseHandler::AddPluginMountPoint" );
const char* pMPKey = pName ? pName : (const char*) pPath->GetBuffer();
// Make sure this mount point is in the list
PluginMountPoint* pMountPoint = NULL;
if( !m_MountPoints.Lookup( pMPKey, (void*&) pMountPoint ) )
{
// Create new mount point
pMountPoint = new PluginMountPoint( this, pName, majorVersion, minorVersion, pPath );
pMountPoint->AddRef();
// Put new mount point in list
m_MountPoints.SetAt( pMPKey, pMountPoint );
}
// Load information from registry, and sync DLLs that aren't up to date
return RefreshPluginInfo( pMountPoint );
}
STDMETHODIMP
BaseHandler::RefreshPluginMountPoint( const char* pName )
{
HX_RESULT result = HXR_FAIL;
// If this mount point is in the list, refresh it
PluginMountPoint* pMountPoint = NULL;
if( m_MountPoints.Lookup( pName, (void*&) pMountPoint ) )
{
result = RefreshPluginInfo( pMountPoint );
}
return result;
}
STDMETHODIMP
BaseHandler::RemovePluginMountPoint( const char* pName )
{
HX_RESULT result = HXR_FAIL;
// Make sure this is a valid mount point
PluginMountPoint* pMountPoint = NULL;
if( m_MountPoints.Lookup( pName, (void*&) pMountPoint ) )
{
// Clean up plugins
if( m_PluginList.GetCount() )
{
LISTPOSITION listPos = m_PluginList.GetHeadPosition();
while( listPos )
{
// Save off current position for delete
LISTPOSITION posAt = listPos;
// Get current item, and increment position
BaseHandler::Plugin* pPlugin = (BaseHandler::Plugin*) m_PluginList.GetNext( listPos );
// If this plugin belongs to the mountpoint, remove it.
if( pPlugin && ( pPlugin->GetDLL()->GetMountPoint() == pMountPoint ) )
{
// Delete from the saved position
m_PluginList.RemoveAt( posAt );
HX_RELEASE( pPlugin );
}
}
}
// Remove mount point from list
m_MountPoints.RemoveKey( pName );
HX_RELEASE( pMountPoint );
}
return result;
}
STDMETHODIMP
BaseHandler::FindImplementationFromClassID( REFGUID GUIDClassID, REF(IUnknown*) pIUnknownInstance,
IUnknown* pIUnkOuter, IUnknown* pContext )
{
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.
// Initialize out params
pIUnknownInstance = NULL;
rc = FindGroupOfPluginsUsingStrings(PLUGIN_CLASS, PLUGIN_CLASS_FACTORY_TYPE,
NULL, NULL, NULL, NULL, pPluginEnumerator);
if (HXR_OK != rc)
{
rc = HXR_FAILED;
goto cleanup;
}
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;
}
HX_RESULT
BaseHandler::RefreshPluginInfo( PluginMountPoint* pMountPoint )
{
return ReloadPluginsNoPropagate( pMountPoint );
}
STDMETHODIMP
BaseHandler::FindCLSIDFromName( const char* pName, REF(IHXBuffer*) pCLSID )
{
return HXR_NOTIMPL;
}
STDMETHODIMP
BaseHandler::FindGroupOfPluginsUsingValues( IHXValues* pValues,
REF(IHXPluginSearchEnumerator*) pIEnumerator)
{
return HXR_NOTIMPL;
}
STDMETHODIMP
BaseHandler::FindGroupOfPluginsUsingStrings( char* PropName1, char* PropVal1,
char* PropName2, char* PropVal2,
char* PropName3, char* PropVal3,
REF(IHXPluginSearchEnumerator*) pIEnumerator)
{
// 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
CPluginEnumerator* 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;
}
void BaseHandler::ReportError( UINT8 severity, const char* pDLLName, const char* pDesc )
{
}
STDMETHODIMP
BaseHandler::FindPluginUsingValues( IHXValues* pCriteria,
REF(IUnknown*) pIUnkResult,
IUnknown* pIUnkOuter )
{
HX_SETUP_CHECKPOINTLIST( "BaseHandler::FindPluginUsingValues()" );
HX_PRIME_ACCUMULATOR( 'fpuv', "Plugin lookup with IHXValues" );
// Initialize out params
pIUnkResult = NULL;
CHXSimpleList PossibleValues;
IHXValues* pPluginValues = NULL;
IHXBuffer* pBuffer = NULL;
CHXSimpleList::Iterator i = m_PluginList.Begin();
for(; i!= m_PluginList.End(); ++i)
{
BaseHandler::Plugin* pPlugin = (BaseHandler::Plugin*) *i;
if (pPlugin->DoesMatch(pCriteria))
{
PossibleValues.AddTail(pPlugin);
}
}
HX_UPDATE_ACCUMULATOR( 'fpuv' );
if (PossibleValues.Begin() == PossibleValues.End())
{
pIUnkResult = 0;
return HXR_FAIL;
}
/****************************************************************
** Presently when we arrive at this spot with more than one
** plugin which matches the search criteria, we simply take
** the first one found. If this is not satisfactory then
** some method can be added which will process the list based
** upon some criteria.
****************************************************************/
// if there are multiple plugins found, we will pick the one whose
// plugin description contains "RealNetworks"
if (PossibleValues.GetCount() > 1)
{
for(i = PossibleValues.Begin(); i!= PossibleValues.End(); ++i)
{
BaseHandler::Plugin* pPlugin = (BaseHandler::Plugin*) *i;
if (HXR_OK == pPlugin->GetPluginInfo(pPluginValues) && pPluginValues)
{
if (HXR_OK == pPluginValues->GetPropertyCString(PLUGIN_DESCRIPTION2, pBuffer) &&
pBuffer)
{
if (strstr((const char*)pBuffer->GetBuffer(), "RealNetworks"))
{
HX_RELEASE(pBuffer);
if ( NO_ERRORS == pPlugin->GetInstance( pIUnkResult, pIUnkOuter ))
{
return HXR_OK;
}
else
{
return HXR_FAIL;
}
}
}
HX_RELEASE(pBuffer);
}
}
}
BaseHandler::Plugin* pPlug = (BaseHandler::Plugin*) *(PossibleValues.Begin());
Errors retVal = pPlug->GetInstance( pIUnkResult, pIUnkOuter );
return ( retVal == NO_ERRORS ) ? HXR_OK : HXR_FAIL;
}
STDMETHODIMP
BaseHandler::FindPluginUsingStrings( char* PropName1, char* PropVal1,
char* PropName2, char* PropVal2,
char* PropName3, char* PropVal3,
REF(IUnknown*) pIUnkResult,
IUnknown* pIUnkOuter )
{
// Initialize out params
pIUnkResult = NULL;
// 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 = FindPluginUsingValues( pValues, pIUnkResult, pIUnkOuter );
pValues->Release();
return retVal;
}
void
BaseHandler::UnloadDeadDLLs()
{
LISTPOSITION pos = m_PluginList.GetHeadPosition();
while( pos )
{
BaseHandler::Plugin* pPlugin = (BaseHandler::Plugin*) m_PluginList.GetNext( pos );
if( pPlugin )
{
PluginDLL * pPluginDll = pPlugin->GetDLL();
if( pPluginDll )
{
pPluginDll->Unload();
}
}
}
}
STDMETHODIMP
BaseHandler::GetPlugin( ULONG32 ulIndex, REF(IUnknown*) pIUnkResult,
IUnknown* pIUnkOuter )
{
if( ulIndex <= (ULONG32)(m_PluginList.GetCount()-1) && m_PluginList.GetCount() )
{
LISTPOSITION pPos = m_PluginList.FindIndex( ulIndex );
if (pPos)
{
BaseHandler::Plugin* pPlugin = (BaseHandler::Plugin*) m_PluginList.GetAt( pPos );
if( pPlugin )
{
if (NO_ERRORS == pPlugin->GetInstance( pIUnkResult, pIUnkOuter ))
{
return HXR_OK;
}
else
{
return HXR_FAIL;
}
}
}
}
return HXR_FAIL;
}
STDMETHODIMP
BaseHandler::UnloadPluginFromClassID(REFGUID GUIDClassID)
{
return HXR_NOTIMPL;
}
STDMETHODIMP
BaseHandler::UnloadPackageByName(const char* pName)
{
return HXR_NOTIMPL;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -