Esempio n. 1
0
BOOL CSxSParser::ParseFile(LPCTSTR szFilePath)
{
    CPEResource res;
    if(!res.Open(szFilePath))
        return FALSE;

    LPVOID pData = NULL;
    DWORD dwLength = 0;
    if(!res.GetManifest(pData, dwLength))
        return FALSE;

    if(pData == NULL)
        return TRUE;

    CStringA strManifest;
    LPSTR pManifest = strManifest.GetBufferSetLength(dwLength);
    memcpy(pManifest, pData, dwLength);
    strManifest.ReleaseBuffer();

    int nStart = 0;
    CStringA strAssembly = Util::GetToken(strManifest, "<dependentAssembly>", "</dependentAssembly>", nStart);
    for(; !strAssembly.IsEmpty(); strAssembly = Util::GetToken(strManifest, "<dependentAssembly>", "</dependentAssembly>", nStart))
    {
        CSxSItem item;

        if(!ParseAssembly(strAssembly, item))
            return FALSE;

        item.listFiles.Add(szFilePath);
        AddAssemblyItem(item);
    }

    return TRUE;
}
Esempio n. 2
0
HRESULT CWAVFile::ReadRIFFINFO(const __int64 info_pos, const int info_size)
{
	m_info.RemoveAll();
	DWORD id = 0;
	m_pFile->Seek(info_pos);

	if (info_size < 4 || m_pFile->ByteRead((BYTE*)&id, 4) != S_OK || id != FCC('INFO')) {
		return E_FAIL;
	}

	__int64 end = info_pos + info_size;
	chunk_t Chunk;

	while (m_pFile->GetPos() + 8 < end && m_pFile->ByteRead(Chunk.data, sizeof(Chunk)) == S_OK && m_pFile->GetPos() + Chunk.size <= end) {
		__int64 pos = m_pFile->GetPos();

		if (Chunk.size > 0 && (Chunk.id == FCC('INAM') || Chunk.id == FCC('IART') || Chunk.id == FCC('ICOP') || Chunk.id == FCC('ISBJ'))) {
			CStringA value;
			if (S_OK != m_pFile->ByteRead((BYTE*)value.GetBufferSetLength(Chunk.size), Chunk.size)) {
				return S_FALSE;
			}
			m_info[Chunk.id] = value;
		}

		m_pFile->Seek(pos + Chunk.size);
	}

	return S_OK;
}
Esempio n. 3
0
/**
 * Returns the .git-path (if .git is a file, read the repository path and return it)
 * adminDir always ends with "\"
 */
