⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 plghand2.cpp

📁 symbian 下的helix player源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/*
    LoadDLL()

    This is called during a Refresh() (which is deprecated)
    or if we determine that the DLL is dirty and needs to be updated
 */
Plugin2Handler::Errors Plugin2Handler::LoadDLL( char* pszDllName,
					PluginMountPoint* pMountPoint )
{
    Errors			result	    = NO_ERRORS;
    UINT32			i	    = 0;
    struct stat			stat_stuct;
    IHXBuffer*			pPathBuffer = pMountPoint->Path();

    // Make sure there is no path in the pszDllName
    HX_ASSERT( !strrchr(pszDllName, Plugin2Handler::zm_cDirectorySeperator) );


    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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -