From 5a1deab8ac2e3986419969ffd6c1e9a73a2472be Mon Sep 17 00:00:00 2001 From: "Brian R. Bondy" Date: Wed, 4 Jan 2012 23:19:17 -0500 Subject: [PATCH] Bug 711834 - Fix force no UAC prompt for xpcshell tests. r=rstrong --- toolkit/mozapps/readstrings/errors.h | 8 +++ .../update/test/unit/head_update.js.in | 6 +++ toolkit/mozapps/update/updater/updater.cpp | 54 ++++++++++++++++--- 3 files changed, 61 insertions(+), 7 deletions(-) diff --git a/toolkit/mozapps/readstrings/errors.h b/toolkit/mozapps/readstrings/errors.h index b89da6475c9b..64fb262246f8 100644 --- a/toolkit/mozapps/readstrings/errors.h +++ b/toolkit/mozapps/readstrings/errors.h @@ -50,4 +50,12 @@ #define UNEXPECTED_ERROR 8 #define ELEVATION_CANCELED 9 +// The following error codes are only used by updater.exe +// when a fallback key exists and XPCShell tests are being run. +#define FALLBACKKEY_UNKNOWN_ERROR 100 +#define FALLBACKKEY_REGPATH_ERROR 101 +#define FALLBACKKEY_NOKEY_ERROR 102 +#define FALLBACKKEY_EVENT_ERROR 103 +#define FALLBACKKEY_LAUNCH_ERROR 104 + #endif // Errors_h__ diff --git a/toolkit/mozapps/update/test/unit/head_update.js.in b/toolkit/mozapps/update/test/unit/head_update.js.in index 9f90eee9d2d6..713f5df1f35a 100644 --- a/toolkit/mozapps/update/test/unit/head_update.js.in +++ b/toolkit/mozapps/update/test/unit/head_update.js.in @@ -1751,6 +1751,9 @@ function setEnvironment() { gEnvAppDirOverride + "\n"); env.set("MOZ_UPDATE_APPDIR_OVERRIDE", gEnvAppDirOverride); } + + logTestInfo("setting MOZ_NO_SERVICE_FALLBACK environment variable to 1"); + env.set("MOZ_NO_SERVICE_FALLBACK", "1"); } /** @@ -1825,4 +1828,7 @@ function resetEnvironment() { env.set("MOZ_UPDATE_APPDIR_OVERRIDE", ""); gEnvAppDirOverride = null; } + + logTestInfo("removing MOZ_NO_SERVICE_FALLBACK environment variable"); + env.set("MOZ_NO_SERVICE_FALLBACK", ""); } diff --git a/toolkit/mozapps/update/updater/updater.cpp b/toolkit/mozapps/update/updater/updater.cpp index ee3b6e2051f7..83bdaac7cbee 100644 --- a/toolkit/mozapps/update/updater/updater.cpp +++ b/toolkit/mozapps/update/updater/updater.cpp @@ -1406,7 +1406,7 @@ LaunchCallbackApp(const NS_tchar *workingDir, int argc, NS_tchar **argv) #elif defined(XP_WIN) // Do not allow the callback to run when running an update through the // service as session 0. The unelevated updater.exe will do the launching. - WCHAR *usingService = _wgetenv(L"MOZ_USING_SERVICE"); + LPCWSTR usingService = _wgetenv(L"MOZ_USING_SERVICE"); if (!usingService) { WinLaunchChild(argv[0], argc, argv, NULL); } @@ -1603,6 +1603,7 @@ int NS_main(int argc, NS_tchar **argv) bool useService = false; bool testOnlyFallbackKeyExists = false; + LPCWSTR runningAsTest = _wgetenv(L"MOZ_NO_SERVICE_FALLBACK"); // We never want the service to be used unless we build with // the maintenance service. @@ -1677,7 +1678,14 @@ int NS_main(int argc, NS_tchar **argv) const int callbackIndex = 5; #if defined(XP_WIN) - WCHAR *usingService = _wgetenv(L"MOZ_USING_SERVICE"); + LPCWSTR usingService = _wgetenv(L"MOZ_USING_SERVICE"); + // lastFallbackError keeps track of the last error for the service not being + // used, in case of an error when fallback is not enabled we write the + // error to the update.status file. + // When fallback is disabled (MOZ_NO_SERVICE_FALLBACK does not exist) then + // we will instead fallback to not using the service and display a UAC prompt. + int lastFallbackError = FALLBACKKEY_UNKNOWN_ERROR; + // Launch a second instance of the updater with the runas verb on Windows // when write access is denied to the installation directory. HANDLE updateLockFileHandle; @@ -1710,7 +1718,7 @@ int NS_main(int argc, NS_tchar **argv) NS_T("%s/update_elevated.lock"), argv[1]); if (updateLockFileHandle == INVALID_HANDLE_VALUE || - (useService && testOnlyFallbackKeyExists)) { + (useService && testOnlyFallbackKeyExists && runningAsTest)) { if (!_waccess(elevatedLockFilePath, F_OK) && NS_tremove(elevatedLockFilePath) != 0) { fprintf(stderr, "Update already elevated! Exiting\n"); @@ -1750,9 +1758,13 @@ int NS_main(int argc, NS_tchar **argv) RegCloseKey(baseKey); } else { useService = testOnlyFallbackKeyExists; + if (!useService) { + lastFallbackError = FALLBACKKEY_NOKEY_ERROR; + } } } else { - useService = FALSE; + useService = false; + lastFallbackError = FALLBACKKEY_REGPATH_ERROR; } } @@ -1768,6 +1780,7 @@ int NS_main(int argc, NS_tchar **argv) // doesn't already exist. if (!serviceInUseEvent) { useService = false; + lastFallbackError = FALLBACKKEY_EVENT_ERROR; } } @@ -1788,6 +1801,8 @@ int NS_main(int argc, NS_tchar **argv) // The service will set the event we wait on when it is done. if (useService) { WaitForSingleObject(serviceInUseEvent, INFINITE); + } else { + lastFallbackError = FALLBACKKEY_LAUNCH_ERROR; } CloseHandle(serviceInUseEvent); } @@ -1810,8 +1825,11 @@ int NS_main(int argc, NS_tchar **argv) // If we didn't want to use the service at all, or if an update was // already happening, or launching the service command failed, then - // launch the elevated updater.exe as we used to without the service. - if (!useService) { + // launch the elevated updater.exe as we do without the service. + // We don't launch the elevated updater in the case that we did have + // write access all along because in that case the only reason we're + // using the service is because we are testing. + if (!useService && updateLockFileHandle == INVALID_HANDLE_VALUE) { SHELLEXECUTEINFO sinfo; memset(&sinfo, 0, sizeof(SHELLEXECUTEINFO)); sinfo.cbSize = sizeof(SHELLEXECUTEINFO); @@ -1840,7 +1858,29 @@ int NS_main(int argc, NS_tchar **argv) } CloseHandle(elevatedFileHandle); - return 0; + + if (!useService && INVALID_HANDLE_VALUE == updateLockFileHandle) { + // We didn't use the service and we did run the elevated updater.exe. + // The elevated updater.exe is responsible for writing out the + // update.status file. + return 0; + } else if(useService) { + // The service command was launched. The service is responsible for + // writing out the update.status file. + if (updateLockFileHandle != INVALID_HANDLE_VALUE) { + CloseHandle(updateLockFileHandle); + } + return 0; + } else { + // Otherwise the service command was not launched at all. + // We are only reaching this code path because we had write access + // all along to the directory and a fallback key existed, and we + // have fallback disabled (MOZ_NO_SERVICE_FALLBACK env var exists). + // We only currently use this env var from XPCShell tests. + CloseHandle(updateLockFileHandle); + WriteStatusFile(lastFallbackError); + return 0; + } } } #endif