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

Symbian

开发平台:

Visual C++

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