tor-browser

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

main.cpp (3376B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 #include <iostream>
      5 #include <optional>
      6 #include <rpc.h>
      7 #include <shellapi.h>
      8 #include <string>
      9 #include <windows.h>
     10 #include "download_firefox.h"
     11 #include "file_sink.h"
     12 #include "find_firefox.h"
     13 #include "tempfile_name.h"
     14 
     15 #define DOWNLOAD_PAGE L"https://www.mozilla.org/firefox/new/"
     16 #define STUB_INSTALLER_ARGS L"/Prompt /LaunchedBy:desktoplauncher"
     17 
     18 /**
     19 * Runs the provided path using the shell using the provided command-line
     20 * parameters.
     21 *
     22 * Blocks until the application starts accepting input, or until a
     23 * Windows-internal timeout is reached. Refer to SEE_MASK_WAITFORINPUTIDLE's
     24 * documentation.
     25 *
     26 * @param path The path to the file or URL to run.
     27 * @param params Command-line arguments to pass. May be null.
     28 * @returns Truthy if the launch succeeded, false otherwise.
     29 */
     30 static bool ExecuteAndWaitForIdle(const std::wstring& path,
     31                                  const wchar_t* params) {
     32  SHELLEXECUTEINFOW sei = {0};
     33  sei.cbSize = sizeof(sei);
     34  sei.fMask = SEE_MASK_WAITFORINPUTIDLE | SEE_MASK_NOASYNC;
     35  sei.lpFile = path.c_str();
     36  sei.lpParameters = params;
     37  sei.nShow = SW_SHOWNORMAL;
     38  ShellExecuteExW(&sei);
     39  return (uintptr_t)sei.hInstApp > 32;
     40 }
     41 
     42 int wmain() {
     43  // For telemetry purposes, let's set the env variable to indicate that
     44  // we used the launcher to start Firefox
     45  if (!SetEnvironmentVariableW(L"FIREFOX_LAUNCHED_BY_DESKTOP_LAUNCHER",
     46                               L"TRUE")) {
     47    std::wcout
     48        << L"Could not set env variable FIREFOX_LAUNCHED_BY_DESKTOP_LAUNCHER"
     49        << std::endl;
     50  }
     51 
     52  // First, we try to launch Firefox if it is installed
     53  std::optional<std::wstring> firefox_path = lookupFirefoxPath();
     54  if (firefox_path.has_value()) {
     55    std::wcout << L"Found Firefox at path " << firefox_path.value()
     56               << std::endl;
     57    if (ExecuteAndWaitForIdle(firefox_path.value(), nullptr)) {
     58      std::wcout << L"Firefox launched" << std::endl;
     59      return 0;
     60    }
     61  }
     62  bool download_completed = false;
     63  // If that doesn't work, we try to download the installer.
     64  std::optional<std::wstring> tempfileName = get_tempfile_name();
     65  // If we do create a fileSink, it needs to live until the
     66  // ExecuteAndWaitForIdle calls return to ensure that other processes cannot
     67  // delete or rename it.
     68  std::unique_ptr<FileSink> fileSink;
     69  if (tempfileName.has_value()) {
     70    fileSink = std::make_unique<FileSink>();
     71    if (fileSink->open(tempfileName.value())) {
     72      ErrCode rc = download_firefox(fileSink.get());
     73      if (rc == ErrCode::OK) {
     74        std::wcout << L"Firefox installer successfully downloaded" << std::endl;
     75        download_completed = true;
     76      }
     77    }
     78  }
     79  // If the installer successfully downloaded, try to launch it
     80  if (download_completed) {
     81    if (fileSink->freeze() &&
     82        ExecuteAndWaitForIdle(tempfileName.value(), STUB_INSTALLER_ARGS)) {
     83      std::wcout << L"Firefox installer launched" << std::endl;
     84      return 0;
     85    }
     86  }
     87 
     88  // If that doesn't work, open the download page in the default browser
     89  if (ExecuteAndWaitForIdle(DOWNLOAD_PAGE, nullptr)) {
     90    std::wcout << L"Opened default browser to the download page" << std::endl;
     91  }
     92  return 0;
     93 }