UINT CCheckForUpdatesDlg::CheckThread()
{
	m_bThreadRunning = TRUE;

	CString temp;
	CString tempfile = CTempFiles::Instance().GetTempFilePath(true).GetWinPathString();

	bool official = false;

	CRegString checkurluser = CRegString(_T("Software\\TortoiseGit\\UpdateCheckURL"), _T(""));
	CRegString checkurlmachine = CRegString(_T("Software\\TortoiseGit\\UpdateCheckURL"), _T(""), FALSE, HKEY_LOCAL_MACHINE);
	CString sCheckURL = checkurluser;
	if (sCheckURL.IsEmpty())
	{
		sCheckURL = checkurlmachine;
		if (sCheckURL.IsEmpty())
		{
			official = true;
			bool checkPreview = false;
#if PREVIEW
			checkPreview = true;
#else
			CRegStdDWORD regCheckPreview(L"Software\\TortoiseGit\\VersionCheckPreview", FALSE);
			if (DWORD(regCheckPreview))
				checkPreview = true;
#endif
			if (checkPreview)
			{
				sCheckURL = _T("https://versioncheck.tortoisegit.org/version-preview.txt");
				SetDlgItemText(IDC_SOURCE, _T("Using preview release channel"));
			}
			else
				sCheckURL = _T("https://versioncheck.tortoisegit.org/version.txt");
		}
	}

	if (!official && sCheckURL.Find(_T("://versioncheck.tortoisegit.org/")) > 0)
		official = true;

	if (!official)
		SetDlgItemText(IDC_SOURCE, _T("Using (unofficial) release channel: ") + sCheckURL);

	CString ver;
	CAutoConfig versioncheck(true);
	CString errorText;
	DWORD ret = m_updateDownloader->DownloadFile(sCheckURL, tempfile, false);
	if (!ret && official)
	{
		CString signatureTempfile = CTempFiles::Instance().GetTempFilePath(true).GetWinPathString();
		ret = m_updateDownloader->DownloadFile(sCheckURL + SIGNATURE_FILE_ENDING, signatureTempfile, false);
		if (ret || VerifyIntegrity(tempfile, signatureTempfile, m_updateDownloader))
		{
			CString error = _T("Could not verify digital signature.");
			if (ret)
				error += _T("\r\nError: ") + GetWinINetError(ret) + _T(" (on ") + sCheckURL + SIGNATURE_FILE_ENDING + _T(")");
			SetDlgItemText(IDC_CHECKRESULT, error);
			DeleteUrlCacheEntry(sCheckURL);
			DeleteUrlCacheEntry(sCheckURL + SIGNATURE_FILE_ENDING);
			goto finish;
		}
	}
	else if (ret)
	{
		DeleteUrlCacheEntry(sCheckURL);
		if (CRegDWORD(_T("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\GlobalUserOffline"), 0))
			errorText.LoadString(IDS_OFFLINEMODE); // offline mode enabled
		else
			errorText.Format(IDS_CHECKNEWER_NETERROR_FORMAT, (LPCTSTR)(GetWinINetError(ret) + _T(" URL: ") + sCheckURL), ret);
		SetDlgItemText(IDC_CHECKRESULT, errorText);
		goto finish;
	}

	git_config_add_file_ondisk(versioncheck, CUnicodeUtils::GetUTF8(tempfile), GIT_CONFIG_LEVEL_GLOBAL, 0);

	unsigned int major, minor, micro, build;
	major = minor = micro = build = 0;
	unsigned __int64 version = 0;

	if (!versioncheck.GetString(_T("tortoisegit.version"), ver))
	{
		CString vertemp = ver;
		major = _ttoi(vertemp);
		vertemp = vertemp.Mid(vertemp.Find('.') + 1);
		minor = _ttoi(vertemp);
		vertemp = vertemp.Mid(vertemp.Find('.') + 1);
		micro = _ttoi(vertemp);
		vertemp = vertemp.Mid(vertemp.Find('.') + 1);
		build = _ttoi(vertemp);
		version = major;
		version <<= 16;
		version += minor;
		version <<= 16;
		version += micro;
		version <<= 16;
		version += build;

		if (version == 0)
		{
			temp.LoadString(IDS_CHECKNEWER_NETERROR);
			SetDlgItemText(IDC_CHECKRESULT, temp);
			goto finish;
		}

		// another versionstring for the filename can be provided
		// this is needed for preview releases
		vertemp.Empty();
		versioncheck.GetString(_T("tortoisegit.versionstring"), vertemp);
		if (!vertemp.IsEmpty())
			ver = vertemp;
	}
	else
	{
		errorText = _T("Could not parse version check file: ") + g_Git.GetLibGit2LastErr();
		SetDlgItemText(IDC_CHECKRESULT, errorText);
		DeleteUrlCacheEntry(sCheckURL);
		goto finish;
	}

	{
		BOOL bNewer = FALSE;
		if (m_bForce)
			bNewer = TRUE;
		else if (major > TGIT_VERMAJOR)
			bNewer = TRUE;
		else if ((minor > TGIT_VERMINOR) && (major == TGIT_VERMAJOR))
			bNewer = TRUE;
		else if ((micro > TGIT_VERMICRO) && (minor == TGIT_VERMINOR) && (major == TGIT_VERMAJOR))
			bNewer = TRUE;
		else if ((build > TGIT_VERBUILD) && (micro == TGIT_VERMICRO) && (minor == TGIT_VERMINOR) && (major == TGIT_VERMAJOR))
			bNewer = TRUE;

		CString versionstr;
		versionstr.Format(_T("%u.%u.%u.%u"), major, minor, micro, build);
		if (versionstr != ver)
			versionstr += _T(" (") + ver + _T(")");
		temp.Format(IDS_CHECKNEWER_CURRENTVERSION, (LPCTSTR)versionstr);
		SetDlgItemText(IDC_CURRENTVERSION, temp);

		if (bNewer)
		{
			versioncheck.GetString(_T("tortoisegit.infotext"), temp);
			if (!temp.IsEmpty())
			{
				CString tempLink;
				versioncheck.GetString(_T("tortoisegit.infotexturl"), tempLink);
				if (!tempLink.IsEmpty()) // find out the download link-URL, if any
					m_sUpdateDownloadLink = tempLink;
			}
			else
				temp.LoadString(IDS_CHECKNEWER_NEWERVERSIONAVAILABLE);
			SetDlgItemText(IDC_CHECKRESULT, temp);

			FillChangelog(versioncheck, official);
			FillDownloads(versioncheck, ver);

			// Show download controls
			RECT rectWindow, rectProgress, rectGroupDownloads, rectOKButton;
			GetWindowRect(&rectWindow);
			m_progress.GetWindowRect(&rectProgress);
			GetDlgItem(IDC_GROUP_DOWNLOADS)->GetWindowRect(&rectGroupDownloads);
			GetDlgItem(IDOK)->GetWindowRect(&rectOKButton);
			LONG bottomDistance = rectWindow.bottom - rectOKButton.bottom;
			OffsetRect(&rectOKButton, 0, (rectGroupDownloads.bottom + (rectGroupDownloads.bottom - rectProgress.bottom)) - rectOKButton.top);
			rectWindow.bottom = rectOKButton.bottom + bottomDistance;
			MoveWindow(&rectWindow);
			::MapWindowPoints(nullptr, GetSafeHwnd(), (LPPOINT)&rectOKButton, 2);
			if (CRegDWORD(_T("Software\\TortoiseGit\\VersionCheck"), TRUE) != FALSE && !m_bForce && !m_bShowInfo)
			{
				GetDlgItem(IDC_DONOTASKAGAIN)->ShowWindow(SW_SHOW);
				rectOKButton.left += 60;
				temp.LoadString(IDS_REMINDMELATER);
				GetDlgItem(IDOK)->SetWindowText(temp);
				rectOKButton.right += 160;
			}
			GetDlgItem(IDOK)->MoveWindow(&rectOKButton);
			m_ctrlFiles.ShowWindow(SW_SHOW);
			GetDlgItem(IDC_GROUP_DOWNLOADS)->ShowWindow(SW_SHOW);
			CenterWindow();
			m_bShowInfo = TRUE;
		}
		else if (m_bShowInfo)
		{
			temp.LoadString(IDS_CHECKNEWER_YOURUPTODATE);
			SetDlgItemText(IDC_CHECKRESULT, temp);
			FillChangelog(versioncheck, official);
		}
	}

finish:
	if (!m_sUpdateDownloadLink.IsEmpty())
	{
		m_link.ShowWindow(SW_SHOW);
		m_link.SetURL(m_sUpdateDownloadLink);
	}
	m_bThreadRunning = FALSE;
	DialogEnableWindow(IDOK, TRUE);
	return 0;
}
UINT CCheckForUpdatesDlg::CheckThread()
{
	m_bThreadRunning = TRUE;

	CString temp;
	CString tempfile = CTempFiles::Instance().GetTempFilePath(true).GetWinPathString();

	CRegString checkurluser = CRegString(_T("Software\\TortoiseGit\\UpdateCheckURL"), _T(""));
	CRegString checkurlmachine = CRegString(_T("Software\\TortoiseGit\\UpdateCheckURL"), _T(""), FALSE, HKEY_LOCAL_MACHINE);
	CString sCheckURL = checkurluser;
	if (sCheckURL.IsEmpty())
	{
		sCheckURL = checkurlmachine;
		if (sCheckURL.IsEmpty())
		{
			bool checkPreview = false;
#if PREVIEW
			checkPreview = true;
#else
			CRegStdDWORD regCheckPreview(L"Software\\TortoiseGit\\VersionCheckPreview", FALSE);
			if (DWORD(regCheckPreview))
				checkPreview = true;
#endif
			if (checkPreview)
				sCheckURL = _T("http://version.tortoisegit.googlecode.com/git/version-preview.txt");
			else
				sCheckURL = _T("http://version.tortoisegit.googlecode.com/git/version.txt");
		}
	}
	CoInitialize(NULL);
	HRESULT res = URLDownloadToFile(NULL, sCheckURL, tempfile, 0, NULL);
	if (res == S_OK)
	{
		try
		{
			CStdioFile file(tempfile, CFile::modeRead | CFile::shareDenyWrite);
			CString ver;
			unsigned int major,minor,micro,build;
			major=minor=micro=build=0;
			unsigned __int64 version=0;

			if (file.ReadString(ver))
			{
				CString vertemp = ver;
				// another versionstring for the filename can be provided after a semicolon
				// this is needed for preview releases
				int differentFilenamePos = vertemp.Find(_T(";"));
				if (differentFilenamePos > 0)
				{
					vertemp = vertemp.Left(differentFilenamePos);
					ver = ver.Mid(differentFilenamePos + 1);
				}

				major = _ttoi(vertemp);
				vertemp = vertemp.Mid(vertemp.Find('.')+1);
				minor = _ttoi(vertemp);
				vertemp = vertemp.Mid(vertemp.Find('.')+1);
				micro = _ttoi(vertemp);
				vertemp = vertemp.Mid(vertemp.Find('.')+1);
				build = _ttoi(vertemp);
				version = major;
				version <<= 16;
				version += minor;
				version <<= 16;
				version += micro;
				version <<= 16;
				version += build;
			}

			{
				BOOL bNewer = FALSE;
				if (m_bForce)
					bNewer = TRUE;
				if (major > TGIT_VERMAJOR)
					bNewer = TRUE;
				else if ((minor > TGIT_VERMINOR)&&(major == TGIT_VERMAJOR))
					bNewer = TRUE;
				else if ((micro > TGIT_VERMICRO)&&(minor == TGIT_VERMINOR)&&(major == TGIT_VERMAJOR))
					bNewer = TRUE;
				else if ((build > TGIT_VERBUILD)&&(micro == TGIT_VERMICRO)&&(minor == TGIT_VERMINOR)&&(major == TGIT_VERMAJOR))
					bNewer = TRUE;

				if (version != 0)
				{
					CString version;
					version.Format(_T("%d.%d.%d.%d"),major,minor,micro,build);
					if (version != ver)
						version += _T(" (") + ver + _T(")");
					temp.Format(IDS_CHECKNEWER_CURRENTVERSION, (LPCTSTR)version);
					SetDlgItemText(IDC_CURRENTVERSION, temp);
				}

				if (version == 0)
				{
					temp.LoadString(IDS_CHECKNEWER_NETERROR);
					SetDlgItemText(IDC_CHECKRESULT, temp);
				}
				else if (bNewer)
				{
					if(file.ReadString(temp) && !temp.IsEmpty())
					{	// Read the next line, it could contain a message for the user
						CString tempLink;
						if(file.ReadString(tempLink) && !tempLink.IsEmpty())
						{	// Read another line to find out the download link-URL, if any
							m_sUpdateDownloadLink = tempLink;
						}
					}
					else
					{
						temp.LoadString(IDS_CHECKNEWER_NEWERVERSIONAVAILABLE);
						CString tempLink;
						file.ReadString(tempLink);
					}
					SetDlgItemText(IDC_CHECKRESULT, temp);
					m_bShowInfo = TRUE;

					FillChangelog(file);
					FillDownloads(file, ver);

					// Show download controls
					RECT rectWindow, rectProgress, rectGroupDownloads, rectOKButton;
					GetWindowRect(&rectWindow);
					m_progress.GetWindowRect(&rectProgress);
					GetDlgItem(IDC_GROUP_DOWNLOADS)->GetWindowRect(&rectGroupDownloads);
					GetDlgItem(IDOK)->GetWindowRect(&rectOKButton);
					LONG bottomDistance = rectWindow.bottom - rectOKButton.bottom;
					OffsetRect(&rectOKButton, 0, (rectGroupDownloads.bottom + (rectGroupDownloads.bottom - rectProgress.bottom)) - rectOKButton.top);
					rectWindow.bottom = rectOKButton.bottom + bottomDistance;
					MoveWindow(&rectWindow);
					::MapWindowPoints(NULL, GetSafeHwnd(), (LPPOINT)&rectOKButton, 2);
					GetDlgItem(IDOK)->MoveWindow(&rectOKButton);
					m_ctrlFiles.ShowWindow(SW_SHOW);
					GetDlgItem(IDC_GROUP_DOWNLOADS)->ShowWindow(SW_SHOW);
					CenterWindow();
				}
				else
				{
					temp.LoadString(IDS_CHECKNEWER_YOURUPTODATE);
					SetDlgItemText(IDC_CHECKRESULT, temp);
					file.ReadString(temp);
					file.ReadString(temp);
					FillChangelog(file);
				}
			}
		}
		catch (CException * e)
		{
			e->Delete();
			temp.LoadString(IDS_CHECKNEWER_NETERROR);
			SetDlgItemText(IDC_CHECKRESULT, temp);
		}
	}
	else
	{
		// Try to cache web page;

		temp.LoadString(IDS_CHECKNEWER_NETERROR);
		SetDlgItemText(IDC_CHECKRESULT, temp);
	}
	if (!m_sUpdateDownloadLink.IsEmpty())
	{
		m_link.ShowWindow(SW_SHOW);
		m_link.SetURL(m_sUpdateDownloadLink);
	}

	DeleteFile(tempfile);
	m_bThreadRunning = FALSE;
	DialogEnableWindow(IDOK, TRUE);
	return 0;
}