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

Symbian

开发平台:

C/C++

  1.     // XXXSM before update the cache, we have to be sure that
  2.     //          it only contains actually loaded dlls.
  3.     //          Removing a mount point during runtime could
  4.     //          invalidate some dlls in this cache resulting in
  5.     //          an invalid memory access.
  6.     //return HXR_OK;
  7.     LISTPOSITION pPos;
  8.     INT32 nTotalSize = 0;
  9.     // find out how many bytes are being used by the plugins.
  10.     for(CHXSimpleList::Iterator i = m_DLL_LRUList.Begin();
  11. i!= m_DLL_LRUList.End(); ++i)
  12.     {
  13. Plugin2Handler::PluginDLL* pDLL = (Plugin2Handler::PluginDLL*) *i;
  14. nTotalSize += pDLL->GetFileSize();
  15.     }
  16.     // are we under the limit?
  17.     if (nTotalSize <= m_nCacheSizeBites)
  18.     {
  19. return HXR_OK;
  20.     }
  21.     return HXR_OK;
  22.     // since the most recently used portions of the list are stuck at the tail we
  23.     // will go forward unloading DLL until we are below the limit.
  24.     for(pPos = m_DLL_LRUList.GetHeadPosition();
  25. pPos != m_DLL_LRUList.GetTail();)
  26.     {
  27. if (!pPos) break;
  28. Plugin2Handler::PluginDLL* pDLL = (Plugin2Handler::PluginDLL*) m_DLL_LRUList.GetAt(pPos);
  29. if (HXR_OK == pDLL->Unload())
  30. {
  31.     nTotalSize -= pDLL->GetFileSize();
  32.     // delete this node from the list
  33.     pPos = m_DLL_LRUList.RemoveAt(pPos);
  34.     if (!pPos)
  35.     {
  36. break;
  37.     }
  38.     if (nTotalSize<= m_nCacheSizeBites)
  39.     {
  40. break;
  41.     }
  42.     continue;
  43. }
  44. m_DLL_LRUList.GetNext(pPos);
  45.     }
  46.     if (nTotalSize<= m_nCacheSizeBites)
  47.     {
  48. return HXR_OK;
  49.     }
  50.     else
  51.     {
  52. return HXR_FAIL;
  53.     }
  54. }
  55. BOOL Plugin2Handler::GetPluginFileInfo(REF(char*) pszCurrentPos,
  56.        REF(char*) pszName,
  57.        REF(char*) pszCheckSum,
  58.        REF(BOOL) bFactory,
  59.        REF(int) nDLLSize,
  60.        REF(int) nNumberPlugins)
  61. {
  62.     HX_LOG_BLOCK( "Plugin2Handler::GetPluginFileInfo" );
  63.     char* pszBOOLFactory;
  64.     char* pszINTSize;
  65.     char* pszINTPlugins;
  66.     // eat characters until you find a {
  67.     for(;*pszCurrentPos!='{' && *pszCurrentPos!=0; pszCurrentPos++){};
  68.     if (*pszCurrentPos=='{')
  69.     {
  70. pszCurrentPos++;
  71. pszName = pszCurrentPos;
  72. // eat until a you find a comma
  73.         for(;*pszCurrentPos!=',' && *pszCurrentPos!=0; pszCurrentPos++) {};
  74. *pszCurrentPos=0;
  75. pszCurrentPos++;
  76. pszCheckSum = pszCurrentPos;
  77. // eat until a you find a comma
  78.         for(;*pszCurrentPos!=',' && *pszCurrentPos!=0; pszCurrentPos++) {};
  79. *pszCurrentPos=0;
  80. pszCurrentPos++;
  81. pszBOOLFactory = pszCurrentPos;
  82. // eat until a you find a comma
  83.         for(;*pszCurrentPos!=',' && *pszCurrentPos!=0; pszCurrentPos++) {};
  84. *pszCurrentPos=0;
  85. pszCurrentPos++;
  86. pszINTSize = pszCurrentPos;
  87. // eat until a you find a comma
  88.         for(;*pszCurrentPos!=',' && *pszCurrentPos!=0; pszCurrentPos++) {};
  89. *pszCurrentPos=0;
  90. pszCurrentPos++;
  91. pszINTPlugins = pszCurrentPos;
  92. // eat until a you find a close brace
  93.         for(;*pszCurrentPos!='}' && *pszCurrentPos!=0; pszCurrentPos++) {};
  94. *pszCurrentPos=0;
  95. pszCurrentPos++;
  96. if (pszBOOLFactory && pszINTSize && pszINTPlugins)
  97. {
  98.    bFactory     = atoi(pszBOOLFactory);
  99.    nDLLSize     = atoi(pszINTSize);
  100.    nNumberPlugins   = atoi(pszINTPlugins);
  101. }
  102. return TRUE;
  103.     }
  104.     return FALSE;
  105. }
  106. BOOL Plugin2Handler::GetNameValuePair(REF(char*) pszCurrentPos, REF(char*) pszName, REF(char*) pszValue)
  107. {
  108.     // eat until we find either a NULL, a comma, or a close brace
  109.     // check for termination condition
  110.     if (*pszCurrentPos=='{')
  111.     {
  112. return FALSE;
  113.     }
  114.     pszName = pszCurrentPos;
  115.     for(;*pszCurrentPos && *pszCurrentPos!='}' && *pszCurrentPos!='~';pszCurrentPos++) {};
  116.     if (*pszCurrentPos == '~')
  117.     {
  118. *pszCurrentPos = 0;
  119. pszCurrentPos++;
  120.     }
  121.     else
  122.     {
  123. return FALSE;
  124.     }
  125.     pszValue = pszCurrentPos;
  126.     for(;*pszCurrentPos && *pszCurrentPos!='}' && *pszCurrentPos!='~';pszCurrentPos++) {};
  127.     if (*pszCurrentPos == '}' || *pszCurrentPos=='~')
  128.     {
  129. *pszCurrentPos = 0;
  130. pszCurrentPos++;
  131. return TRUE;
  132.     }
  133.     else
  134.     {
  135. return FALSE;
  136.     }
  137. }
  138. BOOL Plugin2Handler::GetPluginFileInfo(REF(char*) pszCurrentPos, REF(Plugin2Handler::Plugin*) pPlugin)
  139. {
  140.     /* format of data in regestry is as follows:
  141.      *  {ValueName, N|S|BValue, ValueName, N|S|B, ValueName, N|S|B, etc},
  142.      * {etc}
  143.      */
  144.     // eat until we find a '{' or a null
  145.     for(;*pszCurrentPos!='{' && *pszCurrentPos!=0; pszCurrentPos++) {};
  146.     if (*pszCurrentPos)
  147.     {
  148. pPlugin = new Plugin2Handler::Plugin(m_pContext);
  149. pPlugin->AddRef();
  150. // XXXND  This might do well to get the values from the plugin, and then
  151. // add each property using the IHXValues interface.
  152. char* pszName;
  153. char* pszValue;
  154. pszCurrentPos++;
  155. while (GetNameValuePair(pszCurrentPos, pszName, pszValue))
  156. {
  157.     switch (*pszValue)
  158.     {
  159. case 'N':
  160. {
  161.     pPlugin->SetPropertyULONG32(pszName, pszValue+1);
  162.     if (!strcasecmp(pszName, "indexnumber"))
  163.     {
  164. pPlugin->SetIndex(atoi(pszValue+1));
  165.     }
  166.     break;
  167. }
  168. case 'S':
  169. {
  170.     pPlugin->SetPropertyCString(pszName, pszValue+1);
  171.     break;
  172. }
  173. case 'B':
  174. {
  175.     UINT32 size = strlen(pszValue);
  176.     pPlugin->SetPropertyBuffer( pszName, (BYTE*) pszValue + 1, size - 1 );
  177.     break;
  178. }
  179. case 'X':
  180. {
  181.     UINT32 size = strlen(pszValue);
  182.     CHXBuffer *pBuf = new CHXBuffer();
  183.     HX_ASSERT(pBuf);
  184.     pBuf->AddRef();
  185.     pBuf->SetSize(size);
  186.     // We subtract 1 from size because we move foward in the buffer by 1
  187.     INT32 s = BinFrom64(pszValue+1, size - 1, pBuf->GetBuffer());
  188.     HX_ASSERT((UINT32)s <= size);
  189.     HX_ASSERT(s != -1);
  190.     if (s != -1)
  191.     {
  192. pPlugin->SetPropertyBuffer(pszName, pBuf->GetBuffer(), s );
  193.     }
  194.     HX_RELEASE(pBuf);
  195.     break;
  196. }
  197.     }
  198. }
  199. return TRUE;
  200.     }
  201.     return FALSE;
  202. }
  203. BOOL Plugin2Handler::GetNextSupportingFile(REF(char*) pszCurrentPos, REF(char*) pszFileName, REF(UINT32) index)
  204. {
  205.     char* pszIndex;
  206.     if (*pszCurrentPos == '{')
  207.     {
  208. return FALSE;
  209.     }
  210.     if (*pszCurrentPos)
  211.     {
  212. pszFileName = pszCurrentPos;
  213. // eat until we find a ',' or a null or a '}'
  214. for(;*pszCurrentPos!=',' && *pszCurrentPos!=0 && *pszCurrentPos!='}'; pszCurrentPos++) {};
  215. if (*pszCurrentPos && *pszCurrentPos!='}')
  216. {
  217.     *pszCurrentPos = 0;
  218.     pszCurrentPos++;
  219.     pszIndex = pszCurrentPos;
  220.     // eat until we find a ',' or a null
  221.     for(;*pszCurrentPos!=',' && *pszCurrentPos!=0 && *pszCurrentPos!='}'; pszCurrentPos++) {};
  222.     if (*pszCurrentPos)
  223.     {
  224. *pszCurrentPos = 0;
  225. pszCurrentPos++;
  226. index = atoi(pszIndex);
  227. return TRUE;
  228.     }
  229. }
  230.     }
  231.     return FALSE;
  232. }
  233. BOOL Plugin2Handler::GetGUIDInfo(REF(char*) pszCurrentPos, PluginMountPoint* pMountPoint, REF(char*) pszGUID, REF(CHXSimpleList*) pList)
  234. {
  235.     // format of GUID info:
  236.     // {GUID, filename, index, filename, index, etc}{GUID, filename, index, filename, index}
  237.     UINT32  nDummyVar;
  238.     UINT32  index;
  239.     char*   pszFileName;
  240.     Plugin2Handler::PluginSupportingGUID* pGUIDSupport;
  241.     // eat until we find a '{' or a null
  242.     for(;*pszCurrentPos!='{' && *pszCurrentPos!=0; pszCurrentPos++) {};
  243.     pList   = NULL;
  244.     pszGUID = NULL;
  245.     if (*pszCurrentPos)
  246.     {
  247. pszCurrentPos++;
  248. pszGUID = pszCurrentPos;
  249. // eat until we find a ',' or a null or a close brace
  250. for(;*pszCurrentPos!=',' && *pszCurrentPos!=0 && *pszCurrentPos!='}'; pszCurrentPos++) {};
  251. // do we have support for this GUID?
  252. if (*pszCurrentPos != '}')
  253. {
  254.     if (*pszCurrentPos)
  255.     {
  256. *pszCurrentPos = 0;
  257. pszCurrentPos++;
  258. // ok we have a valid list
  259. pList = new CHXSimpleList;
  260. // now construct the list
  261. while (GetNextSupportingFile(pszCurrentPos, pszFileName, index))
  262. {
  263.     if (FindPlugin(pszFileName, index, nDummyVar))
  264.     {
  265. pGUIDSupport = new Plugin2Handler::PluginSupportingGUID();
  266. pGUIDSupport->m_filename = pszFileName;
  267. pGUIDSupport->m_pMountPoint = pMountPoint;
  268. pGUIDSupport->m_nIndexInDLL = index;
  269. pList->AddTail((void*)pGUIDSupport);
  270.     }
  271. }
  272.     }
  273. }
  274. else
  275. {
  276.     pList = new CHXSimpleList;
  277.     *pszCurrentPos = 0;
  278.     pszCurrentPos++;
  279. }
  280. return TRUE;
  281.     }
  282.     return FALSE;
  283. }
  284. BOOL Plugin2Handler::GetNonHXInfo(REF(char*) pszCurrentPos, PluginMountPoint* pMountPoint, REF(Plugin2Handler::OtherDLL*) pOtherData)
  285. {
  286.     HX_LOG_BLOCK( "Plugin2Handler::GetNonHXInfo" );
  287.     char* pszName;
  288.     char* pszHash;
  289.     // eat until we find a '{' or a null
  290.     for(;*pszCurrentPos!='{' && *pszCurrentPos!=0; pszCurrentPos++) {};
  291.     if (*pszCurrentPos)
  292.     {
  293. pszCurrentPos++;
  294. pszName = pszCurrentPos;
  295. // eat until we find a '{' or a null
  296. for(;*pszCurrentPos!=',' && *pszCurrentPos!=0; pszCurrentPos++) {};
  297. if (*pszCurrentPos)
  298. {
  299.     *pszCurrentPos = 0;
  300.     pszCurrentPos++;
  301.     pszHash = pszCurrentPos;
  302.     // eat until we find a '}' or a null
  303.     for(;*pszCurrentPos!='}' && *pszCurrentPos!=0; pszCurrentPos++) {};
  304.     if (*pszCurrentPos)
  305.     {
  306. *pszCurrentPos = 0;
  307. pszCurrentPos++;
  308. {
  309.     pOtherData = new Plugin2Handler::OtherDLL;
  310.     pOtherData->m_filename = pszName;
  311.     pOtherData->m_pMountPoint = pMountPoint;
  312.     pOtherData->m_fileChecksum = pszHash;
  313.     return TRUE;
  314. }
  315.     }
  316. }
  317.     }
  318.     return FALSE;
  319. }
  320. STDMETHODIMP Plugin2Handler::ReadFromRegistry()
  321. {
  322.     // Set up a mount point with the default plugin location
  323.     IHXBuffer* pIPluginDir = GetPluginDir();
  324.     HX_RESULT result = AddPluginMountPoint( HXVER_SDK_PRODUCT, 0, 0, pIPluginDir );
  325.     HX_RELEASE( pIPluginDir );
  326.     return result;
  327. }
  328. BOOL Plugin2Handler::FindPlugin(const char* pFileName, UINT32 nDLLIndex, REF(UINT32) nIndex)
  329. {
  330.     UINT32 nTempIndex = 0;
  331.     for(CHXSimpleList::Iterator i = m_PluginList.Begin(); i!=m_PluginList.End(); ++i)
  332.     {
  333. Plugin2Handler::Plugin* pPlugin = (Plugin2Handler::Plugin*) *i;
  334. IHXBuffer* pBuffer = pPlugin->GetFileName();
  335. char* pPluginFileName = (char*) pBuffer->GetBuffer();
  336. if (!strcasecmp(pPluginFileName, pFileName))
  337. {
  338.     if (pPlugin->GetIndex() == nDLLIndex)
  339.     {
  340. nIndex = nTempIndex;
  341. HX_RELEASE(pBuffer);
  342. return TRUE;
  343.     }
  344. }
  345. HX_RELEASE(pBuffer);
  346. nTempIndex++;
  347.     }
  348.     return FALSE;
  349. }
  350. HX_RESULT Plugin2Handler::ConnectPluginToDLL(Plugin2Handler::Plugin * pPlugin)
  351. {
  352.     Plugin2Handler::PluginDLL* pPluginDll = NULL;
  353.     IHXBuffer* pBuffer = pPlugin->GetFileName();
  354.     HX_RESULT retVal = HXR_FAIL;
  355.     if (pBuffer)
  356.     {
  357. char* pszFileName = (char*)pBuffer->GetBuffer();
  358. if (m_FileNameMap.Lookup(pszFileName, (void*&)pPluginDll))
  359. {
  360.     // match found...
  361.     pPlugin->SetDLL(pPluginDll);
  362.     retVal = HXR_OK;
  363. }
  364.     }
  365.     HX_RELEASE(pBuffer);
  366.     return retVal;
  367. }
  368. IHXBuffer* Plugin2Handler::GetPluginDir()
  369. {
  370.     // If we don't have a cached PluginDir, figure it out
  371.     if( !m_pPluginDir )
  372.     {
  373. #ifdef _STATICALLY_LINKED
  374. m_pPluginDir = new CHXBuffer();
  375. m_pPluginDir->AddRef();
  376. m_pPluginDir->Set((const UCHAR *)"",1);
  377. #else
  378. const char* pPath = NULL;
  379. // Get the plugin directory from the Dll Access Paths
  380. pPath = GetDLLAccessPath()->GetPath(DLLTYPE_PLUGIN);
  381. if (!pPath || !pPath[0])
  382. {
  383.     m_pPluginDir = GetDefaultPluginDir();
  384.     GetDLLAccessPath()->SetPath(DLLTYPE_PLUGIN,
  385. (const char*)m_pPluginDir->GetBuffer());
  386. }
  387. else
  388. {
  389.     m_pPluginDir = new CHXBuffer();
  390.     m_pPluginDir->AddRef();
  391.     m_pPluginDir->Set((const UCHAR*)pPath, strlen(pPath) + 1);
  392.     // Validate this path.
  393.     //
  394. #ifdef _MAC_CFM // XXXSEH: Revisit validation under Mach-O.
  395.     //
  396.     // Couldn't find a cross platform path validator, so I'll do it just for the Macintosh.
  397.     // That's where this is most important anyways.
  398.     //
  399.     char tempPath[1024]; /* Flawfinder: ignore */
  400.     FSSpec tempSpec;
  401.     OSErr err=0;
  402.             UINT32      ulBytesToCopy = (m_pPluginDir->GetSize() > 1023 ? 1023 : m_pPluginDir->GetSize());
  403.     memcpy(tempPath,m_pPluginDir->GetBuffer(),ulBytesToCopy); /* Flawfinder: ignore */
  404.     tempPath[ulBytesToCopy]=0;
  405.     err = FSSpecFromPathName(tempPath,&tempSpec);
  406.     //
  407.     // Uhoh the Macintosh path validator could not resolve this
  408.     // path, thus we must refresh it.  Strange how we store this
  409.     //  path but never expect it to change.
  410.     //
  411.     if (err != noErr)
  412.     {
  413. HX_RELEASE(m_pPluginDir);
  414. m_pPluginDir = GetDefaultPluginDir();
  415. GetDLLAccessPath()->SetPath(DLLTYPE_PLUGIN,
  416.     (const char*)m_pPluginDir->GetBuffer());
  417.     }
  418. #endif
  419. }
  420. // CFindFile is kind of brain dead in that it will append a OS Seperator
  421. // after the path regardless of what is there currently (bad CFindFile bad!)
  422. // so we will strip it off if it is the last character,
  423. // Also all functions within the plugin handler assume that the plugin
  424. // directory will have not have an OS seperator at the end of it.
  425. char*     pszPluginDir    = NULL;
  426. ULONG32     nPluginDirLen   = 0;
  427. m_pPluginDir->Get((UCHAR*&)pszPluginDir, nPluginDirLen);
  428. // now we COULD (and should for speed) use nPluginDirLen-1 as the
  429. // length of the string. However, it is SLIGHTLY safer to use strlen
  430. if ( *(pszPluginDir+(strlen(pszPluginDir)-1)) == Plugin2Handler::zm_cDirectorySeperator)
  431. {
  432.     *(pszPluginDir+(strlen(pszPluginDir)-1)) = 0;
  433. }
  434. #endif // _STATICALLY_LINKED
  435.     }
  436.     // AddRef() our return value
  437.     if( m_pPluginDir )
  438. m_pPluginDir->AddRef();
  439.     return m_pPluginDir;
  440. }
  441. IHXPreferences*  Plugin2Handler::GetPreferences()
  442. {
  443.     if( m_pPreferences )
  444.     {
  445.         m_pPreferences->AddRef();
  446.     }
  447.     return m_pPreferences;
  448. }
  449. IHXBuffer*  Plugin2Handler::GetDefaultPluginDir()
  450. {
  451.     IHXBuffer* lpBuffer = NULL;
  452.     char mask_name[_MAX_PATH + 1] = ""; /* Flawfinder: ignore */
  453. #if (defined (_WINDOWS) || defined (_WIN32)) && !defined(_WINCE)
  454.     if (!GetSystemDirectory(mask_name, _MAX_PATH))
  455.     {
  456. strcpy(mask_name, ""); /* Flawfinder: ignore */
  457.     }
  458.     if (strlen(mask_name) > 0 && mask_name[strlen(mask_name) - 1] != zm_cDirectorySeperator)
  459.     {
  460.     SafeStrCat(mask_name,  zm_pszDirectorySeperator, _MAX_PATH+1);
  461.     }
  462.     SafeStrCat(mask_name, "Real", _MAX_PATH+1);
  463. #elif defined (_UNIX) && !defined(_MAC_UNIX)
  464.     SafeStrCpy(mask_name, getenv("HOME"), _MAX_PATH+1);
  465.     SafeStrCat(mask_name, "/Real", _MAX_PATH+1);
  466. #elif defined (_MACINTOSH) || defined(_MAC_UNIX)
  467.     FSSpec extSpec;
  468.     extSpec.name[0] = 0;
  469.     // if Sys 8.5 or greater, use Application Support folder, else Extensions
  470.     INT32 sysVersion;
  471.     char* bytes=(char*)&sysVersion;
  472.     OSType  folderType;
  473.     ::Gestalt(gestaltSystemVersion,&sysVersion);
  474.     if (bytes[2]>8 || ((bytes[2]==8) && (bytes[3] >= 0x50)))
  475.      folderType = kApplicationSupportFolderType;
  476.     else
  477. folderType = kExtensionFolderType;
  478.     if (noErr == ::FindFolder (-1, folderType, kDontCreateFolder,
  479. &extSpec.vRefNum, &extSpec.parID))
  480.     {
  481. CHXString str_path;
  482. str_path = extSpec;
  483. SafeStrCpy(mask_name, (char*)(const char*)str_path, _MAX_PATH);
  484.     }
  485.     else
  486. SafeStrCpy(mask_name, ":System Folder:Extensions:", _MAX_PATH+1 );
  487.     SafeStrCat(mask_name, "Real", _MAX_PATH+1);
  488. #if defined(_CARBON) || defined(_MAC_UNIX)
  489.     if (bytes[2] >= 0x10) // OS X
  490.     {
  491. #ifdef _MAC_MACHO
  492.         CFBundleRef mainBundle;
  493.         CFURLRef mainBundleURL;
  494.         CFURLRef updirURL;
  495.         CFBundleRef myBundle;
  496.         // get the main bundle for the app
  497.         mainBundle = ::CFBundleGetMainBundle();
  498.         // look for a resource in the main bundle by name
  499.         mainBundleURL = ::CFBundleCopyBundleURL( mainBundle );
  500.         updirURL = ::CFURLCreateCopyDeletingLastPathComponent(NULL, mainBundleURL);
  501.         CFStringRef urlString = CFURLCopyPath(updirURL);
  502.         CFStringGetCString(urlString, mask_name, _MAX_PATH, kCFStringEncodingMacRoman);
  503. #else
  504.      ProcessSerialNumber psn;
  505.      ProcessInfoRec pir;
  506.      GetCurrentProcess(&psn);
  507.      pir.processName = NULL;
  508.      pir.processAppSpec = &extSpec;
  509.      pir.processInfoLength = sizeof(pir);
  510.      GetProcessInformation(&psn, &pir);
  511.      extSpec.name[0] = '';
  512.      CHXString str_path;
  513.      str_path = extSpec;
  514.      SafeStrCpy(mask_name, (char*)(const char*)str_path, _MAX_PATH);
  515. #endif
  516.     }
  517. #endif
  518. #elif defined(_WINCE)
  519. strcpy(mask_name, "\"); /* Flawfinder: ignore */
  520. #endif //defined (_WINDOWS) || defined (_WIN32)
  521.     CHXBuffer* pCHXBuffer = new CHXBuffer();
  522.     pCHXBuffer->QueryInterface(IID_IHXBuffer,(void**) &lpBuffer);
  523.     lpBuffer->Set((UCHAR*)mask_name, strlen(mask_name)+1);
  524.     return lpBuffer;
  525. }
  526. /**********************************************************************************
  527. ***     Plugin2Handler::Plugin ***
  528. ***********************************************************************************/
  529. Plugin2Handler::Plugin::Plugin(IUnknown* pContext) :
  530. m_lRefCount(0)
  531.     , m_pValues(0)
  532.     , m_pPluginDLL(0)
  533.     , m_pContext(pContext)
  534.     ,  m_bInfoNeedsRefresh(FALSE)
  535.     , m_nPluginIndex(0)
  536. {
  537.     m_pValues = new CHXHeader();
  538.     m_pValues->AddRef();
  539. }
  540. Plugin2Handler::Plugin::~Plugin()
  541. {
  542.     // Test code to look at all of the data in the map.
  543. #if 0
  544.     const char* pPropName=NULL;
  545.     IHXBuffer* pInBuffer=NULL;
  546.     m_pValues->GetFirstPropertyCString(pPropName, pInBuffer);
  547.     HX_RELEASE(pInBuffer);
  548.     HX_RESULT tempresult = HXR_OK;
  549.     while (tempresult == HXR_OK)
  550.     {
  551. tempresult = m_pValues->GetNextPropertyCString(pPropName, pInBuffer);
  552. if (tempresult == HXR_OK)
  553.     pInBuffer->Release();
  554.     }
  555. #endif
  556.     HX_RELEASE(m_pValues);
  557.     HX_RELEASE(m_pPluginDLL);
  558.     //HX_RELEASE(m_pPluginWatcher);
  559. }
  560. BOOL Plugin2Handler::Plugin::DoesMatch(IHXValues* pValues)
  561. {
  562.     CHXSimpleList   PossibleValues1;
  563.     CHXSimpleList   PossibleValues2;
  564.     const char*     pPropName = NULL;
  565.     ULONG32     nInValue;
  566.     ULONG32     nOutValue;
  567.     IHXBuffer*     pInBuffer = NULL;
  568.     IHXBuffer*     pOutBuffer = NULL;
  569.     // Check ULONGS 1st
  570.     if (HXR_OK == pValues->GetFirstPropertyULONG32(pPropName, nInValue))
  571.     {
  572. if (HXR_OK==m_pValues->GetPropertyULONG32(pPropName, nOutValue))
  573. {
  574.     if (nInValue != nOutValue)
  575.     {
  576. goto notFoundexit;
  577.     }
  578. }
  579. else
  580. {
  581.     goto notFoundexit;
  582. }
  583. while (HXR_OK == pValues->GetNextPropertyULONG32(pPropName, nInValue))
  584. {
  585.     if (HXR_OK == m_pValues->GetPropertyULONG32(pPropName, nOutValue))
  586.     {
  587. if (nInValue != nOutValue)
  588. {
  589.     goto notFoundexit;
  590. }
  591.     }
  592.     else
  593.     {
  594. goto notFoundexit;
  595.     }
  596. }
  597.     }
  598.     // Test code to look at all of the data in the map.
  599. #ifdef _DEBUG
  600.     HX_RESULT tempresult;
  601.     tempresult = HXR_OK;
  602.     tempresult = m_pValues->GetFirstPropertyCString(pPropName, pInBuffer);
  603.     HX_RELEASE(pInBuffer);
  604.     while (tempresult == HXR_OK)
  605.     {
  606. tempresult = m_pValues->GetNextPropertyCString(pPropName, pInBuffer);
  607. if (tempresult == HXR_OK)
  608. {
  609.     HX_RELEASE(pInBuffer);
  610. }
  611.     }
  612. #endif /*_DEBUG*/
  613.     // Check String Props.
  614.     if (HXR_OK == pValues->GetFirstPropertyCString(pPropName, pInBuffer))
  615.     {
  616. if (HXR_OK == m_pValues->GetPropertyCString(pPropName, pOutBuffer))
  617. {
  618.     if (!AreBufferEqual(pOutBuffer, pInBuffer))
  619.     {
  620. goto notFoundexit;
  621.     }
  622. }
  623. else
  624. {
  625.     goto notFoundexit;
  626. }
  627. HX_RELEASE(pInBuffer);
  628. HX_RELEASE(pOutBuffer);
  629. while (HXR_OK == pValues->GetNextPropertyCString(pPropName, pInBuffer))
  630. {
  631.     if (HXR_OK == m_pValues->GetPropertyCString(pPropName, pOutBuffer))
  632.     {
  633. if ( !AreBufferEqual(pOutBuffer, pInBuffer))
  634. {
  635.     goto notFoundexit;
  636. }
  637.     }
  638.     else
  639.     {
  640. goto notFoundexit;
  641.     }
  642.     HX_RELEASE(pInBuffer);
  643.     HX_RELEASE(pOutBuffer);
  644. }
  645.     }
  646.      // Check Buffer Properties
  647.     if (HXR_OK == pValues->GetFirstPropertyBuffer(pPropName, pInBuffer))
  648.     {
  649. // XXXND  Make some utility functions for doing this...
  650. if (HXR_OK == m_pValues->GetPropertyBuffer(pPropName, pOutBuffer))
  651. {
  652.     if( pOutBuffer->GetSize() == pInBuffer->GetSize() )
  653.     {
  654. if( ::memcmp( pOutBuffer->GetBuffer(), pInBuffer->GetBuffer(), pOutBuffer->GetSize() ) )
  655. {
  656.     goto notFoundexit;
  657. }
  658.     }
  659. }
  660. else
  661. {
  662.     goto notFoundexit;
  663. }
  664. HX_RELEASE(pInBuffer);
  665. HX_RELEASE(pOutBuffer);
  666. while (HXR_OK == pValues->GetNextPropertyBuffer(pPropName, pInBuffer))
  667. {
  668.     if (HXR_OK == m_pValues->GetPropertyBuffer(pPropName, pOutBuffer))
  669.     {
  670. // XXXND  Make some utility functions for doing this...
  671. if( pOutBuffer->GetSize() == pInBuffer->GetSize() )
  672. {
  673.     if( ::memcmp( pOutBuffer->GetBuffer(), pInBuffer->GetBuffer(), pOutBuffer->GetSize() ) )
  674.     {
  675. goto notFoundexit;
  676.     }
  677. }
  678.     }
  679.     else
  680.     {
  681. goto notFoundexit;
  682.     }
  683.     HX_RELEASE(pInBuffer);
  684.     HX_RELEASE(pOutBuffer);
  685. }
  686.     }
  687.     return TRUE;    // we made it!
  688. notFoundexit:
  689.     HX_RELEASE(pInBuffer);
  690.     HX_RELEASE(pOutBuffer);
  691.     return FALSE;
  692. }
  693. void Plugin2Handler::Plugin::SetDLL(PluginDLL * pPluginDll)
  694. {
  695.     m_pPluginDLL = pPluginDll;
  696.     m_pPluginDLL->AddRef();
  697.     IHXBuffer* pBuffer = pPluginDll->GetFileName();
  698.     HX_ASSERT(pBuffer);
  699.     m_pValues->SetPropertyCString(PLUGIN_FILENAME, pBuffer);
  700.     HX_RELEASE(pBuffer);
  701. }
  702. void Plugin2Handler::Plugin::SetIndex(UINT16 nIndex)
  703. {
  704.     m_nPluginIndex = nIndex;
  705.     m_pValues->SetPropertyULONG32(PLUGIN_INDEX, nIndex);
  706. }
  707. void Plugin2Handler::Plugin::SetPropertyULONG32(char* pName, char* pValue)
  708. {
  709.     if (m_pValues)
  710.     {
  711. m_pValues->SetPropertyULONG32(pName, atoi(pValue));
  712.     }
  713. }
  714. void Plugin2Handler::Plugin::SetPropertyCString(char* pName, char* pValue)
  715. {
  716.     if (m_pValues)
  717.     {
  718. IHXBuffer* pTempBuffer = new CHXBuffer();
  719. pTempBuffer->AddRef();
  720. pTempBuffer->Set((UCHAR*)pValue, strlen(pValue)+1);
  721. m_pValues->SetPropertyCString(pName, pTempBuffer);
  722. HX_RELEASE(pTempBuffer);
  723.     }
  724. }
  725. void Plugin2Handler::Plugin::SetPropertyBuffer(char* pName, BYTE* pData, UINT32 size )
  726. {
  727.     if (m_pValues)
  728.     {
  729. // XXXND  FIX  THis really shouldn't have to do this copy
  730. IHXBuffer* pTempBuffer = new CHXBuffer();
  731. pTempBuffer->AddRef();
  732. pTempBuffer->Set( pData, size );
  733. m_pValues->SetPropertyBuffer(pName, pTempBuffer);
  734. HX_RELEASE(pTempBuffer);
  735.     }
  736. }
  737. HX_RESULT Plugin2Handler::Plugin::WritePref2(REF(CPluginInfoWriter) piw)
  738. {
  739.     /* format of data in regestry is as follows:
  740.      *  {ValueName~ N|S|BValue~ ValueName~ N|S|B~ ValueName~ N|S|B~ etc},
  741.      * {etc}
  742.      */
  743.     // check to see if the DLL we are associated with still exists
  744.     if (!m_pPluginDLL->DoesExist())
  745.     {
  746. piw.Write("");
  747. return HXR_OK;
  748.     }
  749.     piw.Write("{");
  750.     BOOL bFirst = TRUE;
  751.     // Write out data...
  752.     char szScratchPad[100]; /* Flawfinder: ignore */
  753.     const char* pPropertyName;
  754.     ULONG32 uPropertyValue;
  755.     IHXBuffer* pBuffer;
  756.     if(HXR_OK == m_pValues->GetFirstPropertyULONG32(pPropertyName, uPropertyValue))
  757.     {
  758. if (!bFirst)
  759. {
  760.     piw.Write("~");
  761. }
  762. else
  763. {
  764.     bFirst = FALSE;
  765. }
  766. piw.Write(pPropertyName);
  767. itoa(uPropertyValue, szScratchPad, 10);
  768. piw.Write("~N");
  769. piw.Write(szScratchPad);
  770. while (HXR_OK == m_pValues->GetNextPropertyULONG32(pPropertyName, uPropertyValue))
  771. {
  772.     if (!bFirst)
  773.     {
  774. piw.Write("~");
  775.     }
  776.     else
  777.     {
  778. bFirst = FALSE;
  779.     }
  780.     piw.Write(pPropertyName);
  781.     itoa(uPropertyValue, szScratchPad, 10);
  782.     piw.Write("~N");
  783.     piw.Write(szScratchPad);
  784. }
  785.     }
  786.     if (HXR_OK == m_pValues->GetFirstPropertyCString(pPropertyName, pBuffer))
  787.     {
  788. /* add a S to the begining for CString */
  789. if (!bFirst)
  790. {
  791.     piw.Write("~");
  792. }
  793. else
  794. {
  795.     bFirst = FALSE;
  796. }
  797. piw.Write(pPropertyName);
  798. piw.Write("~S");
  799. piw.Write((const char*) pBuffer->GetBuffer());
  800. HX_RELEASE(pBuffer);
  801. while (HXR_OK == m_pValues->GetNextPropertyCString(pPropertyName, pBuffer))
  802. {
  803.     if (!bFirst)
  804.     {
  805. piw.Write("~");
  806.     }
  807.     else
  808.     {
  809. bFirst = FALSE;
  810.     }
  811.     piw.Write(pPropertyName);
  812.     piw.Write("~S");
  813.     piw.Write((const char*) pBuffer->GetBuffer());
  814.     HX_RELEASE(pBuffer);
  815. }
  816.     }
  817.     if (HXR_OK == m_pValues->GetFirstPropertyBuffer(pPropertyName, pBuffer))
  818.     {
  819. UINT32 size = 0;
  820. CHXBuffer *pBuf = NULL;
  821. /* add a B to the begining for Buffer */
  822. if (!bFirst)
  823. {
  824.     piw.Write("~");
  825. }
  826. else
  827. {
  828.     bFirst = FALSE;
  829. }
  830. piw.Write(pPropertyName);
  831. // XXXND  This is for backwards compatibility
  832. if( GetDLL()->GetMountPoint()->IsHXCompliant() )
  833. {
  834.     piw.Write("~B");
  835.     CHXString tmp((const char*) pBuffer->GetBuffer(), pBuffer->GetSize());
  836.     piw.Write( tmp );
  837. }
  838. else
  839. {
  840.     size = pBuffer->GetSize();
  841.     pBuf = new CHXBuffer();
  842.     HX_ASSERT(pBuf);
  843.     pBuf->AddRef();
  844.     pBuf->SetSize(size * 2);
  845.     INT32 s = BinTo64(pBuffer->GetBuffer(), size, (char *)pBuf->GetBuffer());
  846.     HX_ASSERT(size * 2 >= (UINT32)s);
  847.     // Write out data.  s includes the NULL byte.
  848.     piw.Write("~X");
  849.     piw.Write( (const char*) pBuf->GetBuffer(), s - 1 );
  850. }
  851. HX_RELEASE(pBuffer);
  852. HX_RELEASE(pBuf);
  853. while (HXR_OK == m_pValues->GetNextPropertyBuffer(pPropertyName, pBuffer))
  854. {
  855.     if (!bFirst)
  856.     {
  857. piw.Write("~");
  858.     }
  859.     else
  860.     {
  861. bFirst = FALSE;
  862.     }
  863.     piw.Write(pPropertyName);
  864.     // XXXND  This is for backwards compatibility
  865.     if( GetDLL()->GetMountPoint()->IsHXCompliant() )
  866.     {
  867. piw.Write("~B");
  868.         CHXString tmp((const char*) pBuffer->GetBuffer(), pBuffer->GetSize());
  869. piw.Write( tmp );
  870.     }
  871.     else
  872.     {
  873. size = pBuffer->GetSize();
  874. pBuf = new CHXBuffer();
  875. HX_ASSERT(pBuf);
  876. pBuf->AddRef();
  877. pBuf->SetSize(size * 2);
  878. INT32 s = BinTo64(pBuffer->GetBuffer(), size, (char *)pBuf->GetBuffer());
  879. HX_ASSERT(size * 2 >= (UINT32)s);
  880. // Write out data.  s includes the NULL byte.
  881. piw.Write("~X");
  882. piw.Write( (const char*) pBuf->GetBuffer(), s - 1 );
  883.     }
  884.     HX_RELEASE(pBuffer);
  885.     HX_RELEASE(pBuf);
  886. }
  887.     }
  888.     piw.Write("}");
  889.     return HXR_OK;
  890. }
  891. HX_RESULT Plugin2Handler::Plugin::WritePref(PreferenceEnumerator* pPrefEnumParam)
  892. {
  893.     PreferenceEnumerator* pPrefEnum = (PreferenceEnumerator*)pPrefEnumParam;
  894.     const char* pPropertyName=NULL;
  895.     ULONG32 uPropertyValue;
  896.     IHXBuffer* pBuffer=NULL;
  897.     IHXBuffer* pOutBuffer=NULL;
  898.     char pPrefValue[(1<<8)]; /* Flawfinder: ignore */
  899.     pOutBuffer = new CHXBuffer();
  900.     pOutBuffer->AddRef();
  901.     if (HXR_OK == m_pValues->GetFirstPropertyULONG32(pPropertyName, uPropertyValue))
  902.     {
  903. /* add a N to the begining for Number */
  904. sprintf(pPrefValue, "N%d", (int) uPropertyValue); /* Flawfinder: ignore */
  905. pOutBuffer->Set((UCHAR*)pPrefValue, strlen(pPrefValue)+1);
  906. pPrefEnum->WriteSubPref(pPropertyName, pOutBuffer);
  907. while (HXR_OK == m_pValues->GetNextPropertyULONG32(pPropertyName, uPropertyValue))
  908. {
  909.     sprintf(pPrefValue, "N%d", (int)uPropertyValue); /* Flawfinder: ignore */
  910.     pOutBuffer->Set((UCHAR*)pPrefValue, strlen(pPrefValue)+1);
  911.     pPrefEnum->WriteSubPref(pPropertyName, pOutBuffer);
  912. }
  913.     }
  914.     HX_RELEASE(pOutBuffer);
  915.     if (HXR_OK == m_pValues->GetFirstPropertyCString(pPropertyName, pBuffer))
  916.     {
  917. /* add a S to the begining for CString */
  918. CHXString NewString = "S";
  919. NewString += (char*) pBuffer->GetBuffer();
  920. IHXBuffer* pTempBuffer = new CHXBuffer();
  921. pTempBuffer->AddRef();
  922. pTempBuffer->Set((UCHAR*)(const char*)NewString, NewString.GetLength()+1);
  923. pPrefEnum->WriteSubPref(pPropertyName, pTempBuffer);
  924. HX_RELEASE(pBuffer);
  925. HX_RELEASE(pTempBuffer);
  926. while (HXR_OK == m_pValues->GetNextPropertyCString(pPropertyName, pBuffer))
  927. {
  928.     NewString = "S";
  929.     NewString += (char*) pBuffer->GetBuffer();
  930.     pTempBuffer = new CHXBuffer();
  931.     pTempBuffer->AddRef();
  932.     pTempBuffer->Set((UCHAR*)(const char*)NewString, NewString.GetLength()+1);
  933.     pPrefEnum->WriteSubPref(pPropertyName, pTempBuffer);
  934.     HX_RELEASE(pTempBuffer);
  935.     HX_RELEASE(pBuffer);
  936. }
  937.     }
  938.     if (HXR_OK == m_pValues->GetFirstPropertyBuffer(pPropertyName, pBuffer))
  939.     {
  940. /*  add a B to the begining for Buffer -- although someone would have to have rocks in
  941.     his head if he attempted to write a buffer to the reg...
  942. */
  943. UCHAR* pTempChar = new UCHAR[pBuffer->GetSize()+2];
  944. *pTempChar='B';
  945. memcpy(pTempChar+1, pBuffer->GetBuffer(), pBuffer->GetSize()); /* Flawfinder: ignore */
  946. *(pTempChar+pBuffer->GetSize()+1) = 0;
  947. IHXBuffer* pTempBuffer = new CHXBuffer();
  948. pTempBuffer->AddRef();
  949. pTempBuffer->Set(pTempChar, pBuffer->GetSize()+2);
  950. delete[] pTempChar;
  951. pPrefEnum->WriteSubPref(pPropertyName, pTempBuffer);
  952. HX_RELEASE(pBuffer);
  953. HX_RELEASE(pTempBuffer);
  954. while (HXR_OK == m_pValues->GetNextPropertyBuffer(pPropertyName, pBuffer))
  955. {
  956.     pTempChar = new UCHAR[pBuffer->GetSize()+2];
  957.     *pTempChar='B';
  958.     memcpy(pTempChar+1, pBuffer->GetBuffer(), pBuffer->GetSize()); /* Flawfinder: ignore */
  959.     *(pTempChar+pBuffer->GetSize()+1) = 0;
  960.     pTempBuffer = new CHXBuffer();
  961.     pTempBuffer->AddRef();
  962.     pTempBuffer->Set(pTempChar, pBuffer->GetSize()+2);
  963.     delete[] pTempChar;
  964.     pPrefEnum->WriteSubPref(pPropertyName, pTempBuffer);
  965.     HX_RELEASE(pBuffer);
  966.     HX_RELEASE(pTempBuffer);
  967. }
  968.     }
  969.     return HXR_OK;
  970. }
  971. HX_RESULT Plugin2Handler::Plugin::ReadPref(PreferenceEnumerator* pPrefEnum)
  972. {
  973.     UINT32 nIndex     = 0;
  974.     IHXBuffer* pPropName   = 0;
  975.     IHXBuffer* pBuffer     = 0;
  976.     // this function assumes that the enumerator has been properly set up before it is
  977.     // called.
  978.     while (HXR_OK == pPrefEnum->GetPrefKey(nIndex, pPropName))
  979.     {
  980. if (!strcmp((char*)pPropName->GetBuffer(), zm_pszKeyNameRegKey))
  981. {
  982.     HX_RELEASE(pPropName);
  983.     nIndex++;
  984.     continue;
  985. }
  986. pPrefEnum->ReadPref((const char*)pPropName->GetBuffer(), pBuffer);
  987. char* pCharBuffer = (char*)pBuffer->GetBuffer();
  988. switch (*pCharBuffer)
  989. {
  990.     case 'N':
  991.     {
  992. m_pValues->SetPropertyULONG32((const char*)pPropName->GetBuffer(), atoi(pCharBuffer+1));
  993. break;
  994.     }
  995.     case 'S':
  996.     {
  997. IHXBuffer* pTempBuffer = new CHXBuffer();
  998. pTempBuffer->AddRef();
  999. pTempBuffer->Set(pBuffer->GetBuffer()+1, pBuffer->GetSize()-1);
  1000. m_pValues->SetPropertyCString((const char*)pPropName->GetBuffer(), pTempBuffer);
  1001. pTempBuffer->Release();
  1002. break;
  1003.     }
  1004.     case 'B':
  1005.     {
  1006. CHXBuffer *pBuf = new CHXBuffer();
  1007. HX_ASSERT(pBuf);
  1008. pBuf->AddRef();
  1009. pBuf->Set(pBuffer->GetBuffer()+1, pBuffer->GetSize()-1);
  1010. m_pValues->SetPropertyBuffer((const char*)pPropName->GetBuffer(), pBuf );
  1011. HX_RELEASE(pBuf);
  1012. break;
  1013.     }
  1014.     case 'X':
  1015.     {
  1016. CHXBuffer *pBuf = new CHXBuffer();
  1017. HX_ASSERT(pBuf);
  1018. pBuf->AddRef();
  1019. UINT32 size = pBuffer->GetSize();
  1020. pBuf->SetSize(size);
  1021. // We subtract 2 from size - one for NULL terminator and 1 because we move foward in the buffer by 1
  1022. INT32 s = BinFrom64((char *)pBuffer->GetBuffer()+1, size - 2, pBuf->GetBuffer());
  1023. HX_ASSERT(s != -1);
  1024. HX_ASSERT((UINT32) s <= size);
  1025. m_pValues->SetPropertyBuffer((const char*)pPropName->GetBuffer(), pBuf);
  1026. HX_RELEASE(pBuf);
  1027. break;
  1028.     }
  1029. }
  1030. HX_RELEASE(pBuffer);
  1031. HX_RELEASE(pPropName);
  1032. nIndex++;
  1033.     }
  1034.     ULONG32 nTemp;
  1035.     if (HXR_OK == m_pValues->GetPropertyULONG32(PLUGIN_INDEX, nTemp))
  1036.     {
  1037. m_nPluginIndex = (UINT16) nTemp;
  1038.     }
  1039.     return HXR_OK;
  1040. }
  1041. BOOL Plugin2Handler::Plugin::AreBufferEqual(IHXBuffer* pBigBuff,
  1042.    IHXBuffer* pSmallBuff)
  1043. {
  1044.     char*   pTemp;
  1045.     BOOL    bRetVal = FALSE;
  1046.     pTemp = new char[pBigBuff->GetSize()];
  1047.     SafeStrCpy(pTemp, (char*)pBigBuff->GetBuffer(), pBigBuff->GetSize());
  1048.     char* token;
  1049.     token = strtok(pTemp, zm_pszValueSeperator);
  1050.     while (token)
  1051.     {
  1052. CHXString tokenCHXstring;
  1053. CHXString smallCHXstring;
  1054. tokenCHXstring = token;
  1055. smallCHXstring = (char*)pSmallBuff->GetBuffer();
  1056. tokenCHXstring.TrimLeft();
  1057. tokenCHXstring.TrimRight();
  1058. smallCHXstring.TrimLeft();
  1059. smallCHXstring.TrimRight();
  1060. if (!strcasecmp(tokenCHXstring, smallCHXstring))
  1061. {
  1062.     bRetVal = TRUE;
  1063.     break;
  1064. }
  1065. token = strtok(NULL, zm_pszValueSeperator);
  1066.     }
  1067.     delete[] pTemp;
  1068.     return bRetVal;
  1069. }
  1070. Plugin2Handler::Errors Plugin2Handler::Plugin::GetValuesFromDLL(IHXPlugin* pHXPlugin)
  1071. {
  1072.     Plugin2Handler::Errors  retVal;
  1073.     retVal = GetBasicValues(pHXPlugin);
  1074.     if (retVal == NO_ERRORS)
  1075.     {
  1076. retVal = GetExtendedValues(pHXPlugin);
  1077.     }
  1078.     return retVal;
  1079. }
  1080. Plugin2Handler::Errors Plugin2Handler::Plugin::GetPlugin(REF(IUnknown*) pUnknown )
  1081. {
  1082.     pUnknown = NULL;
  1083.     Plugin2Handler::Errors retVal = NO_ERRORS;
  1084.     if (!m_pPluginDLL)
  1085.     {
  1086. return PLUGIN_NOT_FOUND;
  1087.     }
  1088.     if (!m_pPluginDLL->IsLoaded())
  1089.     {
  1090. if (NO_ERRORS != (retVal = m_pPluginDLL->Load(m_pContext)))
  1091. {
  1092.     return retVal;
  1093. }
  1094.     }
  1095.     if (HXR_OK != m_pPluginDLL->CreateInstance(&pUnknown, m_nPluginIndex))
  1096.     {
  1097. return CREATE_INSTANCHXR_FAILURE;
  1098.     }
  1099. //    CreateWatcher(pUnknown);     //XXXAH the watcher is no longer being used
  1100.     return retVal;
  1101. }
  1102. Plugin2Handler::Errors Plugin2Handler::Plugin::GetInstance(REF(IUnknown*) pUnknown, IUnknown* pIUnkOuter )
  1103. {
  1104.     // Initialize out parameter
  1105.     pUnknown = NULL;
  1106.     IUnknown* pIUnkPlugin = NULL;
  1107.     Plugin2Handler::Errors retVal = GetPlugin( pIUnkPlugin );
  1108.     if( retVal == NO_ERRORS )
  1109.     {
  1110. IHXComponentPlugin* pIComp = NULL;
  1111. if( SUCCEEDED( pIUnkPlugin->QueryInterface( IID_IHXComponentPlugin, (void**) &pIComp ) ) )
  1112. {
  1113.     // Ask for the correct object by CLSID
  1114.     IHXBuffer* pCLSID = NULL;
  1115.     if( SUCCEEDED( m_pValues->GetPropertyBuffer( PLUGIN_COMPONENT_CLSID, pCLSID ) ) )
  1116.     {
  1117. if( FAILED( pIComp->CreateComponentInstance( *(GUID*) pCLSID->GetBuffer(), pUnknown, pIUnkOuter ) ) )
  1118. {
  1119.     retVal = CREATE_INSTANCHXR_FAILURE;
  1120. }
  1121. HX_RELEASE( pCLSID );
  1122.     }
  1123.     else
  1124.     {
  1125. // Hmmm...we have a component plugin without a CLSID.  Serious internal error
  1126. retVal = BAD_PLUGIN;
  1127.     }
  1128.     // Release the interface, and destroy the plugin
  1129.     HX_RELEASE( pIComp );
  1130.     HX_RELEASE( pIUnkPlugin );
  1131. }
  1132. else
  1133. {
  1134.     // If this isn't a component plugin, then we can't aggregate anything
  1135.     if( pIUnkOuter )
  1136.     {
  1137. HX_RELEASE( pIUnkPlugin );
  1138. retVal = AGGREGATION_NOT_SUPPORTED;
  1139.     }
  1140.     else
  1141.     {
  1142. pUnknown = pIUnkPlugin;
  1143.     }
  1144. }
  1145.     }
  1146.     return retVal;
  1147. }
  1148. STDMETHODIMP Plugin2Handler::Plugin::AllObjectsDeleted (void*)
  1149. {
  1150.     //HX_RELEASE(m_pPluginWatcher);
  1151.     //m_pPluginWatcher = 0;
  1152.     m_pPluginDLL->ReleaseDLLReference();
  1153.     return HXR_OK;
  1154. }
  1155. Plugin2Handler::Errors
  1156. Plugin2Handler::Plugin::CreateWatcher(IUnknown* pUnknown)
  1157. {
  1158.     return NO_ERRORS; //XXXAH the watcher is no longer being used
  1159. #if 0
  1160.     if (!m_pPluginWatcher)
  1161.     {
  1162. IHXPluginWatcherResponse* pWatcherResp;
  1163. // QueryInterface(IID_IHXPluginWatcherResponse, (void**)&pWatcherResp);  // causes the build to break
  1164. m_pPluginWatcher = new PluginMonitor(pUnknown, pWatcherResp);
  1165. m_pPluginWatcher->AddRef();
  1166. HX_ASSERT(m_pPluginDLL); // Huh?
  1167. m_pPluginDLL->AddDLLReference();
  1168.     }
  1169.     return NO_ERRORS;
  1170. #endif
  1171. }
  1172. BOOL Plugin2Handler::Plugin::IsLoaded()
  1173. {
  1174.     if (!m_pPluginDLL)
  1175. return FALSE;
  1176.     return m_pPluginDLL->IsLoaded();
  1177. }
  1178. HX_RESULT Plugin2Handler::Plugin::GetPluginInfo(REF(IHXValues*) pVals)
  1179. {
  1180.     if (m_pValues)
  1181.     {
  1182. pVals = m_pValues;
  1183. return HXR_OK;
  1184.     }
  1185.     pVals = NULL;
  1186.     return HXR_FAIL;
  1187. }
  1188. IHXBuffer* Plugin2Handler::Plugin::GetFileName()
  1189. {
  1190.     IHXBuffer* retVal = NULL;
  1191.     // Get the filename from m_pValues.  We can't get it from the DLL,
  1192.     // because we may be in the process of loading, and we just got it
  1193.     // from the preferences
  1194.     if( m_pValues )
  1195.     {
  1196. m_pValues->GetPropertyCString( PLUGIN_FILENAME, retVal );
  1197.     }
  1198.     return retVal;
  1199. }
  1200. Plugin2Handler::Errors
  1201. Plugin2Handler::Plugin::GetBasicValues(IHXPlugin* pHXPlugin)
  1202. {
  1203.     const char* pszDescription = NULL;
  1204.     const char* pszCopyright = NULL;
  1205.     const char* pszMoreInfoUrl = NULL;
  1206.     ULONG32 ulVersionNumber = 0;
  1207.     BOOL nload_multiple = 0;
  1208.     if (HXR_OK != pHXPlugin->GetPluginInfo(nload_multiple, pszDescription,
  1209.        pszCopyright, pszMoreInfoUrl, ulVersionNumber))
  1210.     {
  1211.         return BAD_PLUGIN;
  1212.     }
  1213.     IHXBuffer* pBuffer = NULL;
  1214.     CHXBuffer* pCHXBuffer = new CHXBuffer();
  1215.     pCHXBuffer->QueryInterface(IID_IHXBuffer,(void**) &pBuffer);
  1216.     if (pszDescription)
  1217.     {
  1218. pBuffer->Set((UCHAR*)pszDescription, strlen(pszDescription)+1);
  1219.     }
  1220.     m_pValues->SetPropertyCString(PLUGIN_DESCRIPTION2, pBuffer);
  1221.     pBuffer->Release();
  1222.     pCHXBuffer = new CHXBuffer();
  1223.     pCHXBuffer->QueryInterface(IID_IHXBuffer,(void**) &pBuffer);
  1224.     if (pszCopyright)
  1225.     {
  1226. pBuffer->Set((UCHAR*)pszCopyright, strlen(pszCopyright)+1);
  1227.     }
  1228.     m_pValues->SetPropertyCString(PLUGIN_COPYRIGHT2, pBuffer);
  1229.     pBuffer->Release();
  1230.     pCHXBuffer = new CHXBuffer();
  1231.     pCHXBuffer->QueryInterface(IID_IHXBuffer,(void**) &pBuffer);
  1232.     if (pszMoreInfoUrl)
  1233.     {
  1234. pBuffer->Set((UCHAR*)pszMoreInfoUrl, strlen(pszMoreInfoUrl)+1);
  1235.     }
  1236.     m_pValues->SetPropertyCString(PLUGIN_COPYRIGHT, pBuffer);
  1237.     pBuffer->Release();
  1238.     m_pValues->SetPropertyULONG32(PLUGIN_LOADMULTIPLE, nload_multiple);
  1239.     m_pValues->SetPropertyULONG32(PLUGIN_VERSION, ulVersionNumber);
  1240.     return NO_ERRORS;
  1241. }
  1242. Plugin2Handler::Errors
  1243. Plugin2Handler::Plugin::GetExtendedValues(IHXPlugin* pHXPlugin)
  1244. {
  1245. //    Errors result     = NO_ERRORS;
  1246.     IHXFileFormatObject* pFileFormat     = NULL;
  1247. //    IHXMetaFileFormatObject* pMetaFileFormat     = NULL;
  1248.     IHXFileWriter* pFileWriter     = NULL;
  1249.     IHXBroadcastFormatObject* pBroadcastFormat    = NULL;
  1250.     IHXFileSystemObject* pFileSystem     = NULL;
  1251.     IHXRenderer* pRenderer     = NULL;
  1252.     IHXDataRevert* pDataRevert     = NULL;
  1253.     IHXStreamDescription* pStreamDescription  = NULL;
  1254.     IHXPlayerConnectionAdviseSink* pAllowanceFormat    = NULL;
  1255.     IHXCommonClassFactory* pClassFactory       = NULL;
  1256.     IHXPluginProperties* pIHXPluginPropertiesThis = NULL;
  1257.     UINT32 nCountInterfaces    = 0;
  1258.     // file system
  1259.     if (HXR_OK == pHXPlugin->QueryInterface(IID_IHXFileSystemObject, (void**) &pFileSystem))
  1260.     {
  1261. const char* pszShortName;
  1262. const char* pszProtocol;
  1263. if (HXR_OK != pFileSystem->GetFileSystemInfo(pszShortName, pszProtocol))
  1264. {
  1265.     HX_RELEASE (pFileSystem);
  1266.     return  CANT_GET_RENDERER_INFO; //XXXAH Cleanup?
  1267. }
  1268. IHXBuffer* pBuffer = NULL;
  1269. CHXBuffer* pCHXBuffer = new CHXBuffer();
  1270. pCHXBuffer->QueryInterface(IID_IHXBuffer,(void**) &pBuffer);
  1271. pBuffer->Set((UCHAR*)PLUGIN_FILESYSTEM_TYPE, strlen(PLUGIN_FILESYSTEM_TYPE)+1);
  1272. m_pValues->SetPropertyCString(PLUGIN_CLASS, pBuffer);
  1273. pBuffer->Release();
  1274. pCHXBuffer = new CHXBuffer();
  1275. pCHXBuffer->QueryInterface(IID_IHXBuffer,(void**) &pBuffer);
  1276. if (pszShortName)
  1277. {
  1278.     pBuffer->Set((UCHAR*)pszShortName, strlen(pszShortName)+1);
  1279. }
  1280. m_pValues->SetPropertyCString(PLUGIN_FILESYSTEMSHORT, pBuffer);
  1281. pBuffer->Release();
  1282. pCHXBuffer = new CHXBuffer();
  1283. pCHXBuffer->QueryInterface(IID_IHXBuffer,(void**) &pBuffer);
  1284. if (pszProtocol)
  1285. {
  1286.     pBuffer->Set((UCHAR*)pszProtocol, strlen(pszProtocol)+1);
  1287. }
  1288. m_pValues->SetPropertyCString(PLUGIN_FILESYSTEMPROTOCOL, pBuffer);
  1289. pBuffer->Release();
  1290. pFileSystem->Release();
  1291. nCountInterfaces++;
  1292.     }
  1293.     // file format
  1294.     if (HXR_OK == pHXPlugin->QueryInterface(IID_IHXFileFormatObject, (void**)&pFileFormat) ||
  1295. HXR_OK == pHXPlugin->QueryInterface(IID_IHXFileWriter, (void**)&pFileWriter))
  1296.     {
  1297. // fine we are in now we will get the correct type.
  1298. if (pFileFormat)
  1299. {
  1300.     pFileFormat->Release();
  1301. }
  1302. else
  1303. {
  1304.     pFileWriter->Release();
  1305. }
  1306. const char** ppszMimeTypes = NULL;
  1307. const char** ppszExtensions = NULL;
  1308. const char** ppszOpenNames = NULL;
  1309. if (HXR_OK == pHXPlugin->QueryInterface(IID_IHXFileFormatObject, (void**)&pFileFormat))
  1310. {
  1311.     pFileFormat->GetFileFormatInfo( ppszMimeTypes,
  1312.     ppszExtensions,
  1313.     ppszOpenNames);
  1314.     pFileFormat->Release();
  1315.     IHXBuffer* pBuffer = NULL;
  1316.     CHXBuffer* pCHXBuffer = new CHXBuffer();
  1317.     pCHXBuffer->QueryInterface(IID_IHXBuffer,(void**) &pBuffer);
  1318.     pBuffer->Set((UCHAR*)PLUGIN_FILEFORMAT_TYPE, strlen(PLUGIN_FILEFORMAT_TYPE)+1);
  1319.     m_pValues->SetPropertyCString(PLUGIN_CLASS, pBuffer);
  1320.     pBuffer->Release();
  1321. }
  1322. if (HXR_OK == pHXPlugin->QueryInterface(IID_IHXFileWriter, (void**)&pFileWriter))
  1323. {
  1324.     pFileWriter->GetFileFormatInfo( ppszMimeTypes,
  1325.     ppszExtensions,
  1326.     ppszOpenNames);
  1327.     pFileWriter->Release();
  1328.     IHXBuffer* pBuffer = NULL;
  1329.     CHXBuffer* pCHXBuffer = new CHXBuffer();
  1330.     pCHXBuffer->QueryInterface(IID_IHXBuffer,(void**) &pBuffer);
  1331.     pBuffer->Set((UCHAR*)PLUGIN_FILEWRITER_TYPE, strlen(PLUGIN_FILEWRITER_TYPE)+1);
  1332.     m_pValues->SetPropertyCString(PLUGIN_CLASS, pBuffer);
  1333.     pBuffer->Release();
  1334. }
  1335. IHXBuffer* pBuffer = NULL;
  1336. if (ppszMimeTypes)
  1337. {
  1338.     CatStrings((char**)ppszMimeTypes, pBuffer);     //XXXAH this had better be const in reality!
  1339.     m_pValues->SetPropertyCString(PLUGIN_FILEMIMETYPES, pBuffer);
  1340.     pBuffer->Release();
  1341. }
  1342. if (ppszExtensions)
  1343. {
  1344.     CatStrings((char**)ppszExtensions, pBuffer); //XXXAH this had better be const in reality!
  1345.     m_pValues->SetPropertyCString(PLUGIN_FILEEXTENSIONS, pBuffer);
  1346.     pBuffer->Release();
  1347. }
  1348. if (ppszOpenNames)
  1349. {
  1350.     CatStrings((char**)ppszOpenNames, pBuffer); //XXXAH this had better be const in reality!
  1351.     m_pValues->SetPropertyCString(PLUGIN_FILEOPENNAMES, pBuffer);
  1352.     pBuffer->Release();
  1353. }
  1354. nCountInterfaces++;
  1355.     }
  1356.     // renderer
  1357.     if (HXR_OK == pHXPlugin->QueryInterface(IID_IHXRenderer, (void**)&pRenderer))
  1358.     {
  1359. char** ppszMimeTypes;
  1360.         UINT32 initial_granularity = 0;
  1361. // get the basic info
  1362. if (HXR_OK == pRenderer->GetRendererInfo((const char**&)ppszMimeTypes, initial_granularity))
  1363. {
  1364.     IHXBuffer* pBuffer;
  1365.     if (ppszMimeTypes)
  1366.     {
  1367. CatStrings(ppszMimeTypes, pBuffer);
  1368.     }
  1369.     m_pValues->SetPropertyCString(PLUGIN_RENDERER_MIME, pBuffer);
  1370.     pBuffer->Release();
  1371.     m_pValues->SetPropertyULONG32(PLUGIN_RENDERER_GRANULARITY, initial_granularity);
  1372.     CHXBuffer* pCHXBuffer = new CHXBuffer();
  1373.     pCHXBuffer->QueryInterface(IID_IHXBuffer,(void**) &pBuffer);
  1374.     pBuffer->Set((UCHAR*)PLUGIN_RENDERER_TYPE, strlen(PLUGIN_RENDERER_TYPE)+1);
  1375.     m_pValues->SetPropertyCString(PLUGIN_CLASS, pBuffer);
  1376.     pBuffer->Release();
  1377. }
  1378. HX_RELEASE(pRenderer);
  1379. nCountInterfaces++;
  1380.     }
  1381.     //data revert
  1382.     if (HXR_OK == pHXPlugin->QueryInterface(IID_IHXDataRevert, (void**)&pDataRevert))
  1383.     {
  1384. char** ppConversionTypes;
  1385. if (HXR_OK == pDataRevert->GetDataRevertInfo((const char**&)ppConversionTypes))
  1386. {
  1387.     IHXBuffer* pBuffer;
  1388.     CatStrings(ppConversionTypes, pBuffer);
  1389.     m_pValues->SetPropertyCString(PLUGIN_REVERTER_MIME, pBuffer);
  1390.     pBuffer->Release();
  1391.     CHXBuffer* pCHXBuffer = new CHXBuffer();
  1392.     pCHXBuffer->QueryInterface(IID_IHXBuffer,(void**) &pBuffer);
  1393.     pBuffer->Set((UCHAR*)PLUGIN_REVERTER_TYPE, strlen(PLUGIN_REVERTER_TYPE) + 1);
  1394.     m_pValues->SetPropertyCString(PLUGIN_CLASS, pBuffer);
  1395.     pBuffer->Release();
  1396. }
  1397. HX_RELEASE(pDataRevert);
  1398. nCountInterfaces++;
  1399.     }
  1400.     // broadcast
  1401.     if (HXR_OK == pHXPlugin->QueryInterface(IID_IHXBroadcastFormatObject, (void**)&pBroadcastFormat))
  1402.     {
  1403. const char* pszBroadcastType;
  1404. IHXBuffer * pBuffer;
  1405. if (HXR_OK != pBroadcastFormat->GetBroadcastFormatInfo(pszBroadcastType))
  1406. {
  1407.     HX_RELEASE (pBroadcastFormat);
  1408.     return CANT_GET_FILE_FORMAT_INFO; //XXXAH Cleanup?
  1409. }
  1410. pBroadcastFormat->Release();
  1411. CHXBuffer* pCHXBuffer = new CHXBuffer();
  1412. pCHXBuffer->QueryInterface(IID_IHXBuffer,(void**) &pBuffer);
  1413. if (pszBroadcastType)
  1414. {
  1415.     pBuffer->Set((UCHAR*)pszBroadcastType, strlen(pszBroadcastType)+1);
  1416. }
  1417. m_pValues->SetPropertyCString(PLUGIN_BROADCASTTYPE, pBuffer);
  1418. pBuffer->Release();
  1419. pCHXBuffer = new CHXBuffer();
  1420. pCHXBuffer->QueryInterface(IID_IHXBuffer,(void**) &pBuffer);
  1421. pBuffer->Set((UCHAR*)PLUGIN_BROADCAST_TYPE, strlen(PLUGIN_BROADCAST_TYPE)+1);
  1422. m_pValues->SetPropertyCString(PLUGIN_CLASS, pBuffer);
  1423. pBuffer->Release();
  1424. nCountInterfaces++;
  1425.     }
  1426.     // stream description
  1427.     if (HXR_OK == pHXPlugin->QueryInterface(IID_IHXStreamDescription, (void**)&pStreamDescription))
  1428.     {
  1429. const char* pszMimeType;
  1430. IHXBuffer* pBuffer;
  1431. if (HXR_OK != pStreamDescription->GetStreamDescriptionInfo(pszMimeType))
  1432. {
  1433.     HX_RELEASE (pStreamDescription);
  1434.     return CANT_GET_FILE_FORMAT_INFO; // XXXAH Cleanup?
  1435. }
  1436. pStreamDescription->Release();
  1437. CHXBuffer* pCHXBuffer = new CHXBuffer();
  1438. pCHXBuffer->QueryInterface(IID_IHXBuffer,(void**) &pBuffer);
  1439. if (pszMimeType)
  1440. {
  1441.     pBuffer->Set((UCHAR*)pszMimeType, strlen(pszMimeType)+1);
  1442. }
  1443. m_pValues->SetPropertyCString(PLUGIN_STREAMDESCRIPTION, pBuffer);
  1444. pBuffer->Release();
  1445. // IUnknown* pUnk = NULL;
  1446. pCHXBuffer = new CHXBuffer();
  1447. pCHXBuffer->QueryInterface(IID_IHXBuffer,(void**) &pBuffer);
  1448. pBuffer->Set((UCHAR*)PLUGIN_STREAM_DESC_TYPE, strlen(PLUGIN_STREAM_DESC_TYPE)+1);
  1449. m_pValues->SetPropertyCString(PLUGIN_CLASS, pBuffer);
  1450. pBuffer->Release();
  1451. nCountInterfaces++;
  1452.     }
  1453.     // allowance
  1454.     if ( (HXR_OK == pHXPlugin->QueryInterface(IID_IHXPlayerConnectionAdviseSinkManager, (void**)&pAllowanceFormat)) ||
  1455. (HXR_OK == pHXPlugin->QueryInterface(IID_IHXPlayerConnectionAdviseSink, (void**)&pAllowanceFormat)) )
  1456.     {
  1457. IHXBuffer* pBuffer = NULL;
  1458. CHXBuffer* pCHXBuffer = new CHXBuffer();
  1459. pCHXBuffer->QueryInterface(IID_IHXBuffer,(void**) &pBuffer);
  1460. pBuffer->Set((UCHAR*)PLUGIN_ALLOWANCE_TYPE, strlen(PLUGIN_ALLOWANCE_TYPE)+1);
  1461. m_pValues->SetPropertyCString(PLUGIN_CLASS, pBuffer);
  1462. pBuffer->Release();
  1463. pAllowanceFormat->Release();
  1464. nCountInterfaces++;
  1465.     }
  1466.     // common class factory
  1467.     if(HXR_OK == pHXPlugin->QueryInterface(IID_IHXCommonClassFactory,
  1468. (void**)&pClassFactory))
  1469.     {
  1470. IHXBuffer* pBuffer = NULL;
  1471. CHXBuffer* pCHXBuffer = new CHXBuffer();
  1472. pCHXBuffer->QueryInterface(IID_IHXBuffer,(void**) &pBuffer);
  1473. pBuffer->Set((UCHAR*)PLUGIN_CLASS_FACTORY_TYPE, strlen(PLUGIN_CLASS_FACTORY_TYPE)+1);
  1474. m_pValues->SetPropertyCString(PLUGIN_CLASS, pBuffer);
  1475. pBuffer->Release();
  1476. HX_RELEASE (pClassFactory);
  1477. nCountInterfaces++;
  1478.     }
  1479.     // NO MORE NEW PLUGIN INFORMATION INTERFACES!!!!
  1480.     //
  1481.     // THIS IS THE LAST ONE!!!!!
  1482.     if( SUCCEEDED( pHXPlugin->QueryInterface( IID_IHXPluginProperties, (void**)&pIHXPluginPropertiesThis ) ) )
  1483.     {
  1484. IHXValues* pIHXValuesProperties = NULL;
  1485. pHXPlugin->InitPlugin(m_pContext);
  1486. if( SUCCEEDED( pIHXPluginPropertiesThis->GetProperties( pIHXValuesProperties ) ) && pIHXValuesProperties )
  1487. {
  1488.     CHXHeader::mergeHeaders( m_pValues, pIHXValuesProperties );
  1489. }
  1490. HX_RELEASE(pIHXValuesProperties);
  1491. // XXXkshoop Let this coincide with other interfaces.. for now..
  1492. //nCountInterfaces++;
  1493.     }
  1494.     HX_RELEASE(pIHXPluginPropertiesThis);
  1495.     HX_ASSERT(nCountInterfaces<2);
  1496.     return NO_ERRORS;
  1497. }
  1498. HX_RESULT Plugin2Handler::Plugin::GetBandwidthInfo()
  1499. {
  1500.     IHXPlugin* pHXPlugin;
  1501.     IUnknown* pUnk;
  1502.     if (HXR_OK != GetInstance(pUnk))
  1503.     {
  1504. return HXR_FAIL;
  1505.     }
  1506.     if (HXR_OK != pUnk->QueryInterface(IID_IHXPlugin, (void**)& pHXPlugin))
  1507.     {
  1508. return HXR_FAIL;
  1509.     }
  1510.     HX_RELEASE(pUnk);
  1511.     pHXPlugin->InitPlugin(m_pContext);
  1512.     IHXBandwidthLister* bandwidth_lister;
  1513.     if(HXR_OK == pHXPlugin->QueryInterface(IID_IHXBandwidthLister,
  1514. (void**)&bandwidth_lister))
  1515.     {
  1516. IHXValues* pValues;
  1517. pValues = new CHXHeader();
  1518. pValues->AddRef();
  1519. if(HXR_OK == bandwidth_lister->GetBandwidthInfo(pValues))
  1520. {
  1521.     // now that we have these new values we must transcribe them to the
  1522.     // m_pValues.
  1523.     const char*     pValueName;
  1524.     ULONG32     nPropValue;
  1525.     IHXBuffer*     pPropValue;
  1526.     if (HXR_OK == pValues->GetFirstPropertyULONG32(pValueName, nPropValue))
  1527.     {
  1528. m_pValues->SetPropertyULONG32(pValueName, nPropValue);
  1529. while (HXR_OK == pValues->GetNextPropertyULONG32(pValueName, nPropValue))
  1530. {
  1531.     m_pValues->SetPropertyULONG32(pValueName, nPropValue);
  1532. }
  1533.     }
  1534.     if (HXR_OK == pValues->GetFirstPropertyBuffer(pValueName, pPropValue))
  1535.     {
  1536. m_pValues->SetPropertyBuffer(pValueName, pPropValue);
  1537. pPropValue->Release();
  1538. while (HXR_OK == pValues->GetNextPropertyBuffer(pValueName, pPropValue))
  1539. {
  1540.     m_pValues->SetPropertyBuffer(pValueName, pPropValue);
  1541.     pPropValue->Release();
  1542. }
  1543.     }
  1544.     if (HXR_OK == pValues->GetFirstPropertyCString(pValueName, pPropValue))
  1545.     {
  1546. m_pValues->SetPropertyCString(pValueName, pPropValue);
  1547. pPropValue->Release();
  1548. while (HXR_OK == pValues->GetNextPropertyCString(pValueName, pPropValue))
  1549. {
  1550.     m_pValues->SetPropertyCString(pValueName, pPropValue);
  1551.     pPropValue->Release();
  1552. }
  1553.     }
  1554. }
  1555. HX_RELEASE(bandwidth_lister);
  1556. HX_RELEASE(pValues);
  1557. HX_RELEASE(pHXPlugin);
  1558. m_bInfoNeedsRefresh = FALSE;
  1559. return HXR_OK;
  1560.     }
  1561.     HX_RELEASE(pHXPlugin);
  1562.     return HXR_FAIL;
  1563. }
  1564. void Plugin2Handler::Plugin::InitializeComponentPlugin( IHXPlugin* pIPlugin, IHXValues* pIValues )
  1565. {
  1566.     // Setup basic data
  1567.     // XXXHP - this is unnecessary information as it is stored on a PER COMPONENT not PER PLUGIN basis in this case.
  1568.     // GetBasicValues( pIPlugin );
  1569.     // Copy data from pIValues
  1570.     CHXHeader::mergeHeaders( m_pValues, pIValues );
  1571. }
  1572. HX_RESULT Plugin2Handler::Plugin::CatStrings(char** pInStrings,
  1573.     REF(IHXBuffer*) pOutBuffer)
  1574. {
  1575.     ULONG32 nAllocedSpace   = 100;
  1576.     char*   ptemp     = new char[nAllocedSpace];
  1577.     char*   ptemp2     = NULL;
  1578.     ULONG32 nStrLen     = 0;
  1579.     ULONG32 nNewStrLen     = 0;
  1580.     *ptemp = 0;
  1581.     pOutBuffer = 0;
  1582.     for(; *pInStrings; pInStrings++)
  1583.     {
  1584. nNewStrLen = strlen(*pInStrings);
  1585. if (nNewStrLen+ nStrLen >= nAllocedSpace)
  1586. {
  1587.     // double if the new string is less than the new space
  1588.     // or add double what it required.
  1589.     if (nNewStrLen< nAllocedSpace)
  1590.     {
  1591. nAllocedSpace*=2;
  1592.     }
  1593.     else
  1594.     {
  1595. nAllocedSpace+=nNewStrLen*2;
  1596.     }
  1597.     ptemp2 = new char[nAllocedSpace];
  1598.     memcpy(ptemp2, ptemp, nStrLen+1); /* Flawfinder: ignore */
  1599.     delete [] ptemp;
  1600.     ptemp = ptemp2;
  1601. }
  1602. // XXXAH I must trim the strings before I add them to this string.
  1603. // the find function DEPENDS UPON THIS.
  1604. SafeStrCat(ptemp,  *pInStrings, nAllocedSpace);
  1605. if (*(pInStrings+1))
  1606. {
  1607.     SafeStrCat(ptemp,  Plugin2Handler::zm_pszValueSeperator, nAllocedSpace); // XXXAH Perhaps a define?
  1608. }
  1609. nStrLen+=nNewStrLen+1;
  1610.     }
  1611.     CHXBuffer* pCHXBuffer = new CHXBuffer();
  1612.     pCHXBuffer->QueryInterface(IID_IHXBuffer,(void**) &pOutBuffer);
  1613.     pOutBuffer->Set((UCHAR*)ptemp, strlen(ptemp)+1);
  1614.     delete[] ptemp;
  1615.     return HXR_OK;
  1616. }
  1617. HX_RESULT Plugin2Handler::Plugin::CatPropertiesULONG32(REF(IHXBuffer*) pBuffer,
  1618.       const char* pPropName,
  1619.       ULONG32 nValue)
  1620. {
  1621.     CHXString NewString;
  1622.     const char* pchar;
  1623.     ULONG32 nLen;
  1624.     if (pBuffer)
  1625.     {
  1626. pBuffer->Get((UCHAR*&)pchar, nLen);
  1627. NewString=pchar;
  1628. pBuffer->Release();
  1629.     }
  1630.     else
  1631.     {
  1632. NewString = "";
  1633.     }
  1634.     NewString = NewString  + Plugin2Handler::zm_pszListStart + pPropName + " = ";
  1635.     NewString.AppendULONG(nValue);
  1636.     NewString += Plugin2Handler::zm_pszListEnd;
  1637.     CHXBuffer* pCHXBuffer = new CHXBuffer();
  1638.     pCHXBuffer->QueryInterface(IID_IHXBuffer,(void**) &pBuffer);
  1639.     pBuffer->Set((UCHAR*)(const char*)NewString, strlen(NewString)+1);
  1640.     return HXR_OK;
  1641. }
  1642. HX_RESULT Plugin2Handler::Plugin::CatPropertiesCString(REF(IHXBuffer*) pBuffer,
  1643.       const char* pPropName,
  1644.       IHXBuffer* pValue)
  1645. {
  1646.     CHXString     NewString;
  1647.     const char*     pchar;
  1648.     ULONG32     nLen;
  1649.     if (pBuffer)
  1650.     {
  1651. pBuffer->Get((UCHAR*&)pchar, nLen);
  1652. NewString=pchar;
  1653. pBuffer->Release();
  1654.     }
  1655.     else
  1656.     {
  1657. NewString ="";
  1658.     }
  1659.     pValue->Get((UCHAR*&)pchar, nLen);
  1660.     NewString = NewString + Plugin2Handler::zm_pszListStart + pPropName  + " = " + pchar + Plugin2Handler::zm_pszListEnd;
  1661.     CHXBuffer* pCHXBuffer = new CHXBuffer();
  1662.     pCHXBuffer->QueryInterface(IID_IHXBuffer,(void**) &pBuffer);
  1663.     pBuffer->Set((UCHAR*)(const char*)NewString, strlen(NewString)+1);
  1664.     return HXR_OK;
  1665. }
  1666. /////////////////////////////////////////////////////////////////////////
  1667. //  Method:
  1668. //      Plugin2Handler::Plugin::QueryInterface
  1669. //  Purpose:
  1670. //      Implement this to export the interfaces supported by your
  1671. //      object.
  1672. //
  1673. STDMETHODIMP
  1674. Plugin2Handler::Plugin::QueryInterface(REFIID riid, void** ppvObj)
  1675. {
  1676.     if (IsEqualIID(riid, IID_IUnknown))
  1677.     {
  1678.         AddRef();
  1679.         *ppvObj = (IUnknown*)this;
  1680.         return HXR_OK;
  1681.     }
  1682. //    else if (IsEqualIID(riid, IID_IHXPluginWatcherResponse))
  1683. //    {
  1684. //        AddRef();
  1685. //        *ppvObj = (IHXPluginWatcherResponse*)this;
  1686. //        return HXR_OK;
  1687. //    }
  1688.     *ppvObj = NULL;
  1689.     return HXR_NOINTERFACE;
  1690. }
  1691. /////////////////////////////////////////////////////////////////////////
  1692. //  Method:
  1693. //      Plugin2Handler::Plugin::AddRef
  1694. //  Purpose:
  1695. //      Everyone usually implements this the same... feel free to use
  1696. //      this implementation.
  1697. //
  1698. STDMETHODIMP_(ULONG32)
  1699. Plugin2Handler::Plugin::AddRef()
  1700. {
  1701.     return InterlockedIncrement(&m_lRefCount);
  1702. }
  1703. /////////////////////////////////////////////////////////////////////////
  1704. //  Method:
  1705. //      Plugin2Handler::Plugin::Release
  1706. //  Purpose:
  1707. //      Everyone usually implements this the same... feel free to use
  1708. //      this implementation.
  1709. //
  1710. STDMETHODIMP_(ULONG32)
  1711. Plugin2Handler::Plugin::Release()
  1712. {
  1713.     if (InterlockedDecrement(&m_lRefCount) > 0)
  1714.     {
  1715.         return m_lRefCount;
  1716.     }
  1717.     delete this;
  1718.     return 0;
  1719. }
  1720. /**********************************************************************************
  1721. ***     Plugin2Handler::PluginDLL ***
  1722. ***********************************************************************************/
  1723. Plugin2Handler::PluginDLL::PluginDLL( const char* pszFileName, PluginMountPoint* pMountPoint,
  1724. Plugin2Handler* pPlugin2Handler )
  1725.     : m_fpCreateInstance(NULL)
  1726.     , m_fpShutdown(NULL)
  1727.     , m_fCanUnload(NULL)
  1728.     , m_pMountPoint( pMountPoint )
  1729.     , m_pFileName( NULL )
  1730.     , m_pNamespace( NULL )
  1731.     , m_nSizeBites(0)
  1732.     , m_lRefCount(0)
  1733.     , m_NumOfPlugins(0)
  1734.     , m_pDLLAccess(NULL)
  1735.     , m_bHas_factory(FALSE)
  1736.     , m_bLoaded(FALSE)
  1737.     , m_nActiveReferences(0)
  1738.     , m_pPlugin2Handler(pPlugin2Handler)
  1739.     , m_bDoesExist(TRUE)
  1740. {
  1741.     // Always create an IHXBuffer and store the filename there
  1742.     CHXBuffer* pCHXBuffer = new CHXBuffer();
  1743.     if( SUCCEEDED( pCHXBuffer->QueryInterface( IID_IHXBuffer,(void**) &m_pFileName ) ) )
  1744.     {
  1745. if (pszFileName)
  1746. {
  1747.     // Make sure there are no path components in the filename
  1748.     HX_ASSERT( !strrchr( pszFileName, Plugin2Handler::zm_cDirectorySeperator ) );
  1749.     m_pFileName->Set( (BYTE*) pszFileName, ::strlen( pszFileName ) + 1 );
  1750. }
  1751.     }
  1752.     m_pDLLAccess = new DLLAccess();
  1753. }
  1754. Plugin2Handler::PluginDLL::~PluginDLL()
  1755. {
  1756.     HX_RELEASE( m_pFileName );
  1757.     HX_RELEASE( m_pNamespace );
  1758.     if (m_pDLLAccess)
  1759.     {
  1760.         if (m_bLoaded)
  1761. {
  1762.     if (m_fpShutdown)
  1763.     {
  1764. m_fpShutdown();
  1765. m_fpShutdown = NULL;
  1766.     }
  1767.     m_pDLLAccess->close();
  1768. }
  1769. delete m_pDLLAccess;
  1770. m_pDLLAccess = 0;
  1771.     }
  1772.     // Remove ourself from the plugin handler's CanUnload2DllList.
  1773.     LISTPOSITION posCanUnload = m_pPlugin2Handler->GetCanUnload2DllList().Find( this );
  1774.     if ( posCanUnload )
  1775.     {
  1776. m_pPlugin2Handler->GetCanUnload2DllList().RemoveAt( posCanUnload );
  1777.     }
  1778. }
  1779. Plugin2Handler::Errors
  1780. Plugin2Handler::PluginDLL::Load(IUnknown* pContext)
  1781. {
  1782.     HX_LOG_BLOCK( "Plugin2Handler::PluginDLL::Load()" );
  1783.     Errors result     = NO_ERRORS;
  1784.     IUnknown* pInstance   = NULL;
  1785.     IHXPlugin* pPlugin = NULL;
  1786.     IHXPluginFactory* pIFactory = NULL;
  1787.     if (m_bLoaded)
  1788.     {
  1789. return PLUGIN_ALREADY_HAS_MOUNT_POINT; //XXXAH Huh?
  1790.     }
  1791.     if( m_pFileName->GetSize() <= 1 )
  1792.     {
  1793. return PLUGIN_NOT_FOUND;
  1794.     }
  1795.     // Build complete path for DLL
  1796.     IHXBuffer* pBuffer = m_pMountPoint->Path();
  1797.     CHXString fileNameWithPath = (char*) pBuffer->GetBuffer();
  1798.     UINT32 len = fileNameWithPath.GetLength();
  1799.     if(len &&
  1800.        fileNameWithPath.GetAt(len - 1) != Plugin2Handler::zm_cDirectorySeperator)
  1801.     fileNameWithPath += Plugin2Handler::zm_pszDirectorySeperator;
  1802.     fileNameWithPath += (char *) m_pFileName->GetBuffer();
  1803.     HX_RELEASE(pBuffer);
  1804.     // 1st load the DLL into memory
  1805.     HX_PRIME_ACCUMULATOR( 'pdll', "Total DLL Load Time" );
  1806.     int dllLoadResult = m_pDLLAccess->open(fileNameWithPath);
  1807.     HX_UPDATE_ACCUMULATOR( 'pdll' );
  1808.     if( dllLoadResult != DLLAccess::DLL_OK )
  1809.     {
  1810. #ifdef REALPLAYER_PLUGIN_HANDLER_RESEARCH_
  1811.         {
  1812.             // XXXHP -- although using HXLOG_ALERT below I woudld think would notify the user (based on documentation),
  1813.             // it apparently does not
  1814.     // m_pPlugin2Handler->ReportError( HXLOG_ALERT, (char *) m_pFileName->GetBuffer(), m_pDLLAccess->getErrorString() );
  1815.             CHXString errorReport;
  1816.             errorReport.Format ("Please contact Millie or Jeff Chasen immediately!nThe DLL '%s' cannot be opened. ERROR: %s", m_pFileName->GetBuffer (), m_pDLLAccess->getErrorString ());
  1817.             LogCriticalError_ (errorReport);
  1818.             ::MessageBox (0, "Critical Error", errorReport, MB_OK);
  1819.         }
  1820. #else
  1821. m_pPlugin2Handler->ReportError( HXLOG_DEBUG, (char *) m_pFileName->GetBuffer(), m_pDLLAccess->getErrorString() );
  1822. #endif
  1823. return CANT_OPEN_DLL;
  1824.     }
  1825.     HX_LOG_CHECKPOINT( "DLL Loaded" );
  1826.     // Now look for the HXCreateInstance exported function
  1827.     m_fpCreateInstance = (FPCREATEINSTANCE) m_pDLLAccess->getSymbol(HXCREATEINSTANCESTR);
  1828.     if (NULL == m_fpCreateInstance)
  1829.     {
  1830. m_pPlugin2Handler->ReportError( HXLOG_DEBUG, (char *) m_pFileName->GetBuffer(), "No " HXCREATEINSTANCESTR );
  1831. return NO_HX_CREATE_INSTANCE;
  1832.     }
  1833.     // And look for HXShutdown exported function... not required.
  1834.     m_fpShutdown    = (FPSHUTDOWN) m_pDLLAccess->getSymbol(HXSHUTDOWNSTR);
  1835.     // and look for CanUnload2 exported function
  1836.     //JE 3/26/01: look for CanUnload2 instead of CanUnload. This way we will
  1837.     //not try and unload any DLLs that may have incorrectly implemented the old
  1838.     // CanUnload. If you implement CanUnload2, you better get it right ;)
  1839.     m_fCanUnload    = (FPSHUTDOWN) m_pDLLAccess->getSymbol("CanUnload2");
  1840.     if ( m_fCanUnload )
  1841.     {
  1842. // This PluginDLL exports CanUnload2(), so add it to the list of such PluginDLL's.
  1843. m_pPlugin2Handler->GetCanUnload2DllList().AddTail( this );
  1844.     }
  1845.     HX_LOG_CHECKPOINT( "Exported symbols found" );
  1846.     // Does this thing support the IHXPlugin Interface
  1847.     // Now we will test to see if the DLL contains multiple Plugins.
  1848.     HX_PRIME_ACCUMULATOR( 'plmk', "Total Plugin Allocation time" );
  1849.     HX_RESULT createResult = m_fpCreateInstance( &pInstance );
  1850.     HX_UPDATE_ACCUMULATOR( 'plmk' );
  1851.     if( HXR_OK != createResult )
  1852.     {
  1853. m_pPlugin2Handler->ReportError( HXLOG_DEBUG, (char *) m_pFileName->GetBuffer(), HXCREATEINSTANCESTR " Failure");
  1854. result = CREATE_INSTANCHXR_FAILURE;
  1855. goto cleanup;
  1856.     }
  1857.     HX_LOG_CHECKPOINT( "Plugin instance created" );
  1858.     // To be a valid plugin a DLL must support IHXPlugin
  1859.     // In addition, it may support IHXPluginFactory
  1860.     if( SUCCEEDED( pInstance->QueryInterface( IID_IHXPluginFactory, (void**) &pIFactory ) ) )
  1861.     {
  1862. m_bHas_factory = TRUE;
  1863. m_NumOfPlugins = pIFactory->GetNumPlugins();
  1864. HX_RELEASE( pIFactory );
  1865.     }
  1866.     else if( SUCCEEDED( pInstance->QueryInterface( IID_IHXPlugin, (void**) &pPlugin ) ) )
  1867.     {
  1868. m_bHas_factory = FALSE;
  1869. m_NumOfPlugins = 1;
  1870. IHXComponentPlugin* pIPackage = NULL;
  1871. if (SUCCEEDED (pInstance->QueryInterface (IID_IHXComponentPlugin, (void**) &pIPackage)))
  1872. {
  1873. #ifndef _WINDOWS // XXXHP TEMPORARY - viper team has requested that this shouldn't assert for now on windows.
  1874.     HX_ASSERT (m_fpShutdown);
  1875. #endif
  1876.     pPlugin->InitPlugin (pContext);
  1877.     m_packageName = pIPackage->GetPackageName ();
  1878.     HX_RELEASE (pIPackage);
  1879. }
  1880. HX_RELEASE( pPlugin );
  1881.     }
  1882.     else
  1883.     {
  1884. result = BAD_PLUGIN;
  1885. goto cleanup;
  1886.     }
  1887.     // We are now loaded.
  1888.     HX_RELEASE(pInstance);
  1889.     m_bLoaded = TRUE;
  1890. cleanup:
  1891.     HX_LOG_CHECKPOINT( "Plugin2Handler::PluginDLL::Load() exiting" );
  1892.     return result;
  1893. }
  1894. HX_RESULT Plugin2Handler::PluginDLL::WritePref2(REF(CPluginInfoWriter) piw)
  1895. {
  1896.     // the string is defined as follows:
  1897.     // {name, checksum, BOOL has factory, size, INT numplugins},{ditto}
  1898.     // get the checksum
  1899.     IHXBuffer* pPathBuffer = GetMountPoint()->Path();
  1900.     IHXBuffer* pNewChecksum = m_pPlugin2Handler->ChecksumFile( (char *) m_pFileName->GetBuffer(), pPathBuffer);
  1901.     if (!pNewChecksum)
  1902.     {
  1903. HX_RELEASE(pPathBuffer);
  1904. piw.Write("");
  1905. m_bDoesExist = FALSE;
  1906. return HXR_OK;
  1907.     }
  1908.     char* pszCheckSum = (char*) pNewChecksum->GetBuffer();
  1909.     char szSize[16]; /* Flawfinder: ignore */ // XXXAH ok, if some day in the future we have terabite size DLLs then this will fail.
  1910.     itoa(m_nSizeBites, szSize, 10);
  1911.     char szNumPlugins[16]; /* Flawfinder: ignore */
  1912.     itoa(m_NumOfPlugins, szNumPlugins, 10);
  1913.     piw.Write("{");
  1914.     piw.Write((const char*) m_pFileName->GetBuffer());
  1915.     piw.Write(",");
  1916.     piw.Write(pszCheckSum);
  1917.     piw.Write(",");
  1918.     if (m_bHas_factory)
  1919.     {
  1920. piw.Write("1");
  1921.     }
  1922.     else
  1923.     {
  1924. piw.Write("0");
  1925.     }
  1926.     piw.Write(",");
  1927.     piw.Write(szSize);
  1928.     piw.Write(",");
  1929.     piw.Write(szNumPlugins);
  1930.     piw.Write("}");
  1931.     HX_RELEASE(pNewChecksum);
  1932.     HX_RELEASE(pPathBuffer);
  1933.     return HXR_OK;
  1934. }
  1935. HX_RESULT Plugin2Handler::PluginDLL::WritePref(PreferenceEnumerator* pPrefEnum)
  1936. {
  1937.     char pPrefValue[(1<<8)]; /* Flawfinder: ignore */
  1938.     IHXBuffer* pBuffer = new CHXBuffer();
  1939.     pBuffer->AddRef();
  1940.     pBuffer->Set((const UCHAR*)"",1);
  1941. #ifndef _MACINTOSH
  1942.     pPrefEnum->WriteSubPref( (const char *) m_pFileName->GetBuffer(), pBuffer );
  1943. #endif
  1944.     HX_VERIFY(HXR_OK == pPrefEnum->BeginSubPref( (const char *) m_pFileName->GetBuffer() ) );
  1945.     // the number of plugins
  1946.     sprintf(pPrefValue, "%d", m_NumOfPlugins); /* Flawfinder: ignore */
  1947.     pBuffer->Set((UCHAR*)(const char*)pPrefValue, strlen(pPrefValue)+1);
  1948.     pPrefEnum->WriteSubPref(PLUGIN_NUM_PLUGINS, pBuffer);
  1949.     // the checksum of the file.
  1950.     IHXBuffer* pPathBuffer = GetMountPoint()->Path();
  1951.     IHXBuffer* pNewChecksum = m_pPlugin2Handler->ChecksumFile((char*)m_pFileName->GetBuffer(), pPathBuffer);
  1952.     pPrefEnum->WriteSubPref(PLUGIN_FILE_CHECKSUM, pNewChecksum);
  1953.     HX_RELEASE(pNewChecksum);
  1954.     HX_RELEASE(pPathBuffer);
  1955.     // the size of the DLL
  1956.     sprintf(pPrefValue, "%d", (int)m_nSizeBites); /* Flawfinder: ignore */
  1957.     pBuffer->Set((const UCHAR*)pPrefValue, strlen(pPrefValue)+1);
  1958.     pPrefEnum->WriteSubPref(PLUGIN_DLL_SIZE, pBuffer);
  1959.     // if the DLL has a factory or not.
  1960.     if (m_bHas_factory)
  1961.     {
  1962.         pBuffer->Set((const UCHAR*)"TRUE", strlen("TRUE")+1);
  1963.     }
  1964.     else
  1965.     {
  1966.         pBuffer->Set((const UCHAR*)"FALSE", strlen("FALSE")+1);
  1967.     }
  1968.     pPrefEnum->WriteSubPref(PLUGIN_HAS_FACTORY, pBuffer);
  1969.     HX_RELEASE(pBuffer);
  1970.     pPrefEnum->EndSubPref();
  1971.     return HXR_OK;
  1972. }
  1973. void Plugin2Handler::PluginDLL::SetPref(int nNumPlugins, char* pszCheckSum, int nSize, BOOL factory)
  1974. {
  1975.     m_NumOfPlugins = nNumPlugins;
  1976.     m_hash = pszCheckSum;
  1977.     m_nSizeBites = nSize;
  1978.     m_bHas_factory = factory;
  1979. }
  1980. HX_RESULT Plugin2Handler::PluginDLL::ReadPref(PreferenceEnumerator* pPrefEnum)
  1981. {
  1982.     IHXBuffer*     pBuffer;
  1983.     // Number of plugins in this DLL
  1984.     pPrefEnum->ReadPref(PLUGIN_NUM_PLUGINS, pBuffer);
  1985.     m_NumOfPlugins = atoi((const char*)pBuffer->GetBuffer());
  1986.     HX_RELEASE(pBuffer);
  1987.     // The Checksum of the DLL
  1988.     pPrefEnum->ReadPref(PLUGIN_FILE_CHECKSUM, pBuffer);
  1989.     m_hash = (char*)pBuffer->GetBuffer();
  1990.     HX_RELEASE(pBuffer);
  1991.     // the size of the DLL
  1992.     pPrefEnum->ReadPref(PLUGIN_DLL_SIZE, pBuffer);
  1993.     m_nSizeBites = atoi((const char*)pBuffer->GetBuffer());
  1994.     HX_RELEASE(pBuffer);
  1995.     // if the DLL has a factory or not.
  1996.     pPrefEnum->ReadPref(PLUGIN_HAS_FACTORY, pBuffer);
  1997.     if (strcmp((const char*)pBuffer->GetBuffer(), "FALSE"))
  1998.     {
  1999. m_bHas_factory = TRUE;
  2000.     }
  2001.     else
  2002.     {
  2003. m_bHas_factory = FALSE;
  2004.     }
  2005.     HX_RELEASE(pBuffer);
  2006.     return HXR_OK;
  2007. }
  2008. HX_RESULT Plugin2Handler::PluginDLL::Unload(BOOL safe)
  2009. {
  2010.     if (m_bLoaded)
  2011.     {
  2012. if (!safe || ( m_fCanUnload && m_fCanUnload()==HXR_OK ) )
  2013. {
  2014.     if (m_fpShutdown)
  2015.     {
  2016. if (FAILED (m_fpShutdown ())) return HXR_FAIL;
  2017. m_fpShutdown = NULL;
  2018.     }
  2019.     if (DLLAccess::DLL_OK == m_pDLLAccess->close())
  2020.     {
  2021. m_bLoaded = FALSE;
  2022. // Remove ourself from the plugin handler's CanUnload2DllList.
  2023. LISTPOSITION posCanUnload = m_pPlugin2Handler->GetCanUnload2DllList().Find( this );
  2024. if ( posCanUnload )
  2025. {
  2026.     m_pPlugin2Handler->GetCanUnload2DllList().RemoveAt( posCanUnload );
  2027. }
  2028. return HXR_OK;
  2029.     }
  2030. }
  2031.     }
  2032.     return HXR_FAIL;
  2033. }
  2034. BOOL Plugin2Handler::PluginDLL::IsLoaded()
  2035. {
  2036.     return m_bLoaded;
  2037. }
  2038. Plugin2Handler::Errors Plugin2Handler::PluginDLL::CreateInstance(IUnknown** ppUnk,
  2039.  UINT32 uIndex)
  2040. {
  2041.     if (!m_bLoaded)
  2042. return PLUGIN_NOT_FOUND;
  2043.     if (!m_bHas_factory)
  2044.     {
  2045. if (HXR_OK != m_fpCreateInstance(ppUnk))
  2046. {
  2047.     return CREATE_INSTANCHXR_FAILURE;
  2048. }
  2049.     }
  2050.     else
  2051.     {
  2052. if (uIndex > (ULONG32)(m_NumOfPlugins-1) && m_NumOfPlugins)
  2053. {
  2054.     return CANT_LOAD_INTERFACE;
  2055. }
  2056. IUnknown* pUnk;
  2057. IHXPluginFactory* pPluginFactory;
  2058. m_fpCreateInstance(&pUnk);
  2059. if (HXR_OK != pUnk->QueryInterface
  2060. (IID_IHXPluginFactory, (void**) &pPluginFactory))
  2061. {
  2062.     HX_RELEASE(pUnk);
  2063.     return CREATE_INSTANCHXR_FAILURE;
  2064. }
  2065. else
  2066. {
  2067.     HX_RELEASE(pUnk);
  2068.     if (HXR_OK != pPluginFactory->GetPlugin((UINT16)uIndex, ppUnk))
  2069.     {
  2070. HX_RELEASE(pPluginFactory);
  2071. return CREATE_INSTANCHXR_FAILURE;
  2072.     }
  2073.     HX_RELEASE(pPluginFactory);
  2074. }
  2075.     }
  2076.     m_pPlugin2Handler->AddtoLRU(this);
  2077.     m_pPlugin2Handler->UpdateCache();
  2078.     return NO_ERRORS;
  2079. }
  2080. IHXBuffer* Plugin2Handler::PluginDLL::GetFileName()
  2081. {
  2082.     m_pFileName->AddRef();
  2083.     return m_pFileName;
  2084. }
  2085. IHXBuffer* Plugin2Handler::PluginDLL::GetNamespace()
  2086. {
  2087.     if (m_pNamespace)
  2088.     {
  2089. m_pNamespace->AddRef();
  2090.     }
  2091.     return m_pNamespace;
  2092. }
  2093. void Plugin2Handler::PluginDLL::SetNamespace(IHXBuffer* pNamespace)
  2094. {
  2095.     m_pNamespace = pNamespace;
  2096.     if (m_pNamespace)
  2097.     {
  2098. m_pNamespace->AddRef();
  2099.     }
  2100. }
  2101. UINT32 Plugin2Handler::PluginDLL::AddDLLReference()
  2102. {
  2103.     return ++m_nActiveReferences;
  2104. }
  2105. UINT32 Plugin2Handler::PluginDLL::ReleaseDLLReference()
  2106. {
  2107.     --m_nActiveReferences;
  2108.     Unload();     //XXXAH this should only happen if we have set DLL unloading to true.
  2109.     return 0;
  2110. }
  2111. /////////////////////////////////////////////////////////////////////////
  2112. //  Method:
  2113. //      Plugin2Handler::PluginDLL::QueryInterface
  2114. //  Purpose:
  2115. //      Implement this to export the interfaces supported by your
  2116. //      object.
  2117. //
  2118. STDMETHODIMP
  2119. Plugin2Handler::PluginDLL::QueryInterface(REFIID riid, void** ppvObj)
  2120. {
  2121.     if (IsEqualIID(riid, IID_IUnknown))
  2122.     {
  2123.         AddRef();
  2124.         *ppvObj = (IUnknown*)this;
  2125.         return HXR_OK;
  2126.     }
  2127.     *ppvObj = NULL;
  2128.     return HXR_NOINTERFACE;
  2129. }
  2130. /////////////////////////////////////////////////////////////////////////
  2131. //  Method:
  2132. //      Plugin2Handler::PluginDLL::AddRef
  2133. //  Purpose:
  2134. //      Everyone usually implements this the same... feel free to use
  2135. //      this implementation.
  2136. //
  2137. STDMETHODIMP_(ULONG32)
  2138. Plugin2Handler::PluginDLL::AddRef()
  2139. {
  2140.     return InterlockedIncrement(&m_lRefCount);
  2141. }
  2142. /////////////////////////////////////////////////////////////////////////
  2143. //  Method:
  2144. //      Plugin2Handler::PluginDLL::Release
  2145. //  Purpose:
  2146. //      Everyone usually implements this the same... feel free to use
  2147. //      this implementation.
  2148. //
  2149. STDMETHODIMP_(ULONG32)
  2150. Plugin2Handler::PluginDLL::Release()
  2151. {
  2152.     if (InterlockedDecrement(&m_lRefCount) > 0)
  2153.     {
  2154.         return m_lRefCount;
  2155.     }
  2156.     delete this;
  2157.     return 0;
  2158. }
  2159. /**********************************************************************************
  2160. ***     Plugin2Handler::PluginMountPoint ***
  2161. ***********************************************************************************/
  2162. Plugin2Handler::PluginMountPoint::PluginMountPoint( Plugin2Handler* pContext, const char* pName,
  2163.     UINT32 majorVersion, UINT32 minorVersion, IHXBuffer* pPath ) :
  2164.     m_lRefCount( 0 ),
  2165.     m_lClientCount( 0 ),
  2166.     m_bHXCompliant( FALSE ),
  2167.     m_pIPrefs( NULL ),
  2168.     m_pIPath( NULL )
  2169. {
  2170. #ifdef HELIX_FEATURE_PREFERENCES
  2171.     // Set up a preferences object
  2172.     if( pName )
  2173.     {
  2174.         if( !strcmp( pName, HXVER_SDK_PRODUCT ) )
  2175.         {
  2176.             // Just use the preferences aggregated by the context,
  2177.             // and set ourself as HXCompliant
  2178.             m_pIPrefs = pContext->GetPreferences();
  2179.             m_bHXCompliant = TRUE;
  2180.         }
  2181.         else
  2182.         {
  2183.             IHXCommonClassFactory* pICCF = NULL;
  2184.             if( SUCCEEDED( pContext->QueryInterface( IID_IHXCommonClassFactory, (void**) &pICCF ) ) )
  2185.             {
  2186.                 IUnknown* pIUnk = NULL;
  2187.                 if( SUCCEEDED( pICCF->CreateInstance( CLSID_HXPreferences, (void**) &pIUnk ) ) )
  2188.                 {
  2189.                     IHXPreferences3* pIPrefs3 = NULL;
  2190.                     if( SUCCEEDED( pIUnk->QueryInterface( IID_IHXPreferences3, (void**) &pIPrefs3 ) ) )
  2191.                     {
  2192.                         if( SUCCEEDED( pIPrefs3->Open( HXVER_COMPANY, pName, majorVersion, minorVersion ) ) )
  2193.                         {
  2194.                             pIPrefs3->QueryInterface( IID_IHXPreferences, (void**) &m_pIPrefs );
  2195.                         }
  2196.                         HX_RELEASE( pIPrefs3 );
  2197.                     }
  2198.                     HX_RELEASE( pIUnk );
  2199.                 }
  2200.                 HX_RELEASE( pICCF );
  2201.             }
  2202.         }
  2203.         HX_ASSERT( m_pIPrefs );
  2204.     }
  2205. #endif
  2206.     // Set up the path.
  2207.     if( !pPath && m_pIPrefs )
  2208.     {
  2209.         // Handle the special case path as well
  2210.         if( m_bHXCompliant )
  2211.         {
  2212.             m_pIPath = pContext->GetPluginDir();
  2213.         }
  2214.         else
  2215.         {
  2216.             m_pIPrefs->ReadPref( PLUGIN_FILE_PATH, m_pIPath );
  2217.         }
  2218.     }
  2219.     else
  2220.     {
  2221.         m_pIPath = pPath;
  2222.         if( m_pIPath )
  2223.         {
  2224.             m_pIPath->AddRef();
  2225.         }
  2226.     }
  2227. }
  2228. Plugin2Handler::PluginMountPoint::~PluginMountPoint()
  2229. {
  2230.     HX_RELEASE( m_pIPrefs );
  2231.     HX_RELEASE( m_pIPath );
  2232. }
  2233. STDMETHODIMP_(ULONG32)
  2234. Plugin2Handler::PluginMountPoint::AddRef()
  2235. {
  2236.     return InterlockedIncrement(&m_lRefCount);
  2237. }
  2238. STDMETHODIMP_(ULONG32)
  2239. Plugin2Handler::PluginMountPoint::Release()
  2240. {
  2241.     if (InterlockedDecrement(&m_lRefCount) > 0)
  2242.     {
  2243.         return m_lRefCount;
  2244.     }
  2245.     delete this;
  2246.     return 0;
  2247. }
  2248. void Plugin2Handler::PluginMountPoint::AddClient()
  2249. {
  2250.     m_lClientCount++;
  2251. }
  2252. INT32 Plugin2Handler::PluginMountPoint::RemoveClient()
  2253. {
  2254.     return ( --m_lClientCount );
  2255. }
  2256. // XXXND  This is for backward compatibility
  2257. BOOL Plugin2Handler::PluginMountPoint::IsHXCompliant()
  2258. {
  2259.     return m_bHXCompliant;
  2260. }
  2261. IHXPreferences* Plugin2Handler::PluginMountPoint::Prefs()
  2262. {
  2263.     if( m_pIPrefs )
  2264. m_pIPrefs->AddRef();
  2265.     return m_pIPrefs;
  2266. }
  2267. IHXBuffer* Plugin2Handler::PluginMountPoint::Path()
  2268. {
  2269.     if( m_pIPath )
  2270. m_pIPath->AddRef();
  2271.     return m_pIPath;
  2272. }
  2273. #if 0
  2274. /**********************************************************************************
  2275. ***     Plugin2Handler::PluginMonitor ***
  2276. ***********************************************************************************/
  2277. /*
  2278.     The plugin monitor is responsible for monitoring each and every plugin
  2279.     that get instance is used to create. It attaches itself to the addref
  2280.     and relase of the target, and will mimic the refcount. When the object
  2281.     is destroyed it will send a notification to the plugin handler, thus
  2282.     the plugin handler will be able to determine if it is safe to
  2283.     unload the plugins.
  2284. */
  2285. CHXMapPtrToPtr Plugin2Handler::PluginMonitor::MapTargetToMonitor;
  2286. // when we are constructed we will attach ourselves to the target.
  2287. Plugin2Handler::PluginMonitor::PluginMonitor(IUnknown* MonitorTarget,
  2288.      IHXPluginWatcherResponse* pResponse):
  2289. m_lFakeRefCount(1)
  2290.     , m_lRefCount(0)
  2291.     ,   m_pPluginWatcherResponse(pResponse)
  2292. {
  2293. // put this back in if you ever expect plugin watchers to work
  2294. //    if (HXR_OK !=pResponse->QueryInterface(IID_IHXPluginWatcherResponse,
  2295. // (void**) &m_pPluginWatcherResponse))
  2296. //    {
  2297. // return;
  2298. //    }
  2299.     void** ppVoid     = *(void***)MonitorTarget;
  2300.     m_fpAddRefPointer     = (FPWatchRef) (*(ppVoid+1)); // cast to (FPWatchRef) ??
  2301.     m_fpReleasePointer     = (FPWatchRef) (*(ppVoid+2));
  2302.     *(ppVoid+1) = Plugin2Handler::PluginMonitor::FakeAddRef;
  2303.     *(ppVoid+2) = Plugin2Handler::PluginMonitor::FakeRelease;
  2304.     AddMonitorTarget(MonitorTarget, this);
  2305. }
  2306. Plugin2Handler::PluginMonitor::~PluginMonitor()
  2307. {
  2308.     // XXXAH should we do something here?
  2309. }
  2310. HX_RESULT Plugin2Handler::PluginMonitor::AddMonitorTarget(void* pMonitorTarget,
  2311.   PluginMonitor* pPluginMonitor)
  2312. {
  2313.     void* TempVal = NULL;
  2314.     if (MapTargetToMonitor.Lookup(pMonitorTarget, TempVal ))
  2315.     {
  2316. return HXR_FAIL;
  2317.     }
  2318.     MapTargetToMonitor.SetAt(pMonitorTarget, (void*)pPluginMonitor);
  2319.     return HXR_OK;
  2320. }
  2321. HX_RESULT Plugin2Handler::PluginMonitor::ReleaseMonitorTarget(void* pMonitorTarget)
  2322. {
  2323.     void* TempVal = NULL;
  2324.     if (!MapTargetToMonitor.Lookup(pMonitorTarget, TempVal))
  2325.     {
  2326. return HXR_FAIL;
  2327.     }
  2328.     MapTargetToMonitor.RemoveKey(pMonitorTarget);
  2329.     return HXR_OK;
  2330. }
  2331. Plugin2Handler::PluginMonitor* Plugin2Handler::PluginMonitor::GetThisPointerFromTarget(void* pMonitorTarget)
  2332. {
  2333.     PluginMonitor* RetVal = NULL;
  2334.     if (!MapTargetToMonitor.Lookup(pMonitorTarget, (void*&)RetVal))
  2335.     {
  2336. return NULL;
  2337.     }
  2338.     return RetVal;
  2339. }
  2340. ULONG32 STDMETHODCALLTYPE Plugin2Handler::PluginMonitor::FakeAddRef(void* pvoid)
  2341. {
  2342.     PluginMonitor*  pThis   = GetThisPointerFromTarget(pvoid);
  2343.     ULONG32     nResult = 0;
  2344.     if (pThis)
  2345.     {
  2346. nResult = pThis->m_fpAddRefPointer(pvoid);
  2347. InterlockedIncrement(&(pThis->m_lFakeRefCount));
  2348.     }
  2349.     return nResult;
  2350. }
  2351. ULONG32 STDMETHODCALLTYPE Plugin2Handler::PluginMonitor::FakeRelease(void* pvoid)
  2352. {
  2353.     PluginMonitor*  pThis   = GetThisPointerFromTarget(pvoid);
  2354.     ULONG32     nResult = 0;
  2355.     if (pThis)
  2356.     {
  2357. nResult = pThis->m_fpReleasePointer(pvoid);
  2358. InterlockedDecrement(&(pThis->m_lFakeRefCount));
  2359. if (pThis->m_lFakeRefCount)
  2360.     return nResult;
  2361. if (nResult<1)
  2362. {
  2363.     pThis->m_pPluginWatcherResponse->AllObjectsDeleted((void*)pvoid);
  2364.     pThis->m_pPluginWatcherResponse->Release();
  2365.     ReleaseMonitorTarget(pvoid);
  2366.     // restore the v-table.
  2367.     void** pVoid = *(void***)pvoid;
  2368.     (*(pVoid+1)) = pThis->m_fpAddRefPointer;
  2369.     (*(pVoid+2)) = pThis->m_fpReleasePointer;
  2370.     delete pThis;
  2371.     return 0;
  2372. }
  2373.     }
  2374.     return nResult;
  2375. }
  2376. /////////////////////////////////////////////////////////////////////////
  2377. //  Method:
  2378. //      Plugin2Handler::PluginMonitor::QueryInterface
  2379. //  Purpose:
  2380. //      Implement this to export the interfaces supported by your
  2381. //      object.
  2382. //
  2383. STDMETHODIMP
  2384. Plugin2Handler::PluginMonitor::QueryInterface(REFIID riid, void** ppvObj)
  2385. {
  2386.     if (IsEqualIID(riid, IID_IUnknown))
  2387.     {
  2388.         AddRef();
  2389.         *ppvObj = (IUnknown*)this;
  2390.         return HXR_OK;
  2391.     }
  2392.     *ppvObj = NULL;
  2393.     return HXR_NOINTERFACE;
  2394. }
  2395. /////////////////////////////////////////////////////////////////////////
  2396. //  Method:
  2397. //      Plugin2Handler::PluginMonitor::AddRef
  2398. //  Purpose:
  2399. //      Everyone usually implements this the same... feel free to use
  2400. //      this implementation.
  2401. //
  2402. STDMETHODIMP_(ULONG32)
  2403. Plugin2Handler::PluginMonitor::AddRef()
  2404. {
  2405.     return InterlockedIncrement(&m_lRefCount);
  2406. }
  2407. /////////////////////////////////////////////////////////////////////////
  2408. //  Method:
  2409. //      Plugin2Handler::PluginMonitor::Release
  2410. //  Purpose:
  2411. //      Everyone usually implements this the same... feel free to use
  2412. //      this implementation.
  2413. //
  2414. STDMETHODIMP_(ULONG32)
  2415. Plugin2Handler::PluginMonitor::Release()
  2416. {
  2417.     if (InterlockedDecrement(&m_lRefCount) > 0)
  2418.     {
  2419.         return m_lRefCount;
  2420.     }
  2421.     delete this;
  2422.     return 0;
  2423. }
  2424. #endif
  2425. ///////////////////////////////////////////////////////////////////////////////
  2426. //
  2427. // Plugin2Handler::CheckDirectory
  2428. //
  2429. ///////////////////////////////////////////////////////////////////////////////
  2430. Plugin2Handler::Errors Plugin2Handler::Stat(const char* pszFilename, struct stat* pStatBuffer)
  2431. {
  2432.     CHXString strFileName;
  2433.     memset(pStatBuffer,0,sizeof(*pStatBuffer));
  2434. #ifndef _STATICALLY_LINKED
  2435.     if(stat(pszFilename, pStatBuffer) < 0)
  2436. return CANT_OPEN_DLL;
  2437. #endif
  2438.     pStatBuffer->st_atime = 0;
  2439.     return NO_ERRORS ;
  2440. }
  2441. IHXBuffer* Plugin2Handler::ConvertToAsciiString(char* pBuffer, UINT32 nBuffLen)
  2442. {
  2443.     char* pszOut = new char[nBuffLen*2+1];
  2444.     char* pszStartOut = pszOut;
  2445.     char Nibble;
  2446.     IHXBuffer* pOutBuffer = new CHXBuffer(); // This is the ONLY place where this is done!
  2447.     pOutBuffer->AddRef();
  2448.     for (int i = 0; i<(int)nBuffLen; i++)
  2449.     {
  2450. Nibble = (*pBuffer >> 4) & 15;
  2451. *pszOut= (Nibble > 9 ) ? Nibble+55 : Nibble +48;
  2452. pszOut++;
  2453. Nibble = *pBuffer & 15;
  2454. *pszOut= (Nibble> 9 ) ? Nibble+ 55 : Nibble+48;
  2455. pszOut++;
  2456. pBuffer++;
  2457.     }
  2458.     *pszOut = 0;
  2459.     pOutBuffer->Set((UCHAR*)pszStartOut, strlen(pszStartOut)+1);
  2460.     delete[] pszStartOut;
  2461.     return pOutBuffer;
  2462. }
  2463. IHXBuffer* Plugin2Handler::ChecksumFile(char* pszFileName, IHXBuffer* pPathBuffer)
  2464. {
  2465. #ifdef _STATICALLY_LINKED /* don't need checksumming for static linking */
  2466.     return ConvertToAsciiString("abc", 3);
  2467. #endif
  2468.     char     pszFileNameWithPath[(1<<10)]; /* Flawfinder: ignore */
  2469.     SafeStrCpy(pszFileNameWithPath, (char*)pPathBuffer->GetBuffer(), (1<<10));
  2470.     INT32 nLen = ::strlen(pszFileNameWithPath);
  2471.     if (pszFileNameWithPath[nLen - 1] != Plugin2Handler::zm_cDirectorySeperator)
  2472.     {
  2473. SafeStrCat(pszFileNameWithPath, Plugin2Handler::zm_pszDirectorySeperator, (1<<10));
  2474. nLen += strlen(Plugin2Handler::zm_pszDirectorySeperator);
  2475.     }
  2476.     SafeStrCat(pszFileNameWithPath, pszFileName, (1<<10));
  2477.     UCHAR tempbuf[16] = "";
  2478.     struct stat stat_stuct;
  2479.     Errors statError = PLUGIN_NOT_FOUND;
  2480. #ifdef _MAC_CFM
  2481.     CHXFileSpecifier fileSpecifier(pszFileNameWithPath);
  2482.     if (SUCCEEDED(CHXFileSpecUtils::ResolveFileSpecifierAlias(fileSpecifier)))
  2483.     {
  2484. statError = Stat(fileSpecifier.GetPathName(), &stat_stuct);
  2485.     }
  2486. #elif defined(_MAC_MACHO)
  2487. FSRef targetFSRef;
  2488. Boolean isDir;
  2489. OSStatus err = ::FSPathMakeRef(pszFileNameWithPath, &targetFSRef, &isDir);
  2490. if (err == noErr)
  2491. {
  2492. Boolean resolveAliasChains = true;
  2493. Boolean targetIsDir, wasAlias;
  2494. err = FSResolveAliasFileWithMountFlags(&targetFSRef, resolveAliasChains, &targetIsDir, &wasAlias, kResolveAliasFileNoUI);
  2495. if (err == noErr && wasAlias)
  2496. {
  2497. err = FSRefMakePath(&targetFSRef, pszFileNameWithPath, (1<<10));
  2498.   }
  2499. }
  2500.     statError = Stat(pszFileNameWithPath, &stat_stuct);
  2501. #else
  2502.     statError = Stat(pszFileNameWithPath, &stat_stuct);
  2503. #endif
  2504.     stat_stuct.st_atime = 0;
  2505.     if (NO_ERRORS!=statError)
  2506.     {
  2507. return NULL;
  2508.     }
  2509.     md5_state_t MD5_data;
  2510.     md5_init(&MD5_data);
  2511.     md5_append(&MD5_data,(UCHAR*)&(stat_stuct),sizeof(stat_stuct));
  2512.     md5_finish(tempbuf, &MD5_data);
  2513.     return ConvertToAsciiString((char*)tempbuf, sizeof(tempbuf));
  2514. }
  2515. /************************************************************************
  2516. *     PreferenceEnumerator *
  2517. * *
  2518. *   This class encapsulates the optional IHXPreference Enumerator *
  2519. *   interafce which the top level client need not implement. *
  2520. *   If the top level client does implement IHXPreferenceEnumerator *
  2521. *   then this class is simply a wrapper. If the top level client *
  2522. *   does not implement it (why not?) then this class will perform *
  2523. *   the necessary leg work. *
  2524. ************************************************************************/
  2525. Plugin2Handler::PreferenceEnumerator::PreferenceEnumerator(IHXPreferences* pIHXPref)
  2526.     :   m_pPrefEnum(NULL)
  2527.     , m_pPreferences(pIHXPref)
  2528. {
  2529.     m_pPreferences->AddRef();
  2530.     IHXPreferences2* pPref2;
  2531.     if (HXR_OK == pIHXPref->QueryInterface(IID_IHXPreferences2, (void**) &pPref2))
  2532.     {
  2533. pPref2->GetPreferenceEnumerator(m_pPrefEnum);
  2534. pPref2->Release();
  2535.     }
  2536. }
  2537. Plugin2Handler::PreferenceEnumerator::~PreferenceEnumerator()
  2538. {
  2539.     ULONG32 nRefCount;
  2540.     /* go through the list of prop names and delete all of the buffers */
  2541.     for(CHXSimpleList::Iterator i = m_ListofProps.Begin(); i!= m_ListofProps.End(); ++i)
  2542.     {
  2543. nRefCount = ((IHXBuffer*)*i )->Release();
  2544.     }
  2545.     m_ListofProps.RemoveAll();
  2546.     HX_RELEASE(m_pPrefEnum);
  2547.     HX_RELEASE(m_pPreferences);
  2548. }
  2549. HX_RESULT Plugin2Handler::PreferenceEnumerator::ResetPropNameList()
  2550. {
  2551.     ULONG32 nRefCount;
  2552.     /* go through the list of prop names and delete all of the buffers */
  2553.     for(CHXSimpleList::Iterator i = m_ListofProps.Begin(); i!= m_ListofProps.End(); ++i)
  2554.     {
  2555. nRefCount = ((IHXBuffer*)*i )->Release();
  2556.     }
  2557.     m_ListofProps.RemoveAll();
  2558.     /* create the list of props at this level*/
  2559.     /* now store the name of the preference in the 'special' reg value. */
  2560.     char     pszRegKey[(1<<8)]; /* Flawfinder: ignore */
  2561.     IHXBuffer*     pKeyNamesBuffer = NULL;
  2562.     IHXBuffer*     pTempBuffer = NULL;
  2563.     SafeStrCpy(pszRegKey, (const char*)m_RegKey, (1<<8));
  2564.     SafeStrCat(pszRegKey, zm_pszRegKeySeperator, (1<<8));
  2565.     SafeStrCat(pszRegKey, zm_pszKeyNameRegKey, (1<<8));
  2566.     if (HXR_OK == m_pPreferences->ReadPref(pszRegKey, pKeyNamesBuffer))
  2567.     {
  2568. /* ok it was found ... parse the list */
  2569. char* token;
  2570. token = strtok((char*)pKeyNamesBuffer->GetBuffer(), zm_pszValueSeperator);
  2571. while (token)
  2572. {
  2573.     pTempBuffer = new CHXBuffer;
  2574.     pTempBuffer->AddRef();
  2575.     pTempBuffer->Set((const UCHAR*) token, strlen(token)+1);
  2576.     m_ListofProps.AddTail((void*)pTempBuffer);
  2577.     token = strtok(NULL, zm_pszValueSeperator);
  2578. }
  2579. HX_RELEASE(pKeyNamesBuffer);
  2580.     }
  2581.     else
  2582.     {
  2583. return HXR_FAIL;
  2584.     }
  2585.     return HXR_OK;
  2586. }
  2587. HX_RESULT Plugin2Handler::PreferenceEnumerator::BeginSubPref(const char* pszSubPref)
  2588. {
  2589.     if (m_RegKey.GetLength())
  2590.     {
  2591. m_RegKey += "\";
  2592.     }
  2593.     m_RegKey += pszSubPref;
  2594.     if (m_pPrefEnum)
  2595.     {
  2596. return m_pPrefEnum->BeginSubPref(pszSubPref);
  2597.     }
  2598.     ResetPropNameList();
  2599.     return HXR_OK;
  2600. }
  2601. HX_RESULT Plugin2Handler::PreferenceEnumerator::EndSubPref()
  2602. {
  2603.     char* pNewEnd = (char*)strrchr((const char*) m_RegKey , '\');
  2604.     if (pNewEnd)
  2605.     {
  2606. *pNewEnd = 0;
  2607. CHXString sTemp = (const char*) m_RegKey;
  2608. m_RegKey = sTemp;
  2609.     }
  2610.     else
  2611.     {
  2612. m_RegKey = "";
  2613.     }
  2614.     if (m_pPrefEnum)
  2615.     {
  2616. return m_pPrefEnum->EndSubPref();
  2617.     }
  2618.     ResetPropNameList();
  2619.     return HXR_OK;
  2620. }
  2621. HX_RESULT Plugin2Handler::PreferenceEnumerator::WriteSubPref(const char* pszSubName, IHXBuffer* pBuffer)
  2622. {
  2623.     char     pszRegKey[(1<<8)]; /* Flawfinder: ignore */
  2624.     IHXBuffer*     pKeyNameBuffer = NULL;
  2625.     SafeStrCpy(pszRegKey, (const char*)m_RegKey, (1<<8));
  2626.     SafeStrCat(pszRegKey, zm_pszRegKeySeperator, (1<<8));
  2627.     SafeStrCat(pszRegKey, pszSubName, (1<<8));
  2628.     m_pPreferences->WritePref(pszRegKey, pBuffer);
  2629.     /* now store the name of the preference in the 'special' reg value. */
  2630.     SafeStrCpy(pszRegKey, (const char*)m_RegKey, (1<<8));
  2631.     SafeStrCat(pszRegKey, zm_pszRegKeySeperator, (1<<8));
  2632.     SafeStrCat(pszRegKey, zm_pszKeyNameRegKey, (1<<8));
  2633.     /* note: since we do not have an API for removing reg entries it
  2634. is OK to simply append to the list all of the time */
  2635.     if (HXR_OK == m_pPreferences->ReadPref(pszRegKey, pKeyNameBuffer))
  2636.     {
  2637. /*  hey let's check to see if the string we are adding is
  2638.     already in the list of tokens. If so we won't add it */
  2639. char* pszTempString = new char[strlen((char*)pKeyNameBuffer->GetBuffer())+1];
  2640. strcpy(pszTempString, (char*)pKeyNameBuffer->GetBuffer()); /* Flawfinder: ignore */
  2641. char* token;
  2642. BOOL  bFound = FALSE;
  2643. token = strtok(pszTempString, zm_pszValueSeperator);
  2644. while (token)
  2645. {
  2646.     if (!strcasecmp(token, pszSubName))
  2647.     {
  2648. bFound = TRUE;
  2649. break;
  2650.     }
  2651.     token = strtok(NULL, zm_pszValueSeperator);
  2652. }
  2653. delete[] pszTempString;
  2654. if (bFound)
  2655. {
  2656.     pKeyNameBuffer->Release();
  2657.     return HXR_OK;
  2658. }
  2659. /* ok we already have this string. Let's append to it. */
  2660. INT32 nLen = pKeyNameBuffer->GetSize()+strlen(pszSubName) + 2;
  2661. char* pszTemp = new char [nLen];
  2662. SafeStrCpy(pszTemp,  (char*)pKeyNameBuffer->GetBuffer(), nLen);
  2663. SafeStrCat(pszTemp, zm_pszValueSeperator, nLen);
  2664. SafeStrCat(pszTemp, pszSubName, nLen);
  2665. pKeyNameBuffer->Release();
  2666. pKeyNameBuffer = new CHXBuffer();
  2667. pKeyNameBuffer->AddRef();
  2668. pKeyNameBuffer->Set((const UCHAR*) pszTemp, strlen(pszTemp)+1);
  2669. delete [] pszTemp;
  2670. m_pPreferences->WritePref(pszRegKey, pKeyNameBuffer);
  2671. pKeyNameBuffer->Release();
  2672. /* add this to the list of props */
  2673. pKeyNameBuffer = new CHXBuffer();
  2674. pKeyNameBuffer->AddRef();
  2675. pKeyNameBuffer->Set((const UCHAR*) pszSubName, strlen(pszSubName)+1);
  2676. m_ListofProps.AddTail((void*)pKeyNameBuffer);
  2677.     }
  2678.     else
  2679.     {
  2680. pKeyNameBuffer = new CHXBuffer();
  2681. pKeyNameBuffer->AddRef();
  2682. pKeyNameBuffer->Set((const UCHAR*) pszSubName, strlen(pszSubName)+1);
  2683. m_pPreferences->WritePref(pszRegKey, pKeyNameBuffer);
  2684. /* add this to the list of props */
  2685. m_ListofProps.AddTail((void*)pKeyNameBuffer);
  2686.     }
  2687.     return HXR_OK;
  2688. }
  2689. HX_RESULT Plugin2Handler::PreferenceEnumerator::ReadPref(const char* pszSubName, REF(IHXBuffer*) /*OUT*/ pBuffer)
  2690. {
  2691.     if (m_pPrefEnum)
  2692.     {
  2693. return m_pPrefEnum->ReadPref(pszSubName, pBuffer);
  2694.     }
  2695.     char     pszRegKey[(1<<8)]; /* Flawfinder: ignore */
  2696.     SafeStrCpy(pszRegKey, (const char*)m_RegKey, (1<<8));
  2697.     SafeStrCat(pszRegKey, zm_pszRegKeySeperator, (1<<8));
  2698.     SafeStrCat(pszRegKey, pszSubName, (1<<8));
  2699.     if (m_pPreferences)
  2700. return m_pPreferences->ReadPref(pszRegKey, pBuffer);
  2701.     else
  2702. return HXR_FAIL;
  2703. }
  2704. HX_RESULT Plugin2Handler::PreferenceEnumerator::GetPrefKey(UINT32 nIndex, IHXBuffer*& pBuffer)
  2705. {
  2706.     if (m_pPrefEnum)
  2707.     {
  2708. return m_pPrefEnum->GetPrefKey(nIndex, pBuffer);
  2709.     }
  2710.     // get the Ith element of the list and and return it.
  2711.     LISTPOSITION pPos = m_ListofProps.FindIndex(nIndex);
  2712.     if (pPos)
  2713.     {
  2714. pBuffer = (IHXBuffer*)m_ListofProps.GetAt(pPos);
  2715. pBuffer->AddRef();
  2716.     }
  2717.     else
  2718.     {
  2719. return HXR_FAIL;
  2720.     }
  2721.     return HXR_OK;
  2722. }
  2723. /********************************************************************
  2724. *
  2725. * Plugin Enumeration
  2726. *
  2727. ********************************************************************/
  2728. BEGIN_INTERFACE_LIST_NOCREATE( CPluginEnumerator )
  2729.     INTERFACE_LIST_ENTRY_SIMPLE( IHXPluginSearchEnumerator )
  2730. END_INTERFACE_LIST
  2731. CPluginEnumerator::CPluginEnumerator() :
  2732.     m_nIndex(0)
  2733. {
  2734. }
  2735. CPluginEnumerator::~CPluginEnumerator()
  2736. {
  2737. }
  2738. STDMETHODIMP_( UINT32 )
  2739. CPluginEnumerator::GetNumPlugins()
  2740. {
  2741.     return m_ListOfPlugins.GetCount();
  2742. }
  2743. STDMETHODIMP_( void )
  2744. CPluginEnumerator::GoHead()
  2745. {
  2746.     m_nIndex = 0;
  2747. }
  2748. STDMETHODIMP
  2749. CPluginEnumerator::GetNextPlugin( REF(IUnknown*) pIUnkResult, IUnknown* pIUnkOuter )
  2750. {
  2751.     // Initialize out params
  2752.     pIUnkResult = NULL;
  2753.     HX_RESULT res = GetPluginAt( m_nIndex, pIUnkResult, pIUnkOuter );
  2754.     m_nIndex++;
  2755.     return res;
  2756. }
  2757. STDMETHODIMP
  2758. CPluginEnumerator::GetNextPluginInfo( REF(IHXValues*) pRetValues )
  2759. {
  2760.     // Initialize out params
  2761.     pRetValues = NULL;
  2762.     HX_RESULT res = GetPluginInfoAt( m_nIndex, pRetValues );
  2763.     m_nIndex++;
  2764.     return res;
  2765. }
  2766. STDMETHODIMP
  2767. CPluginEnumerator::GetPluginAt( UINT32 index, REF(IUnknown*) pIUnkResult, IUnknown* pIUnkOuter )
  2768. {
  2769.     // Initialize out params
  2770.     pIUnkResult = NULL;
  2771.     HX_RESULT res = HXR_FAIL;
  2772.     LISTPOSITION pos = m_ListOfPlugins.FindIndex(index);
  2773.     if (pos)
  2774.     {
  2775. Plugin2Handler::Plugin* pPlugin = (Plugin2Handler::Plugin*) m_ListOfPlugins.GetAt(pos);
  2776. if (pPlugin)
  2777. {
  2778.     if (Plugin2Handler::NO_ERRORS == pPlugin->GetInstance( pIUnkResult, pIUnkOuter ))
  2779.     {
  2780. res = HXR_OK;
  2781.     }
  2782. }
  2783.     }
  2784.     return res;
  2785. }
  2786. STDMETHODIMP
  2787. CPluginEnumerator::GetPluginInfoAt( UINT32 index, REF(IHXValues*) pRetValues )
  2788. {
  2789.     // Initialize out params
  2790.     pRetValues = NULL;
  2791.     HX_RESULT res = HXR_FAIL;
  2792.     LISTPOSITION pos = m_ListOfPlugins.FindIndex(m_nIndex);
  2793.     m_nIndex++;
  2794.     if (pos)
  2795.     {
  2796. Plugin2Handler::Plugin* pPlugin = (Plugin2Handler::Plugin*) m_ListOfPlugins.GetAt(pos);
  2797. if (pPlugin)
  2798. {
  2799.     res = pPlugin->GetPluginInfo( pRetValues );
  2800. }
  2801.     }
  2802.     return res;
  2803. }
  2804. void CPluginEnumerator::Add(Plugin2Handler::Plugin* pPlugin)
  2805. {
  2806.     IHXValues*     pPluginValues   = NULL;
  2807.     IHXBuffer*     pBuffer     = NULL;
  2808.     BOOL     bAdded     = FALSE;
  2809.     if (HXR_OK == pPlugin->GetPluginInfo(pPluginValues) && pPluginValues)
  2810.     {
  2811. if (HXR_OK == pPluginValues->GetPropertyCString(PLUGIN_DESCRIPTION2, pBuffer) &&
  2812.     pBuffer)
  2813. {
  2814.     if (strstr((const char*)pBuffer->GetBuffer(), "RealNetworks"))
  2815.     {
  2816. m_ListOfPlugins.AddHead(pPlugin);
  2817. bAdded = TRUE;
  2818.     }
  2819. }
  2820. HX_RELEASE(pBuffer);
  2821.     }
  2822.     if (!bAdded)
  2823.     {
  2824. m_ListOfPlugins.AddTail(pPlugin);
  2825.     }
  2826. }
  2827. HX_RESULT CPluginEnumerator::GetNext(REF(IUnknown*) pRetUnk)
  2828. {
  2829.     pRetUnk = NULL;
  2830.     return GetNextPlugin( pRetUnk, NULL );
  2831. }
  2832. CPluginInfoWriter::CPluginInfoWriter() :
  2833. m_pIHXBuffer(NULL),
  2834. m_pIHXPreferences(NULL),
  2835. m_NumWrites(0),
  2836. m_BufUsed(0),
  2837. m_BufSize(0),
  2838. m_Checksum(0)
  2839. {
  2840. }
  2841. CPluginInfoWriter::~CPluginInfoWriter()
  2842. {
  2843.     if (m_Checksum)
  2844.     {
  2845. CHXString checksum;
  2846. checksum.Format ("%u", m_Checksum);
  2847. Write (checksum); // note this will increment m_Checksum but we don't care, we got the value we wanted.
  2848.     }
  2849.     Flush ();
  2850.     HX_RELEASE(m_pIHXBuffer);
  2851.     HX_RELEASE(m_pIHXPreferences);
  2852. }
  2853. HX_RESULT CPluginInfoWriter::Init(IHXPreferences* pPrefs, const char* pBaseKeyName, IHXBuffer* pIHXBuffer)
  2854. {
  2855.     // Helper class, validation is done by caller; we only assert that it has been done
  2856.     HX_ASSERT(pPrefs);
  2857.     HX_ASSERT(pBaseKeyName);
  2858.     HX_ASSERT(pIHXBuffer);
  2859.     HX_RESULT result = HXR_FAIL;
  2860.     if(pIHXBuffer)
  2861.     {
  2862. m_pIHXBuffer = pIHXBuffer;
  2863. m_pIHXBuffer->AddRef();
  2864. m_BufSize = pIHXBuffer->GetSize();
  2865.      // Store base name used to generate plugin info reg key names...
  2866. m_BaseKeyName = pBaseKeyName;
  2867. m_pIHXPreferences = pPrefs;
  2868. m_pIHXPreferences->AddRef();
  2869. result = HXR_OK;
  2870.     }
  2871.     return result;
  2872. }
  2873. HX_RESULT CPluginInfoWriter::Write(IHXBuffer *pBuffer)
  2874. {
  2875.     HX_ASSERT(pBuffer);
  2876.     HX_RESULT result = HXR_FAIL;
  2877.     if(pBuffer)
  2878.     {
  2879. result =  Write((const char*) pBuffer->GetBuffer(), pBuffer->GetSize());
  2880.     }
  2881.     return result;
  2882. }
  2883. HX_RESULT CPluginInfoWriter::Write(const char *pInfo)
  2884. {
  2885.     HX_ASSERT(pInfo);
  2886.     HX_RESULT result = HXR_FAIL;
  2887.     if(pInfo)
  2888.     {
  2889. result = Write(pInfo, strlen(pInfo));
  2890.     }
  2891.     return result;
  2892. }
  2893. HX_RESULT CPluginInfoWriter::Write(const char *pInfo, UINT32 len)
  2894. {
  2895.     // Helper class, validation is done by caller; we only assert that it has been done
  2896.     HX_ASSERT(pInfo);
  2897.     HX_ASSERT(m_pIHXBuffer);
  2898.     // verify ASCII-7 compliance as we've had issues on double-byte machines with writing
  2899.     // ASCII-8 characters to the registry.
  2900.     HX_ASSERT(IsAscii7Compliant(pInfo, len));
  2901.     HX_RESULT result = HXR_FAIL;
  2902.     m_Checksum += len;
  2903.     // Determine how much needs to be written
  2904.     UINT32 toWrite = len;
  2905.     UCHAR* pSrcPos = (UCHAR *)pInfo;
  2906.     UCHAR* pWritePos = m_pIHXBuffer->GetBuffer();
  2907.     pWritePos += m_BufUsed;
  2908.     while(toWrite)
  2909.     {
  2910. // We subtract one that will be used to store NULL terminator added to end of buffer
  2911. UINT32 bufUnused = m_BufSize - m_BufUsed - 1;
  2912. //  We should never be negative...
  2913.      HX_ASSERT(bufUnused >= 0);
  2914. if(bufUnused >= toWrite)
  2915. {
  2916.     memcpy(pWritePos, pSrcPos, toWrite); /* Flawfinder: ignore */
  2917.     pSrcPos += toWrite;
  2918.     pWritePos += toWrite;
  2919.     m_BufUsed += toWrite;
  2920.     toWrite = 0;
  2921. }
  2922. else
  2923. {
  2924.     memcpy(pWritePos, pSrcPos, bufUnused); /* Flawfinder: ignore */
  2925.     pSrcPos += bufUnused;
  2926.     pWritePos += bufUnused;
  2927.     m_BufUsed += bufUnused;
  2928.     toWrite -= bufUnused;
  2929. }
  2930. // We need to subtract 1 for the NULL terminator added to buffer
  2931. if(m_BufUsed == m_BufSize - 1)
  2932. {
  2933.     TerminateBuffer();
  2934.     WriteToRegistry();
  2935.     pWritePos = m_pIHXBuffer->GetBuffer();
  2936.     m_BufUsed = 0;
  2937. }
  2938.     }
  2939.     return result;
  2940. }
  2941. void CPluginInfoWriter::TerminateBuffer()
  2942. {
  2943.     HX_ASSERT(m_pIHXBuffer);
  2944.     // We needed to make sure we have enough room for NULL terminator...
  2945.     HX_ASSERT(m_BufUsed <= m_BufSize  -1);
  2946.     char* pChar = (char *)m_pIHXBuffer->GetBuffer();
  2947.     pChar[m_BufUsed] = '';
  2948. }
  2949. void CPluginInfoWriter::WriteToRegistry()
  2950. {
  2951.     HX_ASSERT(m_pIHXBuffer);
  2952.     HX_ASSERT(m_pIHXPreferences);
  2953.     HX_ASSERT(m_NumWrites >= 0);
  2954.     // Build key name
  2955.     CHXString key;
  2956.     key.Format("%s%u", (const char *)m_BaseKeyName, m_NumWrites);
  2957.     m_pIHXPreferences->WritePref(key, m_pIHXBuffer);
  2958.     m_NumWrites++;
  2959. }
  2960. HX_RESULT CPluginInfoWriter::Flush()
  2961. {
  2962.     if(m_BufUsed > 0)
  2963.     {
  2964.         TerminateBuffer();
  2965. WriteToRegistry();
  2966.     }
  2967.     return HXR_OK;
  2968. }
  2969. BOOL CPluginInfoWriter::IsAscii7Compliant(const char* data, const UINT32 len)
  2970. {
  2971.     for (UINT32 i = 0; i < len; ++i)
  2972.     {
  2973. static const unsigned char ascii7Max = 0x80;
  2974. if (((const unsigned char)data [i]) & ascii7Max)
  2975. {
  2976.     return FALSE;
  2977. }
  2978.     }
  2979.     return TRUE;
  2980. }