Bug 459615 - Remove the needElevation param from WinLaunchChild. r=ted.mielczarek, r=jmathies

This commit is contained in:
Robert Strong 2009-01-01 16:18:33 -08:00
Родитель 4f803cdd28
Коммит 2db4280254
5 изменённых файлов: 90 добавлений и 182 удалений

Просмотреть файл

@ -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

Просмотреть файл

@ -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 <shellapi.h>
NS_IMETHODIMP
nsXULAppInfo::PostUpdate(nsILocalFile *aLogFile)
{
#ifndef WINCE
nsresult rv;
nsCOMPtr<nsIProperties> 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 <shellapi.h>
#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

Просмотреть файл

@ -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"

Просмотреть файл

@ -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

Просмотреть файл

@ -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);