tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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:
Mbrowser/app/desktop-launcher/main.cpp | 48++++++++++++++++++++++++++++--------------------
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;