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

📄 hxpluginmanager.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/* ***** BEGIN LICENSE BLOCK *****
 * Version: RCSL 1.0/RPSL 1.0
 *
 * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved.
 *
 * The contents of this file, and the files included with this file, are
 * subject to the current version of the RealNetworks Public Source License
 * Version 1.0 (the "RPSL") available at
 * http://www.helixcommunity.org/content/rpsl unless you have licensed
 * the file under the RealNetworks Community Source License Version 1.0
 * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl,
 * in which case the RCSL will apply. You may also obtain the license terms
 * directly from RealNetworks.  You may not use this file except in
 * compliance with the RPSL or, if you have a valid RCSL with RealNetworks
 * applicable to this file, the RCSL.  Please see the applicable RPSL or
 * RCSL for the rights, obligations and limitations governing use of the
 * contents of the file.
 *
 * This file is part of the Helix DNA Technology. RealNetworks is the
 * developer of the Original Code and owns the copyrights in the portions
 * it created.
 *
 * This file, and the files included with this file, is distributed and made
 * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
 *
 * Technology Compatibility Kit Test Suite(s) Location:
 *    http://www.helixcommunity.org/content/tck
 *
 * Contributor(s):
 *
 * ***** END LICENSE BLOCK ***** */

#include "hxtypes.h"
#include "hxassert.h"
#include "debug.h"
#include "hxcom.h"
#include "hxccf.h"      // IHXCommonClassFactory
#include "ihxpckts.h"   // IHXBuffer
#include "hxplugn.h"    // IHXComponentPlugin
#include "hxprefs.h"	// IHXPreferences
#include "hxprefutil.h"
#include "findfile.h"
#include "chxpckts.h"   // CHXHeader
#include "dllacces.h"
#include "dllpath.h"
#include "pathutil.h"
#include "hxver.h"

#include "hxheap.h"
#ifdef _DEBUG
#undef HX_THIS_FILE
static const char HX_THIS_FILE[] = __FILE__;
#endif

#if defined(_STATICALLY_LINKED)
#include "staticff.h"
#endif

#include "hxpluginarchive.h"
#include "hxplugindll.h"
#include "hxplugin.h"
#include "hxpluginmanager.h"


#if(0)
// helper
static bool IsRealNetworksPlugin(HXPlugin* pPlugin)
{
    bool isRNPlugin = false;

    HX_ASSERT(pPlugin);
    IHXValues* pval = 0;
    if (SUCCEEDED(pPlugin->GetPluginInfo(pval)))
    {
        IHXBuffer* pbuff = 0;
	if (SUCCEEDED(pval->GetPropertyCString(PLUGIN_DESCRIPTION2, pbuff)))
	{
	    isRNPlugin =  (0 != strstr((const char*)pbuff->GetBuffer(), "RealNetworks"));
            HX_RELEASE(pbuff);
        }
        HX_RELEASE(pval);
    }

    return isRNPlugin;
}
#endif


IMPLEMENT_COM_CREATE_FUNCS( HXPluginManager )

BEGIN_INTERFACE_LIST_NOCREATE( HXPluginManager )
    INTERFACE_LIST_ENTRY_SIMPLE( IHXPluginEnumerator )
    INTERFACE_LIST_ENTRY_SIMPLE( IHXPlugin2Handler )
    INTERFACE_LIST_ENTRY_SIMPLE( IHXPluginHandler3 )
END_INTERFACE_LIST

HXPluginManager::HXPluginManager() 
: m_pContext(0)
, m_pClassFactory(0)
{
}

HXPluginManager::~HXPluginManager()
{
    Close();
}

STDMETHODIMP HXPluginManager::Init(IUnknown* pContext)
{
    DPRINTF(D_INFO, ("HXPluginManager::Init()\n"));
    HX_RESULT result = HXR_FAIL;

    if( SUCCEEDED( result = RegisterContext( pContext ) ) )
    {
	result = ReadFromRegistry();
    }

    return result;
}


STDMETHODIMP_(ULONG32) HXPluginManager::GetNumOfPlugins2()
{
    return m_plugins.GetCount();
}


STDMETHODIMP
HXPluginManager::GetPluginInfo(UINT32 unIndex, REF(IHXValues*) /*OUT*/ pValues)
{
    return HXR_NOTIMPL;
}

///////////////////////////////////////////////////////////////////////////////
//
HX_RESULT HXPluginManager::ReloadPluginsNoPropagate()
{
    return ReloadPlugins();
}

