hxplugindll.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:13k
源码类别:

Symbian

开发平台:

C/C++

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