hxplugindll.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:13k
源码类别:

Symbian

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Source last modified: $Id: hxplugindll.cpp,v 1.2.2.1 2004/07/09 02:07:27 hubbe Exp $
  3.  * 
  4.  * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
  5.  * 
  6.  * The contents of this file, and the files included with this file,
  7.  * are subject to the current version of the RealNetworks Public
  8.  * Source License (the "RPSL") available at
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed
  10.  * the file under the current version of the RealNetworks Community
  11.  * Source License (the "RCSL") available at
  12.  * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
  13.  * will apply. You may also obtain the license terms directly from
  14.  * RealNetworks.  You may not use this file except in compliance with
  15.  * the RPSL or, if you have a valid RCSL with RealNetworks applicable
  16.  * to this file, the RCSL.  Please see the applicable RPSL or RCSL for
  17.  * the rights, obligations and limitations governing use of the
  18.  * contents of the file.
  19.  * 
  20.  * Alternatively, the contents of this file may be used under the
  21.  * terms of the GNU General Public License Version 2 or later (the
  22.  * "GPL") in which case the provisions of the GPL are applicable
  23.  * instead of those above. If you wish to allow use of your version of
  24.  * this file only under the terms of the GPL, and not to allow others
  25.  * to use your version of this file under the terms of either the RPSL
  26.  * or RCSL, indicate your decision by deleting the provisions above
  27.  * and replace them with the notice and other provisions required by
  28.  * the GPL. If you do not delete the provisions above, a recipient may
  29.  * use your version of this file under the terms of any one of the
  30.  * RPSL, the RCSL or the GPL.
  31.  * 
  32.  * This file is part of the Helix DNA Technology. RealNetworks is the
  33.  * developer of the Original Code and owns the copyrights in the
  34.  * portions it created.
  35.  * 
  36.  * This file, and the files included with this file, is distributed
  37.  * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
  38.  * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
  39.  * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
  40.  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
  41.  * ENJOYMENT OR NON-INFRINGEMENT.
  42.  * 
  43.  * Technology Compatibility Kit Test Suite(s) Location:
  44.  *    http://www.helixcommunity.org/content/tck
  45.  * 
  46.  * Contributor(s):
  47.  * 
  48.  * ***** END LICENSE BLOCK ***** */
  49. #include "hxtypes.h"
  50. #include "hlxclib/sys/stat.h"
  51. #include "hlxclib/stdio.h"
  52. #include "hxresult.h"
  53. #include "hxassert.h"
  54. #include "hxcom.h"
  55. #include "hxcomm.h"
  56. #include "hxplugn.h" //IHXPluginFactory
  57. #include "ihxpckts.h" // IHXBuffer
  58. #include "hxstring.h"
  59. #include "hxslist.h"
  60. #include "pathutil.h"
  61. #include "dllacces.h"
  62. #include "dllpath.h"
  63. #include "debug.h"
  64. #include "hxheap.h"
  65. #ifdef _DEBUG
  66. #undef HX_THIS_FILE
  67. static const char HX_THIS_FILE[] = __FILE__;
  68. #endif
  69. #if defined(_STATICALLY_LINKED)
  70. #include "staticff.h"
  71. #endif
  72. #include "hxpluginarchive.h"
  73. #include "hxplugin.h"
  74. #include "hxplugindll.h"
  75. BEGIN_INTERFACE_LIST_NOCREATE(HXPluginDLL)
  76. END_INTERFACE_LIST
  77. HXPluginDLL::HXPluginDLL( IUnknown* pContext,
  78.                          const char* pszFileName, 
  79.                          const char * pszMountPoint)
  80. : m_fpCreateInstance(0)
  81. , m_fpShutdown(0)
  82. , m_fCanUnload(0)
  83. , m_strFileName(pszFileName)
  84. , m_strMountPoint(pszMountPoint)
  85. , m_pluginCount(0)
  86. , m_pDLLAccess(0)
  87. , m_bHasFactory(FALSE)
  88. , m_bLoaded(FALSE)
  89. , m_pContext(0)
  90. , m_pClassFactory(0)
  91. {
  92.     DPRINTF(D_INFO, ("HXPluginDLL::HXPluginDLL()n"));
  93.     Init(pContext);
  94.     
  95. }
  96. // common ctor init
  97. void HXPluginDLL::Init(IUnknown* pContext)
  98. {
  99.     HX_ASSERT(pContext);
  100.     m_pContext = pContext;
  101.     m_pContext->AddRef();
  102.     m_pContext->QueryInterface(IID_IHXCommonClassFactory, (void**)&m_pClassFactory);
  103.     m_pDLLAccess = new DLLAccess();
  104. }
  105.  
  106. // deserializing ctor
  107. HXPluginDLL::HXPluginDLL( IUnknown* pContext,
  108.                          const char* pszMountPoint, 
  109.                          HXPluginArchiveReader& ar)
  110. : m_fpCreateInstance(0)
  111. , m_fpShutdown(0)
  112. , m_fCanUnload(0)
  113. , m_strMountPoint( pszMountPoint )
  114. , m_pluginCount(0)
  115. , m_pDLLAccess(0)
  116. , m_bHasFactory(FALSE)
  117. , m_bLoaded(FALSE)
  118. , m_pContext(0)
  119. {
  120.     DPRINTF(D_INFO, ("HXPluginDLL::HXPluginDLL()n"));
  121.     Init(pContext);
  122.     HX_ASSERT(!ar.AtEnd());
  123.     ar.Read(m_strFileName);
  124.     ar.Read(m_bHasFactory);
  125.     ar.Read(m_pluginCount);
  126.     HX_ASSERT(m_pluginCount > 0);
  127.     
  128.     DPRINTF(D_INFO, ("HXPluginDLL::HXPluginDLL(): '%s' - %u pluginsn", (const char*)m_strFileName, m_pluginCount));
  129.     for(UINT16 idx = 0; idx < m_pluginCount; ++idx)
  130.     {
  131. HXPlugin* pPlugin = new HXPlugin(m_pContext, ar);
  132.         if(pPlugin)
  133.         {
  134.             pPlugin->AddRef();
  135.     HX_RESULT hr = pPlugin->Init(this, idx);
  136.             if(SUCCEEDED(hr))
  137.             {
  138.                 m_plugins.AddTail(pPlugin);
  139.             }
  140.         }
  141.     }
  142.     
  143. }
  144. // serialize object
  145. void HXPluginDLL::Archive(HXPluginArchiveWriter& ar)
  146. {
  147.     ar.Write(UINT32(ARCHIVE_ID_PLUGIN_DLL));
  148.     ar.Write(m_strFileName);
  149.     ar.Write(m_bHasFactory);
  150.     ar.Write(m_pluginCount);
  151.   
  152.     for(CHXSimpleList::Iterator iter = m_plugins.Begin(); iter != m_plugins.End(); ++iter)
  153.     {
  154. HXPlugin* pPlugin = (HXPlugin*) *iter;
  155.         pPlugin->Archive(ar);
  156.     }
  157.     ar.Break();
  158. }
  159. HXPluginDLL::~HXPluginDLL()
  160. {
  161.     DPRINTF(D_INFO, ("HXPluginDLL::~HXPluginDLL()n"));
  162.     // force DLL to unload
  163.     Unload(true);
  164.     // clear plugins
  165.     CHXSimpleList::Iterator iter = m_plugins.Begin();
  166.     for( ; iter != m_plugins.End(); ++iter)
  167.     {
  168. HXPlugin* pPlug = (HXPlugin*) *iter;
  169. pPlug->Release();
  170.     }
  171.     m_plugins.RemoveAll();
  172.     HX_DELETE(m_pDLLAccess);
  173.     HX_RELEASE(m_pContext);
  174.     HX_RELEASE(m_pClassFactory);
  175. }
  176. void HXPluginDLL::AddPlugins(CHXSimpleList& list)
  177. {
  178.     for(CHXSimpleList::Iterator iter = m_plugins.Begin(); iter != m_plugins.End(); ++iter)
  179.     {
  180. HXPlugin* pPlugin = (HXPlugin*) *iter;
  181.         pPlugin->AddRef();
  182. list.AddTail(pPlugin);
  183.     }
  184. }
  185. //
  186. // Load() Helper
  187. //
  188. // Instanciate a plugin wrapper for each plugin this dll
  189. // can instanciate. Called after Load().
  190. //
  191. HX_RESULT HXPluginDLL::CreatePlugins()
  192. {
  193.     HX_ASSERT(m_bLoaded);
  194.     DPRINTF(D_INFO, ("HXPluginDLL::CreatePlugins()n"));
  195.     HX_RESULT hr = HXR_FAIL;
  196.     
  197.     for(UINT16 idx = 0; idx < m_pluginCount; ++idx)
  198.     {
  199. HXPlugin* pPlugin = new HXPlugin(m_pContext);
  200. if(!pPlugin)
  201. {
  202.     hr = HXR_OUTOFMEMORY;
  203.             break;
  204. }
  205. pPlugin->AddRef();
  206.  
  207.         pPlugin->Init(this, idx);
  208.      
  209. IUnknown* pUnk = NULL;
  210. if( SUCCEEDED(pPlugin->GetPlugin(pUnk)) )
  211. {
  212.     IHXComponentPlugin* pComponentPlugin = NULL;
  213.     if( SUCCEEDED( pUnk->QueryInterface( IID_IHXComponentPlugin, (void**) &pComponentPlugin ) ) )
  214.     {
  215. // We don't need this.
  216. HX_RELEASE( pPlugin );
  217. CreateComponentPlugins(pComponentPlugin );
  218. HX_RELEASE( pComponentPlugin );
  219.     }
  220.     else
  221.     {
  222. IHXPlugin* pIHXPlugin;
  223. if( SUCCEEDED( pUnk->QueryInterface(IID_IHXPlugin, (void**)&pIHXPlugin ) ) )
  224. {
  225.     pPlugin->GetValuesFromDLL(pIHXPlugin);
  226.     m_plugins.AddTail(pPlugin);
  227.     pIHXPlugin->Release();
  228. }
  229.     }
  230. }
  231.         else
  232.         {
  233.             // This plugin doesn't work.  Delete it.
  234.     HX_RELEASE( pPlugin );
  235. }
  236. HX_RELEASE( pUnk );
  237.     }
  238.     return hr;
  239. }
  240. //
  241. // CreatePlugins() helper
  242. //
  243. void HXPluginDLL::CreateComponentPlugins( IHXComponentPlugin* pComponentPlugin )
  244. {
  245.     DPRINTF(D_INFO, ("HXPluginManager()::LoadComponentPlugins()n"));
  246.     IHXPlugin* pIHXPlugin = NULL;
  247.     if( SUCCEEDED( pComponentPlugin->QueryInterface(IID_IHXPlugin, (void**)&pIHXPlugin ) ) )
  248.     {
  249. for( UINT32 index = 0; index < pComponentPlugin->GetNumComponents(); index++ )
  250. {
  251.     IHXValues* pVal = 0;
  252.     if( SUCCEEDED( pComponentPlugin->GetComponentInfoAtIndex( index, pVal ) ) )
  253.     {
  254. // create a new plugin object
  255. HXPlugin* pPlugin = new HXPlugin( m_pContext );
  256. HX_ASSERT( pPlugin );
  257. // Setup plugin object (index is set 0 for component plugins)
  258. pPlugin->AddRef();
  259. pPlugin->Init(this, 0);
  260.                 pPlugin->AddComponentInfo(pVal); 
  261. // Put in plugin list
  262. m_plugins.AddTail(pPlugin);
  263. HX_RELEASE(pVal);
  264.     }
  265. }
  266. HX_RELEASE (pIHXPlugin);
  267.     }
  268. }
  269. HX_RESULT HXPluginDLL::Load()
  270. {
  271.     DPRINTF(D_INFO, ("HXPluginDLL()::Load()n"));
  272.     
  273.     HX_ASSERT(m_pContext);
  274.     HX_ASSERT(m_pClassFactory);
  275.     IUnknown* pInstance   = NULL;
  276.     IHXPlugin* pPlugin = NULL;
  277.     IHXPluginFactory* pIFactory = NULL;
  278.     HX_ASSERT(!m_bLoaded);
  279.     // dll full path
  280. #if !defined(_STATICALLY_LINKED) || defined(HELIX_CONFIG_CONSOLIDATED_CORE)
  281.     // we're not statically linked so we must use the mount point path
  282.     CHXString dllPath = HXPathUtil::CombinePath(m_strMountPoint, m_strFileName);
  283. #else
  284.     CHXString dllPath = m_strFileName;
  285. #endif
  286.     
  287.     DPRINTF(D_INFO, ("HXPluginDLL()::Load(): fullpath = '%s'n", (const char*)dllPath));
  288.     // load the DLL into memory
  289.     HX_RESULT hr = HXR_FAIL;
  290.     HX_ASSERT(dllPath.GetLength() > 0);
  291.     int dllLoadResult = m_pDLLAccess->open(dllPath);
  292.     if( dllLoadResult != DLLAccess::DLL_OK )
  293.     {
  294.         if ( DLLAccess::OUT_OF_MEMORY == dllLoadResult)
  295.         {
  296.             hr = HXR_OUTOFMEMORY;
  297.         }
  298.         DPRINTF(D_INFO, ("HXPluginDLL()::Load(): dll open failedn"));
  299. goto cleanup;
  300.     }
  301.     // HXCreateInstance is required
  302.     m_fpCreateInstance = (FPCREATEINSTANCE) m_pDLLAccess->getSymbol(HXCREATEINSTANCESTR);
  303.     if (NULL == m_fpCreateInstance)
  304.     {
  305.         DPRINTF(D_INFO, ("HXPluginDLL()::Load(): dll missing 'create instance'n"));
  306. goto cleanup;
  307.     }
  308.     // HXShutdown not required
  309.     m_fpShutdown    = (FPSHUTDOWN) m_pDLLAccess->getSymbol(HXSHUTDOWNSTR);
  310.     // CanUnload2 not required; CanUnload not used (deprecated)
  311.     m_fCanUnload    = (FPSHUTDOWN) m_pDLLAccess->getSymbol("CanUnload2");
  312.     // CreateInstance() must succeed
  313.     hr = m_fpCreateInstance( &pInstance );
  314.     if( FAILED(hr) )
  315.     {
  316.         DPRINTF(D_INFO, ("HXPluginDLL()::Load(): dll 'create instance' failedn"));
  317. goto cleanup;
  318.     }
  319.     
  320.     // A valid plugin must expose IHXPlugin and/or IHXPluginFactory.
  321.     if( SUCCEEDED( pInstance->QueryInterface( IID_IHXPluginFactory, (void**) &pIFactory ) ) )
  322.     {
  323. m_bHasFactory = TRUE;
  324. m_pluginCount = pIFactory->GetNumPlugins();
  325. HX_RELEASE( pIFactory );
  326.     }
  327.     else if( SUCCEEDED( pInstance->QueryInterface( IID_IHXPlugin, (void**) &pPlugin ) ) )
  328.     {
  329. m_bHasFactory = FALSE;
  330. m_pluginCount = 1;
  331. HX_RELEASE( pPlugin );
  332.     }
  333.     else
  334.     {
  335.         hr = HXR_FAIL;
  336. goto cleanup;
  337.     }
  338.     HX_RELEASE(pInstance);
  339.     m_bLoaded = TRUE;
  340.     // load plugins on first DLL load
  341.     if( m_plugins.GetCount() == 0)
  342.     {
  343.         DPRINTF(D_INFO, ("HXPluginDLL()::Load(): querying dll for plugins...n"));
  344.         CreatePlugins();
  345.     }
  346.     hr = HXR_OK;
  347. cleanup:
  348.     DPRINTF(D_INFO, ("HXPluginDLL()::Load(): result = 0x%08xn", hr));
  349.     return hr;
  350. }
  351. HX_RESULT HXPluginDLL::Unload(bool bForce)
  352. {
  353.     DPRINTF(D_INFO, ("HXPluginDLL()::Unload(): is_loaded = %d; force = %dn", m_bLoaded, bForce));
  354.     
  355.     HX_RESULT hr = HXR_OK;
  356.     if (m_bLoaded)
  357.     {
  358.         hr = HXR_FAIL;
  359.         HX_ASSERT(m_pDLLAccess);
  360. if (bForce || (m_fCanUnload && m_fCanUnload() == HXR_OK) )
  361. {
  362.             DPRINTF(D_INFO, ("HXPluginDLL()::Unload(): unloading ('%s')n", (const char*)m_strFileName));
  363.     if (m_fpShutdown)
  364.     {
  365. m_fpShutdown();
  366. m_fpShutdown = NULL;
  367.     }
  368.             m_pDLLAccess->close();
  369.     m_bLoaded = FALSE;
  370.     hr = HXR_OK;
  371. }
  372.     }
  373.     return hr;
  374. }
  375. BOOL HXPluginDLL::IsLoaded()
  376. {
  377.     return m_bLoaded;
  378. }
  379. HX_RESULT HXPluginDLL::CreateInstance(IUnknown** ppUnk, UINT32 uIndex)
  380. {
  381.     DPRINTF(D_INFO, ("HXPluginDLL()::CreateInstance(): '%s': idx = %lun", (const char*)m_strFileName, uIndex));
  382.     HX_ASSERT(m_bLoaded);
  383.     HX_RESULT hr = HXR_FAIL;
  384.     if (m_bLoaded)
  385.     {
  386.         if (!m_bHasFactory)
  387.         {
  388.     hr = m_fpCreateInstance(ppUnk);
  389.         }
  390.         else
  391.         {
  392.             HX_ASSERT( uIndex < m_pluginCount);
  393.     if (uIndex < m_pluginCount)
  394.             {
  395.         IUnknown* pUnk;
  396.         IHXPluginFactory* pPluginFactory;
  397.         m_fpCreateInstance(&pUnk);
  398.                 HX_ASSERT(pUnk);
  399.         hr = pUnk->QueryInterface(IID_IHXPluginFactory, (void**) &pPluginFactory);
  400.                 HX_ASSERT(pPluginFactory);
  401.                 if(SUCCEEDED(hr))
  402.                 {
  403.             hr = pPluginFactory->GetPlugin((UINT16)uIndex, ppUnk);
  404.                     HX_RELEASE(pPluginFactory);
  405.                 }
  406.                 HX_RELEASE(pUnk);
  407.             }
  408.         }
  409.     }
  410.     
  411.     return hr;
  412. }
  413. BEGIN_INTERFACE_LIST_NOCREATE(HXOtherDLL)
  414. END_INTERFACE_LIST
  415. // ctor
  416. HXOtherDLL::HXOtherDLL(const char* pszFileName, const char* pszMountPoint)
  417. : m_strFileName(pszFileName)
  418. , m_strMountPoint(pszMountPoint)
  419. {
  420. }
  421. // deserializing ctor
  422. HXOtherDLL::HXOtherDLL(const char* pszMountPoint, HXPluginArchiveReader& ar)
  423. : m_strMountPoint(pszMountPoint)
  424. {
  425.     HX_ASSERT(!ar.AtEnd());
  426.     ar.Read(m_strFileName);
  427. }
  428. // serialize
  429. void HXOtherDLL::Archive(HXPluginArchiveWriter& ar)
  430. {
  431.     ar.Write(UINT32(ARCHIVE_ID_OTHER_DLL));
  432.     ar.Write(m_strFileName);
  433.     ar.Break();
  434. }