Bug 603903: use RegisterApplicationRestart behind a pref
MozReview-Commit-ID: 6bMZHDRjW3T
--- a/toolkit/xre/nsAppRunner.cpp
+++ b/toolkit/xre/nsAppRunner.cpp
@@ -1879,17 +1879,51 @@ XRE_GetBinaryPath(nsIFile* *aResult)
return mozilla::BinaryPath::GetFile(aResult);
}
#ifdef XP_WIN
#include "nsWindowsRestart.cpp"
#include <shellapi.h>
typedef BOOL (WINAPI* SetProcessDEPPolicyFunc)(DWORD dwFlags);
-#endif
+
+#define PREF_WIN_REGISTER_APPLICATION_RESTART "toolkit.winRegisterApplicationRestart"
+
+static void
+RegisterApplicationRestartChanged(const char* aPref, void* aData) {
+ if (Preferences::GetBool(PREF_WIN_REGISTER_APPLICATION_RESTART, false)) {
+ // Make the command line to use when restarting
+ wchar_t* restartCommandLine = nullptr;
+ if (gRestartArgc > 1) {
+ // excludes argv[0] because RegisterApplicationRestart adds the
+ // executable name
+ wchar_t** restartArgvConverted =
+ AllocConvertUTF8toUTF16Strings(gRestartArgc - 1, gRestartArgv + 1);
+
+ if (restartArgvConverted) {
+ restartCommandLine = MakeCommandLine(gRestartArgc - 1, restartArgvConverted);
+ FreeAllocStrings(gRestartArgc - 1, restartArgvConverted);
+ }
+ } else {
+ restartCommandLine = (wchar_t*) malloc(sizeof(wchar_t));
+ restartCommandLine[0] = L'\0';
+ }
+
+ if (restartCommandLine) {
+ // Flags RESTART_NO_PATCH and RESTART_NO_REBOOT are not set, so we
+ // should be restarted if terminated by an update or restart.
+ ::RegisterApplicationRestart(restartCommandLine, RESTART_NO_CRASH |
+ RESTART_NO_HANG);
+ free(restartCommandLine);
+ }
+ } else {
+ ::UnregisterApplicationRestart();
+ }
+}
+#endif // XP_WIN
// If aBlankCommandLine is true, then the application will be launched with a
// blank command line instead of being launched with the same command line that
// it was initially started with.
static nsresult LaunchChild(nsINativeAppSupport* aNative,
bool aBlankCommandLine = false)
{
aNative->Quit(); // release DDE mutex, if we're holding it
@@ -4667,16 +4701,21 @@ XREMain::XRE_mainRun()
SaveToEnv("NO_EM_RESTART=");
SaveToEnv("XUL_APP_FILE=");
SaveToEnv("XRE_BINARY_PATH=");
if (!mShuttingDown) {
rv = appStartup->CreateHiddenWindow();
NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
+#ifdef XP_WIN32
+ Preferences::RegisterCallbackAndCall(RegisterApplicationRestartChanged,
+ PREF_WIN_REGISTER_APPLICATION_RESTART);
+#endif
+
#if defined(HAVE_DESKTOP_STARTUP_ID) && defined(MOZ_WIDGET_GTK)
nsGTKToolkit* toolkit = nsGTKToolkit::GetToolkit();
if (toolkit && !mDesktopStartupID.IsEmpty()) {
toolkit->SetDesktopStartupID(mDesktopStartupID);
}
// Clear the environment variable so it won't be inherited by
// child processes and confuse things.
g_unsetenv ("DESKTOP_STARTUP_ID");
--- a/toolkit/xre/nsWindowsRestart.cpp
+++ b/toolkit/xre/nsWindowsRestart.cpp
@@ -108,18 +108,16 @@ static wchar_t* ArgToString(wchar_t *d,
}
return d;
}
/**
* Creates a command line from a list of arguments. The returned
* string is allocated with "malloc" and should be "free"d.
- *
- * argv is UTF8
*/
wchar_t*
MakeCommandLine(int argc, wchar_t **argv)
{
int i;
int len = 0;
// The + 1 of the last argument handles the allocation for null termination
@@ -173,16 +171,32 @@ FreeAllocStrings(int argc, wchar_t **arg
while (argc) {
--argc;
delete [] argv[argc];
}
delete [] argv;
}
+static wchar_t**
+AllocConvertUTF8toUTF16Strings(int argc, char **argv)
+{
+ wchar_t **argvConverted = new wchar_t*[argc];
+ if (!argvConverted)
+ return nullptr;
+
+ for (int i = 0; i < argc; ++i) {
+ argvConverted[i] = reinterpret_cast<wchar_t*>(AllocConvertUTF8toUTF16(argv[i]));
+ if (!argvConverted[i]) {
+ FreeAllocStrings(i, argvConverted);
+ return nullptr;
+ }
+ }
+ return argvConverted;
+}
/**
* Launch a child process with the specified arguments.
* @note argv[0] is ignored
* @note The form of this function that takes char **argv expects UTF-8
*/
@@ -193,28 +207,20 @@ WinLaunchChild(const wchar_t *exePath,
HANDLE *hProcess = nullptr);
BOOL
WinLaunchChild(const wchar_t *exePath,
int argc, char **argv,
HANDLE userToken,
HANDLE *hProcess)
{
- wchar_t** argvConverted = new wchar_t*[argc];
+ wchar_t **argvConverted = AllocConvertUTF8toUTF16Strings(argc, argv);
if (!argvConverted)
return FALSE;
- for (int i = 0; i < argc; ++i) {
- argvConverted[i] = reinterpret_cast<wchar_t*>(AllocConvertUTF8toUTF16(argv[i]));
- if (!argvConverted[i]) {
- FreeAllocStrings(i, argvConverted);
- return FALSE;
- }
- }
-
BOOL ok = WinLaunchChild(exePath, argc, argvConverted, userToken, hProcess);
FreeAllocStrings(argc, argvConverted);
return ok;
}
BOOL
WinLaunchChild(const wchar_t *exePath,
int argc,