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

Symbian

开发平台:

Visual C++

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