Bug 459615 - Remove the needElevation param from WinLaunchChild. r=ted.mielczarek, r=jmathies
--- a/toolkit/mozapps/update/src/updater/updater.cpp
+++ b/toolkit/mozapps/update/src/updater/updater.cpp
@@ -1088,30 +1088,52 @@ LaunchWinPostProcess(const WCHAR *appExe
wcscpy(dlogFile, exefullpath);
slash = wcsrchr(dlogFile, '\\');
wcscpy(slash + 1, L"uninstall.update");
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
static void
LaunchCallbackApp(const NS_tchar *workingDir, int argc, NS_tchar **argv)
{
putenv("NO_EM_RESTART=");
putenv("MOZ_LAUNCHED_CHILD=1");
@@ -1119,17 +1141,17 @@ LaunchCallbackApp(const NS_tchar *workin
// Run from the specified working directory (see bug 312360).
NS_tchdir(workingDir);
#if defined(USE_EXECV)
execv(argv[0], 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
}
static void
WriteStatusFile(int status)
{
--- a/toolkit/xre/nsAppRunner.cpp
+++ b/toolkit/xre/nsAppRunner.cpp
@@ -601,18 +601,16 @@ public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIXULAPPINFO
NS_DECL_NSIXULRUNTIME
#ifdef MOZ_CRASHREPORTER
NS_DECL_NSICRASHREPORTER
#endif
#ifdef XP_WIN
NS_DECL_NSIWINAPPHELPER
-private:
- nsresult LaunchAppHelperWithArgs(int aArgc, char **aArgv);
#endif
};
NS_INTERFACE_MAP_BEGIN(nsXULAppInfo)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXULRuntime)
NS_INTERFACE_MAP_ENTRY(nsIXULRuntime)
#ifdef XP_WIN
NS_INTERFACE_MAP_ENTRY(nsIWinAppHelper)
@@ -726,19 +724,22 @@ nsXULAppInfo::GetXPCOMABI(nsACString& aR
aResult.AssignLiteral(TARGET_XPCOM_ABI);
return NS_OK;
#else
return NS_ERROR_NOT_AVAILABLE;
#endif
}
#ifdef XP_WIN
-nsresult
-nsXULAppInfo::LaunchAppHelperWithArgs(int aArgc, char **aArgv)
+#include <shellapi.h>
+
+NS_IMETHODIMP
+nsXULAppInfo::PostUpdate(nsILocalFile *aLogFile)
{
+#ifndef WINCE
nsresult rv;
nsCOMPtr<nsIProperties> directoryService =
do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsILocalFile> appHelper;
rv = directoryService->Get(NS_XPCOM_CURRENT_PROCESS_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(appHelper));
NS_ENSURE_SUCCESS(rv, rv);
@@ -748,60 +749,53 @@ nsXULAppInfo::LaunchAppHelperWithArgs(in
rv = appHelper->AppendNative(NS_LITERAL_CSTRING("helper.exe"));
NS_ENSURE_SUCCESS(rv, rv);
nsAutoString appHelperPath;
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;
+ len += wcslen(secondArg);
+ len += wcslen(logFilePath.get());
}
- else {
- upgradeArgv[2] = nsnull;
+
+ PRUnichar *cmdLine = (PRUnichar *) malloc((len + 1) * sizeof(PRUnichar));
+ if (!cmdLine)
+ return NS_ERROR_OUT_OF_MEMORY;
+
+ wcscpy(cmdLine, dummyArg);
+ wcscat(cmdLine, firstArg);
+
+ if (aLogFile) {
+ wcscat(cmdLine, secondArg);
+ wcscat(cmdLine, logFilePath.get());
}
- rv = LaunchAppHelperWithArgs(upgradeArgc, upgradeArgv);
-
- if (pathArg)
- PR_smprintf_free(pathArg);
-
- free(upgradeArgv);
- return rv;
+ 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
// safely build with the Vista SDK and without it.
typedef enum
{
VistaTokenElevationTypeDefault = 1,
VistaTokenElevationTypeFull,
@@ -1484,16 +1478,17 @@ XRE_GetBinaryPath(const char* argv0, nsI
NS_ADDREF(*aResult = lf);
return NS_OK;
}
#define NS_ERROR_LAUNCHED_CHILD_PROCESS NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_PROFILE, 200)
#ifdef XP_WIN
#include "nsWindowsRestart.cpp"
+#include <shellapi.h>
#endif
#if defined(XP_OS2) && (__KLIBC__ == 0 && __KLIBC_MINOR__ >= 6) // broken kLibc
// Copy the environment maintained by the C library into an ASCIIZ array
// that can be used to pass it on to the OS/2 Dos* APIs (which otherwise
// don't know anything about the stuff set by PR_SetEnv() or setenv()).
char *createEnv()
{
@@ -1605,17 +1600,17 @@ static nsresult LaunchChild(nsINativeApp
return rv;
#if defined(XP_WIN)
nsAutoString exePath;
rv = lf->GetPath(exePath);
if (NS_FAILED(rv))
return rv;
- if (!WinLaunchChild(exePath.get(), gRestartArgc, gRestartArgv, 0))
+ if (!WinLaunchChild(exePath.get(), gRestartArgc, gRestartArgv))
return NS_ERROR_FAILURE;
#else
nsCAutoString exePath;
rv = lf->GetNativePath(exePath);
if (NS_FAILED(rv))
return rv;
--- a/toolkit/xre/nsAppRunner.h
+++ b/toolkit/xre/nsAppRunner.h
@@ -132,17 +132,17 @@ NS_HIDDEN_(nsresult)
NS_LockProfilePath(nsILocalFile* aPath, nsILocalFile* aTempPath,
nsIProfileUnlocker* *aUnlocker, nsIProfileLock* *aResult);
NS_HIDDEN_(void)
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"
// Like nsXREAppData, but releases all strong refs/allocated memory
// in the destructor.
class ScopedAppData : public nsXREAppData
{
--- a/toolkit/xre/nsUpdateDriver.cpp
+++ b/toolkit/xre/nsUpdateDriver.cpp
@@ -508,17 +508,17 @@ ApplyUpdate(nsIFile *greDir, nsIFile *up
LOG(("spawning updater process [%s]\n", updaterPath.get()));
#if defined(USE_EXECV)
chdir(applyToDir.get());
execv(updaterPath.get(), argv);
#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
PRStatus status;
PRProcessAttr *attr;
attr = PR_NewProcessAttr();
if (!attr)
--- a/toolkit/xre/nsWindowsRestart.cpp
+++ b/toolkit/xre/nsWindowsRestart.cpp
@@ -190,100 +190,16 @@ MakeCommandLine(int argc, PRUnichar **ar
}
*c = '\0';
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.
*/
static PRUnichar*
AllocConvertUTF8toUTF16(const char *arg)
{
// UTF16 can't be longer in units than UTF8
int len = strlen(arg);
@@ -305,91 +221,66 @@ FreeAllocStrings(int argc, PRUnichar **a
delete [] argv[argc];
}
delete [] 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)
return FALSE;
for (int i = 0; i < argc; ++i) {
argvConverted[i] = AllocConvertUTF8toUTF16(argv[i]);
if (!argvConverted[i]) {
return FALSE;
}
}
- 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);
return ok;
}