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

Symbian

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Source last modified: $Id: hxresmg.cpp,v 1.8.20.1 2004/07/09 02:07:27 hubbe Exp $
  3.  * 
  4.  * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
  5.  * 
  6.  * The contents of this file, and the files included with this file,
  7.  * are subject to the current version of the RealNetworks Public
  8.  * Source License (the "RPSL") available at
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed
  10.  * the file under the current version of the RealNetworks Community
  11.  * Source License (the "RCSL") available at
  12.  * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
  13.  * will apply. You may also obtain the license terms directly from
  14.  * RealNetworks.  You may not use this file except in compliance with
  15.  * the RPSL or, if you have a valid RCSL with RealNetworks applicable
  16.  * to this file, the RCSL.  Please see the applicable RPSL or RCSL for
  17.  * the rights, obligations and limitations governing use of the
  18.  * contents of the file.
  19.  * 
  20.  * Alternatively, the contents of this file may be used under the
  21.  * terms of the GNU General Public License Version 2 or later (the
  22.  * "GPL") in which case the provisions of the GPL are applicable
  23.  * instead of those above. If you wish to allow use of your version of
  24.  * this file only under the terms of the GPL, and not to allow others
  25.  * to use your version of this file under the terms of either the RPSL
  26.  * or RCSL, indicate your decision by deleting the provisions above
  27.  * and replace them with the notice and other provisions required by
  28.  * the GPL. If you do not delete the provisions above, a recipient may
  29.  * use your version of this file under the terms of any one of the
  30.  * RPSL, the RCSL or the GPL.
  31.  * 
  32.  * This file is part of the Helix DNA Technology. RealNetworks is the
  33.  * developer of the Original Code and owns the copyrights in the
  34.  * portions it created.
  35.  * 
  36.  * This file, and the files included with this file, is distributed
  37.  * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
  38.  * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
  39.  * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
  40.  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
  41.  * ENJOYMENT OR NON-INFRINGEMENT.
  42.  * 
  43.  * Technology Compatibility Kit Test Suite(s) Location:
  44.  *    http://www.helixcommunity.org/content/tck
  45.  * 
  46.  * Contributor(s):
  47.  * 
  48.  * ***** END LICENSE BLOCK ***** */
  49. #include "hxcom.h"
  50. #include "hlxclib/stdio.h"
  51. #include "hlxclib/stdlib.h"
  52. #ifdef _WINDOWS
  53. #include <windows.h>
  54. #endif
  55. #if defined(_MACINTOSH) && !defined(_MAC_MACHO)
  56. #include <stat.h>
  57. #else
  58. #include "hlxclib/sys/stat.h"
  59. #endif
  60. #include "hxxrsmg.h"
  61. #include "hxplugn.h"
  62. #include "hxfiles.h"
  63. #include "hxcomm.h"
  64. #include "hxxres.h"
  65. #include "hxengin.h"
  66. #include "ihxpckts.h"
  67. #include "hxprefs.h"
  68. #include "hxmon.h"
  69. #include "hxslist.h"
  70. #include "hxstrutl.h"
  71. #include "chxpckts.h"
  72. #include "md5.h"
  73. #include "findfile.h"
  74. #include "hxresmg.h"
  75. #include "dllpath.h"
  76. #include "hxheap.h"
  77. #ifdef _DEBUG
  78. #undef HX_THIS_FILE
  79. static const char HX_THIS_FILE[] = __FILE__;
  80. #endif
  81. // IHXPreferences key defines
  82. #define EXT_RES_DIR "ExtResources"
  83. #define EXT_RES_DATA_KEY "ExternalResourcesData"
  84. #define FILE_INFO_KEY "FileInfo"
  85. #define CHECKSUM_KEY "XRSCheckSum"
  86. #define LANGUAGE_KEY "Language"
  87. #define LANG_ID_KEY "LangID"
  88. // for OS_SEPARATOR_CHAR and OS_SEPARATOR_STRING
  89. #include "hxdir.h"
  90. // static initializations
  91. #if !defined(HELIX_CONFIG_NOSTATICS)
  92. HXExternalResourceManager* HXExternalResourceManager::m_pResourceManager = NULL;
  93. #else
  94. #include "globals/hxglobals.h"
  95. const HXExternalResourceManager* const HXExternalResourceManager::m_pResourceManager = NULL;
  96. #endif
  97. // HXExternalResourceManager methods
  98. HXExternalResourceManager::HXExternalResourceManager(IUnknown* pContext):
  99.      m_lRefCount(0)
  100.     ,m_pResourceList(NULL)
  101.     ,m_pContext(pContext)
  102.     ,m_pHXXResPlugin(NULL)
  103.     ,m_ulLanguageID(0x0409)
  104.     ,m_pExternalResDir(NULL)
  105.     ,m_pPrefs(NULL)
  106.     ,m_pRegistry(NULL)
  107. {
  108.     if(m_pContext)
  109.     {
  110. m_pContext->AddRef();
  111.     }
  112.     Init();
  113. }
  114. HXExternalResourceManager::~HXExternalResourceManager()
  115. {
  116.     delete[] m_pExternalResDir;
  117.     if(m_pResourceList)
  118.     {
  119. CHXSimpleList::Iterator i = m_pResourceList->Begin();
  120. for (; i != m_pResourceList->End(); ++i)
  121. {
  122.     IHXXResFile* pRes = (IHXXResFile*)(*i);
  123.     pRes->Close();
  124.     pRes->Release();
  125. }
  126.     }
  127.     HX_DELETE(m_pResourceList);
  128.     HX_RELEASE(m_pPrefs);
  129.     HX_RELEASE(m_pRegistry);
  130.     HX_RELEASE(m_pContext);
  131.     HX_RELEASE(m_pHXXResPlugin);
  132. #if defined(HELIX_CONFIG_NOSTATICS)
  133.     HXExternalResourceManager*& m_pResourceManager =
  134. (HXExternalResourceManager*&)HXGlobalPtr::Get(
  135.     &HXExternalResourceManager::m_pResourceManager);
  136. #endif
  137.     m_pResourceManager = NULL;
  138. }
  139. HXExternalResourceManager*
  140. HXExternalResourceManager::Instance(IUnknown* pContext)
  141. {
  142. #if defined(HELIX_CONFIG_NOSTATICS)
  143.     HXExternalResourceManager*& m_pResourceManager =
  144. (HXExternalResourceManager*&)HXGlobalPtr::Get(
  145.     &HXExternalResourceManager::m_pResourceManager);
  146. #endif
  147.     if(!m_pResourceManager)
  148.     {
  149. m_pResourceManager = new HXExternalResourceManager(pContext);
  150.     }
  151.     if (m_pResourceManager)
  152.     {
  153. m_pResourceManager->AddRef();
  154.     }
  155.     return m_pResourceManager;
  156. }
  157. // IUnknown methods
  158. STDMETHODIMP 
  159. HXExternalResourceManager::QueryInterface(REFIID riid, void** ppvObj)
  160. {
  161.     QInterfaceList qiList[] =
  162.         {
  163.             { GET_IIDHANDLE(IID_IHXExternalResourceManager), (IHXExternalResourceManager*)this },
  164.             { GET_IIDHANDLE(IID_IUnknown), (IUnknown*)(IHXExternalResourceManager*)this },
  165.         };
  166.     
  167.     return ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
  168. }
  169. STDMETHODIMP_(ULONG32) 
  170. HXExternalResourceManager::AddRef()
  171. {
  172.     return InterlockedIncrement(&m_lRefCount);
  173. }
  174. STDMETHODIMP_(ULONG32) 
  175. HXExternalResourceManager::Release()
  176. {
  177.     if (InterlockedDecrement(&m_lRefCount) > 0)
  178.     {
  179. return m_lRefCount;
  180.     }
  181.     delete this;
  182.     return 0;
  183. }
  184. // IHXExternalResourceManager methods
  185. STDMETHODIMP
  186. HXExternalResourceManager::Init()
  187. {
  188.     HX_RESULT rc = GetHXXResPlugin();
  189.     if(HXR_OK == rc)
  190.     {
  191. // get language and res directory preferences/reg entries
  192. if (HXR_OK == m_pContext->QueryInterface(IID_IHXPreferences,
  193. (void**)&m_pPrefs) &&
  194.     HXR_OK == m_pContext->QueryInterface(IID_IHXRegistry, 
  195. (void**)&m_pRegistry))
  196. {
  197.     IHXBuffer* pBuffer = NULL;
  198.     CHXString strTemp;
  199.     strTemp.Format("%s.%s",HXREGISTRY_PREFPROPNAME, "LangID");
  200.     if(HXR_OK == m_pRegistry->GetStrByName(strTemp, pBuffer))
  201.     {
  202. const char* pActualLangID = (const char*)pBuffer->GetBuffer();
  203. m_ulLanguageID = strtol(pActualLangID, NULL, 10);
  204. HX_RELEASE(pBuffer);
  205.     }
  206.             const char* pPath = NULL;
  207.             // Get the plugin directory from the Dll Access Paths
  208.             if (GetDLLAccessPath() &&
  209.                 (pPath = GetDLLAccessPath()->GetPath(DLLTYPE_PLUGIN)) &&
  210.                 *pPath)
  211.             {
  212.                 UINT32 ulBufLen = strlen(pPath) + 1 + strlen(EXT_RES_DIR) + 1;
  213.                 m_pExternalResDir = new char[ulBufLen];
  214.                 SafeStrCpy(m_pExternalResDir, pPath, ulBufLen);
  215.                 if (m_pExternalResDir[strlen(m_pExternalResDir)-1] != OS_SEPARATOR_CHAR)
  216.                 {
  217.                     SafeStrCat(m_pExternalResDir, OS_SEPARATOR_STRING, ulBufLen);
  218.                 }
  219.                 SafeStrCat(m_pExternalResDir, EXT_RES_DIR, ulBufLen);
  220.                 rc = LoadResourceFiles();
  221.             }
  222. }
  223.     }
  224.     return rc;
  225. }
  226. STDMETHODIMP
  227. HXExternalResourceManager::CreateExternalResourceReader(
  228.     const char* pShortName,
  229.     REF(IHXExternalResourceReader*) pReader)
  230. {
  231.     HX_RESULT rc = HXR_OK;
  232.     HXExternalResourceReader* pHXReader = new HXExternalResourceReader(this);
  233.     if(!pHXReader)
  234.     {
  235. return HXR_OUTOFMEMORY;
  236.     }
  237.     pHXReader->AddRef();
  238.     pHXReader->Init(pShortName, m_pResourceList);
  239.     pReader = pHXReader;
  240.     return rc;
  241. }
  242. // HXExternalResourceManager private methods
  243. HX_RESULT
  244. HXExternalResourceManager::GetHXXResPlugin()
  245. {
  246.     HX_RESULT rc = HXR_FAILED;
  247.     IUnknown* pUnk = NULL;
  248.     IUnknown* pUnknownInstance = NULL;
  249.     IHXCommonClassFactory* pCommonClassFactory = NULL;
  250.     IHXPluginGroupEnumerator* pGroupEnumerator = NULL;
  251.     UINT32 ulNumPlugins = 0;
  252.     // enumerate the plugins
  253.     if (HXR_OK != m_pContext->QueryInterface(
  254. IID_IHXCommonClassFactory,
  255. (void**)&pCommonClassFactory))
  256.     {
  257. goto cleanup;
  258.     }
  259.     if (HXR_OK != pCommonClassFactory->CreateInstance(
  260. CLSID_IHXPluginGroupEnumerator,
  261. (void**)&pUnk))
  262.     {
  263. goto cleanup;
  264.     }
  265.     if (HXR_OK != pUnk->QueryInterface(IID_IHXPluginGroupEnumerator,
  266.     (void**)&pGroupEnumerator))
  267.     {
  268. goto cleanup;
  269.     }
  270.     if (HXR_OK != pGroupEnumerator->Init(IID_IHXXResFile))
  271.     {
  272. goto cleanup;
  273.     }
  274.     ulNumPlugins = pGroupEnumerator->GetNumOfPlugins();
  275.     if(ulNumPlugins > 0)
  276.     {
  277. if (HXR_OK == pGroupEnumerator->GetPlugin(0, pUnknownInstance))
  278. {
  279.     m_pHXXResPlugin = pUnknownInstance;
  280.     m_pHXXResPlugin->AddRef();
  281.     rc = HXR_OK;
  282. }
  283.     }
  284. cleanup:
  285.     HX_RELEASE(pUnk);
  286.     HX_RELEASE(pUnknownInstance);
  287.     HX_RELEASE(pCommonClassFactory);
  288.     HX_RELEASE(pGroupEnumerator);
  289.     return rc;
  290. }
  291. BOOL
  292. HXExternalResourceManager::ContainsCurrentLanguage(IHXXResFile* pResFile)
  293. {
  294.     BOOL rc = FALSE;
  295.     if(!pResFile)
  296.     {
  297. return rc;
  298.     }
  299.     UINT32 ulLangID = 0;
  300.     BOOL bFound = FALSE;
  301.     rc = pResFile->GetFirstResourceLanguage(ulLangID);
  302.     while(HXR_OK == rc)
  303.     {
  304. if(m_ulLanguageID == ulLangID)
  305. {
  306.     rc = TRUE;
  307.     break;
  308. }
  309. rc = pResFile->GetNextResourceLanguage(ulLangID);
  310.     };
  311.     return rc;
  312. }
  313. IHXXResFile*
  314. HXExternalResourceManager::MakeResFileObject(const char* pPath)
  315. {
  316.     IHXXResFile* pResFile = NULL;
  317.     if(m_pHXXResPlugin &&
  318. HXR_OK == m_pHXXResPlugin->QueryInterface(IID_IHXXResFile, 
  319. (void**)&pResFile))
  320.     {
  321. HX_RESULT rc = HXR_OK;
  322. // open res file and see if it contains any resources with the
  323. // current language ID
  324. pResFile->Open(pPath);
  325. if(ContainsCurrentLanguage(pResFile))
  326. {
  327.     pResFile->SetLanguage(m_ulLanguageID);
  328. }
  329. else
  330. {
  331.     HX_RELEASE(pResFile);   // don't want this one
  332. }
  333.     }
  334.     return pResFile;
  335. }
  336. HX_RESULT
  337. HXExternalResourceManager::Stat(const char* pPath, struct stat* pStatBuffer)
  338. {
  339.     HX_RESULT rc = HXR_OK;
  340.     memset(pStatBuffer,0,sizeof(*pStatBuffer));
  341.     if(stat((const char*)pPath, pStatBuffer) < 0)
  342.     {
  343. rc = HXR_FAIL;
  344.     }
  345.     return rc;
  346. }
  347. IHXBuffer* 
  348. HXExternalResourceManager::ConvertToAsciiString(char* pBuffer, UINT32 nBuffLen)
  349. {
  350.     char* pOut = new char[nBuffLen*2+1];
  351.     char* pStartOut = pOut;
  352.     char Nibble;
  353.     IHXBuffer* pOutBuffer = new CHXBuffer;
  354.     pOutBuffer->AddRef();
  355.     for (int i = 0; i < (int)nBuffLen; i++)
  356.     {
  357. Nibble = (*pBuffer >> 4) & 15;
  358. *pOut= (Nibble > 9 ) ? Nibble + 55 : Nibble + 48;
  359. pOut++;
  360. Nibble = *pBuffer & 15;
  361. *pOut= (Nibble > 9 ) ? Nibble + 55 : Nibble + 48;
  362. pOut++;
  363. pBuffer++;
  364.     }
  365.     *pOut = 0;
  366.     pOutBuffer->Set((UCHAR*)pStartOut, strlen(pStartOut)+1);
  367.     delete[] pStartOut;
  368.     return pOutBuffer;
  369. }
  370. IHXBuffer* 
  371. HXExternalResourceManager::ChecksumFile(const char* pPath)
  372. {
  373.     struct stat     stat_struct;
  374.     md5_state_t     MD5_data;
  375.     UCHAR     tempbuf[16];
  376.     md5_init(&MD5_data);
  377.     if (HXR_OK != Stat(pPath, &stat_struct))
  378.     {
  379.         md5_finish(tempbuf, &MD5_data);
  380. return NULL;
  381.     } 
  382.     md5_append(&MD5_data,(UCHAR*)&(stat_struct),sizeof(stat_struct)); 
  383.     md5_finish(tempbuf, &MD5_data);
  384.     return ConvertToAsciiString((char*)tempbuf, sizeof(tempbuf));
  385. }
  386. HX_RESULT
  387. HXExternalResourceManager::SaveFileInfo(const char* pFileName,
  388.          const char* pPath)
  389. {
  390.     HX_RESULT rc = HXR_OK;
  391.    // set/reset cache info
  392.     if(!m_pPrefs)
  393.     {
  394. return HXR_FAIL;
  395.     }
  396.     IHXBuffer* pStatInfo = ChecksumFile(pPath);
  397.     if(pStatInfo)
  398.     {
  399. CHXString prefString;
  400. prefString.Format("%s\%s\%s\%s",
  401.     EXT_RES_DATA_KEY,
  402.     FILE_INFO_KEY,
  403.     pFileName,
  404.     CHECKSUM_KEY);
  405. m_pPrefs->WritePref(prefString, pStatInfo);
  406. HX_RELEASE(pStatInfo);
  407.     }
  408.     // now write out the langages supported in the resource file
  409.     IHXXResFile* pResFile;
  410.     if(HXR_OK == m_pHXXResPlugin->QueryInterface(IID_IHXXResFile, 
  411. (void**)&pResFile))
  412.     {
  413. HX_RESULT rc = HXR_OK;
  414. // open res file and iterate through all of the languages
  415. // it supports
  416. pResFile->Open(pPath);
  417. UINT32 ulLangID = 0;
  418. rc = pResFile->GetFirstResourceLanguage(ulLangID);
  419. while(HXR_OK == rc)
  420. {
  421.     CHXString prefString;
  422.     IHXBuffer* pBuffer = new CHXBuffer;
  423.     prefString.Format("%s\%s\%s\%s\%ld",
  424. EXT_RES_DATA_KEY,
  425. FILE_INFO_KEY,
  426. pFileName,
  427. LANGUAGE_KEY,
  428. ulLangID);
  429.     pBuffer->Set((BYTE*)"", 1);
  430.     m_pPrefs->WritePref(prefString, pBuffer);
  431.     HX_RELEASE(pBuffer);
  432.     rc = pResFile->GetNextResourceLanguage(ulLangID);
  433. };
  434. HX_RELEASE(pResFile);
  435.     }
  436.     return rc;
  437. }
  438. HX_RESULT
  439. HXExternalResourceManager::LoadResourceFile(const char* pPath)
  440. {
  441.     HX_RESULT rc = HXR_OK;
  442.     // MakeResFileObject only returns an IHXXResFile
  443.     // if there are any resources in the current language
  444.     IHXXResFile* pResFile = MakeResFileObject(pPath);
  445.     if (pResFile)
  446.     {
  447. if(!m_pResourceList)
  448. {
  449.     m_pResourceList = new CHXSimpleList;
  450. }
  451.      m_pResourceList->AddTail(pResFile);
  452.     }
  453.     return rc;
  454. }
  455. BOOL
  456. HXExternalResourceManager::FileInfoCurrent(const char* pFileName, 
  457.     const char* pPath)
  458. {
  459.     BOOL rc = FALSE;
  460.     IHXBuffer* pStatInfo = ChecksumFile(pPath);
  461.     if(pStatInfo)
  462.     {
  463. IHXBuffer* pPrefValue = NULL;
  464. CHXString prefString;
  465. prefString.Format("%s\%s\%s\%s",
  466.     EXT_RES_DATA_KEY,
  467.     FILE_INFO_KEY,
  468.     pFileName,
  469.     CHECKSUM_KEY);
  470. if(HXR_OK == m_pPrefs->ReadPref(prefString, pPrefValue) &&
  471.     pPrefValue)
  472. {
  473.     const char* pActualPrefValue = (const char*)pPrefValue->GetBuffer();
  474.     const char* pActualStatInfo = (const char*)pStatInfo->GetBuffer();
  475.     if(strcmp(pActualPrefValue, pActualStatInfo) == 0)
  476.     {
  477. rc = TRUE;
  478.     }
  479.     HX_RELEASE(pPrefValue);
  480. }
  481. HX_RELEASE(pStatInfo);
  482.     }
  483.     return rc;
  484. }
  485. BOOL
  486. HXExternalResourceManager::ContainsCurrentLanguage(const char* pFileName,
  487.    const char* pPath)
  488. {
  489. #if defined (_MACINTOSH) || defined (_UNIX)
  490.     /* Temporary - Mac Installer does not write this pref yet -- XXXRA */
  491.     return TRUE;
  492. #endif
  493.     BOOL rc = FALSE;
  494.     IHXBuffer* pLangInfo = NULL;
  495.     CHXString prefString;
  496.     prefString.Format("%s\%s\%s\%s\%ld",
  497. EXT_RES_DATA_KEY,
  498. FILE_INFO_KEY,
  499. pFileName,
  500. LANGUAGE_KEY,
  501. m_ulLanguageID);
  502.     if(HXR_OK == m_pPrefs->ReadPref(prefString, pLangInfo))
  503.     {
  504. rc = TRUE;
  505. HX_RELEASE(pLangInfo);
  506.     }
  507.     return rc;
  508. }
  509. HX_RESULT
  510. HXExternalResourceManager::LoadResourceFiles()
  511. {
  512.     CFindFile* pFileFinder = NULL;
  513.     char* pResFile = NULL;
  514.     const char* pFileExtension = "*.xrs";
  515.     HX_RESULT   rc = HXR_OK;
  516.     // find plugins with specified pattern
  517.     pFileFinder = CFindFile::CreateFindFile(m_pExternalResDir, 0, 
  518.     pFileExtension);
  519.     if (NULL == pFileFinder)
  520.     {
  521. rc = HXR_FAIL;
  522. goto cleanup;
  523.     }
  524.     // collect plugin info.
  525.     pResFile = pFileFinder->FindFirst();
  526.     while (pResFile)
  527.     {
  528. BOOL bLoadFile = FALSE;
  529. const char* pResPath = pFileFinder->GetCurFilePath();
  530. // only load the file if it has resources that reflect
  531. // the current system language ID
  532. if(!FileInfoCurrent(pResFile, pResPath))
  533. {
  534.     SaveFileInfo(pResFile, pResPath);
  535. }
  536.     
  537. if(ContainsCurrentLanguage(pResFile, pResPath))
  538. {
  539.     rc = LoadResourceFile(pResPath);
  540. }
  541. if(HXR_OK != rc)
  542. {
  543.     // error - log it and keep on?
  544. }
  545. pResFile = pFileFinder->FindNext();
  546.     }
  547.     delete pFileFinder;
  548. cleanup:
  549.     return rc;
  550. }
  551. // HXExternalResourceReader methods
  552. HXExternalResourceReader::HXExternalResourceReader(
  553.      HXExternalResourceManager* pMgr):
  554.      m_lRefCount(0)
  555.     ,m_pResManager(pMgr)
  556.     ,m_pResourceList(NULL)
  557.     ,m_pDefaultRes(NULL)
  558. {
  559. }
  560. HXExternalResourceReader::~HXExternalResourceReader()
  561. {
  562.     HX_DELETE(m_pResourceList);
  563.     HX_RELEASE(m_pDefaultRes);
  564. }
  565. // IUnknown methods
  566. STDMETHODIMP 
  567. HXExternalResourceReader::QueryInterface(REFIID riid, void** ppvObj)
  568. {
  569.     QInterfaceList qiList[] =
  570.         {
  571.             { GET_IIDHANDLE(IID_IHXExternalResourceReader), (IHXExternalResourceReader*)this },
  572.             { GET_IIDHANDLE(IID_IUnknown), (IUnknown*)(IHXExternalResourceReader*)this },
  573.         };
  574.     
  575.     return ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
  576. }
  577. STDMETHODIMP_(ULONG32) 
  578. HXExternalResourceReader::AddRef()
  579. {
  580.     return InterlockedIncrement(&m_lRefCount);
  581. }
  582. STDMETHODIMP_(ULONG32) 
  583. HXExternalResourceReader::Release()
  584. {
  585.     if (InterlockedDecrement(&m_lRefCount) > 0)
  586.     {
  587. return m_lRefCount;
  588.     }
  589.     delete this;
  590.     return 0;
  591. }
  592. STDMETHODIMP
  593. HXExternalResourceReader::SetDefaultResourceFile(
  594.     const char* pResourcePath)
  595. {
  596.     HX_RESULT rc = HXR_OK;
  597.     m_pDefaultRes = m_pResManager->MakeResFileObject(pResourcePath);
  598.     return rc;
  599. }
  600. IHXXResource*
  601. HXExternalResourceReader::GetResource(IHXXResFile* pResFile,
  602.        UINT32 ulResourceType,
  603.        UINT32 ulResourceID)
  604. {
  605.     IHXXResource* pRes = NULL;
  606.     switch(ulResourceType)
  607.     {
  608. case HX_RT_STRING:
  609. {
  610.     pRes = pResFile->GetString(ulResourceID);
  611. }
  612. break;
  613. case HX_RT_DIALOG:
  614. {
  615.     pRes = pResFile->GetDialog(ulResourceID);
  616. }
  617. break;
  618. case HX_RT_BITMAP:
  619. {
  620.     pRes = pResFile->GetBitmap(ulResourceID);
  621. }
  622. break;
  623. default:
  624. break;
  625.     }
  626.     return pRes;
  627. }
  628. STDMETHODIMP_(IHXXResource*)
  629. HXExternalResourceReader::GetResource(UINT32 ulResourceType,
  630.     UINT32 ulResourceID)
  631. {
  632.     IHXXResource* pRes = NULL;
  633.     if(m_pResourceList)
  634.     {
  635. CHXSimpleList::Iterator i = m_pResourceList->Begin();
  636. for (; i != m_pResourceList->End(); ++i)
  637. {
  638.     IHXXResFile* pResFile = (IHXXResFile*)(*i);
  639.     pRes = GetResource(pResFile, ulResourceType, ulResourceID);
  640.     if(pRes)
  641.     {
  642. break;
  643.     }
  644. }
  645.     }
  646.     if(!pRes &&
  647. m_pDefaultRes) // check default
  648.     {
  649. pRes = GetResource(m_pDefaultRes, ulResourceType, ulResourceID);
  650.     }
  651.     return pRes;
  652. }
  653. HX_RESULT
  654. HXExternalResourceReader::Init(const char* pShortName,
  655. CHXSimpleList* pResList)
  656. {
  657.     HX_RESULT rc = HXR_OK;
  658.     if(pResList)
  659.     {
  660. CHXSimpleList::Iterator i = pResList->Begin();
  661. for (; i != pResList->End(); ++i)
  662. {
  663.     IHXXResFile* pResFile = (IHXXResFile*)(*i);
  664.     if(pResFile->IncludesShortName(pShortName))
  665.     {
  666. if(!m_pResourceList)
  667. {
  668.     m_pResourceList = new CHXSimpleList;
  669. }
  670. m_pResourceList->AddTail(pResFile);
  671.     }
  672. }
  673.     }
  674.     return rc;
  675. }