diff --git a/toolkit/mozapps/update/src/updater/updater.cpp b/toolkit/mozapps/update/src/updater/updater.cpp index 6a08eb3d2b44..6c7d5732a777 100644 --- a/toolkit/mozapps/update/src/updater/updater.cpp +++ b/toolkit/mozapps/update/src/updater/updater.cpp @@ -1093,20 +1093,42 @@ LaunchWinPostProcess(const WCHAR *appExe) WCHAR slogFile[MAXPATHLEN]; _snwprintf(slogFile, MAXPATHLEN, L"%s/update.log", gSourcePath); + WCHAR dummyArg[13]; + wcscpy(dummyArg, L"argv0ignored "); + + int len = wcslen(exearg) + wcslen(dummyArg); + WCHAR *cmdline = (WCHAR *) malloc((len + 1) * sizeof(WCHAR)); + if (!cmdline) + return; + + wcscpy(cmdline, dummyArg); + wcscat(cmdline, exearg); + // We want to launch the post update helper app to update the Windows // registry even if there is a failure with removing the uninstall.update // file or copying the update.log file. NS_tremove(dlogFile); CopyFile(slogFile, dlogFile, FALSE); - static int argc = 2; - static WCHAR* argv[3] = { - L"argv0ignoredbywinlaunchchild", - exearg, - L"\0" - }; - - WinLaunchChild(exefullpath, argc, argv, 0); + STARTUPINFOW si = {sizeof(si), 0}; + PROCESS_INFORMATION pi = {0}; + + BOOL ok = CreateProcessW(exefullpath, + cmdline, + NULL, // no special security attributes + NULL, // no special thread attributes + FALSE, // don't inherit filehandles + 0, // No special process creation flags + NULL, // inherit my environment + NULL, // use my current directory + &si, + &pi); + free(cmdline); + + if (ok) { + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + } } #endif @@ -1124,7 +1146,7 @@ LaunchCallbackApp(const NS_tchar *workingDir, int argc, NS_tchar **argv) #elif defined(XP_MACOSX) LaunchChild(argc, argv); #elif defined(XP_WIN) - WinLaunchChild(argv[0], argc, argv, 0); + WinLaunchChild(argv[0], argc, argv); #else # warning "Need implementaton of LaunchCallbackApp" #endif diff --git a/toolkit/xre/nsAppRunner.cpp b/toolkit/xre/nsAppRunner.cpp index c4736a44c6b6..65137ce673b5 100644 --- a/toolkit/xre/nsAppRunner.cpp +++ b/toolkit/xre/nsAppRunner.cpp @@ -606,8 +606,6 @@ public: #endif #ifdef XP_WIN NS_DECL_NSIWINAPPHELPER -private: - nsresult LaunchAppHelperWithArgs(int aArgc, char **aArgv); #endif }; @@ -731,9 +729,12 @@ nsXULAppInfo::GetXPCOMABI(nsACString& aResult) } #ifdef XP_WIN -nsresult -nsXULAppInfo::LaunchAppHelperWithArgs(int aArgc, char **aArgv) +#include + +NS_IMETHODIMP +nsXULAppInfo::PostUpdate(nsILocalFile *aLogFile) { +#ifndef WINCE nsresult rv; nsCOMPtr directoryService = do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv); @@ -753,50 +754,43 @@ nsXULAppInfo::LaunchAppHelperWithArgs(int aArgc, char **aArgv) rv = appHelper->GetPath(appHelperPath); NS_ENSURE_SUCCESS(rv, rv); - if (!WinLaunchChild(appHelperPath.get(), aArgc, aArgv, 1)) - return NS_ERROR_FAILURE; - else - return NS_OK; -} - -NS_IMETHODIMP -nsXULAppInfo::PostUpdate(nsILocalFile *aLogFile) -{ - nsresult rv; - int upgradeArgc = aLogFile ? 3 : 2; - char **upgradeArgv = (char**) malloc(sizeof(char*) * (upgradeArgc + 1)); - - if (!upgradeArgv) - return NS_ERROR_OUT_OF_MEMORY; - - upgradeArgv[0] = "argv0ignoredbywinlaunchchild"; - upgradeArgv[1] = "/postupdate"; - - char *pathArg = nsnull; + nsAutoString logFilePath; + PRUnichar *dummyArg = L"argv0ignored "; + PRUnichar *firstArg = L"/postupdate"; + PRUnichar *secondArg = L" /uninstalllog="; + int len = wcslen(dummyArg) + wcslen(firstArg); if (aLogFile) { - nsCAutoString logFilePath; - rv = aLogFile->GetNativePath(logFilePath); + rv = aLogFile->GetPath(logFilePath); NS_ENSURE_SUCCESS(rv, rv); - - pathArg = PR_smprintf("/uninstalllog=%s", logFilePath.get()); - if (!pathArg) - return NS_ERROR_OUT_OF_MEMORY; - - upgradeArgv[2] = pathArg; - upgradeArgv[3] = nsnull; - } - else { - upgradeArgv[2] = nsnull; + len += wcslen(secondArg); + len += wcslen(logFilePath.get()); } - rv = LaunchAppHelperWithArgs(upgradeArgc, upgradeArgv); - - if (pathArg) - PR_smprintf_free(pathArg); + PRUnichar *cmdLine = (PRUnichar *) malloc((len + 1) * sizeof(PRUnichar)); + if (!cmdLine) + return NS_ERROR_OUT_OF_MEMORY; - free(upgradeArgv); - return rv; + wcscpy(cmdLine, dummyArg); + wcscat(cmdLine, firstArg); + + if (aLogFile) { + wcscat(cmdLine, secondArg); + wcscat(cmdLine, logFilePath.get()); + } + + BOOL ok = ShellExecuteW(NULL, // no special UI window + NULL, // use default verb + appHelperPath.get(), + cmdLine, + NULL, // use my current directory + SW_SHOWDEFAULT) > (HINSTANCE)32; + free(cmdLine); + + return (!ok ? NS_ERROR_FAILURE : NS_OK); +#else + return NS_ERROR_NOT_AVAILABLE; +#endif } // Matches the enum in WinNT.h for the Vista SDK but renamed so that we can @@ -1489,6 +1483,7 @@ XRE_GetBinaryPath(const char* argv0, nsILocalFile* *aResult) #ifdef XP_WIN #include "nsWindowsRestart.cpp" +#include #endif #if defined(XP_OS2) && (__KLIBC__ == 0 && __KLIBC_MINOR__ >= 6) // broken kLibc @@ -1610,7 +1605,7 @@ static nsresult LaunchChild(nsINativeAppSupport* aNative, if (NS_FAILED(rv)) return rv; - if (!WinLaunchChild(exePath.get(), gRestartArgc, gRestartArgv, 0)) + if (!WinLaunchChild(exePath.get(), gRestartArgc, gRestartArgv)) return NS_ERROR_FAILURE; #else diff --git a/toolkit/xre/nsAppRunner.h b/toolkit/xre/nsAppRunner.h index 33642b47279a..ab99d3651748 100644 --- a/toolkit/xre/nsAppRunner.h +++ b/toolkit/xre/nsAppRunner.h @@ -137,7 +137,7 @@ WriteConsoleLog(); #ifdef XP_WIN BOOL -WinLaunchChild(const PRUnichar *exePath, int argc, char **argv, int needElevation); +WinLaunchChild(const PRUnichar *exePath, int argc, char **argv); #endif #define NS_NATIVEAPPSUPPORT_CONTRACTID "@mozilla.org/toolkit/native-app-support;1" diff --git a/toolkit/xre/nsUpdateDriver.cpp b/toolkit/xre/nsUpdateDriver.cpp index 85c4a872671a..2ed9214b1926 100644 --- a/toolkit/xre/nsUpdateDriver.cpp +++ b/toolkit/xre/nsUpdateDriver.cpp @@ -513,7 +513,7 @@ ApplyUpdate(nsIFile *greDir, nsIFile *updateDir, nsILocalFile *statusFile, #elif defined(XP_WIN) _wchdir(applyToDir.get()); - if (!WinLaunchChild(updaterPathW.get(), appArgc + 4, argv, 0)) + if (!WinLaunchChild(updaterPathW.get(), appArgc + 4, argv)) return; _exit(0); #else diff --git a/toolkit/xre/nsWindowsRestart.cpp b/toolkit/xre/nsWindowsRestart.cpp index 2f923925f797..879007f7df25 100755 --- a/toolkit/xre/nsWindowsRestart.cpp +++ b/toolkit/xre/nsWindowsRestart.cpp @@ -194,90 +194,6 @@ MakeCommandLine(int argc, PRUnichar **argv) return s; } -/** - * Launch a child process without elevated privilege. - */ -static BOOL -LaunchAsNormalUser(const PRUnichar *exePath, PRUnichar *cl) -{ -#ifdef WINCE - return PR_FALSE; -#else - if (!pCreateProcessWithTokenW) { - // IsUserAnAdmin is not present on Win9x and not exported by name on Win2k - *(FARPROC *)&pIsUserAnAdmin = - GetProcAddress(GetModuleHandleA("shell32.dll"), "IsUserAnAdmin"); - - // CreateProcessWithTokenW is not present on WinXP or earlier - *(FARPROC *)&pCreateProcessWithTokenW = - GetProcAddress(GetModuleHandleA("advapi32.dll"), - "CreateProcessWithTokenW"); - - if (!pCreateProcessWithTokenW) - return FALSE; - } - - // do nothing here if we are not elevated or IsUserAnAdmin is not present. - if (!pIsUserAnAdmin || pIsUserAnAdmin && !pIsUserAnAdmin()) - return FALSE; - - // borrow the shell token to drop the privilege - HWND hwndShell = FindWindowA("Progman", NULL); - DWORD dwProcessId; - GetWindowThreadProcessId(hwndShell, &dwProcessId); - - HANDLE hProcessShell = OpenProcess(MAXIMUM_ALLOWED, FALSE, dwProcessId); - if (!hProcessShell) - return FALSE; - - HANDLE hTokenShell; - BOOL ok = OpenProcessToken(hProcessShell, MAXIMUM_ALLOWED, &hTokenShell); - CloseHandle(hProcessShell); - if (!ok) - return FALSE; - - HANDLE hNewToken; - ok = DuplicateTokenEx(hTokenShell, - MAXIMUM_ALLOWED, - NULL, - SecurityDelegation, - TokenPrimary, - &hNewToken); - CloseHandle(hTokenShell); - if (!ok) - return FALSE; - - STARTUPINFOW si = {sizeof(si), 0}; - PROCESS_INFORMATION pi = {0}; - - // When launching with reduced privileges, environment inheritance - // (passing NULL as lpEnvironment) doesn't work correctly. Pass our - // current environment block explicitly - WCHAR* myenv = GetEnvironmentStringsW(); - - ok = pCreateProcessWithTokenW(hNewToken, - 0, // profile is already loaded - exePath, - cl, - CREATE_UNICODE_ENVIRONMENT, - myenv, // inherit my environment - NULL, // use my current directory - &si, - &pi); - - if (myenv) - FreeEnvironmentStringsW(myenv); - - CloseHandle(hNewToken); - if (!ok) - return FALSE; - - CloseHandle(pi.hProcess); - CloseHandle(pi.hThread); - - return TRUE; -#endif -} /** * Convert UTF8 to UTF16 without using the normal XPCOM goop, which we * can't link to updater.exe. @@ -310,16 +226,15 @@ FreeAllocStrings(int argc, PRUnichar **argv) /** * Launch a child process with the specified arguments. - * @param needElevation 1:need elevation, -1:want to drop priv, 0:don't care * @note argv[0] is ignored * @note The form of this function that takes char **argv expects UTF-8 */ BOOL -WinLaunchChild(const PRUnichar *exePath, int argc, PRUnichar **argv, int needElevation); +WinLaunchChild(const PRUnichar *exePath, int argc, PRUnichar **argv); BOOL -WinLaunchChild(const PRUnichar *exePath, int argc, char **argv, int needElevation) +WinLaunchChild(const PRUnichar *exePath, int argc, char **argv) { PRUnichar** argvConverted = new PRUnichar*[argc]; if (!argvConverted) @@ -332,61 +247,37 @@ WinLaunchChild(const PRUnichar *exePath, int argc, char **argv, int needElevatio } } - BOOL ok = WinLaunchChild(exePath, argc, argvConverted, needElevation); + BOOL ok = WinLaunchChild(exePath, argc, argvConverted); FreeAllocStrings(argc, argvConverted); return ok; } BOOL -WinLaunchChild(const PRUnichar *exePath, int argc, PRUnichar **argv, int needElevation) +WinLaunchChild(const PRUnichar *exePath, int argc, PRUnichar **argv) { PRUnichar *cl; BOOL ok; -#ifndef WINCE - if (needElevation > 0) { - cl = MakeCommandLine(argc - 1, argv + 1); - if (!cl) - return FALSE; - ok = ShellExecuteW(NULL, // no special UI window - NULL, // use default verb - exePath, - cl, - NULL, // use my current directory - SW_SHOWDEFAULT) > (HINSTANCE)32; - free(cl); - return ok; - } -#endif cl = MakeCommandLine(argc, argv); if (!cl) return FALSE; - if (needElevation < 0) { - // try to launch as a normal user first - ok = LaunchAsNormalUser(exePath, cl); - // if it fails, fallback to normal launching - if (!ok) - needElevation = 0; - } - if (needElevation == 0) { - STARTUPINFOW si = {sizeof(si), 0}; - PROCESS_INFORMATION pi = {0}; + STARTUPINFOW si = {sizeof(si), 0}; + PROCESS_INFORMATION pi = {0}; - ok = CreateProcessW(exePath, - cl, - NULL, // no special security attributes - NULL, // no special thread attributes - FALSE, // don't inherit filehandles - 0, // No special process creation flags - NULL, // inherit my environment - NULL, // use my current directory - &si, - &pi); + ok = CreateProcessW(exePath, + cl, + NULL, // no special security attributes + NULL, // no special thread attributes + FALSE, // don't inherit filehandles + 0, // No special process creation flags + NULL, // inherit my environment + NULL, // use my current directory + &si, + &pi); - if (ok) { - CloseHandle(pi.hProcess); - CloseHandle(pi.hThread); - } + if (ok) { + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); } free(cl);