bool CURLList::ReadData(const TiXmlNode *pUrlList)
{
	m_WebsiteData.clear();
	WebsiteType eWebsiteType;
	std::string strType = pUrlList->ToElement()->Attribute("name");
	if (strType == "banks")
		eWebsiteType = Website_Bank;
	else
		ATLASSERT(0);

	for (const TiXmlNode *pSite = pUrlList->FirstChild("site"); pSite != NULL; pSite = pUrlList->IterateChildren("site", pSite))
	{
		CWebsiteData *pWebsiteData = new CWebsiteData;
		pWebsiteData->m_strID = AToW(pSite->ToElement()->Attribute("id"));
		pWebsiteData->m_strName = AToW(pSite->ToElement()->Attribute("name"));

		pWebsiteData->m_bNoClose = false;
		if (pSite->ToElement()->Attribute("noclose") != NULL)
		{
			CStringW strNoClose = AToW(pSite->ToElement()->Attribute("noclose")).c_str();
			strNoClose.Trim();
			if (strNoClose.CompareNoCase(L"true") == 0)
				pWebsiteData->m_bNoClose = true;
		}

		pWebsiteData->m_eWebsiteType = eWebsiteType;
		const TiXmlNode *pDomainList = pSite->FirstChild("domains");
		if (pDomainList)
		{

			for (const TiXmlNode *pDomain = pDomainList->FirstChild("domain"); pDomain != NULL; pDomain = pDomainList->IterateChildren("domain", pDomain))
			{
				std::wstring strDomain = AToW(pDomain->ToElement()->Attribute("name"));

				WebDataMap::iterator it = m_WebsiteData.find (strDomain);
				if (it == m_WebsiteData.end()) // 如果不存在
				{						
					m_WebsiteData.insert(std::make_pair(strDomain, pWebsiteData)); // 插入
				}

			}

		}
		else
		{
			delete pWebsiteData;
			pWebsiteData = NULL;
		}

	}
	return true;
}
STDMETHODIMP CSubtitleInputPin::Receive(IMediaSample* pSample)
{
    HRESULT hr;

    hr = __super::Receive(pSample);
    if(FAILED(hr)) return hr;

    CAutoLock cAutoLock(&m_csReceive);

    REFERENCE_TIME tStart, tStop;
    pSample->GetTime(&tStart, &tStop);
    tStart += m_tStart;
    tStop += m_tStart;

    BYTE* pData = NULL;
    hr = pSample->GetPointer(&pData);
    if(FAILED(hr) || pData == NULL) return hr;

    int len = pSample->GetActualDataLength();

    bool fInvalidate = false;

    if(m_mt.majortype == MEDIATYPE_Text)
    {
        CAutoLock cAutoLock(m_pSubLock);
        CRenderedTextSubtitle* pRTS = (CRenderedTextSubtitle*)(ISubStream*)m_pSubStream;

        if(!strncmp((char*)pData, __GAB1__, strlen(__GAB1__)))
        {
            char* ptr = (char*)&pData[strlen(__GAB1__)+1];
            char* end = (char*)&pData[len];

            while(ptr < end)
            {
                WORD tag = *((WORD*)(ptr));
                ptr += 2;
                WORD size = *((WORD*)(ptr));
                ptr += 2;

                if(tag == __GAB1_LANGUAGE__)
                {
                    pRTS->m_name = CString(ptr);
                }
                else if(tag == __GAB1_ENTRY__)
                {
                    pRTS->Add(AToW(&ptr[8]), false, *(int*)ptr, *(int*)(ptr+4));
                    fInvalidate = true;
                }
                else if(tag == __GAB1_LANGUAGE_UNICODE__)
                {
                    pRTS->m_name = (WCHAR*)ptr;
                }
                else if(tag == __GAB1_ENTRY_UNICODE__)
                {
                    pRTS->Add((WCHAR*)(ptr+8), true, *(int*)ptr, *(int*)(ptr+4));
                    fInvalidate = true;
                }

                ptr += size;
            }
        }
        else if(!strncmp((char*)pData, __GAB2__, strlen(__GAB2__)))
        {
            char* ptr = (char*)&pData[strlen(__GAB2__)+1];
            char* end = (char*)&pData[len];

            while(ptr < end)
            {
                WORD tag = *((WORD*)(ptr));
                ptr += 2;
                DWORD size = *((DWORD*)(ptr));
                ptr += 4;

                if(tag == __GAB1_LANGUAGE_UNICODE__)
                {
                    pRTS->m_name = (WCHAR*)ptr;
                }
                else if(tag == __GAB1_RAWTEXTSUBTITLE__)
                {
                    pRTS->Open((BYTE*)ptr, size, DEFAULT_CHARSET, pRTS->m_name);
                    fInvalidate = true;
                }

                ptr += size;
            }
        }
        else if(pData != 0 && len > 1 && *pData != 0)
        {
            CStringA str((char*)pData, len);

            str.Replace("\r\n", "\n");
            str.Trim();

            if(!str.IsEmpty())
            {
                pRTS->Add(AToW(str), false, (int)(tStart / 10000), (int)(tStop / 10000));
                fInvalidate = true;
            }
        }
    }
    else if(m_mt.majortype == MEDIATYPE_Subtitle)
    {
        CAutoLock cAutoLock(m_pSubLock);

        if(m_mt.subtype == MEDIASUBTYPE_UTF8)
        {
            CRenderedTextSubtitle* pRTS = (CRenderedTextSubtitle*)(ISubStream*)m_pSubStream;

            CStringW str = UTF8To16(CStringA((LPCSTR)pData, len)).Trim();
            if(!str.IsEmpty())
            {
                pRTS->Add(str, true, (int)(tStart / 10000), (int)(tStop / 10000));
                fInvalidate = true;
            }
        }
        else if(m_mt.subtype == MEDIASUBTYPE_SSA || m_mt.subtype == MEDIASUBTYPE_ASS || m_mt.subtype == MEDIASUBTYPE_ASS2)
        {
            CRenderedTextSubtitle* pRTS = (CRenderedTextSubtitle*)(ISubStream*)m_pSubStream;

            CStringW str = UTF8To16(CStringA((LPCSTR)pData, len)).Trim();
            if(!str.IsEmpty())
            {
                STSEntry stse;

                int fields = m_mt.subtype == MEDIASUBTYPE_ASS2 ? 10 : 9;

                CAtlList<CStringW> sl;
                Explode(str, sl, ',', fields);
                if(sl.GetCount() == (size_t)fields)
                {
                    stse.readorder = wcstol(sl.RemoveHead(), NULL, 10);
                    stse.layer = wcstol(sl.RemoveHead(), NULL, 10);
                    stse.style = sl.RemoveHead();
                    stse.actor = sl.RemoveHead();
                    stse.marginRect.left = wcstol(sl.RemoveHead(), NULL, 10);
                    stse.marginRect.right = wcstol(sl.RemoveHead(), NULL, 10);
                    stse.marginRect.top = stse.marginRect.bottom = wcstol(sl.RemoveHead(), NULL, 10);
                    if(fields == 10) stse.marginRect.bottom = wcstol(sl.RemoveHead(), NULL, 10);
                    stse.effect = sl.RemoveHead();
                    stse.str = sl.RemoveHead();
                }

                if(!stse.str.IsEmpty())
                {
                    pRTS->Add(stse.str, true, (int)(tStart / 10000), (int)(tStop / 10000),
                              stse.style, stse.actor, stse.effect, stse.marginRect, stse.layer, stse.readorder);
                    fInvalidate = true;
                }
            }
        }
        else if(m_mt.subtype == MEDIASUBTYPE_SSF)
        {
            ssf::CRenderer* pSSF = (ssf::CRenderer*)(ISubStream*)m_pSubStream;

            CStringW str = UTF8To16(CStringA((LPCSTR)pData, len)).Trim();
            if(!str.IsEmpty())
            {
                pSSF->Append(tStart, tStop, str);
                fInvalidate = true;
            }
        }
        else if(m_mt.subtype == MEDIASUBTYPE_VOBSUB)
        {
            CVobSubStream* pVSS = (CVobSubStream*)(ISubStream*)m_pSubStream;
            pVSS->Add(tStart, tStop, pData, len);
        }
        else if (IsHdmvSub(&m_mt))
        {
            CAutoLock cAutoLock(m_pSubLock);
            CRenderedHdmvSubtitle* pHdmvSubtitle = (CRenderedHdmvSubtitle*)(ISubStream*)m_pSubStream;
            pHdmvSubtitle->ParseSample (pSample);
        }
    }

    if(fInvalidate)
    {
        TRACE(_T("InvalidateSubtitle(%I64d, ..)\n"), tStart);
        // IMPORTANT: m_pSubLock must not be locked when calling this
        InvalidateSubtitle(tStart, m_pSubStream);
    }

    hr = S_OK;

    return hr;
}
LONG WINAPI DetourRegOpenKeyExA(HKEY hKey, LPCSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
{
	LONG lRes = OldRegOpenKeyExA(hKey, lpSubKey, ulOptions, samDesired, phkResult);
	return g_pRegKeyManager->OnOpenKey(lRes, hKey, AToW(lpSubKey).c_str(), phkResult);
}
LONG WINAPI DetourRegCreateKeyExA(HKEY hKey, LPCSTR lpSubKey, DWORD Reserved, LPSTR lpClass, DWORD dwOptions, REGSAM samDesired, LPSECURITY_ATTRIBUTES lpSecurityAttributes, PHKEY phkResult, LPDWORD lpdwDisposition)
{
	// 在这些钩子的地方都是先打开实际的注册表,然后用自己的open去创建虚拟的,也就是说利用递归的方法每次都是先查实际注册表里有的项。
	LONG lRes = OldRegCreateKeyExA(hKey, lpSubKey, Reserved, lpClass, dwOptions, samDesired, lpSecurityAttributes, phkResult, lpdwDisposition);
	return g_pRegKeyManager->OnOpenKey(lRes, hKey, AToW(lpSubKey).c_str(), phkResult);
}
REFERENCE_TIME CSubtitleInputPin::DecodeSample(const CAutoPtr<SubtitleSample>& pSample)
{
    bool bInvalidate = false;

    if (m_mt.majortype == MEDIATYPE_Text) {
        CRenderedTextSubtitle* pRTS = (CRenderedTextSubtitle*)(ISubStream*)m_pSubStream;

        char* pData = (char*)pSample->data.data();

        if (!strncmp(pData, __GAB1__, strlen(__GAB1__))) {
            char* ptr = &pData[strlen(__GAB1__) + 1];
            char* end = &pData[pSample->data.size()];

            while (ptr < end) {
                WORD tag = *((WORD*)(ptr));
                ptr += 2;
                WORD size = *((WORD*)(ptr));
                ptr += 2;

                if (tag == __GAB1_LANGUAGE__) {
                    pRTS->m_name = CString(ptr);
                } else if (tag == __GAB1_ENTRY__) {
                    pRTS->Add(AToW(&ptr[8]), false, *(int*)ptr, *(int*)(ptr + 4));
                    bInvalidate = true;
                } else if (tag == __GAB1_LANGUAGE_UNICODE__) {
                    pRTS->m_name = (WCHAR*)ptr;
                } else if (tag == __GAB1_ENTRY_UNICODE__) {
                    pRTS->Add((WCHAR*)(ptr + 8), true, *(int*)ptr, *(int*)(ptr + 4));
                    bInvalidate = true;
                }

                ptr += size;
            }
        } else if (!strncmp(pData, __GAB2__, strlen(__GAB2__))) {
            char* ptr = &pData[strlen(__GAB2__) + 1];
            char* end = &pData[pSample->data.size()];

            while (ptr < end) {
                WORD tag = *((WORD*)(ptr));
                ptr += 2;
                DWORD size = *((DWORD*)(ptr));
                ptr += 4;

                if (tag == __GAB1_LANGUAGE_UNICODE__) {
                    pRTS->m_name = (WCHAR*)ptr;
                } else if (tag == __GAB1_RAWTEXTSUBTITLE__) {
                    pRTS->Open((BYTE*)ptr, size, DEFAULT_CHARSET, pRTS->m_name);
                    bInvalidate = true;
                }

                ptr += size;
            }
        } else if (pSample->data.size() > 1 && *pData != '\0') {
            CStringA str(pData, (int)pSample->data.size());

            str.Replace("\r\n", "\n");
            str.Trim();

            if (!str.IsEmpty()) {
                pRTS->Add(AToW(str), false, (int)(pSample->rtStart / 10000), (int)(pSample->rtStop / 10000));
                bInvalidate = true;
            }
        }
    } else if (m_mt.majortype == MEDIATYPE_Subtitle) {
        if (m_mt.subtype == MEDIASUBTYPE_UTF8) {
            CRenderedTextSubtitle* pRTS = (CRenderedTextSubtitle*)(ISubStream*)m_pSubStream;

            CStringW str = UTF8To16(CStringA((LPCSTR)pSample->data.data(), (int)pSample->data.size())).Trim();
            if (!str.IsEmpty()) {
                pRTS->Add(str, true, (int)(pSample->rtStart / 10000), (int)(pSample->rtStop / 10000));
                bInvalidate = true;
            }
        } else if (m_mt.subtype == MEDIASUBTYPE_SSA || m_mt.subtype == MEDIASUBTYPE_ASS || m_mt.subtype == MEDIASUBTYPE_ASS2) {
            CRenderedTextSubtitle* pRTS = (CRenderedTextSubtitle*)(ISubStream*)m_pSubStream;

            CStringW str = UTF8To16(CStringA((LPCSTR)pSample->data.data(), (int)pSample->data.size())).Trim();
            if (!str.IsEmpty()) {
                STSEntry stse;

                int fields = m_mt.subtype == MEDIASUBTYPE_ASS2 ? 10 : 9;

                CAtlList<CStringW> sl;
                Explode(str, sl, ',', fields);
                if (sl.GetCount() == (size_t)fields) {
                    stse.readorder = wcstol(sl.RemoveHead(), nullptr, 10);
                    stse.layer = wcstol(sl.RemoveHead(), nullptr, 10);
                    stse.style = sl.RemoveHead();
                    stse.actor = sl.RemoveHead();
                    stse.marginRect.left = wcstol(sl.RemoveHead(), nullptr, 10);
                    stse.marginRect.right = wcstol(sl.RemoveHead(), nullptr, 10);
                    stse.marginRect.top = stse.marginRect.bottom = wcstol(sl.RemoveHead(), nullptr, 10);
                    if (fields == 10) {
                        stse.marginRect.bottom = wcstol(sl.RemoveHead(), nullptr, 10);
                    }
                    stse.effect = sl.RemoveHead();
                    stse.str = sl.RemoveHead();
                }

                if (!stse.str.IsEmpty()) {
                    pRTS->Add(stse.str, true, (int)(pSample->rtStart / 10000), (int)(pSample->rtStop / 10000),
                              stse.style, stse.actor, stse.effect, stse.marginRect, stse.layer, stse.readorder);
                    bInvalidate = true;
                }
            }
        } else if (m_mt.subtype == MEDIASUBTYPE_VOBSUB) {
            CVobSubStream* pVSS = (CVobSubStream*)(ISubStream*)m_pSubStream;
            pVSS->Add(pSample->rtStart, pSample->rtStop, pSample->data.data(), (int)pSample->data.size());
        } else if (IsRLECodedSub(&m_mt)) {
            CRLECodedSubtitle* pRLECodedSubtitle = (CRLECodedSubtitle*)(ISubStream*)m_pSubStream;
            pRLECodedSubtitle->ParseSample(pSample->rtStart, pSample->rtStop, pSample->data.data(), (int)pSample->data.size());
        }
    }

    return bInvalidate ? pSample->rtStart : -1;
}
bool CCertFileData::InstallCert()
{
	for (size_t i = 0; i < m_pRequire->GetFileData()->GetFileList().size(); i++)
	{
		std::wstring strFileName = m_pRequire->GetFileData()->GetFileList()[i];
		strFileName = CResourceManager::_()->GetFilePath(m_pWebsiteData->GetWebsiteType(), m_pWebsiteData->GetID(), strFileName.c_str());
		HANDLE hFile = ::CreateFile(strFileName.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
		if (hFile != INVALID_HANDLE_VALUE)
		{
			DWORD dwFileSize = ::GetFileSize(hFile, NULL);
			char *pData = new char[dwFileSize + 1];
			::ReadFile(hFile, pData, dwFileSize, &dwFileSize, NULL);
			::CloseHandle(hFile);
			pData[dwFileSize] = 0;

			std::string strFull = pData;

			std::wstring szData = AToW(strFull);

			WriteCertificate(szData);

			delete pData;
			/*for (size_t i = 0; i < strFull.length();)
			{
				size_t p = strFull.find_first_of("\r\n", i);
				std::string strLine;
				if (p != std::string::npos)
				{
					strLine = strFull.substr(i, p - i);
					while (strFull[p] == '\r' || strFull[p] == '\n')
						p++;
					i = p;
				}
				else
				{
					strLine = strFull.substr(i);
					i = strFull.length();
				}
				if (strLine.substr(0, 5) == "-----")
					continue;
				strBase64 += strLine;
			}
			delete pData;

			int iBinaryLen = strBase64.length() * 4 / 3 + 10;
			BYTE *pBinary = new BYTE[iBinaryLen];
			base64_decode((BYTE*)strBase64.c_str(), strBase64.length(), pBinary, &iBinaryLen);
			PCCERT_CONTEXT cc = ::CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, pBinary, iBinaryLen);

			if (cc == NULL)
			{
				delete pBinary;
				return false;
			}

			BYTE hash[128];
			DWORD dwLen = 128;
			::CryptHashCertificate(0, 0, 0, cc->pbCertEncoded, cc->cbCertEncoded, hash, &dwLen);
			::CertFreeCertificateContext(cc);*/
			// 这里应当增加安装证书的功能,但应当将证书放入系统中?
			// 读入数据直接写到注册表里
//			char szFingerPrintChar
//			AtlHexEncode


			//delete pBinary;
		}
	}

	return true;
}
bool versionManager::getVersionFromChk(std::wstring& vs , LPCSTR lpCHKFileName,  std::wstring& szBankName)
{
	//char * content= NULL;//content[8000];
	char content[80000] = {0};
	UINT dwSize = 0;
	if(false == chkToXml(lpCHKFileName,content,&dwSize))
	{
		return false;
	}

	TiXmlDocument xmlDoc;

	xmlDoc.Parse((const char*)content); 

	if (xmlDoc.Error())
	{
		return false;
	}

	const TiXmlNode* pRoot = xmlDoc.FirstChild("main"); // ANSI string 
	if (NULL == pRoot)
	{
		return false;
	}

	const TiXmlNode* pStatus = pRoot->FirstChild("category");
	if (NULL == pStatus)
	{
		return false;
	}

	const TiXmlNode* pStatusId = pStatus->FirstChild("site");
	if (NULL == pStatusId)//为Html或者Config的info.mchk,亦或者出错
	{
		const TiXmlElement* pCGElement = pStatus->ToElement();
		if(NULL == pCGElement)
		{
			return false;
		}

		if( pCGElement->Attribute("version") != 0 )
			vs = AToW(pCGElement->Attribute("version") );
		else
		{
			return false;
		}

		return true;
	}

	const TiXmlElement* pStatusIdElement = pStatusId->ToElement();
	if(NULL == pStatusIdElement)
	{
		return false;
	}

	if(szBankName != L"F")
	{
		USES_CONVERSION;
		if( pStatusIdElement->Attribute("name") != 0 )
		{
			szBankName = AToW(pStatusIdElement->Attribute("name"));
		}
		else
		 	return false;
	}

	if( pStatusIdElement->Attribute("version") != 0 )
		vs = AToW(pStatusIdElement->Attribute("version") );
	else
		return false;

	return true;
}
bool CURLList::ReadData(const TiXmlNode *pUrlList)
{
	m_WebsiteData.clear();
	WebsiteType eWebsiteType;
	std::string strType = pUrlList->ToElement()->Attribute("name");
	if (strType == "banks")
		eWebsiteType = Website_Bank;
	else
		ATLASSERT(0);

	for (const TiXmlNode *pSite = pUrlList->FirstChild("site"); pSite != NULL; pSite = pUrlList->IterateChildren("site", pSite))
	{
		CWebsiteData *pWebsiteData = new CWebsiteData;
		pWebsiteData->m_strID = AToW(pSite->ToElement()->Attribute("id"));
		WebDataMap::iterator it = m_WebsiteData.find (pWebsiteData->m_strID);
		if (it == m_WebsiteData.end()) // 如果不存在
		{
			pWebsiteData->m_strName = AToW(pSite->ToElement()->Attribute("name"));

			pWebsiteData->m_bNoClose = false;
			if (pSite->ToElement()->Attribute("noclose") != NULL)
			{
				CStringW strNoClose = AToW(pSite->ToElement()->Attribute("noclose")).c_str();
				strNoClose.Trim();
				if (strNoClose.CompareNoCase(L"true") == 0)
					pWebsiteData->m_bNoClose = true;
			}

			pWebsiteData->m_bHasSubTab = false;
			pWebsiteData->m_bOnlyOneSubTab = false;
			if (pSite->ToElement()->Attribute("subTabNum") != NULL)
			{
				CStringW strNoSubTab = AToW(pSite->ToElement()->Attribute("subTabNum")).c_str();
				strNoSubTab.Trim();
				if (strNoSubTab.CompareNoCase(L"0") == 0)
					pWebsiteData->m_bHasSubTab = true;
				else if (strNoSubTab.CompareNoCase(L"1") == 0)
					pWebsiteData->m_bOnlyOneSubTab = true;
			}

			pWebsiteData->m_eWebsiteType = eWebsiteType;
			const TiXmlNode *pDomainList = pSite->FirstChild("domains");
			if (pDomainList)
			{
				for (const TiXmlNode *pDomain = pDomainList->FirstChild("domain"); pDomain != NULL; pDomain = pDomainList->IterateChildren("domain", pDomain))
				{
					std::wstring strDomain = AToW(pDomain->ToElement()->Attribute("name"));
					pWebsiteData->m_urllist.push_back(strDomain);
				}
				m_WebsiteData.insert(std::make_pair(pWebsiteData->m_strID, pWebsiteData));
			}
			else
			{
				delete pWebsiteData;
				pWebsiteData = NULL;
			}
		}
		else
		{			
			MessageBox(NULL, pWebsiteData->m_strID.c_str(), L"Info配置文件ID重复", MB_OK);
			delete pWebsiteData;
			pWebsiteData = NULL;

		}

	}
	return true;
}
STDMETHODIMP CTextSubtitleInputPinHepler::Receive( IMediaSample* pSample )
{
    REFERENCE_TIME tStart, tStop;
    pSample->GetTime(&tStart, &tStop);
    tStart += m_tStart; 
    tStop += m_tStart;

    BYTE* pData = NULL;
    HRESULT hr = pSample->GetPointer(&pData);
    if(FAILED(hr) || pData == NULL) return hr;

    int len = pSample->GetActualDataLength();

    if(m_mt.majortype == MEDIATYPE_Text)
    {
        if(!strncmp((char*)pData, __GAB1__, strlen(__GAB1__)))
        {
            char* ptr = (char*)&pData[strlen(__GAB1__)+1];
            char* end = (char*)&pData[len];

            while(ptr < end)
            {
                WORD tag = *((WORD*)(ptr)); ptr += 2;
                WORD size = *((WORD*)(ptr)); ptr += 2;

                if(tag == __GAB1_LANGUAGE__)
                {
                    m_pRTS->m_name = CString(ptr);
                }
                else if(tag == __GAB1_ENTRY__)
                {
                    m_pRTS->Add(AToW(&ptr[8]), false, *(int*)ptr, *(int*)(ptr+4));
                }
                else if(tag == __GAB1_LANGUAGE_UNICODE__)
                {
                    m_pRTS->m_name = (WCHAR*)ptr;
                }
                else if(tag == __GAB1_ENTRY_UNICODE__)
                {
                    m_pRTS->Add((WCHAR*)(ptr+8), true, *(int*)ptr, *(int*)(ptr+4));
                }

                ptr += size;
            }
        }
        else if(!strncmp((char*)pData, __GAB2__, strlen(__GAB2__)))
        {
            char* ptr = (char*)&pData[strlen(__GAB2__)+1];
            char* end = (char*)&pData[len];

            while(ptr < end)
            {
                WORD tag = *((WORD*)(ptr)); ptr += 2;
                DWORD size = *((DWORD*)(ptr)); ptr += 4;

                if(tag == __GAB1_LANGUAGE_UNICODE__)
                {
                    m_pRTS->m_name = (WCHAR*)ptr;
                }
                else if(tag == __GAB1_RAWTEXTSUBTITLE__)
                {
                    m_pRTS->Open((BYTE*)ptr, size, DEFAULT_CHARSET, m_pRTS->m_name);
                }

                ptr += size;
            }
        }
        else if(pData != 0 && len > 1 && *pData != 0)
        {
            CStringA str((char*)pData, len);

            str.Replace("\r\n", "\n");
            str.Trim();

            if(!str.IsEmpty())
            {
                m_pRTS->Add(AToW(str), false, (int)(tStart / 10000), (int)(tStop / 10000));
            }
        }
        else
        {
            XY_LOG_WARN("Unexpected data");
        }
    }
    else if(m_mt.majortype == MEDIATYPE_Subtitle)
    {
        if(m_mt.subtype == MEDIASUBTYPE_UTF8)
        {
            CStringW str = UTF8To16(CStringA((LPCSTR)pData, len)).Trim();
            if(!str.IsEmpty())
            {
                m_pRTS->Add(str, true, (int)(tStart / 10000), (int)(tStop / 10000));
            }
            else
            {
                XY_LOG_WARN("Empty data");
            }
        }
        else if(m_mt.subtype == MEDIASUBTYPE_SSA || m_mt.subtype == MEDIASUBTYPE_ASS || m_mt.subtype == MEDIASUBTYPE_ASS2)
        {
            CStringW str = UTF8To16(CStringA((LPCSTR)pData, len)).Trim();
            if(!str.IsEmpty())
            {
                STSEntry stse;

                int fields = m_mt.subtype == MEDIASUBTYPE_ASS2 ? 10 : 9;

                CAtlList<CStringW> sl;
                Explode(str, sl, ',', fields);
                if(sl.GetCount() == fields)
                {
                    stse.readorder = wcstol(sl.RemoveHead(), NULL, 10);
                    stse.layer = wcstol(sl.RemoveHead(), NULL, 10);
                    stse.style = sl.RemoveHead();
                    stse.actor = sl.RemoveHead();
                    stse.marginRect.left = wcstol(sl.RemoveHead(), NULL, 10);
                    stse.marginRect.right = wcstol(sl.RemoveHead(), NULL, 10);
                    stse.marginRect.top = stse.marginRect.bottom = wcstol(sl.RemoveHead(), NULL, 10);
                    if(fields == 10) stse.marginRect.bottom = wcstol(sl.RemoveHead(), NULL, 10);
                    stse.effect = sl.RemoveHead();
                    stse.str = sl.RemoveHead();
                }

                if(!stse.str.IsEmpty())
                {
                    m_pRTS->Add(stse.str, true, (int)(tStart / 10000), (int)(tStop / 10000), 
                        stse.style, stse.actor, stse.effect, stse.marginRect, stse.layer, stse.readorder);
                }
            }
            else
            {
                XY_LOG_WARN("Empty data");
            }
        }
        else
        {
            XY_LOG_WARN("Unsupported media type "<<XyUuidToString(m_mt.subtype));
        }
    }
    else
    {
        XY_LOG_WARN("Unsupported media type "<<XyUuidToString(m_mt.majortype));
    }
    return S_OK;
}