зеркало из https://github.com/mozilla/gecko-dev.git
Bug 459615 - Remove the needElevation param from WinLaunchChild. r=ted.mielczarek, r=jmathies
This commit is contained in:
Родитель
4f803cdd28
Коммит
2db4280254
|
@ -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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче