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
, 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
, CFormatMessageWrapper());
120 MessageBox(NULL
, temp
, _T("TortoiseGit"), MB_OK
| MB_ICONINFORMATION
);
127 WaitForInputIdle(process
.hProcess
, 10000);
130 CloseHandle(process
.hThread
);
131 CloseHandle(process
.hProcess
);
136 bool CCommonAppUtils::RunTortoiseGitProc(const CString
& sCommandLine
, bool uac
, bool includeGroupingUUID
)
138 CString pathToExecutable
= CPathUtils::GetAppDirectory() + _T("TortoiseGitProc.exe");
140 sCmd
.Format(_T("\"%s\" %s"), (LPCTSTR
)pathToExecutable
, (LPCTSTR
)sCommandLine
);
141 if (AfxGetMainWnd()->GetSafeHwnd() && (sCommandLine
.Find(L
"/hwnd:") < 0))
144 sCmdLine
.Format(L
"%s /hwnd:%ld", (LPCTSTR
)sCommandLine
, AfxGetMainWnd()->GetSafeHwnd());
145 sCmd
.Format(_T("\"%s\" %s"), (LPCTSTR
)pathToExecutable
, (LPCTSTR
)sCmdLine
);
147 if (!g_sGroupingUUID
.IsEmpty() && includeGroupingUUID
)
149 sCmd
+= L
" /groupuuid:\"";
150 sCmd
+= g_sGroupingUUID
;
154 return LaunchApplication(sCmd
, NULL
, false, NULL
, uac
);
157 bool CCommonAppUtils::IsAdminLogin()
159 SID_IDENTIFIER_AUTHORITY ntAuthority
= SECURITY_NT_AUTHORITY
;
160 PSID administratorsGroup
;
162 if (!AllocateAndInitializeSid(&ntAuthority
, 2, SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_ADMINS
, 0, 0, 0, 0, 0, 0, &administratorsGroup
))
165 // Check whether the token is present in admin group.
166 BOOL isInAdminGroup
= FALSE
;
167 if (!CheckTokenMembership(NULL
, administratorsGroup
, &isInAdminGroup
))
168 isInAdminGroup
= FALSE
;
170 // Free SID and return.
171 FreeSid(administratorsGroup
);
172 return !!isInAdminGroup
;
175 bool CCommonAppUtils::SetListCtrlBackgroundImage(HWND hListCtrl
, UINT nID
, int width
/* = 128 */, int height
/* = 128 */)
177 if ((((DWORD
)CRegStdDWORD(_T("Software\\TortoiseGit\\ShowListBackgroundImage"), TRUE
)) == FALSE
))
179 ListView_SetTextBkColor(hListCtrl
, CLR_NONE
);
180 COLORREF bkColor
= ListView_GetBkColor(hListCtrl
);
181 // create a bitmap from the icon
182 HICON hIcon
= (HICON
)LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(nID
), IMAGE_ICON
, width
, height
, LR_DEFAULTCOLOR
);
188 rect
.bottom
= height
;
191 HWND desktop
= ::GetDesktopWindow();
194 HDC screen_dev
= ::GetDC(desktop
);
197 // Create a compatible DC
198 HDC dst_hdc
= ::CreateCompatibleDC(screen_dev
);
201 // Create a new bitmap of icon size
202 bmp
= ::CreateCompatibleBitmap(screen_dev
, rect
.right
, rect
.bottom
);
205 // Select it into the compatible DC
206 HBITMAP old_dst_bmp
= (HBITMAP
)::SelectObject(dst_hdc
, bmp
);
207 // Fill the background of the compatible DC with the given color
208 ::SetBkColor(dst_hdc
, bkColor
);
209 ::ExtTextOut(dst_hdc
, 0, 0, ETO_OPAQUE
, &rect
, NULL
, 0, NULL
);
211 // Draw the icon into the compatible DC
212 ::DrawIconEx(dst_hdc
, 0, 0, hIcon
, rect
.right
, rect
.bottom
, 0, NULL
, DI_NORMAL
);
213 ::SelectObject(dst_hdc
, old_dst_bmp
);
218 ::ReleaseDC(desktop
, screen_dev
);
228 lv
.ulFlags
= LVBKIF_TYPE_WATERMARK
;
230 lv
.xOffsetPercent
= 100;
231 lv
.yOffsetPercent
= 100;
232 ListView_SetBkImage(hListCtrl
, &lv
);
236 bool CCommonAppUtils::FileOpenSave(CString
& path
, int * filterindex
, UINT title
, UINT filter
, bool bOpen
, HWND hwndOwner
)
238 OPENFILENAME ofn
= {0}; // common dialog box structure
239 TCHAR szFile
[MAX_PATH
] = {0}; // buffer for file name. Explorer can't handle paths longer than MAX_PATH.
240 ofn
.lStructSize
= sizeof(OPENFILENAME
);
241 ofn
.hwndOwner
= hwndOwner
;
242 if (path
.GetLength() >= MAX_PATH
)
247 int index
= dir
.ReverseFind(_T('\\'));
250 dir
= dir
.Left(index
);
251 if (PathFileExists(dir
))
254 GetShortPathName(dir
, szFile
, MAX_PATH
);
255 CString remain
= path
.Right(path
.GetLength() - dir
.GetLength());
256 _tcscat_s(szFile
, MAX_PATH
, remain
);
259 _tcscpy_s(szFile
, MAX_PATH
, (LPCTSTR
)path
);
260 ofn
.lpstrFile
= szFile
;
261 ofn
.nMaxFile
= _countof(szFile
);
263 CSelectFileFilter fileFilter
;
266 fileFilter
.Load(filter
);
267 ofn
.lpstrFilter
= fileFilter
;
269 ofn
.nFilterIndex
= 1;
271 ofn
.lpstrFileTitle
= NULL
;
272 ofn
.nMaxFileTitle
= 0;
273 ofn
.lpstrInitialDir
= NULL
;
277 temp
.LoadString(title
);
278 CStringUtils::RemoveAccelerators(temp
);
280 ofn
.lpstrTitle
= temp
;
282 ofn
.Flags
= OFN_PATHMUSTEXIST
| OFN_FILEMUSTEXIST
| OFN_HIDEREADONLY
| OFN_EXPLORER
;
284 ofn
.Flags
= OFN_OVERWRITEPROMPT
| OFN_EXPLORER
;
287 // Display the Open dialog box.
291 bRet
= !!GetOpenFileName(&ofn
);
295 bRet
= !!GetSaveFileName(&ofn
);
297 SetCurrentDirectory(sOrigCWD
.GetBuffer());
298 sOrigCWD
.ReleaseBuffer();
301 path
= CString(ofn
.lpstrFile
);
303 *filterindex
= ofn
.nFilterIndex
;
309 void CCommonAppUtils::SetCharFormat(CWnd
* window
, DWORD mask
, DWORD effects
, const std::vector
<CHARRANGE
>& positions
)
312 SecureZeroMemory(&format
, sizeof(CHARFORMAT2
));
313 format
.cbSize
= sizeof(CHARFORMAT2
);
314 format
.dwMask
= mask
;
315 format
.dwEffects
= effects
;
316 format
.crTextColor
= effects
;
318 for (std::vector
<CHARRANGE
>::const_iterator iter
= positions
.begin(), end
= positions
.end(); iter
!= end
; ++iter
)
320 CHARRANGE range
= *iter
;
321 window
->SendMessage(EM_EXSETSEL
, NULL
, (LPARAM
)&range
);
322 window
->SendMessage(EM_SETCHARFORMAT
, SCF_SELECTION
, (LPARAM
)&format
);
326 void CCommonAppUtils::SetCharFormat(CWnd
* window
, DWORD mask
, DWORD effects
)
329 SecureZeroMemory(&format
, sizeof(CHARFORMAT2
));
330 format
.cbSize
= sizeof(CHARFORMAT2
);
331 format
.dwMask
= mask
;
332 format
.dwEffects
= effects
;
333 window
->SendMessage(EM_SETCHARFORMAT
, SCF_SELECTION
, (LPARAM
)&format
);