commit 8976fdf55d5ebabd160d5a7f378d1b8a81feba02
parent 78810a9f53f6e5271820be97a5e45145032e0983
Author: Duncan McIntosh <dmcintosh@mozilla.com>
Date: Fri, 24 Oct 2025 22:02:34 +0000
Bug 1991233 - Ensure we always wait for the child process to accept input before leaving the desktop launcher. r=cdupuis
Differential Revision: https://phabricator.services.mozilla.com/D266504
Diffstat:
1 file changed, 28 insertions(+), 20 deletions(-)
diff --git a/browser/app/desktop-launcher/main.cpp b/browser/app/desktop-launcher/main.cpp
@@ -15,6 +15,30 @@
#define DOWNLOAD_PAGE L"https://www.mozilla.org/firefox/new/"
#define STUB_INSTALLER_ARGS L"/Prompt /LaunchedBy:desktoplauncher"
+/**
+ * Runs the provided path using the shell using the provided command-line
+ * parameters.
+ *
+ * Blocks until the application starts accepting input, or until a
+ * Windows-internal timeout is reached. Refer to SEE_MASK_WAITFORINPUTIDLE's
+ * documentation.
+ *
+ * @param path The path to the file or URL to run.
+ * @param params Command-line arguments to pass. May be null.
+ * @returns Truthy if the launch succeeded, false otherwise.
+ */
+static bool ExecuteAndWaitForIdle(const std::wstring& path,
+ const wchar_t* params) {
+ SHELLEXECUTEINFOW sei = {0};
+ sei.cbSize = sizeof(sei);
+ sei.fMask = SEE_MASK_WAITFORINPUTIDLE | SEE_MASK_NOASYNC;
+ sei.lpFile = path.c_str();
+ sei.lpParameters = params;
+ sei.nShow = SW_SHOWNORMAL;
+ ShellExecuteExW(&sei);
+ return (uintptr_t)sei.hInstApp > 32;
+}
+
int wmain() {
// For telemetry purposes, let's set the env variable to indicate that
// we used the launcher to start Firefox
@@ -30,12 +54,7 @@ int wmain() {
if (firefox_path.has_value()) {
std::wcout << L"Found Firefox at path " << firefox_path.value()
<< std::endl;
- HINSTANCE hinst =
- ShellExecuteW(nullptr, nullptr, firefox_path.value().c_str(), nullptr,
- nullptr, SW_SHOWNORMAL);
- if ((INT_PTR)hinst > 32) {
- // ShellExecuteW returns a value > 32 on success. So we assume that
- // Firefox has launched.
+ if (ExecuteAndWaitForIdle(firefox_path.value(), nullptr)) {
std::wcout << L"Firefox launched" << std::endl;
return 0;
}
@@ -55,25 +74,14 @@ int wmain() {
}
// If the installer successfully downloaded, try to launch it
if (download_completed) {
- SHELLEXECUTEINFOW sei = {0};
- sei.cbSize = sizeof(sei);
- sei.fMask = SEE_MASK_WAITFORINPUTIDLE | SEE_MASK_NOASYNC;
- sei.lpFile = tempfileName.value().c_str();
- sei.lpParameters = STUB_INSTALLER_ARGS;
- sei.nShow = SW_SHOWNORMAL;
- ShellExecuteExW(&sei);
-
- if ((INT_PTR)sei.hInstApp > 32) {
- // ShellExecuteW returns a value > 32 on success.
+ if (ExecuteAndWaitForIdle(tempfileName.value(), STUB_INSTALLER_ARGS)) {
std::wcout << L"Firefox installer launched" << std::endl;
return 0;
}
}
+
// If that doesn't work, open the download page in the default browser
- HINSTANCE default_browser_hinst = ShellExecuteW(
- nullptr, nullptr, DOWNLOAD_PAGE, nullptr, nullptr, SW_SHOWNORMAL);
- if ((INT_PTR)default_browser_hinst > 32) {
- // ShellExecuteW returns a value > 32 on success.
+ if (ExecuteAndWaitForIdle(DOWNLOAD_PAGE, nullptr)) {
std::wcout << L"Opened default browser to the download page" << std::endl;
}
return 0;