From a7d62ddc856e55582e5cd86070abde7d045455c3 Mon Sep 17 00:00:00 2001 From: "(no author)" <(no author)@4f64403b-2f21-0410-a795-97e2b3489a10> Date: Mon, 22 Nov 2010 01:51:38 +0000 Subject: Added ability to update in directories protected by UAC git-svn-id: https://server.scottellis.com.au/svn/mim_plugs@577 4f64403b-2f21-0410-a795-97e2b3489a10 --- updater/extern.cpp | 112 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 67 insertions(+), 45 deletions(-) (limited to 'updater/extern.cpp') diff --git a/updater/extern.cpp b/updater/extern.cpp index 48b1e94..2f599dd 100644 --- a/updater/extern.cpp +++ b/updater/extern.cpp @@ -3,7 +3,8 @@ // write data needed by the external process, and restart miranda // returns 1 if any error, 0 if shutdown is imminent -int ExternProcess(bool restart) { +int ExternProcess(bool restart) +{ //HWND hWndMiranda = (HWND)CallService(MS_CLUI_GETHWND, 0, 0); // spawn a process that will: @@ -16,13 +17,12 @@ int ExternProcess(bool restart) { NLog(msg); TCHAR data_filename[MAX_PATH]; - - _tcscpy(data_filename, options.data_folder); - _tcscat(data_filename, _T("\\ud_data.txt")); + mir_sntprintf(data_filename, SIZEOF(data_filename), _T("%s\\ud_data.txt"), options.data_folder); // write data to file for external process to use HANDLE hDatFile = CreateFile(data_filename, GENERIC_WRITE, FILE_SHARE_WRITE, 0, CREATE_ALWAYS, 0, 0); - if(hDatFile == INVALID_HANDLE_VALUE) { + if (hDatFile == INVALID_HANDLE_VALUE) + { //MessageBox(0, TranslateT("Could not create data file for restart."), TranslateT("Error"), MB_OK | MB_ICONERROR); ShowError(TranslateT("Could not create data file for restart")); return 1; @@ -56,7 +56,7 @@ int ExternProcess(bool restart) { GetModuleFileName(NULL, mir_exe, SIZEOF(mir_exe)); unsigned long bytes_written; - const TCHAR *tnl = _T("\r\n"); + static const TCHAR tnl[] = _T("\r\n"); WriteFile(hDatFile, mir_exe, (unsigned)_tcslen(mir_exe) * sizeof(TCHAR), &bytes_written, FALSE); WriteFile(hDatFile, tnl, 2 * sizeof(TCHAR), &bytes_written, FALSE); @@ -94,70 +94,86 @@ int ExternProcess(bool restart) { } */ - TCHAR szParams[MAX_PATH], szBuf[MAX_PATH], *szProcDir; + TCHAR szParams[MAX_PATH], szBuf[MAX_PATH], szProcDir[MAX_PATH]; // try to fire up external process from new dll (if present), so we can overwrite the old one -#ifdef PLUGDIR mir_sntprintf(szBuf, SIZEOF(szBuf), _T("%s\\plugins\\updater.dll"), options.temp_folder); -#else - mir_sntprintf(szBuf, SIZEOF(szBuf), _T("%s\\updater.dll"), options.temp_folder); -#endif - - HANDLE hFile = CreateFile(szBuf, 0, 0, 0, OPEN_EXISTING, 0, 0); - if(hFile == INVALID_HANDLE_VALUE) { - // try with short path name...(for win98) - TCHAR szShortBuf[MAX_PATH]; - GetShortPathName(szBuf, szShortBuf, MAX_PATH); - hFile = CreateFile(szShortBuf, 0, 0, 0, OPEN_EXISTING, 0, 0); + if (_taccess(szBuf, 0)) + { + mir_sntprintf(szBuf, SIZEOF(szBuf), _T("%s\\updater.dll"), options.temp_folder); + if (_taccess(szBuf, 0)) + { + GetModuleFileName(hInst, szBuf, MAX_PATH); + } } - if(hFile != INVALID_HANDLE_VALUE) { - // new dll exists - CloseHandle(hFile); - } else { - // can't find new updater dll - restart using this dll - GetModuleFileName(hInst, szBuf, MAX_PATH); - } + GetRootDir(szProcDir); _tcscat(szProcDir, _T("\\")); if (IsWinVerXPPlus()) { mir_sntprintf(szParams, SIZEOF(szParams), _T("RUNDLL32.EXE \"%s\",ExternalUpdate %s"), szBuf, data_filename); - szProcDir = NULL; +// szProcDir = NULL; } else { TCHAR* p = _tcsrchr(szBuf, _T('\\')); if (p) *p = 0; - szProcDir = szBuf; +// szProcDir = szBuf; // rundll32 hates spaces in the arg, but quotes aren't allowed in earlier versions... // GetShortPath can return paths with spaces (at least on XP with 8.3 filenames disabled)... // so we must 'CreateProcess' with the updater.dll location as the startup directory and pass only updater.dll as the arg - mir_sntprintf(szParams, SIZEOF(szParams), _T("RUNDLL32.EXE .\\updater.dll,ExternalUpdate %s"), data_filename); + mir_sntprintf(szParams, SIZEOF(szParams), _T("RUNDLL32.EXE .\\plugins\\updater.dll,ExternalUpdate %s"), data_filename); } - PROCESS_INFORMATION pi = {0}; - STARTUPINFO si = {0}; - si.cb = sizeof(si); + BOOL res; - if(!CreateProcess(0, szParams, 0, 0, 0, - CREATE_NO_WINDOW | DETACHED_PROCESS | NORMAL_PRIORITY_CLASS, - 0, szProcDir, &si, &pi)) + if (IsAdminRequired()) { - int err = GetLastError(); - TCHAR msg[256]; - mir_sntprintf(msg, SIZEOF(msg), _T("Error code: %d"), err); - MessageBox(0, msg, TranslateT("CreateProcess"), MB_OK | MB_ICONERROR); + SHELLEXECUTEINFO info = {0}; + info.cbSize = sizeof(info); - return 1; - } else { - CloseHandle(pi.hThread); - CloseHandle(pi.hProcess); + TCHAR *p = _tcschr(szParams, ' '); if (p) *(p++) = 0; + + info.lpVerb = _T("runas"); + info.lpFile = szParams; + info.lpParameters = p; + info.lpDirectory = szProcDir; + info.nShow = SW_HIDE; + + res = ShellExecuteEx(&info); + info.cbSize = sizeof(info); + + } + else + { + PROCESS_INFORMATION pi = {0}; + STARTUPINFO si = {0}; + si.cb = sizeof(si); + + res = CreateProcess(0, szParams, 0, 0, 0, + CREATE_NO_WINDOW | DETACHED_PROCESS | NORMAL_PRIORITY_CLASS, + 0, szProcDir, &si, &pi); + + if (res) + { + CloseHandle(pi.hThread); + CloseHandle(pi.hProcess); + } + } + + if (res) + { PostMessage((HWND)CallService(MS_CLUI_GETHWND, 0, 0), WM_COMMAND, ID_ICQ_EXIT, 0); - return 0; } + else + { + TCHAR msg[256]; + mir_sntprintf(msg, SIZEOF(msg), _T("Error code: %d"), GetLastError()); + MessageBox(0, msg, TranslateT("CreateProcess"), MB_OK | MB_ICONERROR); + } - return 1; + return !res; } #ifdef _UD_LOGGING @@ -476,10 +492,16 @@ void CALLBACK ExternalUpdate(HWND hwnd, HINSTANCE hInstance, LPSTR lpszCmdLine, STARTUPINFO si = {0}; si.cb = sizeof(si); - if(!CreateProcess(mir_exe, szArgs, 0, 0, 0, DETACHED_PROCESS|NORMAL_PRIORITY_CLASS, 0, 0, &si, &pi)) { + if (!CreateProcess(mir_exe, szArgs, 0, 0, 0, DETACHED_PROCESS | NORMAL_PRIORITY_CLASS, 0, 0, &si, &pi)) + { MessageBox(0, _T("Failed to restart Miranda"), _T("Updater Error"), MB_OK | MB_ICONERROR); //MessageBox(0, szArgs, mir_exe, MB_OK); } + else + { + CloseHandle(pi.hThread); + CloseHandle(pi.hProcess); + } //ShellExecute(0, 0, mir_exe, szArgs, 0, SW_NORMAL); } } -- cgit v1.2.3