コード例 #1
0
TEST(UpdateCrypto, Binary)
{
	CAutoTempDir tempdir;
	CString testFile = tempdir.GetTempDir() + L"\\test.bin";

	unsigned char binaryFile[99] = // based on link.png
	{
		0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52,
		0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x01, 0x03, 0x00, 0x00, 0x00, 0xFE, 0xC1, 0x2C,
		0xC8, 0x00, 0x00, 0x00, 0x06, 0x50, 0x4C, 0x54, 0x45, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xA5,
		0xD9, 0x9F, 0xDD, 0x00, 0x00, 0x00, 0x18, 0x49, 0x44, 0x41, 0x54, 0x78, 0x5E, 0x63, 0xF8, 0xC0,
		0xF0, 0x87, 0xE1, 0x17, 0x83, 0x18, 0x43, 0x3E, 0x43, 0x38, 0x43, 0x39, 0x03, 0x3B, 0x00, 0x2C,
		0x98, 0x04, 0x41, 0xFA, 0xEC, 0xE7, 0x75, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE,
		0x42, 0x60, 0x82,
	};

	CAutoFile file = ::CreateFile(testFile, GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
	ASSERT_TRUE(file.IsValid());
	DWORD written = 0;
	EXPECT_TRUE(::WriteFile(file, binaryFile, sizeof(binaryFile), &written, nullptr));
	EXPECT_EQ(sizeof(binaryFile), written);
	EXPECT_TRUE(file.CloseHandle());

	CString testFileSignature = testFile + _T(".rsa.asc");
	EXPECT_TRUE(CStringUtils::WriteStringToTextFile((LPCTSTR)testFileSignature, L"-----BEGIN PGP SIGNATURE-----\nVersion: GnuPG v2\n\niQIcBAABCgAGBQJVxPvgAAoJEPfxez+d2VOerKsP/iQlt4S20LdUknT5udD8fFpT\nEFhZDPTXMRWkd8OhCLxa+t5b/ijyxFKWNz808Q7BDQcQoOQtC19NDvVmAcfqXflt\nR4Z+ugCG/lqP+3y0xBrL9m4UT9fNzQCiUY8Xpaih+6riLGnXVVpUe29BgVZppEWn\nMG9RVXpXwC+M3VQ0yQWu1F2Yy5OjdH4Ww5kpluoseZMOPhT6VaSfXeyQmg2DrBbw\nUfVV+w718noZ5znDH9MiD5y+sd4o7vqN2YFdg6FNvTjHyha39aFV8UCpPX1lH9ME\nN9v1vt5IWGCWL0zsZ6umHqibGG3Q2S3mlqktFhKJGWci+Swy4cNMpXDHIKY6e5v7\nxPIP92djyFtbjdixcSqBaYFC/Dd0KuCa1eYmyi2KxzUP29rZ+EHWoazfbeL1Y2Pu\nkSBrVFv64j0URzSMxUpJMqYXZRC5QW7vdbVwHGAPzoS+0rBBddwfSKteBQjagcHA\nkLk3sAIZNj1JaP5dcGL2K4Wxlaae0WgwI48lZSBMoL8SaInQvcKq9iL64xfpU+FU\nG0mzbidvTfZpyEU3eeSNiFi+6z4XLQ3NUFxsOr5jEPVKvgRoPljhJ4nCx034KQRQ\nHbVF9KYgMJSroKN9bNi/UFkC45Pc4wVov/XyH82XCVS30Du4hsVXsTdAiiXb3i6w\nkrWIJWYRxx76XGtQoHrR\n=PlFQ\n-----END PGP SIGNATURE-----"));
	EXPECT_EQ(0, VerifyIntegrity(testFile, testFileSignature, nullptr));

	// signature is shorter than pubkey; did not work w/o commit 941c103c00e48b0ffe592ab4d87d40ff48f899f6
	EXPECT_TRUE(CStringUtils::WriteStringToTextFile((LPCTSTR)testFileSignature, L"-----BEGIN PGP SIGNATURE-----\nVersion: GnuPG v2\n\niQIbBAABCgAGBQJVxQQOAAoJEPfxez+d2VOe7GoP+KflvYJVpNXSwnteXyDc1zTo\nJAyAJFtW6mgqCLrN6KoMrncEvd0cHrD07hT5mxULkbP6zy9fGaFYF0gHO0mOqErF\nIIbDcpPTWooJWUHMbnuQjf2I0x70Cr8ikycZQ7uDg7scZx7E8EIwHOJX60dcfdVX\nK1SQ+c+VIvo1uxL1PndloACaeINz6rL0Pj504lVDJaaGBvzdAV6KEIcjjm+Jb4r0\n6CYEntmt1i3Mc8FM6Xp1QfGtJqp4ogjv6o89hvtaBBLihB54EVQn66/2qIjdhX8W\nkdqJE6+pmFTfuD02XNECwl6stDIZcxXCw6EE87/1hdHip8oW9enIVTxKWB3fUWHl\n236eE2qb8zAN/WWGx/2Cvi6ctyosy9Cc/1hopnmV0KgZFfmDJWw0lISlC/3ZYWEe\nQFiXs5FPzLwfKnkq4REpoOKKfbZNk329J2iLFnwrF0mlL4vUZ1m26BBBk6lhm41J\nnjOSFWhJG/AqBbR5DqdJfXMqnxpfVZfaE5cry2rhjI4mfzw0xzrgvL4M9FZ7R9F8\njVHAV11CMqtp/7gMHXu6ljkTEBBQ7cgbU5DEAwfWddaJF+R30jmNSVliN2JW2FAk\nIbE8yV+uPiyXebn49CmRzkOWOAZqx+DShqriXGam37qjhdys147wPMMiwk8lZKjP\n4V66gTFw45UvBpophyg=\n=0bmW\n-----END PGP SIGNATURE-----"));
	EXPECT_EQ(0, VerifyIntegrity(testFile, testFileSignature, nullptr));
}
コード例 #2
0
TEST(UpdateCrypto, BinarySignature)
{
	CAutoTempDir tempdir;
	CString testFile = tempdir.GetTempDir() + L"\\test.txt";

	EXPECT_TRUE(CStringUtils::WriteStringToTextFile((LPCTSTR)testFile, L"Text with\r\nNewline"));

	unsigned char binarySignature[543] =
	{
		0x89, 0x02, 0x1C, 0x04, 0x00, 0x01, 0x0A, 0x00, 0x06, 0x05, 0x02, 0x55, 0xC5, 0x03, 0x29, 0x00,
		0x0A, 0x09, 0x10, 0xF7, 0xF1, 0x7B, 0x3F, 0x9D, 0xD9, 0x53, 0x9E, 0x1E, 0xDF, 0x0F, 0xFF, 0x6C,
		0xE9, 0x7B, 0xE0, 0xD6, 0x97, 0x1A, 0xC0, 0x07, 0x77, 0x1C, 0xAB, 0x63, 0x67, 0x9A, 0x75, 0x34,
		0xF7, 0x17, 0x84, 0xE2, 0x52, 0xD8, 0x79, 0x4E, 0x35, 0x60, 0xF6, 0x2D, 0x30, 0x1D, 0xF1, 0x09,
		0x55, 0x56, 0x4D, 0x00, 0x2E, 0xBF, 0x2C, 0x1A, 0xCA, 0xDE, 0xEF, 0xA2, 0x86, 0xF5, 0xE1, 0x07,
		0x7B, 0x48, 0xB5, 0x42, 0x73, 0x59, 0x7D, 0xE0, 0xC9, 0x57, 0x86, 0x06, 0x12, 0xAE, 0xF0, 0xC4,
		0xF1, 0x73, 0x9B, 0x23, 0xB8, 0xF8, 0x67, 0x99, 0xB0, 0xB3, 0xCA, 0x0F, 0xF9, 0x1F, 0xD1, 0x5D,
		0xD3, 0xFD, 0x44, 0x5C, 0x30, 0x17, 0x4D, 0x84, 0x3A, 0x4E, 0x7B, 0x01, 0xB4, 0x07, 0x37, 0x70,
		0x0F, 0x5D, 0xE1, 0x8C, 0x1A, 0x6B, 0xAE, 0x7D, 0x5E, 0x58, 0x6F, 0x16, 0xE8, 0xBD, 0x3D, 0xC1,
		0x83, 0x89, 0x52, 0x56, 0x57, 0x5E, 0x3A, 0xA6, 0xD1, 0x5E, 0xC6, 0xB0, 0x3F, 0x8D, 0xDC, 0xA8,
		0xAF, 0x32, 0xC4, 0x30, 0x33, 0x9A, 0x5F, 0x5F, 0xF9, 0xAA, 0xFE, 0xCE, 0xBA, 0x4C, 0x86, 0xFD,
		0xC1, 0x46, 0x85, 0x0B, 0x0B, 0x5F, 0xF3, 0x78, 0x55, 0x74, 0x85, 0x13, 0x0D, 0xA0, 0x4B, 0xEF,
		0x36, 0x37, 0xB0, 0xC8, 0x8B, 0x16, 0x10, 0x2D, 0x97, 0xBD, 0x9E, 0x83, 0x14, 0x70, 0x76, 0xD5,
		0x3C, 0xC1, 0x70, 0x35, 0xEF, 0xD1, 0x0D, 0xDA, 0x0B, 0xEA, 0x2B, 0x3F, 0x31, 0x24, 0x26, 0xF8,
		0x6E, 0x2F, 0x43, 0x4B, 0xDD, 0xC2, 0x2F, 0x7B, 0x98, 0x3B, 0x1B, 0x6B, 0x3B, 0x12, 0x6D, 0x94,
		0xC2, 0x04, 0x41, 0x16, 0xF0, 0xB7, 0xE1, 0xBD, 0x2B, 0x35, 0x3F, 0x0D, 0x3A, 0x8B, 0x2D, 0xE0,
		0x1A, 0x07, 0x3E, 0x51, 0xB6, 0xD7, 0x06, 0x27, 0x2E, 0x71, 0x8F, 0x88, 0x0A, 0xC0, 0xF9, 0xE4,
		0x0D, 0x71, 0x86, 0x9F, 0x80, 0xCB, 0x72, 0xC4, 0x8F, 0x2E, 0x4E, 0x7B, 0x83, 0x35, 0xBA, 0xAD,
		0x73, 0xAB, 0x8A, 0x69, 0xEE, 0xCE, 0xA7, 0x34, 0x69, 0x88, 0xF7, 0x39, 0x13, 0xE9, 0x67, 0xE5,
		0x4E, 0x74, 0x16, 0xAB, 0xA4, 0x84, 0xD4, 0x7A, 0x19, 0x5A, 0x71, 0x72, 0xC9, 0xCD, 0x52, 0xFA,
		0xE8, 0x16, 0x33, 0xAF, 0x0B, 0x78, 0xC8, 0xA9, 0x05, 0x57, 0xD1, 0x6A, 0x0D, 0x46, 0x36, 0x46,
		0x45, 0x4A, 0xC4, 0x64, 0x81, 0xC8, 0x0E, 0x8A, 0xDC, 0xF3, 0x75, 0xD2, 0x5D, 0x60, 0x86, 0xE9,
		0x23, 0x02, 0xFA, 0x9C, 0xF5, 0x95, 0xEE, 0x80, 0x47, 0x7F, 0xD1, 0xEE, 0xCC, 0xCF, 0x2D, 0x62,
		0x3E, 0x8A, 0x29, 0xEE, 0x8E, 0x43, 0x5F, 0x74, 0xED, 0xB1, 0x8D, 0xC7, 0x41, 0x5A, 0x51, 0xC8,
		0xE6, 0xCE, 0xCE, 0x03, 0x77, 0x86, 0x60, 0xEA, 0x73, 0xFC, 0x6D, 0x62, 0x62, 0xAF, 0x6C, 0x2A,
		0x1F, 0x84, 0xC4, 0x10, 0x61, 0x78, 0x51, 0x38, 0x8B, 0x4F, 0xE3, 0xDA, 0x39, 0xB6, 0x32, 0x58,
		0x84, 0x0C, 0xE7, 0xCD, 0xDF, 0xB1, 0x6D, 0x72, 0xFD, 0xF6, 0x22, 0x50, 0xB0, 0x7F, 0x35, 0x56,
		0xF0, 0x9B, 0x47, 0xF1, 0x45, 0x13, 0x06, 0xE5, 0x71, 0x15, 0xE9, 0xB2, 0x5E, 0x78, 0xE0, 0x70,
		0xAB, 0x98, 0xBF, 0xF3, 0x15, 0x6A, 0x3D, 0x3E, 0xDF, 0x2D, 0x23, 0xBF, 0x16, 0x96, 0x0D, 0xF3,
		0x4F, 0xD4, 0x48, 0x66, 0x2E, 0x52, 0xB0, 0x48, 0x2E, 0x37, 0x7A, 0xCA, 0xFA, 0x89, 0x3B, 0x21,
		0xAA, 0xD1, 0x96, 0x1C, 0x2E, 0x28, 0x7A, 0xEF, 0xCB, 0x09, 0x62, 0xF4, 0xC5, 0x3E, 0x81, 0x87,
		0xBB, 0x9B, 0x48, 0xAB, 0x1E, 0xD5, 0xAE, 0x3B, 0x20, 0x1A, 0xD1, 0x51, 0x9D, 0xE0, 0x6E, 0x6E,
		0xCC, 0x29, 0x24, 0x34, 0xCF, 0x07, 0xF4, 0x33, 0x42, 0x3A, 0xF2, 0x86, 0x4F, 0xFA, 0xEE, 0x5D,
		0x0A, 0x6A, 0x33, 0xE0, 0xFC, 0xBB, 0x1C, 0xA0, 0xA4, 0x76, 0xE8, 0xB1, 0x17, 0xF5, 0xE4,
	};

	CString testFileSignature = testFile + _T(".rsa.asc");
	CAutoFile file = ::CreateFile(testFileSignature, GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
	ASSERT_TRUE(file.IsValid());
	DWORD written = 0;
	EXPECT_TRUE(::WriteFile(file, binarySignature, sizeof(binarySignature), &written, nullptr));
	EXPECT_EQ(sizeof(binarySignature), written);
	EXPECT_TRUE(file.CloseHandle());

	EXPECT_EQ(0, VerifyIntegrity(testFile, testFileSignature, nullptr));

	EXPECT_TRUE(CStringUtils::WriteStringToTextFile((LPCTSTR)testFile, L"Text with\nNewline"));
	EXPECT_EQ(-1, VerifyIntegrity(testFile, testFileSignature, nullptr));
}
コード例 #3
0
bool CRemoteCacheLink::InternalEnsurePipeOpen ( CAutoFile& hPipe
											  , const CString& pipeName) const
{
	if (hPipe)
		return true;

	int tryleft = 2;

	while (!hPipe && tryleft--)
	{

		hPipe = CreateFile(
							pipeName,                       // pipe name
							GENERIC_READ |                  // read and write access
							GENERIC_WRITE,
							0,                              // no sharing
							NULL,                           // default security attributes
							OPEN_EXISTING,                  // opens existing pipe
							FILE_FLAG_OVERLAPPED,           // default attributes
							NULL);                          // no template file
		if ((!hPipe) && (GetLastError() == ERROR_PIPE_BUSY))
		{
			// TGitCache is running but is busy connecting a different client.
			// Do not give up immediately but wait for a few milliseconds until
			// the server has created the next pipe instance
			if (!WaitNamedPipe (pipeName, 50))
			{
				continue;
			}
		}
	}

	if (hPipe)
	{
		// The pipe connected; change to message-read mode.
		DWORD dwMode;

		dwMode = PIPE_READMODE_MESSAGE;
		if(!SetNamedPipeHandleState(
			hPipe,    // pipe handle
			&dwMode,  // new pipe mode
			NULL,     // don't set maximum bytes
			NULL))    // don't set maximum time
		{
			CTraceToOutputDebugString::Instance()(__FUNCTION__ ": SetNamedPipeHandleState failed");
			hPipe.CloseHandle();
		}
	}

	return hPipe;
}
コード例 #4
0
bool SyncCommand::Execute()
{
    bool bRet = false;
    CRegString rSyncPath(L"Software\\TortoiseSVN\\SyncPath");
    CTSVNPath syncPath = CTSVNPath(CString(rSyncPath));
    CTSVNPath syncFolder = syncPath;
    CRegDWORD regCount(L"Software\\TortoiseSVN\\SyncCounter");
    CRegDWORD regSyncAuth(L"Software\\TortoiseSVN\\SyncAuth");
    bool bSyncAuth = DWORD(regSyncAuth) != 0;
    if (!cmdLinePath.IsEmpty())
        syncPath = cmdLinePath;
    if (syncPath.IsEmpty() && !parser.HasKey(L"askforpath"))
    {
        return false;
    }
    syncPath.AppendPathString(L"tsvnsync.tsex");

    BOOL bWithLocals = FALSE;
    if (parser.HasKey(L"askforpath"))
    {
        // ask for the path first, then for the password
        // this is used for a manual import/export
        CString path;
        bool bGotPath = FileOpenSave(path, bWithLocals, !!parser.HasKey(L"load"), GetExplorerHWND());
        if (bGotPath)
        {
            syncPath = CTSVNPath(path);
            if (!parser.HasKey(L"load") && syncPath.GetFileExtension().IsEmpty())
                syncPath.AppendRawString(L".tsex");
        }
        else
            return false;
    }


    CSimpleIni iniFile;
    iniFile.SetMultiLine(true);
    SVNAuthData authData;

    CAutoRegKey hMainKey;
    RegOpenKeyEx(HKEY_CURRENT_USER, L"Software\\TortoiseSVN", 0, KEY_READ, hMainKey.GetPointer());
    FILETIME filetime = { 0 };
    RegQueryInfoKey(hMainKey, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &filetime);

    bool bCloudIsNewer = false;
    if (!parser.HasKey(L"save"))
    {
        // open the file in read mode
        CAutoFile hFile = CreateFile(syncPath.GetWinPathString(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
        if (hFile.IsValid())
        {
            // load the file
            LARGE_INTEGER fsize = { 0 };
            if (GetFileSizeEx(hFile, &fsize))
            {
                auto filebuf = std::make_unique<char[]>(DWORD(fsize.QuadPart));
                DWORD bytesread = 0;
                if (ReadFile(hFile, filebuf.get(), DWORD(fsize.QuadPart), &bytesread, NULL))
                {
                    // decrypt the file contents
                    std::string encrypted;
                    if (bytesread > 0)
                        encrypted = std::string(filebuf.get(), bytesread);
                    CRegString regPW(L"Software\\TortoiseSVN\\SyncPW");
                    CString password;
                    if (parser.HasKey(L"askforpath") && parser.HasKey(L"load"))
                    {
                        INT_PTR dlgret = 0;
                        bool bPasswordMatches = true;
                        do
                        {
                            bPasswordMatches = true;
                            CPasswordDlg passDlg(CWnd::FromHandle(GetExplorerHWND()));
                            passDlg.m_bForSave = !!parser.HasKey(L"save");
                            dlgret = passDlg.DoModal();
                            password = passDlg.m_sPW1;
                            if ((dlgret == IDOK) && (parser.HasKey(L"load")))
                            {
                                std::string passworda = CUnicodeUtils::StdGetUTF8((LPCWSTR)password);
                                std::string decrypted = CStringUtils::Decrypt(encrypted, passworda);
                                if ((decrypted.size() < 3) || (decrypted.substr(0, 3) != "***"))
                                {
                                    bPasswordMatches = false;
                                }
                            }
                        } while ((dlgret == IDOK) && !bPasswordMatches);
                        if (dlgret != IDOK)
                            return false;
                    }
                    else
                    {
                        auto passwordbuf = CStringUtils::Decrypt(CString(regPW));
                        if (passwordbuf.get())
                        {
                            password = passwordbuf.get();
                        }
                        else
                        {
                            // password does not match or it couldn't be read from
                            // the registry!
                            //
                            TaskDialog(GetExplorerHWND(), AfxGetResourceHandle(), MAKEINTRESOURCE(IDS_APPNAME), MAKEINTRESOURCE(IDS_ERR_ERROROCCURED), MAKEINTRESOURCE(IDS_SYNC_WRONGPASSWORD), TDCBF_OK_BUTTON, TD_ERROR_ICON, NULL);
                            CString sCmd = L" /command:settings /page:21";
                            CAppUtils::RunTortoiseProc(sCmd);
                            return false;
                        }
                    }
                    std::string passworda = CUnicodeUtils::StdGetUTF8((LPCWSTR)password);
                    std::string decrypted = CStringUtils::Decrypt(encrypted, passworda);
                    if (decrypted.size() >= 3)
                    {
                        if (decrypted.substr(0, 3) == "***")
                        {
                            decrypted = decrypted.substr(3);
                            // pass the decrypted data to the ini file
                            iniFile.LoadFile(decrypted.c_str(), decrypted.size());
                            int inicount = _wtoi(iniFile.GetValue(L"sync", L"synccounter", L""));
                            if (inicount != 0)
                            {
                                if (int(DWORD(regCount)) < inicount)
                                {
                                    bCloudIsNewer = true;
                                    regCount = inicount;
                                }
                            }

                            // load the auth data, but do not overwrite already stored auth data!
                            if (bSyncAuth)
                                authData.ImportAuthData(syncFolder.GetWinPathString(), password);
                        }
                        else
                        {
                            CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L": Error decrypting, password may be wrong\n");
                            return false;
                        }
                    }
                }
            }
        }
        else
        {
            CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L": Error opening file %s, Error %u\n", syncPath.GetWinPath(), GetLastError());
            auto lasterr = GetLastError();
            if ((lasterr != ERROR_FILE_NOT_FOUND) && (lasterr != ERROR_PATH_NOT_FOUND))
                return false;
        }
    }

    if (parser.HasKey(L"load"))
        bCloudIsNewer = true;
    if (parser.HasKey(L"save"))
        bCloudIsNewer = false;

    bool bHaveChanges = false;

    if (bWithLocals || parser.HasKey(L"local"))
    {
        // remove all blocks that are allowed for local exports
        for (const auto& allow : regBlockLocalArray)
        {
            regBlockArray.erase(std::remove(regBlockArray.begin(), regBlockArray.end(), allow), regBlockArray.end());
        }
    }
    // go through all registry values and update either the registry
    // or the ini file, depending on which is newer
    for (const auto& regname : regUseArray)
    {
        bool bChanges = HandleRegistryKey(regname, iniFile, bCloudIsNewer);
        bHaveChanges = bHaveChanges || bChanges;
    }
    if (bWithLocals || parser.HasKey(L"local"))
    {
        for (const auto& regname : regUseLocalArray)
        {
            bool bChanges = HandleRegistryKey(regname, iniFile, bCloudIsNewer);
            bHaveChanges = bHaveChanges || bChanges;
        }
    }

    if (bCloudIsNewer)
    {
        CString regpath = L"Software\\";

        CSimpleIni::TNamesDepend keys;
        iniFile.GetAllKeys(L"registry_dword", keys);
        for (const auto& k : keys)
        {
            CRegDWORD reg(regpath + k);
            reg = _wtol(iniFile.GetValue(L"registry_dword", k, L""));
        }

        keys.clear();
        iniFile.GetAllKeys(L"registry_qword", keys);
        for (const auto& k : keys)
        {
            CRegQWORD reg(regpath + k);
            reg = _wtoi64(iniFile.GetValue(L"registry_qword", k, L""));
        }

        keys.clear();
        iniFile.GetAllKeys(L"registry_string", keys);
        for (const auto& k : keys)
        {
            CRegString reg(regpath + k);
            reg = CString(iniFile.GetValue(L"registry_string", k, L""));
        }
    }
    {
        // sync project monitor settings
        CString sDataFilePath = CPathUtils::GetAppDataDirectory();
        sDataFilePath += L"\\MonitoringData.ini";
        CSimpleIni monitorIni;
        monitorIni.SetMultiLine(true);
        if (bCloudIsNewer)
        {
            CSimpleIni origMonitorIni;
            origMonitorIni.SetMultiLine(true);
            origMonitorIni.LoadFile(sDataFilePath);

            CSimpleIni::TNamesDepend keys;
            iniFile.GetAllKeys(L"ini_monitor", keys);
            for (const auto& k : keys)
            {
                CString sKey = k;
                CString sSection = sKey.Left(sKey.Find('.'));
                sKey = sKey.Mid(sKey.Find('.') + 1);
                if (sKey.CompareNoCase(L"name") == 0)
                {
                    // make sure the non-synced values are still used
                    monitorIni.SetValue(sSection, L"lastchecked", origMonitorIni.GetValue(sSection, L"lastchecked", L"0"));
                    monitorIni.SetValue(sSection, L"lastcheckedrobots", origMonitorIni.GetValue(sSection, L"lastcheckedrobots", L"0"));
                    monitorIni.SetValue(sSection, L"lastHEAD", origMonitorIni.GetValue(sSection, L"lastHEAD", L"0"));
                    monitorIni.SetValue(sSection, L"UnreadItems", origMonitorIni.GetValue(sSection, L"UnreadItems", L"0"));
                    monitorIni.SetValue(sSection, L"unreadFirst", origMonitorIni.GetValue(sSection, L"unreadFirst", L"0"));
                    monitorIni.SetValue(sSection, L"WCPathOrUrl", origMonitorIni.GetValue(sSection, L"WCPathOrUrl", L""));
                }
                CString sValue = CString(iniFile.GetValue(L"ini_monitor", k, L""));
                if ((sKey.Compare(L"username") == 0) || (sKey.Compare(L"password") == 0))
                {
                    sValue = CStringUtils::Encrypt(sValue);
                }
                monitorIni.SetValue(sSection, sKey, sValue);
            }
            FILE * pFile = NULL;
            errno_t err = 0;
            int retrycount = 5;
            CString sTempfile = CTempFiles::Instance().GetTempFilePathString();
            do
            {
                err = _tfopen_s(&pFile, sTempfile, L"wb");
                if ((err == 0) && pFile)
                {
                    monitorIni.SaveFile(pFile);
                    err = fclose(pFile);
                }
                if (err)
                {
                    CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L": Error saving %s, retrycount %d\n", (LPCWSTR)sTempfile, retrycount);
                    Sleep(500);
                }
            } while (err && retrycount--);
            if (err == 0)
            {
                if (!CopyFile(sTempfile, sDataFilePath, FALSE))
                    CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L": Error copying %s to %s, Error %u\n", (LPCWSTR)sTempfile, (LPCWSTR)sDataFilePath, GetLastError());
                else
                {
                    // now send a message to a possible running monitor to force it
                    // to reload the ini file. Otherwise it would overwrite the ini
                    // file without using the synced data!
                    HWND hWnd = FindWindow(NULL, CString(MAKEINTRESOURCE(IDS_MONITOR_DLGTITLE)));
                    if (hWnd)
                    {
                        UINT TSVN_COMMITMONITOR_RELOADINI = RegisterWindowMessage(L"TSVNCommitMonitor_ReloadIni");
                        PostMessage(hWnd, TSVN_COMMITMONITOR_RELOADINI, 0, 0);
                    }
                }
            }
        }
        else
        {
            CSimpleIni::TNamesDepend mitems;
            if (PathFileExists(sDataFilePath))
            {
                int retrycount = 5;
                SI_Error err = SI_OK;
                do
                {
                    err = monitorIni.LoadFile(sDataFilePath);
                    if (err == SI_FILE)
                    {
                        CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L": Error loading %s, retrycount %d\n", (LPCWSTR)sDataFilePath, retrycount);
                        Sleep(500);
                    }
                } while ((err == SI_FILE) && retrycount--);

                if (err == SI_FILE)
                {
                    return false;
                }
                monitorIni.GetAllSections(mitems);
            }

            for (const auto& mitem : mitems)
            {
                CString sSection = mitem;
                CString Name = monitorIni.GetValue(mitem, L"Name", L"");
                if (!Name.IsEmpty())
                {
                    CString newval = monitorIni.GetValue(mitem, L"WCPathOrUrl", L"");
                    iniFile.SetValue(L"ini_monitor", sSection + L".Name", Name);
                    CString oldval = iniFile.GetValue(L"ini_monitor", sSection + L".WCPathOrUrl", L"");
                    bHaveChanges |= ((newval != oldval) && (!oldval.IsEmpty()));
                    // only save monitored working copies if local settings are included, or
                    // if the monitored path is an url.
                    // Don't save paths to working copies for non-local stores
                    if (bWithLocals || newval.IsEmpty() || !PathIsDirectory(newval))
                        iniFile.SetValue(L"ini_monitor", sSection + L".WCPathOrUrl", newval);

                    newval = monitorIni.GetValue(mitem, L"interval", L"5");
                    oldval = iniFile.GetValue(L"ini_monitor", sSection + L".interval", L"0");
                    bHaveChanges |= newval != oldval;
                    iniFile.SetValue(L"ini_monitor", sSection + L".interval", newval);

                    newval = monitorIni.GetValue(mitem, L"minminutesinterval", L"0");
                    oldval = iniFile.GetValue(L"ini_monitor", sSection + L".minminutesinterval", L"0");
                    bHaveChanges |= newval != oldval;
                    iniFile.SetValue(L"ini_monitor", sSection + L".minminutesinterval", newval);

                    newval = CStringUtils::Decrypt(monitorIni.GetValue(mitem, L"username", L"")).get();
                    oldval = iniFile.GetValue(L"ini_monitor", sSection + L".username", L"");
                    bHaveChanges |= newval != oldval;
                    iniFile.SetValue(L"ini_monitor", sSection + L".username", newval);

                    newval = CStringUtils::Decrypt(monitorIni.GetValue(mitem, L"password", L"")).get();
                    oldval = iniFile.GetValue(L"ini_monitor", sSection + L".password", L"");
                    bHaveChanges |= newval != oldval;
                    iniFile.SetValue(L"ini_monitor", sSection + L".password", newval);

                    newval = monitorIni.GetValue(mitem, L"MsgRegex", L"");
                    oldval = iniFile.GetValue(L"ini_monitor", sSection + L".MsgRegex", L"");
                    bHaveChanges |= newval != oldval;
                    iniFile.SetValue(L"ini_monitor", sSection + L".MsgRegex", newval);

                    newval = monitorIni.GetValue(mitem, L"ignoreauthors", L"");
                    oldval = iniFile.GetValue(L"ini_monitor", sSection + L".ignoreauthors", L"");
                    bHaveChanges |= newval != oldval;
                    iniFile.SetValue(L"ini_monitor", sSection + L".ignoreauthors", newval);

                    newval = monitorIni.GetValue(mitem, L"parentTreePath", L"");
                    oldval = iniFile.GetValue(L"ini_monitor", sSection + L".parentTreePath", L"");
                    bHaveChanges |= newval != oldval;
                    iniFile.SetValue(L"ini_monitor", sSection + L".parentTreePath", newval);

                    newval = monitorIni.GetValue(mitem, L"uuid", L"");
                    oldval = iniFile.GetValue(L"ini_monitor", sSection + L".uuid", L"");
                    bHaveChanges |= newval != oldval;
                    iniFile.SetValue(L"ini_monitor", sSection + L".uuid", newval);

                    newval = monitorIni.GetValue(mitem, L"root", L"");
                    oldval = iniFile.GetValue(L"ini_monitor", sSection + L".root", L"");
                    bHaveChanges |= newval != oldval;
                    iniFile.SetValue(L"ini_monitor", sSection + L".root", newval);

                    ProjectProperties ProjProps;
                    ProjProps.LoadFromIni(monitorIni, sSection);
                    ProjProps.SaveToIni(iniFile, L"ini_monitor", sSection + L".pp_");
                }
                else if (sSection.CompareNoCase(L"global") == 0)
                {
                    CString newval = monitorIni.GetValue(mitem, L"PlaySound", L"1");
                    CString oldval = iniFile.GetValue(L"ini_monitor", sSection + L".PlaySound", L"1");
                    bHaveChanges |= newval != oldval;
                    iniFile.SetValue(L"ini_monitor", sSection + L".PlaySound", newval);

                    newval = monitorIni.GetValue(mitem, L"ShowNotifications", L"1");
                    oldval = iniFile.GetValue(L"ini_monitor", sSection + L".ShowNotifications", L"1");
                    bHaveChanges |= newval != oldval;
                    iniFile.SetValue(L"ini_monitor", sSection + L".ShowNotifications", newval);
                }
            }
        }
    }

    {
        // sync TortoiseMerge regex filters
        CSimpleIni regexIni;
        regexIni.SetMultiLine(true);
        CString sDataFilePath = CPathUtils::GetAppDataDirectory();
        sDataFilePath += L"\\regexfilters.ini";

        if (bCloudIsNewer)
        {
            CSimpleIni origRegexIni;

            if (PathFileExists(sDataFilePath))
            {
                int retrycount = 5;
                SI_Error err = SI_OK;
                do
                {
                    err = origRegexIni.LoadFile(sDataFilePath);
                    if (err == SI_FILE)
                    {
                        CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L": Error loading %s, retrycount %d\n", (LPCWSTR)sDataFilePath, retrycount);
                        Sleep(500);
                    }
                } while ((err == SI_FILE) && retrycount--);

                if (err == SI_FILE)
                {
                    return false;
                }
            }

            CSimpleIni::TNamesDepend keys;
            iniFile.GetAllKeys(L"ini_tmergeregex", keys);
            for (const auto& k : keys)
            {
                CString sKey = k;
                CString sSection = sKey.Left(sKey.Find('.'));
                sKey = sKey.Mid(sKey.Find('.') + 1);
                CString sValue = CString(iniFile.GetValue(L"ini_tmergeregex", k, L""));
                regexIni.SetValue(sSection, sKey, sValue);
            }
            FILE * pFile = NULL;
            errno_t err = 0;
            int retrycount = 5;
            CString sTempfile = CTempFiles::Instance().GetTempFilePathString();
            do
            {
                err = _tfopen_s(&pFile, sTempfile, L"wb");
                if ((err == 0) && pFile)
                {
                    regexIni.SaveFile(pFile);
                    err = fclose(pFile);
                }
                if (err)
                {
                    CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L": Error saving %s, retrycount %d\n", (LPCWSTR)sTempfile, retrycount);
                    Sleep(500);
                }
            } while (err && retrycount--);
            if (err == 0)
            {
                if (!CopyFile(sTempfile, sDataFilePath, FALSE))
                    CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L": Error copying %s to %s, Error: %u\n", (LPCWSTR)sTempfile, (LPCWSTR)sDataFilePath, GetLastError());
            }
        }
        else
        {
            if (PathFileExists(sDataFilePath))
            {
                int retrycount = 5;
                SI_Error err = SI_OK;
                do
                {
                    err = regexIni.LoadFile(sDataFilePath);
                    if (err == SI_FILE)
                    {
                        CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L": Error loading %s, retrycount %d\n", (LPCWSTR)sDataFilePath, retrycount);
                        Sleep(500);
                    }
                } while ((err == SI_FILE) && retrycount--);

                if (err == SI_FILE)
                {
                    return false;
                }
            }

            CSimpleIni::TNamesDepend mitems;
            regexIni.GetAllSections(mitems);
            for (const auto& mitem : mitems)
            {
                CString sSection = mitem;

                CString newval = regexIni.GetValue(mitem, L"regex", L"");
                CString oldval = iniFile.GetValue(L"ini_tmergeregex", sSection + L".regex", L"");
                bHaveChanges |= newval != oldval;
                iniFile.SetValue(L"ini_tmergeregex", sSection + L".regex", newval);

                newval = regexIni.GetValue(mitem, L"replace", L"5");
                oldval = iniFile.GetValue(L"ini_tmergeregex", sSection + L".replace", L"0");
                bHaveChanges |= newval != oldval;
                iniFile.SetValue(L"ini_tmergeregex", sSection + L".replace", newval);
            }
        }
    }


    if (bHaveChanges)
    {
        iniFile.SetValue(L"sync", L"version", TSVN_SYNC_VERSION_STR);
        DWORD count = regCount;
        ++count;
        regCount = count;
        CString tmp;
        tmp.Format(L"%lu", count);
        iniFile.SetValue(L"sync", L"synccounter", tmp);

        // save the ini file
        std::string iniData;
        iniFile.SaveString(iniData);
        iniData = "***" + iniData;
        // encrypt the string

        CString password;
        if (parser.HasKey(L"askforpath"))
        {
            CPasswordDlg passDlg(CWnd::FromHandle(GetExplorerHWND()));
            passDlg.m_bForSave = true;
            if (passDlg.DoModal() != IDOK)
                return false;
            password = passDlg.m_sPW1;
        }
        else
        {
            CRegString regPW(L"Software\\TortoiseSVN\\SyncPW");
            auto passwordbuf = CStringUtils::Decrypt(CString(regPW));
            if (passwordbuf.get())
            {
                password = passwordbuf.get();
            }
        }

        std::string passworda = CUnicodeUtils::StdGetUTF8((LPCWSTR)password);

        std::string encrypted = CStringUtils::Encrypt(iniData, passworda);
        CPathUtils::MakeSureDirectoryPathExists(syncPath.GetContainingDirectory().GetWinPathString());
        CString sTempfile = CTempFiles::Instance().GetTempFilePathString();
        CAutoFile hFile = CreateFile(sTempfile, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
        if (hFile.IsValid())
        {
            DWORD written = 0;
            if (WriteFile(hFile, encrypted.c_str(), DWORD(encrypted.size()), &written, NULL))
            {
                if (hFile.CloseHandle())
                {
                    if (!CopyFile(sTempfile, syncPath.GetWinPath(), FALSE))
                    {
                        CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L": Error copying %s to %s, Error: %u\n", (LPCWSTR)sTempfile, syncPath.GetWinPath(), GetLastError());
                    }
                    else
                        bRet = true;
                }
                else
                    CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L": Error closing file %s, Error: %u\n", (LPCWSTR)sTempfile, GetLastError());
            }
            else
                CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L": Error writing to file %s, Error: %u\n", (LPCWSTR)sTempfile, GetLastError());
        }
        else
            CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L": Error creating file %s for writing, Error: %u\n", (LPCWSTR)sTempfile, GetLastError());

        if (bSyncAuth)
        {
            // now save all auth data
            CPathUtils::MakeSureDirectoryPathExists(syncFolder.GetWinPathString() + L"\\auth");
            CPathUtils::MakeSureDirectoryPathExists(syncFolder.GetWinPathString() + L"\\auth\\svn.simple");
            CPathUtils::MakeSureDirectoryPathExists(syncFolder.GetWinPathString() + L"\\auth\\svn.ssl.client-passphrase");
            CPathUtils::MakeSureDirectoryPathExists(syncFolder.GetWinPathString() + L"\\auth\\svn.ssl.server");
            CPathUtils::MakeSureDirectoryPathExists(syncFolder.GetWinPathString() + L"\\auth\\svn.username");
            authData.ExportAuthData(syncFolder.GetWinPathString(), password);
        }
    }


    return bRet;
}
コード例 #5
0
ファイル: TGITCache.cpp プロジェクト: chengn/TortoiseGit
DWORD WINAPI CommandWaitThread(LPVOID lpvParam)
{
	ATLTRACE("CommandWaitThread started\n");
	bool * bRun = (bool *)lpvParam;
	// The main loop creates an instance of the named pipe and
	// then waits for a client to connect to it. When the client
	// connects, a thread is created to handle communications
	// with that client, and the loop is repeated.
	DWORD dwThreadId;
	BOOL fConnected;
	CAutoFile hPipe;

	while (*bRun)
	{
		hPipe = CreateNamedPipe(
			GetCacheCommandPipeName(),
			PIPE_ACCESS_DUPLEX,       // read/write access
			PIPE_TYPE_MESSAGE |       // message type pipe
			PIPE_READMODE_MESSAGE |   // message-read mode
			PIPE_WAIT,                // blocking mode
			PIPE_UNLIMITED_INSTANCES, // max. instances
			BUFSIZE,                  // output buffer size
			BUFSIZE,                  // input buffer size
			NMPWAIT_USE_DEFAULT_WAIT, // client time-out
			NULL);                // NULL DACL

		if (!hPipe)
		{
			//OutputDebugStringA("TSVNCache: CreatePipe failed\n");
			//DebugOutputLastError();
			if (*bRun)
				Sleep(200);
			continue; // never leave the thread!
		}

		// Wait for the client to connect; if it succeeds,
		// the function returns a nonzero value. If the function returns
		// zero, GetLastError returns ERROR_PIPE_CONNECTED.
		fConnected = ConnectNamedPipe(hPipe, NULL) ? TRUE : (GetLastError() == ERROR_PIPE_CONNECTED);
		if (fConnected)
		{
			// Create a thread for this client.
			CAutoGeneralHandle hCommandThread = CreateThread(
				NULL,              // no security attribute
				0,                 // default stack size
				CommandThread,
				(HANDLE) hPipe,    // thread parameter
				0,                 // not suspended
				&dwThreadId);      // returns thread ID

			if (!hCommandThread)
			{
				//OutputDebugStringA("TSVNCache: Could not create Command thread\n");
				//DebugOutputLastError();
				DisconnectNamedPipe(hPipe);
				hPipe.CloseHandle();
				// since we're now closing this thread, we also have to close the whole application!
				// otherwise the thread is dead, but the app is still running, refusing new instances
				// but no pipe will be available anymore.
				PostMessage(hWnd, WM_CLOSE, 0, 0);
				return 1;
			}
			// detach the handle, since we passed it to the thread
			hPipe.Detach();
		}
		else
		{
			// The client could not connect, so close the pipe.
			//OutputDebugStringA("TSVNCache: ConnectNamedPipe failed\n");
			//DebugOutputLastError();
			hPipe.CloseHandle();
			if (*bRun)
				Sleep(200);
			continue;	// don't end the thread!
		}
	}
	ATLTRACE("CommandWait thread exited\n");
	return 0;
}
コード例 #6
0
ファイル: Picture.cpp プロジェクト: 15375514460/TortoiseGit
bool CPicture::Load(tstring sFilePathName)
{
	bool bResult = false;
	bIsIcon = false;
	lpIcons = NULL;
	//CFile PictureFile;
	//CFileException e;
	FreePictureData(); // Important - Avoid Leaks...

	// No-op if no file specified
	if (sFilePathName.empty())
		return true;

	// Load & initialize the GDI+ library if available
	HMODULE hGdiPlusLib = AtlLoadSystemLibraryUsingFullPath(_T("gdiplus.dll"));
	if (hGdiPlusLib && GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL) == Ok)
	{
		bHaveGDIPlus = true;
	}
	// Since we loaded the gdiplus.dll only to check if it's available, we
	// can safely free the library here again - GdiplusStartup() loaded it too
	// and reference counting will make sure that it stays loaded until GdiplusShutdown()
	// is called.
	FreeLibrary(hGdiPlusLib);

	// Attempt to load using GDI+ if available
	if (bHaveGDIPlus)
	{
		pBitmap = new Bitmap(sFilePathName.c_str(), FALSE);
		GUID guid;
		pBitmap->GetRawFormat(&guid);

		if (pBitmap->GetLastStatus() != Ok)
		{
			delete pBitmap;
			pBitmap = NULL;
		}

		// gdiplus only loads the first icon found in an icon file
		// so we have to handle icon files ourselves :(

		// Even though gdiplus can load icons, it can't load the new
		// icons from Vista - in Vista, the icon format changed slightly.
		// But the LoadIcon/LoadImage API still can load those icons,
		// at least those dimensions which are also used on pre-Vista
		// systems.
		// For that reason, we don't rely on gdiplus telling us if
		// the image format is "icon" or not, we also check the
		// file extension for ".ico".
		std::transform(sFilePathName.begin(), sFilePathName.end(), sFilePathName.begin(), ::tolower);
		bIsIcon = (guid == ImageFormatIcon) || (wcsstr(sFilePathName.c_str(), L".ico") != NULL) || (wcsstr(sFilePathName.c_str(), L".cur") != NULL);
		bIsTiff = (guid == ImageFormatTIFF) || (_tcsstr(sFilePathName.c_str(), _T(".tiff")) != NULL);
		m_Name = sFilePathName;

		if (bIsIcon)
		{
			// Icon file, get special treatment...
			if (pBitmap)
			{
				// Cleanup first...
				delete (pBitmap);
				pBitmap = NULL;
				bIsIcon = true;
			}

			CAutoFile hFile = CreateFile(sFilePathName.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
			if (hFile)
			{
				BY_HANDLE_FILE_INFORMATION fileinfo;
				if (GetFileInformationByHandle(hFile, &fileinfo))
				{
					lpIcons = new BYTE[fileinfo.nFileSizeLow];
					DWORD readbytes;
					if (ReadFile(hFile, lpIcons, fileinfo.nFileSizeLow, &readbytes, NULL))
					{
						// we have the icon. Now gather the information we need later
						if (readbytes >= sizeof(ICONDIR))
						{
							// we are going to open same file second time so we have to close the file now
							hFile.CloseHandle();

							LPICONDIR lpIconDir = (LPICONDIR)lpIcons;
							if ((lpIconDir->idCount) && ((lpIconDir->idCount * sizeof(ICONDIR)) <= fileinfo.nFileSizeLow))
							{
								try
								{
									bResult = false;
									nCurrentIcon = 0;
									hIcons = new HICON[lpIconDir->idCount];
									// check that the pointers point to data that we just loaded
									if (((BYTE*)lpIconDir->idEntries > (BYTE*)lpIconDir) && 
										(((BYTE*)lpIconDir->idEntries) + (lpIconDir->idCount * sizeof(ICONDIRENTRY)) < ((BYTE*)lpIconDir) + fileinfo.nFileSizeLow))
									{
										m_Width = lpIconDir->idEntries[0].bWidth;
										m_Height = lpIconDir->idEntries[0].bHeight;
										bResult = true;
										for (int i=0; i<lpIconDir->idCount; ++i)
										{
											hIcons[i] = (HICON)LoadImage(NULL, sFilePathName.c_str(), IMAGE_ICON,
																		 lpIconDir->idEntries[i].bWidth,
																		 lpIconDir->idEntries[i].bHeight,
																		 LR_LOADFROMFILE);
											if (hIcons[i] == NULL)
											{
												// if the icon couldn't be loaded, the data is most likely corrupt
												delete [] lpIcons;
												lpIcons = NULL;
												bResult = false;
												break;
											}
										}
									}
								}
								catch (...)
								{
									delete [] lpIcons;
									lpIcons = NULL;
									bResult = false;
								}
							}
							else
							{
								delete [] lpIcons;
								lpIcons = NULL;
								bResult = false;
							}
						}
						else
						{
							delete [] lpIcons;
							lpIcons = NULL;
							bResult = false;
						}
					}
					else
					{
						delete [] lpIcons;
						lpIcons = NULL;
					}
				}
			}
		}
		else if (pBitmap)	// Image loaded successfully with GDI+
		{
			m_Height = pBitmap->GetHeight();
			m_Width = pBitmap->GetWidth();
			bResult = true;
		}

		// If still failed to load the file...
		if (!bResult)
		{
			// Attempt to load the FreeImage library as an optional DLL to support additional formats

			// NOTE: Currently just loading via FreeImage & using GDI+ for drawing.
			// It might be nice to remove this dependency in the future.
			HMODULE hFreeImageLib = LoadLibrary(_T("FreeImage.dll"));

			// FreeImage DLL functions
			typedef const char* (__stdcall *FreeImage_GetVersion_t)(void);
			typedef int			(__stdcall *FreeImage_GetFileType_t)(const TCHAR *filename, int size);
			typedef int			(__stdcall *FreeImage_GetFIFFromFilename_t)(const TCHAR *filename);
			typedef void*		(__stdcall *FreeImage_Load_t)(int format, const TCHAR *filename, int flags);
			typedef void		(__stdcall *FreeImage_Unload_t)(void* dib);
			typedef int			(__stdcall *FreeImage_GetColorType_t)(void* dib);
			typedef unsigned	(__stdcall *FreeImage_GetWidth_t)(void* dib);
			typedef unsigned	(__stdcall *FreeImage_GetHeight_t)(void* dib);
			typedef void		(__stdcall *FreeImage_ConvertToRawBits_t)(BYTE *bits, void *dib, int pitch, unsigned bpp, unsigned red_mask, unsigned green_mask, unsigned blue_mask, BOOL topdown);

			//FreeImage_GetVersion_t FreeImage_GetVersion = NULL;
			FreeImage_GetFileType_t FreeImage_GetFileType = NULL;
			FreeImage_GetFIFFromFilename_t FreeImage_GetFIFFromFilename = NULL;
			FreeImage_Load_t FreeImage_Load = NULL;
			FreeImage_Unload_t FreeImage_Unload = NULL;
			//FreeImage_GetColorType_t FreeImage_GetColorType = NULL;
			FreeImage_GetWidth_t FreeImage_GetWidth = NULL;
			FreeImage_GetHeight_t FreeImage_GetHeight = NULL;
			FreeImage_ConvertToRawBits_t  FreeImage_ConvertToRawBits = NULL;

			if (hFreeImageLib)
			{
				bool exportsValid = true;

				//FreeImage_GetVersion = (FreeImage_GetVersion_t)s_GetProcAddressEx(hFreeImageLib, "_FreeImage_GetVersion@0", valid);
				FreeImage_GetWidth = (FreeImage_GetWidth_t)s_GetProcAddressEx(hFreeImageLib, "_FreeImage_GetWidth@4", exportsValid);
				FreeImage_GetHeight = (FreeImage_GetHeight_t)s_GetProcAddressEx(hFreeImageLib, "_FreeImage_GetHeight@4", exportsValid);
				FreeImage_Unload = (FreeImage_Unload_t)s_GetProcAddressEx(hFreeImageLib, "_FreeImage_Unload@4", exportsValid);
				FreeImage_ConvertToRawBits = (FreeImage_ConvertToRawBits_t)s_GetProcAddressEx(hFreeImageLib, "_FreeImage_ConvertToRawBits@32", exportsValid);

#ifdef UNICODE
				FreeImage_GetFileType = (FreeImage_GetFileType_t)s_GetProcAddressEx(hFreeImageLib, "_FreeImage_GetFileTypeU@8", exportsValid);
				FreeImage_GetFIFFromFilename = (FreeImage_GetFIFFromFilename_t)s_GetProcAddressEx(hFreeImageLib, "_FreeImage_GetFIFFromFilenameU@4", exportsValid);
				FreeImage_Load = (FreeImage_Load_t)s_GetProcAddressEx(hFreeImageLib, "_FreeImage_LoadU@12", exportsValid);
#else
				FreeImage_GetFileType = (FreeImage_GetFileType_t)s_GetProcAddressEx(hFreeImageLib, "_FreeImage_GetFileType@8", exportsValid);
				FreeImage_GetFIFFromFilename = (FreeImage_GetFIFFromFilename_t)s_GetProcAddressEx(hFreeImageLib, "_FreeImage_GetFIFFromFilename@4", exportsValid);
				FreeImage_Load = (FreeImage_Load_t)s_GetProcAddressEx(hFreeImageLib, "_FreeImage_Load@12", exportsValid);
#endif

				//const char* version = FreeImage_GetVersion();

				// Check the DLL is using compatible exports
				if (exportsValid)
				{
					// Derive file type from file header.
					int fileType = FreeImage_GetFileType(sFilePathName.c_str(), 0);
					if (fileType < 0)
					{
						// No file header available, attempt to parse file name for extension.
						fileType = FreeImage_GetFIFFromFilename(sFilePathName.c_str());
					}

					// If we have a valid file type
					if (fileType >= 0)
					{
						void* dib = FreeImage_Load(fileType, sFilePathName.c_str(), 0);

						if (dib)
						{
							unsigned width = FreeImage_GetWidth(dib);
							unsigned height = FreeImage_GetHeight(dib);

							// Create a GDI+ bitmap to load into...
							pBitmap = new Bitmap(width, height, PixelFormat32bppARGB);

							if (pBitmap && pBitmap->GetLastStatus() == Ok)
							{
								// Write & convert the loaded data into the GDI+ Bitmap
								Rect rect(0, 0, width, height);
								BitmapData bitmapData;
								if (pBitmap->LockBits(&rect, ImageLockModeWrite, PixelFormat32bppARGB, &bitmapData) == Ok)
								{
									FreeImage_ConvertToRawBits((BYTE*)bitmapData.Scan0, dib, bitmapData.Stride, 32, 0xff << RED_SHIFT, 0xff << GREEN_SHIFT, 0xff << BLUE_SHIFT, FALSE);

									pBitmap->UnlockBits(&bitmapData);

									m_Width = width;
									m_Height = height;
									bResult = true;
								}
								else    // Failed to lock the destination Bitmap
								{
									delete pBitmap;
									pBitmap = NULL;
								}
							}
							else    // Bitmap allocation failed
							{
								delete pBitmap;
								pBitmap = NULL;
							}

							FreeImage_Unload(dib);
							dib = NULL;
						}
					}
				}

				FreeLibrary(hFreeImageLib);
				hFreeImageLib = NULL;
			}
		}
	}
コード例 #7
0
ファイル: FileTextLines.cpp プロジェクト: goodoid/TortoiseGit
BOOL CFileTextLines::Load(const CString& sFilePath, int lengthHint /* = 0*/)
{
	m_LineEndings = EOL_AUTOLINE;
	m_UnicodeType = CFileTextLines::AUTOTYPE;
	RemoveAll();
	m_endings.clear();
	if(lengthHint != 0)
	{
		Reserve(lengthHint);
	}

	if (PathIsDirectory(sFilePath))
	{
		m_sErrorString.Format(IDS_ERR_FILE_NOTAFILE, (LPCTSTR)sFilePath);
		return FALSE;
	}

	if (!PathFileExists(sFilePath))
	{
		//file does not exist, so just return SUCCESS
		return TRUE;
	}

	CAutoFile hFile = CreateFile(sFilePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL);
	if (!hFile)
	{
		SetErrorString();
		return FALSE;
	}

	LARGE_INTEGER fsize;
	if (!GetFileSizeEx(hFile, &fsize))
	{
		SetErrorString();
		return false;
	}
	if (fsize.HighPart)
	{
		// file is way too big for us
		m_sErrorString.LoadString(IDS_ERR_FILE_TOOBIG);
		return FALSE;
	}

	// If new[] was done for type T delete[] must be called on a pointer of type T*,
	// otherwise the behavior is undefined.
	// +1 is to address possible truncation when integer division is done
	wchar_t* pFileBuf = new wchar_t[fsize.LowPart/sizeof(wchar_t) + 1];
	DWORD dwReadBytes = 0;
	if (!ReadFile(hFile, pFileBuf, fsize.LowPart, &dwReadBytes, NULL))
	{
		delete [] pFileBuf;
		SetErrorString();
		return FALSE;
	}
	if (m_UnicodeType == CFileTextLines::AUTOTYPE)
	{
		m_UnicodeType = this->CheckUnicodeType(pFileBuf, dwReadBytes);
	}
	if (m_LineEndings == EOL_AUTOLINE)
	{
		m_LineEndings = CheckLineEndings(pFileBuf, min(10000, dwReadBytes));
	}
	hFile.CloseHandle();

	if (m_UnicodeType == CFileTextLines::BINARY)
	{
		m_sErrorString.Format(IDS_ERR_FILE_BINARY, (LPCTSTR)sFilePath);
		delete [] pFileBuf;
		return FALSE;
	}

	// we may have to convert the file content
	if ((m_UnicodeType == UTF8)||(m_UnicodeType == UTF8BOM))
	{
		int ret = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)pFileBuf, dwReadBytes, NULL, 0);
		wchar_t * pWideBuf = new wchar_t[ret];
		int ret2 = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)pFileBuf, dwReadBytes, pWideBuf, ret);
		if (ret2 == ret)
		{
			delete [] pFileBuf;
			pFileBuf = pWideBuf;
			dwReadBytes = ret2;
		} else
			delete [] pWideBuf;
	}
	else if (m_UnicodeType == ASCII)
	{
		int ret = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, (LPCSTR)pFileBuf, dwReadBytes, NULL, 0);
		wchar_t * pWideBuf = new wchar_t[ret];
		int ret2 = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, (LPCSTR)pFileBuf, dwReadBytes, pWideBuf, ret);
		if (ret2 == ret)
		{
			delete [] pFileBuf;
			pFileBuf = pWideBuf;
			dwReadBytes = ret2;
		}
		else
			delete [] pWideBuf;
	}
	// fill in the lines into the array
	wchar_t * pTextBuf = pFileBuf;
	wchar_t * pLineStart = pFileBuf;
	if (m_UnicodeType == UNICODE_LE)
	{
		// UTF16 have two bytes per char
		dwReadBytes/=2;
	}
	if ((m_UnicodeType == UTF8BOM)||(m_UnicodeType == UNICODE_LE))
	{
		// ignore the BOM
		++pTextBuf;
		++pLineStart;
		--dwReadBytes;
	}

	for (DWORD i = 0; i<dwReadBytes; ++i)
	{
		if (*pTextBuf == '\r')
		{
			if ((i + 1) < dwReadBytes)
			{
				if (*(pTextBuf+1) == '\n')
				{
					// crlf line ending
					CString line(pLineStart, (int)(pTextBuf-pLineStart));
					Add(line, EOL_CRLF);
					pLineStart = pTextBuf+2;
					++pTextBuf;
					++i;
				}
				else
				{
					// cr line ending
					CString line(pLineStart, (int)(pTextBuf-pLineStart));
					Add(line, EOL_CR);
					pLineStart =pTextBuf+1;
				}
			}
		}
		else if (*pTextBuf == '\n')
		{
			// lf line ending
			CString line(pLineStart, (int)(pTextBuf-pLineStart));
			Add(line, EOL_LF);
			pLineStart =pTextBuf+1;
		}
		++pTextBuf;
	}
	if (pLineStart < pTextBuf)
	{
		CString line(pLineStart, (int)(pTextBuf-pLineStart));
		Add(line, EOL_NOENDING);
		m_bReturnAtEnd = false;
	}
	else
		m_bReturnAtEnd = true;

	delete [] pFileBuf;

	return TRUE;
}