void CCloneDlg::OnBnClickedCloneBrowseUrl() { CBrowseFolder browseFolder; browseFolder.m_style = BIF_EDITBOX | BIF_NEWDIALOGSTYLE | BIF_RETURNFSANCESTORS | BIF_RETURNONLYFSDIRS; CString strCloneDirectory; int sel = (int)this->m_BrowseUrl.GetCurrentEntry(); this->m_regBrowseUrl = sel; if( sel == 1 ) { CString str; m_URLCombo.GetWindowText(str); str.Trim(); if (str.IsEmpty()) { CMessageBox::Show(GetSafeHwnd(), IDS_PROC_CLONE_URLDIREMPTY, IDS_APPNAME, MB_ICONERROR); return; } if (CAppUtils::ExploreTo(GetSafeHwnd(), str) && (int)ShellExecute(nullptr, _T("open"), str, nullptr, nullptr, SW_SHOW) <= 32) MessageBox(CFormatMessageWrapper(), _T("TortoiseGit"), MB_ICONERROR); return; } this->m_URLCombo.GetWindowTextW(strCloneDirectory); if (browseFolder.Show(GetSafeHwnd(), strCloneDirectory) == CBrowseFolder::OK) { this->m_URLCombo.SetWindowTextW(strCloneDirectory); } }
void CGitPropertyPage::RunCommand(const tstring& command) { tstring tortoiseProcPath = CPathUtils::GetAppDirectory(g_hmodThisDll) + _T("TortoiseGitProc.exe"); if (CCreateProcessHelper::CreateProcessDetached(tortoiseProcPath.c_str(), const_cast<TCHAR*>(command.c_str()))) { // process started - exit return; } MessageBox(NULL, CFormatMessageWrapper(), _T("TortoiseGitProc launch failed"), MB_OK | MB_ICONINFORMATION); }
CString CCheckForUpdatesDlg::GetWinINetError(DWORD err) { CString readableError = CFormatMessageWrapper(err); if (readableError.IsEmpty()) { for (const CString& module : { _T("wininet.dll"), _T("urlmon.dll") }) { LPTSTR buffer; FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE, GetModuleHandle(module), err, 0, (LPTSTR)&buffer, 0, nullptr); readableError = buffer; LocalFree(buffer); if (!readableError.IsEmpty()) break; } } return readableError.Trim(); }
void CSetBugTraqAdv::OnOK() { UpdateData(); if (m_sPath.IsEmpty() || !PathIsDirectory(m_sPath) || PathIsRelative(m_sPath)) { ShowEditBalloon(IDC_BUGTRAQPATH, (LPCTSTR)CFormatMessageWrapper(ERROR_PATH_NOT_FOUND), CString(MAKEINTRESOURCE(IDS_ERR_ERROR)), TTI_ERROR); return; } m_provider_clsid = GUID_NULL; int index = m_cProviderCombo.GetCurSel(); if (index != CB_ERR) { CBugTraqProvider *provider = (CBugTraqProvider *)m_cProviderCombo.GetItemDataPtr(index); m_provider_clsid = provider->clsid; } CComPtr<IBugTraqProvider> pProvider; HRESULT hr = pProvider.CoCreateInstance(m_provider_clsid); if (FAILED(hr)) { m_tooltips.ShowBalloon(IDC_BUGTRAQPROVIDERCOMBO, IDS_ERR_MISSING_PROVIDER, IDS_ERR_ERROR, TTI_ERROR); return; } VARIANT_BOOL valid; ATL::CComBSTR parameters(m_sParameters); hr = pProvider->ValidateParameters(GetSafeHwnd(), parameters, &valid); if (FAILED(hr)) { ShowEditBalloon(IDC_BUGTRAQPARAMETERS, IDS_ERR_PROVIDER_VALIDATE_FAILED, IDS_ERR_ERROR, TTI_ERROR); return; } if (valid != VARIANT_TRUE) return; // It's assumed that the provider will have done this. CResizableStandAloneDialog::OnOK(); }
bool CMainWindow::SaveFile(LPCTSTR filename) { FILE* fp = nullptr; _wfopen_s(&fp, filename, L"w+b"); if (!fp) { TCHAR fmt[1024] = { 0 }; LoadString(::hResource, IDS_ERRORSAVE, fmt, _countof(fmt)); TCHAR error[1024] = { 0 }; _snwprintf_s(error, _countof(error), fmt, filename, static_cast<LPCTSTR>(CFormatMessageWrapper())); MessageBox(*this, error, L"TortoiseGitUDiff", MB_OK); return false; } auto len = static_cast<int>(SendEditor(SCI_GETTEXT, 0, 0)); auto data = std::make_unique<char[]>(len + 1); SendEditor(SCI_GETTEXT, len, reinterpret_cast<LPARAM>(static_cast<char *>(data.get()))); fwrite(data.get(), sizeof(char), len-1, fp); fclose(fp); SendEditor(SCI_SETSAVEPOINT); ::ShowWindow(m_hWndEdit, SW_SHOW); return true; }
//static function, Share with SyncDialog UINT CProgressDlg::RunCmdList(CWnd* pWnd, STRING_VECTOR& cmdlist, STRING_VECTOR& dirlist, bool bShowCommand, CString* pfilename, volatile bool* bAbort, CGitGuardedByteArray* pdata, CGit* git) { UINT ret=0; std::vector<std::unique_ptr<CBlockCacheForPath>> cacheBlockList; std::vector<std::unique_ptr<CGit>> gitList; if (dirlist.empty()) cacheBlockList.push_back(std::make_unique<CBlockCacheForPath>(git->m_CurrentDir)); else { for (const auto& dir : dirlist) { auto pGit = std::make_unique<CGit>(); pGit->m_CurrentDir = dir; gitList.push_back(std::move(pGit)); cacheBlockList.push_back(std::make_unique<CBlockCacheForPath>(dir)); } } EnsurePostMessage(pWnd, MSG_PROGRESSDLG_UPDATE_UI, MSG_PROGRESSDLG_START, 0); if(pdata) pdata->clear(); for (size_t i = 0; i < cmdlist.size(); ++i) { if(cmdlist[i].IsEmpty()) continue; if (bShowCommand) { CStringA str; if (gitList.empty() || gitList.size() == 1 && gitList[0]->m_CurrentDir == git->m_CurrentDir) str = CUnicodeUtils::GetMulti(cmdlist[i].Trim() + _T("\r\n\r\n"), CP_UTF8); else str = CUnicodeUtils::GetMulti((i > 0 ? _T("\r\n") : _T("")) + gitList[i]->m_CurrentDir + _T("\r\n") + cmdlist[i].Trim() + _T("\r\n\r\n"), CP_UTF8); for (int j = 0; j < str.GetLength(); ++j) { if(pdata) { pdata->m_critSec.Lock(); pdata->push_back(str[j]); pdata->m_critSec.Unlock(); } else pWnd->PostMessage(MSG_PROGRESSDLG_UPDATE_UI,MSG_PROGRESSDLG_RUN,str[j]); } if(pdata) pWnd->PostMessage(MSG_PROGRESSDLG_UPDATE_UI,MSG_PROGRESSDLG_RUN,0); } PROCESS_INFORMATION pi; CAutoGeneralHandle hRead; int runAsyncRet = -1; if (gitList.empty()) runAsyncRet = git->RunAsync(cmdlist[i].Trim(), &pi, hRead.GetPointer(), nullptr, pfilename); else runAsyncRet = gitList[i]->RunAsync(cmdlist[i].Trim(), &pi, hRead.GetPointer(), nullptr, pfilename); if (runAsyncRet) { EnsurePostMessage(pWnd, MSG_PROGRESSDLG_UPDATE_UI, MSG_PROGRESSDLG_FAILED, -1 * runAsyncRet); return runAsyncRet; } CAutoGeneralHandle piProcess(pi.hProcess); CAutoGeneralHandle piThread(pi.hThread); DWORD readnumber; char lastByte = '\0'; char byte; CString output; while (ReadFile(hRead, &byte, 1, &readnumber, nullptr)) { if(pdata) { if(byte == 0) byte = '\n'; pdata->m_critSec.Lock(); if (byte == '\n' && lastByte != '\r') pdata->push_back('\r'); pdata->push_back( byte); lastByte = byte; pdata->m_critSec.Unlock(); if(byte == '\r' || byte == '\n') pWnd->PostMessage(MSG_PROGRESSDLG_UPDATE_UI,MSG_PROGRESSDLG_RUN,0); } else pWnd->PostMessage(MSG_PROGRESSDLG_UPDATE_UI,MSG_PROGRESSDLG_RUN,byte); } if (pdata) { pdata->m_critSec.Lock(); bool post = !pdata->empty(); pdata->m_critSec.Unlock(); if (post) EnsurePostMessage(pWnd, MSG_PROGRESSDLG_UPDATE_UI, MSG_PROGRESSDLG_RUN, 0); } CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) _T(": waiting for process to finish (%s), aborted: %d\n"), (LPCTSTR)cmdlist[i], *bAbort); WaitForSingleObject(pi.hProcess, INFINITE); DWORD status=0; if(!GetExitCodeProcess(pi.hProcess,&status) || *bAbort) { CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) _T(": process %s finished, status code could not be fetched, (error %d; %s), aborted: %d\n"), (LPCTSTR)cmdlist[i], GetLastError(), (LPCTSTR)CFormatMessageWrapper(), *bAbort); EnsurePostMessage(pWnd, MSG_PROGRESSDLG_UPDATE_UI, MSG_PROGRESSDLG_FAILED, status); return TGIT_GIT_ERROR_GET_EXIT_CODE; } CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) _T(": process %s finished with code %d\n"), (LPCTSTR)cmdlist[i], status); ret |= status; } EnsurePostMessage(pWnd, MSG_PROGRESSDLG_UPDATE_UI, MSG_PROGRESSDLG_END, ret); return ret; }
static void EnsurePostMessage(CWnd *pWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { redo: if (!pWnd->PostMessage(Msg, wParam, lParam)) { if (GetLastError() == ERROR_NOT_ENOUGH_QUOTA) { Sleep(20); goto redo; } else CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) _T(": Message %d-%d could not be sent (error %d; %s)\n"), wParam, lParam, GetLastError(), (LPCTSTR)CFormatMessageWrapper()); } }
void CFileDiffDlg::OnContextMenu(CWnd* pWnd, CPoint point) { if ((pWnd==0)||(pWnd != &m_cFileList)) return; if (m_cFileList.GetSelectedCount() == 0) return; // if the context menu is invoked through the keyboard, we have to use // a calculated position on where to anchor the menu on if ((point.x == -1) && (point.y == -1)) { CRect rect; m_cFileList.GetItemRect(m_cFileList.GetSelectionMark(), &rect, LVIR_LABEL); m_cFileList.ClientToScreen(&rect); point = rect.CenterPoint(); } CIconMenu popup; if (popup.CreatePopupMenu()) { int firstEntry = -1; POSITION firstPos = m_cFileList.GetFirstSelectedItemPosition(); if (firstPos) firstEntry = m_cFileList.GetNextSelectedItem(firstPos); CString menuText; popup.AppendMenuIcon(ID_COMPARE, IDS_LOG_POPUP_COMPARETWO, IDI_DIFF); popup.AppendMenuIcon(ID_GNUDIFFCOMPARE, IDS_LOG_POPUP_GNUDIFF, IDI_DIFF); popup.AppendMenu(MF_SEPARATOR, NULL); if (!m_bIsBare) { menuText.Format(IDS_FILEDIFF_POPREVERTTOREV, (LPCTSTR)m_rev1.m_CommitHash.ToString().Left(g_Git.GetShortHASHLength())); popup.AppendMenuIcon(ID_REVERT1, menuText, IDI_REVERT); menuText.Format(IDS_FILEDIFF_POPREVERTTOREV, (LPCTSTR)m_rev2.m_CommitHash.ToString().Left(g_Git.GetShortHASHLength())); popup.AppendMenuIcon(ID_REVERT2, menuText, IDI_REVERT); popup.AppendMenu(MF_SEPARATOR, NULL); } popup.AppendMenuIcon(ID_LOG, IDS_FILEDIFF_LOG, IDI_LOG); if (firstEntry >= 0 && !m_arFilteredList[firstEntry]->IsDirectory()) { if (!m_bIsBare) { popup.AppendMenuIcon(ID_BLAME, IDS_FILEDIFF_POPBLAME, IDI_BLAME); popup.AppendMenu(MF_SEPARATOR, NULL); } popup.AppendMenuIcon(ID_EXPORT, IDS_FILEDIFF_POPEXPORT, IDI_EXPORT); } else if (firstEntry >= 0) popup.AppendMenuIcon(ID_LOGSUBMODULE, IDS_MENULOGSUBMODULE, IDI_LOG); popup.AppendMenu(MF_SEPARATOR, NULL); popup.AppendMenuIcon(ID_SAVEAS, IDS_FILEDIFF_POPSAVELIST, IDI_SAVEAS); popup.AppendMenuIcon(ID_CLIPBOARD_PATH, IDS_STATUSLIST_CONTEXT_COPY, IDI_COPYCLIP); popup.AppendMenuIcon(ID_CLIPBOARD_ALL, IDS_STATUSLIST_CONTEXT_COPYEXT, IDI_COPYCLIP); int cmd = popup.TrackPopupMenu(TPM_RETURNCMD | TPM_LEFTALIGN | TPM_NONOTIFY, point.x, point.y, this, 0); m_bCancelled = false; switch (cmd) { case ID_COMPARE: { if (!CheckMultipleDiffs()) break; POSITION pos = m_cFileList.GetFirstSelectedItemPosition(); while (pos) { int index = m_cFileList.GetNextSelectedItem(pos); DoDiff(index, false); } } break; case ID_GNUDIFFCOMPARE: { if (!CheckMultipleDiffs()) break; POSITION pos = m_cFileList.GetFirstSelectedItemPosition(); while (pos) { CTGitPath *fd2 = m_arFilteredList[m_cFileList.GetNextSelectedItem(pos)]; CTGitPath *fd1 = fd2; if (fd2->m_Action & CTGitPath::LOGACTIONS_REPLACED) fd1 = new CTGitPath(fd2->GetGitOldPathString()); CAppUtils::StartShowUnifiedDiff(m_hWnd, *fd2, m_rev2.m_CommitHash.ToString(), *fd1, m_rev1.m_CommitHash.ToString()); if (fd1 != fd2) delete fd1; } } break; case ID_REVERT1: RevertSelectedItemToVersion(m_rev1.m_CommitHash.ToString()); break; case ID_REVERT2: RevertSelectedItemToVersion(m_rev2.m_CommitHash.ToString()); break; case ID_BLAME: { if (!CheckMultipleDiffs()) break; POSITION pos = m_cFileList.GetFirstSelectedItemPosition(); while (pos) { int index = m_cFileList.GetNextSelectedItem(pos); CAppUtils::LaunchTortoiseBlame(m_arFilteredList[index]->GetWinPathString(), m_rev1.m_CommitHash.ToString()); } } break; case ID_LOG: case ID_LOGSUBMODULE: { if (!CheckMultipleDiffs()) break; POSITION pos = m_cFileList.GetFirstSelectedItemPosition(); while (pos) { int index = m_cFileList.GetNextSelectedItem(pos); CString sCmd = _T("/command:log"); if (sCmd == ID_LOGSUBMODULE) sCmd += _T(" /submodule"); sCmd += _T(" /path:\"") + m_arFilteredList[index]->GetWinPathString() + _T("\" "); sCmd += _T(" /endrev:") + m_rev1.m_CommitHash.ToString(); CAppUtils::RunTortoiseGitProc(sCmd); } } break; case ID_SAVEAS: { if (m_cFileList.GetSelectedCount() > 0) { CString temp; CTGitPath savePath; CString pathSave; if (!CAppUtils::FileOpenSave(pathSave, NULL, IDS_REPOBROWSE_SAVEAS, IDS_TEXTFILEFILTER, false, m_hWnd, _T(".txt"))) { break; } savePath = CTGitPath(pathSave); // now open the selected file for writing try { CStdioFile file(savePath.GetWinPathString(), CFile::typeBinary | CFile::modeReadWrite | CFile::modeCreate); if (m_path1.IsEmpty() && m_path2.IsEmpty()) temp.Format(IDS_FILEDIFF_CHANGEDLISTINTROROOT, (LPCTSTR)m_rev1.m_CommitHash.ToString(), (LPCTSTR)m_rev2.m_CommitHash.ToString()); else temp.Format(IDS_FILEDIFF_CHANGEDLISTINTRO, (LPCTSTR)m_path1.GetGitPathString(), (LPCTSTR)m_rev1.m_CommitHash.ToString(), (LPCTSTR)m_path2.GetGitPathString(), (LPCTSTR)m_rev2.m_CommitHash.ToString()); file.WriteString(temp + _T("\r\n")); POSITION pos = m_cFileList.GetFirstSelectedItemPosition(); while (pos) { int index = m_cFileList.GetNextSelectedItem(pos); CTGitPath* fd = m_arFilteredList[index]; file.WriteString(fd->GetGitPathString()); file.WriteString(_T("\r\n")); } file.Close(); } catch (CFileException* pE) { pE->ReportError(); } } } break; case ID_CLIPBOARD_PATH: { CopySelectionToClipboard(); } break; case ID_CLIPBOARD_ALL: { CopySelectionToClipboard(TRUE); } break; case ID_EXPORT: { // export all changed files to a folder CBrowseFolder browseFolder; browseFolder.m_style = BIF_EDITBOX | BIF_NEWDIALOGSTYLE | BIF_RETURNFSANCESTORS | BIF_RETURNONLYFSDIRS; if (browseFolder.Show(GetSafeHwnd(), m_strExportDir) == CBrowseFolder::OK) { POSITION pos = m_cFileList.GetFirstSelectedItemPosition(); while (pos) { int index = m_cFileList.GetNextSelectedItem(pos); CTGitPath* fd = m_arFilteredList[index]; // we cannot export directories or folders if (fd->m_Action == CTGitPath::LOGACTIONS_DELETED || fd->IsDirectory()) continue; CPathUtils::MakeSureDirectoryPathExists(m_strExportDir + _T("\\") + fd->GetContainingDirectory().GetWinPathString()); CString filename = m_strExportDir + _T("\\") + fd->GetWinPathString(); if(m_rev1.m_CommitHash.ToString() == GIT_REV_ZERO) { if(!CopyFile(g_Git.CombinePath(fd), filename, false)) { MessageBox(CFormatMessageWrapper(), _T("TortoiseGit"), MB_OK | MB_ICONERROR); return; } } else { if(g_Git.GetOneFile(m_rev1.m_CommitHash, *fd, filename)) { CString out; out.Format(IDS_STATUSLIST_CHECKOUTFILEFAILED, (LPCTSTR)fd->GetGitPathString(), (LPCTSTR)m_rev1.m_CommitHash.ToString(), (LPCTSTR)filename); if (CMessageBox::Show(nullptr, g_Git.GetGitLastErr(out, CGit::GIT_CMD_GETONEFILE), _T("TortoiseGit"), 2, IDI_WARNING, CString(MAKEINTRESOURCE(IDS_IGNOREBUTTON)), CString(MAKEINTRESOURCE(IDS_ABORTBUTTON))) == 2) return; } } } } } break; } } }
//static function, Share with SyncDialog UINT CProgressDlg::RunCmdList(CWnd *pWnd,std::vector<CString> &cmdlist,bool bShowCommand,CString *pfilename,bool *bAbort,CGitByteArray *pdata, CGit *git) { UINT ret=0; PROCESS_INFORMATION pi; HANDLE hRead = 0; memset(&pi,0,sizeof(PROCESS_INFORMATION)); CBlockCacheForPath cacheBlock(git->m_CurrentDir); EnsurePostMessage(pWnd, MSG_PROGRESSDLG_UPDATE_UI, MSG_PROGRESSDLG_START, 0); if(pdata) pdata->clear(); for (size_t i = 0; i < cmdlist.size(); ++i) { if(cmdlist[i].IsEmpty()) continue; if (bShowCommand) { CStringA str = CUnicodeUtils::GetMulti(cmdlist[i].Trim() + _T("\r\n\r\n"), CP_UTF8); for (int j = 0; j < str.GetLength(); ++j) { if(pdata) { pdata->m_critSec.Lock(); pdata->push_back(str[j]); pdata->m_critSec.Unlock(); } else pWnd->PostMessage(MSG_PROGRESSDLG_UPDATE_UI,MSG_PROGRESSDLG_RUN,str[j]); } if(pdata) pWnd->PostMessage(MSG_PROGRESSDLG_UPDATE_UI,MSG_PROGRESSDLG_RUN,0); } git->RunAsync(cmdlist[i].Trim(),&pi, &hRead, NULL, pfilename); DWORD readnumber; char lastByte = '\0'; char byte; CString output; while(ReadFile(hRead,&byte,1,&readnumber,NULL)) { if(pdata) { if(byte == 0) byte = '\n'; pdata->m_critSec.Lock(); if (byte == '\n' && lastByte != '\r') pdata->push_back('\r'); pdata->push_back( byte); lastByte = byte; pdata->m_critSec.Unlock(); if(byte == '\r' || byte == '\n') pWnd->PostMessage(MSG_PROGRESSDLG_UPDATE_UI,MSG_PROGRESSDLG_RUN,0); } else pWnd->PostMessage(MSG_PROGRESSDLG_UPDATE_UI,MSG_PROGRESSDLG_RUN,byte); } if (pdata) { pdata->m_critSec.Lock(); bool post = !pdata->empty(); pdata->m_critSec.Unlock(); if (post) EnsurePostMessage(pWnd, MSG_PROGRESSDLG_UPDATE_UI, MSG_PROGRESSDLG_RUN, 0); } CloseHandle(pi.hThread); CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) _T(": waiting for process to finish (%s), aborted: %d\n"), cmdlist[i], *bAbort); WaitForSingleObject(pi.hProcess, INFINITE); DWORD status=0; if(!GetExitCodeProcess(pi.hProcess,&status) || *bAbort) { CloseHandle(pi.hProcess); CloseHandle(hRead); CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) _T(": process %s finished, status code could not be fetched, (error %d; %s), aborted: %d\n"), cmdlist[i], GetLastError(), (CString)CFormatMessageWrapper(), *bAbort); EnsurePostMessage(pWnd, MSG_PROGRESSDLG_UPDATE_UI, MSG_PROGRESSDLG_FAILED, status); return TGIT_GIT_ERROR_GET_EXIT_CODE; } CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) _T(": process %s finished with code %d\n"), cmdlist[i], status); ret |= status; } CloseHandle(pi.hProcess); CloseHandle(hRead); EnsurePostMessage(pWnd, MSG_PROGRESSDLG_UPDATE_UI, MSG_PROGRESSDLG_END, ret); return ret; }
bool CCommonAppUtils::LaunchApplication(const CString& sCommandLine, UINT idErrMessageFormat, bool bWaitForStartup, CString *cwd, bool uac) { CString theCWD = sOrigCWD; if (cwd != NULL) theCWD = *cwd; if (uac) { CString file, param; SHELLEXECUTEINFO shellinfo; memset(&shellinfo, 0, sizeof(shellinfo)); shellinfo.cbSize = sizeof(shellinfo); shellinfo.hwnd = NULL; shellinfo.lpVerb = _T("runas"); shellinfo.nShow = SW_SHOWNORMAL; shellinfo.fMask = SEE_MASK_NOCLOSEPROCESS; shellinfo.lpDirectory = theCWD; int pos = sCommandLine.Find('"'); if (pos == 0) { pos = sCommandLine.Find('"', 2); if (pos > 1) { file = sCommandLine.Mid(1, pos - 1); param = sCommandLine.Mid(pos + 1); } else { if (idErrMessageFormat != 0) { CString temp; temp.Format(idErrMessageFormat, CFormatMessageWrapper()); MessageBox(NULL, temp, _T("TortoiseGit"), MB_OK | MB_ICONINFORMATION); } return false; } } else { pos = sCommandLine.Find(' ', 1); if (pos > 0) { file = sCommandLine.Mid(0, pos); param = sCommandLine.Mid(pos + 1); } else file = sCommandLine; } shellinfo.lpFile = file; shellinfo.lpParameters = param; if (!ShellExecuteEx(&shellinfo)) { if (idErrMessageFormat != 0) { CString temp; temp.Format(idErrMessageFormat, (CString)CFormatMessageWrapper()); MessageBox(NULL, temp, _T("TortoiseGit"), MB_OK | MB_ICONINFORMATION); } return false; } if (bWaitForStartup) { WaitForInputIdle(shellinfo.hProcess, 10000); } CloseHandle(shellinfo.hProcess); } else { STARTUPINFO startup; PROCESS_INFORMATION process; memset(&startup, 0, sizeof(startup)); startup.cb = sizeof(startup); memset(&process, 0, sizeof(process)); CString cleanCommandLine(sCommandLine); if (CreateProcess(NULL, const_cast<TCHAR*>((LPCTSTR)cleanCommandLine), NULL, NULL, FALSE, 0, 0, theCWD, &startup, &process)==0) { if(idErrMessageFormat != 0) { CString temp; temp.Format(idErrMessageFormat, (CString)CFormatMessageWrapper()); MessageBox(NULL, temp, _T("TortoiseGit"), MB_OK | MB_ICONINFORMATION); } return false; } AllowSetForegroundWindow(process.dwProcessId); if (bWaitForStartup) { WaitForInputIdle(process.hProcess, 10000); } CloseHandle(process.hThread); CloseHandle(process.hProcess); } return true; }
DWORD CHooks::RunScript(CString cmd, LPCTSTR currentDir, CString& error, bool bWait, bool bShow) { DWORD exitcode = 0; SECURITY_ATTRIBUTES sa; SecureZeroMemory(&sa, sizeof(sa)); sa.nLength = sizeof(sa); sa.bInheritHandle = TRUE; CAutoFile hOut ; CAutoFile hRedir; CAutoFile hErr; // clear the error string error.Empty(); // Create Temp File for redirection TCHAR szTempPath[MAX_PATH]; TCHAR szOutput[MAX_PATH]; TCHAR szErr[MAX_PATH]; GetTempPath(_countof(szTempPath), szTempPath); GetTempFileName(szTempPath, _T("git"), 0, szErr); // setup redirection handles // output handle must be WRITE mode, share READ // redirect handle must be READ mode, share WRITE hErr = CreateFile(szErr, GENERIC_WRITE, FILE_SHARE_READ, &sa, CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY, 0); if (!hErr) return (DWORD)-1; hRedir = CreateFile(szErr, GENERIC_READ, FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); if (!hRedir) return (DWORD)-1; GetTempFileName(szTempPath, _T("git"), 0, szOutput); hOut = CreateFile(szOutput, GENERIC_WRITE, FILE_SHARE_READ, &sa, CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY, 0); if (!hOut) return (DWORD)-1; // setup startup info, set std out/err handles // hide window STARTUPINFO si; SecureZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); if (hOut != INVALID_HANDLE_VALUE) { si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; si.hStdOutput = hOut; si.hStdError = hErr; si.wShowWindow = bShow ? SW_SHOW : SW_HIDE; } PROCESS_INFORMATION pi; SecureZeroMemory(&pi, sizeof(pi)); DWORD dwFlags = 0; if (!CreateProcess(NULL, cmd.GetBuffer(), NULL, NULL, TRUE, dwFlags, NULL, currentDir, &si, &pi)) { int err = GetLastError(); // preserve the CreateProcess error error = CFormatMessageWrapper(err); SetLastError(err); cmd.ReleaseBuffer(); return (DWORD)-1; } cmd.ReleaseBuffer(); CloseHandle(pi.hThread); // wait for process to finish, capture redirection and // send it to the parent window/console if (bWait) { DWORD dw; char buf[256]; do { SecureZeroMemory(&buf,sizeof(buf)); while (ReadFile(hRedir, &buf, sizeof(buf)-1, &dw, NULL)) { if (dw == 0) break; error += CString(CStringA(buf,dw)); SecureZeroMemory(&buf,sizeof(buf)); } } while (WaitForSingleObject(pi.hProcess, 0) != WAIT_OBJECT_0); // perform any final flushing while (ReadFile(hRedir, &buf, sizeof(buf)-1, &dw, NULL)) { if (dw == 0) break; error += CString(CStringA(buf, dw)); SecureZeroMemory(&buf,sizeof(buf)); } WaitForSingleObject(pi.hProcess, INFINITE); GetExitCodeProcess(pi.hProcess, &exitcode); } CloseHandle(pi.hProcess); DeleteFile(szOutput); DeleteFile(szErr); return exitcode; }
void CFileTextLines::SetErrorString() { m_sErrorString = CFormatMessageWrapper(); }
void DropCopyAddCommand::ShowErrorMessage() { CString strMessage; strMessage.Format(IDS_ERR_COPYFILES, CFormatMessageWrapper()); MessageBox(hwndExplorer, strMessage, _T("TortoiseGit"), MB_OK | MB_ICONINFORMATION); }
bool CatCommand::Execute() { if (!GitAdminDir::IsWorkingTreeOrBareRepo(g_Git.m_CurrentDir)) { CMessageBox::Show(GetExplorerHWND(), IDS_NOGITREPO, IDS_APPNAME, MB_ICONERROR); return false; } CString savepath = CPathUtils::GetLongPathname(parser.GetVal(L"savepath")); CString revision = parser.GetVal(L"revision"); if (g_Git.UsingLibGit2(CGit::GIT_CMD_GETONEFILE)) { CAutoRepository repo(g_Git.GetGitRepository()); if (!repo) { ::DeleteFile(savepath); MessageBox(GetExplorerHWND(), g_Git.GetLibGit2LastErr(L"Could not open repository."), L"TortoiseGit", MB_ICONERROR); return false; } CAutoObject obj; if (git_revparse_single(obj.GetPointer(), repo, CUnicodeUtils::GetUTF8(revision))) { ::DeleteFile(savepath); MessageBox(GetExplorerHWND(), g_Git.GetLibGit2LastErr(L"Could not parse revision."), L"TortoiseGit", MB_ICONERROR); return false; } if (git_object_type(obj) == GIT_OBJECT_BLOB) { CAutoFILE file = _wfsopen(savepath, L"wb", SH_DENYRW); if (file == nullptr) { ::DeleteFile(savepath); MessageBox(GetExplorerHWND(), L"Could not open file for writing.", L"TortoiseGit", MB_ICONERROR); return false; } CAutoBuf buf; if (git_blob_filtered_content(buf, reinterpret_cast<git_blob*>(static_cast<git_object*>(obj)), CUnicodeUtils::GetUTF8(cmdLinePath.GetGitPathString()), 0)) { ::DeleteFile(savepath); MessageBox(GetExplorerHWND(), g_Git.GetLibGit2LastErr(L"Could not get filtered content."), L"TortoiseGit", MB_ICONERROR); return false; } if (fwrite(buf->ptr, sizeof(char), buf->size, file) != buf->size) { ::DeleteFile(savepath); CString err = CFormatMessageWrapper(); CMessageBox::Show(GetExplorerHWND(), L"Could not write to file: " + err, L"TortoiseGit", MB_ICONERROR); return false; } return true; } if (g_Git.GetOneFile(revision, cmdLinePath, savepath)) { MessageBox(GetExplorerHWND(), g_Git.GetGitLastErr(L"Could get file.", CGit::GIT_CMD_GETONEFILE), L"TortoiseGit", MB_ICONERROR); return false; } return true; } CString cmd, output, err; cmd.Format(L"git.exe cat-file -t %s", static_cast<LPCTSTR>(revision)); if (g_Git.Run(cmd, &output, &err, CP_UTF8)) { ::DeleteFile(savepath); MessageBox(GetExplorerHWND(), output + L'\n' + err, L"TortoiseGit", MB_ICONERROR); return false; } if (CStringUtils::StartsWith(output, L"blob")) cmd.Format(L"git.exe cat-file -p %s", static_cast<LPCTSTR>(revision)); else cmd.Format(L"git.exe show %s -- \"%s\"", static_cast<LPCTSTR>(revision), static_cast<LPCTSTR>(this->cmdLinePath.GetWinPathString())); if (g_Git.RunLogFile(cmd, savepath, &err)) { ::DeleteFile(savepath); MessageBox(GetExplorerHWND(), L"Cat file failed:\n" + err, L"TortoiseGit", MB_ICONERROR); return false; } return true; }
void CFileDiffDlg::OnContextMenu(CWnd* pWnd, CPoint point) { if ((pWnd==0)||(pWnd != &m_cFileList)) return; if (m_cFileList.GetSelectedCount() == 0) return; // if the context menu is invoked through the keyboard, we have to use // a calculated position on where to anchor the menu on if ((point.x == -1) && (point.y == -1)) { CRect rect; m_cFileList.GetItemRect(m_cFileList.GetSelectionMark(), &rect, LVIR_LABEL); m_cFileList.ClientToScreen(&rect); point = rect.CenterPoint(); } CIconMenu popup; if (popup.CreatePopupMenu()) { popup.AppendMenuIcon(ID_COMPARE, IDS_LOG_POPUP_COMPARETWO, IDI_DIFF); popup.AppendMenuIcon(ID_BLAME, IDS_FILEDIFF_POPBLAME, IDI_BLAME); popup.AppendMenuIcon(ID_LOG, IDS_FILEDIFF_LOG, IDI_LOG); popup.AppendMenu(MF_SEPARATOR, NULL); popup.AppendMenuIcon(ID_EXPORT, IDS_FILEDIFF_POPEXPORT, IDI_EXPORT); popup.AppendMenu(MF_SEPARATOR, NULL); popup.AppendMenuIcon(ID_SAVEAS, IDS_FILEDIFF_POPSAVELIST, IDI_SAVEAS); popup.AppendMenuIcon(ID_CLIPBOARD_PATH, IDS_STATUSLIST_CONTEXT_COPY, IDI_COPYCLIP); popup.AppendMenuIcon(ID_CLIPBOARD_ALL, IDS_STATUSLIST_CONTEXT_COPYEXT, IDI_COPYCLIP); int cmd = popup.TrackPopupMenu(TPM_RETURNCMD | TPM_LEFTALIGN | TPM_NONOTIFY, point.x, point.y, this, 0); m_bCancelled = false; switch (cmd) { case ID_COMPARE: { POSITION pos = m_cFileList.GetFirstSelectedItemPosition(); while (pos) { int index = m_cFileList.GetNextSelectedItem(pos); DoDiff(index, false); } } break; case ID_BLAME: { POSITION pos = m_cFileList.GetFirstSelectedItemPosition(); while (pos) { int index = m_cFileList.GetNextSelectedItem(pos); CAppUtils::LaunchTortoiseBlame(m_arFilteredList[index]->GetWinPathString(), m_rev1.m_CommitHash.ToString()); } } break; case ID_LOG: { POSITION pos = m_cFileList.GetFirstSelectedItemPosition(); while (pos) { int index = m_cFileList.GetNextSelectedItem(pos); CString cmd = _T("/command:log"); cmd += _T(" /path:\"")+m_arFilteredList[index]->GetWinPathString()+_T("\" "); cmd += _T(" /endrev:")+m_rev1.m_CommitHash.ToString(); CAppUtils::RunTortoiseProc(cmd); } } break; case ID_SAVEAS: { if (m_cFileList.GetSelectedCount() > 0) { CString temp; CTGitPath savePath; CString pathSave; if (!CAppUtils::FileOpenSave(pathSave, NULL, IDS_REPOBROWSE_SAVEAS, IDS_COMMONFILEFILTER, false, m_hWnd)) { break; } savePath = CTGitPath(pathSave); // now open the selected file for writing try { CStdioFile file(savePath.GetWinPathString(), CFile::typeBinary | CFile::modeReadWrite | CFile::modeCreate); // temp.Format(IDS_FILEDIFF_CHANGEDLISTINTRO, (LPCTSTR)m_path1.GetGitPathString(), (LPCTSTR)m_rev1.ToString(), (LPCTSTR)m_path2.GetGitPathString(), (LPCTSTR)m_rev2.ToString()); file.WriteString(temp + _T("\n")); POSITION pos = m_cFileList.GetFirstSelectedItemPosition(); while (pos) { int index = m_cFileList.GetNextSelectedItem(pos); CTGitPath* fd = m_arFilteredList[index]; file.WriteString(fd->GetGitPathString()); file.WriteString(_T("\n")); } file.Close(); } catch (CFileException* pE) { pE->ReportError(); } } } break; case ID_CLIPBOARD_PATH: { CopySelectionToClipboard(); } break; case ID_CLIPBOARD_ALL: { CopySelectionToClipboard(TRUE); } break; case ID_EXPORT: { // export all changed files to a folder CBrowseFolder browseFolder; browseFolder.m_style = BIF_EDITBOX | BIF_NEWDIALOGSTYLE | BIF_RETURNFSANCESTORS | BIF_RETURNONLYFSDIRS; if (browseFolder.Show(GetSafeHwnd(), m_strExportDir) == CBrowseFolder::OK) { POSITION pos = m_cFileList.GetFirstSelectedItemPosition(); while (pos) { int index = m_cFileList.GetNextSelectedItem(pos); CTGitPath* fd = m_arFilteredList[index]; // we cannot export directories or folders if (fd->m_Action == CTGitPath::LOGACTIONS_DELETED || fd->IsDirectory()) continue; CAppUtils::CreateMultipleDirectory(m_strExportDir + _T("\\") + fd->GetDirectory().GetWinPathString()); CString filename = m_strExportDir + _T("\\") + fd->GetWinPathString(); if(m_rev1.m_CommitHash.ToString() == GIT_REV_ZERO) { if(!CopyFile(g_Git.m_CurrentDir + _T("\\") + fd->GetWinPath(), filename, false)) { MessageBox(CFormatMessageWrapper(), _T("TortoiseGit"), MB_OK | MB_ICONERROR); return; } } else { if(g_Git.GetOneFile(m_rev1.m_CommitHash, *fd, filename)) { CString out; out.Format(_T("Fail checkout one file %s;%s"), m_rev1.m_CommitHash.ToString(), fd->GetWinPath()); CMessageBox::Show(NULL, out, _T("TortoiseGit"), MB_OK); return; } } } } } break; } } }