///////////////////////////////////////////////////////////////////////////////
//
HX_RESULT HXPluginManager::ReloadPlugins()
{
    DPRINTF(D_INFO, ("HXPluginManager()::ReloadPlugins()\n"));

    HX_RESULT result = HXR_OK;

    // reload plugins for all mountpoints
    for(CHXMapStringToString::Iterator iter = m_mountPoints.Begin(); iter != m_mountPoints.End(); ++iter)
    {
	const char* pMountPoint = (const char*) *iter;
	if( FAILED( ReloadPlugins( pMountPoint ) ) )
	{
	    result = HXR_FAIL;
	}
    }

    return result;
}

/////////////////////////////////
//
// do we already have the given dll in our collection?
//
// we use case insensitive match in all OS/filesystem cases (even if technically inappropriate)
//
bool HXPluginManager::DoesDLLExist(const char* pszName, const char* pszMountPoint)
{
    CHXSimpleList::Iterator iter;
    for(iter = m_pluginDlls.Begin(); iter != m_pluginDlls.End(); ++iter)
    {
	HXPluginDLL* pLib = (HXPluginDLL*) *iter;

        if( !pLib->GetFileName().CompareNoCase(pszName) && !pLib->GetMountPoint().CompareNoCase(pszMountPoint) )
        {
            DPRINTF(D_INFO, ("HXPluginManager::DoesDLLExist(): plugin dll exists '%s'\n", (const char*)pLib->GetFileName()));
            return true;
        }
    }

    for(iter = m_otherDlls.Begin(); iter != m_otherDlls.End(); ++iter)
    {
	HXOtherDLL* pLib = (HXOtherDLL*) *iter;
        if( !pLib->GetFileName().CompareNoCase(pszName) && !pLib->GetMountPoint().CompareNoCase(pszMountPoint) )
        {
            DPRINTF(D_INFO, ("HXPluginManager::DoesDLLExist(): other dll exists '%s'\n", (const char*)pLib->GetFileName()));
            return true;
        }
    }
    return false;
}

HX_RESULT HXPluginManager::SaveToArchive(const char* pszArchiveFile)
{
    DPRINTF(D_INFO, ("SaveToArchive(): writing '%s' (%d plugin dlls; %d other dlls)\n", pszArchiveFile, m_pluginDlls.GetCount(), m_otherDlls.GetCount()));
    HXPluginArchiveWriter ar;
    HX_RESULT hr = ar.Open(m_pContext, pszArchiveFile);
    if(SUCCEEDED(hr))
    {
        CHXSimpleList::Iterator iter;
        for(iter = m_pluginDlls.Begin(); iter != m_pluginDlls.End(); ++iter)
        {
            HXPluginDLL* pLib = (HXPluginDLL*) *iter;
            pLib->Archive(ar);
        }
        for(iter = m_otherDlls.Begin(); iter != m_otherDlls.End(); ++iter)
        {
            HXOtherDLL* pLib = (HXOtherDLL*) *iter;
            pLib->Archive(ar);
        }
    }
    ar.Close();
    return hr;
}

HX_RESULT HXPluginManager::LoadPluginDLLFromArchive(const char* pszMountPoint, HXPluginArchiveReader& ar)
{
    HXPluginDLL* pPluginDLL = new HXPluginDLL(m_pContext, pszMountPoint, ar);
    if( !pPluginDLL )
    {
        return HXR_OUTOFMEMORY;
    }
    pPluginDLL->AddRef();

    HX_ASSERT(!DoesDLLExist(pPluginDLL->GetFileName(), pPluginDLL->GetMountPoint()));

    // no need to load! that's the point of the archive
    HX_ASSERT(pPluginDLL->GetNumPlugins() > 0);

    m_pluginDlls.AddTail(pPluginDLL);

    return HXR_OK;
}

HX_RESULT HXPluginManager::LoadOtherDLLFromArchive(const char* pszMountPoint, HXPluginArchiveReader& ar)
{
    HXOtherDLL* pOtherDLL = new HXOtherDLL(pszMountPoint, ar);
    if( !pOtherDLL )
    {
        return HXR_OUTOFMEMORY;
    }

    pOtherDLL->AddRef();
    HX_ASSERT(!DoesDLLExist(pOtherDLL->GetFileName(), pOtherDLL->GetMountPoint()));
    m_otherDlls.AddTail(pOtherDLL);

    return HXR_OK;
}

