1
// TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2008-2013 - TortoiseGit
4 // Copyright (C) 2003-2008,2010 - TortoiseSVN
6 // This program is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU General Public License
8 // as published by the Free Software Foundation; either version 2
9 // of the License, or (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software Foundation,
18 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 #include "..\Resources\LoglistCommonResource.h"
22 #include "CommonAppUtils.h"
23 #include "PathUtils.h"
24 #include "StringUtils.h"
25 #include "CreateProcessHelper.h"
26 #include "FormatMessageWrapper.h"
28 #include "SelectFileFilter.h"
30 extern CString sOrigCWD
;
31 extern CString g_sGroupingUUID
;
33 bool CCommonAppUtils::LaunchApplication(const CString
& sCommandLine
, UINT idErrMessageFormat
, bool bWaitForStartup
, CString
*cwd
, bool uac
)
35 CString theCWD
= sOrigCWD
;
42 SHELLEXECUTEINFO shellinfo
;
43 memset(&shellinfo
, 0, sizeof(shellinfo
));
44 shellinfo
.cbSize
= sizeof(shellinfo
);
45 shellinfo
.hwnd
= NULL
;
46 shellinfo
.lpVerb
= _T("runas");
47 shellinfo
.nShow
= SW_SHOWNORMAL
;
48 shellinfo
.fMask
= SEE_MASK_NOCLOSEPROCESS
;
49 shellinfo
.lpDirectory
= theCWD
;
51 int pos
= sCommandLine
.Find('"');
54 pos
= sCommandLine
.Find('"', 2);
57 file
= sCommandLine
.Mid(1, pos
- 1);
58 param
= sCommandLine
.Mid(pos
+ 1);
62 if (idErrMessageFormat
!= 0)
65 temp
.Format(idErrMessageFormat
, CFormatMessageWrapper());
66 MessageBox(NULL
, temp
, _T("TortoiseGit"), MB_OK
| MB_ICONINFORMATION
);
73 pos
= sCommandLine
.Find(' ', 1);
76 file
= sCommandLine
.Mid(0, pos
);
77 param
= sCommandLine
.Mid(pos
+ 1);
83 shellinfo
.lpFile
= file
;
84 shellinfo
.lpParameters
= param
;
86 if (!ShellExecuteEx(&shellinfo
))
88 if (idErrMessageFormat
!= 0)
91 temp
.Format(idErrMessageFormat
, (CString
)CFormatMessageWrapper());
92 MessageBox(NULL
, temp
, _T("TortoiseGit"), MB_OK
| MB_ICONINFORMATION
);
99 WaitForInputIdle(shellinfo
.hProcess
, 10000);
102 CloseHandle(shellinfo
.hProcess
);
107 PROCESS_INFORMATION process
;
108 memset(&startup
, 0, sizeof(startup
));
109 startup
.cb
= sizeof(startup
);
110 memset(&process
, 0, sizeof(process
));
112 CString
cleanCommandLine(sCommandLine
);
114 if (CreateProcess(NULL
, const_cast<TCHAR
*>((LPCTSTR
)cleanCommandLine
), NULL
, NULL
, FALSE
, 0, 0, theCWD
, &startup
, &process
)==0)
116 if(idErrMessageFormat
!= 0)
119 temp
.Format(idErrMessageFormat
, (CString
)CFormatMessageWrapper());
120 MessageBox(NULL
, temp
, _T("TortoiseGit"), MB_OK
| MB_ICONINFORMATION
);
125 AllowSetForegroundWindow(process
.dwProcessId
);
129 WaitForInputIdle(process
.hProcess
, 10000);
132 CloseHandle(process
.hThread
);
133 CloseHandle(process
.hProcess
);
138 bool CCommonAppUtils::RunTortoiseGitProc(const CString
& sCommandLine
, bool uac
, bool includeGroupingUUID
)
140 CString pathToExecutable
= CPathUtils::GetAppDirectory() + _T("TortoiseGitProc.exe");
142 sCmd
.Format(_T("\"%s\" %s"), (LPCTSTR
)pathToExecutable
, (LPCTSTR
)sCommandLine
);
143 if (AfxGetMainWnd()->GetSafeHwnd() && (sCommandLine
.Find(L
"/hwnd:") < 0))
146 sCmdLine
.Format(L
"%s /hwnd:%p", (LPCTSTR
)sCommandLine
, (void*)AfxGetMainWnd()->GetSafeHwnd());
147 sCmd
.Format(_T("\"%s\" %s"), (LPCTSTR
)pathToExecutable
, (LPCTSTR
)sCmdLine
);
149 if (!g_sGroupingUUID
.IsEmpty() && includeGroupingUUID
)
151 sCmd
+= L
" /groupuuid:\"";
152 sCmd
+= g_sGroupingUUID
;
156 return LaunchApplication(sCmd
, NULL
, false, NULL
, uac
);
159 bool CCommonAppUtils::IsAdminLogin()
161 SID_IDENTIFIER_AUTHORITY ntAuthority
= SECURITY_NT_AUTHORITY
;
162 PSID administratorsGroup
;
164 if (!AllocateAndInitializeSid(&ntAuthority
, 2, SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_ADMINS
, 0, 0, 0, 0, 0, 0, &administratorsGroup
))
167 // Check whether the token is present in admin group.
168 BOOL isInAdminGroup
= FALSE
;
169 if (!CheckTokenMembership(NULL
, administratorsGroup
, &isInAdminGroup
))
170 isInAdminGroup
= FALSE
;
172 // Free SID and return.
173 FreeSid(administratorsGroup
);
174 return !!isInAdminGroup
;
177 bool CCommonAppUtils::SetListCtrlBackgroundImage(HWND hListCtrl
, UINT nID
, int width
/* = 128 */, int height
/* = 128 */)
179 if ((((DWORD
)CRegStdDWORD(_T("Software\\TortoiseGit\\ShowListBackgroundImage"), TRUE
)) == FALSE
))
181 ListView_SetTextBkColor(hListCtrl
, CLR_NONE
);
182 COLORREF bkColor
= ListView_GetBkColor(hListCtrl
);
183 // create a bitmap from the icon
184 HICON hIcon
= (HICON
)LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(nID
), IMAGE_ICON
, width
, height
, LR_DEFAULTCOLOR
);
190 rect
.bottom
= height
;
193 HWND desktop
= ::GetDesktopWindow();
196 HDC screen_dev
= ::GetDC(desktop
);
199 // Create a compatible DC
200 HDC dst_hdc
= ::CreateCompatibleDC(screen_dev
);
203 // Create a new bitmap of icon size
204 bmp
= ::CreateCompatibleBitmap(screen_dev
, rect
.right
, rect
.bottom
);
207 // Select it into the compatible DC
208 HBITMAP old_dst_bmp
= (HBITMAP
)::SelectObject(dst_hdc
, bmp
);
209 // Fill the background of the compatible DC with the given color
210 ::SetBkColor(dst_hdc
, bkColor
);
211 ::ExtTextOut(dst_hdc
, 0, 0, ETO_OPAQUE
, &rect
, NULL
, 0, NULL
);
213 // Draw the icon into the compatible DC
214 ::DrawIconEx(dst_hdc
, 0, 0, hIcon
, rect
.right
, rect
.bottom
, 0, NULL
, DI_NORMAL
);
215 ::SelectObject(dst_hdc
, old_dst_bmp
);
219 ::ReleaseDC(desktop
, screen_dev
);
230 lv
.ulFlags
= LVBKIF_TYPE_WATERMARK
;
232 lv
.xOffsetPercent
= 100;
233 lv
.yOffsetPercent
= 100;
234 ListView_SetBkImage(hListCtrl
, &lv
);
238 bool CCommonAppUtils::FileOpenSave(CString
& path
, int * filterindex
, UINT title
, UINT filter
, bool bOpen
, HWND hwndOwner
, LPCTSTR defaultExt
)
240 OPENFILENAME ofn
= {0}; // common dialog box structure
241 TCHAR szFile
[MAX_PATH
] = {0}; // buffer for file name. Explorer can't handle paths longer than MAX_PATH.
242 ofn
.lStructSize
= sizeof(OPENFILENAME
);
243 ofn
.hwndOwner
= hwndOwner
;
244 if (path
.GetLength() >= MAX_PATH
)
249 int index
= dir
.ReverseFind(_T('\\'));
252 dir
= dir
.Left(index
);
253 if (PathFileExists(dir
))
256 GetShortPathName(dir
, szFile
, MAX_PATH
);
257 CString remain
= path
.Right(path
.GetLength() - dir
.GetLength());
258 _tcscat_s(szFile
, MAX_PATH
, remain
);
261 _tcscpy_s(szFile
, MAX_PATH
, (LPCTSTR
)path
);
262 ofn
.lpstrFile
= szFile
;
263 ofn
.nMaxFile
= _countof(szFile
);
265 CSelectFileFilter fileFilter
;
268 fileFilter
.Load(filter
);
269 ofn
.lpstrFilter
= fileFilter
;
271 ofn
.nFilterIndex
= 1;
273 ofn
.lpstrFileTitle
= NULL
;
274 ofn
.nMaxFileTitle
= 0;
275 ofn
.lpstrInitialDir
= NULL
;
276 ofn
.lpstrDefExt
= defaultExt
;
280 temp
.LoadString(title
);
281 CStringUtils::RemoveAccelerators(temp
);
283 ofn
.lpstrTitle
= temp
;
285 ofn
.Flags
= OFN_PATHMUSTEXIST
| OFN_FILEMUSTEXIST
| OFN_HIDEREADONLY
| OFN_EXPLORER
;
287 ofn
.Flags
= OFN_OVERWRITEPROMPT
| OFN_EXPLORER
;
290 // Display the Open dialog box.
294 bRet
= !!GetOpenFileName(&ofn
);
298 bRet
= !!GetSaveFileName(&ofn
);
300 SetCurrentDirectory(sOrigCWD
.GetBuffer());
301 sOrigCWD
.ReleaseBuffer();
304 path
= CString(ofn
.lpstrFile
);
306 *filterindex
= ofn
.nFilterIndex
;
312 void CCommonAppUtils::SetCharFormat(CWnd
* window
, DWORD mask
, DWORD effects
, const std::vector
<CHARRANGE
>& positions
)
315 SecureZeroMemory(&format
, sizeof(CHARFORMAT2
));
316 format
.cbSize
= sizeof(CHARFORMAT2
);
317 format
.dwMask
= mask
;
318 format
.dwEffects
= effects
;
319 format
.crTextColor
= effects
;
321 for (std::vector
<CHARRANGE
>::const_iterator iter
= positions
.begin(), end
= positions
.end(); iter
!= end
; ++iter
)
323 CHARRANGE range
= *iter
;
324 window
->SendMessage(EM_EXSETSEL
, NULL
, (LPARAM
)&range
);
325 window
->SendMessage(EM_SETCHARFORMAT
, SCF_SELECTION
, (LPARAM
)&format
);
329 void CCommonAppUtils::SetCharFormat(CWnd
* window
, DWORD mask
, DWORD effects
)
332 SecureZeroMemory(&format
, sizeof(CHARFORMAT2
));
333 format
.cbSize
= sizeof(CHARFORMAT2
);
334 format
.dwMask
= mask
;
335 format
.dwEffects
= effects
;
336 window
->SendMessage(EM_SETCHARFORMAT
, SCF_SELECTION
, (LPARAM
)&format
);