bool GitAdminDir::GetAdminDirPath(const CString& projectTopDir, CString& adminDir, bool* isWorktree)
{
	CString wtAdminDir;
	if (!GetWorktreeAdminDirPath(projectTopDir, wtAdminDir))
		return false;

	CString pathToCommonDir = wtAdminDir + L"commondir";
	if (!PathFileExists(pathToCommonDir))
	{
		adminDir = wtAdminDir;
		if (isWorktree)
			*isWorktree = false;
		return true;
	}

	CAutoFILE pFile = _wfsopen(pathToCommonDir, L"rb", SH_DENYWR);
	if (!pFile)
		return false;

	int size = 65536;
	CStringA commonDirA;
	int length = (int)fread(commonDirA.GetBufferSetLength(size), sizeof(char), size, pFile);
	commonDirA.ReleaseBuffer(length);
	CString commonDir = CUnicodeUtils::GetUnicode(commonDirA);
	commonDir.TrimRight(L"\r\n");
	commonDir.Replace(L'/', L'\\');
	if (PathIsRelative(commonDir))
		adminDir = CPathUtils::BuildPathWithPathDelimiter(wtAdminDir + commonDir);
	else
		adminDir = CPathUtils::BuildPathWithPathDelimiter(commonDir);
	if (isWorktree)
		*isWorktree = true;
	return true;
}
Esempio n. 4
0
CStringA Util::String::UnicodeToGBK( CStringW unicode )
{
	CStringA strGBK = "";
	DWORD dwMinSize = 0;
	dwMinSize = WideCharToMultiByte(936, NULL, unicode, unicode.GetLength(),NULL, 0, NULL, FALSE);
	strGBK.GetBufferSetLength(dwMinSize);
	LPSTR lpszStr =  strGBK.GetBuffer();
	INT ok = WideCharToMultiByte(936, NULL, unicode, unicode.GetLength(), lpszStr, dwMinSize, NULL, FALSE);
	strGBK.ReleaseBuffer();
	return strGBK;
}
Esempio n. 5
0
bool CDSMSplitterFile::Read(__int64 len, CStreamInfoMap& im)
{
	while (len >= 5) {
		CStringA key;
		ByteRead((BYTE*)key.GetBufferSetLength(4), 4);
		len -= 4;
		len -= Read(len, im[key]);
	}

	return len == 0;
}
Esempio n. 6
0
HRESULT CPixelShaderCompiler::CompileShader(
    LPCSTR pSrcData,
    LPCSTR pFunctionName,
    LPCSTR pProfile,
    DWORD Flags,
    IDirect3DPixelShader9** ppPixelShader,
    CString* disasm,
    CString* errmsg)
{
    if (!m_pD3DXCompileShader || !m_pD3DXDisassembleShader) {
        return E_FAIL;
    }

    HRESULT hr;

    CComPtr<ID3DXBuffer> pShader, pDisAsm, pErrorMsgs;
    hr = m_pD3DXCompileShader(pSrcData, (UINT)strlen(pSrcData), NULL, NULL, pFunctionName, pProfile, Flags, &pShader, &pErrorMsgs, NULL);

    if (FAILED(hr)) {
        if (errmsg) {
            CStringA msg = "Unexpected compiler error";

            if (pErrorMsgs) {
                int len = pErrorMsgs->GetBufferSize();
                memcpy(msg.GetBufferSetLength(len), pErrorMsgs->GetBufferPointer(), len);
            }

            *errmsg = msg;
        }

        return hr;
    }

    if (ppPixelShader) {
        if (!m_pD3DDev) {
            return E_FAIL;
        }
        hr = m_pD3DDev->CreatePixelShader((DWORD*)pShader->GetBufferPointer(), ppPixelShader);
        if (FAILED(hr)) {
            return hr;
        }
    }

    if (disasm) {
        hr = m_pD3DXDisassembleShader((DWORD*)pShader->GetBufferPointer(), FALSE, NULL, &pDisAsm);
        if (SUCCEEDED(hr) && pDisAsm) {
            *disasm = CStringA((const char*)pDisAsm->GetBufferPointer());
        }
    }

    return S_OK;
}
Esempio n. 7
0
BOOL CStdioFileEx::ReadAnsiString(CStringA& rString)
{
   _ASSERTE(m_pStream);
   rString = "";      // empty string without deallocating
   
   if(!m_bIsUnicodeText)
   {
      const int nMaxSize = 128;
      LPSTR lpsz = rString.GetBuffer(nMaxSize);
      LPSTR lpszResult;
      int nLen = 0;
      for (;;)
      {
         lpszResult = fgets(lpsz, nMaxSize+1, m_pStream);
         rString.ReleaseBuffer();
         
         // handle error/eof case
         if (lpszResult == NULL && !feof(m_pStream))
         {
            Afx_clearerr_s(m_pStream);
            AfxThrowFileException(CFileException::genericException, _doserrno,
               m_strFileName);
         }
         
         // if string is read completely or EOF
         if (lpszResult == NULL ||
            (nLen = (int)lstrlenA(lpsz)) < nMaxSize ||
            lpsz[nLen-1] == '\n')
            break;
         
         nLen = rString.GetLength();
         lpsz = rString.GetBuffer(nMaxSize + nLen) + nLen;
      }
      //remove crlf if exist.
      nLen = rString.GetLength();
      if (nLen > 1 && rString.Mid(nLen-2) == "\r\n")
      {
         rString.GetBufferSetLength(nLen-2);
      }
      return rString.GetLength() > 0;
   }
   else
   {
      CStringW wideString;
      BOOL bRetval = ReadWideString(wideString);
      //setlocale(LC_ALL, "chs_chn.936");//no need
      rString = wideString;
      return bRetval;
   }
}
Esempio n. 8
0
CString ScintillaEditor::GetWord()
{
	int savePos = GetCurrentPos();
	SendEditor(SCI_WORDLEFT);
	DWORD startPos = GetCurrentPos();
	SendEditor(SCI_WORDRIGHTEXTEND);
	DWORD endPos = GetCurrentPos();
	CStringA str;
	LPSTR buf = str.GetBufferSetLength(endPos - startPos);
	GetSelText(buf);
	str.ReleaseBuffer(endPos - startPos);
	SendEditor(SCI_SETCURRENTPOS, savePos);

	return CString(str);
}
Esempio n. 9
0
LPCSTR StringWCharToChar(LPCWSTR sWChar, CStringA &sChar, int iChars/* = -1*/, char chDef/* = '?'*/, UINT codepage/* = CP_ACP*/)
{
	if (!sWChar)
		return NULL;

	sChar.Empty();
	int iLen = WideCharToMultiByte(codepage, WC_NO_BEST_FIT_CHARS, sWChar, iChars, NULL, 0, &chDef, NULL);
	if (iLen > 0) {
		LPSTR sBuf = sChar.GetBufferSetLength(iLen);
		WideCharToMultiByte(codepage, WC_NO_BEST_FIT_CHARS, sWChar, iChars, sBuf, iLen, &chDef, NULL);
		sChar.ReleaseBufferSetLength(sBuf[iLen - 1] ? iLen : iLen - 1);
		return (iLen > 0) ? sChar.GetString() : NULL;
	}

	return (*sWChar != 0) ? sChar.GetString() : NULL;
}
Esempio n. 10
0
LPCSTR StringWCharToUTF8(LPCWSTR sWChar, CStringA &sUTF8, int iChars/* = -1*/)
{
	if (!sWChar)
		return NULL;

	sUTF8.Empty();
	int iLen = WideCharToMultiByte(CP_UTF8, 0, sWChar, iChars, NULL, 0, NULL, NULL);
	if (iLen > 0) {
		LPSTR sBuf = sUTF8.GetBufferSetLength(iLen);
		WideCharToMultiByte(CP_UTF8, 0, sWChar, iChars, sBuf, iLen, NULL, NULL);
		sUTF8.ReleaseBufferSetLength(sBuf[iLen - 1] ? iLen : iLen - 1);
		return (iLen > 0) ? sUTF8.GetString() : NULL;
	}

	return (*sWChar != 0) ? sUTF8.GetString() : NULL;
}
Esempio n. 11
0
bool CWebServer::LoadPage(UINT resid, CStringA& str, CString path)
{
	CString redir;
	if (ToLocalPath(path, redir)) {
		if (FILE* f = _tfopen(path, _T("rb"))) {
			fseek(f, 0, 2);
			char* buff = str.GetBufferSetLength(ftell(f));
			fseek(f, 0, 0);
			int len = fread(buff, 1, str.GetLength(), f);
			fclose(f);
			return len == str.GetLength();
		}
	}

	return LoadResource(resid, str, RT_HTML);
}
Esempio n. 12
0
BOOL CStdioFileT::ReadString(CStringA& rString)
{
	ASSERT_VALID(this);

#ifndef afxChNil
	static TCHAR afxChNil = '\0';
#endif

	rString = &afxChNil;    // empty string without deallocating
	const int nMaxSize = 128;
	LPSTR lpsz = rString.GetBuffer(nMaxSize);
	LPSTR lpszResult;
	int nLen = 0;
	for (;;)
	{
		lpszResult = fgets(lpsz, nMaxSize+1, m_pStream);
		rString.ReleaseBuffer();

		// handle error/eof case
		if (lpszResult == NULL && !feof(m_pStream))
		{
			clearerr(m_pStream);
			AfxThrowFileException(CFileException::genericException, _doserrno,
				m_strFileName);
		}

		// if string is read completely or EOF
		if (lpszResult == NULL ||
			(nLen = (int)strlen(lpsz)) < nMaxSize ||
			lpsz[nLen-1] == '\n')
			break;

		nLen = rString.GetLength();
		lpsz = rString.GetBuffer(nMaxSize + nLen) + nLen;
	}

	// remove '\n' from end of string if present
	lpsz = rString.GetBuffer(0);
	nLen = rString.GetLength();
	if (nLen != 0 && lpsz[nLen-1] == '\n')
		rString.GetBufferSetLength(nLen-1);

	return lpszResult != NULL;
}
Esempio n. 13
0
//To convert escaped characters back to their original values.
CString CStrUtil::DecodeURL(const CString& strSour)
{
	CStringA strDestination;

//#ifdef _UNICODE
//	WCHAR* pBuf = DecodeFromUTF8(FilterMultiBytes(strSour));
//	strDestination = pBuf;
//	delete []pBuf;
//#else	
//	DWORD dwLength = strSour.GetLength();
//	//TCHAR *pBuff = new TCHAR[dwLength + 1];
//	strDestination.GetBufferSetLength(dwLength);
//	if (AtlUnescapeUrl(strSour, strDestination.GetBuffer(), &dwLength, dwLength + 1))
//	{
//		strDestination.ReleaseBuffer();
//	}		
//	else
//	{
//		strDestination.ReleaseBuffer(0);
//	}
//#endif		

	CString strTemp = FilterMultiBytes(strSour);
	CStringA strA = CT2A(strTemp,CP_UTF8);
	DWORD dwLength = strA.GetLength();
	//TCHAR *pBuff = new TCHAR[dwLength + 1];
	strDestination.GetBufferSetLength(dwLength);
	if (AtlUnescapeUrl(strA, strDestination.GetBuffer(), &dwLength, dwLength + 1))
	{
		strDestination.ReleaseBuffer();
	}		
	else
	{
		strDestination.ReleaseBuffer(0);
	}

	strTemp = CA2T(strDestination,CP_UTF8);
	return strTemp;	
}
Esempio n. 14
0
BOOL CCsgIdeView::LoadFile (LPCTSTR szPath)
{
	// if pathname is empty do nothing
	if (szPath == NULL || *szPath == L'\0')
		return TRUE;

	HANDLE h = CreateFile(szPath,GENERIC_READ, FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);

	DWORD fs=0, fsr=0;
	fs = GetFileSize(h,NULL);

	CStringA str;
	ReadFile(h,str.GetBufferSetLength(fs),fs,&fsr,NULL);

	ASSERT(fs == fsr);
	GetCtrl().SetText((LPCSTR)str);

	CloseHandle(h);

	GetCtrl().FoldAll(SC_FOLDACTION_CONTRACT);

	return TRUE;
}
Esempio n. 15
0
void CWebServer::OnRequest(CWebClientSocket* pClient, CStringA& hdr, CStringA& body)
{
    CPath p(pClient->m_path);
    CStringA ext = p.GetExtension().MakeLower();
    CStringA mime;
    if (ext.IsEmpty()) {
        mime = "text/html";
    } else {
        m_mimes.Lookup(ext, mime);
    }

    hdr = "HTTP/1.0 200 OK\r\n";

    bool fHandled = false, fCGI = false;

    if (!fHandled && m_webroot.IsDirectory()) {
        CStringA tmphdr;
        fHandled = fCGI = CallCGI(pClient, tmphdr, body, mime);

        if (fHandled) {
            tmphdr.Replace("\r\n", "\n");
            CAtlList<CStringA> hdrlines;
            ExplodeMin(tmphdr, hdrlines, '\n');
            POSITION pos = hdrlines.GetHeadPosition();
            while (pos) {
                POSITION cur = pos;
                CAtlList<CStringA> sl;
                CStringA key = Explode(hdrlines.GetNext(pos), sl, ':', 2);
                if (sl.GetCount() < 2) {
                    continue;
                }
                key.Trim().MakeLower();
                if (key == "content-type") {
                    mime = sl.GetTail().Trim();
                    hdrlines.RemoveAt(cur);
                } else if (key == "content-length") {
                    hdrlines.RemoveAt(cur);
                }
            }
            tmphdr = Implode(hdrlines, '\n');
            tmphdr.Replace("\n", "\r\n");
            hdr += tmphdr + "\r\n";
        }
    }

    RequestHandler rh = NULL;
    if (!fHandled && m_internalpages.Lookup(pClient->m_path, rh) && (pClient->*rh)(hdr, body, mime)) {
        if (mime.IsEmpty()) {
            mime = "text/html";
        }

        CString redir;
        if (pClient->m_get.Lookup(_T("redir"), redir)
                || pClient->m_post.Lookup(_T("redir"), redir)) {
            if (redir.IsEmpty()) {
                redir = '/';
            }

            hdr =
                "HTTP/1.0 302 Found\r\n"
                "Location: " + CStringA(redir) + "\r\n";
            return;
        }

        fHandled = true;
    }

    if (!fHandled && m_webroot.IsDirectory()) {
        fHandled = LoadPage(0, body, pClient->m_path);
    }

    UINT resid;
    CStringA res;
    if (!fHandled && m_downloads.Lookup(pClient->m_path, resid)
            && (LoadResource(resid, res, _T("FILE")) || LoadResource(resid, res, _T("PNG")))) {
        if (mime.IsEmpty()) {
            mime = "application/octet-stream";
        }
        memcpy(body.GetBufferSetLength(res.GetLength()), res.GetBuffer(), res.GetLength());
        fHandled = true;
    }

    if (!fHandled) {
        hdr = mime == "text/html"
              ? "HTTP/1.0 301 Moved Permanently\r\n" "Location: /404.html\r\n"
              : "HTTP/1.0 404 Not Found\r\n";
        return;
    }

    if ((mime == "text/html" || mime == "text/javascript") && !fCGI) {
        if (mime == "text/html") {
            hdr +=
                "Expires: Thu, 19 Nov 1981 08:52:00 GMT\r\n"
                "Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0\r\n"
                "Pragma: no-cache\r\n";

            CStringA debug;
            if (AfxGetAppSettings().fWebServerPrintDebugInfo) {
                debug += "<br><hr>\r\n";
                debug += "<div id=\"debug\">";
                CString key, value;
                POSITION pos;
                pos = pClient->m_hdrlines.GetStartPosition();
                while (pos) {
                    pClient->m_hdrlines.GetNextAssoc(pos, key, value);
                    debug += "HEADER[" + key + "] = " + value + "\r\n";
                }
                debug += "cmd: " + pClient->m_cmd + "\r\n";
                debug += "path: " + pClient->m_path + "\r\n";
                debug += "ver: " + pClient->m_ver + "\r\n";
                pos = pClient->m_get.GetStartPosition();
                while (pos) {
                    pClient->m_get.GetNextAssoc(pos, key, value);
                    debug += "GET[" + key + "] = " + value + "\r\n";
                }
                pos = pClient->m_post.GetStartPosition();
                while (pos) {
                    pClient->m_post.GetNextAssoc(pos, key, value);
                    debug += "POST[" + key + "] = " + value + "\r\n";
                }
                pos = pClient->m_cookie.GetStartPosition();
                while (pos) {
                    pClient->m_cookie.GetNextAssoc(pos, key, value);
                    debug += "COOKIE[" + key + "] = " + value + "\r\n";
                }
                pos = pClient->m_request.GetStartPosition();
                while (pos) {
                    pClient->m_request.GetNextAssoc(pos, key, value);
                    debug += "REQUEST[" + key + "] = " + value + "\r\n";
                }
                debug += "</div>";
            }
            body.Replace("[debug]", debug);
        }

        body.Replace("[browserpath]", "/browser.html");
        body.Replace("[commandpath]", "/command.html");
        body.Replace("[controlspath]", "/controls.html");
        body.Replace("[indexpath]", "/index.html");
        body.Replace("[path]", CStringA(pClient->m_path));
        body.Replace("[setposcommand]", CMD_SETPOS);
        body.Replace("[setvolumecommand]", CMD_SETVOLUME);
        body.Replace("[wmcname]", "wm_command");
        // TODO: add more general tags to replace
    }

    // gzip
    if (AfxGetAppSettings().fWebServerUseCompression && hdr.Find("Content-Encoding:") < 0)
        do {
            CString accept_encoding;
            pClient->m_hdrlines.Lookup(_T("accept-encoding"), accept_encoding);
            accept_encoding.MakeLower();
            CAtlList<CString> sl;
            ExplodeMin(accept_encoding, sl, ',');
            if (!sl.Find(_T("gzip"))) {
                break;
            }

            CHAR path[_MAX_PATH], fn[_MAX_PATH];
            if (!GetTempPathA(_MAX_PATH, path) || !GetTempFileNameA(path, "mpc_gz", 0, fn)) {
                break;
            }

            gzFile gf = gzopen(fn, "wb9");
            if (!gf || gzwrite(gf, (LPVOID)(LPCSTR)body, body.GetLength()) != body.GetLength()) {
                if (gf) {
                    gzclose(gf);
                }
                DeleteFileA(fn);
                break;
            }
            gzclose(gf);

            FILE* f = NULL;
            if (fopen_s(&f, fn, "rb")) {
                DeleteFileA(fn);
                break;
            }
            fseek(f, 0, 2);
            CHAR* s = body.GetBufferSetLength(ftell(f));
            fseek(f, 0, 0);
            int len = (int)fread(s, 1, body.GetLength(), f);
            ASSERT(len == body.GetLength());
#ifndef _DEBUG
            UNREFERENCED_PARAMETER(len);
#endif
            fclose(f);
            DeleteFileA(fn);

            hdr += "Content-Encoding: gzip\r\n";
        } while (0);

    CStringA content;
    content.Format(
        "Content-Type: %s\r\n"
        "Content-Length: %d\r\n",
        mime, body.GetLength());
    hdr += content;
}
Esempio n. 16
0
BOOL CTortoiseProcApp::InitInstance()
{
	CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) _T(": InitInstance\n"));
	CheckUpgrade();
	CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows));
	CMFCButton::EnableWindowsTheming();
	CHistoryCombo::m_nGitIconIndex = SYS_IMAGE_LIST().AddIcon((HICON)LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_GITCONFIG), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE));

	Gdiplus::GdiplusStartupInput gdiplusStartupInput;
	Gdiplus::GdiplusStartup(&m_gdiplusToken,&gdiplusStartupInput,NULL);

	//set the resource dll for the required language
	CRegDWORD loc = CRegDWORD(_T("Software\\TortoiseGit\\LanguageID"), 1033);
	long langId = loc;
	{
		CString langStr;
		langStr.Format(_T("%ld"), langId);
		CCrashReport::Instance().AddUserInfoToReport(L"LanguageID", langStr);
	}
	CString langDll;
	CStringA langpath = CStringA(CPathUtils::GetAppParentDirectory());
	langpath += "Languages";
	do
	{
		langDll.Format(_T("%sLanguages\\TortoiseProc%ld.dll"), (LPCTSTR)CPathUtils::GetAppParentDirectory(), langId);

		CString sVer = _T(STRPRODUCTVER);
		CString sFileVer = CPathUtils::GetVersionFromFile(langDll);
		if (sFileVer == sVer)
		{
			HINSTANCE hInst = LoadLibrary(langDll);
			if (hInst != NULL)
			{
				CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) _T(": Load Language DLL %s\n"), langDll);
				AfxSetResourceHandle(hInst);
				break;
			}
		}
		{
			DWORD lid = SUBLANGID(langId);
			lid--;
			if (lid > 0)
			{
				langId = MAKELANGID(PRIMARYLANGID(langId), lid);
			}
			else
				langId = 0;
		}
	} while (langId != 0);
	TCHAR buf[6] = { 0 };
	_tcscpy_s(buf, _T("en"));
	langId = loc;
	// MFC uses a help file with the same name as the application by default,
	// which means we have to change that default to our language specific help files
	CString sHelppath = CPathUtils::GetAppDirectory() + _T("TortoiseGit_en.chm");
	free((void*)m_pszHelpFilePath);
	m_pszHelpFilePath=_tcsdup(sHelppath);
	sHelppath = CPathUtils::GetAppParentDirectory() + _T("Languages\\TortoiseGit_en.chm");
	do
	{
		CString sLang = _T("_");
		if (GetLocaleInfo(MAKELCID(langId, SORT_DEFAULT), LOCALE_SISO639LANGNAME, buf, _countof(buf)))
		{
			sLang += buf;
			sHelppath.Replace(_T("_en"), sLang);
			if (PathFileExists(sHelppath))
			{
				free((void*)m_pszHelpFilePath);
				m_pszHelpFilePath=_tcsdup(sHelppath);
				break;
			}
		}
		sHelppath.Replace(sLang, _T("_en"));
		if (GetLocaleInfo(MAKELCID(langId, SORT_DEFAULT), LOCALE_SISO3166CTRYNAME, buf, _countof(buf)))
		{
			sLang += _T("_");
			sLang += buf;
			sHelppath.Replace(_T("_en"), sLang);
			if (PathFileExists(sHelppath))
			{
				free((void*)m_pszHelpFilePath);
				m_pszHelpFilePath=_tcsdup(sHelppath);
				break;
			}
		}
		sHelppath.Replace(sLang, _T("_en"));

		DWORD lid = SUBLANGID(langId);
		lid--;
		if (lid > 0)
		{
			langId = MAKELANGID(PRIMARYLANGID(langId), lid);
		}
		else
			langId = 0;
	} while (langId);
	CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) _T(": Set Help Filename %s\n"), m_pszHelpFilePath);
	setlocale(LC_ALL, "");

	if (!g_Git.CheckMsysGitDir())
	{
		UINT ret = CMessageBox::Show(NULL, IDS_PROC_NOMSYSGIT, IDS_APPNAME, 3, IDI_HAND, IDS_PROC_SETMSYSGITPATH, IDS_PROC_GOTOMSYSGITWEBSITE, IDS_ABORTBUTTON);
		if(ret == 2)
		{
			ShellExecute(NULL, NULL, _T("http://msysgit.github.io/"), NULL, NULL, SW_SHOW);
		}
		else if(ret == 1)
		{
			// open settings dialog
			CSinglePropSheetDlg(CString(MAKEINTRESOURCE(IDS_PROC_SETTINGS_TITLE)), new CSetMainPage(), this->GetMainWnd()).DoModal();
		}
		return FALSE;
	}
	if (CAppUtils::GetMsysgitVersion() < 0x01070a00)
	{
		int ret = CMessageBox::ShowCheck(NULL, IDS_PROC_OLDMSYSGIT, IDS_APPNAME, 1, IDI_EXCLAMATION, IDS_PROC_GOTOMSYSGITWEBSITE, IDS_ABORTBUTTON, IDS_IGNOREBUTTON, _T("OldMsysgitVersionWarning"), IDS_PROC_NOTSHOWAGAINIGNORE);
		if (ret == 1)
		{
			CMessageBox::RemoveRegistryKey(_T("OldMsysgitVersionWarning")); // only store answer if it is "Ignore"
			ShellExecute(NULL, NULL, _T("http://msysgit.github.io/"), NULL, NULL, SW_SHOW);
			return FALSE;
		}
		else if (ret == 2)
		{
			CMessageBox::RemoveRegistryKey(_T("OldMsysgitVersionWarning")); // only store answer if it is "Ignore"
			return FALSE;
		}
	}

	{
		CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) _T(": Registering Crash Report ...\n"));
		CCrashReport::Instance().AddUserInfoToReport(L"msysGitDir", CGit::ms_LastMsysGitDir);
		CString versionString;
		versionString.Format(_T("%d"), CGit::ms_LastMsysGitVersion);
		CCrashReport::Instance().AddUserInfoToReport(L"msysGitVersion", versionString);
	}

	CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) _T(": Initializing UI components ...\n"));
	// InitCommonControls() is required on Windows XP if an application
	// manifest specifies use of ComCtl32.dll version 6 or later to enable
	// visual styles.  Otherwise, any window creation will fail.

	INITCOMMONCONTROLSEX used = {
		sizeof(INITCOMMONCONTROLSEX),
			ICC_ANIMATE_CLASS | ICC_BAR_CLASSES | ICC_COOL_CLASSES | ICC_DATE_CLASSES |
			ICC_HOTKEY_CLASS | ICC_INTERNET_CLASSES | ICC_LISTVIEW_CLASSES |
			ICC_NATIVEFNTCTL_CLASS | ICC_PAGESCROLLER_CLASS | ICC_PROGRESS_CLASS |
			ICC_TAB_CLASSES | ICC_TREEVIEW_CLASSES | ICC_UPDOWN_CLASS |
			ICC_USEREX_CLASSES | ICC_WIN95_CLASSES
	};
	InitCommonControlsEx(&used);
	AfxOleInit();
	AfxEnableControlContainer();
	AfxInitRichEdit5();
	CWinAppEx::InitInstance();
	SetRegistryKey(_T("TortoiseGit"));
	AfxGetApp()->m_pszProfileName = _tcsdup(_T("TortoiseProc")); // w/o this ResizableLib will store data under TortoiseGitProc which is not compatible with older versions

	CCmdLineParser parser(AfxGetApp()->m_lpCmdLine);

	hWndExplorer = NULL;
	CString sVal = parser.GetVal(_T("hwnd"));
	if (!sVal.IsEmpty())
		hWndExplorer = (HWND)_wcstoui64(sVal, nullptr, 16);

	while (GetParent(hWndExplorer)!=NULL)
		hWndExplorer = GetParent(hWndExplorer);
	if (!IsWindow(hWndExplorer))
	{
		hWndExplorer = NULL;
	}

	// if HKCU\Software\TortoiseGit\Debug is not 0, show our command line
	// in a message box
	if (CRegDWORD(_T("Software\\TortoiseGit\\Debug"), FALSE)==TRUE)
		AfxMessageBox(AfxGetApp()->m_lpCmdLine, MB_OK | MB_ICONINFORMATION);

	if (parser.HasKey(_T("urlhandler")))
	{
		CString url = parser.GetVal(_T("urlhandler"));
		if (url.Find(_T("tgit://clone/")) == 0)
		{
			url = url.Mid(13); // 21 = "tgit://clone/".GetLength()
		}
		else if (url.Find(_T("github-windows://openRepo/")) == 0)
		{
			url = url.Mid(26); // 26 = "github-windows://openRepo/".GetLength()
			int questioMark = url.Find('?');
			if (questioMark > 0)
				url = url.Left(questioMark);
		}
		else if (url.Find(_T("smartgit://cloneRepo/")) == 0)
		{
			url = url.Mid(21); // 21 = "smartgit://cloneRepo/".GetLength()
		}
		else
		{
			CMessageBox::Show(NULL, IDS_ERR_INVALIDPATH, IDS_APPNAME, MB_ICONERROR);
			return FALSE;
		}
		CString newCmd;
		newCmd.Format(_T("/command:clone /url:\"%s\" /hasurlhandler"), url);
		parser = CCmdLineParser(newCmd);
	}

	if ( parser.HasKey(_T("path")) && parser.HasKey(_T("pathfile")))
	{
		CMessageBox::Show(NULL, IDS_ERR_INVALIDPATH, IDS_APPNAME, MB_ICONERROR);
		return FALSE;
	}

	CTGitPath cmdLinePath;
	CTGitPathList pathList;
	if (g_sGroupingUUID.IsEmpty())
		g_sGroupingUUID = parser.GetVal(L"groupuuid");
	if ( parser.HasKey(_T("pathfile")) )
	{

		CString sPathfileArgument = CPathUtils::GetLongPathname(parser.GetVal(_T("pathfile")));

		cmdLinePath.SetFromUnknown(sPathfileArgument);
		if (pathList.LoadFromFile(cmdLinePath)==false)
			return FALSE;		// no path specified!
		if ( parser.HasKey(_T("deletepathfile")) )
		{
			// We can delete the temporary path file, now that we've loaded it
			::DeleteFile(cmdLinePath.GetWinPath());
		}
		// This was a path to a temporary file - it's got no meaning now, and
		// anybody who uses it again is in for a problem...
		cmdLinePath.Reset();

	}
	else
	{

		CString sPathArgument = CPathUtils::GetLongPathname(parser.GetVal(_T("path")));
		if (parser.HasKey(_T("expaths")))
		{
			// an /expaths param means we're started via the buttons in our Win7 library
			// and that means the value of /expaths is the current directory, and
			// the selected paths are then added as additional parameters but without a key, only a value

			// because of the "strange treatment of quotation marks and backslashes by CommandLineToArgvW"
			// we have to escape the backslashes first. Since we're only dealing with paths here, that's
			// a save bet.
			// Without this, a command line like:
			// /command:commit /expaths:"D:\" "D:\Utils"
			// would fail because the "D:\" is treated as the backslash being the escape char for the quotation
			// mark and we'd end up with:
			// argv[1] = /command:commit
			// argv[2] = /expaths:D:" D:\Utils
			// See here for more details: http://blogs.msdn.com/b/oldnewthing/archive/2010/09/17/10063629.aspx
			CString cmdLine = GetCommandLineW();
			cmdLine.Replace(L"\\", L"\\\\");
			int nArgs = 0;
			LPWSTR *szArglist = CommandLineToArgvW(cmdLine, &nArgs);
			if (szArglist)
			{
				// argument 0 is the process path, so start with 1
				for (int i = 1; i < nArgs; ++i)
				{
					if (szArglist[i][0] != '/')
					{
						if (!sPathArgument.IsEmpty())
							sPathArgument += '*';
						sPathArgument += szArglist[i];
					}
				}
				sPathArgument.Replace(L"\\\\", L"\\");
			}
			LocalFree(szArglist);
		}
		if (sPathArgument.IsEmpty() && parser.HasKey(L"path"))
		{
			CMessageBox::Show(hWndExplorer, IDS_ERR_INVALIDPATH, IDS_APPNAME, MB_ICONERROR);
			return FALSE;
		}
		int asterisk = sPathArgument.Find('*');
		cmdLinePath.SetFromUnknown(asterisk >= 0 ? sPathArgument.Left(asterisk) : sPathArgument);
		pathList.LoadFromAsteriskSeparatedString(sPathArgument);
	}

	if (pathList.IsEmpty()) {
		pathList.AddPath(CTGitPath::CTGitPath(g_Git.m_CurrentDir));
	}

	// Set CWD to temporary dir, and restore it later
	{
		DWORD len = GetCurrentDirectory(0, NULL);
		if (len)
		{
			std::unique_ptr<TCHAR[]> originalCurrentDirectory(new TCHAR[len]);
			if (GetCurrentDirectory(len, originalCurrentDirectory.get()))
			{
				sOrigCWD = originalCurrentDirectory.get();
				sOrigCWD = CPathUtils::GetLongPathname(sOrigCWD);
			}
		}
		TCHAR pathbuf[MAX_PATH] = {0};
		GetTortoiseGitTempPath(MAX_PATH, pathbuf);
		SetCurrentDirectory(pathbuf);
	}

	CheckForNewerVersion();

	CAutoGeneralHandle TGitMutex = ::CreateMutex(NULL, FALSE, _T("TortoiseGitProc.exe"));
	if (!g_Git.SetCurrentDir(cmdLinePath.GetWinPathString(), parser.HasKey(_T("submodule")) == TRUE))
	{
		for (int i = 0; i < pathList.GetCount(); ++i)
			if(g_Git.SetCurrentDir(pathList[i].GetWinPath()))
				break;
	}

	if(!g_Git.m_CurrentDir.IsEmpty())
	{
		sOrigCWD = g_Git.m_CurrentDir;
		SetCurrentDirectory(g_Git.m_CurrentDir);
	}

	if (g_sGroupingUUID.IsEmpty())
	{
		CRegStdDWORD groupSetting = CRegStdDWORD(_T("Software\\TortoiseGit\\GroupTaskbarIconsPerRepo"), 3);
		switch (DWORD(groupSetting))
		{
		case 1:
		case 2:
			// implemented differently to TortoiseSVN atm
			break;
		case 3:
		case 4:
			{
				CString wcroot;
				if (g_GitAdminDir.HasAdminDir(g_Git.m_CurrentDir, true, &wcroot))
				{
					git_oid oid;
					CStringA wcRootA(wcroot + CPathUtils::GetAppDirectory());
					if (!git_odb_hash(&oid, wcRootA, wcRootA.GetLength(), GIT_OBJ_BLOB))
					{
						CStringA hash;
						git_oid_tostr(hash.GetBufferSetLength(GIT_OID_HEXSZ + 1), GIT_OID_HEXSZ + 1, &oid);
						hash.ReleaseBuffer();
						g_sGroupingUUID = hash;
					}
					ProjectProperties pp;
					pp.ReadProps();
					CString icon = pp.sIcon;
					icon.Replace('/', '\\');
					if (icon.IsEmpty())
						g_bGroupingRemoveIcon = true;
					g_sGroupingIcon = icon;
				}
			}
		}
	}

	CString sAppID = GetTaskIDPerUUID(g_sGroupingUUID).c_str();
	InitializeJumpList(sAppID);
	EnsureGitLibrary(false);

	{
		CString err;
		try
		{
			// requires CWD to be set
			CGit::m_LogEncode = CAppUtils::GetLogOutputEncode();

			// make sure all config files are read in order to check that none contains an error
			g_Git.GetConfigValue(_T("doesnot.exist"));
		}
		catch (char* msg)
		{
			err = CString(msg);
		}

		if (!err.IsEmpty())
		{
			UINT choice = CMessageBox::Show(hWndExplorer, err, _T("TortoiseGit"), 1, IDI_ERROR, CString(MAKEINTRESOURCE(IDS_PROC_EDITLOCALGITCONFIG)), CString(MAKEINTRESOURCE(IDS_PROC_EDITGLOBALGITCONFIG)), CString(MAKEINTRESOURCE(IDS_ABORTBUTTON)));
			if (choice == 1)
			{
				// open the config file with alternative editor
				CAppUtils::LaunchAlternativeEditor(g_Git.GetGitLocalConfig());
			}
			else if (choice == 2)
			{
				// open the global config file with alternative editor
				CAppUtils::LaunchAlternativeEditor(g_Git.GetGitGlobalConfig());
			}
			return FALSE;
		}
	}

	// execute the requested command
	CommandServer server;
	Command * cmd = server.GetCommand(parser.GetVal(_T("command")));
	if (cmd)
	{
		cmd->SetExplorerHwnd(hWndExplorer);

		cmd->SetParser(parser);
		cmd->SetPaths(pathList, cmdLinePath);

		retSuccess = cmd->Execute();
		delete cmd;
	}

	// Look for temporary files left around by TortoiseSVN and
	// remove them. But only delete 'old' files because some
	// apps might still be needing the recent ones.
	{
		DWORD len = GetTortoiseGitTempPath(0, NULL);
		std::unique_ptr<TCHAR[]> path(new TCHAR[len + 100]);
		len = GetTortoiseGitTempPath (len + 100, path.get());
		if (len != 0)
		{
			CDirFileEnum finder(path.get());
			FILETIME systime_;
			::GetSystemTimeAsFileTime(&systime_);
			__int64 systime = (((_int64)systime_.dwHighDateTime)<<32) | ((__int64)systime_.dwLowDateTime);
			bool isDir;
			CString filepath;
			while (finder.NextFile(filepath, &isDir))
			{
				HANDLE hFile = ::CreateFile(filepath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, isDir ? FILE_FLAG_BACKUP_SEMANTICS : NULL, NULL);
				if (hFile != INVALID_HANDLE_VALUE)
				{
					FILETIME createtime_;
					if (::GetFileTime(hFile, &createtime_, NULL, NULL))
					{
						::CloseHandle(hFile);
						__int64 createtime = (((_int64)createtime_.dwHighDateTime)<<32) | ((__int64)createtime_.dwLowDateTime);
						if ((createtime + 864000000000) < systime)		//only delete files older than a day
						{
							::SetFileAttributes(filepath, FILE_ATTRIBUTE_NORMAL);
							if (isDir)
								::RemoveDirectory(filepath);
							else
								::DeleteFile(filepath);
						}
					}
					else
						::CloseHandle(hFile);
				}
			}
		}
	}

	// Since the dialog has been closed, return FALSE so that we exit the
	// application, rather than start the application's message pump.
	return FALSE;
}
Esempio n. 17
0
void CWebServer::OnRequest(CWebClientSocket* pClient, CStringA& hdr, CStringA& body)
{
    CPath p(AToT(pClient->m_path));
    CStringA ext = p.GetExtension().MakeLower();
    CStringA mime;
    if (ext.IsEmpty()) {
        mime = "text/html";
    } else {
        m_mimes.Lookup(ext, mime);
    }

    hdr = "HTTP/1.0 200 OK\r\n";

    bool fHandled = false, fCGI = false;

    if (!fHandled && m_webroot.IsDirectory()) {
        CStringA tmphdr;
        fHandled = fCGI = CallCGI(pClient, tmphdr, body, mime);

        if (fHandled) {
            tmphdr.Replace("\r\n", "\n");
            CAtlList<CStringA> hdrlines;
            ExplodeMin(tmphdr, hdrlines, '\n');
            POSITION pos = hdrlines.GetHeadPosition();
            while (pos) {
                POSITION cur = pos;
                CAtlList<CStringA> sl;
                CStringA key = Explode(hdrlines.GetNext(pos), sl, ':', 2);
                if (sl.GetCount() < 2) {
                    continue;
                }
                key.Trim().MakeLower();
                if (key == "content-type") {
                    mime = sl.GetTail().Trim();
                    hdrlines.RemoveAt(cur);
                } else if (key == "content-length") {
                    hdrlines.RemoveAt(cur);
                }
            }
            tmphdr = Implode(hdrlines, "\r\n");
            hdr += tmphdr + "\r\n";
        }
    }

    RequestHandler rh = NULL;
    if (!fHandled && m_internalpages.Lookup(pClient->m_path, rh) && (pClient->*rh)(hdr, body, mime)) {
        if (mime.IsEmpty()) {
            mime = "text/html";
        }

        CString redir;
        if (pClient->m_get.Lookup("redir", redir)
                || pClient->m_post.Lookup("redir", redir)) {
            if (redir.IsEmpty()) {
                redir = '/';
            }

            hdr =
                "HTTP/1.0 302 Found\r\n"
                "Location: " + CStringA(redir) + "\r\n";
            return;
        }

        fHandled = true;
    }

    if (!fHandled && m_webroot.IsDirectory()) {
        fHandled = LoadPage(0, body, UTF8To16(pClient->m_path));
    }

    UINT resid;
    if (!fHandled && m_downloads.Lookup(pClient->m_path, resid)
            && (LoadResource(resid, body, _T("FILE")) || LoadResource(resid, body, _T("PNG")))) {
        if (mime.IsEmpty()) {
            mime = "application/octet-stream";
        }
        fHandled = true;
    }

    if (!fHandled) {
        hdr = mime == "text/html"
              ? "HTTP/1.0 301 Moved Permanently\r\n" "Location: /404.html\r\n"
              : "HTTP/1.0 404 Not Found\r\n";
        return;
    }

    if ((mime == "text/html" || mime == "text/javascript") && !fCGI) {
        if (mime == "text/html") {
            hdr +=
                "Expires: Thu, 19 Nov 1981 08:52:00 GMT\r\n"
                "Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0\r\n"
                "Pragma: no-cache\r\n";

            CStringA debug;
            if (AfxGetAppSettings().fWebServerPrintDebugInfo) {
                debug += "<br><hr>\r\n";
                debug += "<div id=\"debug\">";

                CStringA key;
                POSITION pos;

                {
                    CStringA value;

                    pos = pClient->m_hdrlines.GetStartPosition();
                    while (pos) {
                        pClient->m_hdrlines.GetNextAssoc(pos, key, value);
                        debug += "HEADER[" + key + "] = " + value + "\r\n";
                    }
                }
                debug += "cmd: " + pClient->m_cmd + "\r\n";
                debug += "path: " + pClient->m_path + "\r\n";
                debug += "ver: " + pClient->m_ver + "\r\n";

                {
                    CString value;

                    pos = pClient->m_get.GetStartPosition();
                    while (pos) {
                        pClient->m_get.GetNextAssoc(pos, key, value);
                        debug += "GET[" + HtmlSpecialChars(key) + "] = " + HtmlSpecialChars(UTF8(value)) + "\r\n";
                    }
                    pos = pClient->m_post.GetStartPosition();
                    while (pos) {
                        pClient->m_post.GetNextAssoc(pos, key, value);
                        debug += "POST[" + HtmlSpecialChars(key) + "] = " + HtmlSpecialChars(UTF8(value)) + "\r\n";
                    }
                    pos = pClient->m_cookie.GetStartPosition();
                    while (pos) {
                        pClient->m_cookie.GetNextAssoc(pos, key, value);
                        debug += "COOKIE[" + HtmlSpecialChars(key) + "] = " + HtmlSpecialChars(UTF8(value)) + "\r\n";
                    }
                    pos = pClient->m_request.GetStartPosition();
                    while (pos) {
                        pClient->m_request.GetNextAssoc(pos, key, value);
                        debug += "REQUEST[" + HtmlSpecialChars(key) + "] = " + HtmlSpecialChars(UTF8(value)) + "\r\n";
                    }
                }
                debug += "</div>";
            }
            body.Replace("[debug]", debug);
        }

        body.Replace("[browserpath]", "/browser.html");
        body.Replace("[commandpath]", "/command.html");
        body.Replace("[controlspath]", "/controls.html");
        body.Replace("[indexpath]", "/index.html");
        body.Replace("[path]", pClient->m_path);
        body.Replace("[setposcommand]", CMD_SETPOS);
        body.Replace("[setvolumecommand]", CMD_SETVOLUME);
        body.Replace("[wmcname]", "wm_command");
        // TODO: add more general tags to replace
    }

    // gzip
    if (AfxGetAppSettings().fWebServerUseCompression && !body.IsEmpty()
            && hdr.Find("Content-Encoding:") < 0 && ext != ".png" && ext != ".jpeg" && ext != ".gif")
        do {
            CStringA accept_encoding;
            pClient->m_hdrlines.Lookup("accept-encoding", accept_encoding);
            accept_encoding.MakeLower();
            CAtlList<CStringA> sl;
            ExplodeMin(accept_encoding, sl, ',');
            if (!sl.Find("gzip")) {
                break;
            }

            // Allocate deflate state
            z_stream strm;

            strm.zalloc = Z_NULL;
            strm.zfree = Z_NULL;
            strm.opaque = Z_NULL;
            int ret = deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 15 + 16, 8, Z_DEFAULT_STRATEGY);
            if (ret != Z_OK) {
                ASSERT(0);
                break;
            }

            int gzippedBuffLen = body.GetLength();
            BYTE* gzippedBuff = DEBUG_NEW BYTE[gzippedBuffLen];

            // Compress
            strm.avail_in = body.GetLength();
            strm.next_in = (Bytef*)(LPCSTR)body;

            strm.avail_out = gzippedBuffLen;
            strm.next_out = gzippedBuff;

            ret = deflate(&strm, Z_FINISH);
            if (ret != Z_STREAM_END || strm.avail_in != 0) {
                ASSERT(0);
                deflateEnd(&strm);
                delete [] gzippedBuff;
                break;
            }
            gzippedBuffLen -= strm.avail_out;
            memcpy(body.GetBufferSetLength(gzippedBuffLen), gzippedBuff, gzippedBuffLen);

            // Clean up
            deflateEnd(&strm);
            delete [] gzippedBuff;

            hdr += "Content-Encoding: gzip\r\n";
        } while (0);

    CStringA content;
    content.Format(
        "Content-Type: %s\r\n"
        "Content-Length: %d\r\n",
        mime, body.GetLength());
    hdr += content;
}
Esempio n. 18
0
HRESULT CPixelShaderCompiler::InternalCompile(
    LPCSTR pSrcData,
    SIZE_T SrcDataSize,
    LPCSTR pSourceName,
    LPCSTR pEntrypoint,
    LPCSTR pProfile,
    DWORD Flags,
    IDirect3DPixelShader9** ppPixelShader,
    CString* pDisasm,
    CString* pErrMsg)
{
    if (!m_pD3DCompile) {
        return E_FAIL;
    }

    if (pDisasm && !m_pD3DDisassemble) {
        return E_FAIL;
    }

    if (ppPixelShader && !m_pD3DDev) {
        return E_FAIL;
    }

    LPCSTR pSelProfile = pProfile;
    if (!pSelProfile || *pSelProfile == '\0') {
        D3DCAPS9 caps;
        if (m_pD3DDev && m_pD3DDev->GetDeviceCaps(&caps) == D3D_OK) {
            switch (D3DSHADER_VERSION_MAJOR(caps.PixelShaderVersion)) {
                case 2:
                    if (caps.PS20Caps.NumInstructionSlots < 512) {
                        pSelProfile = "ps_2_0";
                    } else if (caps.PS20Caps.Caps > 0) {
                        pSelProfile = "ps_2_a";
                    } else {
                        pSelProfile = "ps_2_b";
                    }
                    break;
                case 3:
                    pSelProfile = "ps_3_0";
                    break;
            }
        } else {
            ASSERT(FALSE);
        }
    }

    if (!pSelProfile || *pSelProfile == '\0') {
        return E_FAIL;
    }

    LPCSTR defProfile = "MPC_HC_SHADER_PROFILE";
    LPCSTR defProfileVal;
    if (!strcmp(pSelProfile, "ps_2_0")) {
        defProfileVal = "0";
    } else if (!strcmp(pSelProfile, "ps_2_b")) {
        defProfileVal = "1";
    } else if (!strcmp(pSelProfile, "ps_2_a") || !strcmp(pSelProfile, "ps_2_sw")) {
        defProfileVal = "2";
    } else if (!strcmp(pSelProfile, "ps_3_0") || !strcmp(pSelProfile, "ps_3_sw")) {
        defProfileVal = "3";
    } else {
        defProfileVal = "-1";
    }

    if (ppPixelShader && SUCCEEDED(m_Cache.CreatePixelShader(defProfileVal, pSrcData, SrcDataSize, ppPixelShader))) {
        return S_OK;
    }

    D3D_SHADER_MACRO macros[] = { { defProfile, defProfileVal }, { 0 } };

    CComPtr<ID3DBlob> pShaderBlob, pErrorBlob;
    HRESULT hr = m_pD3DCompile(pSrcData, SrcDataSize, pSourceName, macros, nullptr, pEntrypoint,
                               pSelProfile, Flags, 0, &pShaderBlob, &pErrorBlob);

    if (pErrMsg) {
        CStringA msg;
        if (pErrorBlob) {
            auto len = pErrorBlob->GetBufferSize();
            VERIFY(memcpy_s(msg.GetBufferSetLength((int)len), len, pErrorBlob->GetBufferPointer(), len) == 0);
            msg.ReleaseBuffer((int)len);
        }
        *pErrMsg = msg;
    }

    if (FAILED(hr)) {
        return hr;
    }

    if (ppPixelShader) {
        hr = m_pD3DDev->CreatePixelShader((DWORD*)pShaderBlob->GetBufferPointer(), ppPixelShader);
        if (FAILED(hr)) {
            return hr;
        }

        m_Cache.SavePixelShader(defProfileVal, pSrcData, SrcDataSize,
                                (void*)pShaderBlob->GetBufferPointer(), pShaderBlob->GetBufferSize());
    }

    if (pDisasm) {
        CComPtr<ID3DBlob> pDisasmBlob;
        CStringA defs;
        for (auto pMacro = macros; pMacro && pMacro->Name && pMacro->Definition; pMacro++) {
            defs.Append("// #define ");
            defs.Append(pMacro->Name);
            defs.Append(" ");
            defs.Append(pMacro->Definition);
            defs.Append("\n");
        }
        hr = m_pD3DDisassemble(pShaderBlob->GetBufferPointer(), pShaderBlob->GetBufferSize(),
                               0, defs, &pDisasmBlob);
        if (SUCCEEDED(hr)) {
            CStringA disasm;
            auto len = pDisasmBlob->GetBufferSize();
            VERIFY(memcpy_s(disasm.GetBufferSetLength((int)len), len, pDisasmBlob->GetBufferPointer(), len) == 0);
            disasm.ReleaseBuffer((int)len);
            *pDisasm = disasm;
        }
    }

    return S_OK;
}