//
// Try to re-construct plugin dll and associated plugin objects
// from saved archive for faster plugin discovery
//
// If you want to override this (i.e., after new dlls installed), delete the archive
//
HX_RESULT HXPluginManager::LoadFromArchive(const char* pszArchiveFile, const char* pszMountPoint)
{
    DPRINTF(D_INFO, ("LoadFromArchive(): looking for '%s'\n", pszArchiveFile));
    HXPluginArchiveReader ar;
    HX_RESULT hr = ar.Open(m_pContext, pszArchiveFile);
    if(SUCCEEDED(hr))
    {
        while(SUCCEEDED(hr) && !ar.AtEnd())
        {
            UINT32 type;
            ar.Read(type);
            switch(type)
            {
            case ARCHIVE_ID_PLUGIN_DLL:
                hr = LoadPluginDLLFromArchive(pszMountPoint,ar);
                break;
            case ARCHIVE_ID_OTHER_DLL:
                hr = LoadOtherDLLFromArchive(pszMountPoint, ar);
                break;
            default:
                hr = HXR_FAIL;
                break;
            }
        }
    
        ar.Close();

        DPRINTF(D_INFO, ("LoadFromArchive(): found %ld plugin dlls, %ld other dlls\n", m_pluginDlls.GetCount(), m_otherDlls.GetCount()));
    }
    else
    {
        DPRINTF(D_INFO, ("LoadFromArchive(): archive missing\n"));
    }

    return hr;
}

///////////////////////////////////////////////////////////////////////////////
//
// 'query plugin dlls'
//
// load all plugin dlls and determine associated plugin attributes
//
// called when:
//
//   1) a mount point is added
//   2) a mount point is removed and re-added (e.g., dynamic re-load)
//
// does nothing if dlls for mount point have already been loaded and queried
//
HX_RESULT HXPluginManager::ReloadPluginsWithFindFile(
               const char* pMountPoint, CFindFile* pFileFinder,
               IHXBuffer* pPathBuffer, const char* pszPluginDir)
{
    DPRINTF(D_INFO, ("HXPluginManager()::ReloadPluginsWithFindFile()\n"));
  
    CHXString strArchiveFile;
    IHXPreferences* pPrefs = 0;
    m_pContext->QueryInterface(IID_IHXPreferences, (void**) &pPrefs);
    HX_RESULT hr = ReadPrefCSTRING(pPrefs, "PluginArchiveFileName", strArchiveFile);
    HX_RELEASE(pPrefs);
    if(SUCCEEDED(hr))
    {
        // first try to recreate dll and plugin state from archive
        hr = LoadFromArchive(strArchiveFile, pMountPoint); 
    }
    if(HXR_OUTOFMEMORY == hr)
    {
        return hr;
    }
    
    // iterate files in this plugin directory
    hr = HXR_OK;
    bool bWriteArchive = false;
    const char* pszDllName = pFileFinder->FindFirst();
    for (; pszDllName; pszDllName = pFileFinder->FindNext())
    {
        if( DoesDLLExist(pszDllName, pMountPoint) )
        {
            // we already have info about this dll (perhaps from achive)
            continue;
        }

        // since we found a dll we don't know about yet we need to update the archive
        bWriteArchive = true;

        // create plugin dll wrapper, assuming this is a plugin dll
        HXPluginDLL* pPluginDll  = new HXPluginDLL(m_pContext, pszDllName, pMountPoint);
        if(!pPluginDll)
        {
            // oom
	    hr = HXR_OUTOFMEMORY;
            break;
        }
        pPluginDll->AddRef();

        // load dll to force query of supported plugins
        hr = pPluginDll->Load();
        if (SUCCEEDED(hr))
        {
            // add successfully loaded dll to list
            pPluginDll->AddRef();
            m_pluginDlls.AddTail(pPluginDll);

            // Unload the dll. The dll was loaded only to query supported plugin 
            // info. It will be re-loaded only when actually needed, i.e., when
            // an instance of a plugin that it implements is requested.
            pPluginDll->Unload();
        }
        HX_RELEASE(pPluginDll);
        if (FAILED(hr))
        {
            if(HXR_OUTOFMEMORY == hr)
            {
                break;
            }

            // lib load attempt failed; add this to 'other' dll list (maybe it is a codec dll, e.g.)
            HXOtherDLL* pOtherDll  = new HXOtherDLL(pszDllName, pMountPoint);
            if( !pOtherDll)
            {
                //oom
                hr = HXR_OUTOFMEMORY;
                break;
            }
            pOtherDll->AddRef();
            m_otherDlls.AddTail(pOtherDll);
            bWriteArchive = true;
        }	
    }

    RebuildPluginList();

    // write archive now if it needs updating

⌨️ 快捷键说明

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