plghand2.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:192k
- // XXXSM before update the cache, we have to be sure that
- // it only contains actually loaded dlls.
- // Removing a mount point during runtime could
- // invalidate some dlls in this cache resulting in
- // an invalid memory access.
- //return HXR_OK;
- LISTPOSITION pPos;
- INT32 nTotalSize = 0;
- // find out how many bytes are being used by the plugins.
- for(CHXSimpleList::Iterator i = m_DLL_LRUList.Begin();
- i!= m_DLL_LRUList.End(); ++i)
- {
- Plugin2Handler::PluginDLL* pDLL = (Plugin2Handler::PluginDLL*) *i;
- nTotalSize += pDLL->GetFileSize();
- }
- // are we under the limit?
- if (nTotalSize <= m_nCacheSizeBites)
- {
- return HXR_OK;
- }
- return HXR_OK;
- // since the most recently used portions of the list are stuck at the tail we
- // will go forward unloading DLL until we are below the limit.
- for(pPos = m_DLL_LRUList.GetHeadPosition();
- pPos != m_DLL_LRUList.GetTail();)
- {
- if (!pPos) break;
- Plugin2Handler::PluginDLL* pDLL = (Plugin2Handler::PluginDLL*) m_DLL_LRUList.GetAt(pPos);
- if (HXR_OK == pDLL->Unload())
- {
- nTotalSize -= pDLL->GetFileSize();
- // delete this node from the list
- pPos = m_DLL_LRUList.RemoveAt(pPos);
- if (!pPos)
- {
- break;
- }
- if (nTotalSize<= m_nCacheSizeBites)
- {
- break;
- }
- continue;
- }
- m_DLL_LRUList.GetNext(pPos);
- }
- if (nTotalSize<= m_nCacheSizeBites)
- {
- return HXR_OK;
- }
- else
- {
- return HXR_FAIL;
- }
- }
- BOOL Plugin2Handler::GetPluginFileInfo(REF(char*) pszCurrentPos,
- REF(char*) pszName,
- REF(char*) pszCheckSum,
- REF(BOOL) bFactory,
- REF(int) nDLLSize,
- REF(int) nNumberPlugins)
- {
- HX_LOG_BLOCK( "Plugin2Handler::GetPluginFileInfo" );
- char* pszBOOLFactory;
- char* pszINTSize;
- char* pszINTPlugins;
- // eat characters until you find a {
- for(;*pszCurrentPos!='{' && *pszCurrentPos!=0; pszCurrentPos++){};
- if (*pszCurrentPos=='{')
- {
- pszCurrentPos++;
- pszName = pszCurrentPos;
- // eat until a you find a comma
- for(;*pszCurrentPos!=',' && *pszCurrentPos!=0; pszCurrentPos++) {};
- *pszCurrentPos=0;
- pszCurrentPos++;
- pszCheckSum = pszCurrentPos;
- // eat until a you find a comma
- for(;*pszCurrentPos!=',' && *pszCurrentPos!=0; pszCurrentPos++) {};
- *pszCurrentPos=0;
- pszCurrentPos++;
- pszBOOLFactory = pszCurrentPos;
- // eat until a you find a comma
- for(;*pszCurrentPos!=',' && *pszCurrentPos!=0; pszCurrentPos++) {};
- *pszCurrentPos=0;
- pszCurrentPos++;
- pszINTSize = pszCurrentPos;
- // eat until a you find a comma
- for(;*pszCurrentPos!=',' && *pszCurrentPos!=0; pszCurrentPos++) {};
- *pszCurrentPos=0;
- pszCurrentPos++;
- pszINTPlugins = pszCurrentPos;
- // eat until a you find a close brace
- for(;*pszCurrentPos!='}' && *pszCurrentPos!=0; pszCurrentPos++) {};
- *pszCurrentPos=0;
- pszCurrentPos++;
- if (pszBOOLFactory && pszINTSize && pszINTPlugins)
- {
- bFactory = atoi(pszBOOLFactory);
- nDLLSize = atoi(pszINTSize);
- nNumberPlugins = atoi(pszINTPlugins);
- }
- return TRUE;
- }
- return FALSE;
- }
- BOOL Plugin2Handler::GetNameValuePair(REF(char*) pszCurrentPos, REF(char*) pszName, REF(char*) pszValue)
- {
- // eat until we find either a NULL, a comma, or a close brace
- // check for termination condition
- if (*pszCurrentPos=='{')
- {
- return FALSE;
- }
- pszName = pszCurrentPos;
- for(;*pszCurrentPos && *pszCurrentPos!='}' && *pszCurrentPos!='~';pszCurrentPos++) {};
- if (*pszCurrentPos == '~')
- {
- *pszCurrentPos = 0;
- pszCurrentPos++;
- }
- else
- {
- return FALSE;
- }
- pszValue = pszCurrentPos;
- for(;*pszCurrentPos && *pszCurrentPos!='}' && *pszCurrentPos!='~';pszCurrentPos++) {};
- if (*pszCurrentPos == '}' || *pszCurrentPos=='~')
- {
- *pszCurrentPos = 0;
- pszCurrentPos++;
- return TRUE;
- }
- else
- {
- return FALSE;
- }
- }
- BOOL Plugin2Handler::GetPluginFileInfo(REF(char*) pszCurrentPos, REF(Plugin2Handler::Plugin*) pPlugin)
- {
- /* format of data in regestry is as follows:
- * {ValueName, N|S|BValue, ValueName, N|S|B, ValueName, N|S|B, etc},
- * {etc}
- */
- // eat until we find a '{' or a null
- for(;*pszCurrentPos!='{' && *pszCurrentPos!=0; pszCurrentPos++) {};
- if (*pszCurrentPos)
- {
- pPlugin = new Plugin2Handler::Plugin(m_pContext);
- pPlugin->AddRef();
- // XXXND This might do well to get the values from the plugin, and then
- // add each property using the IHXValues interface.
- char* pszName;
- char* pszValue;
- pszCurrentPos++;
- while (GetNameValuePair(pszCurrentPos, pszName, pszValue))
- {
- switch (*pszValue)
- {
- case 'N':
- {
- pPlugin->SetPropertyULONG32(pszName, pszValue+1);
- if (!strcasecmp(pszName, "indexnumber"))
- {
- pPlugin->SetIndex(atoi(pszValue+1));
- }
- break;
- }
- case 'S':
- {
- pPlugin->SetPropertyCString(pszName, pszValue+1);
- break;
- }
- case 'B':
- {
- UINT32 size = strlen(pszValue);
- pPlugin->SetPropertyBuffer( pszName, (BYTE*) pszValue + 1, size - 1 );
- break;
- }
- case 'X':
- {
- UINT32 size = strlen(pszValue);
- CHXBuffer *pBuf = new CHXBuffer();
- HX_ASSERT(pBuf);
- pBuf->AddRef();
- pBuf->SetSize(size);
- // We subtract 1 from size because we move foward in the buffer by 1
- INT32 s = BinFrom64(pszValue+1, size - 1, pBuf->GetBuffer());
- HX_ASSERT((UINT32)s <= size);
- HX_ASSERT(s != -1);
- if (s != -1)
- {
- pPlugin->SetPropertyBuffer(pszName, pBuf->GetBuffer(), s );
- }
- HX_RELEASE(pBuf);
- break;
- }
- }
- }
- return TRUE;
- }
- return FALSE;
- }
- BOOL Plugin2Handler::GetNextSupportingFile(REF(char*) pszCurrentPos, REF(char*) pszFileName, REF(UINT32) index)
- {
- char* pszIndex;
- if (*pszCurrentPos == '{')
- {
- return FALSE;
- }
- if (*pszCurrentPos)
- {
- pszFileName = pszCurrentPos;
- // eat until we find a ',' or a null or a '}'
- for(;*pszCurrentPos!=',' && *pszCurrentPos!=0 && *pszCurrentPos!='}'; pszCurrentPos++) {};
- if (*pszCurrentPos && *pszCurrentPos!='}')
- {
- *pszCurrentPos = 0;
- pszCurrentPos++;
- pszIndex = pszCurrentPos;
- // eat until we find a ',' or a null
- for(;*pszCurrentPos!=',' && *pszCurrentPos!=0 && *pszCurrentPos!='}'; pszCurrentPos++) {};
- if (*pszCurrentPos)
- {
- *pszCurrentPos = 0;
- pszCurrentPos++;
- index = atoi(pszIndex);
- return TRUE;
- }
- }
- }
- return FALSE;
- }
- BOOL Plugin2Handler::GetGUIDInfo(REF(char*) pszCurrentPos, PluginMountPoint* pMountPoint, REF(char*) pszGUID, REF(CHXSimpleList*) pList)
- {
- // format of GUID info:
- // {GUID, filename, index, filename, index, etc}{GUID, filename, index, filename, index}
- UINT32 nDummyVar;
- UINT32 index;
- char* pszFileName;
- Plugin2Handler::PluginSupportingGUID* pGUIDSupport;
- // eat until we find a '{' or a null
- for(;*pszCurrentPos!='{' && *pszCurrentPos!=0; pszCurrentPos++) {};
- pList = NULL;
- pszGUID = NULL;
- if (*pszCurrentPos)
- {
- pszCurrentPos++;
- pszGUID = pszCurrentPos;
- // eat until we find a ',' or a null or a close brace
- for(;*pszCurrentPos!=',' && *pszCurrentPos!=0 && *pszCurrentPos!='}'; pszCurrentPos++) {};
- // do we have support for this GUID?
- if (*pszCurrentPos != '}')
- {
- if (*pszCurrentPos)
- {
- *pszCurrentPos = 0;
- pszCurrentPos++;
- // ok we have a valid list
- pList = new CHXSimpleList;
- // now construct the list
- while (GetNextSupportingFile(pszCurrentPos, pszFileName, index))
- {
- if (FindPlugin(pszFileName, index, nDummyVar))
- {
- pGUIDSupport = new Plugin2Handler::PluginSupportingGUID();
- pGUIDSupport->m_filename = pszFileName;
- pGUIDSupport->m_pMountPoint = pMountPoint;
- pGUIDSupport->m_nIndexInDLL = index;
- pList->AddTail((void*)pGUIDSupport);
- }
- }
- }
- }
- else
- {
- pList = new CHXSimpleList;
- *pszCurrentPos = 0;
- pszCurrentPos++;
- }
- return TRUE;
- }
- return FALSE;
- }
- BOOL Plugin2Handler::GetNonHXInfo(REF(char*) pszCurrentPos, PluginMountPoint* pMountPoint, REF(Plugin2Handler::OtherDLL*) pOtherData)
- {
- HX_LOG_BLOCK( "Plugin2Handler::GetNonHXInfo" );
- char* pszName;
- char* pszHash;
- // eat until we find a '{' or a null
- for(;*pszCurrentPos!='{' && *pszCurrentPos!=0; pszCurrentPos++) {};
- if (*pszCurrentPos)
- {
- pszCurrentPos++;
- pszName = pszCurrentPos;
- // eat until we find a '{' or a null
- for(;*pszCurrentPos!=',' && *pszCurrentPos!=0; pszCurrentPos++) {};
- if (*pszCurrentPos)
- {
- *pszCurrentPos = 0;
- pszCurrentPos++;
- pszHash = pszCurrentPos;
- // eat until we find a '}' or a null
- for(;*pszCurrentPos!='}' && *pszCurrentPos!=0; pszCurrentPos++) {};
- if (*pszCurrentPos)
- {
- *pszCurrentPos = 0;
- pszCurrentPos++;
- {
- pOtherData = new Plugin2Handler::OtherDLL;
- pOtherData->m_filename = pszName;
- pOtherData->m_pMountPoint = pMountPoint;
- pOtherData->m_fileChecksum = pszHash;
- return TRUE;
- }
- }
- }
- }
- return FALSE;
- }
- STDMETHODIMP Plugin2Handler::ReadFromRegistry()
- {
- // Set up a mount point with the default plugin location
- IHXBuffer* pIPluginDir = GetPluginDir();
- HX_RESULT result = AddPluginMountPoint( HXVER_SDK_PRODUCT, 0, 0, pIPluginDir );
- HX_RELEASE( pIPluginDir );
- return result;
- }
- BOOL Plugin2Handler::FindPlugin(const char* pFileName, UINT32 nDLLIndex, REF(UINT32) nIndex)
- {
- UINT32 nTempIndex = 0;
- for(CHXSimpleList::Iterator i = m_PluginList.Begin(); i!=m_PluginList.End(); ++i)
- {
- Plugin2Handler::Plugin* pPlugin = (Plugin2Handler::Plugin*) *i;
- IHXBuffer* pBuffer = pPlugin->GetFileName();
- char* pPluginFileName = (char*) pBuffer->GetBuffer();
- if (!strcasecmp(pPluginFileName, pFileName))
- {
- if (pPlugin->GetIndex() == nDLLIndex)
- {
- nIndex = nTempIndex;
- HX_RELEASE(pBuffer);
- return TRUE;
- }
- }
- HX_RELEASE(pBuffer);
- nTempIndex++;
- }
- return FALSE;
- }
- HX_RESULT Plugin2Handler::ConnectPluginToDLL(Plugin2Handler::Plugin * pPlugin)
- {
- Plugin2Handler::PluginDLL* pPluginDll = NULL;
- IHXBuffer* pBuffer = pPlugin->GetFileName();
- HX_RESULT retVal = HXR_FAIL;
- if (pBuffer)
- {
- char* pszFileName = (char*)pBuffer->GetBuffer();
- if (m_FileNameMap.Lookup(pszFileName, (void*&)pPluginDll))
- {
- // match found...
- pPlugin->SetDLL(pPluginDll);
- retVal = HXR_OK;
- }
- }
- HX_RELEASE(pBuffer);
- return retVal;
- }
- IHXBuffer* Plugin2Handler::GetPluginDir()
- {
- // If we don't have a cached PluginDir, figure it out
- if( !m_pPluginDir )
- {
- #ifdef _STATICALLY_LINKED
- m_pPluginDir = new CHXBuffer();
- m_pPluginDir->AddRef();
- m_pPluginDir->Set((const UCHAR *)"",1);
- #else
- const char* pPath = NULL;
- // Get the plugin directory from the Dll Access Paths
- pPath = GetDLLAccessPath()->GetPath(DLLTYPE_PLUGIN);
- if (!pPath || !pPath[0])
- {
- m_pPluginDir = GetDefaultPluginDir();
- GetDLLAccessPath()->SetPath(DLLTYPE_PLUGIN,
- (const char*)m_pPluginDir->GetBuffer());
- }
- else
- {
- m_pPluginDir = new CHXBuffer();
- m_pPluginDir->AddRef();
- m_pPluginDir->Set((const UCHAR*)pPath, strlen(pPath) + 1);
- // Validate this path.
- //
- #ifdef _MAC_CFM // XXXSEH: Revisit validation under Mach-O.
- //
- // Couldn't find a cross platform path validator, so I'll do it just for the Macintosh.
- // That's where this is most important anyways.
- //
- char tempPath[1024]; /* Flawfinder: ignore */
- FSSpec tempSpec;
- OSErr err=0;
- UINT32 ulBytesToCopy = (m_pPluginDir->GetSize() > 1023 ? 1023 : m_pPluginDir->GetSize());
- memcpy(tempPath,m_pPluginDir->GetBuffer(),ulBytesToCopy); /* Flawfinder: ignore */
- tempPath[ulBytesToCopy]=0;
- err = FSSpecFromPathName(tempPath,&tempSpec);
- //
- // Uhoh the Macintosh path validator could not resolve this
- // path, thus we must refresh it. Strange how we store this
- // path but never expect it to change.
- //
- if (err != noErr)
- {
- HX_RELEASE(m_pPluginDir);
- m_pPluginDir = GetDefaultPluginDir();
- GetDLLAccessPath()->SetPath(DLLTYPE_PLUGIN,
- (const char*)m_pPluginDir->GetBuffer());
- }
- #endif
- }
- // CFindFile is kind of brain dead in that it will append a OS Seperator
- // after the path regardless of what is there currently (bad CFindFile bad!)
- // so we will strip it off if it is the last character,
- // Also all functions within the plugin handler assume that the plugin
- // directory will have not have an OS seperator at the end of it.
- char* pszPluginDir = NULL;
- ULONG32 nPluginDirLen = 0;
- m_pPluginDir->Get((UCHAR*&)pszPluginDir, nPluginDirLen);
- // now we COULD (and should for speed) use nPluginDirLen-1 as the
- // length of the string. However, it is SLIGHTLY safer to use strlen
- if ( *(pszPluginDir+(strlen(pszPluginDir)-1)) == Plugin2Handler::zm_cDirectorySeperator)
- {
- *(pszPluginDir+(strlen(pszPluginDir)-1)) = 0;
- }
- #endif // _STATICALLY_LINKED
- }
- // AddRef() our return value
- if( m_pPluginDir )
- m_pPluginDir->AddRef();
- return m_pPluginDir;
- }
- IHXPreferences* Plugin2Handler::GetPreferences()
- {
- if( m_pPreferences )
- {
- m_pPreferences->AddRef();
- }
- return m_pPreferences;
- }
- IHXBuffer* Plugin2Handler::GetDefaultPluginDir()
- {
- IHXBuffer* lpBuffer = NULL;
- char mask_name[_MAX_PATH + 1] = ""; /* Flawfinder: ignore */
- #if (defined (_WINDOWS) || defined (_WIN32)) && !defined(_WINCE)
- if (!GetSystemDirectory(mask_name, _MAX_PATH))
- {
- strcpy(mask_name, ""); /* Flawfinder: ignore */
- }
- if (strlen(mask_name) > 0 && mask_name[strlen(mask_name) - 1] != zm_cDirectorySeperator)
- {
- SafeStrCat(mask_name, zm_pszDirectorySeperator, _MAX_PATH+1);
- }
- SafeStrCat(mask_name, "Real", _MAX_PATH+1);
- #elif defined (_UNIX) && !defined(_MAC_UNIX)
- SafeStrCpy(mask_name, getenv("HOME"), _MAX_PATH+1);
- SafeStrCat(mask_name, "/Real", _MAX_PATH+1);
- #elif defined (_MACINTOSH) || defined(_MAC_UNIX)
- FSSpec extSpec;
- extSpec.name[0] = 0;
- // if Sys 8.5 or greater, use Application Support folder, else Extensions
- INT32 sysVersion;
- char* bytes=(char*)&sysVersion;
- OSType folderType;
- ::Gestalt(gestaltSystemVersion,&sysVersion);
- if (bytes[2]>8 || ((bytes[2]==8) && (bytes[3] >= 0x50)))
- folderType = kApplicationSupportFolderType;
- else
- folderType = kExtensionFolderType;
- if (noErr == ::FindFolder (-1, folderType, kDontCreateFolder,
- &extSpec.vRefNum, &extSpec.parID))
- {
- CHXString str_path;
- str_path = extSpec;
- SafeStrCpy(mask_name, (char*)(const char*)str_path, _MAX_PATH);
- }
- else
- SafeStrCpy(mask_name, ":System Folder:Extensions:", _MAX_PATH+1 );
- SafeStrCat(mask_name, "Real", _MAX_PATH+1);
- #if defined(_CARBON) || defined(_MAC_UNIX)
- if (bytes[2] >= 0x10) // OS X
- {
- #ifdef _MAC_MACHO
- CFBundleRef mainBundle;
- CFURLRef mainBundleURL;
- CFURLRef updirURL;
- CFBundleRef myBundle;
- // get the main bundle for the app
- mainBundle = ::CFBundleGetMainBundle();
- // look for a resource in the main bundle by name
- mainBundleURL = ::CFBundleCopyBundleURL( mainBundle );
- updirURL = ::CFURLCreateCopyDeletingLastPathComponent(NULL, mainBundleURL);
- CFStringRef urlString = CFURLCopyPath(updirURL);
- CFStringGetCString(urlString, mask_name, _MAX_PATH, kCFStringEncodingMacRoman);
- #else
- ProcessSerialNumber psn;
- ProcessInfoRec pir;
- GetCurrentProcess(&psn);
- pir.processName = NULL;
- pir.processAppSpec = &extSpec;
- pir.processInfoLength = sizeof(pir);
- GetProcessInformation(&psn, &pir);
- extSpec.name[0] = ' ';
- CHXString str_path;
- str_path = extSpec;
- SafeStrCpy(mask_name, (char*)(const char*)str_path, _MAX_PATH);
- #endif
- }
- #endif
- #elif defined(_WINCE)
- strcpy(mask_name, "\"); /* Flawfinder: ignore */
- #endif //defined (_WINDOWS) || defined (_WIN32)
- CHXBuffer* pCHXBuffer = new CHXBuffer();
- pCHXBuffer->QueryInterface(IID_IHXBuffer,(void**) &lpBuffer);
- lpBuffer->Set((UCHAR*)mask_name, strlen(mask_name)+1);
- return lpBuffer;
- }
- /**********************************************************************************
- *** Plugin2Handler::Plugin ***
- ***********************************************************************************/
- Plugin2Handler::Plugin::Plugin(IUnknown* pContext) :
- m_lRefCount(0)
- , m_pValues(0)
- , m_pPluginDLL(0)
- , m_pContext(pContext)
- , m_bInfoNeedsRefresh(FALSE)
- , m_nPluginIndex(0)
- {
- m_pValues = new CHXHeader();
- m_pValues->AddRef();
- }
- Plugin2Handler::Plugin::~Plugin()
- {
- // Test code to look at all of the data in the map.
- #if 0
- const char* pPropName=NULL;
- IHXBuffer* pInBuffer=NULL;
- m_pValues->GetFirstPropertyCString(pPropName, pInBuffer);
- HX_RELEASE(pInBuffer);
- HX_RESULT tempresult = HXR_OK;
- while (tempresult == HXR_OK)
- {
- tempresult = m_pValues->GetNextPropertyCString(pPropName, pInBuffer);
- if (tempresult == HXR_OK)
- pInBuffer->Release();
- }
- #endif
- HX_RELEASE(m_pValues);
- HX_RELEASE(m_pPluginDLL);
- //HX_RELEASE(m_pPluginWatcher);
- }
- BOOL Plugin2Handler::Plugin::DoesMatch(IHXValues* pValues)
- {
- CHXSimpleList PossibleValues1;
- CHXSimpleList PossibleValues2;
- const char* pPropName = NULL;
- ULONG32 nInValue;
- ULONG32 nOutValue;
- IHXBuffer* pInBuffer = NULL;
- IHXBuffer* pOutBuffer = NULL;
- // Check ULONGS 1st
- if (HXR_OK == pValues->GetFirstPropertyULONG32(pPropName, nInValue))
- {
- if (HXR_OK==m_pValues->GetPropertyULONG32(pPropName, nOutValue))
- {
- if (nInValue != nOutValue)
- {
- goto notFoundexit;
- }
- }
- else
- {
- goto notFoundexit;
- }
- while (HXR_OK == pValues->GetNextPropertyULONG32(pPropName, nInValue))
- {
- if (HXR_OK == m_pValues->GetPropertyULONG32(pPropName, nOutValue))
- {
- if (nInValue != nOutValue)
- {
- goto notFoundexit;
- }
- }
- else
- {
- goto notFoundexit;
- }
- }
- }
- // Test code to look at all of the data in the map.
- #ifdef _DEBUG
- HX_RESULT tempresult;
- tempresult = HXR_OK;
- tempresult = m_pValues->GetFirstPropertyCString(pPropName, pInBuffer);
- HX_RELEASE(pInBuffer);
- while (tempresult == HXR_OK)
- {
- tempresult = m_pValues->GetNextPropertyCString(pPropName, pInBuffer);
- if (tempresult == HXR_OK)
- {
- HX_RELEASE(pInBuffer);
- }
- }
- #endif /*_DEBUG*/
- // Check String Props.
- if (HXR_OK == pValues->GetFirstPropertyCString(pPropName, pInBuffer))
- {
- if (HXR_OK == m_pValues->GetPropertyCString(pPropName, pOutBuffer))
- {
- if (!AreBufferEqual(pOutBuffer, pInBuffer))
- {
- goto notFoundexit;
- }
- }
- else
- {
- goto notFoundexit;
- }
- HX_RELEASE(pInBuffer);
- HX_RELEASE(pOutBuffer);
- while (HXR_OK == pValues->GetNextPropertyCString(pPropName, pInBuffer))
- {
- if (HXR_OK == m_pValues->GetPropertyCString(pPropName, pOutBuffer))
- {
- if ( !AreBufferEqual(pOutBuffer, pInBuffer))
- {
- goto notFoundexit;
- }
- }
- else
- {
- goto notFoundexit;
- }
- HX_RELEASE(pInBuffer);
- HX_RELEASE(pOutBuffer);
- }
- }
- // Check Buffer Properties
- if (HXR_OK == pValues->GetFirstPropertyBuffer(pPropName, pInBuffer))
- {
- // XXXND Make some utility functions for doing this...
- if (HXR_OK == m_pValues->GetPropertyBuffer(pPropName, pOutBuffer))
- {
- if( pOutBuffer->GetSize() == pInBuffer->GetSize() )
- {
- if( ::memcmp( pOutBuffer->GetBuffer(), pInBuffer->GetBuffer(), pOutBuffer->GetSize() ) )
- {
- goto notFoundexit;
- }
- }
- }
- else
- {
- goto notFoundexit;
- }
- HX_RELEASE(pInBuffer);
- HX_RELEASE(pOutBuffer);
- while (HXR_OK == pValues->GetNextPropertyBuffer(pPropName, pInBuffer))
- {
- if (HXR_OK == m_pValues->GetPropertyBuffer(pPropName, pOutBuffer))
- {
- // XXXND Make some utility functions for doing this...
- if( pOutBuffer->GetSize() == pInBuffer->GetSize() )
- {
- if( ::memcmp( pOutBuffer->GetBuffer(), pInBuffer->GetBuffer(), pOutBuffer->GetSize() ) )
- {
- goto notFoundexit;
- }
- }
- }
- else
- {
- goto notFoundexit;
- }
- HX_RELEASE(pInBuffer);
- HX_RELEASE(pOutBuffer);
- }
- }
- return TRUE; // we made it!
- notFoundexit:
- HX_RELEASE(pInBuffer);
- HX_RELEASE(pOutBuffer);
- return FALSE;
- }
- void Plugin2Handler::Plugin::SetDLL(PluginDLL * pPluginDll)
- {
- m_pPluginDLL = pPluginDll;
- m_pPluginDLL->AddRef();
- IHXBuffer* pBuffer = pPluginDll->GetFileName();
- HX_ASSERT(pBuffer);
- m_pValues->SetPropertyCString(PLUGIN_FILENAME, pBuffer);
- HX_RELEASE(pBuffer);
- }
- void Plugin2Handler::Plugin::SetIndex(UINT16 nIndex)
- {
- m_nPluginIndex = nIndex;
- m_pValues->SetPropertyULONG32(PLUGIN_INDEX, nIndex);
- }
- void Plugin2Handler::Plugin::SetPropertyULONG32(char* pName, char* pValue)
- {
- if (m_pValues)
- {
- m_pValues->SetPropertyULONG32(pName, atoi(pValue));
- }
- }
- void Plugin2Handler::Plugin::SetPropertyCString(char* pName, char* pValue)
- {
- if (m_pValues)
- {
- IHXBuffer* pTempBuffer = new CHXBuffer();
- pTempBuffer->AddRef();
- pTempBuffer->Set((UCHAR*)pValue, strlen(pValue)+1);
- m_pValues->SetPropertyCString(pName, pTempBuffer);
- HX_RELEASE(pTempBuffer);
- }
- }
- void Plugin2Handler::Plugin::SetPropertyBuffer(char* pName, BYTE* pData, UINT32 size )
- {
- if (m_pValues)
- {
- // XXXND FIX THis really shouldn't have to do this copy
- IHXBuffer* pTempBuffer = new CHXBuffer();
- pTempBuffer->AddRef();
- pTempBuffer->Set( pData, size );
- m_pValues->SetPropertyBuffer(pName, pTempBuffer);
- HX_RELEASE(pTempBuffer);
- }
- }
- HX_RESULT Plugin2Handler::Plugin::WritePref2(REF(CPluginInfoWriter) piw)
- {
- /* format of data in regestry is as follows:
- * {ValueName~ N|S|BValue~ ValueName~ N|S|B~ ValueName~ N|S|B~ etc},
- * {etc}
- */
- // check to see if the DLL we are associated with still exists
- if (!m_pPluginDLL->DoesExist())
- {
- piw.Write("");
- return HXR_OK;
- }
- piw.Write("{");
- BOOL bFirst = TRUE;
- // Write out data...
- char szScratchPad[100]; /* Flawfinder: ignore */
- const char* pPropertyName;
- ULONG32 uPropertyValue;
- IHXBuffer* pBuffer;
- if(HXR_OK == m_pValues->GetFirstPropertyULONG32(pPropertyName, uPropertyValue))
- {
- if (!bFirst)
- {
- piw.Write("~");
- }
- else
- {
- bFirst = FALSE;
- }
- piw.Write(pPropertyName);
- itoa(uPropertyValue, szScratchPad, 10);
- piw.Write("~N");
- piw.Write(szScratchPad);
- while (HXR_OK == m_pValues->GetNextPropertyULONG32(pPropertyName, uPropertyValue))
- {
- if (!bFirst)
- {
- piw.Write("~");
- }
- else
- {
- bFirst = FALSE;
- }
- piw.Write(pPropertyName);
- itoa(uPropertyValue, szScratchPad, 10);
- piw.Write("~N");
- piw.Write(szScratchPad);
- }
- }
- if (HXR_OK == m_pValues->GetFirstPropertyCString(pPropertyName, pBuffer))
- {
- /* add a S to the begining for CString */
- if (!bFirst)
- {
- piw.Write("~");
- }
- else
- {
- bFirst = FALSE;
- }
- piw.Write(pPropertyName);
- piw.Write("~S");
- piw.Write((const char*) pBuffer->GetBuffer());
- HX_RELEASE(pBuffer);
- while (HXR_OK == m_pValues->GetNextPropertyCString(pPropertyName, pBuffer))
- {
- if (!bFirst)
- {
- piw.Write("~");
- }
- else
- {
- bFirst = FALSE;
- }
- piw.Write(pPropertyName);
- piw.Write("~S");
- piw.Write((const char*) pBuffer->GetBuffer());
- HX_RELEASE(pBuffer);
- }
- }
- if (HXR_OK == m_pValues->GetFirstPropertyBuffer(pPropertyName, pBuffer))
- {
- UINT32 size = 0;
- CHXBuffer *pBuf = NULL;
- /* add a B to the begining for Buffer */
- if (!bFirst)
- {
- piw.Write("~");
- }
- else
- {
- bFirst = FALSE;
- }
- piw.Write(pPropertyName);
- // XXXND This is for backwards compatibility
- if( GetDLL()->GetMountPoint()->IsHXCompliant() )
- {
- piw.Write("~B");
- CHXString tmp((const char*) pBuffer->GetBuffer(), pBuffer->GetSize());
- piw.Write( tmp );
- }
- else
- {
- size = pBuffer->GetSize();
- pBuf = new CHXBuffer();
- HX_ASSERT(pBuf);
- pBuf->AddRef();
- pBuf->SetSize(size * 2);
- INT32 s = BinTo64(pBuffer->GetBuffer(), size, (char *)pBuf->GetBuffer());
- HX_ASSERT(size * 2 >= (UINT32)s);
- // Write out data. s includes the NULL byte.
- piw.Write("~X");
- piw.Write( (const char*) pBuf->GetBuffer(), s - 1 );
- }
- HX_RELEASE(pBuffer);
- HX_RELEASE(pBuf);
- while (HXR_OK == m_pValues->GetNextPropertyBuffer(pPropertyName, pBuffer))
- {
- if (!bFirst)
- {
- piw.Write("~");
- }
- else
- {
- bFirst = FALSE;
- }
- piw.Write(pPropertyName);
- // XXXND This is for backwards compatibility
- if( GetDLL()->GetMountPoint()->IsHXCompliant() )
- {
- piw.Write("~B");
- CHXString tmp((const char*) pBuffer->GetBuffer(), pBuffer->GetSize());
- piw.Write( tmp );
- }
- else
- {
- size = pBuffer->GetSize();
- pBuf = new CHXBuffer();
- HX_ASSERT(pBuf);
- pBuf->AddRef();
- pBuf->SetSize(size * 2);
- INT32 s = BinTo64(pBuffer->GetBuffer(), size, (char *)pBuf->GetBuffer());
- HX_ASSERT(size * 2 >= (UINT32)s);
- // Write out data. s includes the NULL byte.
- piw.Write("~X");
- piw.Write( (const char*) pBuf->GetBuffer(), s - 1 );
- }
- HX_RELEASE(pBuffer);
- HX_RELEASE(pBuf);
- }
- }
- piw.Write("}");
- return HXR_OK;
- }
- HX_RESULT Plugin2Handler::Plugin::WritePref(PreferenceEnumerator* pPrefEnumParam)
- {
- PreferenceEnumerator* pPrefEnum = (PreferenceEnumerator*)pPrefEnumParam;
- const char* pPropertyName=NULL;
- ULONG32 uPropertyValue;
- IHXBuffer* pBuffer=NULL;
- IHXBuffer* pOutBuffer=NULL;
- char pPrefValue[(1<<8)]; /* Flawfinder: ignore */
- pOutBuffer = new CHXBuffer();
- pOutBuffer->AddRef();
- if (HXR_OK == m_pValues->GetFirstPropertyULONG32(pPropertyName, uPropertyValue))
- {
- /* add a N to the begining for Number */
- sprintf(pPrefValue, "N%d", (int) uPropertyValue); /* Flawfinder: ignore */
- pOutBuffer->Set((UCHAR*)pPrefValue, strlen(pPrefValue)+1);
- pPrefEnum->WriteSubPref(pPropertyName, pOutBuffer);
- while (HXR_OK == m_pValues->GetNextPropertyULONG32(pPropertyName, uPropertyValue))
- {
- sprintf(pPrefValue, "N%d", (int)uPropertyValue); /* Flawfinder: ignore */
- pOutBuffer->Set((UCHAR*)pPrefValue, strlen(pPrefValue)+1);
- pPrefEnum->WriteSubPref(pPropertyName, pOutBuffer);
- }
- }
- HX_RELEASE(pOutBuffer);
- if (HXR_OK == m_pValues->GetFirstPropertyCString(pPropertyName, pBuffer))
- {
- /* add a S to the begining for CString */
- CHXString NewString = "S";
- NewString += (char*) pBuffer->GetBuffer();
- IHXBuffer* pTempBuffer = new CHXBuffer();
- pTempBuffer->AddRef();
- pTempBuffer->Set((UCHAR*)(const char*)NewString, NewString.GetLength()+1);
- pPrefEnum->WriteSubPref(pPropertyName, pTempBuffer);
- HX_RELEASE(pBuffer);
- HX_RELEASE(pTempBuffer);
- while (HXR_OK == m_pValues->GetNextPropertyCString(pPropertyName, pBuffer))
- {
- NewString = "S";
- NewString += (char*) pBuffer->GetBuffer();
- pTempBuffer = new CHXBuffer();
- pTempBuffer->AddRef();
- pTempBuffer->Set((UCHAR*)(const char*)NewString, NewString.GetLength()+1);
- pPrefEnum->WriteSubPref(pPropertyName, pTempBuffer);
- HX_RELEASE(pTempBuffer);
- HX_RELEASE(pBuffer);
- }
- }
- if (HXR_OK == m_pValues->GetFirstPropertyBuffer(pPropertyName, pBuffer))
- {
- /* add a B to the begining for Buffer -- although someone would have to have rocks in
- his head if he attempted to write a buffer to the reg...
- */
- UCHAR* pTempChar = new UCHAR[pBuffer->GetSize()+2];
- *pTempChar='B';
- memcpy(pTempChar+1, pBuffer->GetBuffer(), pBuffer->GetSize()); /* Flawfinder: ignore */
- *(pTempChar+pBuffer->GetSize()+1) = 0;
- IHXBuffer* pTempBuffer = new CHXBuffer();
- pTempBuffer->AddRef();
- pTempBuffer->Set(pTempChar, pBuffer->GetSize()+2);
- delete[] pTempChar;
- pPrefEnum->WriteSubPref(pPropertyName, pTempBuffer);
- HX_RELEASE(pBuffer);
- HX_RELEASE(pTempBuffer);
- while (HXR_OK == m_pValues->GetNextPropertyBuffer(pPropertyName, pBuffer))
- {
- pTempChar = new UCHAR[pBuffer->GetSize()+2];
- *pTempChar='B';
- memcpy(pTempChar+1, pBuffer->GetBuffer(), pBuffer->GetSize()); /* Flawfinder: ignore */
- *(pTempChar+pBuffer->GetSize()+1) = 0;
- pTempBuffer = new CHXBuffer();
- pTempBuffer->AddRef();
- pTempBuffer->Set(pTempChar, pBuffer->GetSize()+2);
- delete[] pTempChar;
- pPrefEnum->WriteSubPref(pPropertyName, pTempBuffer);
- HX_RELEASE(pBuffer);
- HX_RELEASE(pTempBuffer);
- }
- }
- return HXR_OK;
- }
- HX_RESULT Plugin2Handler::Plugin::ReadPref(PreferenceEnumerator* pPrefEnum)
- {
- UINT32 nIndex = 0;
- IHXBuffer* pPropName = 0;
- IHXBuffer* pBuffer = 0;
- // this function assumes that the enumerator has been properly set up before it is
- // called.
- while (HXR_OK == pPrefEnum->GetPrefKey(nIndex, pPropName))
- {
- if (!strcmp((char*)pPropName->GetBuffer(), zm_pszKeyNameRegKey))
- {
- HX_RELEASE(pPropName);
- nIndex++;
- continue;
- }
- pPrefEnum->ReadPref((const char*)pPropName->GetBuffer(), pBuffer);
- char* pCharBuffer = (char*)pBuffer->GetBuffer();
- switch (*pCharBuffer)
- {
- case 'N':
- {
- m_pValues->SetPropertyULONG32((const char*)pPropName->GetBuffer(), atoi(pCharBuffer+1));
- break;
- }
- case 'S':
- {
- IHXBuffer* pTempBuffer = new CHXBuffer();
- pTempBuffer->AddRef();
- pTempBuffer->Set(pBuffer->GetBuffer()+1, pBuffer->GetSize()-1);
- m_pValues->SetPropertyCString((const char*)pPropName->GetBuffer(), pTempBuffer);
- pTempBuffer->Release();
- break;
- }
- case 'B':
- {
- CHXBuffer *pBuf = new CHXBuffer();
- HX_ASSERT(pBuf);
- pBuf->AddRef();
- pBuf->Set(pBuffer->GetBuffer()+1, pBuffer->GetSize()-1);
- m_pValues->SetPropertyBuffer((const char*)pPropName->GetBuffer(), pBuf );
- HX_RELEASE(pBuf);
- break;
- }
- case 'X':
- {
- CHXBuffer *pBuf = new CHXBuffer();
- HX_ASSERT(pBuf);
- pBuf->AddRef();
- UINT32 size = pBuffer->GetSize();
- pBuf->SetSize(size);
- // We subtract 2 from size - one for NULL terminator and 1 because we move foward in the buffer by 1
- INT32 s = BinFrom64((char *)pBuffer->GetBuffer()+1, size - 2, pBuf->GetBuffer());
- HX_ASSERT(s != -1);
- HX_ASSERT((UINT32) s <= size);
- m_pValues->SetPropertyBuffer((const char*)pPropName->GetBuffer(), pBuf);
- HX_RELEASE(pBuf);
- break;
- }
- }
- HX_RELEASE(pBuffer);
- HX_RELEASE(pPropName);
- nIndex++;
- }
- ULONG32 nTemp;
- if (HXR_OK == m_pValues->GetPropertyULONG32(PLUGIN_INDEX, nTemp))
- {
- m_nPluginIndex = (UINT16) nTemp;
- }
- return HXR_OK;
- }
- BOOL Plugin2Handler::Plugin::AreBufferEqual(IHXBuffer* pBigBuff,
- IHXBuffer* pSmallBuff)
- {
- char* pTemp;
- BOOL bRetVal = FALSE;
- pTemp = new char[pBigBuff->GetSize()];
- SafeStrCpy(pTemp, (char*)pBigBuff->GetBuffer(), pBigBuff->GetSize());
- char* token;
- token = strtok(pTemp, zm_pszValueSeperator);
- while (token)
- {
- CHXString tokenCHXstring;
- CHXString smallCHXstring;
- tokenCHXstring = token;
- smallCHXstring = (char*)pSmallBuff->GetBuffer();
- tokenCHXstring.TrimLeft();
- tokenCHXstring.TrimRight();
- smallCHXstring.TrimLeft();
- smallCHXstring.TrimRight();
- if (!strcasecmp(tokenCHXstring, smallCHXstring))
- {
- bRetVal = TRUE;
- break;
- }
- token = strtok(NULL, zm_pszValueSeperator);
- }
- delete[] pTemp;
- return bRetVal;
- }
- Plugin2Handler::Errors Plugin2Handler::Plugin::GetValuesFromDLL(IHXPlugin* pHXPlugin)
- {
- Plugin2Handler::Errors retVal;
- retVal = GetBasicValues(pHXPlugin);
- if (retVal == NO_ERRORS)
- {
- retVal = GetExtendedValues(pHXPlugin);
- }
- return retVal;
- }
- Plugin2Handler::Errors Plugin2Handler::Plugin::GetPlugin(REF(IUnknown*) pUnknown )
- {
- pUnknown = NULL;
- Plugin2Handler::Errors retVal = NO_ERRORS;
- if (!m_pPluginDLL)
- {
- return PLUGIN_NOT_FOUND;
- }
- if (!m_pPluginDLL->IsLoaded())
- {
- if (NO_ERRORS != (retVal = m_pPluginDLL->Load(m_pContext)))
- {
- return retVal;
- }
- }
- if (HXR_OK != m_pPluginDLL->CreateInstance(&pUnknown, m_nPluginIndex))
- {
- return CREATE_INSTANCHXR_FAILURE;
- }
- // CreateWatcher(pUnknown); //XXXAH the watcher is no longer being used
- return retVal;
- }
- Plugin2Handler::Errors Plugin2Handler::Plugin::GetInstance(REF(IUnknown*) pUnknown, IUnknown* pIUnkOuter )
- {
- // Initialize out parameter
- pUnknown = NULL;
- IUnknown* pIUnkPlugin = NULL;
- Plugin2Handler::Errors retVal = GetPlugin( pIUnkPlugin );
- if( retVal == NO_ERRORS )
- {
- IHXComponentPlugin* pIComp = NULL;
- if( SUCCEEDED( pIUnkPlugin->QueryInterface( IID_IHXComponentPlugin, (void**) &pIComp ) ) )
- {
- // Ask for the correct object by CLSID
- IHXBuffer* pCLSID = NULL;
- if( SUCCEEDED( m_pValues->GetPropertyBuffer( PLUGIN_COMPONENT_CLSID, pCLSID ) ) )
- {
- if( FAILED( pIComp->CreateComponentInstance( *(GUID*) pCLSID->GetBuffer(), pUnknown, pIUnkOuter ) ) )
- {
- retVal = CREATE_INSTANCHXR_FAILURE;
- }
- HX_RELEASE( pCLSID );
- }
- else
- {
- // Hmmm...we have a component plugin without a CLSID. Serious internal error
- retVal = BAD_PLUGIN;
- }
- // Release the interface, and destroy the plugin
- HX_RELEASE( pIComp );
- HX_RELEASE( pIUnkPlugin );
- }
- else
- {
- // If this isn't a component plugin, then we can't aggregate anything
- if( pIUnkOuter )
- {
- HX_RELEASE( pIUnkPlugin );
- retVal = AGGREGATION_NOT_SUPPORTED;
- }
- else
- {
- pUnknown = pIUnkPlugin;
- }
- }
- }
- return retVal;
- }
- STDMETHODIMP Plugin2Handler::Plugin::AllObjectsDeleted (void*)
- {
- //HX_RELEASE(m_pPluginWatcher);
- //m_pPluginWatcher = 0;
- m_pPluginDLL->ReleaseDLLReference();
- return HXR_OK;
- }
- Plugin2Handler::Errors
- Plugin2Handler::Plugin::CreateWatcher(IUnknown* pUnknown)
- {
- return NO_ERRORS; //XXXAH the watcher is no longer being used
- #if 0
- if (!m_pPluginWatcher)
- {
- IHXPluginWatcherResponse* pWatcherResp;
- // QueryInterface(IID_IHXPluginWatcherResponse, (void**)&pWatcherResp); // causes the build to break
- m_pPluginWatcher = new PluginMonitor(pUnknown, pWatcherResp);
- m_pPluginWatcher->AddRef();
- HX_ASSERT(m_pPluginDLL); // Huh?
- m_pPluginDLL->AddDLLReference();
- }
- return NO_ERRORS;
- #endif
- }
- BOOL Plugin2Handler::Plugin::IsLoaded()
- {
- if (!m_pPluginDLL)
- return FALSE;
- return m_pPluginDLL->IsLoaded();
- }
- HX_RESULT Plugin2Handler::Plugin::GetPluginInfo(REF(IHXValues*) pVals)
- {
- if (m_pValues)
- {
- pVals = m_pValues;
- return HXR_OK;
- }
- pVals = NULL;
- return HXR_FAIL;
- }
- IHXBuffer* Plugin2Handler::Plugin::GetFileName()
- {
- IHXBuffer* retVal = NULL;
- // Get the filename from m_pValues. We can't get it from the DLL,
- // because we may be in the process of loading, and we just got it
- // from the preferences
- if( m_pValues )
- {
- m_pValues->GetPropertyCString( PLUGIN_FILENAME, retVal );
- }
- return retVal;
- }
- Plugin2Handler::Errors
- Plugin2Handler::Plugin::GetBasicValues(IHXPlugin* pHXPlugin)
- {
- const char* pszDescription = NULL;
- const char* pszCopyright = NULL;
- const char* pszMoreInfoUrl = NULL;
- ULONG32 ulVersionNumber = 0;
- BOOL nload_multiple = 0;
- if (HXR_OK != pHXPlugin->GetPluginInfo(nload_multiple, pszDescription,
- pszCopyright, pszMoreInfoUrl, ulVersionNumber))
- {
- return BAD_PLUGIN;
- }
- IHXBuffer* pBuffer = NULL;
- CHXBuffer* pCHXBuffer = new CHXBuffer();
- pCHXBuffer->QueryInterface(IID_IHXBuffer,(void**) &pBuffer);
- if (pszDescription)
- {
- pBuffer->Set((UCHAR*)pszDescription, strlen(pszDescription)+1);
- }
- m_pValues->SetPropertyCString(PLUGIN_DESCRIPTION2, pBuffer);
- pBuffer->Release();
- pCHXBuffer = new CHXBuffer();
- pCHXBuffer->QueryInterface(IID_IHXBuffer,(void**) &pBuffer);
- if (pszCopyright)
- {
- pBuffer->Set((UCHAR*)pszCopyright, strlen(pszCopyright)+1);
- }
- m_pValues->SetPropertyCString(PLUGIN_COPYRIGHT2, pBuffer);
- pBuffer->Release();
- pCHXBuffer = new CHXBuffer();
- pCHXBuffer->QueryInterface(IID_IHXBuffer,(void**) &pBuffer);
- if (pszMoreInfoUrl)
- {
- pBuffer->Set((UCHAR*)pszMoreInfoUrl, strlen(pszMoreInfoUrl)+1);
- }
- m_pValues->SetPropertyCString(PLUGIN_COPYRIGHT, pBuffer);
- pBuffer->Release();
- m_pValues->SetPropertyULONG32(PLUGIN_LOADMULTIPLE, nload_multiple);
- m_pValues->SetPropertyULONG32(PLUGIN_VERSION, ulVersionNumber);
- return NO_ERRORS;
- }
- Plugin2Handler::Errors
- Plugin2Handler::Plugin::GetExtendedValues(IHXPlugin* pHXPlugin)
- {
- // Errors result = NO_ERRORS;
- IHXFileFormatObject* pFileFormat = NULL;
- // IHXMetaFileFormatObject* pMetaFileFormat = NULL;
- IHXFileWriter* pFileWriter = NULL;
- IHXBroadcastFormatObject* pBroadcastFormat = NULL;
- IHXFileSystemObject* pFileSystem = NULL;
- IHXRenderer* pRenderer = NULL;
- IHXDataRevert* pDataRevert = NULL;
- IHXStreamDescription* pStreamDescription = NULL;
- IHXPlayerConnectionAdviseSink* pAllowanceFormat = NULL;
- IHXCommonClassFactory* pClassFactory = NULL;
- IHXPluginProperties* pIHXPluginPropertiesThis = NULL;
- UINT32 nCountInterfaces = 0;
- // file system
- if (HXR_OK == pHXPlugin->QueryInterface(IID_IHXFileSystemObject, (void**) &pFileSystem))
- {
- const char* pszShortName;
- const char* pszProtocol;
- if (HXR_OK != pFileSystem->GetFileSystemInfo(pszShortName, pszProtocol))
- {
- HX_RELEASE (pFileSystem);
- return CANT_GET_RENDERER_INFO; //XXXAH Cleanup?
- }
- IHXBuffer* pBuffer = NULL;
- CHXBuffer* pCHXBuffer = new CHXBuffer();
- pCHXBuffer->QueryInterface(IID_IHXBuffer,(void**) &pBuffer);
- pBuffer->Set((UCHAR*)PLUGIN_FILESYSTEM_TYPE, strlen(PLUGIN_FILESYSTEM_TYPE)+1);
- m_pValues->SetPropertyCString(PLUGIN_CLASS, pBuffer);
- pBuffer->Release();
- pCHXBuffer = new CHXBuffer();
- pCHXBuffer->QueryInterface(IID_IHXBuffer,(void**) &pBuffer);
- if (pszShortName)
- {
- pBuffer->Set((UCHAR*)pszShortName, strlen(pszShortName)+1);
- }
- m_pValues->SetPropertyCString(PLUGIN_FILESYSTEMSHORT, pBuffer);
- pBuffer->Release();
- pCHXBuffer = new CHXBuffer();
- pCHXBuffer->QueryInterface(IID_IHXBuffer,(void**) &pBuffer);
- if (pszProtocol)
- {
- pBuffer->Set((UCHAR*)pszProtocol, strlen(pszProtocol)+1);
- }
- m_pValues->SetPropertyCString(PLUGIN_FILESYSTEMPROTOCOL, pBuffer);
- pBuffer->Release();
- pFileSystem->Release();
- nCountInterfaces++;
- }
- // file format
- if (HXR_OK == pHXPlugin->QueryInterface(IID_IHXFileFormatObject, (void**)&pFileFormat) ||
- HXR_OK == pHXPlugin->QueryInterface(IID_IHXFileWriter, (void**)&pFileWriter))
- {
- // fine we are in now we will get the correct type.
- if (pFileFormat)
- {
- pFileFormat->Release();
- }
- else
- {
- pFileWriter->Release();
- }
- const char** ppszMimeTypes = NULL;
- const char** ppszExtensions = NULL;
- const char** ppszOpenNames = NULL;
- if (HXR_OK == pHXPlugin->QueryInterface(IID_IHXFileFormatObject, (void**)&pFileFormat))
- {
- pFileFormat->GetFileFormatInfo( ppszMimeTypes,
- ppszExtensions,
- ppszOpenNames);
- pFileFormat->Release();
- IHXBuffer* pBuffer = NULL;
- CHXBuffer* pCHXBuffer = new CHXBuffer();
- pCHXBuffer->QueryInterface(IID_IHXBuffer,(void**) &pBuffer);
- pBuffer->Set((UCHAR*)PLUGIN_FILEFORMAT_TYPE, strlen(PLUGIN_FILEFORMAT_TYPE)+1);
- m_pValues->SetPropertyCString(PLUGIN_CLASS, pBuffer);
- pBuffer->Release();
- }
- if (HXR_OK == pHXPlugin->QueryInterface(IID_IHXFileWriter, (void**)&pFileWriter))
- {
- pFileWriter->GetFileFormatInfo( ppszMimeTypes,
- ppszExtensions,
- ppszOpenNames);
- pFileWriter->Release();
- IHXBuffer* pBuffer = NULL;
- CHXBuffer* pCHXBuffer = new CHXBuffer();
- pCHXBuffer->QueryInterface(IID_IHXBuffer,(void**) &pBuffer);
- pBuffer->Set((UCHAR*)PLUGIN_FILEWRITER_TYPE, strlen(PLUGIN_FILEWRITER_TYPE)+1);
- m_pValues->SetPropertyCString(PLUGIN_CLASS, pBuffer);
- pBuffer->Release();
- }
- IHXBuffer* pBuffer = NULL;
- if (ppszMimeTypes)
- {
- CatStrings((char**)ppszMimeTypes, pBuffer); //XXXAH this had better be const in reality!
- m_pValues->SetPropertyCString(PLUGIN_FILEMIMETYPES, pBuffer);
- pBuffer->Release();
- }
- if (ppszExtensions)
- {
- CatStrings((char**)ppszExtensions, pBuffer); //XXXAH this had better be const in reality!
- m_pValues->SetPropertyCString(PLUGIN_FILEEXTENSIONS, pBuffer);
- pBuffer->Release();
- }
- if (ppszOpenNames)
- {
- CatStrings((char**)ppszOpenNames, pBuffer); //XXXAH this had better be const in reality!
- m_pValues->SetPropertyCString(PLUGIN_FILEOPENNAMES, pBuffer);
- pBuffer->Release();
- }
- nCountInterfaces++;
- }
- // renderer
- if (HXR_OK == pHXPlugin->QueryInterface(IID_IHXRenderer, (void**)&pRenderer))
- {
- char** ppszMimeTypes;
- UINT32 initial_granularity = 0;
- // get the basic info
- if (HXR_OK == pRenderer->GetRendererInfo((const char**&)ppszMimeTypes, initial_granularity))
- {
- IHXBuffer* pBuffer;
- if (ppszMimeTypes)
- {
- CatStrings(ppszMimeTypes, pBuffer);
- }
- m_pValues->SetPropertyCString(PLUGIN_RENDERER_MIME, pBuffer);
- pBuffer->Release();
- m_pValues->SetPropertyULONG32(PLUGIN_RENDERER_GRANULARITY, initial_granularity);
- CHXBuffer* pCHXBuffer = new CHXBuffer();
- pCHXBuffer->QueryInterface(IID_IHXBuffer,(void**) &pBuffer);
- pBuffer->Set((UCHAR*)PLUGIN_RENDERER_TYPE, strlen(PLUGIN_RENDERER_TYPE)+1);
- m_pValues->SetPropertyCString(PLUGIN_CLASS, pBuffer);
- pBuffer->Release();
- }
- HX_RELEASE(pRenderer);
- nCountInterfaces++;
- }
- //data revert
- if (HXR_OK == pHXPlugin->QueryInterface(IID_IHXDataRevert, (void**)&pDataRevert))
- {
- char** ppConversionTypes;
- if (HXR_OK == pDataRevert->GetDataRevertInfo((const char**&)ppConversionTypes))
- {
- IHXBuffer* pBuffer;
- CatStrings(ppConversionTypes, pBuffer);
- m_pValues->SetPropertyCString(PLUGIN_REVERTER_MIME, pBuffer);
- pBuffer->Release();
- CHXBuffer* pCHXBuffer = new CHXBuffer();
- pCHXBuffer->QueryInterface(IID_IHXBuffer,(void**) &pBuffer);
- pBuffer->Set((UCHAR*)PLUGIN_REVERTER_TYPE, strlen(PLUGIN_REVERTER_TYPE) + 1);
- m_pValues->SetPropertyCString(PLUGIN_CLASS, pBuffer);
- pBuffer->Release();
- }
- HX_RELEASE(pDataRevert);
- nCountInterfaces++;
- }
- // broadcast
- if (HXR_OK == pHXPlugin->QueryInterface(IID_IHXBroadcastFormatObject, (void**)&pBroadcastFormat))
- {
- const char* pszBroadcastType;
- IHXBuffer * pBuffer;
- if (HXR_OK != pBroadcastFormat->GetBroadcastFormatInfo(pszBroadcastType))
- {
- HX_RELEASE (pBroadcastFormat);
- return CANT_GET_FILE_FORMAT_INFO; //XXXAH Cleanup?
- }
- pBroadcastFormat->Release();
- CHXBuffer* pCHXBuffer = new CHXBuffer();
- pCHXBuffer->QueryInterface(IID_IHXBuffer,(void**) &pBuffer);
- if (pszBroadcastType)
- {
- pBuffer->Set((UCHAR*)pszBroadcastType, strlen(pszBroadcastType)+1);
- }
- m_pValues->SetPropertyCString(PLUGIN_BROADCASTTYPE, pBuffer);
- pBuffer->Release();
- pCHXBuffer = new CHXBuffer();
- pCHXBuffer->QueryInterface(IID_IHXBuffer,(void**) &pBuffer);
- pBuffer->Set((UCHAR*)PLUGIN_BROADCAST_TYPE, strlen(PLUGIN_BROADCAST_TYPE)+1);
- m_pValues->SetPropertyCString(PLUGIN_CLASS, pBuffer);
- pBuffer->Release();
- nCountInterfaces++;
- }
- // stream description
- if (HXR_OK == pHXPlugin->QueryInterface(IID_IHXStreamDescription, (void**)&pStreamDescription))
- {
- const char* pszMimeType;
- IHXBuffer* pBuffer;
- if (HXR_OK != pStreamDescription->GetStreamDescriptionInfo(pszMimeType))
- {
- HX_RELEASE (pStreamDescription);
- return CANT_GET_FILE_FORMAT_INFO; // XXXAH Cleanup?
- }
- pStreamDescription->Release();
- CHXBuffer* pCHXBuffer = new CHXBuffer();
- pCHXBuffer->QueryInterface(IID_IHXBuffer,(void**) &pBuffer);
- if (pszMimeType)
- {
- pBuffer->Set((UCHAR*)pszMimeType, strlen(pszMimeType)+1);
- }
- m_pValues->SetPropertyCString(PLUGIN_STREAMDESCRIPTION, pBuffer);
- pBuffer->Release();
- // IUnknown* pUnk = NULL;
- pCHXBuffer = new CHXBuffer();
- pCHXBuffer->QueryInterface(IID_IHXBuffer,(void**) &pBuffer);
- pBuffer->Set((UCHAR*)PLUGIN_STREAM_DESC_TYPE, strlen(PLUGIN_STREAM_DESC_TYPE)+1);
- m_pValues->SetPropertyCString(PLUGIN_CLASS, pBuffer);
- pBuffer->Release();
- nCountInterfaces++;
- }
- // allowance
- if ( (HXR_OK == pHXPlugin->QueryInterface(IID_IHXPlayerConnectionAdviseSinkManager, (void**)&pAllowanceFormat)) ||
- (HXR_OK == pHXPlugin->QueryInterface(IID_IHXPlayerConnectionAdviseSink, (void**)&pAllowanceFormat)) )
- {
- IHXBuffer* pBuffer = NULL;
- CHXBuffer* pCHXBuffer = new CHXBuffer();
- pCHXBuffer->QueryInterface(IID_IHXBuffer,(void**) &pBuffer);
- pBuffer->Set((UCHAR*)PLUGIN_ALLOWANCE_TYPE, strlen(PLUGIN_ALLOWANCE_TYPE)+1);
- m_pValues->SetPropertyCString(PLUGIN_CLASS, pBuffer);
- pBuffer->Release();
- pAllowanceFormat->Release();
- nCountInterfaces++;
- }
- // common class factory
- if(HXR_OK == pHXPlugin->QueryInterface(IID_IHXCommonClassFactory,
- (void**)&pClassFactory))
- {
- IHXBuffer* pBuffer = NULL;
- CHXBuffer* pCHXBuffer = new CHXBuffer();
- pCHXBuffer->QueryInterface(IID_IHXBuffer,(void**) &pBuffer);
- pBuffer->Set((UCHAR*)PLUGIN_CLASS_FACTORY_TYPE, strlen(PLUGIN_CLASS_FACTORY_TYPE)+1);
- m_pValues->SetPropertyCString(PLUGIN_CLASS, pBuffer);
- pBuffer->Release();
- HX_RELEASE (pClassFactory);
- nCountInterfaces++;
- }
- // NO MORE NEW PLUGIN INFORMATION INTERFACES!!!!
- //
- // THIS IS THE LAST ONE!!!!!
- if( SUCCEEDED( pHXPlugin->QueryInterface( IID_IHXPluginProperties, (void**)&pIHXPluginPropertiesThis ) ) )
- {
- IHXValues* pIHXValuesProperties = NULL;
- pHXPlugin->InitPlugin(m_pContext);
- if( SUCCEEDED( pIHXPluginPropertiesThis->GetProperties( pIHXValuesProperties ) ) && pIHXValuesProperties )
- {
- CHXHeader::mergeHeaders( m_pValues, pIHXValuesProperties );
- }
- HX_RELEASE(pIHXValuesProperties);
- // XXXkshoop Let this coincide with other interfaces.. for now..
- //nCountInterfaces++;
- }
- HX_RELEASE(pIHXPluginPropertiesThis);
- HX_ASSERT(nCountInterfaces<2);
- return NO_ERRORS;
- }
- HX_RESULT Plugin2Handler::Plugin::GetBandwidthInfo()
- {
- IHXPlugin* pHXPlugin;
- IUnknown* pUnk;
- if (HXR_OK != GetInstance(pUnk))
- {
- return HXR_FAIL;
- }
- if (HXR_OK != pUnk->QueryInterface(IID_IHXPlugin, (void**)& pHXPlugin))
- {
- return HXR_FAIL;
- }
- HX_RELEASE(pUnk);
- pHXPlugin->InitPlugin(m_pContext);
- IHXBandwidthLister* bandwidth_lister;
- if(HXR_OK == pHXPlugin->QueryInterface(IID_IHXBandwidthLister,
- (void**)&bandwidth_lister))
- {
- IHXValues* pValues;
- pValues = new CHXHeader();
- pValues->AddRef();
- if(HXR_OK == bandwidth_lister->GetBandwidthInfo(pValues))
- {
- // now that we have these new values we must transcribe them to the
- // m_pValues.
- const char* pValueName;
- ULONG32 nPropValue;
- IHXBuffer* pPropValue;
- if (HXR_OK == pValues->GetFirstPropertyULONG32(pValueName, nPropValue))
- {
- m_pValues->SetPropertyULONG32(pValueName, nPropValue);
- while (HXR_OK == pValues->GetNextPropertyULONG32(pValueName, nPropValue))
- {
- m_pValues->SetPropertyULONG32(pValueName, nPropValue);
- }
- }
- if (HXR_OK == pValues->GetFirstPropertyBuffer(pValueName, pPropValue))
- {
- m_pValues->SetPropertyBuffer(pValueName, pPropValue);
- pPropValue->Release();
- while (HXR_OK == pValues->GetNextPropertyBuffer(pValueName, pPropValue))
- {
- m_pValues->SetPropertyBuffer(pValueName, pPropValue);
- pPropValue->Release();
- }
- }
- if (HXR_OK == pValues->GetFirstPropertyCString(pValueName, pPropValue))
- {
- m_pValues->SetPropertyCString(pValueName, pPropValue);
- pPropValue->Release();
- while (HXR_OK == pValues->GetNextPropertyCString(pValueName, pPropValue))
- {
- m_pValues->SetPropertyCString(pValueName, pPropValue);
- pPropValue->Release();
- }
- }
- }
- HX_RELEASE(bandwidth_lister);
- HX_RELEASE(pValues);
- HX_RELEASE(pHXPlugin);
- m_bInfoNeedsRefresh = FALSE;
- return HXR_OK;
- }
- HX_RELEASE(pHXPlugin);
- return HXR_FAIL;
- }
- void Plugin2Handler::Plugin::InitializeComponentPlugin( IHXPlugin* pIPlugin, IHXValues* pIValues )
- {
- // Setup basic data
- // XXXHP - this is unnecessary information as it is stored on a PER COMPONENT not PER PLUGIN basis in this case.
- // GetBasicValues( pIPlugin );
- // Copy data from pIValues
- CHXHeader::mergeHeaders( m_pValues, pIValues );
- }
- HX_RESULT Plugin2Handler::Plugin::CatStrings(char** pInStrings,
- REF(IHXBuffer*) pOutBuffer)
- {
- ULONG32 nAllocedSpace = 100;
- char* ptemp = new char[nAllocedSpace];
- char* ptemp2 = NULL;
- ULONG32 nStrLen = 0;
- ULONG32 nNewStrLen = 0;
- *ptemp = 0;
- pOutBuffer = 0;
- for(; *pInStrings; pInStrings++)
- {
- nNewStrLen = strlen(*pInStrings);
- if (nNewStrLen+ nStrLen >= nAllocedSpace)
- {
- // double if the new string is less than the new space
- // or add double what it required.
- if (nNewStrLen< nAllocedSpace)
- {
- nAllocedSpace*=2;
- }
- else
- {
- nAllocedSpace+=nNewStrLen*2;
- }
- ptemp2 = new char[nAllocedSpace];
- memcpy(ptemp2, ptemp, nStrLen+1); /* Flawfinder: ignore */
- delete [] ptemp;
- ptemp = ptemp2;
- }
- // XXXAH I must trim the strings before I add them to this string.
- // the find function DEPENDS UPON THIS.
- SafeStrCat(ptemp, *pInStrings, nAllocedSpace);
- if (*(pInStrings+1))
- {
- SafeStrCat(ptemp, Plugin2Handler::zm_pszValueSeperator, nAllocedSpace); // XXXAH Perhaps a define?
- }
- nStrLen+=nNewStrLen+1;
- }
- CHXBuffer* pCHXBuffer = new CHXBuffer();
- pCHXBuffer->QueryInterface(IID_IHXBuffer,(void**) &pOutBuffer);
- pOutBuffer->Set((UCHAR*)ptemp, strlen(ptemp)+1);
- delete[] ptemp;
- return HXR_OK;
- }
- HX_RESULT Plugin2Handler::Plugin::CatPropertiesULONG32(REF(IHXBuffer*) pBuffer,
- const char* pPropName,
- ULONG32 nValue)
- {
- CHXString NewString;
- const char* pchar;
- ULONG32 nLen;
- if (pBuffer)
- {
- pBuffer->Get((UCHAR*&)pchar, nLen);
- NewString=pchar;
- pBuffer->Release();
- }
- else
- {
- NewString = "";
- }
- NewString = NewString + Plugin2Handler::zm_pszListStart + pPropName + " = ";
- NewString.AppendULONG(nValue);
- NewString += Plugin2Handler::zm_pszListEnd;
- CHXBuffer* pCHXBuffer = new CHXBuffer();
- pCHXBuffer->QueryInterface(IID_IHXBuffer,(void**) &pBuffer);
- pBuffer->Set((UCHAR*)(const char*)NewString, strlen(NewString)+1);
- return HXR_OK;
- }
- HX_RESULT Plugin2Handler::Plugin::CatPropertiesCString(REF(IHXBuffer*) pBuffer,
- const char* pPropName,
- IHXBuffer* pValue)
- {
- CHXString NewString;
- const char* pchar;
- ULONG32 nLen;
- if (pBuffer)
- {
- pBuffer->Get((UCHAR*&)pchar, nLen);
- NewString=pchar;
- pBuffer->Release();
- }
- else
- {
- NewString ="";
- }
- pValue->Get((UCHAR*&)pchar, nLen);
- NewString = NewString + Plugin2Handler::zm_pszListStart + pPropName + " = " + pchar + Plugin2Handler::zm_pszListEnd;
- CHXBuffer* pCHXBuffer = new CHXBuffer();
- pCHXBuffer->QueryInterface(IID_IHXBuffer,(void**) &pBuffer);
- pBuffer->Set((UCHAR*)(const char*)NewString, strlen(NewString)+1);
- return HXR_OK;
- }
- /////////////////////////////////////////////////////////////////////////
- // Method:
- // Plugin2Handler::Plugin::QueryInterface
- // Purpose:
- // Implement this to export the interfaces supported by your
- // object.
- //
- STDMETHODIMP
- Plugin2Handler::Plugin::QueryInterface(REFIID riid, void** ppvObj)
- {
- if (IsEqualIID(riid, IID_IUnknown))
- {
- AddRef();
- *ppvObj = (IUnknown*)this;
- return HXR_OK;
- }
- // else if (IsEqualIID(riid, IID_IHXPluginWatcherResponse))
- // {
- // AddRef();
- // *ppvObj = (IHXPluginWatcherResponse*)this;
- // return HXR_OK;
- // }
- *ppvObj = NULL;
- return HXR_NOINTERFACE;
- }
- /////////////////////////////////////////////////////////////////////////
- // Method:
- // Plugin2Handler::Plugin::AddRef
- // Purpose:
- // Everyone usually implements this the same... feel free to use
- // this implementation.
- //
- STDMETHODIMP_(ULONG32)
- Plugin2Handler::Plugin::AddRef()
- {
- return InterlockedIncrement(&m_lRefCount);
- }
- /////////////////////////////////////////////////////////////////////////
- // Method:
- // Plugin2Handler::Plugin::Release
- // Purpose:
- // Everyone usually implements this the same... feel free to use
- // this implementation.
- //
- STDMETHODIMP_(ULONG32)
- Plugin2Handler::Plugin::Release()
- {
- if (InterlockedDecrement(&m_lRefCount) > 0)
- {
- return m_lRefCount;
- }
- delete this;
- return 0;
- }
- /**********************************************************************************
- *** Plugin2Handler::PluginDLL ***
- ***********************************************************************************/
- Plugin2Handler::PluginDLL::PluginDLL( const char* pszFileName, PluginMountPoint* pMountPoint,
- Plugin2Handler* pPlugin2Handler )
- : m_fpCreateInstance(NULL)
- , m_fpShutdown(NULL)
- , m_fCanUnload(NULL)
- , m_pMountPoint( pMountPoint )
- , m_pFileName( NULL )
- , m_pNamespace( NULL )
- , m_nSizeBites(0)
- , m_lRefCount(0)
- , m_NumOfPlugins(0)
- , m_pDLLAccess(NULL)
- , m_bHas_factory(FALSE)
- , m_bLoaded(FALSE)
- , m_nActiveReferences(0)
- , m_pPlugin2Handler(pPlugin2Handler)
- , m_bDoesExist(TRUE)
- {
- // Always create an IHXBuffer and store the filename there
- CHXBuffer* pCHXBuffer = new CHXBuffer();
- if( SUCCEEDED( pCHXBuffer->QueryInterface( IID_IHXBuffer,(void**) &m_pFileName ) ) )
- {
- if (pszFileName)
- {
- // Make sure there are no path components in the filename
- HX_ASSERT( !strrchr( pszFileName, Plugin2Handler::zm_cDirectorySeperator ) );
- m_pFileName->Set( (BYTE*) pszFileName, ::strlen( pszFileName ) + 1 );
- }
- }
- m_pDLLAccess = new DLLAccess();
- }
- Plugin2Handler::PluginDLL::~PluginDLL()
- {
- HX_RELEASE( m_pFileName );
- HX_RELEASE( m_pNamespace );
- if (m_pDLLAccess)
- {
- if (m_bLoaded)
- {
- if (m_fpShutdown)
- {
- m_fpShutdown();
- m_fpShutdown = NULL;
- }
- m_pDLLAccess->close();
- }
- delete m_pDLLAccess;
- m_pDLLAccess = 0;
- }
- // Remove ourself from the plugin handler's CanUnload2DllList.
- LISTPOSITION posCanUnload = m_pPlugin2Handler->GetCanUnload2DllList().Find( this );
- if ( posCanUnload )
- {
- m_pPlugin2Handler->GetCanUnload2DllList().RemoveAt( posCanUnload );
- }
- }
- Plugin2Handler::Errors
- Plugin2Handler::PluginDLL::Load(IUnknown* pContext)
- {
- HX_LOG_BLOCK( "Plugin2Handler::PluginDLL::Load()" );
- Errors result = NO_ERRORS;
- IUnknown* pInstance = NULL;
- IHXPlugin* pPlugin = NULL;
- IHXPluginFactory* pIFactory = NULL;
- if (m_bLoaded)
- {
- return PLUGIN_ALREADY_HAS_MOUNT_POINT; //XXXAH Huh?
- }
- if( m_pFileName->GetSize() <= 1 )
- {
- return PLUGIN_NOT_FOUND;
- }
- // Build complete path for DLL
- IHXBuffer* pBuffer = m_pMountPoint->Path();
- CHXString fileNameWithPath = (char*) pBuffer->GetBuffer();
- UINT32 len = fileNameWithPath.GetLength();
- if(len &&
- fileNameWithPath.GetAt(len - 1) != Plugin2Handler::zm_cDirectorySeperator)
- fileNameWithPath += Plugin2Handler::zm_pszDirectorySeperator;
- fileNameWithPath += (char *) m_pFileName->GetBuffer();
- HX_RELEASE(pBuffer);
- // 1st load the DLL into memory
- HX_PRIME_ACCUMULATOR( 'pdll', "Total DLL Load Time" );
- int dllLoadResult = m_pDLLAccess->open(fileNameWithPath);
- HX_UPDATE_ACCUMULATOR( 'pdll' );
- if( dllLoadResult != DLLAccess::DLL_OK )
- {
- #ifdef REALPLAYER_PLUGIN_HANDLER_RESEARCH_
- {
- // XXXHP -- although using HXLOG_ALERT below I woudld think would notify the user (based on documentation),
- // it apparently does not
- // m_pPlugin2Handler->ReportError( HXLOG_ALERT, (char *) m_pFileName->GetBuffer(), m_pDLLAccess->getErrorString() );
- CHXString errorReport;
- errorReport.Format ("Please contact Millie or Jeff Chasen immediately!nThe DLL '%s' cannot be opened. ERROR: %s", m_pFileName->GetBuffer (), m_pDLLAccess->getErrorString ());
- LogCriticalError_ (errorReport);
- ::MessageBox (0, "Critical Error", errorReport, MB_OK);
- }
- #else
- m_pPlugin2Handler->ReportError( HXLOG_DEBUG, (char *) m_pFileName->GetBuffer(), m_pDLLAccess->getErrorString() );
- #endif
- return CANT_OPEN_DLL;
- }
- HX_LOG_CHECKPOINT( "DLL Loaded" );
- // Now look for the HXCreateInstance exported function
- m_fpCreateInstance = (FPCREATEINSTANCE) m_pDLLAccess->getSymbol(HXCREATEINSTANCESTR);
- if (NULL == m_fpCreateInstance)
- {
- m_pPlugin2Handler->ReportError( HXLOG_DEBUG, (char *) m_pFileName->GetBuffer(), "No " HXCREATEINSTANCESTR );
- return NO_HX_CREATE_INSTANCE;
- }
- // And look for HXShutdown exported function... not required.
- m_fpShutdown = (FPSHUTDOWN) m_pDLLAccess->getSymbol(HXSHUTDOWNSTR);
- // and look for CanUnload2 exported function
- //JE 3/26/01: look for CanUnload2 instead of CanUnload. This way we will
- //not try and unload any DLLs that may have incorrectly implemented the old
- // CanUnload. If you implement CanUnload2, you better get it right ;)
- m_fCanUnload = (FPSHUTDOWN) m_pDLLAccess->getSymbol("CanUnload2");
- if ( m_fCanUnload )
- {
- // This PluginDLL exports CanUnload2(), so add it to the list of such PluginDLL's.
- m_pPlugin2Handler->GetCanUnload2DllList().AddTail( this );
- }
- HX_LOG_CHECKPOINT( "Exported symbols found" );
- // Does this thing support the IHXPlugin Interface
- // Now we will test to see if the DLL contains multiple Plugins.
- HX_PRIME_ACCUMULATOR( 'plmk', "Total Plugin Allocation time" );
- HX_RESULT createResult = m_fpCreateInstance( &pInstance );
- HX_UPDATE_ACCUMULATOR( 'plmk' );
- if( HXR_OK != createResult )
- {
- m_pPlugin2Handler->ReportError( HXLOG_DEBUG, (char *) m_pFileName->GetBuffer(), HXCREATEINSTANCESTR " Failure");
- result = CREATE_INSTANCHXR_FAILURE;
- goto cleanup;
- }
- HX_LOG_CHECKPOINT( "Plugin instance created" );
- // To be a valid plugin a DLL must support IHXPlugin
- // In addition, it may support IHXPluginFactory
- if( SUCCEEDED( pInstance->QueryInterface( IID_IHXPluginFactory, (void**) &pIFactory ) ) )
- {
- m_bHas_factory = TRUE;
- m_NumOfPlugins = pIFactory->GetNumPlugins();
- HX_RELEASE( pIFactory );
- }
- else if( SUCCEEDED( pInstance->QueryInterface( IID_IHXPlugin, (void**) &pPlugin ) ) )
- {
- m_bHas_factory = FALSE;
- m_NumOfPlugins = 1;
- IHXComponentPlugin* pIPackage = NULL;
- if (SUCCEEDED (pInstance->QueryInterface (IID_IHXComponentPlugin, (void**) &pIPackage)))
- {
- #ifndef _WINDOWS // XXXHP TEMPORARY - viper team has requested that this shouldn't assert for now on windows.
- HX_ASSERT (m_fpShutdown);
- #endif
- pPlugin->InitPlugin (pContext);
- m_packageName = pIPackage->GetPackageName ();
- HX_RELEASE (pIPackage);
- }
- HX_RELEASE( pPlugin );
- }
- else
- {
- result = BAD_PLUGIN;
- goto cleanup;
- }
- // We are now loaded.
- HX_RELEASE(pInstance);
- m_bLoaded = TRUE;
- cleanup:
- HX_LOG_CHECKPOINT( "Plugin2Handler::PluginDLL::Load() exiting" );
- return result;
- }
- HX_RESULT Plugin2Handler::PluginDLL::WritePref2(REF(CPluginInfoWriter) piw)
- {
- // the string is defined as follows:
- // {name, checksum, BOOL has factory, size, INT numplugins},{ditto}
- // get the checksum
- IHXBuffer* pPathBuffer = GetMountPoint()->Path();
- IHXBuffer* pNewChecksum = m_pPlugin2Handler->ChecksumFile( (char *) m_pFileName->GetBuffer(), pPathBuffer);
- if (!pNewChecksum)
- {
- HX_RELEASE(pPathBuffer);
- piw.Write("");
- m_bDoesExist = FALSE;
- return HXR_OK;
- }
- char* pszCheckSum = (char*) pNewChecksum->GetBuffer();
- char szSize[16]; /* Flawfinder: ignore */ // XXXAH ok, if some day in the future we have terabite size DLLs then this will fail.
- itoa(m_nSizeBites, szSize, 10);
- char szNumPlugins[16]; /* Flawfinder: ignore */
- itoa(m_NumOfPlugins, szNumPlugins, 10);
- piw.Write("{");
- piw.Write((const char*) m_pFileName->GetBuffer());
- piw.Write(",");
- piw.Write(pszCheckSum);
- piw.Write(",");
- if (m_bHas_factory)
- {
- piw.Write("1");
- }
- else
- {
- piw.Write("0");
- }
- piw.Write(",");
- piw.Write(szSize);
- piw.Write(",");
- piw.Write(szNumPlugins);
- piw.Write("}");
- HX_RELEASE(pNewChecksum);
- HX_RELEASE(pPathBuffer);
- return HXR_OK;
- }
- HX_RESULT Plugin2Handler::PluginDLL::WritePref(PreferenceEnumerator* pPrefEnum)
- {
- char pPrefValue[(1<<8)]; /* Flawfinder: ignore */
- IHXBuffer* pBuffer = new CHXBuffer();
- pBuffer->AddRef();
- pBuffer->Set((const UCHAR*)"",1);
- #ifndef _MACINTOSH
- pPrefEnum->WriteSubPref( (const char *) m_pFileName->GetBuffer(), pBuffer );
- #endif
- HX_VERIFY(HXR_OK == pPrefEnum->BeginSubPref( (const char *) m_pFileName->GetBuffer() ) );
- // the number of plugins
- sprintf(pPrefValue, "%d", m_NumOfPlugins); /* Flawfinder: ignore */
- pBuffer->Set((UCHAR*)(const char*)pPrefValue, strlen(pPrefValue)+1);
- pPrefEnum->WriteSubPref(PLUGIN_NUM_PLUGINS, pBuffer);
- // the checksum of the file.
- IHXBuffer* pPathBuffer = GetMountPoint()->Path();
- IHXBuffer* pNewChecksum = m_pPlugin2Handler->ChecksumFile((char*)m_pFileName->GetBuffer(), pPathBuffer);
- pPrefEnum->WriteSubPref(PLUGIN_FILE_CHECKSUM, pNewChecksum);
- HX_RELEASE(pNewChecksum);
- HX_RELEASE(pPathBuffer);
- // the size of the DLL
- sprintf(pPrefValue, "%d", (int)m_nSizeBites); /* Flawfinder: ignore */
- pBuffer->Set((const UCHAR*)pPrefValue, strlen(pPrefValue)+1);
- pPrefEnum->WriteSubPref(PLUGIN_DLL_SIZE, pBuffer);
- // if the DLL has a factory or not.
- if (m_bHas_factory)
- {
- pBuffer->Set((const UCHAR*)"TRUE", strlen("TRUE")+1);
- }
- else
- {
- pBuffer->Set((const UCHAR*)"FALSE", strlen("FALSE")+1);
- }
- pPrefEnum->WriteSubPref(PLUGIN_HAS_FACTORY, pBuffer);
- HX_RELEASE(pBuffer);
- pPrefEnum->EndSubPref();
- return HXR_OK;
- }
- void Plugin2Handler::PluginDLL::SetPref(int nNumPlugins, char* pszCheckSum, int nSize, BOOL factory)
- {
- m_NumOfPlugins = nNumPlugins;
- m_hash = pszCheckSum;
- m_nSizeBites = nSize;
- m_bHas_factory = factory;
- }
- HX_RESULT Plugin2Handler::PluginDLL::ReadPref(PreferenceEnumerator* pPrefEnum)
- {
- IHXBuffer* pBuffer;
- // Number of plugins in this DLL
- pPrefEnum->ReadPref(PLUGIN_NUM_PLUGINS, pBuffer);
- m_NumOfPlugins = atoi((const char*)pBuffer->GetBuffer());
- HX_RELEASE(pBuffer);
- // The Checksum of the DLL
- pPrefEnum->ReadPref(PLUGIN_FILE_CHECKSUM, pBuffer);
- m_hash = (char*)pBuffer->GetBuffer();
- HX_RELEASE(pBuffer);
- // the size of the DLL
- pPrefEnum->ReadPref(PLUGIN_DLL_SIZE, pBuffer);
- m_nSizeBites = atoi((const char*)pBuffer->GetBuffer());
- HX_RELEASE(pBuffer);
- // if the DLL has a factory or not.
- pPrefEnum->ReadPref(PLUGIN_HAS_FACTORY, pBuffer);
- if (strcmp((const char*)pBuffer->GetBuffer(), "FALSE"))
- {
- m_bHas_factory = TRUE;
- }
- else
- {
- m_bHas_factory = FALSE;
- }
- HX_RELEASE(pBuffer);
- return HXR_OK;
- }
- HX_RESULT Plugin2Handler::PluginDLL::Unload(BOOL safe)
- {
- if (m_bLoaded)
- {
- if (!safe || ( m_fCanUnload && m_fCanUnload()==HXR_OK ) )
- {
- if (m_fpShutdown)
- {
- if (FAILED (m_fpShutdown ())) return HXR_FAIL;
- m_fpShutdown = NULL;
- }
- if (DLLAccess::DLL_OK == m_pDLLAccess->close())
- {
- m_bLoaded = FALSE;
- // Remove ourself from the plugin handler's CanUnload2DllList.
- LISTPOSITION posCanUnload = m_pPlugin2Handler->GetCanUnload2DllList().Find( this );
- if ( posCanUnload )
- {
- m_pPlugin2Handler->GetCanUnload2DllList().RemoveAt( posCanUnload );
- }
- return HXR_OK;
- }
- }
- }
- return HXR_FAIL;
- }
- BOOL Plugin2Handler::PluginDLL::IsLoaded()
- {
- return m_bLoaded;
- }
- Plugin2Handler::Errors Plugin2Handler::PluginDLL::CreateInstance(IUnknown** ppUnk,
- UINT32 uIndex)
- {
- if (!m_bLoaded)
- return PLUGIN_NOT_FOUND;
- if (!m_bHas_factory)
- {
- if (HXR_OK != m_fpCreateInstance(ppUnk))
- {
- return CREATE_INSTANCHXR_FAILURE;
- }
- }
- else
- {
- if (uIndex > (ULONG32)(m_NumOfPlugins-1) && m_NumOfPlugins)
- {
- return CANT_LOAD_INTERFACE;
- }
- IUnknown* pUnk;
- IHXPluginFactory* pPluginFactory;
- m_fpCreateInstance(&pUnk);
- if (HXR_OK != pUnk->QueryInterface
- (IID_IHXPluginFactory, (void**) &pPluginFactory))
- {
- HX_RELEASE(pUnk);
- return CREATE_INSTANCHXR_FAILURE;
- }
- else
- {
- HX_RELEASE(pUnk);
- if (HXR_OK != pPluginFactory->GetPlugin((UINT16)uIndex, ppUnk))
- {
- HX_RELEASE(pPluginFactory);
- return CREATE_INSTANCHXR_FAILURE;
- }
- HX_RELEASE(pPluginFactory);
- }
- }
- m_pPlugin2Handler->AddtoLRU(this);
- m_pPlugin2Handler->UpdateCache();
- return NO_ERRORS;
- }
- IHXBuffer* Plugin2Handler::PluginDLL::GetFileName()
- {
- m_pFileName->AddRef();
- return m_pFileName;
- }
- IHXBuffer* Plugin2Handler::PluginDLL::GetNamespace()
- {
- if (m_pNamespace)
- {
- m_pNamespace->AddRef();
- }
- return m_pNamespace;
- }
- void Plugin2Handler::PluginDLL::SetNamespace(IHXBuffer* pNamespace)
- {
- m_pNamespace = pNamespace;
- if (m_pNamespace)
- {
- m_pNamespace->AddRef();
- }
- }
- UINT32 Plugin2Handler::PluginDLL::AddDLLReference()
- {
- return ++m_nActiveReferences;
- }
- UINT32 Plugin2Handler::PluginDLL::ReleaseDLLReference()
- {
- --m_nActiveReferences;
- Unload(); //XXXAH this should only happen if we have set DLL unloading to true.
- return 0;
- }
- /////////////////////////////////////////////////////////////////////////
- // Method:
- // Plugin2Handler::PluginDLL::QueryInterface
- // Purpose:
- // Implement this to export the interfaces supported by your
- // object.
- //
- STDMETHODIMP
- Plugin2Handler::PluginDLL::QueryInterface(REFIID riid, void** ppvObj)
- {
- if (IsEqualIID(riid, IID_IUnknown))
- {
- AddRef();
- *ppvObj = (IUnknown*)this;
- return HXR_OK;
- }
- *ppvObj = NULL;
- return HXR_NOINTERFACE;
- }
- /////////////////////////////////////////////////////////////////////////
- // Method:
- // Plugin2Handler::PluginDLL::AddRef
- // Purpose:
- // Everyone usually implements this the same... feel free to use
- // this implementation.
- //
- STDMETHODIMP_(ULONG32)
- Plugin2Handler::PluginDLL::AddRef()
- {
- return InterlockedIncrement(&m_lRefCount);
- }
- /////////////////////////////////////////////////////////////////////////
- // Method:
- // Plugin2Handler::PluginDLL::Release
- // Purpose:
- // Everyone usually implements this the same... feel free to use
- // this implementation.
- //
- STDMETHODIMP_(ULONG32)
- Plugin2Handler::PluginDLL::Release()
- {
- if (InterlockedDecrement(&m_lRefCount) > 0)
- {
- return m_lRefCount;
- }
- delete this;
- return 0;
- }
- /**********************************************************************************
- *** Plugin2Handler::PluginMountPoint ***
- ***********************************************************************************/
- Plugin2Handler::PluginMountPoint::PluginMountPoint( Plugin2Handler* pContext, const char* pName,
- UINT32 majorVersion, UINT32 minorVersion, IHXBuffer* pPath ) :
- m_lRefCount( 0 ),
- m_lClientCount( 0 ),
- m_bHXCompliant( FALSE ),
- m_pIPrefs( NULL ),
- m_pIPath( NULL )
- {
- #ifdef HELIX_FEATURE_PREFERENCES
- // Set up a preferences object
- if( pName )
- {
- if( !strcmp( pName, HXVER_SDK_PRODUCT ) )
- {
- // Just use the preferences aggregated by the context,
- // and set ourself as HXCompliant
- m_pIPrefs = pContext->GetPreferences();
- m_bHXCompliant = TRUE;
- }
- else
- {
- IHXCommonClassFactory* pICCF = NULL;
- if( SUCCEEDED( pContext->QueryInterface( IID_IHXCommonClassFactory, (void**) &pICCF ) ) )
- {
- IUnknown* pIUnk = NULL;
- if( SUCCEEDED( pICCF->CreateInstance( CLSID_HXPreferences, (void**) &pIUnk ) ) )
- {
- IHXPreferences3* pIPrefs3 = NULL;
- if( SUCCEEDED( pIUnk->QueryInterface( IID_IHXPreferences3, (void**) &pIPrefs3 ) ) )
- {
- if( SUCCEEDED( pIPrefs3->Open( HXVER_COMPANY, pName, majorVersion, minorVersion ) ) )
- {
- pIPrefs3->QueryInterface( IID_IHXPreferences, (void**) &m_pIPrefs );
- }
- HX_RELEASE( pIPrefs3 );
- }
- HX_RELEASE( pIUnk );
- }
- HX_RELEASE( pICCF );
- }
- }
- HX_ASSERT( m_pIPrefs );
- }
- #endif
- // Set up the path.
- if( !pPath && m_pIPrefs )
- {
- // Handle the special case path as well
- if( m_bHXCompliant )
- {
- m_pIPath = pContext->GetPluginDir();
- }
- else
- {
- m_pIPrefs->ReadPref( PLUGIN_FILE_PATH, m_pIPath );
- }
- }
- else
- {
- m_pIPath = pPath;
- if( m_pIPath )
- {
- m_pIPath->AddRef();
- }
- }
- }
- Plugin2Handler::PluginMountPoint::~PluginMountPoint()
- {
- HX_RELEASE( m_pIPrefs );
- HX_RELEASE( m_pIPath );
- }
- STDMETHODIMP_(ULONG32)
- Plugin2Handler::PluginMountPoint::AddRef()
- {
- return InterlockedIncrement(&m_lRefCount);
- }
- STDMETHODIMP_(ULONG32)
- Plugin2Handler::PluginMountPoint::Release()
- {
- if (InterlockedDecrement(&m_lRefCount) > 0)
- {
- return m_lRefCount;
- }
- delete this;
- return 0;
- }
- void Plugin2Handler::PluginMountPoint::AddClient()
- {
- m_lClientCount++;
- }
- INT32 Plugin2Handler::PluginMountPoint::RemoveClient()
- {
- return ( --m_lClientCount );
- }
- // XXXND This is for backward compatibility
- BOOL Plugin2Handler::PluginMountPoint::IsHXCompliant()
- {
- return m_bHXCompliant;
- }
- IHXPreferences* Plugin2Handler::PluginMountPoint::Prefs()
- {
- if( m_pIPrefs )
- m_pIPrefs->AddRef();
- return m_pIPrefs;
- }
- IHXBuffer* Plugin2Handler::PluginMountPoint::Path()
- {
- if( m_pIPath )
- m_pIPath->AddRef();
- return m_pIPath;
- }
- #if 0
- /**********************************************************************************
- *** Plugin2Handler::PluginMonitor ***
- ***********************************************************************************/
- /*
- The plugin monitor is responsible for monitoring each and every plugin
- that get instance is used to create. It attaches itself to the addref
- and relase of the target, and will mimic the refcount. When the object
- is destroyed it will send a notification to the plugin handler, thus
- the plugin handler will be able to determine if it is safe to
- unload the plugins.
- */
- CHXMapPtrToPtr Plugin2Handler::PluginMonitor::MapTargetToMonitor;
- // when we are constructed we will attach ourselves to the target.
- Plugin2Handler::PluginMonitor::PluginMonitor(IUnknown* MonitorTarget,
- IHXPluginWatcherResponse* pResponse):
- m_lFakeRefCount(1)
- , m_lRefCount(0)
- , m_pPluginWatcherResponse(pResponse)
- {
- // put this back in if you ever expect plugin watchers to work
- // if (HXR_OK !=pResponse->QueryInterface(IID_IHXPluginWatcherResponse,
- // (void**) &m_pPluginWatcherResponse))
- // {
- // return;
- // }
- void** ppVoid = *(void***)MonitorTarget;
- m_fpAddRefPointer = (FPWatchRef) (*(ppVoid+1)); // cast to (FPWatchRef) ??
- m_fpReleasePointer = (FPWatchRef) (*(ppVoid+2));
- *(ppVoid+1) = Plugin2Handler::PluginMonitor::FakeAddRef;
- *(ppVoid+2) = Plugin2Handler::PluginMonitor::FakeRelease;
- AddMonitorTarget(MonitorTarget, this);
- }
- Plugin2Handler::PluginMonitor::~PluginMonitor()
- {
- // XXXAH should we do something here?
- }
- HX_RESULT Plugin2Handler::PluginMonitor::AddMonitorTarget(void* pMonitorTarget,
- PluginMonitor* pPluginMonitor)
- {
- void* TempVal = NULL;
- if (MapTargetToMonitor.Lookup(pMonitorTarget, TempVal ))
- {
- return HXR_FAIL;
- }
- MapTargetToMonitor.SetAt(pMonitorTarget, (void*)pPluginMonitor);
- return HXR_OK;
- }
- HX_RESULT Plugin2Handler::PluginMonitor::ReleaseMonitorTarget(void* pMonitorTarget)
- {
- void* TempVal = NULL;
- if (!MapTargetToMonitor.Lookup(pMonitorTarget, TempVal))
- {
- return HXR_FAIL;
- }
- MapTargetToMonitor.RemoveKey(pMonitorTarget);
- return HXR_OK;
- }
- Plugin2Handler::PluginMonitor* Plugin2Handler::PluginMonitor::GetThisPointerFromTarget(void* pMonitorTarget)
- {
- PluginMonitor* RetVal = NULL;
- if (!MapTargetToMonitor.Lookup(pMonitorTarget, (void*&)RetVal))
- {
- return NULL;
- }
- return RetVal;
- }
- ULONG32 STDMETHODCALLTYPE Plugin2Handler::PluginMonitor::FakeAddRef(void* pvoid)
- {
- PluginMonitor* pThis = GetThisPointerFromTarget(pvoid);
- ULONG32 nResult = 0;
- if (pThis)
- {
- nResult = pThis->m_fpAddRefPointer(pvoid);
- InterlockedIncrement(&(pThis->m_lFakeRefCount));
- }
- return nResult;
- }
- ULONG32 STDMETHODCALLTYPE Plugin2Handler::PluginMonitor::FakeRelease(void* pvoid)
- {
- PluginMonitor* pThis = GetThisPointerFromTarget(pvoid);
- ULONG32 nResult = 0;
- if (pThis)
- {
- nResult = pThis->m_fpReleasePointer(pvoid);
- InterlockedDecrement(&(pThis->m_lFakeRefCount));
- if (pThis->m_lFakeRefCount)
- return nResult;
- if (nResult<1)
- {
- pThis->m_pPluginWatcherResponse->AllObjectsDeleted((void*)pvoid);
- pThis->m_pPluginWatcherResponse->Release();
- ReleaseMonitorTarget(pvoid);
- // restore the v-table.
- void** pVoid = *(void***)pvoid;
- (*(pVoid+1)) = pThis->m_fpAddRefPointer;
- (*(pVoid+2)) = pThis->m_fpReleasePointer;
- delete pThis;
- return 0;
- }
- }
- return nResult;
- }
- /////////////////////////////////////////////////////////////////////////
- // Method:
- // Plugin2Handler::PluginMonitor::QueryInterface
- // Purpose:
- // Implement this to export the interfaces supported by your
- // object.
- //
- STDMETHODIMP
- Plugin2Handler::PluginMonitor::QueryInterface(REFIID riid, void** ppvObj)
- {
- if (IsEqualIID(riid, IID_IUnknown))
- {
- AddRef();
- *ppvObj = (IUnknown*)this;
- return HXR_OK;
- }
- *ppvObj = NULL;
- return HXR_NOINTERFACE;
- }
- /////////////////////////////////////////////////////////////////////////
- // Method:
- // Plugin2Handler::PluginMonitor::AddRef
- // Purpose:
- // Everyone usually implements this the same... feel free to use
- // this implementation.
- //
- STDMETHODIMP_(ULONG32)
- Plugin2Handler::PluginMonitor::AddRef()
- {
- return InterlockedIncrement(&m_lRefCount);
- }
- /////////////////////////////////////////////////////////////////////////
- // Method:
- // Plugin2Handler::PluginMonitor::Release
- // Purpose:
- // Everyone usually implements this the same... feel free to use
- // this implementation.
- //
- STDMETHODIMP_(ULONG32)
- Plugin2Handler::PluginMonitor::Release()
- {
- if (InterlockedDecrement(&m_lRefCount) > 0)
- {
- return m_lRefCount;
- }
- delete this;
- return 0;
- }
- #endif
- ///////////////////////////////////////////////////////////////////////////////
- //
- // Plugin2Handler::CheckDirectory
- //
- ///////////////////////////////////////////////////////////////////////////////
- Plugin2Handler::Errors Plugin2Handler::Stat(const char* pszFilename, struct stat* pStatBuffer)
- {
- CHXString strFileName;
- memset(pStatBuffer,0,sizeof(*pStatBuffer));
- #ifndef _STATICALLY_LINKED
- if(stat(pszFilename, pStatBuffer) < 0)
- return CANT_OPEN_DLL;
- #endif
- pStatBuffer->st_atime = 0;
- return NO_ERRORS ;
- }
- IHXBuffer* Plugin2Handler::ConvertToAsciiString(char* pBuffer, UINT32 nBuffLen)
- {
- char* pszOut = new char[nBuffLen*2+1];
- char* pszStartOut = pszOut;
- char Nibble;
- IHXBuffer* pOutBuffer = new CHXBuffer(); // This is the ONLY place where this is done!
- pOutBuffer->AddRef();
- for (int i = 0; i<(int)nBuffLen; i++)
- {
- Nibble = (*pBuffer >> 4) & 15;
- *pszOut= (Nibble > 9 ) ? Nibble+55 : Nibble +48;
- pszOut++;
- Nibble = *pBuffer & 15;
- *pszOut= (Nibble> 9 ) ? Nibble+ 55 : Nibble+48;
- pszOut++;
- pBuffer++;
- }
- *pszOut = 0;
- pOutBuffer->Set((UCHAR*)pszStartOut, strlen(pszStartOut)+1);
- delete[] pszStartOut;
- return pOutBuffer;
- }
- IHXBuffer* Plugin2Handler::ChecksumFile(char* pszFileName, IHXBuffer* pPathBuffer)
- {
- #ifdef _STATICALLY_LINKED /* don't need checksumming for static linking */
- return ConvertToAsciiString("abc", 3);
- #endif
- char pszFileNameWithPath[(1<<10)]; /* Flawfinder: ignore */
- SafeStrCpy(pszFileNameWithPath, (char*)pPathBuffer->GetBuffer(), (1<<10));
- INT32 nLen = ::strlen(pszFileNameWithPath);
- if (pszFileNameWithPath[nLen - 1] != Plugin2Handler::zm_cDirectorySeperator)
- {
- SafeStrCat(pszFileNameWithPath, Plugin2Handler::zm_pszDirectorySeperator, (1<<10));
- nLen += strlen(Plugin2Handler::zm_pszDirectorySeperator);
- }
- SafeStrCat(pszFileNameWithPath, pszFileName, (1<<10));
- UCHAR tempbuf[16] = "";
- struct stat stat_stuct;
- Errors statError = PLUGIN_NOT_FOUND;
- #ifdef _MAC_CFM
- CHXFileSpecifier fileSpecifier(pszFileNameWithPath);
- if (SUCCEEDED(CHXFileSpecUtils::ResolveFileSpecifierAlias(fileSpecifier)))
- {
- statError = Stat(fileSpecifier.GetPathName(), &stat_stuct);
- }
- #elif defined(_MAC_MACHO)
- FSRef targetFSRef;
- Boolean isDir;
- OSStatus err = ::FSPathMakeRef(pszFileNameWithPath, &targetFSRef, &isDir);
- if (err == noErr)
- {
- Boolean resolveAliasChains = true;
- Boolean targetIsDir, wasAlias;
- err = FSResolveAliasFileWithMountFlags(&targetFSRef, resolveAliasChains, &targetIsDir, &wasAlias, kResolveAliasFileNoUI);
- if (err == noErr && wasAlias)
- {
- err = FSRefMakePath(&targetFSRef, pszFileNameWithPath, (1<<10));
- }
- }
- statError = Stat(pszFileNameWithPath, &stat_stuct);
- #else
- statError = Stat(pszFileNameWithPath, &stat_stuct);
- #endif
- stat_stuct.st_atime = 0;
- if (NO_ERRORS!=statError)
- {
- return NULL;
- }
- md5_state_t MD5_data;
- md5_init(&MD5_data);
- md5_append(&MD5_data,(UCHAR*)&(stat_stuct),sizeof(stat_stuct));
- md5_finish(tempbuf, &MD5_data);
- return ConvertToAsciiString((char*)tempbuf, sizeof(tempbuf));
- }
- /************************************************************************
- * PreferenceEnumerator *
- * *
- * This class encapsulates the optional IHXPreference Enumerator *
- * interafce which the top level client need not implement. *
- * If the top level client does implement IHXPreferenceEnumerator *
- * then this class is simply a wrapper. If the top level client *
- * does not implement it (why not?) then this class will perform *
- * the necessary leg work. *
- ************************************************************************/
- Plugin2Handler::PreferenceEnumerator::PreferenceEnumerator(IHXPreferences* pIHXPref)
- : m_pPrefEnum(NULL)
- , m_pPreferences(pIHXPref)
- {
- m_pPreferences->AddRef();
- IHXPreferences2* pPref2;
- if (HXR_OK == pIHXPref->QueryInterface(IID_IHXPreferences2, (void**) &pPref2))
- {
- pPref2->GetPreferenceEnumerator(m_pPrefEnum);
- pPref2->Release();
- }
- }
- Plugin2Handler::PreferenceEnumerator::~PreferenceEnumerator()
- {
- ULONG32 nRefCount;
- /* go through the list of prop names and delete all of the buffers */
- for(CHXSimpleList::Iterator i = m_ListofProps.Begin(); i!= m_ListofProps.End(); ++i)
- {
- nRefCount = ((IHXBuffer*)*i )->Release();
- }
- m_ListofProps.RemoveAll();
- HX_RELEASE(m_pPrefEnum);
- HX_RELEASE(m_pPreferences);
- }
- HX_RESULT Plugin2Handler::PreferenceEnumerator::ResetPropNameList()
- {
- ULONG32 nRefCount;
- /* go through the list of prop names and delete all of the buffers */
- for(CHXSimpleList::Iterator i = m_ListofProps.Begin(); i!= m_ListofProps.End(); ++i)
- {
- nRefCount = ((IHXBuffer*)*i )->Release();
- }
- m_ListofProps.RemoveAll();
- /* create the list of props at this level*/
- /* now store the name of the preference in the 'special' reg value. */
- char pszRegKey[(1<<8)]; /* Flawfinder: ignore */
- IHXBuffer* pKeyNamesBuffer = NULL;
- IHXBuffer* pTempBuffer = NULL;
- SafeStrCpy(pszRegKey, (const char*)m_RegKey, (1<<8));
- SafeStrCat(pszRegKey, zm_pszRegKeySeperator, (1<<8));
- SafeStrCat(pszRegKey, zm_pszKeyNameRegKey, (1<<8));
- if (HXR_OK == m_pPreferences->ReadPref(pszRegKey, pKeyNamesBuffer))
- {
- /* ok it was found ... parse the list */
- char* token;
- token = strtok((char*)pKeyNamesBuffer->GetBuffer(), zm_pszValueSeperator);
- while (token)
- {
- pTempBuffer = new CHXBuffer;
- pTempBuffer->AddRef();
- pTempBuffer->Set((const UCHAR*) token, strlen(token)+1);
- m_ListofProps.AddTail((void*)pTempBuffer);
- token = strtok(NULL, zm_pszValueSeperator);
- }
- HX_RELEASE(pKeyNamesBuffer);
- }
- else
- {
- return HXR_FAIL;
- }
- return HXR_OK;
- }
- HX_RESULT Plugin2Handler::PreferenceEnumerator::BeginSubPref(const char* pszSubPref)
- {
- if (m_RegKey.GetLength())
- {
- m_RegKey += "\";
- }
- m_RegKey += pszSubPref;
- if (m_pPrefEnum)
- {
- return m_pPrefEnum->BeginSubPref(pszSubPref);
- }
- ResetPropNameList();
- return HXR_OK;
- }
- HX_RESULT Plugin2Handler::PreferenceEnumerator::EndSubPref()
- {
- char* pNewEnd = (char*)strrchr((const char*) m_RegKey , '\');
- if (pNewEnd)
- {
- *pNewEnd = 0;
- CHXString sTemp = (const char*) m_RegKey;
- m_RegKey = sTemp;
- }
- else
- {
- m_RegKey = "";
- }
- if (m_pPrefEnum)
- {
- return m_pPrefEnum->EndSubPref();
- }
- ResetPropNameList();
- return HXR_OK;
- }
- HX_RESULT Plugin2Handler::PreferenceEnumerator::WriteSubPref(const char* pszSubName, IHXBuffer* pBuffer)
- {
- char pszRegKey[(1<<8)]; /* Flawfinder: ignore */
- IHXBuffer* pKeyNameBuffer = NULL;
- SafeStrCpy(pszRegKey, (const char*)m_RegKey, (1<<8));
- SafeStrCat(pszRegKey, zm_pszRegKeySeperator, (1<<8));
- SafeStrCat(pszRegKey, pszSubName, (1<<8));
- m_pPreferences->WritePref(pszRegKey, pBuffer);
- /* now store the name of the preference in the 'special' reg value. */
- SafeStrCpy(pszRegKey, (const char*)m_RegKey, (1<<8));
- SafeStrCat(pszRegKey, zm_pszRegKeySeperator, (1<<8));
- SafeStrCat(pszRegKey, zm_pszKeyNameRegKey, (1<<8));
- /* note: since we do not have an API for removing reg entries it
- is OK to simply append to the list all of the time */
- if (HXR_OK == m_pPreferences->ReadPref(pszRegKey, pKeyNameBuffer))
- {
- /* hey let's check to see if the string we are adding is
- already in the list of tokens. If so we won't add it */
- char* pszTempString = new char[strlen((char*)pKeyNameBuffer->GetBuffer())+1];
- strcpy(pszTempString, (char*)pKeyNameBuffer->GetBuffer()); /* Flawfinder: ignore */
- char* token;
- BOOL bFound = FALSE;
- token = strtok(pszTempString, zm_pszValueSeperator);
- while (token)
- {
- if (!strcasecmp(token, pszSubName))
- {
- bFound = TRUE;
- break;
- }
- token = strtok(NULL, zm_pszValueSeperator);
- }
- delete[] pszTempString;
- if (bFound)
- {
- pKeyNameBuffer->Release();
- return HXR_OK;
- }
- /* ok we already have this string. Let's append to it. */
- INT32 nLen = pKeyNameBuffer->GetSize()+strlen(pszSubName) + 2;
- char* pszTemp = new char [nLen];
- SafeStrCpy(pszTemp, (char*)pKeyNameBuffer->GetBuffer(), nLen);
- SafeStrCat(pszTemp, zm_pszValueSeperator, nLen);
- SafeStrCat(pszTemp, pszSubName, nLen);
- pKeyNameBuffer->Release();
- pKeyNameBuffer = new CHXBuffer();
- pKeyNameBuffer->AddRef();
- pKeyNameBuffer->Set((const UCHAR*) pszTemp, strlen(pszTemp)+1);
- delete [] pszTemp;
- m_pPreferences->WritePref(pszRegKey, pKeyNameBuffer);
- pKeyNameBuffer->Release();
- /* add this to the list of props */
- pKeyNameBuffer = new CHXBuffer();
- pKeyNameBuffer->AddRef();
- pKeyNameBuffer->Set((const UCHAR*) pszSubName, strlen(pszSubName)+1);
- m_ListofProps.AddTail((void*)pKeyNameBuffer);
- }
- else
- {
- pKeyNameBuffer = new CHXBuffer();
- pKeyNameBuffer->AddRef();
- pKeyNameBuffer->Set((const UCHAR*) pszSubName, strlen(pszSubName)+1);
- m_pPreferences->WritePref(pszRegKey, pKeyNameBuffer);
- /* add this to the list of props */
- m_ListofProps.AddTail((void*)pKeyNameBuffer);
- }
- return HXR_OK;
- }
- HX_RESULT Plugin2Handler::PreferenceEnumerator::ReadPref(const char* pszSubName, REF(IHXBuffer*) /*OUT*/ pBuffer)
- {
- if (m_pPrefEnum)
- {
- return m_pPrefEnum->ReadPref(pszSubName, pBuffer);
- }
- char pszRegKey[(1<<8)]; /* Flawfinder: ignore */
- SafeStrCpy(pszRegKey, (const char*)m_RegKey, (1<<8));
- SafeStrCat(pszRegKey, zm_pszRegKeySeperator, (1<<8));
- SafeStrCat(pszRegKey, pszSubName, (1<<8));
- if (m_pPreferences)
- return m_pPreferences->ReadPref(pszRegKey, pBuffer);
- else
- return HXR_FAIL;
- }
- HX_RESULT Plugin2Handler::PreferenceEnumerator::GetPrefKey(UINT32 nIndex, IHXBuffer*& pBuffer)
- {
- if (m_pPrefEnum)
- {
- return m_pPrefEnum->GetPrefKey(nIndex, pBuffer);
- }
- // get the Ith element of the list and and return it.
- LISTPOSITION pPos = m_ListofProps.FindIndex(nIndex);
- if (pPos)
- {
- pBuffer = (IHXBuffer*)m_ListofProps.GetAt(pPos);
- pBuffer->AddRef();
- }
- else
- {
- return HXR_FAIL;
- }
- return HXR_OK;
- }
- /********************************************************************
- *
- * Plugin Enumeration
- *
- ********************************************************************/
- BEGIN_INTERFACE_LIST_NOCREATE( CPluginEnumerator )
- INTERFACE_LIST_ENTRY_SIMPLE( IHXPluginSearchEnumerator )
- END_INTERFACE_LIST
- CPluginEnumerator::CPluginEnumerator() :
- m_nIndex(0)
- {
- }
- CPluginEnumerator::~CPluginEnumerator()
- {
- }
- STDMETHODIMP_( UINT32 )
- CPluginEnumerator::GetNumPlugins()
- {
- return m_ListOfPlugins.GetCount();
- }
- STDMETHODIMP_( void )
- CPluginEnumerator::GoHead()
- {
- m_nIndex = 0;
- }
- STDMETHODIMP
- CPluginEnumerator::GetNextPlugin( REF(IUnknown*) pIUnkResult, IUnknown* pIUnkOuter )
- {
- // Initialize out params
- pIUnkResult = NULL;
- HX_RESULT res = GetPluginAt( m_nIndex, pIUnkResult, pIUnkOuter );
- m_nIndex++;
- return res;
- }
- STDMETHODIMP
- CPluginEnumerator::GetNextPluginInfo( REF(IHXValues*) pRetValues )
- {
- // Initialize out params
- pRetValues = NULL;
- HX_RESULT res = GetPluginInfoAt( m_nIndex, pRetValues );
- m_nIndex++;
- return res;
- }
- STDMETHODIMP
- CPluginEnumerator::GetPluginAt( UINT32 index, REF(IUnknown*) pIUnkResult, IUnknown* pIUnkOuter )
- {
- // Initialize out params
- pIUnkResult = NULL;
- HX_RESULT res = HXR_FAIL;
- LISTPOSITION pos = m_ListOfPlugins.FindIndex(index);
- if (pos)
- {
- Plugin2Handler::Plugin* pPlugin = (Plugin2Handler::Plugin*) m_ListOfPlugins.GetAt(pos);
- if (pPlugin)
- {
- if (Plugin2Handler::NO_ERRORS == pPlugin->GetInstance( pIUnkResult, pIUnkOuter ))
- {
- res = HXR_OK;
- }
- }
- }
- return res;
- }
- STDMETHODIMP
- CPluginEnumerator::GetPluginInfoAt( UINT32 index, REF(IHXValues*) pRetValues )
- {
- // Initialize out params
- pRetValues = NULL;
- HX_RESULT res = HXR_FAIL;
- LISTPOSITION pos = m_ListOfPlugins.FindIndex(m_nIndex);
- m_nIndex++;
- if (pos)
- {
- Plugin2Handler::Plugin* pPlugin = (Plugin2Handler::Plugin*) m_ListOfPlugins.GetAt(pos);
- if (pPlugin)
- {
- res = pPlugin->GetPluginInfo( pRetValues );
- }
- }
- return res;
- }
- void CPluginEnumerator::Add(Plugin2Handler::Plugin* pPlugin)
- {
- IHXValues* pPluginValues = NULL;
- IHXBuffer* pBuffer = NULL;
- BOOL bAdded = FALSE;
- if (HXR_OK == pPlugin->GetPluginInfo(pPluginValues) && pPluginValues)
- {
- if (HXR_OK == pPluginValues->GetPropertyCString(PLUGIN_DESCRIPTION2, pBuffer) &&
- pBuffer)
- {
- if (strstr((const char*)pBuffer->GetBuffer(), "RealNetworks"))
- {
- m_ListOfPlugins.AddHead(pPlugin);
- bAdded = TRUE;
- }
- }
- HX_RELEASE(pBuffer);
- }
- if (!bAdded)
- {
- m_ListOfPlugins.AddTail(pPlugin);
- }
- }
- HX_RESULT CPluginEnumerator::GetNext(REF(IUnknown*) pRetUnk)
- {
- pRetUnk = NULL;
- return GetNextPlugin( pRetUnk, NULL );
- }
- CPluginInfoWriter::CPluginInfoWriter() :
- m_pIHXBuffer(NULL),
- m_pIHXPreferences(NULL),
- m_NumWrites(0),
- m_BufUsed(0),
- m_BufSize(0),
- m_Checksum(0)
- {
- }
- CPluginInfoWriter::~CPluginInfoWriter()
- {
- if (m_Checksum)
- {
- CHXString checksum;
- checksum.Format ("%u", m_Checksum);
- Write (checksum); // note this will increment m_Checksum but we don't care, we got the value we wanted.
- }
- Flush ();
- HX_RELEASE(m_pIHXBuffer);
- HX_RELEASE(m_pIHXPreferences);
- }
- HX_RESULT CPluginInfoWriter::Init(IHXPreferences* pPrefs, const char* pBaseKeyName, IHXBuffer* pIHXBuffer)
- {
- // Helper class, validation is done by caller; we only assert that it has been done
- HX_ASSERT(pPrefs);
- HX_ASSERT(pBaseKeyName);
- HX_ASSERT(pIHXBuffer);
- HX_RESULT result = HXR_FAIL;
- if(pIHXBuffer)
- {
- m_pIHXBuffer = pIHXBuffer;
- m_pIHXBuffer->AddRef();
- m_BufSize = pIHXBuffer->GetSize();
- // Store base name used to generate plugin info reg key names...
- m_BaseKeyName = pBaseKeyName;
- m_pIHXPreferences = pPrefs;
- m_pIHXPreferences->AddRef();
- result = HXR_OK;
- }
- return result;
- }
- HX_RESULT CPluginInfoWriter::Write(IHXBuffer *pBuffer)
- {
- HX_ASSERT(pBuffer);
- HX_RESULT result = HXR_FAIL;
- if(pBuffer)
- {
- result = Write((const char*) pBuffer->GetBuffer(), pBuffer->GetSize());
- }
- return result;
- }
- HX_RESULT CPluginInfoWriter::Write(const char *pInfo)
- {
- HX_ASSERT(pInfo);
- HX_RESULT result = HXR_FAIL;
- if(pInfo)
- {
- result = Write(pInfo, strlen(pInfo));
- }
- return result;
- }
- HX_RESULT CPluginInfoWriter::Write(const char *pInfo, UINT32 len)
- {
- // Helper class, validation is done by caller; we only assert that it has been done
- HX_ASSERT(pInfo);
- HX_ASSERT(m_pIHXBuffer);
- // verify ASCII-7 compliance as we've had issues on double-byte machines with writing
- // ASCII-8 characters to the registry.
- HX_ASSERT(IsAscii7Compliant(pInfo, len));
- HX_RESULT result = HXR_FAIL;
- m_Checksum += len;
- // Determine how much needs to be written
- UINT32 toWrite = len;
- UCHAR* pSrcPos = (UCHAR *)pInfo;
- UCHAR* pWritePos = m_pIHXBuffer->GetBuffer();
- pWritePos += m_BufUsed;
- while(toWrite)
- {
- // We subtract one that will be used to store NULL terminator added to end of buffer
- UINT32 bufUnused = m_BufSize - m_BufUsed - 1;
- // We should never be negative...
- HX_ASSERT(bufUnused >= 0);
- if(bufUnused >= toWrite)
- {
- memcpy(pWritePos, pSrcPos, toWrite); /* Flawfinder: ignore */
- pSrcPos += toWrite;
- pWritePos += toWrite;
- m_BufUsed += toWrite;
- toWrite = 0;
- }
- else
- {
- memcpy(pWritePos, pSrcPos, bufUnused); /* Flawfinder: ignore */
- pSrcPos += bufUnused;
- pWritePos += bufUnused;
- m_BufUsed += bufUnused;
- toWrite -= bufUnused;
- }
- // We need to subtract 1 for the NULL terminator added to buffer
- if(m_BufUsed == m_BufSize - 1)
- {
- TerminateBuffer();
- WriteToRegistry();
- pWritePos = m_pIHXBuffer->GetBuffer();
- m_BufUsed = 0;
- }
- }
- return result;
- }
- void CPluginInfoWriter::TerminateBuffer()
- {
- HX_ASSERT(m_pIHXBuffer);
- // We needed to make sure we have enough room for NULL terminator...
- HX_ASSERT(m_BufUsed <= m_BufSize -1);
- char* pChar = (char *)m_pIHXBuffer->GetBuffer();
- pChar[m_BufUsed] = ' ';
- }
- void CPluginInfoWriter::WriteToRegistry()
- {
- HX_ASSERT(m_pIHXBuffer);
- HX_ASSERT(m_pIHXPreferences);
- HX_ASSERT(m_NumWrites >= 0);
- // Build key name
- CHXString key;
- key.Format("%s%u", (const char *)m_BaseKeyName, m_NumWrites);
- m_pIHXPreferences->WritePref(key, m_pIHXBuffer);
- m_NumWrites++;
- }
- HX_RESULT CPluginInfoWriter::Flush()
- {
- if(m_BufUsed > 0)
- {
- TerminateBuffer();
- WriteToRegistry();
- }
- return HXR_OK;
- }
- BOOL CPluginInfoWriter::IsAscii7Compliant(const char* data, const UINT32 len)
- {
- for (UINT32 i = 0; i < len; ++i)
- {
- static const unsigned char ascii7Max = 0x80;
- if (((const unsigned char)data [i]) & ascii7Max)
- {
- return FALSE;
- }
- }
- return TRUE;
- }