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

Symbian

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Source last modified: $Id: validatr.cpp,v 1.6.20.2 2004/07/09 02:07:59 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 "hxtypes.h"
  52. #include "hxresult.h"
  53. #include "hxassert.h"
  54. #include "hxcomm.h"
  55. #include "hxplugn.h"
  56. #include "hxfiles.h"
  57. #include "hxmeta.h"
  58. #include "hxcore.h"
  59. #include "hxpends.h"
  60. #include "timeval.h"
  61. #include "pq.h"
  62. #include "hxstring.h"
  63. #include "hxslist.h"
  64. #include "hxrquest.h"
  65. #include "hxbuffer.h"
  66. #include "chxpckts.h"
  67. #include "dbcs.h"
  68. #include "hxmarsh.h"
  69. #include "hxmime.h"
  70. #include "hxstrutl.h"
  71. #include "plghand2.h"
  72. #include "validatr.h"
  73. #include "hxxfile.h"
  74. #include "rmfftype.h"
  75. #include "hxheap.h"
  76. #ifdef _DEBUG
  77. #undef HX_THIS_FILE
  78. static const char HX_THIS_FILE[] = __FILE__;
  79. #endif
  80. #define MAX_URL_STRING 4096
  81. HXValidator::HXValidator(IUnknown* pContext)
  82. : m_lRefCount (0)
  83. , m_pContext (NULL)
  84. , m_bRefresh (TRUE)
  85. {
  86.     if (pContext)
  87.     {
  88. m_pContext = pContext;
  89. m_pContext->AddRef();
  90.     }
  91. }
  92. HXValidator::~HXValidator()
  93. {
  94.     CHXSimpleList::Iterator i;
  95.     // cleanup the protocol list
  96.     i = m_ProtocolList.Begin();
  97.     for (; i != m_ProtocolList.End(); ++i)
  98.     {
  99. CHXString* pProtocol = (CHXString*) (*i);
  100. HX_DELETE(pProtocol);
  101.     }
  102.     m_ProtocolList.RemoveAll();
  103.     HX_RELEASE(m_pContext);
  104. }
  105. STDMETHODIMP
  106. HXValidator::QueryInterface(REFIID riid, void**ppvObj)
  107. {
  108.     QInterfaceList qiList[] =
  109.         {
  110.             { GET_IIDHANDLE(IID_IHXValidator), (IHXValidator*)this },
  111.             { GET_IIDHANDLE(IID_IUnknown), (IUnknown*)(IHXValidator*)this },
  112.         };
  113.     
  114.     return ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
  115. }
  116. /////////////////////////////////////////////////////////////////////////
  117. //  Method:
  118. // IUnknown::AddRef
  119. //  Purpose:
  120. // Everyone usually implements this the same... feel free to use
  121. // this implementation.
  122. //
  123. STDMETHODIMP_(ULONG32) 
  124. HXValidator::AddRef()
  125. {
  126.     return InterlockedIncrement(&m_lRefCount);
  127. }
  128. /////////////////////////////////////////////////////////////////////////
  129. //  Method:
  130. // IUnknown::Release
  131. //  Purpose:
  132. // Everyone usually implements this the same... feel free to use
  133. // this implementation.
  134. //
  135. STDMETHODIMP_(ULONG32) 
  136. HXValidator::Release()
  137. {
  138.     if (InterlockedDecrement(&m_lRefCount) > 0)
  139.     {
  140.         return m_lRefCount;
  141.     }
  142.     delete this;
  143.     return 0;
  144. }
  145. /************************************************************************
  146.  * Method:
  147.  *     IHXValidator::ValidateProtocol
  148.  * Purpose:
  149.  *     Find out if the protocol is valid
  150.  *     
  151.  *
  152.  */
  153. STDMETHODIMP_(BOOL)
  154. HXValidator::ValidateProtocol(char* pProtocol)
  155. {
  156.     BOOL bResult = FALSE;
  157.     CHXString* pValue = NULL;
  158.     CHXSimpleList::Iterator i;
  159.     if (!pProtocol)
  160.     {
  161. goto cleanup;
  162.     }
  163.     if (m_bRefresh)
  164.     {
  165. BuildProtocolList();
  166. m_bRefresh = FALSE;
  167.     }
  168.     i = m_ProtocolList.Begin();
  169.     for (; i != m_ProtocolList.End(); ++i)
  170.     {
  171. pValue = (CHXString*) (*i);
  172. if (strcasecmp(pProtocol, (const char*)(*pValue)) == 0)
  173. {
  174.     bResult = TRUE;
  175.     break;
  176. }
  177.     }
  178. cleanup:
  179.     return bResult;
  180. }
  181. /************************************************************************
  182.  * Method:
  183.  *     IHXValidator::ValidateMetaFile
  184.  * Purpose:
  185.  *     Find out if it is a meta file
  186.  *     
  187.  *
  188.  */
  189. STDMETHODIMP
  190. HXValidator::ValidateMetaFile(IHXRequest* pRequest,
  191.        IHXBuffer* pData)
  192. {
  193.     HX_RESULT hr = HXR_OK;    
  194.     BOOL bIsRAM = FALSE;
  195.     BOOL bTrackFound = FALSE;
  196.     BOOL bHeaderToBeSet = FALSE;
  197.     UINT32 ulFileType = 0;
  198.     UINT32 ulSize = 0;
  199.     UINT32 ulMajorVersion = 0;
  200.     int i = 0; 
  201.     int j = 0;
  202.     int iLen = 0;
  203.     int iSize = 0;
  204.     char* pMimeType = NULL;
  205.     char* pFileExt = NULL;
  206.     char* pProtocol = NULL;
  207.     char* pCursor = NULL;
  208.     char* pLine = NULL;
  209.     char* pContent = NULL;
  210.     char* pTemp = NULL;
  211.     char* pURL = NULL;
  212.     const char* pConstTemp = NULL;
  213.     const char* charset = " rnt";
  214.     const char* tokenset = "nr";    
  215.     UINT32 ulProtocol = 0;
  216.     CHXString* pString = NULL;
  217.     IHXBuffer* pValue = NULL;
  218.     IHXValues* pResponseHeaders = NULL;
  219.     
  220.     if (pRequest)
  221.     {
  222. pRequest->AddRef();
  223.     }
  224.     if (pData)
  225.     {
  226.         pData->AddRef();
  227.     }
  228.     else
  229.     {
  230. hr = HXR_FAILED;
  231. goto cleanup;
  232.     }
  233.     if (pRequest)
  234.     {
  235.         pRequest->GetURL(pConstTemp);
  236.         if (HXXFile::IsPlusURL(pConstTemp))
  237.         {
  238.     hr = HXR_FAILED;
  239.     goto cleanup;
  240.         }
  241.     }
  242.     ulSize = pData->GetSize() + 1;
  243.     pContent = new char[ulSize];
  244.     memset(pContent, 0, ulSize);
  245.     memcpy(pContent, (char*)pData->GetBuffer(), pData->GetSize()); /* Flawfinder: ignore */
  246.     // if the first FOURCC is either ".RA " or ".RMF"
  247.     if (pData->GetSize() >= 4)
  248.     {
  249. ulFileType = (UINT32) getlong((UCHAR*) pContent);
  250.     
  251. const char* pContentType = NULL;
  252. switch (ulFileType)
  253. {
  254.     case RM_HEADER_OBJECT:
  255.     case RMS_HEADER_OBJECT:
  256.     case RA_FILE_MAGIC_NUMBER:
  257.     {
  258. pContentType = REALAUDIO_MIME_TYPE;
  259.     }
  260.     break;
  261.     case REDHAT_PACKAGE_MAGIC_NUMBER:
  262.     {
  263. pContentType = REDHAT_PACKAGE_MIME_TYPE;
  264.     }
  265.     break;
  266. }
  267. if (pContentType)
  268. {
  269.     if (pRequest)
  270.     {
  271. pRequest->GetResponseHeaders(pResponseHeaders);
  272. if (!pResponseHeaders)
  273. {
  274.     pResponseHeaders = (IHXValues*) new CHXHeader;
  275.     pResponseHeaders->AddRef();
  276.     bHeaderToBeSet = TRUE;
  277. }
  278. if (HXR_OK !=
  279.     pResponseHeaders->GetPropertyCString("Content-Type",
  280.  pValue) ||
  281.     !pValue)
  282. {
  283.     pValue = (IHXBuffer*) new CHXBuffer;
  284.     pValue->AddRef();
  285.     pValue->Set((UCHAR*)pContentType,
  286. ::strlen(pContentType) + 1);
  287.     pResponseHeaders->SetPropertyCString("Content-Type",
  288.  pValue);
  289.     if (bHeaderToBeSet)
  290.     {
  291. pRequest->SetResponseHeaders(pResponseHeaders);
  292.     }
  293. }
  294.     }
  295.     
  296.     hr = HXR_FAILED;
  297.     goto cleanup;
  298. }
  299.     }
  300.     // retreive the MimeType and FileExt
  301.     if (pRequest)
  302.     {
  303. if (HXR_OK == pRequest->GetResponseHeaders(pResponseHeaders) &&
  304.     pResponseHeaders)
  305. {
  306.     if (HXR_OK == pResponseHeaders->GetPropertyCString("Content-Type", pValue) &&
  307. pValue)
  308.     {
  309. pMimeType = (char*)pValue->GetBuffer();
  310.     }
  311. }
  312. pTemp = (char*)pConstTemp;
  313. if (pTemp)
  314. {
  315.     pURL = new char[strlen(pTemp) + 1];
  316.     strcpy(pURL, pTemp); /* Flawfinder: ignore */
  317.     pTemp = strrchr(pURL, '?');
  318.     if (pTemp)
  319.     {
  320. *pTemp = '';
  321.     }
  322.     pFileExt = strrchr(pURL, '.');
  323. }
  324.     }
  325.     // determine whether it is a RAM file
  326.     if ((pMimeType &&
  327.  ((strcasecmp(pMimeType, "audio/x-pn-realaudio") == 0) ||
  328.   (strcasecmp(pMimeType, "audio/x-pn-realaudio-plugin") == 0))) ||
  329. (pFileExt &&
  330.  ((strcasecmp(pFileExt, ".ram") == 0) ||
  331.   (strcasecmp(pFileExt, ".rpm") == 0) ||
  332.   (strcasecmp(pFileExt, ".rmm") == 0))))
  333.     {
  334. bIsRAM = TRUE;
  335.         iLen = pData->GetSize();
  336. char* ramFile = new char[iLen+1];
  337.     
  338. while( i <= iLen && !bTrackFound)
  339. {
  340. /*
  341.  * XXXJHUG  12/07/00 change to allow unlimitted length ram files.
  342.  *      - we no longer need to check to see if the url
  343.  *        is longer than a fixed value.
  344.     if (j >= MAX_URL_STRING)
  345.     {
  346. // exceeds the max. length of URL
  347. // skip the whole line
  348. while (pContent[i] != 'n' && pContent[i] != 'r' &&
  349.        pContent[i] != 0 && i < iLen)
  350. {
  351.     i++;
  352. }
  353. memset(pUrl, 0, MAX_URL_STRING);
  354. j = 0;
  355. i++;
  356. continue;
  357.     }
  358. */
  359.     ramFile[j] = pContent[i]; 
  360.     
  361.     // Look for line terminators.
  362.     if ( ramFile[j] == 'n' || ramFile[j] == 'r' || ramFile[j] == 0 || i == iLen)
  363.     {
  364. ramFile[j] = 0;
  365. pString = new CHXString(ramFile);
  366. pString->TrimLeft();
  367. pString->TrimRight();
  368. iSize = pString->GetLength();
  369. if (iSize)
  370. {
  371.     memset(ramFile, 0, iLen+1);
  372.     SafeStrCpy(ramFile,  pString->GetBuffer(iSize), iLen+1);
  373.     
  374.     // A URL must have at least 4 chars. for protocol. This will
  375.     // take care of lines with junk or just CR on them.
  376.     
  377.     // detect RAM3.0 syntax
  378.     if (strncasecmp(ramFile, HX_RAM30_START_TAG, HX_RAM30_START_TAGSIZE) == 0)
  379.     {
  380. ulMajorVersion = 3;
  381.     }
  382.     else if (strncasecmp(ramFile, HX_RAM30_END_TAG, HX_RAM30_END_TAGSIZE) == 0)
  383.     {
  384. HX_DELETE(pString);
  385. break;
  386.     }
  387.     // detect RAM2.0 syntax
  388.     else if (strncasecmp(ramFile, HX_RAM20_START_TAG, HX_RAM20_START_TAGSIZE) == 0)
  389.     {
  390. ulMajorVersion = 2;
  391.     }
  392.     else if (strncasecmp(ramFile, HX_RAM20_END_TAG, HX_RAM20_END_TAGSIZE) == 0)
  393.     {
  394. HX_DELETE(pString);
  395. break;
  396.     }
  397.     // handle "--stop--" tag in 6.0
  398.     else if (strncasecmp(ramFile, "--stop--", 8) == 0)
  399.     {
  400. HX_DELETE(pString);
  401. break;
  402.     }
  403.     else 
  404.     {
  405. if (ulMajorVersion == 2 || ulMajorVersion == 3)
  406. {
  407.     if (strncasecmp(ramFile, HX_RAM_ENTRY_TAG, HX_RAM_ENTRY_TAGSIZE) == 0 && 
  408. (iSize >= (HX_RAM_ENTRY_TAGSIZE + 4)))
  409.     {
  410. CHXString* pStringAfterTag = new CHXString(ramFile+2);
  411. pStringAfterTag->TrimLeft();
  412. pStringAfterTag->TrimRight();
  413.     
  414. iSize = pStringAfterTag->GetLength();
  415. if (iSize)
  416. {
  417.     memset(ramFile, 0, iLen);
  418.     SafeStrCpy(ramFile,  pStringAfterTag->GetBuffer(iSize), iLen+1);
  419. }
  420. HX_DELETE(pStringAfterTag);
  421.     }
  422.     else
  423.     {
  424. memset(ramFile, 0, iLen);
  425.     }     
  426. }
  427.     
  428. pCursor = strstr(ramFile, ":");
  429. if (pCursor)
  430. {
  431.     ulProtocol = pCursor - ramFile;
  432.     if (ulProtocol > 0)
  433.     {
  434. pProtocol = new char[ulProtocol+1];
  435. memset(pProtocol, 0, ulProtocol+1);
  436. strncpy(pProtocol, ramFile, ulProtocol); /* Flawfinder: ignore */
  437. if (ValidateProtocol(pProtocol))
  438. {
  439.     bTrackFound = TRUE;
  440. }
  441. HX_VECTOR_DELETE(pProtocol);
  442.     }
  443. }
  444.     }
  445. }
  446. j = 0;
  447. HX_DELETE(pString);
  448.     }
  449.     else
  450.     {
  451. j++; 
  452.     }
  453.     i++;
  454. }
  455. HX_VECTOR_DELETE(ramFile);
  456. if (bTrackFound)
  457. {     
  458.     hr = HXR_OK;
  459.     goto cleanup;
  460. }
  461. else
  462. {
  463.     hr = HXR_INVALID_METAFILE;
  464.     goto cleanup;
  465. }
  466.     }
  467.     // determine if it is a RAM
  468.     else
  469.     {
  470. // Trim off any leading spaces/EOLs/tabs before adding on the pnm protocol...
  471. pLine = strtok(pContent, tokenset);
  472. while (pLine != NULL)
  473. {
  474.     size_t pos = strspn(pLine,charset);
  475.     pLine += pos;
  476.     // handle RAM3.0 syntax
  477.     if (strncasecmp(pLine, HX_RAM30_START_TAG, HX_RAM30_START_TAGSIZE) == 0)
  478.     {
  479. ulMajorVersion = 3;
  480. pLine = strtok(NULL, tokenset);
  481. continue;
  482.     }
  483.     // handle RAM2.0 syntax
  484.     else if (strncasecmp(pLine, HX_RAM20_START_TAG, HX_RAM20_START_TAGSIZE) == 0)
  485.     {
  486. ulMajorVersion = 2;
  487. pLine = strtok(NULL, tokenset);
  488. continue;
  489.     }
  490.     if (ulMajorVersion == 2 && ulMajorVersion == 3)
  491.     {
  492. if (strncasecmp(pLine, HX_RAM_ENTRY_TAG, HX_RAM_ENTRY_TAGSIZE) == 0 &&
  493.     (pCursor = strstr(pLine, ":")))
  494. {
  495.     pLine += 2;     
  496.     // trim off the leading spaces
  497.     while (pLine[0] == ' ')
  498.     {
  499. pLine++;
  500.     }
  501. }
  502. else
  503. {
  504.     pLine = strtok(NULL, tokenset);
  505.     continue;
  506. }     
  507.     }
  508.     else
  509.     {
  510. pString = new CHXString(pLine);
  511. pString->TrimLeft();
  512. pString->TrimRight();
  513. if ((pString->GetLength() == 0)     ||
  514.     (strncasecmp(pLine, "//", 2) == 0)  ||
  515.     (strncasecmp(pLine, "#", 1) == 0))
  516. {
  517.     // comments, skip to next line
  518.     pLine = strtok(NULL, tokenset);
  519.     HX_DELETE(pString);
  520.     continue;
  521. }
  522. HX_DELETE(pString);
  523. pCursor = strstr(pLine, ":");
  524. if (!pCursor)
  525. {
  526.     bIsRAM = FALSE;
  527.     break;
  528. }
  529.     }
  530.     ulProtocol = pCursor - pLine;
  531.     if (ulProtocol > 0)
  532.     {
  533. pProtocol = new char[ulProtocol+1];
  534. memset(pProtocol, 0, ulProtocol+1);
  535. strncpy(pProtocol, pLine, ulProtocol); /* Flawfinder: ignore */
  536. bIsRAM = ValidateProtocol(pProtocol);
  537. HX_VECTOR_DELETE(pProtocol);
  538. break;
  539.     }
  540.     else
  541.     {
  542. bIsRAM = FALSE;
  543. break;
  544.     }
  545. }
  546. if (bIsRAM)
  547. {
  548.     hr = HXR_OK;
  549.     goto cleanup;
  550. }
  551. else
  552. {
  553.     hr = HXR_FAILED;
  554.     goto cleanup;
  555. }
  556.     }
  557.     
  558. cleanup:
  559.     // set the RAMVersion to response header, it will be retrieved by the 
  560.     // RAM file format
  561.     if (pRequest && bIsRAM)
  562.     {
  563. if (!pResponseHeaders)
  564. {
  565.     pResponseHeaders = (IHXValues*) new CHXHeader;
  566.     pResponseHeaders->AddRef();
  567.     bHeaderToBeSet = TRUE;
  568. }
  569. UINT32 ulPersistentVersion = HX_ENCODE_PROD_VERSION(ulMajorVersion, 0, 0, 0);
  570. pResponseHeaders->SetPropertyULONG32("PersistentVersion", ulPersistentVersion);
  571. if (bHeaderToBeSet)
  572. {
  573.     pRequest->SetResponseHeaders(pResponseHeaders); 
  574. }
  575.     }
  576.     HX_VECTOR_DELETE(pURL);
  577.     HX_VECTOR_DELETE(pContent);
  578.     HX_RELEASE(pResponseHeaders);
  579.     HX_RELEASE(pValue);
  580.     HX_RELEASE(pRequest);
  581.     HX_RELEASE(pData);
  582.     return hr;
  583. }
  584. HX_RESULT
  585. HXValidator::BuildProtocolList(void)
  586. {
  587.     HX_RESULT hr = HXR_OK;
  588.     UINT32 j = 0;
  589.     UINT32 ulPlugins = 0;
  590.     IHXValues* pValues = NULL;
  591.     IHXBuffer* pBuffer = NULL;
  592.     IHXCommonClassFactory* pCommonClassFactory = NULL;
  593.     IHXPluginQuery* pPluginQuery = NULL;
  594.     IHXPluginGroupEnumerator* pPluginEnum = NULL;
  595.     CHXString* pProtocol = NULL;
  596.     CHXSimpleList::Iterator i;
  597.     if (HXR_OK != m_pContext->QueryInterface(IID_IHXCommonClassFactory, (void**)&pCommonClassFactory))
  598.     {
  599. hr = HXR_FAILED;
  600. goto cleanup;
  601.     }
  602.     // reset the list
  603.     i = m_ProtocolList.Begin();
  604.     for (; i != m_ProtocolList.End(); ++i)
  605.     {
  606. pProtocol = (CHXString*) (*i);
  607. HX_DELETE(pProtocol);
  608.     }
  609.     m_ProtocolList.RemoveAll();
  610.     // we always add "pnm" and "rtsp"
  611.     pProtocol = new CHXString("pnm");
  612.     m_ProtocolList.AddTail(pProtocol);
  613.     pProtocol = new CHXString("rtsp");
  614.     m_ProtocolList.AddTail(pProtocol);
  615.     // collect protocol info. from the pluginhandler
  616.     if (HXR_OK != pCommonClassFactory->CreateInstance(IID_IHXPluginGroupEnumerator, 
  617. (void**)&pPluginEnum))
  618.     {
  619. goto cleanup;
  620.     }
  621.     if (HXR_OK != pPluginEnum->QueryInterface(IID_IHXPluginQuery, (void**)&pPluginQuery))
  622.     {
  623. goto cleanup;
  624.     }
  625.     if (HXR_OK != pPluginQuery->GetNumPluginsGivenGroup(IID_IHXFileSystemObject, ulPlugins))
  626.     {
  627. goto cleanup;
  628.     }
  629.     for (j = 0; j < ulPlugins; j++)
  630.     {
  631. HX_RELEASE(pBuffer);
  632. HX_RELEASE(pValues);
  633. if (HXR_OK != pPluginQuery->GetPluginInfo(IID_IHXFileSystemObject, j, pValues) ||
  634.     !pValues)
  635. {
  636.     continue;
  637. }
  638. if (HXR_OK != pValues->GetPropertyCString("FileProtocol", pBuffer) ||
  639.     !pBuffer)
  640. {
  641.     continue;
  642. }
  643. pProtocol = new CHXString((const char*) pBuffer->GetBuffer());
  644. int nPos = pProtocol->Find('|');
  645. while (nPos > 0)
  646. {
  647.     CHXString* pTemp = new CHXString(pProtocol->Left(nPos));
  648.     *pProtocol = pProtocol->Mid(nPos + 1);
  649.     m_ProtocolList.AddTail(pTemp);
  650.     nPos = pProtocol->Find('|');
  651. }
  652. m_ProtocolList.AddTail(pProtocol);
  653. if (pProtocol->CompareNoCase("lice") == 0)
  654. {
  655.     CHXString *pAnother = new CHXString("rnba");
  656.     m_ProtocolList.AddTail(pAnother);
  657. }
  658.     }
  659. cleanup:
  660.     HX_RELEASE(pBuffer);
  661.     HX_RELEASE(pValues);
  662.     HX_RELEASE(pPluginQuery);
  663.     HX_RELEASE(pPluginEnum);
  664.     HX_RELEASE(pCommonClassFactory);
  665.     return hr;
  666. }
  667. void
  668. HXValidator::RefreshProtocols(void)
  669. {
  670.     m_bRefresh = TRUE;
  671. }