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

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. /****************************************************************************
  36.  *
  37.  *
  38.  *  Plugin information are stored into the registry in the following format:
  39.  *
  40.  * File Format Plugins: {dllpath;description;copyright;moreinfo;loadmultiple;mimetype1|mimetype2;extension1|extension2}{ ... }
  41.  *      ---------------------------------------------------------------------------------------------------
  42.  * One Plugin
  43.  *
  44.  * File System Plugins: {dllpath;description;copyright;moreinfo;loadmultiple;protocol;shortname}{ ... }
  45.  *      ----------------------------------------------------------------------------
  46.  * One Plugin
  47.  *
  48.  * Renderer Plugins:    {dllpath;description;copyright;moreinfo;loadmultiple;mimetype1|mimetype2}{ ... }
  49.  *      -----------------------------------------------------------------------------
  50.  * One Plugin
  51.  *
  52.  * Broadcast Plugins:   {dllpath;description;copyright;moreinfo;loadmultiple;type}{ ... }
  53.  *      --------------------------------------------------------------
  54.  * One Plugin
  55.  *
  56.  * Stream Description Plugins: {dllpath;description;copyright;moreinfo;loadmultiple;mimetype}{ ... }
  57.  *      ----------------------------------------------------------------------------
  58.  * One Plugin
  59.  *
  60.  * Allowance Plugins:   {dllpath;description;copyright;moreinfo;loadmultiple}{ ... }
  61.  *                           ---------------------------------------------------------
  62.  * One Plugin
  63.  *
  64.  * Misc. Plugins:      {dllpath;description;copyright;moreinfo;loadmultiple}{ ... }
  65.  *                           ---------------------------------------------------------
  66.  * One Plugin
  67.  *
  68.  * Plugins:      {dllpath;description;copyright;moreinfo;loadmultiple}{ ... }
  69.  *                           ---------------------------------------------------------
  70.  * One Plugin
  71.  *
  72.  */
  73. #include "hxtypes.h"
  74. #ifdef _WINDOWS
  75. #include <windows.h>
  76. #include <ctype.h>
  77. #endif
  78. #ifdef _MACINTOSH
  79. #include <ctype.h>
  80. #include "filespec.h"
  81. #include "filespecutils.h"
  82. #endif
  83. #if defined _UNIX
  84. #include <stdlib.h>
  85. #include <sys/param.h>
  86. #define _MAX_PATH MAXPATHLEN
  87. #elif defined (_MACINTOSH)
  88. #include <stdlib.h>
  89. #include "fullpathname.h"
  90. #include "chxdataf.h"
  91. #ifdef _MAC_MACHO
  92. #include <sys/stat.h>
  93. #else
  94. #include <stat.h>
  95. #endif
  96. #include <fcntl.h>
  97. #endif
  98. #include <stdio.h>
  99. #include "hlxclib/sys/stat.h"
  100. #include "hxresult.h"
  101. #include "hxassert.h"
  102. #include "hxcom.h"
  103. #include "ihxpckts.h"
  104. #include "hxfiles.h"
  105. #include "hxformt.h"
  106. #include "hxfwrtr.h"
  107. #include "hxrendr.h"
  108. #include "hxprefs.h"
  109. #include "hxplugn.h"
  110. #include "hxdtcvt.h"
  111. #include "hxphand.h"
  112. //#include "hxmeta.h"
  113. #include "hxsdesc.h"
  114. #include "hxauth.h"
  115. #include "hxallow.h"
  116. #include "hxerror.h"
  117. #include "hxcomm.h"
  118. #include "hxengin.h"
  119. #include "hxshtdn.h"
  120. #include "hxplgns.h"
  121. #include "hxmon.h"
  122. #include "chxpckts.h"
  123. #include "hxstring.h"
  124. #include "hxslist.h"
  125. #include "hxmap.h"
  126. #include "hxstrutl.h"
  127. #include "hxdir.h"
  128. #include "findfile.h"
  129. #include "dbcs.h"
  130. #include "hxbdwdth.h"
  131. #include "plghand2.h"
  132. #include "chxuuid.h"
  133. #include "md5.h"
  134. #include "dllacces.h"
  135. #include "dllpath.h"
  136. #include "hxperf.h"
  137. #include "rtsputil.h"
  138. #include "hxver.h"
  139. #include "hxheap.h"
  140. #ifdef _DEBUG
  141. #undef HX_THIS_FILE
  142. static const char HX_THIS_FILE[] = __FILE__;
  143. #endif
  144. #ifdef _STATICALLY_LINKED
  145. #include "staticff.h"
  146. #endif
  147. #if defined(HELIX_FEATURE_PREFERENCES)
  148. #include "hxprefs.h"
  149. #include "hxprefutil.h"
  150. #endif /* HELIX_FEATURE_PREFERENCES */
  151. /*
  152.  * XXXND These are also defined in geminc/gemplatformdata.h
  153.  */
  154. #define NAMESPACE_SEPARATOR ':'
  155. /*
  156.  *  Win98 does not allow reg keys that are larger than 16k a pop. we used this value to break up into more manageable bites
  157.  */
  158. #define PREF_CACHE_SIZE 10000
  159. /*
  160.     Load each plug-in, read info, store in memory and update prefs
  161.     This is only done if the plugin hash within the registery is not the same
  162.     as the plugin hash of the plugins directory.
  163. */
  164. const char* const Plugin2Handler::zm_pszValueSeperator = "|";
  165. const char* const Plugin2Handler::zm_pszListStart = "{";
  166. const char* const Plugin2Handler::zm_pszListEnd = "}";
  167. const char* const Plugin2Handler::zm_pszValueSeperator2= ",";
  168. const char* const Plugin2Handler::zm_pszKeyNameRegKey = "~KeyNames~";
  169. const char* const Plugin2Handler::zm_pszRegKeySeperator = "\";
  170. #if !defined(HELIX_CONFIG_NOSTATICS)
  171. BOOL Plugin2Handler::zm_bFasterPrefs = 0;
  172. #else
  173. const BOOL Plugin2Handler::zm_bFasterPrefs = 0;
  174. #endif
  175. const char* const Plugin2Handler::zm_pszFileExtension = OS_DLL_PATTERN_STRING;
  176. const char* const Plugin2Handler::zm_pszDirectorySeperator = OS_SEPARATOR_STRING;
  177. const char Plugin2Handler::zm_cDirectorySeperator = OS_SEPARATOR_CHAR;
  178. // XXXHP - temporary changes to track PR70528
  179. #ifdef REALPLAYER_PLUGIN_HANDLER_RESEARCH_
  180.     inline FILE* OpenErrorLog_ ()
  181.     {
  182.         static char const* const realPlayerErrorsLog = "rperrors.log";
  183.         static char const* const appendMode = "a+";
  184.         return fopen (realPlayerErrorsLog, appendMode);
  185.     }
  186.     inline void LogRegistryRegeneration_ (char const* pKey, IHXBuffer* pIEntry)
  187.     {
  188.        FILE* const logStream = OpenErrorLog_ ();
  189.        PRE_REQUIRE_VOID_RETURN (logStream);
  190.        fprintf (logStream, "--------------- INVALID REGISTRY ENTRY: ----------------------------n");
  191.        fprintf (logStream, "Key: %sn", pKey);
  192.        fprintf (logStream, "tData: [%s]n", pIEntry->GetBuffer ());
  193.        fprintf (logStream, "--------------------------------------------------------------------n");
  194.        fclose (logStream);
  195.     }
  196.     inline void LogCriticalError_ (char const* pErrorReport)
  197.     {
  198.        FILE* const logStream = OpenErrorLog_ ();
  199.        PRE_REQUIRE_VOID_RETURN (logStream);
  200.        fprintf (logStream, "---------------- CRITICAL ERROR ------------------------------------n");
  201.        fprintf (logStream, "%sn", pErrorReport);
  202.        fprintf (logStream, "--------------------------------------------------------------------n");
  203.        fclose (logStream);
  204.     }
  205. #else
  206.     inline void LogRegistryRegeneration_ (char const*, IHXBuffer*)
  207.     {
  208.     }
  209. #endif
  210. /**************************************************************************
  211. ****************************Plugin2Handler**********************************
  212. **************************************************************************/
  213. IMPLEMENT_COM_CREATE_FUNCS( Plugin2Handler )
  214. BEGIN_INTERFACE_LIST_NOCREATE( Plugin2Handler )
  215.     INTERFACE_LIST_ENTRY_SIMPLE( IHXCallback )
  216.     INTERFACE_LIST_ENTRY_SIMPLE( IHXPluginEnumerator )
  217.     INTERFACE_LIST_ENTRY_SIMPLE( IHXPluginReloader )
  218.     INTERFACE_LIST_ENTRY_SIMPLE( IHXPlugin2Handler )
  219.     INTERFACE_LIST_ENTRY_SIMPLE( IHXPlugin2HandlerEnumeratorInterface )
  220.     INTERFACE_LIST_ENTRY_SIMPLE( IHXPluginHandler3 )
  221.     INTERFACE_LIST_ENTRY_SIMPLE( IHXPluginDatabase )
  222. END_INTERFACE_LIST
  223. inline HX_RESULT Plugin2Handler::VerifyChecksum_ (const char* pData)
  224. {
  225.     REQUIRE_RETURN (pData, HXR_INVALID_PARAMETER);
  226.     static const char endEntry = '}';
  227.     static const int error = -1;
  228.     // find the last end-marker of the last entry.
  229.     const CHXString data = pData;
  230.     const int lastEntry = data.ReverseFind (endEntry);
  231.     REQUIRE_RETURN_QUIET (lastEntry != error, HXR_FAIL);
  232.     // the checksum should be equal to the position of the end of the last entry plus 1.
  233.     const int calculatedChecksum = lastEntry + 1;
  234.     // read in the actual checksum.
  235.     const CHXString checksumString = pData + calculatedChecksum;
  236.     const int actualChecksum = ::atoi (checksumString);
  237.     return actualChecksum == calculatedChecksum ? HXR_OK : HXR_FAIL;
  238. }
  239. Plugin2Handler::Plugin2Handler() :
  240. m_pPluginDir( NULL )
  241.     , m_pPreferences(NULL)
  242.     , m_pErrorMessages(NULL)
  243.     , m_pContext(NULL)
  244.     , m_nCacheSizeBites( (1<<24) )
  245.     , m_pIScheduler(NULL)
  246.     , m_hScheduler( 0 )
  247. {
  248. }
  249. Plugin2Handler::~Plugin2Handler()
  250. {
  251.     // Make sure Close() got called
  252.     if( m_pContext )
  253.     {
  254. Close();
  255.     }
  256. }
  257. STDMETHODIMP Plugin2Handler::Init(IUnknown* pContext)
  258. {
  259.     HX_RESULT result = HXR_FAIL;
  260.     if( SUCCEEDED( result = RegisterContext( pContext ) ) )
  261.     {
  262. result = ReadFromRegistry();
  263.     }
  264.     return result;
  265. }
  266. STDMETHODIMP_(ULONG32) Plugin2Handler::GetNumOfPlugins2()
  267. {
  268.     return m_PluginList.GetCount();
  269. }
  270. STDMETHODIMP  Plugin2Handler::GetPluginInfo (UINT32 unIndex,
  271. REF(IHXValues*) /*OUT*/ pValues)
  272. {
  273.     HX_RESULT retVal = HXR_FAIL;
  274.     LISTPOSITION pPos = m_PluginList.FindIndex(unIndex);
  275.     if (pPos)
  276.     {
  277. Plugin2Handler::Plugin* pPlugin = (Plugin2Handler::Plugin*) m_PluginList.GetAt(pPos);
  278. if (pPlugin)
  279. {
  280.     retVal = pPlugin->GetPluginInfo(pValues);
  281.     pValues->AddRef();
  282. }
  283.     }
  284.     return retVal;
  285. }
  286. // ---------------------------------------------------------- IHXCallback
  287. // **********************************************
  288. STDMETHODIMP
  289. Plugin2Handler::Func( THIS )
  290. {
  291.     if ( !m_pIScheduler || !m_hScheduler )
  292.     {
  293. return( HXR_UNEXPECTED );
  294.     }
  295.     HX_RESULT outResult = HXR_OK;
  296.     // Our timer is infinite.
  297.     m_hScheduler = m_pIScheduler->RelativeEnter( this, kPingDuration );
  298.     if ( !m_hScheduler )
  299.     {
  300. outResult = HXR_FAIL;
  301.     }
  302.     UnloadDeadDLLs();
  303.     return( outResult );
  304. }
  305. // **********************************************
  306. // This function is called periodically when the plugin handler
  307. // object is pinged by the scheduler.
  308. void Plugin2Handler::UnloadDeadDLLs( void )
  309. {
  310.     HX_LOG_BLOCK( "Plugin2Handler::UnloadDeadDLLs" );
  311.     LISTPOSITION posCanUnload = m_CanUnload2DllList.GetHeadPosition();
  312.     while ( posCanUnload )
  313.     {
  314. // Save off current position for delete.
  315. LISTPOSITION posAt = posCanUnload;
  316. // Get current item, and increment position.
  317. Plugin2Handler::PluginDLL* pPluginDLLCanUnload = (Plugin2Handler::PluginDLL*) m_CanUnload2DllList.GetNext( posCanUnload );
  318. if ( pPluginDLLCanUnload )
  319. {
  320.     pPluginDLLCanUnload->Unload( TRUE );  // TRUE: "safe" unload
  321. }
  322.     }
  323. }
  324. /*
  325.     ReconnectDLL()
  326.     This replaces one PluginDLL in m_PluginDLLList with a new instance.
  327.     It removes any plugins that refered to the old DLL.
  328.  */
  329. void Plugin2Handler::ReconnectDLL(const char* pszDLLName, Plugin2Handler::PluginDLL* pNewDLL)
  330. {
  331.     HX_LOG_BLOCK( "Plugin2Handler::ReconnectDLL" );
  332.     // before we add this to the tail we must check to see if this
  333.     // plugin is already within the list....
  334.     Plugin2Handler::PluginDLL* pOldPluginDll = NULL;
  335.     LISTPOSITION pPos = NULL;
  336.     if (m_FileNameMap.Lookup(pszDLLName, (void*&)pOldPluginDll))
  337.     {
  338. pPos = m_PluginDLLList.Find(pOldPluginDll);
  339. if (pPos)
  340. {
  341.     m_PluginDLLList.RemoveAt(pPos);
  342. }
  343. // now see who the heck was connected to this pluginDLL
  344. pPos = m_PluginList.GetHeadPosition();
  345. while( pPos )
  346. {
  347.     // Save off current position for delete
  348.     LISTPOSITION posAt = pPos;
  349.     // Get current item, and increment position
  350.     Plugin2Handler::Plugin* pPlugin = (Plugin2Handler::Plugin*) m_PluginList.GetNext( pPos );
  351.     // If this plugin belongs to the old DLL, remove it.
  352.     if( pPlugin && pPlugin->GetDLL() == pOldPluginDll )
  353.     {
  354. // Delete from the saved position
  355. m_PluginList.RemoveAt( posAt );
  356. HX_RELEASE( pPlugin );
  357.     }
  358. }
  359. HX_RELEASE(pOldPluginDll);
  360.     }
  361.     m_PluginDLLList.AddTail(pNewDLL);
  362.     m_FileNameMap.SetAt(pszDLLName, pNewDLL);
  363. }
  364. /*
  365.     LoadDLL()
  366.     This is called during a Refresh() (which is deprecated)
  367.     or if we determine that the DLL is dirty and needs to be updated
  368.  */
  369. Plugin2Handler::Errors Plugin2Handler::LoadDLL( char* pszDllName,
  370. PluginMountPoint* pMountPoint )
  371. {
  372.     Errors result     = NO_ERRORS;
  373.     UINT32 i     = 0;
  374.     struct stat stat_stuct;
  375.     IHXBuffer* pPathBuffer = pMountPoint->Path();
  376.     // Make sure there is no path in the pszDllName
  377.     HX_ASSERT( !strrchr(pszDllName, Plugin2Handler::zm_cDirectorySeperator) );
  378.     Plugin2Handler::PluginDLL* pPluginDll  = NULL;
  379.     if( !( pPluginDll = new Plugin2Handler::PluginDLL( pszDllName, pMountPoint, this ) ) )
  380.     {
  381. return MEMORY_ERROR;
  382.     }
  383.     pPluginDll->AddRef();
  384.     CHXString sFileWithPath = pPathBuffer->GetBuffer();
  385.     UINT32 len = sFileWithPath.GetLength();
  386.     if(len &&
  387.        sFileWithPath.GetAt(len - 1) != Plugin2Handler::zm_cDirectorySeperator)
  388.         sFileWithPath += Plugin2Handler::zm_cDirectorySeperator;
  389.     sFileWithPath += pszDllName;
  390.     if (NO_ERRORS==Stat(sFileWithPath, &stat_stuct))
  391.     {
  392.         pPluginDll->SetFileSize((INT32)stat_stuct.st_size);
  393.     }
  394.     result = pPluginDll->Load(m_pContext);
  395.     if (NO_ERRORS != result )
  396.     {
  397. goto cleanup;
  398.     }
  399.     // Set the hash
  400.     if (pPathBuffer)
  401.     {
  402. IHXBuffer* pNewChecksum = ChecksumFile( pszDllName, pPathBuffer );
  403. if (pNewChecksum)
  404. {
  405.     HX_RELEASE(pPathBuffer);
  406.     pPluginDll->SetHash((char*)pNewChecksum->GetBuffer());
  407.     HX_RELEASE(pNewChecksum);
  408. }
  409.     }
  410.     // Remove this DLL from the list of supported DLL (based on GUIDs)
  411.     RemoveDLLFromGUIDSupportLists(pszDllName);
  412.     // ReconnectDLL() replaces one PluginDLL object with another PluginDLL; however,
  413.     // both of these PluginDLL objects refer to the same DLL.  This ensures that
  414.     // only one PluginDLL object per DLL is in the m_PluginDLLList.
  415.     ReconnectDLL(pszDllName, pPluginDll);
  416.     for(i=0;i<pPluginDll->GetNumPlugins();i++)
  417.     {
  418. Plugin* pPlugin = NULL;
  419.      // create a new plugin object
  420. if (!(pPlugin = new Plugin(m_pContext)))
  421. {
  422.     return MEMORY_ERROR;
  423. }
  424. // Setup plugin information
  425. pPlugin->AddRef();
  426. pPlugin->SetDLL(pPluginDll);
  427. pPlugin->SetIndex((UINT16)i);
  428. pPlugin->SetInfoNeedsRefresh(TRUE);
  429. IUnknown* pUnk = NULL;
  430. if( NO_ERRORS != pPlugin->GetPlugin( pUnk ) )
  431. {
  432.     // This plugin doesn't work.  Delete it.
  433.     HX_RELEASE( pPlugin );
  434. }
  435. else
  436. {
  437.     IHXPluginNamespace* pPluginNamespace = NULL;
  438.     if (SUCCEEDED(pUnk->QueryInterface(IID_IHXPluginNamespace, (void**) &pPluginNamespace)))
  439.     {
  440. /*
  441.  * Memory for the IHXBuffer is allocated in the plugin
  442.  */
  443. IHXBuffer* pBuffer = NULL;
  444. if (SUCCEEDED(pPluginNamespace->GetPluginNamespace(pBuffer)))
  445. {
  446.     pPluginDll->SetNamespace(pBuffer);
  447.     HX_RELEASE(pBuffer);
  448. }
  449. HX_RELEASE(pPluginNamespace);
  450.     }
  451.     IHXComponentPlugin* pIIterator = NULL;
  452.     if( SUCCEEDED( pUnk->QueryInterface( IID_IHXComponentPlugin, (void**) &pIIterator ) ) )
  453.     {
  454. // We don't need this.
  455. HX_RELEASE( pPlugin );
  456. LoadPluginsFromComponentDLL( pPluginDll, pIIterator );
  457. HX_RELEASE( pIIterator );
  458.     }
  459.     else
  460.     {
  461. IHXPlugin* pIHXPlugin;
  462. if( SUCCEEDED( pUnk->QueryInterface(IID_IHXPlugin, (void**)&pIHXPlugin ) ) )
  463. {
  464.     pPlugin->GetValuesFromDLL(pIHXPlugin);
  465.     m_PluginList.AddTail(pPlugin);
  466.     // Print out some log info about the plugin we just loaded
  467.     {
  468. const char *pDesc, *pCopy, *pURL;
  469. ULONG32 ulVersionNumber = 0;
  470. BOOL junk;
  471. pIHXPlugin->GetPluginInfo(junk, pDesc, pCopy, pURL, ulVersionNumber);
  472. ReportError( HXLOG_INFO, pszDllName, pDesc );
  473.     }
  474.     // At this point since we have the HXPlugin we should query it to see if
  475.     // it supports any of the GUIDs which have been enumerated so far.
  476.     UINT32 nNumGUIDs = GetNumSupportedGUIDs();
  477.     for(; nNumGUIDs; nNumGUIDs--)
  478.     {
  479. CHXString pszGUID;
  480. GUID theGUID;
  481. GetGUIDForIndex(nNumGUIDs-1, pszGUID);
  482. CHXuuid::HXUuidFromString(pszGUID, (uuid_tt*)&theGUID);
  483. IUnknown* pQueryUnk;
  484. if (HXR_OK == pIHXPlugin->QueryInterface(theGUID, (void**)&pQueryUnk))
  485. {
  486.     AddSupportForGUID(pszGUID, pPluginDll, i);
  487.     HX_RELEASE(pQueryUnk);
  488. }
  489.     }
  490. //          if this is a required plugin, validate it     // XXXAH this could be a problem
  491. //          if (IsPluginRequired(pDesc, pPlugin))
  492. //          {
  493. //           bValidated = ValidateRequiredPlugin(pIHXPlugin, pPlugin);
  494. //          }
  495.     pIHXPlugin->Release();
  496. }
  497.     }
  498. }
  499. HX_RELEASE( pUnk );
  500.     }
  501. cleanup:
  502.     HX_RELEASE(pPathBuffer);
  503.     if (result != NO_ERRORS)
  504.     {
  505. HX_RELEASE( pPluginDll );
  506.     }
  507.     return result;
  508. }
  509. void Plugin2Handler::LoadPluginsFromComponentDLL( Plugin2Handler::PluginDLL* pPluginDll,
  510.     IHXComponentPlugin* pIIterator )
  511. {
  512.     IHXPlugin* pIHXPlugin = NULL;
  513.     if( SUCCEEDED( pIIterator->QueryInterface(IID_IHXPlugin, (void**)&pIHXPlugin ) ) )
  514.     {
  515. // XXXHP - this is now done in the PluginDLL::Load() method
  516. // pIHXPlugin->InitPlugin( m_pContext );
  517. for( UINT32 index = 0; index < pIIterator->GetNumComponents(); index++ )
  518. {
  519.     IHXValues* pIValues = NULL;
  520.     if( SUCCEEDED( pIIterator->GetComponentInfoAtIndex( index, pIValues ) ) )
  521.     {
  522. IHXBuffer* pBuffer = NULL;
  523. if (SUCCEEDED(pIValues->GetPropertyCString(PLUGIN_COMPONENT_NAME, pBuffer)))
  524. {
  525.     IHXBuffer* pNamespace = pPluginDll->GetNamespace();
  526.     if (pNamespace)
  527.     {
  528. CHXString TempNamespace = pNamespace->GetBuffer();
  529. TempNamespace += NAMESPACE_SEPARATOR;
  530. TempNamespace += pBuffer->GetBuffer();
  531. IHXBuffer* pTempBuffer = new CHXBuffer();
  532. pTempBuffer->AddRef();
  533. pTempBuffer->Set((BYTE*)(const char*)TempNamespace, TempNamespace.GetLength()+1);
  534. pIValues->SetPropertyCString(PLUGIN_COMPONENT_NAME, pTempBuffer);
  535. HX_RELEASE(pTempBuffer);
  536. HX_RELEASE(pNamespace);
  537.     }
  538.     HX_RELEASE(pBuffer);
  539. }
  540. // create a new plugin object
  541. Plugin* pPlugin = new Plugin( m_pContext );
  542. HX_ASSERT( pPlugin );
  543. // Setup plugin object
  544. pPlugin->AddRef();
  545. pPlugin->SetDLL( pPluginDll );
  546. // XXXP - this isn't necessary, the Plugin is initialized with an index of 0 if no index is found.
  547. // pPlugin->SetIndex( (UINT16) 0 );
  548. pPlugin->SetInfoNeedsRefresh( TRUE );
  549. // XXXND FIX  I don't like this specialized interface.
  550. // This gets the basic info from pIHXPlugin, and the rest from pValues
  551. pPlugin->InitializeComponentPlugin( pIHXPlugin, pIValues );
  552. // Put in plugin list
  553. m_PluginList.AddTail(pPlugin);
  554. // Stick CLSID in map
  555. AddPluginToIndices( pPlugin );
  556. HX_RELEASE( pIValues );
  557.     }
  558. }
  559. HX_RELEASE (pIHXPlugin);
  560.     }
  561. }
  562. STDMETHODIMP Plugin2Handler::ReloadPlugins()
  563. {
  564.     // now we have to tell all other players that they should also
  565.     // reload their plugins.
  566.     IHXShutDownEverything* pShutDown = NULL ;
  567.     if (HXR_OK == m_pContext->QueryInterface(IID_IHXShutDownEverything, (void**) &pShutDown))
  568.     {
  569. pShutDown->AskAllOtherPlayersToReload();
  570. HX_RELEASE(pShutDown);
  571.     }
  572.     // This will re-initialize all the MountPoints
  573.     return ReloadPluginsNoPropagate();
  574. }
  575. ///////////////////////////////////////////////////////////////////////////////
  576. //  These functions will find all plugins which are different
  577. //  then those loaded into the registry.
  578. //  It will then load them into memory, get their data, and unload them.
  579. //  It will return HXR_FAIL if some DLL has different values within the
  580. //  registry, and is presently in memory (how could this happen??)
  581. //  If anyone was keeping an index to a loaded DLL and assuming that it
  582. //  would remain constant ... that won't work!!
  583. HX_RESULT Plugin2Handler::ReloadPluginsNoPropagate()
  584. {
  585.     HX_LOG_BLOCK( "Plugin2Handler::ReloadPluginsNoPropagate" );
  586.     HX_RESULT result = HXR_OK;
  587.     // Reload them all.
  588.     for(CHXMapStringToOb::Iterator mp = m_MountPoints.Begin(); mp!=m_MountPoints.End(); ++mp)
  589.     {
  590. PluginMountPoint* pMountPoint = (PluginMountPoint*) *mp;
  591. if( FAILED( ReloadPluginsNoPropagate( pMountPoint ) ) )
  592. {
  593.     result = HXR_FAIL;
  594. }
  595.     }
  596.     return result;
  597. }
  598. HX_RESULT Plugin2Handler::ReloadPluginsNoPropagate( PluginMountPoint* pMountPoint )
  599. {
  600.     HX_LOG_BLOCK( "Plugin2Handler::ReloadPluginsNoPropagate(PluginMP*)" );
  601. #ifndef _STATICALLY_LINKED
  602.     CFindFile*      pFileFinder     = NULL;
  603. #else
  604.     CStaticFindFile*        pFileFinder     = NULL;
  605. #endif
  606.     IHXBuffer*  pPathBuffer     = NULL;
  607.     char*       pszPluginDir    = NULL;
  608.     ULONG32     nPluginDirLen   = 0;
  609.     char*       pszDllName      = 0;
  610.     IHXBuffer*  pNewChecksum    = 0;
  611.     BOOL        bRegIsDirty     = FALSE;
  612.     BOOL        bContinue;
  613.     // if we have no context do not proceed.
  614.     if (!m_pContext)
  615.     {
  616.         return INVALID_CONTEXT;
  617.     }
  618.     // If this is the 1st time, load everything into the registry.
  619. #ifndef _STATICALLY_LINKED
  620.     pPathBuffer = pMountPoint->Path();
  621.     if (!pPathBuffer)
  622.     {
  623.     return HXR_FAIL;
  624.     }
  625.     pPathBuffer->Get((UCHAR*&)pszPluginDir, nPluginDirLen);
  626.     if (!nPluginDirLen)
  627.     {
  628.     return HXR_FAIL;
  629.     }
  630. #else
  631.     pszPluginDir="";
  632. #endif
  633.     pFileFinder =
  634. #ifndef _STATICALLY_LINKED
  635.       CFindFile::CreateFindFile
  636. #else
  637.       CStaticFindFile::CreateFindFile
  638. #endif
  639.       (pszPluginDir, 0, Plugin2Handler::zm_pszFileExtension);
  640.     if (NULL == pFileFinder)
  641.     {
  642.     pPathBuffer->Release();
  643.     HX_DELETE(pFileFinder);
  644.     return HXR_FAIL;
  645.     }
  646.     pszDllName = pFileFinder->FindFirst();
  647.     BOOL bDLLIsDirty = FALSE;
  648.     while (pszDllName)
  649.     {
  650.     // See if this file exists in our list of pluginDLLs
  651.     BOOL bFound = FALSE;
  652.     CHXSimpleList::Iterator i;
  653.     Plugin2Handler::PluginDLL* pDLL = NULL;
  654.     bFound =  m_FileNameMap.Lookup(pszDllName, (void*&)pDLL);
  655.     // If it was not found it may a misc DLL -- ie not an
  656.     // RMA DLL. Thus, we should ignore it.
  657.     bContinue = FALSE;
  658.     if (!bFound)
  659.     {
  660.         for(i=m_MiscDLLList.Begin();i!=m_MiscDLLList.End(); ++i)
  661.         {
  662.         Plugin2Handler::OtherDLL* pOther = (Plugin2Handler::OtherDLL*) *i;
  663.         if (!stricmp(pOther->m_filename, pszDllName))
  664.         {
  665.             // ok we have a match does the checksum match?
  666.             pNewChecksum = ChecksumFile(pszDllName, pPathBuffer);
  667.             if (!strcmp((char*)pNewChecksum->GetBuffer(), pOther->m_fileChecksum))
  668.             {
  669.             HX_RELEASE(pNewChecksum);
  670.             bContinue = TRUE;
  671.             }
  672.             HX_RELEASE(pNewChecksum);
  673.         }
  674.         }
  675.     }
  676.     if (bContinue)
  677.     {
  678.         pszDllName = pFileFinder->FindNext();
  679.         continue;
  680.     }
  681.     if (bFound)
  682.     {
  683.         pNewChecksum    = ChecksumFile(pszDllName, pPathBuffer);
  684.         if (!strcasecmp(pDLL->GetHash(), (const char*)pNewChecksum->GetBuffer()))
  685.         {
  686.         pszDllName = pFileFinder->FindNext();
  687.         pNewChecksum->Release();
  688.         continue;   // old checksum == new checksum. no changes.
  689.         }
  690.         pNewChecksum->Release();
  691.         pNewChecksum = NULL;
  692.         // Delete all Plugins which are associated with this PluginDLL.
  693.         LISTPOSITION pPos = NULL;
  694.         if ( m_PluginList.GetCount() )
  695.         {
  696.             LISTPOSITION pPos = m_PluginList.GetHeadPosition();
  697.             while (pPos)
  698.             {
  699.                 // save off current position for delete
  700.                 LISTPOSITION posAt = pPos;
  701.                 Plugin2Handler::Plugin* pPlugin = (Plugin2Handler::Plugin*)m_PluginList.GetNext(pPos);
  702.                 HX_ASSERT(pPlugin);
  703.                 if ( pPlugin && pPlugin->GetDLL() == pDLL )
  704.                 {
  705.                     RemovePluginFromIndices( pPlugin );
  706.                     m_PluginList.RemoveAt( posAt );
  707.                     HX_RELEASE( pPlugin );
  708.                 }
  709.             }
  710.         }
  711.         // Remove the pluginDLL from the PluginDLL list.
  712.         pPos = m_PluginDLLList.Find(pDLL);
  713.         if (pPos)
  714.         {
  715.         m_PluginDLLList.RemoveAt(pPos);
  716.         m_FileNameMap.RemoveKey(pszDllName);
  717.         // Since this PluginDLL was unloaded, no need to keep
  718.         // it in the list of PluginDLLs which export CanUnload2().
  719.         LISTPOSITION posCanUnload = m_CanUnload2DllList.Find( pDLL );
  720.         if ( posCanUnload )
  721.         {
  722.             m_CanUnload2DllList.RemoveAt( posCanUnload );
  723.         }
  724.         }
  725.         bDLLIsDirty = TRUE;
  726.     }
  727.     else
  728.     {
  729.         bDLLIsDirty = TRUE;
  730.     }
  731.     if (bDLLIsDirty)
  732.     {
  733.         // if we got here we have a new dll.
  734.         Plugin2Handler::Errors loadResult;
  735.         loadResult = LoadDLL( pszDllName, pMountPoint );
  736.         if (loadResult!= NO_ERRORS)
  737.         {
  738.         // The DLL had one of the following problems:
  739.         // (1) the DLL was unloadable
  740.         // (2) the DLL did not have an HXCreateInstance
  741.         // (3) an instance could not be created.
  742.         // (4) It did not implement the PLUGIN interface
  743.         // if it was case 2,3,4 then we can safely never attempt to
  744.         // load the DLL again. However if it was (1) then we must attempt
  745.         // to load the DLL ever time through since it was possibly unloadable due
  746.         // to an imp-lib that will be satisfied lated (without modifing the
  747.         // dll). Jeeze. That comment is UNREADABLE. I have to take effective written
  748.         // english again!
  749.         if (loadResult!=CANT_OPEN_DLL)
  750.         {
  751.             Plugin2Handler::OtherDLL* pDLLData = new Plugin2Handler::OtherDLL;
  752.             pDLLData->m_filename = pszDllName;
  753.             pDLLData->m_pMountPoint = pMountPoint;
  754.             pNewChecksum            = ChecksumFile(pszDllName, pPathBuffer);
  755.             if (pNewChecksum)
  756.             {
  757.             pDLLData->m_fileChecksum    = (char*)pNewChecksum->GetBuffer();
  758.             HX_RELEASE(pNewChecksum);
  759.             bRegIsDirty=TRUE;
  760.             m_MiscDLLList.AddTail(pDLLData);
  761.             }
  762.             else
  763.             {
  764.             HX_DELETE(pDLLData);
  765.             }
  766.         }
  767.         }
  768.         else
  769.         {
  770.             bRegIsDirty = TRUE;
  771.         }
  772.     }
  773.     pszDllName = pFileFinder->FindNext();
  774.     }
  775.     // now get the bandwidth data on all renderer plugins
  776.     IHXValues* pVal = new CHXHeader();
  777.     pVal->AddRef();
  778.     IHXBuffer* pBuffer = new CHXBuffer();
  779.     pBuffer->AddRef();
  780.     pBuffer->Set((const UCHAR*)PLUGIN_RENDERER_TYPE, strlen(PLUGIN_RENDERER_TYPE)+1);
  781.     pVal->SetPropertyCString(PLUGIN_CLASS, pBuffer);
  782.     HX_RELEASE(pBuffer);
  783.     for(CHXSimpleList::Iterator i = m_PluginList.Begin(); i!=m_PluginList.End(); ++i)
  784.     {
  785.     Plugin2Handler::Plugin* pPlug = (Plugin2Handler::Plugin*)*i;
  786.     if (pPlug->DoesInfoNeedsRefresh() && pPlug->DoesMatch(pVal))
  787.     {
  788.         pPlug->GetBandwidthInfo();
  789.     }
  790.     }
  791.     HX_RELEASE(pVal);
  792.     if (bRegIsDirty)
  793.     {
  794.     // Pass the MountPoint to this so it can write the
  795.     // specific plugins to the correct place
  796.     WritePluginInfo( pMountPoint );
  797.     }
  798.     HX_RELEASE(pPathBuffer);
  799.     HX_DELETE(pFileFinder);
  800.     return HXR_OK;
  801. }
  802. STDMETHODIMP Plugin2Handler::FindIndexUsingValues (IHXValues* pValues,
  803. REF(UINT32) unIndex)
  804. {
  805.     CHXSimpleList   PossibleValues;
  806.     CHXSimpleList   PossibleIndexes;
  807.     UINT32     j = 0;
  808.     IHXValues*     pPluginValues = NULL;
  809.     IHXBuffer*     pBuffer = NULL;
  810.     CHXSimpleList::Iterator i = m_PluginList.Begin();
  811.     for(; i!= m_PluginList.End(); ++i, j++)
  812.     {
  813. Plugin2Handler::Plugin* pPlugin = (Plugin2Handler::Plugin*) *i;
  814. if (pPlugin->DoesMatch(pValues))
  815. {
  816.     PossibleValues.AddTail(pPlugin);
  817.     PossibleIndexes.AddTail((void*)j);
  818. }
  819.     }
  820.     if (PossibleValues.Begin() == PossibleValues.End())
  821.     {
  822. unIndex = 0;
  823. return HXR_FAIL;
  824.     }
  825.     /****************************************************************
  826.     ** Presently when we arrive at this spot with more than one
  827.     ** plugin which matches the search criteria, we simply take
  828.     ** the first one found. If this is not satisfactory then
  829.     ** some method can be added which will process the list based
  830.     ** upon some criteria.
  831.     ****************************************************************/
  832.     // if there are multiple plugins found, we will pick the one whose
  833.     // plugin description contains "RealNetworks"
  834.     if (PossibleValues.GetCount() > 1)
  835.     {
  836. j = 0;
  837. for(i = PossibleValues.Begin(); i!= PossibleValues.End(); ++i, j++)
  838. {
  839.     Plugin2Handler::Plugin* pPlugin = (Plugin2Handler::Plugin*) *i;
  840.     if (HXR_OK == pPlugin->GetPluginInfo(pPluginValues) && pPluginValues)
  841.     {
  842. if (HXR_OK == pPluginValues->GetPropertyCString(PLUGIN_DESCRIPTION2, pBuffer) &&
  843.     pBuffer)
  844. {
  845.     if (strstr((const char*)pBuffer->GetBuffer(), "RealNetworks"))
  846.     {
  847. LISTPOSITION pos = PossibleIndexes.FindIndex(j);
  848. unIndex = (UINT32)(PTR_INT)PossibleIndexes.GetAt(pos);
  849. HX_RELEASE(pBuffer);
  850. return HXR_OK;
  851.     }
  852. }
  853. HX_RELEASE(pBuffer);
  854.     }
  855. }
  856.     }
  857.     i = PossibleIndexes.Begin();
  858.     unIndex = (UINT32)(PTR_INT)*i;
  859.     return HXR_OK;
  860. }
  861. STDMETHODIMP Plugin2Handler::GetInstance (UINT32 index, REF(IUnknown*) pUnknown)
  862. {
  863.     pUnknown = NULL;
  864.     LISTPOSITION pPos = m_PluginList.FindIndex(index);
  865.     if (pPos)
  866.     {
  867. Plugin2Handler::Plugin* pPlugin = (Plugin2Handler::Plugin*) m_PluginList.GetAt(pPos);
  868. if (pPlugin)
  869. {
  870.     Errors retVal = pPlugin->GetInstance(pUnknown);
  871.     if (retVal== NO_ERRORS)
  872.     {
  873. return HXR_OK;
  874.     }
  875. }
  876.     }
  877.     return HXR_FAIL;
  878. }
  879. STDMETHODIMP Plugin2Handler::FindIndexUsingStrings (char* PropName1,
  880.     char* PropVal1,
  881.     char* PropName2,
  882.     char* PropVal2,
  883.     char* PropName3,
  884.     char* PropVal3,
  885.     REF(UINT32) unIndex)
  886. {
  887.     unIndex = 0;
  888.     // PropName and PropVal have to to valid tuple
  889.     if ((PropName1 && !PropVal1)    ||
  890. (PropName2 && !PropVal2)    ||
  891. (PropName3 && !PropVal3)    ||
  892. (!PropName1 && PropVal1)    ||
  893. (!PropName2 && PropVal2)    ||
  894. (!PropName3 && PropVal3))
  895. return HXR_FAIL;
  896.     IHXValues* pValues;
  897.     HX_RESULT   retVal = HXR_FAIL;
  898.     CHXHeader* pHeader = new CHXHeader;
  899.     pHeader->QueryInterface(IID_IHXValues,  (void**)&pValues);
  900.     AddToValues(pValues, PropName1, PropVal1, eString);
  901.     AddToValues(pValues, PropName2, PropVal2, eString);
  902.     AddToValues(pValues, PropName3, PropVal3, eString);
  903.     retVal = FindIndexUsingValues(pValues, unIndex);
  904.     pValues->Release();
  905.     return retVal;
  906. }
  907. STDMETHODIMP Plugin2Handler::FindPluginUsingValues (IHXValues* pValues,
  908. REF(IUnknown*) pUnk)
  909. {
  910.     return FindPluginUsingValues( pValues, pUnk, NULL );
  911. }
  912. HX_RESULT Plugin2Handler::FindGroupOfPluginsUsingStrings(char* PropName1,
  913.     char* PropVal1,
  914.     char* PropName2,
  915.     char* PropVal2,
  916.     char* PropName3,
  917.     char* PropVal3,
  918.     REF(CPluginEnumerator*) pEnumerator)
  919. {
  920.     // PropName and PropVal have to to valid tuple
  921.     if ((PropName1 && !PropVal1)    ||
  922. (PropName2 && !PropVal2)    ||
  923. (PropName3 && !PropVal3)    ||
  924. (!PropName1 && PropVal1)    ||
  925. (!PropName2 && PropVal2)    ||
  926. (!PropName3 && PropVal3))
  927. return HXR_FAIL;
  928.     IHXValues* pValues;
  929.     HX_RESULT   retVal = HXR_FAIL;
  930.     CHXHeader* pHeader = new CHXHeader;
  931.     pHeader->QueryInterface(IID_IHXValues,  (void**)&pValues);
  932.     AddToValues(pValues, PropName1, PropVal1, eString);
  933.     AddToValues(pValues, PropName2, PropVal2, eString);
  934.     AddToValues(pValues, PropName3, PropVal3, eString);
  935.     retVal = FindGroupOfPluginsUsingValues(pValues, pEnumerator);
  936.     pValues->Release();
  937.     return retVal;
  938. }
  939. HX_RESULT Plugin2Handler::FindGroupOfPluginsUsingValues(IHXValues* pValues,
  940. REF(CPluginEnumerator*) pEnumerator)
  941. {
  942.     CHXSimpleList::Iterator i = m_PluginList.Begin();
  943.     pEnumerator = NULL;
  944.     for(; i!= m_PluginList.End(); ++i)
  945.     {
  946. Plugin2Handler::Plugin* pPlugin = (Plugin2Handler::Plugin*) *i;
  947. if (pPlugin->DoesMatch(pValues))
  948. {
  949.     if (!pEnumerator)
  950.     {
  951. pEnumerator = new CPluginEnumerator();
  952.     }
  953.     pEnumerator->Add(pPlugin);
  954. }
  955.     }
  956.     if (!pEnumerator)
  957.     {
  958. return HXR_FAIL;
  959.     }
  960.     return HXR_OK;
  961. }
  962. STDMETHODIMP Plugin2Handler::GetNumPluginsSupporting(REFIID iid, REF(UINT32) nNumPlugins)
  963. {
  964.     CHXString     sGUID;
  965.     CHXSimpleList*  pSupportList;
  966.     CHXuuid::HXUuidToString( (uuid_tt*) &iid, &sGUID);
  967.     if (!m_GUIDtoSupportList.Lookup(sGUID, (void*&)pSupportList))
  968.     {
  969. return HXR_FAIL;
  970.     }
  971.     nNumPlugins = pSupportList->GetCount();
  972.     return HXR_OK;
  973. }
  974. STDMETHODIMP Plugin2Handler::GetPluginIndexSupportingIID(REFIID iid, UINT32 nPluginIndex, REF(UINT32) nIndexOut)
  975. {
  976.     CHXString     sGUID;
  977.     CHXSimpleList*  pSupportList;
  978.     CHXuuid::HXUuidToString( (uuid_tt*) &iid, &sGUID);
  979.     if (m_GUIDtoSupportList.Lookup(sGUID, (void*&)pSupportList))
  980.     {
  981. if (nPluginIndex < (UINT32)pSupportList->GetCount())
  982. {
  983.     LISTPOSITION pPos = pSupportList->FindIndex(nPluginIndex);
  984.     PluginSupportingGUID* pSupportItem = (PluginSupportingGUID*) pSupportList->GetAt(pPos);
  985.     if (FindPlugin(pSupportItem ->m_filename, pSupportItem->m_nIndexInDLL, nIndexOut))
  986.     {
  987. return HXR_OK;
  988.     }
  989. }
  990.     }
  991.     return HXR_FAIL;
  992. }
  993. STDMETHODIMP Plugin2Handler::AddSupportedIID(REFIID iid)
  994. {
  995.     //1st scan to see if this GUID is already supported...
  996.     CHXString     sGUID;
  997.     CHXSimpleList*  pSupportList;
  998.     CHXuuid::HXUuidToString( (uuid_tt*) &iid, &sGUID);
  999.     if (m_GUIDtoSupportList.Lookup(sGUID, (void*&)pSupportList))
  1000.     {
  1001. #ifdef _MACINTOSH
  1002.     // the preferences are getting messed up on the mac.
  1003.     // so here we have to validate that the list of plugins we are about to
  1004.     // send over is valid.
  1005. void* pGarbage;
  1006. if (!m_GUIDSupportListIsValid.Lookup(sGUID, pGarbage))
  1007. {
  1008.     // to validate we will load all of the plugins within this list and
  1009.     // QI them.
  1010.     BOOL bListIsInvalid = FALSE;
  1011.     for(LISTPOSITION pPos = pSupportList->GetHeadPosition(); pPos!=NULL;)
  1012.     {
  1013. BOOL IsValid = FALSE;
  1014. UINT32 nTestPluginIndex;
  1015. IUnknown* pTestUnk;
  1016. PluginSupportingGUID* pSupportItemToTest =  (PluginSupportingGUID*) pSupportList->GetAt(pPos);
  1017. if (FindPlugin(pSupportItemToTest->m_filename, pSupportItemToTest->m_nIndexInDLL, nTestPluginIndex))
  1018. {
  1019.     if (HXR_OK == GetInstance(nTestPluginIndex, pTestUnk))
  1020.     {
  1021. IUnknown* pTempUnk;
  1022. if (HXR_OK == pTestUnk->QueryInterface(iid, (void**)&pTempUnk))
  1023. {
  1024.     // ohhh we are in trouble now. We HAVE to assume one of the two following
  1025.     // statements:
  1026.     // (1) All interfaces have derive from IUnknown.
  1027.     // (2) All of our interfaces support aggeration correctly.
  1028.     // I guess we'll have to assume (1) since I KNOW (2) is incorrect.
  1029.     HX_RELEASE(pTempUnk);
  1030.     IsValid = TRUE;
  1031. }
  1032. HX_RELEASE (pTestUnk);
  1033.     }
  1034. }
  1035. HX_ASSERT(IsValid);
  1036. if (!IsValid)
  1037. {
  1038.     // Should not be part of this list. Delete this node.
  1039.     pSupportList->RemoveAt(pPos);
  1040.     bListIsInvalid = TRUE;
  1041. }
  1042. else
  1043. {
  1044.     pSupportList->GetNext(pPos);
  1045. }
  1046.     }
  1047.     m_GUIDSupportListIsValid.SetAt(sGUID, NULL);
  1048.     // at this point we should rewrite the prefs file if bListIsInvalid
  1049.     // however, I do not believe that we have an interface for removing
  1050.     // enteries from the preferences. hmmmm...
  1051. }
  1052. #endif
  1053. return HXR_FAIL;    // hey! it is already in!
  1054.     }
  1055. #ifndef _MACINTOSH
  1056.     if  (!zm_bFasterPrefs)
  1057.     {
  1058. // Write this out for each mount point
  1059. for(CHXMapStringToOb::Iterator mp = m_MountPoints.Begin(); mp!=m_MountPoints.End(); ++mp)
  1060. {
  1061.     PluginMountPoint* pMountPoint = (PluginMountPoint*) *mp;
  1062.     IHXPreferences* pIPrefs = pMountPoint->Prefs();
  1063.     if( pIPrefs )
  1064.     {
  1065. PreferenceEnumerator* pPrefEnum = new PreferenceEnumerator( pIPrefs );
  1066. HX_VERIFY( HXR_OK == pPrefEnum->BeginSubPref(PLUGIN_REGKEY_ROOT));
  1067. HX_VERIFY( HXR_OK == pPrefEnum->BeginSubPref(PLUGIN_GUIDINFO));
  1068. IHXBuffer* pIndexBuffer = new CHXBuffer();
  1069. pIndexBuffer->AddRef();
  1070. pIndexBuffer->Set((UCHAR*)"",1);
  1071. pPrefEnum->WriteSubPref((const char*)sGUID, pIndexBuffer);
  1072. pIndexBuffer->Release();
  1073. pPrefEnum->EndSubPref(); // XXXAH these may not be necessary.
  1074. pPrefEnum->EndSubPref(); // XXXAH these may not be necessary.
  1075. delete pPrefEnum;
  1076. HX_RELEASE( pIPrefs );
  1077.     }
  1078. }
  1079.     }
  1080. #endif
  1081.     // Now create the new structure.
  1082.     CHXSimpleList* pSimpleList = new CHXSimpleList();
  1083.     m_GUIDtoSupportList.SetAt(sGUID, pSimpleList);
  1084.     // now scan all of the Plugins to see if any of them support this interface,
  1085.     for(CHXSimpleList::Iterator i = m_PluginList.Begin(); i!=m_PluginList.End(); ++i)
  1086.     {
  1087. IUnknown*   pUnk;
  1088. IUnknown*   pQuery;
  1089. Plugin2Handler::Plugin* pPlugin = (Plugin2Handler::Plugin*) *i;
  1090. if (HXR_OK == pPlugin->GetPlugin(pUnk))
  1091. {
  1092.     if(HXR_OK == pUnk->QueryInterface(iid, (void**)&pQuery))
  1093.     {
  1094. PluginSupportingGUID* pSupportItem = new PluginSupportingGUID();
  1095. IHXBuffer* pBuffer = pPlugin->GetFileName();
  1096. pSupportItem->m_filename    = (char*) pBuffer->GetBuffer();
  1097. HX_RELEASE( pBuffer );
  1098. pSupportItem->m_pMountPoint = pPlugin->GetDLL()->GetMountPoint();
  1099. pSupportItem->m_nIndexInDLL = pPlugin->GetIndex();
  1100. pSimpleList->AddTail((void*)pSupportItem);
  1101. // now write this info the registry
  1102. char IndexArray[16]; /* Flawfinder: ignore */
  1103. sprintf(IndexArray, "%d", (int) pSupportItem->m_nIndexInDLL); /* Flawfinder: ignore */
  1104. IHXBuffer* pIndexBuffer = new CHXBuffer();
  1105. pIndexBuffer->AddRef();
  1106. pIndexBuffer->Set((const UCHAR*)IndexArray, strlen(IndexArray)+1);
  1107. if (!zm_bFasterPrefs)
  1108. {
  1109.     IHXPreferences* pIPrefs = pPlugin->GetDLL()->GetMountPoint()->Prefs();
  1110.     if( pIPrefs )
  1111.     {
  1112. PreferenceEnumerator* pPrefEnum = new PreferenceEnumerator( pIPrefs );
  1113. HX_VERIFY(HXR_OK == pPrefEnum->BeginSubPref(PLUGIN_REGKEY_ROOT));
  1114. HX_VERIFY(HXR_OK == pPrefEnum->BeginSubPref(PLUGIN_GUIDINFO));
  1115. HX_VERIFY(HXR_OK == pPrefEnum->BeginSubPref((const char*)sGUID));
  1116. pPrefEnum->WriteSubPref((const char*)pSupportItem->m_filename, pIndexBuffer);
  1117. pPrefEnum->EndSubPref(); // XXXAH these may not be necessary.
  1118. pPrefEnum->EndSubPref(); // XXXAH these may not be necessary.
  1119. pPrefEnum->EndSubPref(); // XXXAH these may not be necessary.
  1120. delete pPrefEnum;
  1121. HX_RELEASE( pIPrefs );
  1122.     }
  1123. }
  1124. HX_RELEASE(pIndexBuffer);
  1125. HX_RELEASE(pQuery);
  1126.     }
  1127.     HX_RELEASE(pUnk);
  1128. }
  1129.     }
  1130.     WriteSupportedGUIDs();
  1131.     return HXR_OK;
  1132. }
  1133. /********************************************************************
  1134. *
  1135. * IHXPluginHandler3
  1136. *
  1137. ********************************************************************/
  1138. STDMETHODIMP
  1139. Plugin2Handler::RegisterContext( IUnknown* pContext )
  1140. {
  1141.     if( !pContext )
  1142.     {
  1143.         return INVALID_CONTEXT;
  1144.     }
  1145.     if( m_pContext )
  1146.     {
  1147.         return HXR_UNEXPECTED;
  1148.     }
  1149.     m_pContext = pContext;
  1150.     m_pContext->AddRef();
  1151.     if ( FAILED( m_pContext->QueryInterface( IID_IHXScheduler, (void**) &m_pIScheduler ) ) )
  1152.     {
  1153.         return( INVALID_CONTEXT );
  1154.     }
  1155.     // Set up scheduler to ping us.
  1156.     m_hScheduler = m_pIScheduler->RelativeEnter( this, kPingDuration );
  1157.     if (HXR_OK != m_pContext->QueryInterface(IID_IHXPreferences, (void**) &m_pPreferences))
  1158.     {
  1159.         return INVALID_CONTEXT;
  1160.     }
  1161.     /* We don't check errors because it's ok not to have this available. */
  1162.     m_pContext->QueryInterface(IID_IHXErrorMessages, (void**) &m_pErrorMessages);
  1163. #if defined(HELIX_FEATURE_PREFERENCES)
  1164. #if !defined(HELIX_CONFIG_NOSTATICS)
  1165.     /* Check to see if we wish to use the 'faster' prefs.
  1166.      * This means using VERY long strings to store the
  1167.      * plugin information. Windows supports this but
  1168.      * discourages the practice.
  1169.      */
  1170.     IHXBuffer* pBuffer = NULL;
  1171.     if (m_pPreferences)
  1172.     {
  1173.         if (ReadPrefBOOL(m_pPreferences, "UseFasterPref", zm_bFasterPrefs) != HXR_OK)
  1174.         {
  1175. #if !defined (_WINCE)
  1176.             zm_bFasterPrefs = TRUE;
  1177. #else
  1178.             zm_bFasterPrefs = FALSE;
  1179. #endif
  1180.         }
  1181.     }
  1182. #endif /* #if !defined(HELIX_CONFIG_NOSTATICS) */
  1183. #endif /* HELIX_FEATURE_PREFERENCES */
  1184.     return HXR_OK;
  1185. }
  1186. STDMETHODIMP
  1187. Plugin2Handler::AddPluginMountPoint( const char* pName, UINT32 majorVersion, UINT32 minorVersion, IHXBuffer* pPath )
  1188. {
  1189.     HX_LOG_BLOCK( "Plugin2Handler::AddPluginMountPoint" );
  1190.     const char* pMPKey = pName ? pName : (const char*) pPath->GetBuffer();
  1191.     // Make sure this mount point is in the list
  1192.     PluginMountPoint* pMountPoint = NULL;
  1193.     if( !m_MountPoints.Lookup( pMPKey, (void*&) pMountPoint ) )
  1194.     {
  1195. // Create new mount point
  1196. pMountPoint = new PluginMountPoint( this, pName, majorVersion, minorVersion, pPath );
  1197. pMountPoint->AddRef();
  1198. // Put new mount point in list
  1199. m_MountPoints.SetAt( pMPKey, pMountPoint );
  1200.     }
  1201.     // Increment client count
  1202.     pMountPoint->AddClient();
  1203.     // Load information from registry, and sync DLLs that aren't up to date
  1204.     return RefreshPluginInfo( pMountPoint );
  1205. }
  1206. STDMETHODIMP
  1207. Plugin2Handler::RefreshPluginMountPoint( const char* pName )
  1208. {
  1209.     HX_RESULT result = HXR_FAIL;
  1210.     // If this mount point is in the list, refresh it
  1211.     PluginMountPoint* pMountPoint = NULL;
  1212.     if( m_MountPoints.Lookup( pName, (void*&) pMountPoint ) )
  1213.     {
  1214. result = RefreshPluginInfo( pMountPoint );
  1215.     }
  1216.     return result;
  1217. }
  1218. STDMETHODIMP
  1219. Plugin2Handler::RemovePluginMountPoint( const char* pName )
  1220. {
  1221.     HX_RESULT result = HXR_FAIL;
  1222.     // Make sure this is a valid mount point
  1223.     PluginMountPoint* pMountPoint = NULL;
  1224.     if( m_MountPoints.Lookup( pName, (void*&) pMountPoint ) )
  1225.     {
  1226. // If this was the last client, do the clean up stuff
  1227. if( !pMountPoint->RemoveClient() )
  1228. {
  1229.     // Clean up plugins
  1230.     if( m_PluginList.GetCount() )
  1231.     {
  1232. LISTPOSITION listPos = m_PluginList.GetHeadPosition();
  1233. while( listPos )
  1234. {
  1235.     // Save off current position for delete
  1236.     LISTPOSITION posAt = listPos;
  1237.     // Get current item, and increment position
  1238.     Plugin2Handler::Plugin* pPlugin = (Plugin2Handler::Plugin*) m_PluginList.GetNext( listPos );
  1239.     // If this plugin belongs to the mountpoint, remove it.
  1240.     if( pPlugin && ( pPlugin->GetDLL()->GetMountPoint() == pMountPoint ) )
  1241.     {
  1242. // Remove plugin from indices
  1243. RemovePluginFromIndices( pPlugin );
  1244. // Delete from the saved position
  1245. m_PluginList.RemoveAt( posAt );
  1246. HX_RELEASE( pPlugin );
  1247.     }
  1248. }
  1249.     }
  1250.     // Clean up dlls
  1251.     if (m_PluginDLLList.GetCount())
  1252.     {
  1253. LISTPOSITION listPos = m_PluginDLLList.GetHeadPosition();
  1254. while( listPos )
  1255. {
  1256.     // Save off current position for delete
  1257.     LISTPOSITION posAt = listPos;
  1258.     // Get current item, and increment position
  1259.     Plugin2Handler::PluginDLL* pPluginDLL = (Plugin2Handler::PluginDLL*) m_PluginDLLList.GetNext( listPos );
  1260.     // If this plugin belongs to the mountpoint, remove it.
  1261.     if( pPluginDLL && ( pPluginDLL->GetMountPoint() == pMountPoint ) )
  1262.     {
  1263. // Remove from filename map
  1264. IHXBuffer* pBuffer = pPluginDLL->GetFileName();
  1265. m_FileNameMap.RemoveKey( (char*) pBuffer->GetBuffer() );
  1266. HX_RELEASE( pBuffer );
  1267. // Remove from the LRU
  1268. RemoveFromLRU(pPluginDLL);
  1269. // Delete from the saved position
  1270. m_PluginDLLList.RemoveAt( posAt );
  1271. HX_RELEASE( pPluginDLL );
  1272.     }
  1273. }
  1274.     }
  1275.     // Clean up OtherDLL
  1276.     if (m_MiscDLLList.GetCount())
  1277.     {
  1278. LISTPOSITION listPos = m_MiscDLLList.GetHeadPosition();
  1279. while( listPos )
  1280. {
  1281.     // Save off current position for delete
  1282.     LISTPOSITION posAt = listPos;
  1283.     // Get current item, and increment position
  1284.     Plugin2Handler::OtherDLL* pOtherDLL = (Plugin2Handler::OtherDLL*) m_MiscDLLList.GetNext( listPos );
  1285.     // If this plugin belongs to the mountpoint, remove it.
  1286.     if( pOtherDLL && ( pOtherDLL->m_pMountPoint == pMountPoint ) )
  1287.     {
  1288. // Delete from the saved position
  1289. m_MiscDLLList.RemoveAt( posAt );
  1290. HX_DELETE( pOtherDLL );
  1291.     }
  1292. }
  1293.     }
  1294.     // Clean up supported GUIDs
  1295.     if (m_GUIDtoSupportList.GetCount())
  1296.     {
  1297. CHXMapStringToOb::Iterator k;
  1298. for(k = m_GUIDtoSupportList.Begin(); k!=m_GUIDtoSupportList.End(); ++k)
  1299. {
  1300.     CHXSimpleList* pSupportedList = (CHXSimpleList*) *k;
  1301.     LISTPOSITION listPos = pSupportedList->GetHeadPosition();
  1302.     while( listPos )
  1303.     {
  1304. // Save off current position for delete
  1305. LISTPOSITION posAt = listPos;
  1306. // Get current item, and increment position
  1307. PluginSupportingGUID* pSupportItem = (PluginSupportingGUID*) pSupportedList->GetNext( listPos );
  1308. // If this plugin belongs to the mountpoint, remove it.
  1309. if( pSupportItem && ( pSupportItem->m_pMountPoint == pMountPoint ) )
  1310. {
  1311.     // Delete from the saved position
  1312.     pSupportedList->RemoveAt( posAt );
  1313.     HX_DELETE( pSupportItem );
  1314. }
  1315.     }
  1316.     // XXXND Remove the list from m_GUIDtoSupportList if it's empty
  1317. }
  1318.     }
  1319.     // Remove mount point from list
  1320.     m_MountPoints.RemoveKey( pName );
  1321.             if (pMountPoint)
  1322.             {
  1323.                 pMountPoint->Release();
  1324.                 pMountPoint = NULL;
  1325.             }
  1326. }
  1327.     }
  1328.     return result;
  1329. }
  1330. STDMETHODIMP
  1331. Plugin2Handler::FindImplementationFromClassID( REFGUID GUIDClassID, REF(IUnknown*) pIUnknownInstance,
  1332. IUnknown* pIUnkOuter, IUnknown* pContext )
  1333. {
  1334.     // Look though the Component plugins
  1335.     HX_RESULT result = HXR_FAIL;
  1336.     if( FAILED( result = CreatePluginViaIndex( PLUGIN_COMPONENT_CLSID, &GUIDClassID, &pIUnknownInstance, pIUnkOuter ) ) )
  1337.     {
  1338. // XXXND FIX Try doing a manual lookup (FindPluginUsingValues)
  1339. // Couldn't find it with the new method, try the old one.
  1340. result = FindImplementationFromClassIDInternal( GUIDClassID, pIUnknownInstance, pContext );
  1341.     }
  1342.     return result;
  1343. }
  1344. STDMETHODIMP
  1345. Plugin2Handler::FindCLSIDFromName( const char* pName, REF(IHXBuffer*) pCLSID )
  1346. {
  1347.     HX_SETUP_CHECKPOINTLIST( "Plugin2Handler::FindCLSIDFromName()" );
  1348.     HX_PRIME_ACCUMULATOR( 'idfn', "Looking up CLSID from name" );
  1349.     HX_ACCUMULATE( 'idfc', "Number of CLSIDs looked up", 1 );
  1350.     // Initialize out params
  1351.     pCLSID = NULL;
  1352.     HX_RESULT result = HXR_FAIL;
  1353.     IHXValues* pIValues = NULL;
  1354.     if( SUCCEEDED( FindPluginInfoViaIndex( PLUGIN_COMPONENT_NAME, (char*) pName, &pIValues ) ) )
  1355.     {
  1356. pIValues->GetPropertyBuffer( PLUGIN_COMPONENT_CLSID, pCLSID );
  1357. HX_RELEASE( pIValues );
  1358. result = HXR_OK;
  1359.     }
  1360.     else
  1361.     {
  1362. // XXXND  FIX  Try using FindPluginUsingString
  1363.     }
  1364.     HX_UPDATE_ACCUMULATOR( 'idfn' );
  1365.     return result;
  1366. }
  1367. STDMETHODIMP
  1368. Plugin2Handler::FindGroupOfPluginsUsingValues( IHXValues* pValues,
  1369. REF(IHXPluginSearchEnumerator*) pIEnumerator)
  1370. {
  1371.     // Initialize out params
  1372.     pIEnumerator = NULL;
  1373.     // Use the internal function to build up an enumerator object
  1374.     CPluginEnumerator* pEnumerator = NULL;
  1375.     HX_RESULT result = FindGroupOfPluginsUsingValues( pValues, pEnumerator );
  1376.     // If we have our enumerator, get the appropriate interface
  1377.     if( SUCCEEDED( result ) )
  1378.     {
  1379. result = pEnumerator->QueryInterface( IID_IHXPluginSearchEnumerator,
  1380. (void**) &pIEnumerator );
  1381.     }
  1382.     return result;
  1383. }
  1384. STDMETHODIMP
  1385. Plugin2Handler::FindGroupOfPluginsUsingStrings( char* PropName1, char* PropVal1,
  1386. char* PropName2, char* PropVal2,
  1387. char* PropName3, char* PropVal3,
  1388. REF(IHXPluginSearchEnumerator*) pIEnumerator)
  1389. {
  1390.     // Initialize out params
  1391.     pIEnumerator = NULL;
  1392.     // Use the internal function to build up an enumerator object
  1393.     CPluginEnumerator* pEnumerator = NULL;
  1394.     HX_RESULT result = FindGroupOfPluginsUsingStrings( PropName1, PropVal1,
  1395.     PropName2, PropVal2, PropName3, PropVal3, pEnumerator );
  1396.     // If we have our enumerator, get the appropriate interface
  1397.     if( SUCCEEDED( result ) )
  1398.     {
  1399. result = pEnumerator->QueryInterface( IID_IHXPluginSearchEnumerator,
  1400. (void**) &pIEnumerator );
  1401.     }
  1402.     return result;
  1403. }
  1404. void Plugin2Handler::ReportError( UINT8 severity, const char* pDLLName, const char* pDesc )
  1405. {
  1406.     if (m_pErrorMessages)
  1407.     {
  1408.         int nErrorTempLength;
  1409. char *pErrorTemp;
  1410.         nErrorTempLength = strlen(pDLLName) + strlen(pDesc) + 2;
  1411.         pErrorTemp = new char[nErrorTempLength];
  1412.         if(pErrorTemp)
  1413.         {
  1414.             SafeSprintf(pErrorTemp, nErrorTempLength, "%s %s", pDLLName, pDesc );
  1415.             m_pErrorMessages->Report( severity, 0, 0, pErrorTemp, NULL );
  1416.             delete [] pErrorTemp;
  1417.         }
  1418.         else
  1419.         {
  1420.             m_pErrorMessages->Report( HXLOG_ERR, HXR_OUTOFMEMORY, 0, NULL, NULL );
  1421.         }
  1422.     }
  1423. }
  1424. STDMETHODIMP
  1425. Plugin2Handler::FindPluginUsingValues( IHXValues* pCriteria,
  1426. REF(IUnknown*) pIUnkResult,
  1427. IUnknown* pIUnkOuter )
  1428. {
  1429.     HX_SETUP_CHECKPOINTLIST( "Plugin2Handler::FindPluginUsingValues()" );
  1430.     HX_PRIME_ACCUMULATOR( 'fpuv', "Plugin lookup with IHXValues" );
  1431.     // Initialize out params
  1432.     pIUnkResult = NULL;
  1433.     CHXSimpleList   PossibleValues;
  1434.     IHXValues*     pPluginValues = NULL;
  1435.     IHXBuffer*     pBuffer = NULL;
  1436.     CHXSimpleList::Iterator i = m_PluginList.Begin();
  1437.     for(; i!= m_PluginList.End(); ++i)
  1438.     {
  1439. Plugin2Handler::Plugin* pPlugin = (Plugin2Handler::Plugin*) *i;
  1440. if (pPlugin->DoesMatch(pCriteria))
  1441. {
  1442.     PossibleValues.AddTail(pPlugin);
  1443. }
  1444.     }
  1445.     HX_UPDATE_ACCUMULATOR( 'fpuv' );
  1446.     if (PossibleValues.Begin() == PossibleValues.End())
  1447.     {
  1448. pIUnkResult = 0;
  1449. return HXR_FAIL;
  1450.     }
  1451.     /****************************************************************
  1452.     ** Presently when we arrive at this spot with more than one
  1453.     ** plugin which matches the search criteria, we simply take
  1454.     ** the first one found. If this is not satisfactory then
  1455.     ** some method can be added which will process the list based
  1456.     ** upon some criteria.
  1457.     ****************************************************************/
  1458.     // if there are multiple plugins found, we will pick the one whose
  1459.     // plugin description contains "RealNetworks"
  1460.     if (PossibleValues.GetCount() > 1)
  1461.     {
  1462. for(i = PossibleValues.Begin(); i!= PossibleValues.End(); ++i)
  1463. {
  1464.     Plugin2Handler::Plugin* pPlugin = (Plugin2Handler::Plugin*) *i;
  1465.     if (HXR_OK == pPlugin->GetPluginInfo(pPluginValues) && pPluginValues)
  1466.     {
  1467. if (HXR_OK == pPluginValues->GetPropertyCString(PLUGIN_DESCRIPTION2, pBuffer) &&
  1468.     pBuffer)
  1469. {
  1470.     if (strstr((const char*)pBuffer->GetBuffer(), "RealNetworks"))
  1471.     {
  1472. HX_RELEASE(pBuffer);
  1473. if ( NO_ERRORS == pPlugin->GetInstance( pIUnkResult, pIUnkOuter ))
  1474. {
  1475.     return HXR_OK;
  1476. }
  1477. else
  1478. {
  1479.     return HXR_FAIL;
  1480. }
  1481.     }
  1482. }
  1483. HX_RELEASE(pBuffer);
  1484.     }
  1485. }
  1486.     }
  1487.     Plugin2Handler::Plugin* pPlug = (Plugin2Handler::Plugin*) *(PossibleValues.Begin());
  1488.     Errors retVal = pPlug->GetInstance( pIUnkResult, pIUnkOuter );
  1489.     return ( retVal == NO_ERRORS ) ? HXR_OK : HXR_FAIL;
  1490. }
  1491. STDMETHODIMP
  1492. Plugin2Handler::FindPluginUsingStrings( char* PropName1, char* PropVal1,
  1493. char* PropName2, char* PropVal2,
  1494. char* PropName3, char* PropVal3,
  1495. REF(IUnknown*) pIUnkResult,
  1496. IUnknown* pIUnkOuter )
  1497. {
  1498.     // Initialize out params
  1499.     pIUnkResult = NULL;
  1500.     // PropName and PropVal have to to valid tuple
  1501.     if ((PropName1 && !PropVal1)    ||
  1502. (PropName2 && !PropVal2)    ||
  1503. (PropName3 && !PropVal3)    ||
  1504. (!PropName1 && PropVal1)    ||
  1505. (!PropName2 && PropVal2)    ||
  1506. (!PropName3 && PropVal3))
  1507. return HXR_FAIL;
  1508.     IHXValues* pValues;
  1509.     HX_RESULT   retVal = HXR_FAIL;
  1510.     CHXHeader* pHeader = new CHXHeader();
  1511.     pHeader->QueryInterface(IID_IHXValues,  (void**)&pValues);
  1512.     AddToValues(pValues, PropName1, PropVal1, eString);
  1513.     AddToValues(pValues, PropName2, PropVal2, eString);
  1514.     AddToValues(pValues, PropName3, PropVal3, eString);
  1515.     retVal = FindPluginUsingValues( pValues, pIUnkResult, pIUnkOuter );
  1516.     pValues->Release();
  1517.     return retVal;
  1518. }
  1519. STDMETHODIMP
  1520. Plugin2Handler::GetPlugin( ULONG32 ulIndex, REF(IUnknown*) pIUnkResult,
  1521.     IUnknown* pIUnkOuter )
  1522. {
  1523.     if( ulIndex <= (ULONG32)(m_PluginList.GetCount()-1) && m_PluginList.GetCount() )
  1524.     {
  1525. LISTPOSITION pPos = m_PluginList.FindIndex( ulIndex );
  1526. if (pPos)
  1527. {
  1528.     Plugin2Handler::Plugin* pPlugin = (Plugin2Handler::Plugin*) m_PluginList.GetAt( pPos );
  1529.     if( pPlugin )
  1530.     {
  1531. if (NO_ERRORS == pPlugin->GetInstance( pIUnkResult, pIUnkOuter ))
  1532. {
  1533.     return HXR_OK;
  1534. }
  1535. else
  1536. {
  1537.     return HXR_FAIL;
  1538. }
  1539.     }
  1540. }
  1541.     }
  1542.     return HXR_FAIL;
  1543. }
  1544. //------------------------------------ IHXPluginDatabase interface methods
  1545. STDMETHODIMP
  1546. Plugin2Handler::AddPluginIndex( THIS_ const char* pKeyName, EPluginIndexType indexType, BOOL bScanExisting )
  1547. {
  1548.     HX_LOG_BLOCK( "Plugin2Handler::AddPluginIndex" );
  1549.     HX_RESULT result = HXR_FAIL;
  1550.     CPluginDatabaseIndex* pNewIndex = CPluginDatabaseIndex::CreateIndex( indexType );
  1551.     if( pNewIndex )
  1552.     {
  1553. m_dbIndices.SetAt( pKeyName, pNewIndex );
  1554. if( bScanExisting )
  1555. {
  1556.     // XXXND FIX  Scan the existing plugins and add them to this index
  1557. }
  1558. result = HXR_OK;
  1559.     }
  1560.     return result;
  1561. }
  1562. STDMETHODIMP
  1563. Plugin2Handler::RemovePluginIndex( THIS_ const char* pKeyName )
  1564. {
  1565.     HX_RESULT result = HXR_UNEXPECTED;
  1566.     CPluginDatabaseIndex* pIndex = FindDBIndex( pKeyName );
  1567.     if( pIndex )
  1568.     {
  1569. if( !m_dbIndices.RemoveKey( pKeyName ) )
  1570. {
  1571.     result = HXR_FAIL;
  1572. }
  1573. else
  1574. {
  1575.     HX_DELETE( pIndex );
  1576.     result = HXR_OK;
  1577. }
  1578.     }
  1579.     return result;
  1580. }
  1581. STDMETHODIMP
  1582. Plugin2Handler::FindPluginInfoViaIndex( THIS_ const char* pKeyName, const void* pValue, IHXValues** ppIInfo )
  1583. {
  1584.     HX_RESULT result = HXR_INVALID_PARAMETER;
  1585.     if( ppIInfo )
  1586.     {
  1587. result = HXR_FAIL;
  1588. *ppIInfo = NULL;
  1589. CPluginDatabaseIndex* pIndex = FindDBIndex( pKeyName );
  1590. if( pIndex )
  1591. {
  1592.     IUnknown* pIUnk = NULL;
  1593.     if( SUCCEEDED( pIndex->FindItem( pValue, &pIUnk ) ) )
  1594.     {
  1595. Plugin2Handler::Plugin* pPlugin = (Plugin2Handler::Plugin*) pIUnk;
  1596. if( SUCCEEDED( result = pPlugin->GetPluginInfo( *ppIInfo ) ) )
  1597. {
  1598.     // Since GetPluginInfo() doesn't addref, we have to here.
  1599.     (*ppIInfo)->AddRef();
  1600. }
  1601. HX_RELEASE( pIUnk );
  1602.     }
  1603. }
  1604.     }
  1605.     return result;
  1606. }
  1607. STDMETHODIMP
  1608. Plugin2Handler::FindPluginSetViaIndex( THIS_ const char* pKeyName, const void* pValue, IHXPluginSearchEnumerator** ppIEnumerator )
  1609. {
  1610.     // XXXND  Implement this
  1611.     *ppIEnumerator = NULL;
  1612.     return HXR_NOTIMPL;
  1613. }
  1614. STDMETHODIMP
  1615. Plugin2Handler::CreatePluginViaIndex( THIS_ const char* pKeyName, const void* pValue, IUnknown** ppIUnkPlugin, IUnknown* pIUnkOuter )
  1616. {
  1617.     HX_RESULT result = HXR_INVALID_PARAMETER;
  1618.     if( ppIUnkPlugin )
  1619.     {
  1620. result = HXR_FAIL;
  1621. *ppIUnkPlugin = NULL;
  1622. CPluginDatabaseIndex* pIndex = FindDBIndex( pKeyName );
  1623. if( pIndex )
  1624. {
  1625.     IUnknown* pIUnk = NULL;
  1626.     if( SUCCEEDED( pIndex->FindItem( pValue, &pIUnk ) ) )
  1627.     {
  1628. Plugin2Handler::Plugin* pPlugin = (Plugin2Handler::Plugin*) pIUnk;
  1629. if( NO_ERRORS == pPlugin->GetInstance( *ppIUnkPlugin, pIUnkOuter ) )
  1630. {
  1631.     result = HXR_OK;
  1632. }
  1633. HX_RELEASE( pIUnk );
  1634.     }
  1635. }
  1636.     }
  1637.     return result;
  1638. }
  1639. STDMETHODIMP
  1640. Plugin2Handler::UnloadPluginFromClassID(REFGUID GUIDClassID)
  1641. {
  1642.     HX_RESULT res = HXR_FAIL;
  1643.     CPluginDatabaseIndex* pIndex = FindDBIndex( PLUGIN_COMPONENT_CLSID );
  1644.     if( pIndex )
  1645.     {
  1646. IUnknown* pIUnk = NULL;
  1647. if( SUCCEEDED( pIndex->FindItem( &GUIDClassID, &pIUnk ) ) )
  1648. {
  1649.     Plugin2Handler::Plugin* pPlugin = (Plugin2Handler::Plugin*) pIUnk;
  1650.     if(pPlugin->GetDLL())
  1651.     {
  1652. res = pPlugin->GetDLL()->Unload();
  1653.     }
  1654.     HX_RELEASE( pIUnk );
  1655. }
  1656.     }
  1657.     return res;
  1658. }
  1659. STDMETHODIMP
  1660. Plugin2Handler::UnloadPackageByName(const char* pName)
  1661. {
  1662.     if (!pName)
  1663. return HXR_INVALID_PARAMETER;
  1664.     for (CHXSimpleList::Iterator i = m_PluginDLLList.Begin(); i != m_PluginDLLList.End(); ++i)
  1665.     {
  1666. PluginDLL* pPluginDLL = (PluginDLL*) *i;
  1667. if (pPluginDLL->GetPackageName() == pName)
  1668. {
  1669.     return pPluginDLL->Unload(FALSE);
  1670. }
  1671.     }
  1672.     return HXR_FAIL;
  1673. }
  1674. //------------------------------------ Class Methods
  1675. HX_RESULT Plugin2Handler::FindImplementationFromClassIDInternal(
  1676.     REFGUID GUIDClassID,
  1677.     REF(IUnknown*) pIUnknownInstance,
  1678.     IUnknown* pContext )
  1679. {
  1680.     // Initialize out params
  1681.     pIUnknownInstance = NULL;
  1682.     HX_RESULT HX_RESULTThis = HXR_OK;
  1683.     UINT32 ulNumClassFactories = 0;
  1684.     UINT32 ulCurrentClassFactory = 0;
  1685.     UINT32 ulCurrentClassFactoryIndex = 0;
  1686.     IUnknown* pIUnknownClassFactoryCurrent = NULL;
  1687.     IHXCommonClassFactory* pIHXCommonClassFactoryCurrent = NULL;
  1688.     IHXPlugin* pIHXPluginCurrent = NULL;
  1689.     IHXObjectConfiguration* pIHXObjectConfigurationCurrent = NULL;
  1690.    AddSupportedIID(IID_IHXCommonClassFactory);
  1691.     HX_RESULTThis = GetNumPluginsSupporting( IID_IHXCommonClassFactory, ulNumClassFactories );
  1692.     if( SUCCEEDED(HX_RESULTThis) && ulNumClassFactories > 0 )
  1693.     {
  1694. for( ulCurrentClassFactory = 0, ulCurrentClassFactoryIndex = 0;
  1695. ulCurrentClassFactoryIndex < ulNumClassFactories; ++ulCurrentClassFactoryIndex )
  1696. {
  1697.     HX_RESULTThis = GetPluginIndexSupportingIID( IID_IHXCommonClassFactory,
  1698.     ulCurrentClassFactoryIndex,
  1699.     ulCurrentClassFactory );
  1700.     // Create an instance of the plugin at the index ulCurrentClassFactory
  1701.     if( SUCCEEDED(HX_RESULTThis) )
  1702.     {
  1703. HX_RESULTThis = GetInstance( ulCurrentClassFactory, pIUnknownClassFactoryCurrent );
  1704.     }
  1705.     // If we got a plugin, see if we can get the correct object from it.
  1706.     if( SUCCEEDED(HX_RESULTThis) && pIUnknownClassFactoryCurrent )
  1707.     {
  1708. // Initialize the plugin either through IHXPlugin or IHXObjectConfiguration
  1709. if( SUCCEEDED( pIUnknownClassFactoryCurrent->QueryInterface( IID_IHXPlugin,
  1710.     (void**)&pIHXPluginCurrent ) )
  1711.     && pIHXPluginCurrent )
  1712. {
  1713.     pIHXPluginCurrent->InitPlugin( pContext );
  1714. }
  1715. HX_RELEASE(pIHXPluginCurrent);
  1716. if( SUCCEEDED( pIUnknownClassFactoryCurrent->QueryInterface( IID_IHXObjectConfiguration,
  1717.     (void**)&pIHXObjectConfigurationCurrent ) )
  1718.     && pIHXObjectConfigurationCurrent )
  1719. {
  1720.     pIHXObjectConfigurationCurrent->SetContext( pContext );
  1721. }
  1722. HX_RELEASE(pIHXObjectConfigurationCurrent);
  1723. // Now that it's initialized, get the IHXCommonClassFactory interface
  1724. HX_RESULTThis = pIUnknownClassFactoryCurrent->QueryInterface( IID_IHXCommonClassFactory,
  1725.     (void**)&pIHXCommonClassFactoryCurrent );
  1726.     }
  1727.     HX_RELEASE(pIUnknownClassFactoryCurrent);
  1728.     // We have IHXCommonClassFactory on an intialized plugin.
  1729.     // See if it can create the object we want
  1730.     if( SUCCEEDED(HX_RESULTThis) && pIHXCommonClassFactoryCurrent )
  1731.     {
  1732. HX_RESULTThis = pIHXCommonClassFactoryCurrent->CreateInstance( GUIDClassID, (void **)&pIUnknownInstance );
  1733.     }
  1734.     HX_RELEASE(pIHXCommonClassFactoryCurrent);
  1735.     // Check to see if CreateInstance succeeded.  If so, this is the plugin we want
  1736.     if( SUCCEEDED(HX_RESULTThis) && pIUnknownInstance )
  1737.     {
  1738. // got It!
  1739. break;
  1740.     }
  1741.     // If CreateInstance allocated something, but returned a failure code, clean up
  1742.     HX_RELEASE(pIUnknownInstance);
  1743. }
  1744.     }
  1745.     else
  1746.     {
  1747. // there are no Class factories.
  1748. HX_RESULTThis = HXR_FAIL;
  1749.     }
  1750.     return HX_RESULTThis;
  1751. }
  1752. HX_RESULT Plugin2Handler::RefreshPluginInfo( PluginMountPoint* pMountPoint )
  1753. {
  1754.     HX_LOG_BLOCK( "Plugin2Handler::RefreshPluginInfo" );
  1755.     HX_RESULT result = HXR_FAIL;
  1756.     IHXPreferences* pIPrefs = pMountPoint->Prefs();
  1757.     if( pIPrefs )
  1758.     {
  1759. if( zm_bFasterPrefs )
  1760. {
  1761.     result = ReadPluginInfoFast( pMountPoint );
  1762. }
  1763. else
  1764. {
  1765.     result = ReadPluginInfoSlow( pMountPoint );
  1766. }
  1767.     }
  1768.     if (FAILED (result))
  1769.     {
  1770. result = ClearMountPoint_ (pMountPoint);
  1771.     }
  1772.     if( !pIPrefs || SUCCEEDED( result ) )
  1773. result = ReloadPluginsNoPropagate( pMountPoint );
  1774.     HX_RELEASE( pIPrefs );
  1775.     return result;
  1776. }
  1777. HX_RESULT Plugin2Handler::ClearMountPoint_ (PluginMountPoint* pMountPoint)
  1778. {
  1779.     HX_LOG_BLOCK( "Plugin2Handler::ClearMountPoint_" );
  1780.     IHXPreferences* pIPrefs = pMountPoint->Prefs();
  1781.     REQUIRE_RETURN_QUIET (pIPrefs, HXR_FAIL);
  1782.     IHXPreferences3* pIPrefs3 = NULL;
  1783.     if (FAILED (pIPrefs->QueryInterface(IID_IHXPreferences3, (void**)&pIPrefs3)))
  1784.     {
  1785. HX_RELEASE (pIPrefs);
  1786. return HXR_FAIL;
  1787.     }
  1788.     char szRegKey[255]; /* Flawfinder: ignore */
  1789.     // delete file info
  1790.     SafeStrCpy(szRegKey,  PLUGIN_REGKEY_ROOT, 255);
  1791.     SafeStrCat(szRegKey,  zm_pszRegKeySeperator, 255);
  1792.     SafeStrCat(szRegKey,  PLUGIN_FILENAMES, 255);
  1793.     DeleteHugePref_ (pIPrefs, pIPrefs3, szRegKey);
  1794.     // delete plugin info
  1795.     SafeStrCpy(szRegKey,  PLUGIN_REGKEY_ROOT, 255);
  1796.     SafeStrCat(szRegKey,  zm_pszRegKeySeperator, 255);
  1797.     SafeStrCat(szRegKey,  PLUGIN_PLUGININFO, 255);
  1798.     DeleteHugePref_ (pIPrefs, pIPrefs3, szRegKey);
  1799.     // delete guid info
  1800.     SafeStrCpy(szRegKey,  PLUGIN_REGKEY_ROOT, 255);
  1801.     SafeStrCat(szRegKey,  zm_pszRegKeySeperator, 255);
  1802.     SafeStrCat(szRegKey,  PLUGIN_GUIDINFO, 255);
  1803.     DeleteHugePref_ (pIPrefs, pIPrefs3, szRegKey);
  1804.     // delete non RMA plugin info
  1805.     SafeStrCpy(szRegKey,  PLUGIN_REGKEY_ROOT, 255);
  1806.     SafeStrCat(szRegKey,  zm_pszRegKeySeperator, 255);
  1807.     SafeStrCat(szRegKey,  PLUGIN_NONHXINFO, 255);
  1808.     DeleteHugePref_ (pIPrefs, pIPrefs3, szRegKey);
  1809.     HX_RELEASE (pIPrefs);
  1810.     HX_RELEASE (pIPrefs3);
  1811.     return HXR_OK;
  1812. }
  1813. void Plugin2Handler::DeleteHugePref_ (IHXPreferences* pIPrefs, IHXPreferences3* pIPrefs3, const char* pszKeyName)
  1814. {
  1815.     HX_LOG_BLOCK( "Plugin2Handler::DeleteHugePref_" );
  1816.     char szNewKeyName [1024]; /* Flawfinder: ignore */
  1817.     char szNumber [16]; /* Flawfinder: ignore */
  1818.     IHXBuffer* pIBuffer = NULL;
  1819.     for (int i = 0; ; ++i)
  1820.     {
  1821. SafeStrCpy(szNewKeyName,  pszKeyName, 1024);
  1822. sprintf (szNumber, "%d", i); /* Flawfinder: ignore */
  1823. SafeStrCat(szNewKeyName,  szNumber, 1024);
  1824.         // unfortunately delete pref doesn't give us the return value we want so we will read the prefs for now to
  1825. // determine if they are there.
  1826. if (FAILED (pIPrefs->ReadPref (szNewKeyName, pIBuffer))) break;
  1827.         LogRegistryRegeneration_ (szNewKeyName, pIBuffer);
  1828. HX_RELEASE (pIBuffer);
  1829. pIPrefs3->DeletePref (szNewKeyName);
  1830.     }
  1831. }
  1832. HX_RESULT Plugin2Handler::WritePluginInfo( PluginMountPoint* pMountPoint )
  1833. {
  1834.     HX_LOG_BLOCK( "Plugin2Handler::WritePluginInfo" );
  1835.     HX_RESULT result = HXR_FAIL;
  1836.     IHXPreferences* pIPrefs = pMountPoint->Prefs();
  1837.     if( pIPrefs )
  1838.     {
  1839. if( zm_bFasterPrefs )
  1840. {
  1841.     result = WritePluginInfoFast( pMountPoint );
  1842. }
  1843. else
  1844. {
  1845.     result = WritePluginInfoSlow( pMountPoint );
  1846. }
  1847.     }
  1848.     HX_RELEASE( pIPrefs );
  1849.     return result;
  1850. }
  1851. HX_RESULT Plugin2Handler::ReadPluginInfoFast( PluginMountPoint* pMountPoint )
  1852. {
  1853.     HX_LOG_BLOCK( "Plugin2Handler::ReadPluginInfoFast" );
  1854.     /*
  1855.     * Code to read from the preferences in one big chunk since
  1856.     *   it seems that using many readable preferences is not efficient
  1857.     * on either windows or on macintosh.
  1858.     */
  1859.     IHXPreferences* pIPrefs = pMountPoint->Prefs();
  1860.     if( !pIPrefs )
  1861.     {
  1862. // If there are no prefs, there's nothing to read
  1863. return HXR_OK;
  1864.     }
  1865.     IHXBuffer* pIPathBuffer = pMountPoint->Path();
  1866.     if( !pIPathBuffer )
  1867.     {
  1868. HX_RELEASE( pIPrefs );
  1869. return HXR_FAIL;
  1870.     }
  1871.     char szRegKey[255]; /* Flawfinder: ignore */
  1872.     SafeStrCpy(szRegKey,  PLUGIN_REGKEY_ROOT, 255);
  1873.     SafeStrCat(szRegKey,  zm_pszRegKeySeperator, 255);
  1874.     SafeStrCat(szRegKey,  PLUGIN_FILENAMES, 255);
  1875.     /*
  1876.      *  Get the DLL info.
  1877.      */
  1878.     HX_LOG_CHECKPOINT( "Get DLL info" );
  1879.     IHXBuffer*     pInfo = NULL;
  1880.     if (HXR_OK == ReadHugePref( pIPrefs, szRegKey, pInfo))
  1881.     {
  1882. // the string is defined as follows:
  1883. // {name, checksum, BOOL has factory, size, INT numplugins}{ditto}checksum
  1884. char* pszName = NULL;
  1885. char* pszCheckSum = NULL;
  1886. BOOL bFactory = FALSE;
  1887. int nDLLSize = 0, nNumberPlugins = 0;
  1888. char* pszCurrentPos = (char*) pInfo->GetBuffer();
  1889. if (FAILED (VerifyChecksum_ (pszCurrentPos)))
  1890. {
  1891.     HX_RELEASE(pIPathBuffer);
  1892.     HX_RELEASE(pIPrefs);
  1893.     HX_RELEASE(pInfo);
  1894. #ifdef _WINDOWS
  1895.     HX_ASSERT (!"Plugin handler data is corrupt. Regenerating data.");
  1896. #endif
  1897.     return HXR_FAIL;
  1898. }
  1899. while( GetPluginFileInfo( pszCurrentPos, pszName, pszCheckSum, bFactory, nDLLSize, nNumberPlugins ) )
  1900. {
  1901.     // validate the plugin by comparing the hash of the
  1902.     // stats info to the one stored in memory.
  1903.     IHXBuffer* pNewChecksum;
  1904.     pNewChecksum = ChecksumFile(pszName, pIPathBuffer);
  1905.     if( pNewChecksum && (!strcasecmp((const char*)pNewChecksum->GetBuffer(), pszCheckSum)))
  1906.     {
  1907. Plugin2Handler::PluginDLL* pDLL = new Plugin2Handler::PluginDLL( pszName, pMountPoint, this );
  1908. pDLL->AddRef();
  1909. // ReconnectDLL() replaces one PluginDLL object with another PluginDLL; however,
  1910. // both of these PluginDLL objects refer to the same DLL.  This ensures that
  1911. // only one PluginDLL object per DLL is in the m_PluginDLLList.
  1912. ReconnectDLL( pszName, pDLL );
  1913. pDLL->SetPref( nNumberPlugins, pszCheckSum, nDLLSize, bFactory );
  1914.     }
  1915.     HX_RELEASE(pNewChecksum);
  1916. }
  1917. HX_RELEASE(pInfo);
  1918.     }
  1919.     /*
  1920.      *  Get the Plugin info.
  1921.      */
  1922.     SafeStrCpy(szRegKey,  PLUGIN_REGKEY_ROOT, 255);
  1923.     SafeStrCat(szRegKey,  zm_pszRegKeySeperator, 255);
  1924.     SafeStrCat(szRegKey,  PLUGIN_PLUGININFO, 255);
  1925.     if (HXR_OK == ReadHugePref(  pIPrefs, szRegKey, pInfo))
  1926.     {
  1927. char* pszCurrentPos = (char*) pInfo->GetBuffer();
  1928. if (FAILED (VerifyChecksum_ (pszCurrentPos)))
  1929. {
  1930.     HX_RELEASE(pIPathBuffer);
  1931.     HX_RELEASE(pIPrefs);
  1932.     HX_RELEASE(pInfo);
  1933. #ifdef _WINDOWS
  1934.     HX_ASSERT (!"Plugin handler data is corrupt. Regenerating data.");
  1935. #endif
  1936.     return HXR_FAIL;
  1937. }
  1938. Plugin2Handler::Plugin* pPlugin = NULL;
  1939. while( GetPluginFileInfo( pszCurrentPos, pPlugin ) )
  1940. {
  1941.     // XXXND  This really ought to search for duplicates
  1942.     if( HXR_OK != ConnectPluginToDLL( pPlugin ) )
  1943.     {
  1944. // Must delete from list...
  1945. HX_RELEASE(pPlugin);
  1946.     }
  1947.     else
  1948.     {
  1949. AddPluginToIndices( pPlugin );
  1950. m_PluginList.AddTail(pPlugin);
  1951.     }
  1952. }
  1953. HX_RELEASE(pInfo);
  1954.     }
  1955.     /*
  1956.      * Get GUID info for the Plugin Enumerator.
  1957.      */
  1958.     HX_LOG_CHECKPOINT( "Get GUID" );
  1959.     SafeStrCpy(szRegKey,  PLUGIN_REGKEY_ROOT, 255);
  1960.     SafeStrCat(szRegKey,  zm_pszRegKeySeperator, 255);
  1961.     SafeStrCat(szRegKey,  PLUGIN_GUIDINFO, 255);
  1962.     if (HXR_OK == ReadHugePref( pIPrefs, szRegKey, pInfo))
  1963.     {
  1964. char* pszCurrentPos = (char*) pInfo->GetBuffer();
  1965. if (FAILED (VerifyChecksum_ (pszCurrentPos)))
  1966. {
  1967.     HX_RELEASE(pIPathBuffer);
  1968.     HX_RELEASE(pIPrefs);
  1969.     HX_RELEASE(pInfo);
  1970. #ifdef _WINDOWS
  1971.     HX_ASSERT (!"Plugin handler data is corrupt. Regenerating data.");
  1972. #endif
  1973.     return HXR_FAIL;
  1974. }
  1975. CHXSimpleList* pList = NULL;
  1976. char* pszGUID = NULL;
  1977. while(GetGUIDInfo(pszCurrentPos, pMountPoint, pszGUID, pList))
  1978. {
  1979.     m_GUIDtoSupportList.SetAt(pszGUID, (void*)pList);
  1980. }
  1981. HX_RELEASE(pInfo);
  1982.     }
  1983.     /*
  1984.      * Get non RMA DLL info
  1985.      */
  1986.     HX_LOG_CHECKPOINT( "Get non RMA DLL info" );
  1987.     SafeStrCpy(szRegKey,  PLUGIN_REGKEY_ROOT, 255);
  1988.     SafeStrCat(szRegKey,  zm_pszRegKeySeperator, 255);
  1989.     SafeStrCat(szRegKey,  PLUGIN_NONHXINFO, 255);
  1990.     if (HXR_OK == ReadHugePref( pIPrefs, szRegKey, pInfo))
  1991.     {
  1992. char* pszCurrentPos = (char*) pInfo->GetBuffer();
  1993. if (FAILED (VerifyChecksum_ (pszCurrentPos)))
  1994. {
  1995.     HX_RELEASE(pIPathBuffer);
  1996.     HX_RELEASE(pIPrefs);
  1997.     HX_RELEASE(pInfo);
  1998. #ifdef _WINDOWS
  1999.     HX_ASSERT (!"Plugin handler data is corrupt. Regenerating data.");
  2000. #endif
  2001.     return HXR_FAIL;
  2002. }
  2003. Plugin2Handler::OtherDLL* pOtherData = NULL;
  2004. while(GetNonHXInfo(pszCurrentPos, pMountPoint, pOtherData))
  2005. {
  2006.     m_MiscDLLList.AddTail((void*)pOtherData);
  2007. }
  2008. HX_RELEASE(pInfo);
  2009.     }
  2010.     HX_RELEASE(pIPathBuffer);
  2011.     HX_RELEASE(pIPrefs);
  2012.     return HXR_OK;
  2013. }
  2014. HX_RESULT Plugin2Handler::WritePluginInfoFast( PluginMountPoint* pMountPoint )
  2015. {
  2016.     HX_LOG_BLOCK( "Plugin2Handler::WritePluginInfoFast" );
  2017.     IHXPreferences* pIPrefs = pMountPoint->Prefs();
  2018.     if( !pIPrefs )
  2019.     {
  2020. return HXR_OK;
  2021.     }
  2022.     char szRegKey[255]; /* Flawfinder: ignore */
  2023.     CHXSimpleList::Iterator i;
  2024.     // Create buffer to use by CPluginInfoWriter...
  2025.     IHXBuffer* pIHXBuffer = NULL;
  2026.     CHXBuffer* pBuffer = new CHXBuffer();
  2027.     if(pBuffer)
  2028.     {
  2029. if(SUCCEEDED(pBuffer->QueryInterface(IID_IHXBuffer, (void**)&pIHXBuffer)))
  2030. {
  2031.     pIHXBuffer->SetSize(PREF_CACHE_SIZE);
  2032. }
  2033.     }
  2034.     /*
  2035.      * Now write the PluginDLL info to the reg.
  2036.      */
  2037.     if (m_PluginDLLList.GetCount())
  2038.     {
  2039. SafeStrCpy(szRegKey,  PLUGIN_REGKEY_ROOT, 255);
  2040. SafeStrCat(szRegKey,  zm_pszRegKeySeperator, 255);
  2041. SafeStrCat(szRegKey,  PLUGIN_FILENAMES, 255);
  2042.         CPluginInfoWriter piw;
  2043. piw.Init(pIPrefs, szRegKey, pIHXBuffer);
  2044. i = m_PluginDLLList.Begin();
  2045. for(; i!=m_PluginDLLList.End(); ++i)
  2046. {
  2047.     Plugin2Handler::PluginDLL* pPlugDLL = (Plugin2Handler::PluginDLL*) *i;
  2048.     if( pPlugDLL->GetMountPoint() == pMountPoint )
  2049.     {
  2050. pPlugDLL->WritePref2(piw);
  2051.     }
  2052. }
  2053.     }
  2054.     /*
  2055.      * Now write the Plugin info to the reg.
  2056.      */
  2057.     if (m_PluginList.GetCount())
  2058.     {
  2059. SafeStrCpy(szRegKey,  PLUGIN_REGKEY_ROOT, 255);
  2060. SafeStrCat(szRegKey,  zm_pszRegKeySeperator, 255);
  2061. SafeStrCat(szRegKey,  PLUGIN_PLUGININFO, 255);
  2062.         CPluginInfoWriter piw;
  2063. piw.Init(pIPrefs, szRegKey, pIHXBuffer);
  2064. i = m_PluginList.Begin();
  2065. for(; i!=m_PluginList.End(); ++i)
  2066. {
  2067.     Plugin2Handler::Plugin* pPlug = (Plugin2Handler::Plugin*) *i;
  2068.     if( pPlug->GetDLL()->GetMountPoint() == pMountPoint )
  2069.     {
  2070. pPlug->WritePref2(piw);
  2071.     }
  2072. }
  2073.     }
  2074.     /*
  2075.      * Now write the non-RMA DLL info to the reg.
  2076.      */
  2077.     if (m_MiscDLLList.GetCount())
  2078.     {
  2079. SafeStrCpy(szRegKey,  PLUGIN_REGKEY_ROOT, 255);
  2080. SafeStrCat(szRegKey,  zm_pszRegKeySeperator, 255);
  2081. SafeStrCat(szRegKey,  PLUGIN_NONHXINFO, 255);
  2082.         CPluginInfoWriter piw;
  2083. piw.Init(pIPrefs, szRegKey, pIHXBuffer);
  2084. for(i = m_MiscDLLList.Begin();i!=m_MiscDLLList.End(); ++i/*, counter++*/)
  2085. {
  2086.     Plugin2Handler::OtherDLL* pOtherData = (Plugin2Handler::OtherDLL*) *i;
  2087.     if( pOtherData->m_pMountPoint == pMountPoint )
  2088.     {
  2089. // format of the non-rma DLL information is:
  2090. // {filename, checksum}
  2091. piw.Write("{");
  2092. piw.Write((const char*)pOtherData->m_filename);
  2093. piw.Write(",");
  2094. piw.Write((const char*)pOtherData->m_fileChecksum);
  2095. piw.Write("}");
  2096.     }
  2097. }
  2098.     }
  2099.     /*
  2100.      * Now write the GUID info to the reg.
  2101.      */
  2102.     // format of GUID info:
  2103.     // {GUID, filename, index, filename, index, etc}{GUID, filename, index, filename, index}
  2104.     if (m_GUIDtoSupportList.GetCount())
  2105.     {
  2106. SafeStrCpy(szRegKey,  PLUGIN_REGKEY_ROOT, 255);
  2107. SafeStrCat(szRegKey,  zm_pszRegKeySeperator, 255);
  2108. SafeStrCat(szRegKey,  PLUGIN_GUIDINFO, 255);
  2109. CHXMapStringToOb::Iterator k;
  2110. // Dump the data.
  2111.         CPluginInfoWriter piw;
  2112. piw.Init(pIPrefs, szRegKey, pIHXBuffer);
  2113. for(k = m_GUIDtoSupportList.Begin(); k!=m_GUIDtoSupportList.End(); ++k)
  2114. {
  2115.     BOOL foundFirst = FALSE;
  2116.     CHXSimpleList* pSupportedList = (CHXSimpleList*) *k;
  2117.     for (i=pSupportedList->Begin(); i!=pSupportedList->End();++i)
  2118.     {
  2119. PluginSupportingGUID* pSupportItem = (PluginSupportingGUID*) *i;
  2120. if( pSupportItem->m_pMountPoint == pMountPoint )
  2121. {
  2122.     // If we found an item, write out the header
  2123.     if( !foundFirst )
  2124.     {
  2125. foundFirst = TRUE;
  2126. piw.Write("{");
  2127. piw.Write(k.get_key());
  2128.     }
  2129.     char szScratch[20]; /* Flawfinder: ignore */
  2130.     itoa(pSupportItem->m_nIndexInDLL, szScratch, 10);
  2131.     piw.Write(",");
  2132.     piw.Write((const char*) pSupportItem->m_filename);
  2133.     piw.Write(",");
  2134.     piw.Write(szScratch);
  2135. }
  2136.     }
  2137.     // If we wrote out a header, write out a tail
  2138.     if( foundFirst )
  2139.     {
  2140. piw.Write("}");
  2141.     }
  2142. }
  2143.     }
  2144.     HX_RELEASE( pIPrefs );
  2145.     HX_RELEASE( pIHXBuffer );
  2146.     return HXR_OK;
  2147. }
  2148. HX_RESULT Plugin2Handler::ReadPluginInfoSlow( PluginMountPoint* pMountPoint )
  2149. {
  2150.     HX_LOG_BLOCK( "Plugin2Handler::ReadPluginInfoSlow" );
  2151.     IHXBuffer* pBuffer = NULL;
  2152.     // using IHXPreferences2 we will load all data from the registery
  2153.     // we must load all of the information from the registry here.
  2154.     UINT32 nIndex     = 0;
  2155.     IHXBuffer* pPropName   = 0;
  2156.     IHXPreferences* pIPrefs      = pMountPoint->Prefs();
  2157.     {
  2158. if( !pIPrefs )
  2159. {
  2160.     return HXR_OK;
  2161. }
  2162.     }
  2163.     IHXBuffer* pPathBuffer     = pMountPoint->Path();
  2164.     PreferenceEnumerator* pPrefEnum = new PreferenceEnumerator( pIPrefs );
  2165.     // Read the values for the pluginDLLs.
  2166.     HX_VERIFY(HXR_OK == pPrefEnum->BeginSubPref(PLUGIN_REGKEY_ROOT));
  2167.     HX_VERIFY(HXR_OK == pPrefEnum->BeginSubPref(PLUGIN_FILENAMES));
  2168.     while (HXR_OK == pPrefEnum->GetPrefKey(nIndex++, pPropName))
  2169.     {
  2170. if (!strcmp((char*)pPropName->GetBuffer(), zm_pszKeyNameRegKey))
  2171. {
  2172.     HX_RELEASE(pPropName);
  2173.     continue;
  2174. }
  2175. Plugin2Handler::PluginDLL* pDLL = new Plugin2Handler::PluginDLL(
  2176. (const char*)pPropName->GetBuffer(),
  2177.      pMountPoint, this);
  2178. pDLL->AddRef();
  2179. HX_VERIFY(HXR_OK == pPrefEnum->BeginSubPref((const char*)pPropName->GetBuffer()));
  2180. pDLL->ReadPref(pPrefEnum);
  2181. pPrefEnum->EndSubPref();
  2182. // Does this file exist on the HD?
  2183. BOOL bIsOK     = TRUE;
  2184. CFindFile* pFileFinder     = NULL;
  2185. pFileFinder = CFindFile::CreateFindFile((const char*)pPathBuffer->GetBuffer(), 0,
  2186.     (const char*)pPropName->GetBuffer());
  2187. if (!pFileFinder->FindFirst())
  2188. {
  2189.     HX_RELEASE(pPropName);
  2190.     delete pFileFinder;
  2191.     delete pDLL;
  2192.     continue;
  2193. }
  2194. delete pFileFinder;
  2195. HX_RELEASE(pBuffer);
  2196. // is the hash the same?
  2197. pBuffer = pDLL->GetFileName();
  2198. IHXBuffer* pNewChecksum = ChecksumFile((char*)pBuffer->GetBuffer(), pPathBuffer);
  2199. if (pNewChecksum)
  2200. {
  2201.     bIsOK = bIsOK && (!strcasecmp((const char*)pNewChecksum->GetBuffer(), pDLL->GetHash()));
  2202. }
  2203. else
  2204. {
  2205.     bIsOK = FALSE;
  2206. }
  2207. HX_RELEASE(pNewChecksum);
  2208. // if everthing is OK then add the DLL to the list
  2209. if (bIsOK)
  2210. {
  2211.     // ReconnectDLL() replaces one PluginDLL object with another PluginDLL; however,
  2212.     // both of these PluginDLL objects refer to the same DLL.  This ensures that
  2213.     // only one PluginDLL object per DLL is in the m_PluginDLLList.
  2214.     ReconnectDLL((char*)pBuffer->GetBuffer(), pDLL);
  2215. }
  2216. else
  2217. {
  2218.     delete pDLL;
  2219. }
  2220. HX_RELEASE(pBuffer);
  2221. HX_RELEASE(pPropName);
  2222.     }
  2223.     pPrefEnum->EndSubPref();
  2224.     // Read the values for the Plugins.
  2225.     HX_VERIFY(HXR_OK == pPrefEnum->BeginSubPref(PLUGIN_PLUGININFO));
  2226.     nIndex = 0;
  2227.     while (HXR_OK == pPrefEnum->GetPrefKey(nIndex++, pPropName))
  2228.     {
  2229. if (!strcmp((char*)pPropName->GetBuffer(), zm_pszKeyNameRegKey))
  2230. {
  2231.     HX_RELEASE(pPropName);
  2232.     continue;
  2233. }
  2234. Plugin2Handler::Plugin* pPlugin = new Plugin2Handler::Plugin(
  2235. m_pContext);
  2236. pPlugin->AddRef();
  2237. HX_VERIFY(HXR_OK == pPrefEnum->BeginSubPref((const char*)pPropName->GetBuffer()));
  2238. pPlugin->ReadPref(pPrefEnum);
  2239. pPrefEnum->EndSubPref();
  2240. // XXXND  This really ought to search for duplicates
  2241. if( HXR_OK != ConnectPluginToDLL(pPlugin) )
  2242. {
  2243.     // Must delete from list...
  2244.     pPlugin->Release();
  2245. }
  2246. else
  2247. {
  2248.     m_PluginList.AddTail(pPlugin);
  2249. }
  2250. HX_RELEASE(pPropName);
  2251.     }
  2252.     pPrefEnum->EndSubPref();
  2253.     // Read the Prefs for other DLL which are not RMA dlls
  2254.     HX_VERIFY(HXR_OK == pPrefEnum->BeginSubPref(PLUGIN_NONHXINFO));
  2255.     nIndex = 0;
  2256.     while (HXR_OK == pPrefEnum->GetPrefKey(nIndex++, pPropName))
  2257.     {
  2258. if (!strcmp((char*)pPropName->GetBuffer(), zm_pszKeyNameRegKey))
  2259. {
  2260.     HX_RELEASE(pPropName);
  2261.     continue;
  2262. }
  2263. Plugin2Handler::OtherDLL* pOtherData = new Plugin2Handler::OtherDLL;
  2264. pOtherData->m_filename     = (char*)pPropName->GetBuffer();
  2265. pOtherData->m_pMountPoint = pMountPoint;
  2266. IHXBuffer* pCheckSumData   = NULL;
  2267. pPrefEnum->ReadPref((const char*) pPropName->GetBuffer(), pCheckSumData);
  2268. if (pCheckSumData)
  2269. {
  2270.     pOtherData->m_fileChecksum    = (char*)pCheckSumData->GetBuffer();
  2271. }
  2272. m_MiscDLLList.AddTail((void*)pOtherData);
  2273. HX_RELEASE(pCheckSumData);
  2274. HX_RELEASE(pPropName);
  2275.     }
  2276.     pPrefEnum->EndSubPref();
  2277.     // Read the values for the Supported GUIDs.
  2278.     HX_VERIFY(HXR_OK == pPrefEnum->BeginSubPref(PLUGIN_GUIDINFO));
  2279.     nIndex = 0;
  2280.     while (HXR_OK == pPrefEnum->GetPrefKey(nIndex++, pPropName))
  2281.     {
  2282. if (!strcmp((char*)pPropName->GetBuffer(), zm_pszKeyNameRegKey))
  2283. {
  2284.     HX_RELEASE(pPropName);
  2285.     continue;
  2286. }
  2287. CHXSimpleList* pSupportList = new CHXSimpleList();
  2288. m_GUIDtoSupportList.SetAt((char*) pPropName->GetBuffer(), (void*)pSupportList);
  2289. UINT32 nSubIndex     = 0;
  2290. IHXBuffer* pSubPropName     = 0;
  2291. if (HXR_OK == pPrefEnum->BeginSubPref((const char*)pPropName->GetBuffer()))
  2292. {
  2293. while (HXR_OK == pPrefEnum->GetPrefKey(nSubIndex++, pSubPropName))
  2294. {
  2295.     if (!strcmp((char*)pSubPropName->GetBuffer(), zm_pszKeyNameRegKey))
  2296.     {
  2297. HX_RELEASE(pSubPropName);
  2298. continue;
  2299.     }
  2300.     UINT32 nDummyVar;
  2301.     Plugin2Handler::PluginSupportingGUID* pGUIDSupport =
  2302. new Plugin2Handler::PluginSupportingGUID();
  2303.     pPrefEnum->ReadPref((const char*)pSubPropName->GetBuffer(), pBuffer);
  2304.     pGUIDSupport->m_nIndexInDLL = atoi((const char*)pBuffer->GetBuffer());
  2305.     pGUIDSupport->m_filename = pSubPropName->GetBuffer();
  2306.     pGUIDSupport->m_pMountPoint = pMountPoint;
  2307.     if (FindPlugin((const char*)pSubPropName->GetBuffer(), pGUIDSupport->m_nIndexInDLL
  2308. , nDummyVar))
  2309.     {
  2310. pSupportList->AddTail((void*)pGUIDSupport);
  2311.     }
  2312.     else
  2313.     {
  2314. delete pGUIDSupport;
  2315.     }
  2316.     HX_RELEASE(pBuffer);
  2317.     HX_RELEASE(pSubPropName);
  2318. }
  2319. pPrefEnum->EndSubPref();
  2320. }
  2321. HX_RELEASE(pPropName);
  2322.     }
  2323.     delete pPrefEnum;
  2324.     HX_RELEASE( pIPrefs );
  2325.     HX_RELEASE( pPathBuffer );
  2326.     HX_RELEASE( pIPrefs );
  2327.     return HXR_OK;
  2328. }
  2329. HX_RESULT Plugin2Handler::WritePluginInfoSlow( PluginMountPoint* pMountPoint )
  2330. {
  2331.     HX_LOG_BLOCK( "Plugin2Handler::WritePluginInfoSlow" );
  2332.     UINT32 nCounter = 0;
  2333.     IHXBuffer* pBuffer = 0;
  2334.     IHXBuffer* pBuffer2 = 0;
  2335.     char namebuffer[(1<<8)]; /* Flawfinder: ignore */
  2336.     IHXPreferences* pIPrefs = pMountPoint->Prefs();
  2337.     if (!pIPrefs)
  2338.     {
  2339. return HXR_OK;
  2340.     }
  2341.     // Save the DLL names.
  2342.     PreferenceEnumerator* pPrefEnum = new PreferenceEnumerator( pIPrefs );
  2343.     HX_VERIFY(HXR_OK == pPrefEnum->BeginSubPref(PLUGIN_REGKEY_ROOT));
  2344.     HX_VERIFY(HXR_OK == pPrefEnum->BeginSubPref(PLUGIN_FILENAMES));
  2345.     CHXSimpleList::Iterator i = m_PluginDLLList.Begin();
  2346.     for(; i!=m_PluginDLLList.End(); ++i, nCounter++)
  2347.     {
  2348. Plugin2Handler::PluginDLL* pPlugDLL = (Plugin2Handler::PluginDLL*) *i;
  2349. if( pPlugDLL->GetMountPoint() == pMountPoint )
  2350. {
  2351.     pPlugDLL->WritePref(pPrefEnum);
  2352. }
  2353.     }
  2354.     pPrefEnum->EndSubPref();
  2355.     HX_VERIFY(HXR_OK == pPrefEnum->BeginSubPref(PLUGIN_PLUGININFO));
  2356.     INT32 nIndexNumber = 0;
  2357.     pBuffer = new CHXBuffer();
  2358.     pBuffer->AddRef();
  2359.     pBuffer->Set((const UCHAR*)"",1);
  2360.     // Save the plugin Info.
  2361.     for(i = m_PluginList.Begin(); i!=m_PluginList.End(); ++i, nCounter--)
  2362.     {
  2363. Plugin2Handler::Plugin* pPlug = (Plugin2Handler::Plugin*) *i;
  2364. if( pPlug->GetDLL()->GetMountPoint() == pMountPoint )
  2365. {
  2366.     IHXBuffer* pNameBuf = pPlug->GetFileName();
  2367.     char* pChar = (char*)pNameBuf->GetBuffer();
  2368.     SafeSprintf(namebuffer, 256, "%s-%d", pChar, (int)pPlug->GetIndex());
  2369.     HX_RELEASE(pNameBuf);
  2370. #ifndef _MACINTOSH
  2371.     pPrefEnum->WriteSubPref(namebuffer, pBuffer);
  2372. #endif
  2373.     HX_VERIFY(HXR_OK == pPrefEnum->BeginSubPref(namebuffer));
  2374.     pPlug->WritePref(pPrefEnum);
  2375.     pNameBuf = new CHXBuffer();
  2376.     pNameBuf->AddRef();
  2377.     char tempchar[16]; /* Flawfinder: ignore */
  2378.     sprintf(tempchar, "%d", (int)nIndexNumber++); /* Flawfinder: ignore */
  2379.     pNameBuf->Set((const UCHAR*)tempchar, strlen(tempchar)+1);
  2380.     pPrefEnum->WriteSubPref(namebuffer, pNameBuf);
  2381.     pPrefEnum->EndSubPref();
  2382.     HX_RELEASE(pNameBuf);
  2383. }
  2384.     }
  2385.     HX_RELEASE(pBuffer);
  2386.     pPrefEnum->EndSubPref();
  2387.     // Now write the non-RMA DLL info to the reg.
  2388.     HX_VERIFY(HXR_OK == pPrefEnum->BeginSubPref(PLUGIN_NONHXINFO));
  2389.     for(i = m_MiscDLLList.Begin(); i!=m_MiscDLLList.End(); ++i)
  2390.     {
  2391. Plugin2Handler::OtherDLL* pOtherData = (Plugin2Handler::OtherDLL*) *i;
  2392. if( pOtherData->m_pMountPoint == pMountPoint )
  2393. {
  2394.     pBuffer = new CHXBuffer();
  2395.     pBuffer->AddRef();
  2396.     pBuffer->Set((UCHAR*) (const char*) pOtherData->m_fileChecksum, pOtherData->m_fileChecksum.GetLength()+1);
  2397.     pPrefEnum->WriteSubPref(pOtherData->m_filename, pBuffer);
  2398.     HX_RELEASE(pBuffer);
  2399. }
  2400.     }
  2401.     pPrefEnum->EndSubPref();
  2402.     HX_VERIFY(HXR_OK == pPrefEnum->BeginSubPref(PLUGIN_GUIDINFO));
  2403.     // Now save the Data to support the plugin Enumerator.
  2404.     for(CHXMapStringToOb::Iterator k = m_GUIDtoSupportList.Begin();
  2405. k!=m_GUIDtoSupportList.End(); ++k)
  2406.     {
  2407. CHXString sGUID  = k.get_key();
  2408. CHXSimpleList* pSupportedList = (CHXSimpleList*) *k;
  2409. for(CHXSimpleList::Iterator j = pSupportedList->Begin();
  2410. j!=pSupportedList->End(); ++j)
  2411. {
  2412.     char IndexArray[16]; /* Flawfinder: ignore */
  2413.     PluginSupportingGUID* pSupportItem = (PluginSupportingGUID*) *j;
  2414.     if( pSupportItem->m_pMountPoint == pMountPoint )
  2415.     {
  2416. IHXBuffer* pIndexBuffer = new CHXBuffer();
  2417. pIndexBuffer->AddRef();
  2418. sprintf(IndexArray, "%d", (int)pSupportItem->m_nIndexInDLL); /* Flawfinder: ignore */
  2419. pIndexBuffer->Set((const UCHAR*)IndexArray, strlen(IndexArray)+1);
  2420. HX_VERIFY(HXR_OK == pPrefEnum->BeginSubPref((const char*)sGUID));
  2421. pPrefEnum->WriteSubPref((const char*)pSupportItem->m_filename, pIndexBuffer);
  2422. pPrefEnum->EndSubPref();
  2423. HX_RELEASE(pIndexBuffer);
  2424.     }
  2425. }
  2426.     }
  2427.     pPrefEnum->EndSubPref();
  2428.     pPrefEnum->EndSubPref();
  2429.     delete pPrefEnum;
  2430.     HX_RELEASE( pIPrefs );
  2431.     return HXR_OK;
  2432. }
  2433. CPluginDatabaseIndex* Plugin2Handler::FindDBIndex( const char* pKeyName )
  2434. {
  2435.     CPluginDatabaseIndex* pIndex = NULL;
  2436.     void* pVoid = NULL;
  2437.     if( m_dbIndices.Lookup( pKeyName, pVoid ) )
  2438.     {
  2439. pIndex = (CPluginDatabaseIndex*) pVoid;
  2440.     }
  2441.     return pIndex;
  2442. }
  2443. void Plugin2Handler::AddPluginToIndices( Plugin2Handler::Plugin* pPlugin )
  2444. {
  2445.     IHXValues* pIValues = NULL;
  2446.     if( SUCCEEDED( pPlugin->GetPluginInfo( pIValues ) ) )
  2447.     {
  2448. HX_RESULT status = HXR_FAIL;
  2449. const char* pPropName = NULL;
  2450. IHXBuffer* pBuffer;
  2451. // Iterate over all the elements in pIValues.  If there's a key for that
  2452. // name, add the plugin to that index.
  2453. // Scan the CString entries
  2454. status = pIValues->GetFirstPropertyCString( pPropName, pBuffer );
  2455. while( status == HXR_OK )
  2456. {
  2457.     CPluginDatabaseIndex* pIndex = FindDBIndex( pPropName );
  2458.     if( pIndex )
  2459.     {
  2460.      pIndex->AddItem( pBuffer, pPlugin );
  2461.     }
  2462.          HX_RELEASE( pBuffer );
  2463.     status = pIValues->GetNextPropertyCString( pPropName, pBuffer );
  2464. }
  2465. // Scan the Buffer entries
  2466. status = pIValues->GetFirstPropertyBuffer( pPropName, pBuffer );
  2467. while( status == HXR_OK )
  2468. {
  2469.     CPluginDatabaseIndex* pIndex = FindDBIndex( pPropName );
  2470.     if( pIndex )
  2471.     {
  2472.      pIndex->AddItem( pBuffer, pPlugin );
  2473.     }
  2474.          HX_RELEASE( pBuffer );
  2475.     status = pIValues->GetNextPropertyBuffer( pPropName, pBuffer );
  2476. }
  2477. // NOTE:  Don't release pIValues.  GetPluginInfo() doesn't AddRef() it
  2478.     }
  2479. }
  2480. void Plugin2Handler::RemovePluginFromIndices( Plugin2Handler::Plugin* pPlugin )
  2481. {
  2482.     HX_LOG_BLOCK( "Plugin2Handler::RemovePluginFromIndices" );
  2483.     CHXMapStringToOb::Iterator iter;
  2484.     for(iter = m_dbIndices.Begin(); iter != m_dbIndices.End(); ++iter)
  2485.     {
  2486. CPluginDatabaseIndex* pIndex = (CPluginDatabaseIndex*) *iter;
  2487. pIndex->RemoveItem( pPlugin );
  2488.     }
  2489. }
  2490. HX_RESULT Plugin2Handler::RemoveDLLFromGUIDSupportLists(const char* pszFileName)
  2491. {
  2492.     for(CHXMapStringToOb::Iterator i = m_GUIDtoSupportList.Begin();
  2493. i!=m_GUIDtoSupportList.End(); ++i)
  2494.     {
  2495. CHXSimpleList*  pSupportList = (CHXSimpleList*) *i;
  2496. if (pSupportList->IsEmpty())
  2497.     continue;
  2498. for(LISTPOSITION pPos = pSupportList->GetHeadPosition();
  2499. pPos != pSupportList->GetTail();)
  2500. {
  2501.     if (!pPos) break;
  2502.     PluginSupportingGUID* pSupportItem = (PluginSupportingGUID*) pSupportList->GetAt(pPos);
  2503.     if (!strcmp(pszFileName, pSupportItem->m_filename))
  2504.     {
  2505. pPos = pSupportList->RemoveAt(pPos);
  2506. delete pSupportItem;
  2507.     }
  2508.     if (!pPos)
  2509.     {
  2510. break;
  2511.     }
  2512.     pSupportList->GetNext(pPos);
  2513. }
  2514.     }
  2515.     return HXR_OK;
  2516. }
  2517. UINT32 Plugin2Handler::GetNumSupportedGUIDs()
  2518. {
  2519.     return m_GUIDtoSupportList.GetCount();
  2520. }
  2521. HX_RESULT Plugin2Handler::GetGUIDForIndex(UINT32 nIndex, REF(CHXString) sGUID)
  2522. {
  2523.     if (nIndex>= (UINT32)m_GUIDtoSupportList.GetCount())
  2524. return HXR_FAIL;
  2525.     CHXMapStringToOb::Iterator i = m_GUIDtoSupportList.Begin();
  2526.     for(; nIndex; nIndex--, ++i) {};  // not a mistake.
  2527.     sGUID = (char*)i.get_key();
  2528.     return HXR_OK;
  2529. }
  2530. HX_RESULT Plugin2Handler::AddSupportForGUID(const char* pszGUID, PluginDLL* pDLL, UINT32 nIndexInDLL)
  2531. {
  2532.     // Get the DLL name.  We'll need it in a couple places below.
  2533.     IHXBuffer* pBuffer = pDLL->GetFileName();
  2534.     char* pNewDLLName = (char*) pBuffer->GetBuffer();
  2535.     // 1st look to see if we have data about this plugin already if so then return
  2536.     // Find the GUID which we are supporting.
  2537.     CHXSimpleList* pSupportList;
  2538.     if (m_GUIDtoSupportList.Lookup(pszGUID, (void*&)pSupportList))
  2539.     {
  2540. if (!pSupportList->IsEmpty())
  2541. {
  2542.     for(LISTPOSITION pPos = pSupportList->GetHeadPosition();
  2543. pPos != pSupportList->GetTail();)
  2544.     {
  2545. if (!pPos) break;
  2546. PluginSupportingGUID* pSupport = (PluginSupportingGUID*) pSupportList->GetAt(pPos);
  2547. if ( (pSupport->m_nIndexInDLL == nIndexInDLL) && (!strcmp(pSupport->m_filename, pNewDLLName)))
  2548. {
  2549.     HX_RELEASE( pBuffer );
  2550.     return HXR_FAIL;
  2551. }
  2552. pSupportList->GetNext(pPos);
  2553.     }
  2554. }
  2555.     }
  2556.     else
  2557.     {
  2558. HX_ASSERT(1);
  2559. HX_RELEASE( pBuffer );
  2560. return HXR_NOTIMPL;
  2561.     }
  2562.     PluginSupportingGUID* pSupport = new PluginSupportingGUID;
  2563.     pSupport->m_filename = pNewDLLName;
  2564.     pSupport->m_pMountPoint = pDLL->GetMountPoint();
  2565.     pSupport->m_nIndexInDLL = nIndexInDLL;
  2566.     pSupportList->AddTail((void*) pSupport);
  2567.     HX_RELEASE( pBuffer );
  2568.     return HXR_OK;
  2569. }
  2570. STDMETHODIMP Plugin2Handler::FindPluginUsingStrings (char* PropName1,
  2571.     char* PropVal1,
  2572.     char* PropName2,
  2573.     char* PropVal2,
  2574.     char* PropName3,
  2575.     char* PropVal3,
  2576.     REF(IUnknown*) pRetUnk)
  2577. {
  2578.     return FindPluginUsingStrings( PropName1, PropVal1, PropName2, PropVal2,
  2579.     PropName3, PropVal3, pRetUnk, NULL );
  2580. }
  2581. STDMETHODIMP
  2582. Plugin2Handler::FindImplementationFromClassID
  2583. (
  2584.     REFGUID GUIDClassID,
  2585.     REF(IUnknown*) pIUnknownInstance
  2586. )
  2587. {
  2588.     // Defer to the new version
  2589.     return FindImplementationFromClassID( GUIDClassID, pIUnknownInstance, NULL, m_pContext );
  2590. }
  2591. STDMETHODIMP Plugin2Handler::Close ()
  2592. {
  2593.     CHXSimpleList::Iterator i = m_PluginList.Begin();
  2594.     // Release all Plugins and Their Associated DLLs
  2595.     for(; i!=m_PluginList.End(); ++i)
  2596.     {
  2597. Plugin2Handler::Plugin* pPlug = (Plugin2Handler::Plugin*) *i;
  2598. pPlug->Release();
  2599.     }
  2600.     m_PluginList.RemoveAll();
  2601.     for(i = m_PluginDLLList.Begin(); i!=m_PluginDLLList.End(); ++i)
  2602.     {
  2603. Plugin2Handler::PluginDLL* pPlugDLL = (Plugin2Handler::PluginDLL*) *i;
  2604. pPlugDLL->Release();
  2605.     }
  2606.     m_PluginDLLList.RemoveAll();
  2607.     for(i = m_MiscDLLList.Begin(); i!=m_MiscDLLList.End(); ++i)
  2608.     {
  2609. Plugin2Handler::OtherDLL* pOtherDLL = (Plugin2Handler::OtherDLL*) *i;
  2610. delete pOtherDLL;
  2611.     }
  2612.     m_MiscDLLList.RemoveAll();
  2613.     for(CHXMapStringToOb::Iterator mp = m_MountPoints.Begin(); mp!=m_MountPoints.End(); ++mp)
  2614.     {
  2615. Plugin2Handler::PluginMountPoint* pMountPoint = (Plugin2Handler::PluginMountPoint*) *mp;
  2616. pMountPoint->Release();
  2617.     }
  2618.     m_MountPoints.RemoveAll();
  2619.     // Release all of the GUID stuff
  2620.     CHXMapStringToOb::Iterator j;
  2621.     for(j = m_GUIDtoSupportList.Begin();
  2622.     j!= m_GUIDtoSupportList.End(); ++j)
  2623.     {
  2624. CHXSimpleList* pList = (CHXSimpleList*) *j;
  2625. for(i = pList->Begin(); i!=pList->End(); ++i)
  2626. {
  2627.     PluginSupportingGUID* pSupportItem = (PluginSupportingGUID*) *i;
  2628.     delete pSupportItem;
  2629. }
  2630. delete pList;
  2631.     }
  2632.     m_GUIDtoSupportList.RemoveAll();
  2633.     // Clean up all the indices
  2634.     for(j = m_dbIndices.Begin(); j!=m_dbIndices.End(); ++j)
  2635.     {
  2636. CPluginDatabaseIndex* pIndex = (CPluginDatabaseIndex*) *j;
  2637. HX_DELETE( pIndex );
  2638.     }
  2639.     m_dbIndices.RemoveAll();
  2640.     // release all of the CORE stuff...
  2641.     HX_RELEASE(m_pPluginDir);
  2642.     HX_RELEASE(m_pPreferences);
  2643.     HX_RELEASE(m_pErrorMessages);
  2644.     HX_RELEASE(m_pContext);
  2645.     m_CanUnload2DllList.RemoveAll();
  2646.     if ( m_pIScheduler && m_hScheduler )
  2647.     {
  2648. m_pIScheduler->Remove( m_hScheduler );
  2649.     }
  2650.     HX_RELEASE( m_pIScheduler );
  2651.     return HXR_OK;
  2652. }
  2653. STDMETHODIMP Plugin2Handler::SetRequiredPlugins (const char** ppszRequiredPlugins)
  2654. {
  2655.     return HXR_OK;
  2656. }
  2657. HX_RESULT Plugin2Handler::AddToValues(IHXValues* pValues, char* pPropName, char* pPropVal, eValueTypes eValueType)
  2658. {
  2659.     if (!pPropName || !pPropVal)
  2660. return HXR_FAIL;
  2661.     // 1st make into a cstrig and to trim the buffer...
  2662.     CHXString theValue = (pPropVal);
  2663.     theValue.TrimLeft();
  2664.     theValue.TrimRight();
  2665.     switch (eValueType)
  2666.     {
  2667. case eString:
  2668. {
  2669.     IHXBuffer* pBuffer;
  2670.     CHXBuffer* pCHXBuffer;
  2671.     pCHXBuffer = new CHXBuffer;
  2672.     pCHXBuffer->QueryInterface(IID_IHXBuffer, (void**) &pBuffer);
  2673.     pBuffer->Set((const unsigned char*)(const char*)theValue, strlen(theValue)+1);
  2674.     pValues->SetPropertyCString(pPropName, pBuffer);
  2675.     pBuffer->Release();
  2676.     return HXR_OK;
  2677. }
  2678. case eInt:
  2679. {
  2680.     int val = atoi(theValue);
  2681.     pValues->SetPropertyULONG32(pPropName, (ULONG32)val);
  2682.     return HXR_OK;
  2683. }
  2684.     }
  2685.     return HXR_NOTIMPL;
  2686. }
  2687. /*
  2688.  *  Win98 does not allow reg keys that are larger than 16k a pop.
  2689.  *  Thus, this function splits up regkeys into more managiable bites.
  2690.  */
  2691. #define PREF_THRESHOLD 10000
  2692. void Plugin2Handler::WriteHugePref( IHXPreferences* pIPrefs, const char* pszKeyName, IHXBuffer* pBigBuffer)
  2693. {
  2694.     int counter = 0;
  2695.     UCHAR* pPlaceHolder;
  2696.     char szNewKeyName[1024]; /* Flawfinder: ignore */
  2697.     char szNumber[16]; /* Flawfinder: ignore */ // a REALLY big buffer could be put in :)
  2698.     int nOriginalBufferSize = pBigBuffer->GetSize();
  2699.     CHXBuffer* pNewBuffer;
  2700.     IHXBuffer* pIHXBuffer;
  2701.     ULONG32 nNewBufferSize;
  2702.     char oldValue;
  2703.     if (nOriginalBufferSize>PREF_THRESHOLD)
  2704.     {
  2705. pNewBuffer = new CHXBuffer();
  2706. pNewBuffer->QueryInterface(IID_IHXBuffer, (void**)&pIHXBuffer);
  2707. pNewBuffer->SetSize(PREF_THRESHOLD);
  2708. pPlaceHolder = pBigBuffer->GetBuffer();
  2709. // bleech we are going to break up the buffer into more managiable chunks.
  2710. while(((int)(pPlaceHolder - pBigBuffer->GetBuffer() ))!= nOriginalBufferSize)
  2711. {
  2712.     nNewBufferSize = nOriginalBufferSize - (ULONG32 ( pPlaceHolder - pBigBuffer->GetBuffer() ));
  2713.     if (nNewBufferSize> PREF_THRESHOLD)
  2714.     {
  2715. nNewBufferSize = PREF_THRESHOLD;
  2716.     }
  2717.     memcpy((char*)pNewBuffer->GetBuffer(), pPlaceHolder, nNewBufferSize); /* Flawfinder: ignore */
  2718.     SafeStrCpy(szNewKeyName,  pszKeyName, 1024);
  2719.     sprintf(szNumber, "%d", counter); /* Flawfinder: ignore */
  2720.     SafeStrCat(szNewKeyName,  szNumber, 1024);
  2721.     /*
  2722.      * Check for a null termination at the end .. if not then muck around.
  2723.      */
  2724.     char* pTempchar = (char*)pNewBuffer->GetBuffer();
  2725.     if (pTempchar[nNewBufferSize-1])
  2726.     {
  2727. // not null terminated.
  2728. oldValue = pTempchar[nNewBufferSize-1];
  2729. pTempchar[nNewBufferSize-1] = 0;
  2730. pIPrefs->WritePref(szNewKeyName, pIHXBuffer);
  2731. nNewBufferSize--;
  2732.     }
  2733.     else
  2734.     {
  2735. pIPrefs->WritePref(szNewKeyName, pIHXBuffer);
  2736.     }
  2737.     pPlaceHolder+=nNewBufferSize;
  2738.     counter++;
  2739. }
  2740. HX_RELEASE(pIHXBuffer);
  2741.     }
  2742.     else
  2743.     {
  2744. SafeStrCpy(szNewKeyName,  pszKeyName, 1024);
  2745. SafeStrCat(szNewKeyName,  "0", 1024);
  2746. pIPrefs->WritePref(szNewKeyName, pBigBuffer);
  2747.     }
  2748. }
  2749. /*
  2750.  *  Win98 does not allow reg keys that are larger than 16k a pop.
  2751.  *  Thus, this function takes regkeys that were split up and re-joins them
  2752.  *  for later processing.
  2753.  */
  2754. HX_RESULT Plugin2Handler::ReadHugePref( IHXPreferences* pIPrefs, const char* pszKeyName, REF(IHXBuffer*) pBigBuffer)
  2755. {
  2756.     HX_LOG_BLOCK( "Plugin2Handler::ReadHugePref" );
  2757.     CHXSimpleList   listOBuffers;
  2758.     HX_RESULT     retVal = HXR_FAIL;
  2759.     IHXBuffer*     pBuffer;
  2760.     char     szNewKeyName[1024]; /* Flawfinder: ignore */
  2761.     char     szNumber[16]; /* Flawfinder: ignore */
  2762.     int     counter = 0;
  2763.     int     totalSize = 0;
  2764.     UCHAR*     pPos;
  2765.     pBigBuffer     = NULL;
  2766.     SafeStrCpy(szNewKeyName,  pszKeyName, 1024);
  2767.     SafeStrCat(szNewKeyName,  "0", 1024);
  2768.     retVal = pIPrefs->ReadPref(szNewKeyName, pBuffer);
  2769.     while(HXR_OK == retVal)
  2770.     {
  2771. totalSize+=pBuffer->GetSize();
  2772. listOBuffers.AddTail((void*) pBuffer);
  2773. counter++;
  2774. SafeStrCpy(szNewKeyName,  pszKeyName, 1024);
  2775. sprintf(szNumber, "%d", counter); /* Flawfinder: ignore */
  2776. SafeStrCat(szNewKeyName,  szNumber, 1024);
  2777. retVal = pIPrefs->ReadPref(szNewKeyName, pBuffer);
  2778.     }
  2779.     if (listOBuffers.GetCount())
  2780.     {
  2781. pBigBuffer = new CHXBuffer;
  2782. pBigBuffer->AddRef();
  2783. pBigBuffer->SetSize(totalSize);
  2784. pPos = pBigBuffer->GetBuffer();
  2785. *pPos = 0;
  2786. CHXSimpleList::Iterator i;
  2787. for(i=listOBuffers.Begin(); i!=listOBuffers.End(); ++i)
  2788. {
  2789.     pBuffer = (IHXBuffer*)*i;
  2790.     SafeStrCat((char*)pPos, (char*)pBuffer->GetBuffer(), totalSize);
  2791.     HX_RELEASE(pBuffer);
  2792. }
  2793. return HXR_OK;
  2794.     }
  2795.     else
  2796.     {
  2797. return HXR_FAIL;
  2798.     }
  2799. }
  2800. // XXXND This function doesn't correctly deal with mount points.  The last mount point in the list
  2801. // that has any contents will overwrite all the others.
  2802. void Plugin2Handler::WriteSupportedGUIDs()
  2803. {
  2804.     if (m_GUIDtoSupportList.GetCount())
  2805.     {
  2806.        // Create buffer to use by CPluginInfoWriter...
  2807. IHXBuffer* pIHXBuffer = NULL;
  2808. CHXBuffer* pBuffer = new CHXBuffer();
  2809. if(pBuffer)
  2810. {
  2811.     if(SUCCEEDED(pBuffer->QueryInterface(IID_IHXBuffer, (void**)&pIHXBuffer)))
  2812.     {
  2813. pIHXBuffer->SetSize(PREF_CACHE_SIZE);
  2814.     }
  2815. }
  2816. char szRegKey[255]; /* Flawfinder: ignore */
  2817. SafeStrCpy(szRegKey,  PLUGIN_REGKEY_ROOT, 255);
  2818. SafeStrCat(szRegKey,  zm_pszRegKeySeperator, 255);
  2819. SafeStrCat(szRegKey,  PLUGIN_GUIDINFO, 255);
  2820. // Do this for each MountPoint
  2821. for(CHXMapStringToOb::Iterator mp = m_MountPoints.Begin(); mp!=m_MountPoints.End(); ++mp)
  2822. {
  2823.     PluginMountPoint* pMountPoint = (PluginMountPoint*) *mp;
  2824.     // format of GUID info:
  2825.     // {GUID, filename, index, filename, index, etc}{GUID, filename, index, filename, index}
  2826.     IHXPreferences* pIPrefs = pMountPoint->Prefs();
  2827.     if( pIPrefs )
  2828.     {
  2829. CPluginInfoWriter piw;
  2830. piw.Init(pIPrefs, szRegKey, pIHXBuffer);
  2831. // Dump the data.
  2832. CHXSimpleList::Iterator i;
  2833. CHXMapStringToOb::Iterator k;
  2834. for(k = m_GUIDtoSupportList.Begin(); k!=m_GUIDtoSupportList.End(); ++k)
  2835. {
  2836.     BOOL foundFirst = FALSE;
  2837.     CHXSimpleList* pSupportedList = (CHXSimpleList*) *k;
  2838.     for (i=pSupportedList->Begin(); i!=pSupportedList->End();++i)
  2839.     {
  2840. PluginSupportingGUID* pSupportItem = (PluginSupportingGUID*) *i;
  2841. if( pSupportItem->m_pMountPoint == pMountPoint )
  2842. {
  2843.     if( !foundFirst )
  2844.     {
  2845. foundFirst = TRUE;
  2846. piw.Write("{");
  2847. piw.Write(k.get_key());
  2848.     }
  2849.     char    szScratch[20]; /* Flawfinder: ignore */
  2850.     itoa(pSupportItem->m_nIndexInDLL, szScratch, 10);
  2851.     piw.Write(",");
  2852.     piw.Write((const char*) pSupportItem->m_filename);
  2853.     piw.Write(",");
  2854.     piw.Write(szScratch);
  2855. }
  2856.     }
  2857.     if( foundFirst )
  2858.     {
  2859. piw.Write("}");
  2860.     }
  2861. }
  2862. HX_RELEASE( pIPrefs );
  2863.     }
  2864. }
  2865. HX_RELEASE( pIHXBuffer );
  2866.     }
  2867. }
  2868. STDMETHODIMP_(ULONG32) Plugin2Handler::GetNumOfPlugins()
  2869. {
  2870.     return m_PluginList.GetCount();
  2871. }
  2872. STDMETHODIMP Plugin2Handler::GetPlugin(ULONG32 ulIndex, REF(IUnknown*)  /*OUT*/ pInstance)
  2873. {
  2874.     return GetPlugin( ulIndex, pInstance, NULL );
  2875. }
  2876. STDMETHODIMP Plugin2Handler::FlushCache()
  2877. {
  2878.     // if we have no context do not proceed.
  2879.     if (!m_pContext)
  2880.     {
  2881. return INVALID_CONTEXT;
  2882.     }
  2883.     INT32 nTempCache = m_nCacheSizeBites;
  2884.     m_nCacheSizeBites = 0;
  2885.     UpdateCache();
  2886.     m_nCacheSizeBites = nTempCache;
  2887.     // now we have to tell all other players that they should also
  2888.     // flush thier cache.
  2889.     IHXShutDownEverything* pShutDown = NULL ;
  2890.     if (HXR_OK == m_pContext->QueryInterface(IID_IHXShutDownEverything, (void**) &pShutDown))
  2891.     {
  2892. pShutDown->AskAllOtherPlayersToUnload();
  2893. HX_RELEASE(pShutDown);
  2894.     }
  2895.     return HXR_OK;
  2896. }
  2897. STDMETHODIMP Plugin2Handler::SetCacheSize(ULONG32 nSizeKB)
  2898. {
  2899.     m_nCacheSizeBites = (nSizeKB<<10);
  2900.     UpdateCache();
  2901.     return HXR_OK;
  2902. }
  2903. HX_RESULT Plugin2Handler::AddtoLRU(Plugin2Handler::PluginDLL* pDLL)
  2904. {
  2905.     // 1st we have to find if the plugin is in the LRU list
  2906.     // and if it is remove it.
  2907.     RemoveFromLRU(pDLL);
  2908.     // now just add to the LRU list.
  2909.     m_DLL_LRUList.AddTail((void*)pDLL);
  2910.     return HXR_OK;
  2911. }
  2912. HX_RESULT Plugin2Handler::RemoveFromLRU(Plugin2Handler::PluginDLL* pDLL)
  2913. {
  2914.     if (pDLL)
  2915.     {
  2916.         LISTPOSITION pPos = m_DLL_LRUList.Find(pDLL);
  2917.         if (pPos)
  2918.         {
  2919.             m_DLL_LRUList.RemoveAt(pPos);
  2920.         }
  2921.         return HXR_OK;
  2922.     }
  2923.     return HXR_INVALID_PARAMETER;
  2924. }
  2925. HX_RESULT Plugin2Handler::UpdateCache()
  2926. {
  2927.     // XXXAH we are disabling the cache feature until
  2928.     //       we fix all of our plugins to make all
  2929.     //      objects which are supposed to live past the
  2930.     //      lifetime of the plugin with the CCF.