plghand2.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:192k
- /* ***** BEGIN LICENSE BLOCK *****
- * Source last modified: $Id: plghand2.cpp,v 1.26.8.4 2004/07/09 02:07:28 hubbe Exp $
- *
- * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
- *
- * The contents of this file, and the files included with this file,
- * are subject to the current version of the RealNetworks Public
- * Source License (the "RPSL") available at
- * http://www.helixcommunity.org/content/rpsl unless you have licensed
- * the file under the current version of the RealNetworks Community
- * Source License (the "RCSL") available at
- * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
- * will apply. You may also obtain the license terms directly from
- * RealNetworks. You may not use this file except in compliance with
- * the RPSL or, if you have a valid RCSL with RealNetworks applicable
- * to this file, the RCSL. Please see the applicable RPSL or RCSL for
- * the rights, obligations and limitations governing use of the
- * contents of the file.
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL") in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your version of
- * this file only under the terms of the GPL, and not to allow others
- * to use your version of this file under the terms of either the RPSL
- * or RCSL, indicate your decision by deleting the provisions above
- * and replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient may
- * use your version of this file under the terms of any one of the
- * RPSL, the RCSL or the GPL.
- *
- * This file is part of the Helix DNA Technology. RealNetworks is the
- * developer of the Original Code and owns the copyrights in the
- * portions it created.
- *
- * This file, and the files included with this file, is distributed
- * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
- * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
- * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
- * ENJOYMENT OR NON-INFRINGEMENT.
- *
- * Technology Compatibility Kit Test Suite(s) Location:
- * http://www.helixcommunity.org/content/tck
- *
- * Contributor(s):
- *
- * ***** END LICENSE BLOCK ***** */
- /****************************************************************************
- *
- *
- * Plugin information are stored into the registry in the following format:
- *
- * File Format Plugins: {dllpath;description;copyright;moreinfo;loadmultiple;mimetype1|mimetype2;extension1|extension2}{ ... }
- * ---------------------------------------------------------------------------------------------------
- * One Plugin
- *
- * File System Plugins: {dllpath;description;copyright;moreinfo;loadmultiple;protocol;shortname}{ ... }
- * ----------------------------------------------------------------------------
- * One Plugin
- *
- * Renderer Plugins: {dllpath;description;copyright;moreinfo;loadmultiple;mimetype1|mimetype2}{ ... }
- * -----------------------------------------------------------------------------
- * One Plugin
- *
- * Broadcast Plugins: {dllpath;description;copyright;moreinfo;loadmultiple;type}{ ... }
- * --------------------------------------------------------------
- * One Plugin
- *
- * Stream Description Plugins: {dllpath;description;copyright;moreinfo;loadmultiple;mimetype}{ ... }
- * ----------------------------------------------------------------------------
- * One Plugin
- *
- * Allowance Plugins: {dllpath;description;copyright;moreinfo;loadmultiple}{ ... }
- * ---------------------------------------------------------
- * One Plugin
- *
- * Misc. Plugins: {dllpath;description;copyright;moreinfo;loadmultiple}{ ... }
- * ---------------------------------------------------------
- * One Plugin
- *
- * Plugins: {dllpath;description;copyright;moreinfo;loadmultiple}{ ... }
- * ---------------------------------------------------------
- * One Plugin
- *
- */
- #include "hxtypes.h"
- #ifdef _WINDOWS
- #include <windows.h>
- #include <ctype.h>
- #endif
- #ifdef _MACINTOSH
- #include <ctype.h>
- #include "filespec.h"
- #include "filespecutils.h"
- #endif
- #if defined _UNIX
- #include <stdlib.h>
- #include <sys/param.h>
- #define _MAX_PATH MAXPATHLEN
- #elif defined (_MACINTOSH)
- #include <stdlib.h>
- #include "fullpathname.h"
- #include "chxdataf.h"
- #ifdef _MAC_MACHO
- #include <sys/stat.h>
- #else
- #include <stat.h>
- #endif
- #include <fcntl.h>
- #endif
- #include <stdio.h>
- #include "hlxclib/sys/stat.h"
- #include "hxresult.h"
- #include "hxassert.h"
- #include "hxcom.h"
- #include "ihxpckts.h"
- #include "hxfiles.h"
- #include "hxformt.h"
- #include "hxfwrtr.h"
- #include "hxrendr.h"
- #include "hxprefs.h"
- #include "hxplugn.h"
- #include "hxdtcvt.h"
- #include "hxphand.h"
- //#include "hxmeta.h"
- #include "hxsdesc.h"
- #include "hxauth.h"
- #include "hxallow.h"
- #include "hxerror.h"
- #include "hxcomm.h"
- #include "hxengin.h"
- #include "hxshtdn.h"
- #include "hxplgns.h"
- #include "hxmon.h"
- #include "chxpckts.h"
- #include "hxstring.h"
- #include "hxslist.h"
- #include "hxmap.h"
- #include "hxstrutl.h"
- #include "hxdir.h"
- #include "findfile.h"
- #include "dbcs.h"
- #include "hxbdwdth.h"
- #include "plghand2.h"
- #include "chxuuid.h"
- #include "md5.h"
- #include "dllacces.h"
- #include "dllpath.h"
- #include "hxperf.h"
- #include "rtsputil.h"
- #include "hxver.h"
- #include "hxheap.h"
- #ifdef _DEBUG
- #undef HX_THIS_FILE
- static const char HX_THIS_FILE[] = __FILE__;
- #endif
- #ifdef _STATICALLY_LINKED
- #include "staticff.h"
- #endif
- #if defined(HELIX_FEATURE_PREFERENCES)
- #include "hxprefs.h"
- #include "hxprefutil.h"
- #endif /* HELIX_FEATURE_PREFERENCES */
- /*
- * XXXND These are also defined in geminc/gemplatformdata.h
- */
- #define NAMESPACE_SEPARATOR ':'
- /*
- * Win98 does not allow reg keys that are larger than 16k a pop. we used this value to break up into more manageable bites
- */
- #define PREF_CACHE_SIZE 10000
- /*
- Load each plug-in, read info, store in memory and update prefs
- This is only done if the plugin hash within the registery is not the same
- as the plugin hash of the plugins directory.
- */
- const char* const Plugin2Handler::zm_pszValueSeperator = "|";
- const char* const Plugin2Handler::zm_pszListStart = "{";
- const char* const Plugin2Handler::zm_pszListEnd = "}";
- const char* const Plugin2Handler::zm_pszValueSeperator2= ",";
- const char* const Plugin2Handler::zm_pszKeyNameRegKey = "~KeyNames~";
- const char* const Plugin2Handler::zm_pszRegKeySeperator = "\";
- #if !defined(HELIX_CONFIG_NOSTATICS)
- BOOL Plugin2Handler::zm_bFasterPrefs = 0;
- #else
- const BOOL Plugin2Handler::zm_bFasterPrefs = 0;
- #endif
- const char* const Plugin2Handler::zm_pszFileExtension = OS_DLL_PATTERN_STRING;
- const char* const Plugin2Handler::zm_pszDirectorySeperator = OS_SEPARATOR_STRING;
- const char Plugin2Handler::zm_cDirectorySeperator = OS_SEPARATOR_CHAR;
- // XXXHP - temporary changes to track PR70528
- #ifdef REALPLAYER_PLUGIN_HANDLER_RESEARCH_
- inline FILE* OpenErrorLog_ ()
- {
- static char const* const realPlayerErrorsLog = "rperrors.log";
- static char const* const appendMode = "a+";
- return fopen (realPlayerErrorsLog, appendMode);
- }
- inline void LogRegistryRegeneration_ (char const* pKey, IHXBuffer* pIEntry)
- {
- FILE* const logStream = OpenErrorLog_ ();
- PRE_REQUIRE_VOID_RETURN (logStream);
- fprintf (logStream, "--------------- INVALID REGISTRY ENTRY: ----------------------------n");
- fprintf (logStream, "Key: %sn", pKey);
- fprintf (logStream, "tData: [%s]n", pIEntry->GetBuffer ());
- fprintf (logStream, "--------------------------------------------------------------------n");
- fclose (logStream);
- }
- inline void LogCriticalError_ (char const* pErrorReport)
- {
- FILE* const logStream = OpenErrorLog_ ();
- PRE_REQUIRE_VOID_RETURN (logStream);
- fprintf (logStream, "---------------- CRITICAL ERROR ------------------------------------n");
- fprintf (logStream, "%sn", pErrorReport);
- fprintf (logStream, "--------------------------------------------------------------------n");
- fclose (logStream);
- }
- #else
- inline void LogRegistryRegeneration_ (char const*, IHXBuffer*)
- {
- }
- #endif
- /**************************************************************************
- ****************************Plugin2Handler**********************************
- **************************************************************************/
- IMPLEMENT_COM_CREATE_FUNCS( Plugin2Handler )
- BEGIN_INTERFACE_LIST_NOCREATE( Plugin2Handler )
- INTERFACE_LIST_ENTRY_SIMPLE( IHXCallback )
- INTERFACE_LIST_ENTRY_SIMPLE( IHXPluginEnumerator )
- INTERFACE_LIST_ENTRY_SIMPLE( IHXPluginReloader )
- INTERFACE_LIST_ENTRY_SIMPLE( IHXPlugin2Handler )
- INTERFACE_LIST_ENTRY_SIMPLE( IHXPlugin2HandlerEnumeratorInterface )
- INTERFACE_LIST_ENTRY_SIMPLE( IHXPluginHandler3 )
- INTERFACE_LIST_ENTRY_SIMPLE( IHXPluginDatabase )
- END_INTERFACE_LIST
- inline HX_RESULT Plugin2Handler::VerifyChecksum_ (const char* pData)
- {
- REQUIRE_RETURN (pData, HXR_INVALID_PARAMETER);
- static const char endEntry = '}';
- static const int error = -1;
- // find the last end-marker of the last entry.
- const CHXString data = pData;
- const int lastEntry = data.ReverseFind (endEntry);
- REQUIRE_RETURN_QUIET (lastEntry != error, HXR_FAIL);
- // the checksum should be equal to the position of the end of the last entry plus 1.
- const int calculatedChecksum = lastEntry + 1;
- // read in the actual checksum.
- const CHXString checksumString = pData + calculatedChecksum;
- const int actualChecksum = ::atoi (checksumString);
- return actualChecksum == calculatedChecksum ? HXR_OK : HXR_FAIL;
- }
- Plugin2Handler::Plugin2Handler() :
- m_pPluginDir( NULL )
- , m_pPreferences(NULL)
- , m_pErrorMessages(NULL)
- , m_pContext(NULL)
- , m_nCacheSizeBites( (1<<24) )
- , m_pIScheduler(NULL)
- , m_hScheduler( 0 )
- {
- }
- Plugin2Handler::~Plugin2Handler()
- {
- // Make sure Close() got called
- if( m_pContext )
- {
- Close();
- }
- }
- STDMETHODIMP Plugin2Handler::Init(IUnknown* pContext)
- {
- HX_RESULT result = HXR_FAIL;
- if( SUCCEEDED( result = RegisterContext( pContext ) ) )
- {
- result = ReadFromRegistry();
- }
- return result;
- }
- STDMETHODIMP_(ULONG32) Plugin2Handler::GetNumOfPlugins2()
- {
- return m_PluginList.GetCount();
- }
- STDMETHODIMP Plugin2Handler::GetPluginInfo (UINT32 unIndex,
- REF(IHXValues*) /*OUT*/ pValues)
- {
- HX_RESULT retVal = HXR_FAIL;
- LISTPOSITION pPos = m_PluginList.FindIndex(unIndex);
- if (pPos)
- {
- Plugin2Handler::Plugin* pPlugin = (Plugin2Handler::Plugin*) m_PluginList.GetAt(pPos);
- if (pPlugin)
- {
- retVal = pPlugin->GetPluginInfo(pValues);
- pValues->AddRef();
- }
- }
- return retVal;
- }
- // ---------------------------------------------------------- IHXCallback
- // **********************************************
- STDMETHODIMP
- Plugin2Handler::Func( THIS )
- {
- if ( !m_pIScheduler || !m_hScheduler )
- {
- return( HXR_UNEXPECTED );
- }
- HX_RESULT outResult = HXR_OK;
- // Our timer is infinite.
- m_hScheduler = m_pIScheduler->RelativeEnter( this, kPingDuration );
- if ( !m_hScheduler )
- {
- outResult = HXR_FAIL;
- }
- UnloadDeadDLLs();
- return( outResult );
- }
- // **********************************************
- // This function is called periodically when the plugin handler
- // object is pinged by the scheduler.
- void Plugin2Handler::UnloadDeadDLLs( void )
- {
- HX_LOG_BLOCK( "Plugin2Handler::UnloadDeadDLLs" );
- LISTPOSITION posCanUnload = m_CanUnload2DllList.GetHeadPosition();
- while ( posCanUnload )
- {
- // Save off current position for delete.
- LISTPOSITION posAt = posCanUnload;
- // Get current item, and increment position.
- Plugin2Handler::PluginDLL* pPluginDLLCanUnload = (Plugin2Handler::PluginDLL*) m_CanUnload2DllList.GetNext( posCanUnload );
- if ( pPluginDLLCanUnload )
- {
- pPluginDLLCanUnload->Unload( TRUE ); // TRUE: "safe" unload
- }
- }
- }
- /*
- ReconnectDLL()
- This replaces one PluginDLL in m_PluginDLLList with a new instance.
- It removes any plugins that refered to the old DLL.
- */
- void Plugin2Handler::ReconnectDLL(const char* pszDLLName, Plugin2Handler::PluginDLL* pNewDLL)
- {
- HX_LOG_BLOCK( "Plugin2Handler::ReconnectDLL" );
- // before we add this to the tail we must check to see if this
- // plugin is already within the list....
- Plugin2Handler::PluginDLL* pOldPluginDll = NULL;
- LISTPOSITION pPos = NULL;
- if (m_FileNameMap.Lookup(pszDLLName, (void*&)pOldPluginDll))
- {
- pPos = m_PluginDLLList.Find(pOldPluginDll);
- if (pPos)
- {
- m_PluginDLLList.RemoveAt(pPos);
- }
- // now see who the heck was connected to this pluginDLL
- pPos = m_PluginList.GetHeadPosition();
- while( pPos )
- {
- // Save off current position for delete
- LISTPOSITION posAt = pPos;
- // Get current item, and increment position
- Plugin2Handler::Plugin* pPlugin = (Plugin2Handler::Plugin*) m_PluginList.GetNext( pPos );
- // If this plugin belongs to the old DLL, remove it.
- if( pPlugin && pPlugin->GetDLL() == pOldPluginDll )
- {
- // Delete from the saved position
- m_PluginList.RemoveAt( posAt );
- HX_RELEASE( pPlugin );
- }
- }
- HX_RELEASE(pOldPluginDll);
- }
- m_PluginDLLList.AddTail(pNewDLL);
- m_FileNameMap.SetAt(pszDLLName, pNewDLL);
- }
- /*
- LoadDLL()
- This is called during a Refresh() (which is deprecated)
- or if we determine that the DLL is dirty and needs to be updated
- */
- Plugin2Handler::Errors Plugin2Handler::LoadDLL( char* pszDllName,
- PluginMountPoint* pMountPoint )
- {
- Errors result = NO_ERRORS;
- UINT32 i = 0;
- struct stat stat_stuct;
- IHXBuffer* pPathBuffer = pMountPoint->Path();
- // Make sure there is no path in the pszDllName
- HX_ASSERT( !strrchr(pszDllName, Plugin2Handler::zm_cDirectorySeperator) );
- Plugin2Handler::PluginDLL* pPluginDll = NULL;
- if( !( pPluginDll = new Plugin2Handler::PluginDLL( pszDllName, pMountPoint, this ) ) )
- {
- return MEMORY_ERROR;
- }
- pPluginDll->AddRef();
- CHXString sFileWithPath = pPathBuffer->GetBuffer();
- UINT32 len = sFileWithPath.GetLength();
- if(len &&
- sFileWithPath.GetAt(len - 1) != Plugin2Handler::zm_cDirectorySeperator)
- sFileWithPath += Plugin2Handler::zm_cDirectorySeperator;
- sFileWithPath += pszDllName;
- if (NO_ERRORS==Stat(sFileWithPath, &stat_stuct))
- {
- pPluginDll->SetFileSize((INT32)stat_stuct.st_size);
- }
- result = pPluginDll->Load(m_pContext);
- if (NO_ERRORS != result )
- {
- goto cleanup;
- }
- // Set the hash
- if (pPathBuffer)
- {
- IHXBuffer* pNewChecksum = ChecksumFile( pszDllName, pPathBuffer );
- if (pNewChecksum)
- {
- HX_RELEASE(pPathBuffer);
- pPluginDll->SetHash((char*)pNewChecksum->GetBuffer());
- HX_RELEASE(pNewChecksum);
- }
- }
- // Remove this DLL from the list of supported DLL (based on GUIDs)
- RemoveDLLFromGUIDSupportLists(pszDllName);
- // ReconnectDLL() replaces one PluginDLL object with another PluginDLL; however,
- // both of these PluginDLL objects refer to the same DLL. This ensures that
- // only one PluginDLL object per DLL is in the m_PluginDLLList.
- ReconnectDLL(pszDllName, pPluginDll);
- for(i=0;i<pPluginDll->GetNumPlugins();i++)
- {
- Plugin* pPlugin = NULL;
- // create a new plugin object
- if (!(pPlugin = new Plugin(m_pContext)))
- {
- return MEMORY_ERROR;
- }
- // Setup plugin information
- pPlugin->AddRef();
- pPlugin->SetDLL(pPluginDll);
- pPlugin->SetIndex((UINT16)i);
- pPlugin->SetInfoNeedsRefresh(TRUE);
- IUnknown* pUnk = NULL;
- if( NO_ERRORS != pPlugin->GetPlugin( pUnk ) )
- {
- // This plugin doesn't work. Delete it.
- HX_RELEASE( pPlugin );
- }
- else
- {
- IHXPluginNamespace* pPluginNamespace = NULL;
- if (SUCCEEDED(pUnk->QueryInterface(IID_IHXPluginNamespace, (void**) &pPluginNamespace)))
- {
- /*
- * Memory for the IHXBuffer is allocated in the plugin
- */
- IHXBuffer* pBuffer = NULL;
- if (SUCCEEDED(pPluginNamespace->GetPluginNamespace(pBuffer)))
- {
- pPluginDll->SetNamespace(pBuffer);
- HX_RELEASE(pBuffer);
- }
- HX_RELEASE(pPluginNamespace);
- }
- IHXComponentPlugin* pIIterator = NULL;
- if( SUCCEEDED( pUnk->QueryInterface( IID_IHXComponentPlugin, (void**) &pIIterator ) ) )
- {
- // We don't need this.
- HX_RELEASE( pPlugin );
- LoadPluginsFromComponentDLL( pPluginDll, pIIterator );
- HX_RELEASE( pIIterator );
- }
- else
- {
- IHXPlugin* pIHXPlugin;
- if( SUCCEEDED( pUnk->QueryInterface(IID_IHXPlugin, (void**)&pIHXPlugin ) ) )
- {
- pPlugin->GetValuesFromDLL(pIHXPlugin);
- m_PluginList.AddTail(pPlugin);
- // Print out some log info about the plugin we just loaded
- {
- const char *pDesc, *pCopy, *pURL;
- ULONG32 ulVersionNumber = 0;
- BOOL junk;
- pIHXPlugin->GetPluginInfo(junk, pDesc, pCopy, pURL, ulVersionNumber);
- ReportError( HXLOG_INFO, pszDllName, pDesc );
- }
- // At this point since we have the HXPlugin we should query it to see if
- // it supports any of the GUIDs which have been enumerated so far.
- UINT32 nNumGUIDs = GetNumSupportedGUIDs();
- for(; nNumGUIDs; nNumGUIDs--)
- {
- CHXString pszGUID;
- GUID theGUID;
- GetGUIDForIndex(nNumGUIDs-1, pszGUID);
- CHXuuid::HXUuidFromString(pszGUID, (uuid_tt*)&theGUID);
- IUnknown* pQueryUnk;
- if (HXR_OK == pIHXPlugin->QueryInterface(theGUID, (void**)&pQueryUnk))
- {
- AddSupportForGUID(pszGUID, pPluginDll, i);
- HX_RELEASE(pQueryUnk);
- }
- }
- // if this is a required plugin, validate it // XXXAH this could be a problem
- // if (IsPluginRequired(pDesc, pPlugin))
- // {
- // bValidated = ValidateRequiredPlugin(pIHXPlugin, pPlugin);
- // }
- pIHXPlugin->Release();
- }
- }
- }
- HX_RELEASE( pUnk );
- }
- cleanup:
- HX_RELEASE(pPathBuffer);
- if (result != NO_ERRORS)
- {
- HX_RELEASE( pPluginDll );
- }
- return result;
- }
- void Plugin2Handler::LoadPluginsFromComponentDLL( Plugin2Handler::PluginDLL* pPluginDll,
- IHXComponentPlugin* pIIterator )
- {
- IHXPlugin* pIHXPlugin = NULL;
- if( SUCCEEDED( pIIterator->QueryInterface(IID_IHXPlugin, (void**)&pIHXPlugin ) ) )
- {
- // XXXHP - this is now done in the PluginDLL::Load() method
- // pIHXPlugin->InitPlugin( m_pContext );
- for( UINT32 index = 0; index < pIIterator->GetNumComponents(); index++ )
- {
- IHXValues* pIValues = NULL;
- if( SUCCEEDED( pIIterator->GetComponentInfoAtIndex( index, pIValues ) ) )
- {
- IHXBuffer* pBuffer = NULL;
- if (SUCCEEDED(pIValues->GetPropertyCString(PLUGIN_COMPONENT_NAME, pBuffer)))
- {
- IHXBuffer* pNamespace = pPluginDll->GetNamespace();
- if (pNamespace)
- {
- CHXString TempNamespace = pNamespace->GetBuffer();
- TempNamespace += NAMESPACE_SEPARATOR;
- TempNamespace += pBuffer->GetBuffer();
- IHXBuffer* pTempBuffer = new CHXBuffer();
- pTempBuffer->AddRef();
- pTempBuffer->Set((BYTE*)(const char*)TempNamespace, TempNamespace.GetLength()+1);
- pIValues->SetPropertyCString(PLUGIN_COMPONENT_NAME, pTempBuffer);
- HX_RELEASE(pTempBuffer);
- HX_RELEASE(pNamespace);
- }
- HX_RELEASE(pBuffer);
- }
- // create a new plugin object
- Plugin* pPlugin = new Plugin( m_pContext );
- HX_ASSERT( pPlugin );
- // Setup plugin object
- pPlugin->AddRef();
- pPlugin->SetDLL( pPluginDll );
- // XXXP - this isn't necessary, the Plugin is initialized with an index of 0 if no index is found.
- // pPlugin->SetIndex( (UINT16) 0 );
- pPlugin->SetInfoNeedsRefresh( TRUE );
- // XXXND FIX I don't like this specialized interface.
- // This gets the basic info from pIHXPlugin, and the rest from pValues
- pPlugin->InitializeComponentPlugin( pIHXPlugin, pIValues );
- // Put in plugin list
- m_PluginList.AddTail(pPlugin);
- // Stick CLSID in map
- AddPluginToIndices( pPlugin );
- HX_RELEASE( pIValues );
- }
- }
- HX_RELEASE (pIHXPlugin);
- }
- }
- STDMETHODIMP Plugin2Handler::ReloadPlugins()
- {
- // now we have to tell all other players that they should also
- // reload their plugins.
- IHXShutDownEverything* pShutDown = NULL ;
- if (HXR_OK == m_pContext->QueryInterface(IID_IHXShutDownEverything, (void**) &pShutDown))
- {
- pShutDown->AskAllOtherPlayersToReload();
- HX_RELEASE(pShutDown);
- }
- // This will re-initialize all the MountPoints
- return ReloadPluginsNoPropagate();
- }
- ///////////////////////////////////////////////////////////////////////////////
- // These functions will find all plugins which are different
- // then those loaded into the registry.
- // It will then load them into memory, get their data, and unload them.
- // It will return HXR_FAIL if some DLL has different values within the
- // registry, and is presently in memory (how could this happen??)
- // If anyone was keeping an index to a loaded DLL and assuming that it
- // would remain constant ... that won't work!!
- HX_RESULT Plugin2Handler::ReloadPluginsNoPropagate()
- {
- HX_LOG_BLOCK( "Plugin2Handler::ReloadPluginsNoPropagate" );
- HX_RESULT result = HXR_OK;
- // Reload them all.
- for(CHXMapStringToOb::Iterator mp = m_MountPoints.Begin(); mp!=m_MountPoints.End(); ++mp)
- {
- PluginMountPoint* pMountPoint = (PluginMountPoint*) *mp;
- if( FAILED( ReloadPluginsNoPropagate( pMountPoint ) ) )
- {
- result = HXR_FAIL;
- }
- }
- return result;
- }
- HX_RESULT Plugin2Handler::ReloadPluginsNoPropagate( PluginMountPoint* pMountPoint )
- {
- HX_LOG_BLOCK( "Plugin2Handler::ReloadPluginsNoPropagate(PluginMP*)" );
- #ifndef _STATICALLY_LINKED
- CFindFile* pFileFinder = NULL;
- #else
- CStaticFindFile* pFileFinder = NULL;
- #endif
- IHXBuffer* pPathBuffer = NULL;
- char* pszPluginDir = NULL;
- ULONG32 nPluginDirLen = 0;
- char* pszDllName = 0;
- IHXBuffer* pNewChecksum = 0;
- BOOL bRegIsDirty = FALSE;
- BOOL bContinue;
- // if we have no context do not proceed.
- if (!m_pContext)
- {
- return INVALID_CONTEXT;
- }
- // If this is the 1st time, load everything into the registry.
- #ifndef _STATICALLY_LINKED
- pPathBuffer = pMountPoint->Path();
- if (!pPathBuffer)
- {
- return HXR_FAIL;
- }
- pPathBuffer->Get((UCHAR*&)pszPluginDir, nPluginDirLen);
- if (!nPluginDirLen)
- {
- return HXR_FAIL;
- }
- #else
- pszPluginDir="";
- #endif
- pFileFinder =
- #ifndef _STATICALLY_LINKED
- CFindFile::CreateFindFile
- #else
- CStaticFindFile::CreateFindFile
- #endif
- (pszPluginDir, 0, Plugin2Handler::zm_pszFileExtension);
- if (NULL == pFileFinder)
- {
- pPathBuffer->Release();
- HX_DELETE(pFileFinder);
- return HXR_FAIL;
- }
- pszDllName = pFileFinder->FindFirst();
- BOOL bDLLIsDirty = FALSE;
- while (pszDllName)
- {
- // See if this file exists in our list of pluginDLLs
- BOOL bFound = FALSE;
- CHXSimpleList::Iterator i;
- Plugin2Handler::PluginDLL* pDLL = NULL;
- bFound = m_FileNameMap.Lookup(pszDllName, (void*&)pDLL);
- // If it was not found it may a misc DLL -- ie not an
- // RMA DLL. Thus, we should ignore it.
- bContinue = FALSE;
- if (!bFound)
- {
- for(i=m_MiscDLLList.Begin();i!=m_MiscDLLList.End(); ++i)
- {
- Plugin2Handler::OtherDLL* pOther = (Plugin2Handler::OtherDLL*) *i;
- if (!stricmp(pOther->m_filename, pszDllName))
- {
- // ok we have a match does the checksum match?
- if (pNewChecksum = ChecksumFile(pszDllName, pPathBuffer))
- {
- if (!strcmp((char*)pNewChecksum->GetBuffer(), pOther->m_fileChecksum))
- bContinue = TRUE;
- HX_RELEASE(pNewChecksum);
- }
- }
- }
- }
- if (bContinue)
- {
- pszDllName = pFileFinder->FindNext();
- continue;
- }
- if (bFound)
- {
- if (pNewChecksum = ChecksumFile(pszDllName, pPathBuffer))
- {
- if (!strcasecmp(pDLL->GetHash(), (const char*)pNewChecksum->GetBuffer()))
- {
- pszDllName = pFileFinder->FindNext();
- pNewChecksum->Release();
- continue; // old checksum == new checksum. no changes.
- }
- pNewChecksum->Release();
- pNewChecksum = NULL;
- }
- // Delete all Plugins which are associated with this PluginDLL.
- LISTPOSITION pPos = NULL;
- if ( m_PluginList.GetCount() )
- {
- LISTPOSITION pPos = m_PluginList.GetHeadPosition();
- while (pPos)
- {
- // save off current position for delete
- LISTPOSITION posAt = pPos;
- Plugin2Handler::Plugin* pPlugin = (Plugin2Handler::Plugin*)m_PluginList.GetNext(pPos);
- HX_ASSERT(pPlugin);
- if ( pPlugin && pPlugin->GetDLL() == pDLL )
- {
- RemovePluginFromIndices( pPlugin );
- m_PluginList.RemoveAt( posAt );
- HX_RELEASE( pPlugin );
- }
- }
- }
- // Remove the pluginDLL from the PluginDLL list.
- pPos = m_PluginDLLList.Find(pDLL);
- if (pPos)
- {
- m_PluginDLLList.RemoveAt(pPos);
- m_FileNameMap.RemoveKey(pszDllName);
- // Since this PluginDLL was unloaded, no need to keep
- // it in the list of PluginDLLs which export CanUnload2().
- LISTPOSITION posCanUnload = m_CanUnload2DllList.Find( pDLL );
- if ( posCanUnload )
- {
- m_CanUnload2DllList.RemoveAt( posCanUnload );
- }
- }
- bDLLIsDirty = TRUE;
- }
- else
- {
- bDLLIsDirty = TRUE;
- }
- if (bDLLIsDirty)
- {
- // if we got here we have a new dll.
- Plugin2Handler::Errors loadResult;
- loadResult = LoadDLL( pszDllName, pMountPoint );
- if (loadResult!= NO_ERRORS)
- {
- // The DLL had one of the following problems:
- // (1) the DLL was unloadable
- // (2) the DLL did not have an HXCreateInstance
- // (3) an instance could not be created.
- // (4) It did not implement the PLUGIN interface
- // if it was case 2,3,4 then we can safely never attempt to
- // load the DLL again. However if it was (1) then we must attempt
- // to load the DLL ever time through since it was possibly unloadable due
- // to an imp-lib that will be satisfied lated (without modifing the
- // dll). Jeeze. That comment is UNREADABLE. I have to take effective written
- // english again!
- if (loadResult!=CANT_OPEN_DLL)
- {
- Plugin2Handler::OtherDLL* pDLLData = new Plugin2Handler::OtherDLL;
- pDLLData->m_filename = pszDllName;
- pDLLData->m_pMountPoint = pMountPoint;
- pNewChecksum = ChecksumFile(pszDllName, pPathBuffer);
- if (pNewChecksum)
- {
- pDLLData->m_fileChecksum = (char*)pNewChecksum->GetBuffer();
- HX_RELEASE(pNewChecksum);
- bRegIsDirty=TRUE;
- m_MiscDLLList.AddTail(pDLLData);
- }
- else
- {
- HX_DELETE(pDLLData);
- }
- }
- }
- else
- {
- bRegIsDirty = TRUE;
- }
- }
- pszDllName = pFileFinder->FindNext();
- }
- // now get the bandwidth data on all renderer plugins
- IHXValues* pVal = new CHXHeader();
- pVal->AddRef();
- IHXBuffer* pBuffer = new CHXBuffer();
- pBuffer->AddRef();
- pBuffer->Set((const UCHAR*)PLUGIN_RENDERER_TYPE, strlen(PLUGIN_RENDERER_TYPE)+1);
- pVal->SetPropertyCString(PLUGIN_CLASS, pBuffer);
- HX_RELEASE(pBuffer);
- for(CHXSimpleList::Iterator i = m_PluginList.Begin(); i!=m_PluginList.End(); ++i)
- {
- Plugin2Handler::Plugin* pPlug = (Plugin2Handler::Plugin*)*i;
- if (pPlug->DoesInfoNeedsRefresh() && pPlug->DoesMatch(pVal))
- {
- pPlug->GetBandwidthInfo();
- }
- }
- HX_RELEASE(pVal);
- if (bRegIsDirty)
- {
- // Pass the MountPoint to this so it can write the
- // specific plugins to the correct place
- WritePluginInfo( pMountPoint );
- }
- HX_RELEASE(pPathBuffer);
- HX_DELETE(pFileFinder);
- return HXR_OK;
- }
- STDMETHODIMP Plugin2Handler::FindIndexUsingValues (IHXValues* pValues,
- REF(UINT32) unIndex)
- {
- CHXSimpleList PossibleValues;
- CHXSimpleList PossibleIndexes;
- UINT32 j = 0;
- IHXValues* pPluginValues = NULL;
- IHXBuffer* pBuffer = NULL;
- CHXSimpleList::Iterator i = m_PluginList.Begin();
- for(; i!= m_PluginList.End(); ++i, j++)
- {
- Plugin2Handler::Plugin* pPlugin = (Plugin2Handler::Plugin*) *i;
- if (pPlugin->DoesMatch(pValues))
- {
- PossibleValues.AddTail(pPlugin);
- PossibleIndexes.AddTail((void*)j);
- }
- }
- if (PossibleValues.Begin() == PossibleValues.End())
- {
- unIndex = 0;
- return HXR_FAIL;
- }
- /****************************************************************
- ** Presently when we arrive at this spot with more than one
- ** plugin which matches the search criteria, we simply take
- ** the first one found. If this is not satisfactory then
- ** some method can be added which will process the list based
- ** upon some criteria.
- ****************************************************************/
- // if there are multiple plugins found, we will pick the one whose
- // plugin description contains "RealNetworks"
- if (PossibleValues.GetCount() > 1)
- {
- j = 0;
- for(i = PossibleValues.Begin(); i!= PossibleValues.End(); ++i, j++)
- {
- Plugin2Handler::Plugin* pPlugin = (Plugin2Handler::Plugin*) *i;
- if (HXR_OK == pPlugin->GetPluginInfo(pPluginValues) && pPluginValues)
- {
- if (HXR_OK == pPluginValues->GetPropertyCString(PLUGIN_DESCRIPTION2, pBuffer) &&
- pBuffer)
- {
- if (strstr((const char*)pBuffer->GetBuffer(), "RealNetworks"))
- {
- LISTPOSITION pos = PossibleIndexes.FindIndex(j);
- unIndex = (UINT32)(PTR_INT)PossibleIndexes.GetAt(pos);
- HX_RELEASE(pBuffer);
- return HXR_OK;
- }
- }
- HX_RELEASE(pBuffer);
- }
- }
- }
- i = PossibleIndexes.Begin();
- unIndex = (UINT32)(PTR_INT)*i;
- return HXR_OK;
- }
- STDMETHODIMP Plugin2Handler::GetInstance (UINT32 index, REF(IUnknown*) pUnknown)
- {
- pUnknown = NULL;
- LISTPOSITION pPos = m_PluginList.FindIndex(index);
- if (pPos)
- {
- Plugin2Handler::Plugin* pPlugin = (Plugin2Handler::Plugin*) m_PluginList.GetAt(pPos);
- if (pPlugin)
- {
- Errors retVal = pPlugin->GetInstance(pUnknown);
- if (retVal== NO_ERRORS)
- {
- return HXR_OK;
- }
- }
- }
- return HXR_FAIL;
- }
- STDMETHODIMP Plugin2Handler::FindIndexUsingStrings (char* PropName1,
- char* PropVal1,
- char* PropName2,
- char* PropVal2,
- char* PropName3,
- char* PropVal3,
- REF(UINT32) unIndex)
- {
- unIndex = 0;
- // PropName and PropVal have to to valid tuple
- if ((PropName1 && !PropVal1) ||
- (PropName2 && !PropVal2) ||
- (PropName3 && !PropVal3) ||
- (!PropName1 && PropVal1) ||
- (!PropName2 && PropVal2) ||
- (!PropName3 && PropVal3))
- return HXR_FAIL;
- IHXValues* pValues;
- HX_RESULT retVal = HXR_FAIL;
- CHXHeader* pHeader = new CHXHeader;
- pHeader->QueryInterface(IID_IHXValues, (void**)&pValues);
- AddToValues(pValues, PropName1, PropVal1, eString);
- AddToValues(pValues, PropName2, PropVal2, eString);
- AddToValues(pValues, PropName3, PropVal3, eString);
- retVal = FindIndexUsingValues(pValues, unIndex);
- pValues->Release();
- return retVal;
- }
- STDMETHODIMP Plugin2Handler::FindPluginUsingValues (IHXValues* pValues,
- REF(IUnknown*) pUnk)
- {
- return FindPluginUsingValues( pValues, pUnk, NULL );
- }
- HX_RESULT Plugin2Handler::FindGroupOfPluginsUsingStrings(char* PropName1,
- char* PropVal1,
- char* PropName2,
- char* PropVal2,
- char* PropName3,
- char* PropVal3,
- REF(CPluginEnumerator*) pEnumerator)
- {
- // PropName and PropVal have to to valid tuple
- if ((PropName1 && !PropVal1) ||
- (PropName2 && !PropVal2) ||
- (PropName3 && !PropVal3) ||
- (!PropName1 && PropVal1) ||
- (!PropName2 && PropVal2) ||
- (!PropName3 && PropVal3))
- return HXR_FAIL;
- IHXValues* pValues;
- HX_RESULT retVal = HXR_FAIL;
- CHXHeader* pHeader = new CHXHeader;
- pHeader->QueryInterface(IID_IHXValues, (void**)&pValues);
- AddToValues(pValues, PropName1, PropVal1, eString);
- AddToValues(pValues, PropName2, PropVal2, eString);
- AddToValues(pValues, PropName3, PropVal3, eString);
- retVal = FindGroupOfPluginsUsingValues(pValues, pEnumerator);
- pValues->Release();
- return retVal;
- }
- HX_RESULT Plugin2Handler::FindGroupOfPluginsUsingValues(IHXValues* pValues,
- REF(CPluginEnumerator*) pEnumerator)
- {
- CHXSimpleList::Iterator i = m_PluginList.Begin();
- pEnumerator = NULL;
- for(; i!= m_PluginList.End(); ++i)
- {
- Plugin2Handler::Plugin* pPlugin = (Plugin2Handler::Plugin*) *i;
- if (pPlugin->DoesMatch(pValues))
- {
- if (!pEnumerator)
- {
- pEnumerator = new CPluginEnumerator();
- }
- pEnumerator->Add(pPlugin);
- }
- }
- if (!pEnumerator)
- {
- return HXR_FAIL;
- }
- return HXR_OK;
- }
- STDMETHODIMP Plugin2Handler::GetNumPluginsSupporting(REFIID iid, REF(UINT32) nNumPlugins)
- {
- CHXString sGUID;
- CHXSimpleList* pSupportList;
- CHXuuid::HXUuidToString( (uuid_tt*) &iid, &sGUID);
- if (!m_GUIDtoSupportList.Lookup(sGUID, (void*&)pSupportList))
- {
- return HXR_FAIL;
- }
- nNumPlugins = pSupportList->GetCount();
- return HXR_OK;
- }
- STDMETHODIMP Plugin2Handler::GetPluginIndexSupportingIID(REFIID iid, UINT32 nPluginIndex, REF(UINT32) nIndexOut)
- {
- CHXString sGUID;
- CHXSimpleList* pSupportList;
- CHXuuid::HXUuidToString( (uuid_tt*) &iid, &sGUID);
- if (m_GUIDtoSupportList.Lookup(sGUID, (void*&)pSupportList))
- {
- if (nPluginIndex < (UINT32)pSupportList->GetCount())
- {
- LISTPOSITION pPos = pSupportList->FindIndex(nPluginIndex);
- PluginSupportingGUID* pSupportItem = (PluginSupportingGUID*) pSupportList->GetAt(pPos);
- if (FindPlugin(pSupportItem ->m_filename, pSupportItem->m_nIndexInDLL, nIndexOut))
- {
- return HXR_OK;
- }
- }
- }
- return HXR_FAIL;
- }
- STDMETHODIMP Plugin2Handler::AddSupportedIID(REFIID iid)
- {
- //1st scan to see if this GUID is already supported...
- CHXString sGUID;
- CHXSimpleList* pSupportList;
- CHXuuid::HXUuidToString( (uuid_tt*) &iid, &sGUID);
- if (m_GUIDtoSupportList.Lookup(sGUID, (void*&)pSupportList))
- {
- #ifdef _MACINTOSH
- // the preferences are getting messed up on the mac.
- // so here we have to validate that the list of plugins we are about to
- // send over is valid.
- void* pGarbage;
- if (!m_GUIDSupportListIsValid.Lookup(sGUID, pGarbage))
- {
- // to validate we will load all of the plugins within this list and
- // QI them.
- BOOL bListIsInvalid = FALSE;
- for(LISTPOSITION pPos = pSupportList->GetHeadPosition(); pPos!=NULL;)
- {
- BOOL IsValid = FALSE;
- UINT32 nTestPluginIndex;
- IUnknown* pTestUnk;
- PluginSupportingGUID* pSupportItemToTest = (PluginSupportingGUID*) pSupportList->GetAt(pPos);
- if (FindPlugin(pSupportItemToTest->m_filename, pSupportItemToTest->m_nIndexInDLL, nTestPluginIndex))
- {
- if (HXR_OK == GetInstance(nTestPluginIndex, pTestUnk))
- {
- IUnknown* pTempUnk;
- if (HXR_OK == pTestUnk->QueryInterface(iid, (void**)&pTempUnk))
- {
- // ohhh we are in trouble now. We HAVE to assume one of the two following
- // statements:
- // (1) All interfaces have derive from IUnknown.
- // (2) All of our interfaces support aggeration correctly.
- // I guess we'll have to assume (1) since I KNOW (2) is incorrect.
- HX_RELEASE(pTempUnk);
- IsValid = TRUE;
- }
- HX_RELEASE (pTestUnk);
- }
- }
- HX_ASSERT(IsValid);
- if (!IsValid)
- {
- // Should not be part of this list. Delete this node.
- pSupportList->RemoveAt(pPos);
- bListIsInvalid = TRUE;
- }
- else
- {
- pSupportList->GetNext(pPos);
- }
- }
- m_GUIDSupportListIsValid.SetAt(sGUID, NULL);
- // at this point we should rewrite the prefs file if bListIsInvalid
- // however, I do not believe that we have an interface for removing
- // enteries from the preferences. hmmmm...
- }
- #endif
- return HXR_FAIL; // hey! it is already in!
- }
- #ifndef _MACINTOSH
- if (!zm_bFasterPrefs)
- {
- // Write this out for each mount point
- for(CHXMapStringToOb::Iterator mp = m_MountPoints.Begin(); mp!=m_MountPoints.End(); ++mp)
- {
- PluginMountPoint* pMountPoint = (PluginMountPoint*) *mp;
- IHXPreferences* pIPrefs = pMountPoint->Prefs();
- if( pIPrefs )
- {
- PreferenceEnumerator* pPrefEnum = new PreferenceEnumerator( pIPrefs );
- HX_VERIFY( HXR_OK == pPrefEnum->BeginSubPref(PLUGIN_REGKEY_ROOT));
- HX_VERIFY( HXR_OK == pPrefEnum->BeginSubPref(PLUGIN_GUIDINFO));
- IHXBuffer* pIndexBuffer = new CHXBuffer();
- pIndexBuffer->AddRef();
- pIndexBuffer->Set((UCHAR*)"",1);
- pPrefEnum->WriteSubPref((const char*)sGUID, pIndexBuffer);
- pIndexBuffer->Release();
- pPrefEnum->EndSubPref(); // XXXAH these may not be necessary.
- pPrefEnum->EndSubPref(); // XXXAH these may not be necessary.
- delete pPrefEnum;
- HX_RELEASE( pIPrefs );
- }
- }
- }
- #endif
- // Now create the new structure.
- CHXSimpleList* pSimpleList = new CHXSimpleList();
- m_GUIDtoSupportList.SetAt(sGUID, pSimpleList);
- // now scan all of the Plugins to see if any of them support this interface,
- for(CHXSimpleList::Iterator i = m_PluginList.Begin(); i!=m_PluginList.End(); ++i)
- {
- IUnknown* pUnk;
- IUnknown* pQuery;
- Plugin2Handler::Plugin* pPlugin = (Plugin2Handler::Plugin*) *i;
- if (HXR_OK == pPlugin->GetPlugin(pUnk))
- {
- if(HXR_OK == pUnk->QueryInterface(iid, (void**)&pQuery))
- {
- PluginSupportingGUID* pSupportItem = new PluginSupportingGUID();
- IHXBuffer* pBuffer = pPlugin->GetFileName();
- pSupportItem->m_filename = (char*) pBuffer->GetBuffer();
- HX_RELEASE( pBuffer );
- pSupportItem->m_pMountPoint = pPlugin->GetDLL()->GetMountPoint();
- pSupportItem->m_nIndexInDLL = pPlugin->GetIndex();
- pSimpleList->AddTail((void*)pSupportItem);
- // now write this info the registry
- char IndexArray[16]; /* Flawfinder: ignore */
- sprintf(IndexArray, "%d", (int) pSupportItem->m_nIndexInDLL); /* Flawfinder: ignore */
- IHXBuffer* pIndexBuffer = new CHXBuffer();
- pIndexBuffer->AddRef();
- pIndexBuffer->Set((const UCHAR*)IndexArray, strlen(IndexArray)+1);
- if (!zm_bFasterPrefs)
- {
- IHXPreferences* pIPrefs = pPlugin->GetDLL()->GetMountPoint()->Prefs();
- if( pIPrefs )
- {
- PreferenceEnumerator* pPrefEnum = new PreferenceEnumerator( pIPrefs );
- HX_VERIFY(HXR_OK == pPrefEnum->BeginSubPref(PLUGIN_REGKEY_ROOT));
- HX_VERIFY(HXR_OK == pPrefEnum->BeginSubPref(PLUGIN_GUIDINFO));
- HX_VERIFY(HXR_OK == pPrefEnum->BeginSubPref((const char*)sGUID));
- pPrefEnum->WriteSubPref((const char*)pSupportItem->m_filename, pIndexBuffer);
- pPrefEnum->EndSubPref(); // XXXAH these may not be necessary.
- pPrefEnum->EndSubPref(); // XXXAH these may not be necessary.
- pPrefEnum->EndSubPref(); // XXXAH these may not be necessary.
- delete pPrefEnum;
- HX_RELEASE( pIPrefs );
- }
- }
- HX_RELEASE(pIndexBuffer);
- HX_RELEASE(pQuery);
- }
- HX_RELEASE(pUnk);
- }
- }
- WriteSupportedGUIDs();
- return HXR_OK;
- }
- /********************************************************************
- *
- * IHXPluginHandler3
- *
- ********************************************************************/
- STDMETHODIMP
- Plugin2Handler::RegisterContext( IUnknown* pContext )
- {
- if( !pContext )
- {
- return INVALID_CONTEXT;
- }
- if( m_pContext )
- {
- return HXR_UNEXPECTED;
- }
- m_pContext = pContext;
- m_pContext->AddRef();
- if ( FAILED( m_pContext->QueryInterface( IID_IHXScheduler, (void**) &m_pIScheduler ) ) )
- {
- return( INVALID_CONTEXT );
- }
- // Set up scheduler to ping us.
- m_hScheduler = m_pIScheduler->RelativeEnter( this, kPingDuration );
- if (HXR_OK != m_pContext->QueryInterface(IID_IHXPreferences, (void**) &m_pPreferences))
- {
- return INVALID_CONTEXT;
- }
- /* We don't check errors because it's ok not to have this available. */
- m_pContext->QueryInterface(IID_IHXErrorMessages, (void**) &m_pErrorMessages);
- #if defined(HELIX_FEATURE_PREFERENCES)
- #if !defined(HELIX_CONFIG_NOSTATICS)
- /* Check to see if we wish to use the 'faster' prefs.
- * This means using VERY long strings to store the
- * plugin information. Windows supports this but
- * discourages the practice.
- */
- IHXBuffer* pBuffer = NULL;
- if (m_pPreferences)
- {
- if (ReadPrefBOOL(m_pPreferences, "UseFasterPref", zm_bFasterPrefs) != HXR_OK)
- {
- #if !defined (_WINCE)
- zm_bFasterPrefs = TRUE;
- #else
- zm_bFasterPrefs = FALSE;
- #endif
- }
- }
- #endif /* #if !defined(HELIX_CONFIG_NOSTATICS) */
- #endif /* HELIX_FEATURE_PREFERENCES */
- return HXR_OK;
- }
- STDMETHODIMP
- Plugin2Handler::AddPluginMountPoint( const char* pName, UINT32 majorVersion, UINT32 minorVersion, IHXBuffer* pPath )
- {
- HX_LOG_BLOCK( "Plugin2Handler::AddPluginMountPoint" );
- const char* pMPKey = pName ? pName : (const char*) pPath->GetBuffer();
- // Make sure this mount point is in the list
- PluginMountPoint* pMountPoint = NULL;
- if( !m_MountPoints.Lookup( pMPKey, (void*&) pMountPoint ) )
- {
- // Create new mount point
- pMountPoint = new PluginMountPoint( this, pName, majorVersion, minorVersion, pPath );
- pMountPoint->AddRef();
- // Put new mount point in list
- m_MountPoints.SetAt( pMPKey, pMountPoint );
- }
- // Increment client count
- pMountPoint->AddClient();
- // Load information from registry, and sync DLLs that aren't up to date
- return RefreshPluginInfo( pMountPoint );
- }
- STDMETHODIMP
- Plugin2Handler::RefreshPluginMountPoint( const char* pName )
- {
- HX_RESULT result = HXR_FAIL;
- // If this mount point is in the list, refresh it
- PluginMountPoint* pMountPoint = NULL;
- if( m_MountPoints.Lookup( pName, (void*&) pMountPoint ) )
- {
- result = RefreshPluginInfo( pMountPoint );
- }
- return result;
- }
- STDMETHODIMP
- Plugin2Handler::RemovePluginMountPoint( const char* pName )
- {
- HX_RESULT result = HXR_FAIL;
- // Make sure this is a valid mount point
- PluginMountPoint* pMountPoint = NULL;
- if( m_MountPoints.Lookup( pName, (void*&) pMountPoint ) )
- {
- // If this was the last client, do the clean up stuff
- if( !pMountPoint->RemoveClient() )
- {
- // Clean up plugins
- if( m_PluginList.GetCount() )
- {
- LISTPOSITION listPos = m_PluginList.GetHeadPosition();
- while( listPos )
- {
- // Save off current position for delete
- LISTPOSITION posAt = listPos;
- // Get current item, and increment position
- Plugin2Handler::Plugin* pPlugin = (Plugin2Handler::Plugin*) m_PluginList.GetNext( listPos );
- // If this plugin belongs to the mountpoint, remove it.
- if( pPlugin && ( pPlugin->GetDLL()->GetMountPoint() == pMountPoint ) )
- {
- // Remove plugin from indices
- RemovePluginFromIndices( pPlugin );
- // Delete from the saved position
- m_PluginList.RemoveAt( posAt );
- HX_RELEASE( pPlugin );
- }
- }
- }
- // Clean up dlls
- if (m_PluginDLLList.GetCount())
- {
- LISTPOSITION listPos = m_PluginDLLList.GetHeadPosition();
- while( listPos )
- {
- // Save off current position for delete
- LISTPOSITION posAt = listPos;
- // Get current item, and increment position
- Plugin2Handler::PluginDLL* pPluginDLL = (Plugin2Handler::PluginDLL*) m_PluginDLLList.GetNext( listPos );
- // If this plugin belongs to the mountpoint, remove it.
- if( pPluginDLL && ( pPluginDLL->GetMountPoint() == pMountPoint ) )
- {
- // Remove from filename map
- IHXBuffer* pBuffer = pPluginDLL->GetFileName();
- m_FileNameMap.RemoveKey( (char*) pBuffer->GetBuffer() );
- HX_RELEASE( pBuffer );
- // Remove from the LRU
- RemoveFromLRU(pPluginDLL);
- // Delete from the saved position
- m_PluginDLLList.RemoveAt( posAt );
- HX_RELEASE( pPluginDLL );
- }
- }
- }
- // Clean up OtherDLL
- if (m_MiscDLLList.GetCount())
- {
- LISTPOSITION listPos = m_MiscDLLList.GetHeadPosition();
- while( listPos )
- {
- // Save off current position for delete
- LISTPOSITION posAt = listPos;
- // Get current item, and increment position
- Plugin2Handler::OtherDLL* pOtherDLL = (Plugin2Handler::OtherDLL*) m_MiscDLLList.GetNext( listPos );
- // If this plugin belongs to the mountpoint, remove it.
- if( pOtherDLL && ( pOtherDLL->m_pMountPoint == pMountPoint ) )
- {
- // Delete from the saved position
- m_MiscDLLList.RemoveAt( posAt );
- HX_DELETE( pOtherDLL );
- }
- }
- }
- // Clean up supported GUIDs
- if (m_GUIDtoSupportList.GetCount())
- {
- CHXMapStringToOb::Iterator k;
- for(k = m_GUIDtoSupportList.Begin(); k!=m_GUIDtoSupportList.End(); ++k)
- {
- CHXSimpleList* pSupportedList = (CHXSimpleList*) *k;
- LISTPOSITION listPos = pSupportedList->GetHeadPosition();
- while( listPos )
- {
- // Save off current position for delete
- LISTPOSITION posAt = listPos;
- // Get current item, and increment position
- PluginSupportingGUID* pSupportItem = (PluginSupportingGUID*) pSupportedList->GetNext( listPos );
- // If this plugin belongs to the mountpoint, remove it.
- if( pSupportItem && ( pSupportItem->m_pMountPoint == pMountPoint ) )
- {
- // Delete from the saved position
- pSupportedList->RemoveAt( posAt );
- HX_DELETE( pSupportItem );
- }
- }
- // XXXND Remove the list from m_GUIDtoSupportList if it's empty
- }
- }
- // Remove mount point from list
- m_MountPoints.RemoveKey( pName );
- if (pMountPoint)
- {
- pMountPoint->Release();
- pMountPoint = NULL;
- }
- }
- }
- return result;
- }
- STDMETHODIMP
- Plugin2Handler::FindImplementationFromClassID( REFGUID GUIDClassID, REF(IUnknown*) pIUnknownInstance,
- IUnknown* pIUnkOuter, IUnknown* pContext )
- {
- // Look though the Component plugins
- HX_RESULT result = HXR_FAIL;
- if( FAILED( result = CreatePluginViaIndex( PLUGIN_COMPONENT_CLSID, &GUIDClassID, &pIUnknownInstance, pIUnkOuter ) ) )
- {
- // XXXND FIX Try doing a manual lookup (FindPluginUsingValues)
- // Couldn't find it with the new method, try the old one.
- result = FindImplementationFromClassIDInternal( GUIDClassID, pIUnknownInstance, pContext );
- }
- return result;
- }
- STDMETHODIMP
- Plugin2Handler::FindCLSIDFromName( const char* pName, REF(IHXBuffer*) pCLSID )
- {
- HX_SETUP_CHECKPOINTLIST( "Plugin2Handler::FindCLSIDFromName()" );
- HX_PRIME_ACCUMULATOR( 'idfn', "Looking up CLSID from name" );
- HX_ACCUMULATE( 'idfc', "Number of CLSIDs looked up", 1 );
- // Initialize out params
- pCLSID = NULL;
- HX_RESULT result = HXR_FAIL;
- IHXValues* pIValues = NULL;
- if( SUCCEEDED( FindPluginInfoViaIndex( PLUGIN_COMPONENT_NAME, (char*) pName, &pIValues ) ) )
- {
- pIValues->GetPropertyBuffer( PLUGIN_COMPONENT_CLSID, pCLSID );
- HX_RELEASE( pIValues );
- result = HXR_OK;
- }
- else
- {
- // XXXND FIX Try using FindPluginUsingString
- }
- HX_UPDATE_ACCUMULATOR( 'idfn' );
- return result;
- }
- STDMETHODIMP
- Plugin2Handler::FindGroupOfPluginsUsingValues( IHXValues* pValues,
- REF(IHXPluginSearchEnumerator*) pIEnumerator)
- {
- // Initialize out params
- pIEnumerator = NULL;
- // Use the internal function to build up an enumerator object
- CPluginEnumerator* pEnumerator = NULL;
- HX_RESULT result = FindGroupOfPluginsUsingValues( pValues, pEnumerator );
- // If we have our enumerator, get the appropriate interface
- if( SUCCEEDED( result ) )
- {
- result = pEnumerator->QueryInterface( IID_IHXPluginSearchEnumerator,
- (void**) &pIEnumerator );
- }
- return result;
- }
- STDMETHODIMP
- Plugin2Handler::FindGroupOfPluginsUsingStrings( char* PropName1, char* PropVal1,
- char* PropName2, char* PropVal2,
- char* PropName3, char* PropVal3,
- REF(IHXPluginSearchEnumerator*) pIEnumerator)
- {
- // Initialize out params
- pIEnumerator = NULL;
- // Use the internal function to build up an enumerator object
- CPluginEnumerator* pEnumerator = NULL;
- HX_RESULT result = FindGroupOfPluginsUsingStrings( PropName1, PropVal1,
- PropName2, PropVal2, PropName3, PropVal3, pEnumerator );
- // If we have our enumerator, get the appropriate interface
- if( SUCCEEDED( result ) )
- {
- result = pEnumerator->QueryInterface( IID_IHXPluginSearchEnumerator,
- (void**) &pIEnumerator );
- }
- return result;
- }
- void Plugin2Handler::ReportError( UINT8 severity, const char* pDLLName, const char* pDesc )
- {
- if (m_pErrorMessages)
- {
- int nErrorTempLength;
- char *pErrorTemp;
- nErrorTempLength = strlen(pDLLName) + strlen(pDesc) + 2;
- pErrorTemp = new char[nErrorTempLength];
- if(pErrorTemp)
- {
- SafeSprintf(pErrorTemp, nErrorTempLength, "%s %s", pDLLName, pDesc );
- m_pErrorMessages->Report( severity, 0, 0, pErrorTemp, NULL );
- delete [] pErrorTemp;
- }
- else
- {
- m_pErrorMessages->Report( HXLOG_ERR, HXR_OUTOFMEMORY, 0, NULL, NULL );
- }
- }
- }
- STDMETHODIMP
- Plugin2Handler::FindPluginUsingValues( IHXValues* pCriteria,
- REF(IUnknown*) pIUnkResult,
- IUnknown* pIUnkOuter )
- {
- HX_SETUP_CHECKPOINTLIST( "Plugin2Handler::FindPluginUsingValues()" );
- HX_PRIME_ACCUMULATOR( 'fpuv', "Plugin lookup with IHXValues" );
- // Initialize out params
- pIUnkResult = NULL;
- CHXSimpleList PossibleValues;
- IHXValues* pPluginValues = NULL;
- IHXBuffer* pBuffer = NULL;
- CHXSimpleList::Iterator i = m_PluginList.Begin();
- for(; i!= m_PluginList.End(); ++i)
- {
- Plugin2Handler::Plugin* pPlugin = (Plugin2Handler::Plugin*) *i;
- if (pPlugin->DoesMatch(pCriteria))
- {
- PossibleValues.AddTail(pPlugin);
- }
- }
- HX_UPDATE_ACCUMULATOR( 'fpuv' );
- if (PossibleValues.Begin() == PossibleValues.End())
- {
- pIUnkResult = 0;
- return HXR_FAIL;
- }
- /****************************************************************
- ** Presently when we arrive at this spot with more than one
- ** plugin which matches the search criteria, we simply take
- ** the first one found. If this is not satisfactory then
- ** some method can be added which will process the list based
- ** upon some criteria.
- ****************************************************************/
- // if there are multiple plugins found, we will pick the one whose
- // plugin description contains "RealNetworks"
- if (PossibleValues.GetCount() > 1)
- {
- for(i = PossibleValues.Begin(); i!= PossibleValues.End(); ++i)
- {
- Plugin2Handler::Plugin* pPlugin = (Plugin2Handler::Plugin*) *i;
- if (HXR_OK == pPlugin->GetPluginInfo(pPluginValues) && pPluginValues)
- {
- if (HXR_OK == pPluginValues->GetPropertyCString(PLUGIN_DESCRIPTION2, pBuffer) &&
- pBuffer)
- {
- if (strstr((const char*)pBuffer->GetBuffer(), "RealNetworks"))
- {
- HX_RELEASE(pBuffer);
- if ( NO_ERRORS == pPlugin->GetInstance( pIUnkResult, pIUnkOuter ))
- {
- return HXR_OK;
- }
- else
- {
- return HXR_FAIL;
- }
- }
- }
- HX_RELEASE(pBuffer);
- }
- }
- }
- Plugin2Handler::Plugin* pPlug = (Plugin2Handler::Plugin*) *(PossibleValues.Begin());
- Errors retVal = pPlug->GetInstance( pIUnkResult, pIUnkOuter );
- return ( retVal == NO_ERRORS ) ? HXR_OK : HXR_FAIL;
- }
- STDMETHODIMP
- Plugin2Handler::FindPluginUsingStrings( char* PropName1, char* PropVal1,
- char* PropName2, char* PropVal2,
- char* PropName3, char* PropVal3,
- REF(IUnknown*) pIUnkResult,
- IUnknown* pIUnkOuter )
- {
- // Initialize out params
- pIUnkResult = NULL;
- // PropName and PropVal have to to valid tuple
- if ((PropName1 && !PropVal1) ||
- (PropName2 && !PropVal2) ||
- (PropName3 && !PropVal3) ||
- (!PropName1 && PropVal1) ||
- (!PropName2 && PropVal2) ||
- (!PropName3 && PropVal3))
- return HXR_FAIL;
- IHXValues* pValues;
- HX_RESULT retVal = HXR_FAIL;
- CHXHeader* pHeader = new CHXHeader();
- pHeader->QueryInterface(IID_IHXValues, (void**)&pValues);
- AddToValues(pValues, PropName1, PropVal1, eString);
- AddToValues(pValues, PropName2, PropVal2, eString);
- AddToValues(pValues, PropName3, PropVal3, eString);
- retVal = FindPluginUsingValues( pValues, pIUnkResult, pIUnkOuter );
- pValues->Release();
- return retVal;
- }
- STDMETHODIMP
- Plugin2Handler::GetPlugin( ULONG32 ulIndex, REF(IUnknown*) pIUnkResult,
- IUnknown* pIUnkOuter )
- {
- if( ulIndex <= (ULONG32)(m_PluginList.GetCount()-1) && m_PluginList.GetCount() )
- {
- LISTPOSITION pPos = m_PluginList.FindIndex( ulIndex );
- if (pPos)
- {
- Plugin2Handler::Plugin* pPlugin = (Plugin2Handler::Plugin*) m_PluginList.GetAt( pPos );
- if( pPlugin )
- {
- if (NO_ERRORS == pPlugin->GetInstance( pIUnkResult, pIUnkOuter ))
- {
- return HXR_OK;
- }
- else
- {
- return HXR_FAIL;
- }
- }
- }
- }
- return HXR_FAIL;
- }
- //------------------------------------ IHXPluginDatabase interface methods
- STDMETHODIMP
- Plugin2Handler::AddPluginIndex( THIS_ const char* pKeyName, EPluginIndexType indexType, BOOL bScanExisting )
- {
- HX_LOG_BLOCK( "Plugin2Handler::AddPluginIndex" );
- HX_RESULT result = HXR_FAIL;
- CPluginDatabaseIndex* pNewIndex = CPluginDatabaseIndex::CreateIndex( indexType );
- if( pNewIndex )
- {
- m_dbIndices.SetAt( pKeyName, pNewIndex );
- if( bScanExisting )
- {
- // XXXND FIX Scan the existing plugins and add them to this index
- }
- result = HXR_OK;
- }
- return result;
- }
- STDMETHODIMP
- Plugin2Handler::RemovePluginIndex( THIS_ const char* pKeyName )
- {
- HX_RESULT result = HXR_UNEXPECTED;
- CPluginDatabaseIndex* pIndex = FindDBIndex( pKeyName );
- if( pIndex )
- {
- if( !m_dbIndices.RemoveKey( pKeyName ) )
- {
- result = HXR_FAIL;
- }
- else
- {
- HX_DELETE( pIndex );
- result = HXR_OK;
- }
- }
- return result;
- }
- STDMETHODIMP
- Plugin2Handler::FindPluginInfoViaIndex( THIS_ const char* pKeyName, const void* pValue, IHXValues** ppIInfo )
- {
- HX_RESULT result = HXR_INVALID_PARAMETER;
- if( ppIInfo )
- {
- result = HXR_FAIL;
- *ppIInfo = NULL;
- CPluginDatabaseIndex* pIndex = FindDBIndex( pKeyName );
- if( pIndex )
- {
- IUnknown* pIUnk = NULL;
- if( SUCCEEDED( pIndex->FindItem( pValue, &pIUnk ) ) )
- {
- Plugin2Handler::Plugin* pPlugin = (Plugin2Handler::Plugin*) pIUnk;
- if( SUCCEEDED( result = pPlugin->GetPluginInfo( *ppIInfo ) ) )
- {
- // Since GetPluginInfo() doesn't addref, we have to here.
- (*ppIInfo)->AddRef();
- }
- HX_RELEASE( pIUnk );
- }
- }
- }
- return result;
- }
- STDMETHODIMP
- Plugin2Handler::FindPluginSetViaIndex( THIS_ const char* pKeyName, const void* pValue, IHXPluginSearchEnumerator** ppIEnumerator )
- {
- // XXXND Implement this
- *ppIEnumerator = NULL;
- return HXR_NOTIMPL;
- }
- STDMETHODIMP
- Plugin2Handler::CreatePluginViaIndex( THIS_ const char* pKeyName, const void* pValue, IUnknown** ppIUnkPlugin, IUnknown* pIUnkOuter )
- {
- HX_RESULT result = HXR_INVALID_PARAMETER;
- if( ppIUnkPlugin )
- {
- result = HXR_FAIL;
- *ppIUnkPlugin = NULL;
- CPluginDatabaseIndex* pIndex = FindDBIndex( pKeyName );
- if( pIndex )
- {
- IUnknown* pIUnk = NULL;
- if( SUCCEEDED( pIndex->FindItem( pValue, &pIUnk ) ) )
- {
- Plugin2Handler::Plugin* pPlugin = (Plugin2Handler::Plugin*) pIUnk;
- if( NO_ERRORS == pPlugin->GetInstance( *ppIUnkPlugin, pIUnkOuter ) )
- {
- result = HXR_OK;
- }
- HX_RELEASE( pIUnk );
- }
- }
- }
- return result;
- }
- STDMETHODIMP
- Plugin2Handler::UnloadPluginFromClassID(REFGUID GUIDClassID)
- {
- HX_RESULT res = HXR_FAIL;
- CPluginDatabaseIndex* pIndex = FindDBIndex( PLUGIN_COMPONENT_CLSID );
- if( pIndex )
- {
- IUnknown* pIUnk = NULL;
- if( SUCCEEDED( pIndex->FindItem( &GUIDClassID, &pIUnk ) ) )
- {
- Plugin2Handler::Plugin* pPlugin = (Plugin2Handler::Plugin*) pIUnk;
- if(pPlugin->GetDLL())
- {
- res = pPlugin->GetDLL()->Unload();
- }
- HX_RELEASE( pIUnk );
- }
- }
- return res;
- }
- STDMETHODIMP
- Plugin2Handler::UnloadPackageByName(const char* pName)
- {
- if (!pName)
- return HXR_INVALID_PARAMETER;
- for (CHXSimpleList::Iterator i = m_PluginDLLList.Begin(); i != m_PluginDLLList.End(); ++i)
- {
- PluginDLL* pPluginDLL = (PluginDLL*) *i;
- if (pPluginDLL->GetPackageName() == pName)
- {
- return pPluginDLL->Unload(FALSE);
- }
- }
- return HXR_FAIL;
- }
- //------------------------------------ Class Methods
- HX_RESULT Plugin2Handler::FindImplementationFromClassIDInternal(
- REFGUID GUIDClassID,
- REF(IUnknown*) pIUnknownInstance,
- IUnknown* pContext )
- {
- // Initialize out params
- pIUnknownInstance = NULL;
- HX_RESULT HX_RESULTThis = HXR_OK;
- UINT32 ulNumClassFactories = 0;
- UINT32 ulCurrentClassFactory = 0;
- UINT32 ulCurrentClassFactoryIndex = 0;
- IUnknown* pIUnknownClassFactoryCurrent = NULL;
- IHXCommonClassFactory* pIHXCommonClassFactoryCurrent = NULL;
- IHXPlugin* pIHXPluginCurrent = NULL;
- IHXObjectConfiguration* pIHXObjectConfigurationCurrent = NULL;
- AddSupportedIID(IID_IHXCommonClassFactory);
- HX_RESULTThis = GetNumPluginsSupporting( IID_IHXCommonClassFactory, ulNumClassFactories );
- if( SUCCEEDED(HX_RESULTThis) && ulNumClassFactories > 0 )
- {
- for( ulCurrentClassFactory = 0, ulCurrentClassFactoryIndex = 0;
- ulCurrentClassFactoryIndex < ulNumClassFactories; ++ulCurrentClassFactoryIndex )
- {
- HX_RESULTThis = GetPluginIndexSupportingIID( IID_IHXCommonClassFactory,
- ulCurrentClassFactoryIndex,
- ulCurrentClassFactory );
- // Create an instance of the plugin at the index ulCurrentClassFactory
- if( SUCCEEDED(HX_RESULTThis) )
- {
- HX_RESULTThis = GetInstance( ulCurrentClassFactory, pIUnknownClassFactoryCurrent );
- }
- // If we got a plugin, see if we can get the correct object from it.
- if( SUCCEEDED(HX_RESULTThis) && pIUnknownClassFactoryCurrent )
- {
- // Initialize the plugin either through IHXPlugin or IHXObjectConfiguration
- if( SUCCEEDED( pIUnknownClassFactoryCurrent->QueryInterface( IID_IHXPlugin,
- (void**)&pIHXPluginCurrent ) )
- && pIHXPluginCurrent )
- {
- pIHXPluginCurrent->InitPlugin( pContext );
- }
- HX_RELEASE(pIHXPluginCurrent);
- if( SUCCEEDED( pIUnknownClassFactoryCurrent->QueryInterface( IID_IHXObjectConfiguration,
- (void**)&pIHXObjectConfigurationCurrent ) )
- && pIHXObjectConfigurationCurrent )
- {
- pIHXObjectConfigurationCurrent->SetContext( pContext );
- }
- HX_RELEASE(pIHXObjectConfigurationCurrent);
- // Now that it's initialized, get the IHXCommonClassFactory interface
- HX_RESULTThis = pIUnknownClassFactoryCurrent->QueryInterface( IID_IHXCommonClassFactory,
- (void**)&pIHXCommonClassFactoryCurrent );
- }
- HX_RELEASE(pIUnknownClassFactoryCurrent);
- // We have IHXCommonClassFactory on an intialized plugin.
- // See if it can create the object we want
- if( SUCCEEDED(HX_RESULTThis) && pIHXCommonClassFactoryCurrent )
- {
- HX_RESULTThis = pIHXCommonClassFactoryCurrent->CreateInstance( GUIDClassID, (void **)&pIUnknownInstance );
- }
- HX_RELEASE(pIHXCommonClassFactoryCurrent);
- // Check to see if CreateInstance succeeded. If so, this is the plugin we want
- if( SUCCEEDED(HX_RESULTThis) && pIUnknownInstance )
- {
- // got It!
- break;
- }
- // If CreateInstance allocated something, but returned a failure code, clean up
- HX_RELEASE(pIUnknownInstance);
- }
- }
- else
- {
- // there are no Class factories.
- HX_RESULTThis = HXR_FAIL;
- }
- return HX_RESULTThis;
- }
- HX_RESULT Plugin2Handler::RefreshPluginInfo( PluginMountPoint* pMountPoint )
- {
- HX_LOG_BLOCK( "Plugin2Handler::RefreshPluginInfo" );
- HX_RESULT result = HXR_FAIL;
- IHXPreferences* pIPrefs = pMountPoint->Prefs();
- if( pIPrefs )
- {
- if( zm_bFasterPrefs )
- {
- result = ReadPluginInfoFast( pMountPoint );
- }
- else
- {
- result = ReadPluginInfoSlow( pMountPoint );
- }
- }
- if (FAILED (result))
- {
- result = ClearMountPoint_ (pMountPoint);
- }
- if( !pIPrefs || SUCCEEDED( result ) )
- result = ReloadPluginsNoPropagate( pMountPoint );
- HX_RELEASE( pIPrefs );
- return result;
- }
- HX_RESULT Plugin2Handler::ClearMountPoint_ (PluginMountPoint* pMountPoint)
- {
- HX_LOG_BLOCK( "Plugin2Handler::ClearMountPoint_" );
- IHXPreferences* pIPrefs = pMountPoint->Prefs();
- REQUIRE_RETURN_QUIET (pIPrefs, HXR_FAIL);
- IHXPreferences3* pIPrefs3 = NULL;
- if (FAILED (pIPrefs->QueryInterface(IID_IHXPreferences3, (void**)&pIPrefs3)))
- {
- HX_RELEASE (pIPrefs);
- return HXR_FAIL;
- }
- char szRegKey[255]; /* Flawfinder: ignore */
- // delete file info
- SafeStrCpy(szRegKey, PLUGIN_REGKEY_ROOT, 255);
- SafeStrCat(szRegKey, zm_pszRegKeySeperator, 255);
- SafeStrCat(szRegKey, PLUGIN_FILENAMES, 255);
- DeleteHugePref_ (pIPrefs, pIPrefs3, szRegKey);
- // delete plugin info
- SafeStrCpy(szRegKey, PLUGIN_REGKEY_ROOT, 255);
- SafeStrCat(szRegKey, zm_pszRegKeySeperator, 255);
- SafeStrCat(szRegKey, PLUGIN_PLUGININFO, 255);
- DeleteHugePref_ (pIPrefs, pIPrefs3, szRegKey);
- // delete guid info
- SafeStrCpy(szRegKey, PLUGIN_REGKEY_ROOT, 255);
- SafeStrCat(szRegKey, zm_pszRegKeySeperator, 255);
- SafeStrCat(szRegKey, PLUGIN_GUIDINFO, 255);
- DeleteHugePref_ (pIPrefs, pIPrefs3, szRegKey);
- // delete non RMA plugin info
- SafeStrCpy(szRegKey, PLUGIN_REGKEY_ROOT, 255);
- SafeStrCat(szRegKey, zm_pszRegKeySeperator, 255);
- SafeStrCat(szRegKey, PLUGIN_NONHXINFO, 255);
- DeleteHugePref_ (pIPrefs, pIPrefs3, szRegKey);
- HX_RELEASE (pIPrefs);
- HX_RELEASE (pIPrefs3);
- return HXR_OK;
- }
- void Plugin2Handler::DeleteHugePref_ (IHXPreferences* pIPrefs, IHXPreferences3* pIPrefs3, const char* pszKeyName)
- {
- HX_LOG_BLOCK( "Plugin2Handler::DeleteHugePref_" );
- char szNewKeyName [1024]; /* Flawfinder: ignore */
- char szNumber [16]; /* Flawfinder: ignore */
- IHXBuffer* pIBuffer = NULL;
- for (int i = 0; ; ++i)
- {
- SafeStrCpy(szNewKeyName, pszKeyName, 1024);
- sprintf (szNumber, "%d", i); /* Flawfinder: ignore */
- SafeStrCat(szNewKeyName, szNumber, 1024);
- // unfortunately delete pref doesn't give us the return value we want so we will read the prefs for now to
- // determine if they are there.
- if (FAILED (pIPrefs->ReadPref (szNewKeyName, pIBuffer))) break;
- LogRegistryRegeneration_ (szNewKeyName, pIBuffer);
- HX_RELEASE (pIBuffer);
- pIPrefs3->DeletePref (szNewKeyName);
- }
- }
- HX_RESULT Plugin2Handler::WritePluginInfo( PluginMountPoint* pMountPoint )
- {
- HX_LOG_BLOCK( "Plugin2Handler::WritePluginInfo" );
- HX_RESULT result = HXR_FAIL;
- IHXPreferences* pIPrefs = pMountPoint->Prefs();
- if( pIPrefs )
- {
- if( zm_bFasterPrefs )
- {
- result = WritePluginInfoFast( pMountPoint );
- }
- else
- {
- result = WritePluginInfoSlow( pMountPoint );
- }
- }
- HX_RELEASE( pIPrefs );
- return result;
- }
- HX_RESULT Plugin2Handler::ReadPluginInfoFast( PluginMountPoint* pMountPoint )
- {
- HX_LOG_BLOCK( "Plugin2Handler::ReadPluginInfoFast" );
- /*
- * Code to read from the preferences in one big chunk since
- * it seems that using many readable preferences is not efficient
- * on either windows or on macintosh.
- */
- IHXPreferences* pIPrefs = pMountPoint->Prefs();
- if( !pIPrefs )
- {
- // If there are no prefs, there's nothing to read
- return HXR_OK;
- }
- IHXBuffer* pIPathBuffer = pMountPoint->Path();
- if( !pIPathBuffer )
- {
- HX_RELEASE( pIPrefs );
- return HXR_FAIL;
- }
- char szRegKey[255]; /* Flawfinder: ignore */
- SafeStrCpy(szRegKey, PLUGIN_REGKEY_ROOT, 255);
- SafeStrCat(szRegKey, zm_pszRegKeySeperator, 255);
- SafeStrCat(szRegKey, PLUGIN_FILENAMES, 255);
- /*
- * Get the DLL info.
- */
- HX_LOG_CHECKPOINT( "Get DLL info" );
- IHXBuffer* pInfo = NULL;
- if (HXR_OK == ReadHugePref( pIPrefs, szRegKey, pInfo))
- {
- // the string is defined as follows:
- // {name, checksum, BOOL has factory, size, INT numplugins}{ditto}checksum
- char* pszName = NULL;
- char* pszCheckSum = NULL;
- BOOL bFactory = FALSE;
- int nDLLSize = 0, nNumberPlugins = 0;
- char* pszCurrentPos = (char*) pInfo->GetBuffer();
- if (FAILED (VerifyChecksum_ (pszCurrentPos)))
- {
- HX_RELEASE(pIPathBuffer);
- HX_RELEASE(pIPrefs);
- HX_RELEASE(pInfo);
- #ifdef _WINDOWS
- HX_ASSERT (!"Plugin handler data is corrupt. Regenerating data.");
- #endif
- return HXR_FAIL;
- }
- while( GetPluginFileInfo( pszCurrentPos, pszName, pszCheckSum, bFactory, nDLLSize, nNumberPlugins ) )
- {
- // validate the plugin by comparing the hash of the
- // stats info to the one stored in memory.
- IHXBuffer* pNewChecksum;
- pNewChecksum = ChecksumFile(pszName, pIPathBuffer);
- if( pNewChecksum && (!strcasecmp((const char*)pNewChecksum->GetBuffer(), pszCheckSum)))
- {
- Plugin2Handler::PluginDLL* pDLL = new Plugin2Handler::PluginDLL( pszName, pMountPoint, this );
- pDLL->AddRef();
- // ReconnectDLL() replaces one PluginDLL object with another PluginDLL; however,
- // both of these PluginDLL objects refer to the same DLL. This ensures that
- // only one PluginDLL object per DLL is in the m_PluginDLLList.
- ReconnectDLL( pszName, pDLL );
- pDLL->SetPref( nNumberPlugins, pszCheckSum, nDLLSize, bFactory );
- }
- HX_RELEASE(pNewChecksum);
- }
- HX_RELEASE(pInfo);
- }
- /*
- * Get the Plugin info.
- */
- SafeStrCpy(szRegKey, PLUGIN_REGKEY_ROOT, 255);
- SafeStrCat(szRegKey, zm_pszRegKeySeperator, 255);
- SafeStrCat(szRegKey, PLUGIN_PLUGININFO, 255);
- if (HXR_OK == ReadHugePref( pIPrefs, szRegKey, pInfo))
- {
- char* pszCurrentPos = (char*) pInfo->GetBuffer();
- if (FAILED (VerifyChecksum_ (pszCurrentPos)))
- {
- HX_RELEASE(pIPathBuffer);
- HX_RELEASE(pIPrefs);
- HX_RELEASE(pInfo);
- #ifdef _WINDOWS
- HX_ASSERT (!"Plugin handler data is corrupt. Regenerating data.");
- #endif
- return HXR_FAIL;
- }
- Plugin2Handler::Plugin* pPlugin = NULL;
- while( GetPluginFileInfo( pszCurrentPos, pPlugin ) )
- {
- // XXXND This really ought to search for duplicates
- if( HXR_OK != ConnectPluginToDLL( pPlugin ) )
- {
- // Must delete from list...
- HX_RELEASE(pPlugin);
- }
- else
- {
- AddPluginToIndices( pPlugin );
- m_PluginList.AddTail(pPlugin);
- }
- }
- HX_RELEASE(pInfo);
- }
- /*
- * Get GUID info for the Plugin Enumerator.
- */
- HX_LOG_CHECKPOINT( "Get GUID" );
- SafeStrCpy(szRegKey, PLUGIN_REGKEY_ROOT, 255);
- SafeStrCat(szRegKey, zm_pszRegKeySeperator, 255);
- SafeStrCat(szRegKey, PLUGIN_GUIDINFO, 255);
- if (HXR_OK == ReadHugePref( pIPrefs, szRegKey, pInfo))
- {
- char* pszCurrentPos = (char*) pInfo->GetBuffer();
- if (FAILED (VerifyChecksum_ (pszCurrentPos)))
- {
- HX_RELEASE(pIPathBuffer);
- HX_RELEASE(pIPrefs);
- HX_RELEASE(pInfo);
- #ifdef _WINDOWS
- HX_ASSERT (!"Plugin handler data is corrupt. Regenerating data.");
- #endif
- return HXR_FAIL;
- }
- CHXSimpleList* pList = NULL;
- char* pszGUID = NULL;
- while(GetGUIDInfo(pszCurrentPos, pMountPoint, pszGUID, pList))
- {
- m_GUIDtoSupportList.SetAt(pszGUID, (void*)pList);
- }
- HX_RELEASE(pInfo);
- }
- /*
- * Get non RMA DLL info
- */
- HX_LOG_CHECKPOINT( "Get non RMA DLL info" );
- SafeStrCpy(szRegKey, PLUGIN_REGKEY_ROOT, 255);
- SafeStrCat(szRegKey, zm_pszRegKeySeperator, 255);
- SafeStrCat(szRegKey, PLUGIN_NONHXINFO, 255);
- if (HXR_OK == ReadHugePref( pIPrefs, szRegKey, pInfo))
- {
- char* pszCurrentPos = (char*) pInfo->GetBuffer();
- if (FAILED (VerifyChecksum_ (pszCurrentPos)))
- {
- HX_RELEASE(pIPathBuffer);
- HX_RELEASE(pIPrefs);
- HX_RELEASE(pInfo);
- #ifdef _WINDOWS
- HX_ASSERT (!"Plugin handler data is corrupt. Regenerating data.");
- #endif
- return HXR_FAIL;
- }
- Plugin2Handler::OtherDLL* pOtherData = NULL;
- while(GetNonHXInfo(pszCurrentPos, pMountPoint, pOtherData))
- {
- m_MiscDLLList.AddTail((void*)pOtherData);
- }
- HX_RELEASE(pInfo);
- }
- HX_RELEASE(pIPathBuffer);
- HX_RELEASE(pIPrefs);
- return HXR_OK;
- }
- HX_RESULT Plugin2Handler::WritePluginInfoFast( PluginMountPoint* pMountPoint )
- {
- HX_LOG_BLOCK( "Plugin2Handler::WritePluginInfoFast" );
- IHXPreferences* pIPrefs = pMountPoint->Prefs();
- if( !pIPrefs )
- {
- return HXR_OK;
- }
- char szRegKey[255]; /* Flawfinder: ignore */
- CHXSimpleList::Iterator i;
- // Create buffer to use by CPluginInfoWriter...
- IHXBuffer* pIHXBuffer = NULL;
- CHXBuffer* pBuffer = new CHXBuffer();
- if(pBuffer)
- {
- if(SUCCEEDED(pBuffer->QueryInterface(IID_IHXBuffer, (void**)&pIHXBuffer)))
- {
- pIHXBuffer->SetSize(PREF_CACHE_SIZE);
- }
- }
- /*
- * Now write the PluginDLL info to the reg.
- */
- if (m_PluginDLLList.GetCount())
- {
- SafeStrCpy(szRegKey, PLUGIN_REGKEY_ROOT, 255);
- SafeStrCat(szRegKey, zm_pszRegKeySeperator, 255);
- SafeStrCat(szRegKey, PLUGIN_FILENAMES, 255);
- CPluginInfoWriter piw;
- piw.Init(pIPrefs, szRegKey, pIHXBuffer);
- i = m_PluginDLLList.Begin();
- for(; i!=m_PluginDLLList.End(); ++i)
- {
- Plugin2Handler::PluginDLL* pPlugDLL = (Plugin2Handler::PluginDLL*) *i;
- if( pPlugDLL->GetMountPoint() == pMountPoint )
- {
- pPlugDLL->WritePref2(piw);
- }
- }
- }
- /*
- * Now write the Plugin info to the reg.
- */
- if (m_PluginList.GetCount())
- {
- SafeStrCpy(szRegKey, PLUGIN_REGKEY_ROOT, 255);
- SafeStrCat(szRegKey, zm_pszRegKeySeperator, 255);
- SafeStrCat(szRegKey, PLUGIN_PLUGININFO, 255);
- CPluginInfoWriter piw;
- piw.Init(pIPrefs, szRegKey, pIHXBuffer);
- i = m_PluginList.Begin();
- for(; i!=m_PluginList.End(); ++i)
- {
- Plugin2Handler::Plugin* pPlug = (Plugin2Handler::Plugin*) *i;
- if( pPlug->GetDLL()->GetMountPoint() == pMountPoint )
- {
- pPlug->WritePref2(piw);
- }
- }
- }
- /*
- * Now write the non-RMA DLL info to the reg.
- */
- if (m_MiscDLLList.GetCount())
- {
- SafeStrCpy(szRegKey, PLUGIN_REGKEY_ROOT, 255);
- SafeStrCat(szRegKey, zm_pszRegKeySeperator, 255);
- SafeStrCat(szRegKey, PLUGIN_NONHXINFO, 255);
- CPluginInfoWriter piw;
- piw.Init(pIPrefs, szRegKey, pIHXBuffer);
- for(i = m_MiscDLLList.Begin();i!=m_MiscDLLList.End(); ++i/*, counter++*/)
- {
- Plugin2Handler::OtherDLL* pOtherData = (Plugin2Handler::OtherDLL*) *i;
- if( pOtherData->m_pMountPoint == pMountPoint )
- {
- // format of the non-rma DLL information is:
- // {filename, checksum}
- piw.Write("{");
- piw.Write((const char*)pOtherData->m_filename);
- piw.Write(",");
- piw.Write((const char*)pOtherData->m_fileChecksum);
- piw.Write("}");
- }
- }
- }
- /*
- * Now write the GUID info to the reg.
- */
- // format of GUID info:
- // {GUID, filename, index, filename, index, etc}{GUID, filename, index, filename, index}
- if (m_GUIDtoSupportList.GetCount())
- {
- SafeStrCpy(szRegKey, PLUGIN_REGKEY_ROOT, 255);
- SafeStrCat(szRegKey, zm_pszRegKeySeperator, 255);
- SafeStrCat(szRegKey, PLUGIN_GUIDINFO, 255);
- CHXMapStringToOb::Iterator k;
- // Dump the data.
- CPluginInfoWriter piw;
- piw.Init(pIPrefs, szRegKey, pIHXBuffer);
- for(k = m_GUIDtoSupportList.Begin(); k!=m_GUIDtoSupportList.End(); ++k)
- {
- BOOL foundFirst = FALSE;
- CHXSimpleList* pSupportedList = (CHXSimpleList*) *k;
- for (i=pSupportedList->Begin(); i!=pSupportedList->End();++i)
- {
- PluginSupportingGUID* pSupportItem = (PluginSupportingGUID*) *i;
- if( pSupportItem->m_pMountPoint == pMountPoint )
- {
- // If we found an item, write out the header
- if( !foundFirst )
- {
- foundFirst = TRUE;
- piw.Write("{");
- piw.Write(k.get_key());
- }
- char szScratch[20]; /* Flawfinder: ignore */
- itoa(pSupportItem->m_nIndexInDLL, szScratch, 10);
- piw.Write(",");
- piw.Write((const char*) pSupportItem->m_filename);
- piw.Write(",");
- piw.Write(szScratch);
- }
- }
- // If we wrote out a header, write out a tail
- if( foundFirst )
- {
- piw.Write("}");
- }
- }
- }
- HX_RELEASE( pIPrefs );
- HX_RELEASE( pIHXBuffer );
- return HXR_OK;
- }
- HX_RESULT Plugin2Handler::ReadPluginInfoSlow( PluginMountPoint* pMountPoint )
- {
- HX_LOG_BLOCK( "Plugin2Handler::ReadPluginInfoSlow" );
- IHXBuffer* pBuffer = NULL;
- // using IHXPreferences2 we will load all data from the registery
- // we must load all of the information from the registry here.
- UINT32 nIndex = 0;
- IHXBuffer* pPropName = 0;
- IHXPreferences* pIPrefs = pMountPoint->Prefs();
- {
- if( !pIPrefs )
- {
- return HXR_OK;
- }
- }
- IHXBuffer* pPathBuffer = pMountPoint->Path();
- PreferenceEnumerator* pPrefEnum = new PreferenceEnumerator( pIPrefs );
- // Read the values for the pluginDLLs.
- HX_VERIFY(HXR_OK == pPrefEnum->BeginSubPref(PLUGIN_REGKEY_ROOT));
- HX_VERIFY(HXR_OK == pPrefEnum->BeginSubPref(PLUGIN_FILENAMES));
- while (HXR_OK == pPrefEnum->GetPrefKey(nIndex++, pPropName))
- {
- if (!strcmp((char*)pPropName->GetBuffer(), zm_pszKeyNameRegKey))
- {
- HX_RELEASE(pPropName);
- continue;
- }
- Plugin2Handler::PluginDLL* pDLL = new Plugin2Handler::PluginDLL(
- (const char*)pPropName->GetBuffer(),
- pMountPoint, this);
- pDLL->AddRef();
- HX_VERIFY(HXR_OK == pPrefEnum->BeginSubPref((const char*)pPropName->GetBuffer()));
- pDLL->ReadPref(pPrefEnum);
- pPrefEnum->EndSubPref();
- // Does this file exist on the HD?
- BOOL bIsOK = TRUE;
- CFindFile* pFileFinder = NULL;
- pFileFinder = CFindFile::CreateFindFile((const char*)pPathBuffer->GetBuffer(), 0,
- (const char*)pPropName->GetBuffer());
- if (!pFileFinder->FindFirst())
- {
- HX_RELEASE(pPropName);
- delete pFileFinder;
- delete pDLL;
- continue;
- }
- delete pFileFinder;
- HX_RELEASE(pBuffer);
- // is the hash the same?
- pBuffer = pDLL->GetFileName();
- IHXBuffer* pNewChecksum = ChecksumFile((char*)pBuffer->GetBuffer(), pPathBuffer);
- if (pNewChecksum)
- {
- bIsOK = bIsOK && (!strcasecmp((const char*)pNewChecksum->GetBuffer(), pDLL->GetHash()));
- }
- else
- {
- bIsOK = FALSE;
- }
- HX_RELEASE(pNewChecksum);
- // if everthing is OK then add the DLL to the list
- if (bIsOK)
- {
- // ReconnectDLL() replaces one PluginDLL object with another PluginDLL; however,
- // both of these PluginDLL objects refer to the same DLL. This ensures that
- // only one PluginDLL object per DLL is in the m_PluginDLLList.
- ReconnectDLL((char*)pBuffer->GetBuffer(), pDLL);
- }
- else
- {
- delete pDLL;
- }
- HX_RELEASE(pBuffer);
- HX_RELEASE(pPropName);
- }
- pPrefEnum->EndSubPref();
- // Read the values for the Plugins.
- HX_VERIFY(HXR_OK == pPrefEnum->BeginSubPref(PLUGIN_PLUGININFO));
- nIndex = 0;
- while (HXR_OK == pPrefEnum->GetPrefKey(nIndex++, pPropName))
- {
- if (!strcmp((char*)pPropName->GetBuffer(), zm_pszKeyNameRegKey))
- {
- HX_RELEASE(pPropName);
- continue;
- }
- Plugin2Handler::Plugin* pPlugin = new Plugin2Handler::Plugin(
- m_pContext);
- pPlugin->AddRef();
- HX_VERIFY(HXR_OK == pPrefEnum->BeginSubPref((const char*)pPropName->GetBuffer()));
- pPlugin->ReadPref(pPrefEnum);
- pPrefEnum->EndSubPref();
- // XXXND This really ought to search for duplicates
- if( HXR_OK != ConnectPluginToDLL(pPlugin) )
- {
- // Must delete from list...
- pPlugin->Release();
- }
- else
- {
- m_PluginList.AddTail(pPlugin);
- }
- HX_RELEASE(pPropName);
- }
- pPrefEnum->EndSubPref();
- // Read the Prefs for other DLL which are not RMA dlls
- HX_VERIFY(HXR_OK == pPrefEnum->BeginSubPref(PLUGIN_NONHXINFO));
- nIndex = 0;
- while (HXR_OK == pPrefEnum->GetPrefKey(nIndex++, pPropName))
- {
- if (!strcmp((char*)pPropName->GetBuffer(), zm_pszKeyNameRegKey))
- {
- HX_RELEASE(pPropName);
- continue;
- }
- Plugin2Handler::OtherDLL* pOtherData = new Plugin2Handler::OtherDLL;
- pOtherData->m_filename = (char*)pPropName->GetBuffer();
- pOtherData->m_pMountPoint = pMountPoint;
- IHXBuffer* pCheckSumData = NULL;
- pPrefEnum->ReadPref((const char*) pPropName->GetBuffer(), pCheckSumData);
- if (pCheckSumData)
- {
- pOtherData->m_fileChecksum = (char*)pCheckSumData->GetBuffer();
- }
- m_MiscDLLList.AddTail((void*)pOtherData);
- HX_RELEASE(pCheckSumData);
- HX_RELEASE(pPropName);
- }
- pPrefEnum->EndSubPref();
- // Read the values for the Supported GUIDs.
- HX_VERIFY(HXR_OK == pPrefEnum->BeginSubPref(PLUGIN_GUIDINFO));
- nIndex = 0;
- while (HXR_OK == pPrefEnum->GetPrefKey(nIndex++, pPropName))
- {
- if (!strcmp((char*)pPropName->GetBuffer(), zm_pszKeyNameRegKey))
- {
- HX_RELEASE(pPropName);
- continue;
- }
- CHXSimpleList* pSupportList = new CHXSimpleList();
- m_GUIDtoSupportList.SetAt((char*) pPropName->GetBuffer(), (void*)pSupportList);
- UINT32 nSubIndex = 0;
- IHXBuffer* pSubPropName = 0;
- if (HXR_OK == pPrefEnum->BeginSubPref((const char*)pPropName->GetBuffer()))
- {
- while (HXR_OK == pPrefEnum->GetPrefKey(nSubIndex++, pSubPropName))
- {
- if (!strcmp((char*)pSubPropName->GetBuffer(), zm_pszKeyNameRegKey))
- {
- HX_RELEASE(pSubPropName);
- continue;
- }
- UINT32 nDummyVar;
- Plugin2Handler::PluginSupportingGUID* pGUIDSupport =
- new Plugin2Handler::PluginSupportingGUID();
- pPrefEnum->ReadPref((const char*)pSubPropName->GetBuffer(), pBuffer);
- if (pBuffer)
- {
- pGUIDSupport->m_nIndexInDLL = atoi((const char*)pBuffer->GetBuffer());
- pGUIDSupport->m_filename = pSubPropName->GetBuffer();
- pGUIDSupport->m_pMountPoint = pMountPoint;
- }
- if (pBuffer && FindPlugin((const char*)pSubPropName->GetBuffer(), pGUIDSupport->m_nIndexInDLL
- , nDummyVar))
- {
- pSupportList->AddTail((void*)pGUIDSupport);
- }
- else
- {
- delete pGUIDSupport;
- }
- HX_RELEASE(pBuffer);
- HX_RELEASE(pSubPropName);
- }
- pPrefEnum->EndSubPref();
- }
- HX_RELEASE(pPropName);
- }
- delete pPrefEnum;
- HX_RELEASE( pIPrefs );
- HX_RELEASE( pPathBuffer );
- HX_RELEASE( pIPrefs );
- return HXR_OK;
- }
- HX_RESULT Plugin2Handler::WritePluginInfoSlow( PluginMountPoint* pMountPoint )
- {
- HX_LOG_BLOCK( "Plugin2Handler::WritePluginInfoSlow" );
- UINT32 nCounter = 0;
- IHXBuffer* pBuffer = 0;
- IHXBuffer* pBuffer2 = 0;
- char namebuffer[(1<<8)]; /* Flawfinder: ignore */
- IHXPreferences* pIPrefs = pMountPoint->Prefs();
- if (!pIPrefs)
- {
- return HXR_OK;
- }
- // Save the DLL names.
- PreferenceEnumerator* pPrefEnum = new PreferenceEnumerator( pIPrefs );
- HX_VERIFY(HXR_OK == pPrefEnum->BeginSubPref(PLUGIN_REGKEY_ROOT));
- HX_VERIFY(HXR_OK == pPrefEnum->BeginSubPref(PLUGIN_FILENAMES));
- CHXSimpleList::Iterator i = m_PluginDLLList.Begin();
- for(; i!=m_PluginDLLList.End(); ++i, nCounter++)
- {
- Plugin2Handler::PluginDLL* pPlugDLL = (Plugin2Handler::PluginDLL*) *i;
- if( pPlugDLL->GetMountPoint() == pMountPoint )
- {
- pPlugDLL->WritePref(pPrefEnum);
- }
- }
- pPrefEnum->EndSubPref();
- HX_VERIFY(HXR_OK == pPrefEnum->BeginSubPref(PLUGIN_PLUGININFO));
- INT32 nIndexNumber = 0;
- pBuffer = new CHXBuffer();
- pBuffer->AddRef();
- pBuffer->Set((const UCHAR*)"",1);
- // Save the plugin Info.
- for(i = m_PluginList.Begin(); i!=m_PluginList.End(); ++i, nCounter--)
- {
- Plugin2Handler::Plugin* pPlug = (Plugin2Handler::Plugin*) *i;
- if( pPlug->GetDLL()->GetMountPoint() == pMountPoint )
- {
- IHXBuffer* pNameBuf = pPlug->GetFileName();
- char* pChar = (char*)pNameBuf->GetBuffer();
- SafeSprintf(namebuffer, 256, "%s-%d", pChar, (int)pPlug->GetIndex());
- HX_RELEASE(pNameBuf);
- #ifndef _MACINTOSH
- pPrefEnum->WriteSubPref(namebuffer, pBuffer);
- #endif
- HX_VERIFY(HXR_OK == pPrefEnum->BeginSubPref(namebuffer));
- pPlug->WritePref(pPrefEnum);
- pNameBuf = new CHXBuffer();
- pNameBuf->AddRef();
- char tempchar[16]; /* Flawfinder: ignore */
- sprintf(tempchar, "%d", (int)nIndexNumber++); /* Flawfinder: ignore */
- pNameBuf->Set((const UCHAR*)tempchar, strlen(tempchar)+1);
- pPrefEnum->WriteSubPref(namebuffer, pNameBuf);
- pPrefEnum->EndSubPref();
- HX_RELEASE(pNameBuf);
- }
- }
- HX_RELEASE(pBuffer);
- pPrefEnum->EndSubPref();
- // Now write the non-RMA DLL info to the reg.
- HX_VERIFY(HXR_OK == pPrefEnum->BeginSubPref(PLUGIN_NONHXINFO));
- for(i = m_MiscDLLList.Begin(); i!=m_MiscDLLList.End(); ++i)
- {
- Plugin2Handler::OtherDLL* pOtherData = (Plugin2Handler::OtherDLL*) *i;
- if( pOtherData->m_pMountPoint == pMountPoint )
- {
- pBuffer = new CHXBuffer();
- pBuffer->AddRef();
- pBuffer->Set((UCHAR*) (const char*) pOtherData->m_fileChecksum, pOtherData->m_fileChecksum.GetLength()+1);
- pPrefEnum->WriteSubPref(pOtherData->m_filename, pBuffer);
- HX_RELEASE(pBuffer);
- }
- }
- pPrefEnum->EndSubPref();
- HX_VERIFY(HXR_OK == pPrefEnum->BeginSubPref(PLUGIN_GUIDINFO));
- // Now save the Data to support the plugin Enumerator.
- for(CHXMapStringToOb::Iterator k = m_GUIDtoSupportList.Begin();
- k!=m_GUIDtoSupportList.End(); ++k)
- {
- CHXString sGUID = k.get_key();
- CHXSimpleList* pSupportedList = (CHXSimpleList*) *k;
- for(CHXSimpleList::Iterator j = pSupportedList->Begin();
- j!=pSupportedList->End(); ++j)
- {
- char IndexArray[16]; /* Flawfinder: ignore */
- PluginSupportingGUID* pSupportItem = (PluginSupportingGUID*) *j;
- if( pSupportItem->m_pMountPoint == pMountPoint )
- {
- IHXBuffer* pIndexBuffer = new CHXBuffer();
- pIndexBuffer->AddRef();
- sprintf(IndexArray, "%d", (int)pSupportItem->m_nIndexInDLL); /* Flawfinder: ignore */
- pIndexBuffer->Set((const UCHAR*)IndexArray, strlen(IndexArray)+1);
- HX_VERIFY(HXR_OK == pPrefEnum->BeginSubPref((const char*)sGUID));
- pPrefEnum->WriteSubPref((const char*)pSupportItem->m_filename, pIndexBuffer);
- pPrefEnum->EndSubPref();
- HX_RELEASE(pIndexBuffer);
- }
- }
- }
- pPrefEnum->EndSubPref();
- pPrefEnum->EndSubPref();
- delete pPrefEnum;
- HX_RELEASE( pIPrefs );
- return HXR_OK;
- }
- CPluginDatabaseIndex* Plugin2Handler::FindDBIndex( const char* pKeyName )
- {
- CPluginDatabaseIndex* pIndex = NULL;
- void* pVoid = NULL;
- if( m_dbIndices.Lookup( pKeyName, pVoid ) )
- {
- pIndex = (CPluginDatabaseIndex*) pVoid;
- }
- return pIndex;
- }
- void Plugin2Handler::AddPluginToIndices( Plugin2Handler::Plugin* pPlugin )
- {
- IHXValues* pIValues = NULL;
- if( SUCCEEDED( pPlugin->GetPluginInfo( pIValues ) ) )
- {
- HX_RESULT status = HXR_FAIL;
- const char* pPropName = NULL;
- IHXBuffer* pBuffer;
- // Iterate over all the elements in pIValues. If there's a key for that
- // name, add the plugin to that index.
- // Scan the CString entries
- status = pIValues->GetFirstPropertyCString( pPropName, pBuffer );
- while( status == HXR_OK )
- {
- CPluginDatabaseIndex* pIndex = FindDBIndex( pPropName );
- if( pIndex )
- {
- pIndex->AddItem( pBuffer, pPlugin );
- }
- HX_RELEASE( pBuffer );
- status = pIValues->GetNextPropertyCString( pPropName, pBuffer );
- }
- // Scan the Buffer entries
- status = pIValues->GetFirstPropertyBuffer( pPropName, pBuffer );
- while( status == HXR_OK )
- {
- CPluginDatabaseIndex* pIndex = FindDBIndex( pPropName );
- if( pIndex )
- {
- pIndex->AddItem( pBuffer, pPlugin );
- }
- HX_RELEASE( pBuffer );
- status = pIValues->GetNextPropertyBuffer( pPropName, pBuffer );
- }
- // NOTE: Don't release pIValues. GetPluginInfo() doesn't AddRef() it
- }
- }
- void Plugin2Handler::RemovePluginFromIndices( Plugin2Handler::Plugin* pPlugin )
- {
- HX_LOG_BLOCK( "Plugin2Handler::RemovePluginFromIndices" );
- CHXMapStringToOb::Iterator iter;
- for(iter = m_dbIndices.Begin(); iter != m_dbIndices.End(); ++iter)
- {
- CPluginDatabaseIndex* pIndex = (CPluginDatabaseIndex*) *iter;
- pIndex->RemoveItem( pPlugin );
- }
- }
- HX_RESULT Plugin2Handler::RemoveDLLFromGUIDSupportLists(const char* pszFileName)
- {
- for(CHXMapStringToOb::Iterator i = m_GUIDtoSupportList.Begin();
- i!=m_GUIDtoSupportList.End(); ++i)
- {
- CHXSimpleList* pSupportList = (CHXSimpleList*) *i;
- if (pSupportList->IsEmpty())
- continue;
- for(LISTPOSITION pPos = pSupportList->GetHeadPosition();
- pPos != pSupportList->GetTail();)
- {
- if (!pPos) break;
- PluginSupportingGUID* pSupportItem = (PluginSupportingGUID*) pSupportList->GetAt(pPos);
- if (!strcmp(pszFileName, pSupportItem->m_filename))
- {
- pPos = pSupportList->RemoveAt(pPos);
- delete pSupportItem;
- }
- if (!pPos)
- {
- break;
- }
- pSupportList->GetNext(pPos);
- }
- }
- return HXR_OK;
- }
- UINT32 Plugin2Handler::GetNumSupportedGUIDs()
- {
- return m_GUIDtoSupportList.GetCount();
- }
- HX_RESULT Plugin2Handler::GetGUIDForIndex(UINT32 nIndex, REF(CHXString) sGUID)
- {
- if (nIndex>= (UINT32)m_GUIDtoSupportList.GetCount())
- return HXR_FAIL;
- CHXMapStringToOb::Iterator i = m_GUIDtoSupportList.Begin();
- for(; nIndex; nIndex--, ++i) {}; // not a mistake.
- sGUID = (char*)i.get_key();
- return HXR_OK;
- }
- HX_RESULT Plugin2Handler::AddSupportForGUID(const char* pszGUID, PluginDLL* pDLL, UINT32 nIndexInDLL)
- {
- // Get the DLL name. We'll need it in a couple places below.
- IHXBuffer* pBuffer = pDLL->GetFileName();
- char* pNewDLLName = (char*) pBuffer->GetBuffer();
- // 1st look to see if we have data about this plugin already if so then return
- // Find the GUID which we are supporting.
- CHXSimpleList* pSupportList;
- if (m_GUIDtoSupportList.Lookup(pszGUID, (void*&)pSupportList))
- {
- if (!pSupportList->IsEmpty())
- {
- for(LISTPOSITION pPos = pSupportList->GetHeadPosition();
- pPos != pSupportList->GetTail();)
- {
- if (!pPos) break;
- PluginSupportingGUID* pSupport = (PluginSupportingGUID*) pSupportList->GetAt(pPos);
- if ( (pSupport->m_nIndexInDLL == nIndexInDLL) && (!strcmp(pSupport->m_filename, pNewDLLName)))
- {
- HX_RELEASE( pBuffer );
- return HXR_FAIL;
- }
- pSupportList->GetNext(pPos);
- }
- }
- }
- else
- {
- HX_ASSERT(1);
- HX_RELEASE( pBuffer );
- return HXR_NOTIMPL;
- }
- PluginSupportingGUID* pSupport = new PluginSupportingGUID;
- pSupport->m_filename = pNewDLLName;
- pSupport->m_pMountPoint = pDLL->GetMountPoint();
- pSupport->m_nIndexInDLL = nIndexInDLL;
- pSupportList->AddTail((void*) pSupport);
- HX_RELEASE( pBuffer );
- return HXR_OK;
- }
- STDMETHODIMP Plugin2Handler::FindPluginUsingStrings (char* PropName1,
- char* PropVal1,
- char* PropName2,
- char* PropVal2,
- char* PropName3,
- char* PropVal3,
- REF(IUnknown*) pRetUnk)
- {
- return FindPluginUsingStrings( PropName1, PropVal1, PropName2, PropVal2,
- PropName3, PropVal3, pRetUnk, NULL );
- }
- STDMETHODIMP
- Plugin2Handler::FindImplementationFromClassID
- (
- REFGUID GUIDClassID,
- REF(IUnknown*) pIUnknownInstance
- )
- {
- // Defer to the new version
- return FindImplementationFromClassID( GUIDClassID, pIUnknownInstance, NULL, m_pContext );
- }
- STDMETHODIMP Plugin2Handler::Close ()
- {
- CHXSimpleList::Iterator i = m_PluginList.Begin();
- // Release all Plugins and Their Associated DLLs
- for(; i!=m_PluginList.End(); ++i)
- {
- Plugin2Handler::Plugin* pPlug = (Plugin2Handler::Plugin*) *i;
- pPlug->Release();
- }
- m_PluginList.RemoveAll();
- for(i = m_PluginDLLList.Begin(); i!=m_PluginDLLList.End(); ++i)
- {
- Plugin2Handler::PluginDLL* pPlugDLL = (Plugin2Handler::PluginDLL*) *i;
- pPlugDLL->Release();
- }
- m_PluginDLLList.RemoveAll();
- for(i = m_MiscDLLList.Begin(); i!=m_MiscDLLList.End(); ++i)
- {
- Plugin2Handler::OtherDLL* pOtherDLL = (Plugin2Handler::OtherDLL*) *i;
- delete pOtherDLL;
- }
- m_MiscDLLList.RemoveAll();
- for(CHXMapStringToOb::Iterator mp = m_MountPoints.Begin(); mp!=m_MountPoints.End(); ++mp)
- {
- Plugin2Handler::PluginMountPoint* pMountPoint = (Plugin2Handler::PluginMountPoint*) *mp;
- pMountPoint->Release();
- }
- m_MountPoints.RemoveAll();
- // Release all of the GUID stuff
- CHXMapStringToOb::Iterator j;
- for(j = m_GUIDtoSupportList.Begin();
- j!= m_GUIDtoSupportList.End(); ++j)
- {
- CHXSimpleList* pList = (CHXSimpleList*) *j;
- for(i = pList->Begin(); i!=pList->End(); ++i)
- {
- PluginSupportingGUID* pSupportItem = (PluginSupportingGUID*) *i;
- delete pSupportItem;
- }
- delete pList;
- }
- m_GUIDtoSupportList.RemoveAll();
- // Clean up all the indices
- for(j = m_dbIndices.Begin(); j!=m_dbIndices.End(); ++j)
- {
- CPluginDatabaseIndex* pIndex = (CPluginDatabaseIndex*) *j;
- HX_DELETE( pIndex );
- }
- m_dbIndices.RemoveAll();
- // release all of the CORE stuff...
- HX_RELEASE(m_pPluginDir);
- HX_RELEASE(m_pPreferences);
- HX_RELEASE(m_pErrorMessages);
- HX_RELEASE(m_pContext);
- m_CanUnload2DllList.RemoveAll();
- if ( m_pIScheduler && m_hScheduler )
- {
- m_pIScheduler->Remove( m_hScheduler );
- }
- HX_RELEASE( m_pIScheduler );
- return HXR_OK;
- }
- STDMETHODIMP Plugin2Handler::SetRequiredPlugins (const char** ppszRequiredPlugins)
- {
- return HXR_OK;
- }
- HX_RESULT Plugin2Handler::AddToValues(IHXValues* pValues, char* pPropName, char* pPropVal, eValueTypes eValueType)
- {
- if (!pPropName || !pPropVal)
- return HXR_FAIL;
- // 1st make into a cstrig and to trim the buffer...
- CHXString theValue = (pPropVal);
- theValue.TrimLeft();
- theValue.TrimRight();
- switch (eValueType)
- {
- case eString:
- {
- IHXBuffer* pBuffer;
- CHXBuffer* pCHXBuffer;
- pCHXBuffer = new CHXBuffer;
- pCHXBuffer->QueryInterface(IID_IHXBuffer, (void**) &pBuffer);
- pBuffer->Set((const unsigned char*)(const char*)theValue, strlen(theValue)+1);
- pValues->SetPropertyCString(pPropName, pBuffer);
- pBuffer->Release();
- return HXR_OK;
- }
- case eInt:
- {
- int val = atoi(theValue);
- pValues->SetPropertyULONG32(pPropName, (ULONG32)val);
- return HXR_OK;
- }
- }
- return HXR_NOTIMPL;
- }
- /*
- * Win98 does not allow reg keys that are larger than 16k a pop.
- * Thus, this function splits up regkeys into more managiable bites.
- */
- #define PREF_THRESHOLD 10000
- void Plugin2Handler::WriteHugePref( IHXPreferences* pIPrefs, const char* pszKeyName, IHXBuffer* pBigBuffer)
- {
- int counter = 0;
- UCHAR* pPlaceHolder;
- char szNewKeyName[1024]; /* Flawfinder: ignore */
- char szNumber[16]; /* Flawfinder: ignore */ // a REALLY big buffer could be put in :)
- int nOriginalBufferSize = pBigBuffer->GetSize();
- CHXBuffer* pNewBuffer;
- IHXBuffer* pIHXBuffer;
- ULONG32 nNewBufferSize;
- char oldValue;
- if (nOriginalBufferSize>PREF_THRESHOLD)
- {
- pNewBuffer = new CHXBuffer();
- pNewBuffer->QueryInterface(IID_IHXBuffer, (void**)&pIHXBuffer);
- pNewBuffer->SetSize(PREF_THRESHOLD);
- pPlaceHolder = pBigBuffer->GetBuffer();
- // bleech we are going to break up the buffer into more managiable chunks.
- while(((int)(pPlaceHolder - pBigBuffer->GetBuffer() ))!= nOriginalBufferSize)
- {
- nNewBufferSize = nOriginalBufferSize - (ULONG32 ( pPlaceHolder - pBigBuffer->GetBuffer() ));
- if (nNewBufferSize> PREF_THRESHOLD)
- {
- nNewBufferSize = PREF_THRESHOLD;
- }
- memcpy((char*)pNewBuffer->GetBuffer(), pPlaceHolder, nNewBufferSize); /* Flawfinder: ignore */
- SafeStrCpy(szNewKeyName, pszKeyName, 1024);
- sprintf(szNumber, "%d", counter); /* Flawfinder: ignore */
- SafeStrCat(szNewKeyName, szNumber, 1024);
- /*
- * Check for a null termination at the end .. if not then muck around.
- */
- char* pTempchar = (char*)pNewBuffer->GetBuffer();
- if (pTempchar[nNewBufferSize-1])
- {
- // not null terminated.
- oldValue = pTempchar[nNewBufferSize-1];
- pTempchar[nNewBufferSize-1] = 0;
- pIPrefs->WritePref(szNewKeyName, pIHXBuffer);
- nNewBufferSize--;
- }
- else
- {
- pIPrefs->WritePref(szNewKeyName, pIHXBuffer);
- }
- pPlaceHolder+=nNewBufferSize;
- counter++;
- }
- HX_RELEASE(pIHXBuffer);
- }
- else
- {
- SafeStrCpy(szNewKeyName, pszKeyName, 1024);
- SafeStrCat(szNewKeyName, "0", 1024);
- pIPrefs->WritePref(szNewKeyName, pBigBuffer);
- }
- }
- /*
- * Win98 does not allow reg keys that are larger than 16k a pop.
- * Thus, this function takes regkeys that were split up and re-joins them
- * for later processing.
- */
- HX_RESULT Plugin2Handler::ReadHugePref( IHXPreferences* pIPrefs, const char* pszKeyName, REF(IHXBuffer*) pBigBuffer)
- {
- HX_LOG_BLOCK( "Plugin2Handler::ReadHugePref" );
- CHXSimpleList listOBuffers;
- HX_RESULT retVal = HXR_FAIL;
- IHXBuffer* pBuffer;
- char szNewKeyName[1024]; /* Flawfinder: ignore */
- char szNumber[16]; /* Flawfinder: ignore */
- int counter = 0;
- int totalSize = 0;
- UCHAR* pPos;
- pBigBuffer = NULL;
- SafeStrCpy(szNewKeyName, pszKeyName, 1024);
- SafeStrCat(szNewKeyName, "0", 1024);
- retVal = pIPrefs->ReadPref(szNewKeyName, pBuffer);
- while(HXR_OK == retVal)
- {
- totalSize+=pBuffer->GetSize();
- listOBuffers.AddTail((void*) pBuffer);
- counter++;
- SafeStrCpy(szNewKeyName, pszKeyName, 1024);
- sprintf(szNumber, "%d", counter); /* Flawfinder: ignore */
- SafeStrCat(szNewKeyName, szNumber, 1024);
- retVal = pIPrefs->ReadPref(szNewKeyName, pBuffer);
- }
- if (listOBuffers.GetCount())
- {
- pBigBuffer = new CHXBuffer;
- pBigBuffer->AddRef();
- pBigBuffer->SetSize(totalSize);
- pPos = pBigBuffer->GetBuffer();
- *pPos = 0;
- CHXSimpleList::Iterator i;
- for(i=listOBuffers.Begin(); i!=listOBuffers.End(); ++i)
- {
- pBuffer = (IHXBuffer*)*i;
- SafeStrCat((char*)pPos, (char*)pBuffer->GetBuffer(), totalSize);
- HX_RELEASE(pBuffer);
- }
- return HXR_OK;
- }
- else
- {
- return HXR_FAIL;
- }
- }
- // XXXND This function doesn't correctly deal with mount points. The last mount point in the list
- // that has any contents will overwrite all the others.
- void Plugin2Handler::WriteSupportedGUIDs()
- {
- if (m_GUIDtoSupportList.GetCount())
- {
- // Create buffer to use by CPluginInfoWriter...
- IHXBuffer* pIHXBuffer = NULL;
- CHXBuffer* pBuffer = new CHXBuffer();
- if(pBuffer)
- {
- if(SUCCEEDED(pBuffer->QueryInterface(IID_IHXBuffer, (void**)&pIHXBuffer)))
- {
- pIHXBuffer->SetSize(PREF_CACHE_SIZE);
- }
- }
- char szRegKey[255]; /* Flawfinder: ignore */
- SafeStrCpy(szRegKey, PLUGIN_REGKEY_ROOT, 255);
- SafeStrCat(szRegKey, zm_pszRegKeySeperator, 255);
- SafeStrCat(szRegKey, PLUGIN_GUIDINFO, 255);
- // Do this for each MountPoint
- for(CHXMapStringToOb::Iterator mp = m_MountPoints.Begin(); mp!=m_MountPoints.End(); ++mp)
- {
- PluginMountPoint* pMountPoint = (PluginMountPoint*) *mp;
- // format of GUID info:
- // {GUID, filename, index, filename, index, etc}{GUID, filename, index, filename, index}
- IHXPreferences* pIPrefs = pMountPoint->Prefs();
- if( pIPrefs )
- {
- CPluginInfoWriter piw;
- piw.Init(pIPrefs, szRegKey, pIHXBuffer);
- // Dump the data.
- CHXSimpleList::Iterator i;
- CHXMapStringToOb::Iterator k;
- for(k = m_GUIDtoSupportList.Begin(); k!=m_GUIDtoSupportList.End(); ++k)
- {
- BOOL foundFirst = FALSE;
- CHXSimpleList* pSupportedList = (CHXSimpleList*) *k;
- for (i=pSupportedList->Begin(); i!=pSupportedList->End();++i)
- {
- PluginSupportingGUID* pSupportItem = (PluginSupportingGUID*) *i;
- if( pSupportItem->m_pMountPoint == pMountPoint )
- {
- if( !foundFirst )
- {
- foundFirst = TRUE;
- piw.Write("{");
- piw.Write(k.get_key());
- }
- char szScratch[20]; /* Flawfinder: ignore */
- itoa(pSupportItem->m_nIndexInDLL, szScratch, 10);
- piw.Write(",");
- piw.Write((const char*) pSupportItem->m_filename);
- piw.Write(",");
- piw.Write(szScratch);
- }
- }
- if( foundFirst )
- {
- piw.Write("}");
- }
- }
- HX_RELEASE( pIPrefs );
- }
- }
- HX_RELEASE( pIHXBuffer );
- }
- }
- STDMETHODIMP_(ULONG32) Plugin2Handler::GetNumOfPlugins()
- {
- return m_PluginList.GetCount();
- }
- STDMETHODIMP Plugin2Handler::GetPlugin(ULONG32 ulIndex, REF(IUnknown*) /*OUT*/ pInstance)
- {
- return GetPlugin( ulIndex, pInstance, NULL );
- }
- STDMETHODIMP Plugin2Handler::FlushCache()
- {
- // if we have no context do not proceed.
- if (!m_pContext)
- {
- return INVALID_CONTEXT;
- }
- INT32 nTempCache = m_nCacheSizeBites;
- m_nCacheSizeBites = 0;
- UpdateCache();
- m_nCacheSizeBites = nTempCache;
- // now we have to tell all other players that they should also
- // flush thier cache.
- IHXShutDownEverything* pShutDown = NULL ;
- if (HXR_OK == m_pContext->QueryInterface(IID_IHXShutDownEverything, (void**) &pShutDown))
- {
- pShutDown->AskAllOtherPlayersToUnload();
- HX_RELEASE(pShutDown);
- }
- return HXR_OK;
- }
- STDMETHODIMP Plugin2Handler::SetCacheSize(ULONG32 nSizeKB)
- {
- m_nCacheSizeBites = (nSizeKB<<10);
- UpdateCache();
- return HXR_OK;
- }
- HX_RESULT Plugin2Handler::AddtoLRU(Plugin2Handler::PluginDLL* pDLL)
- {
- // 1st we have to find if the plugin is in the LRU list
- // and if it is remove it.
- RemoveFromLRU(pDLL);
- // now just add to the LRU list.
- m_DLL_LRUList.AddTail((void*)pDLL);
- return HXR_OK;
- }
- HX_RESULT Plugin2Handler::RemoveFromLRU(Plugin2Handler::PluginDLL* pDLL)
- {
- if (pDLL)
- {
- LISTPOSITION pPos = m_DLL_LRUList.Find(pDLL);
- if (pPos)
- {
- m_DLL_LRUList.RemoveAt(pPos);
- }
- return HXR_OK;
- }
- return HXR_INVALID_PARAMETER;
- }
- HX_RESULT Plugin2Handler::UpdateCache()