tor-browser

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

find_firefox.cpp (3773B)


      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 "find_firefox.h"
      5 
      6 #include <iostream>
      7 #include <optional>
      8 #include <string>
      9 #include <windows.h>
     10 
     11 // The firefox_node logic here mirrors the definition of BrandFullNameInternal
     12 // in browser/branding/${channel}/branding.nsi
     13 // Opened Bug 1979135 to address refactoring this.
     14 #if defined(MOZ_BRANDING_IS_OFFICIAL)
     15 static const wchar_t* firefox_node = L"SOFTWARE\\Mozilla\\Mozilla Firefox";
     16 #elif defined(MOZ_BRANDING_IS_NIGHTLY)
     17 static const wchar_t* firefox_node = L"SOFTWARE\\Mozilla\\Nightly";
     18 #elif defined(MOZ_BRANDING_IS_BETA)
     19 static const wchar_t* firefox_node = L"SOFTWARE\\Mozilla\\Mozilla Firefox";
     20 #elif defined(MOZ_BRANDING_IS_DEVEDITION)
     21 static const wchar_t* firefox_node =
     22    L"SOFTWARE\\Mozilla\\Firefox Developer Edition";
     23 #elif defined(MOZ_BRANDING_IS_UNOFFICIAL)
     24 static const wchar_t* firefox_node =
     25    L"SOFTWARE\\Mozilla\\Mozilla Developer Preview";
     26 #else
     27 // Unexpected case. Fail the build here so we can figure out the missing case.
     28 static_assert(false);
     29 #endif
     30 
     31 /**
     32 * The base registry key that Firefox uses to store its settings is different
     33 * depending on the branding for the build. This function exposes the correct
     34 * registry key to use for the current build's branding.
     35 */
     36 const wchar_t* getFirefoxRegistryBranding() { return firefox_node; }
     37 
     38 /**
     39 * Look up Firefox path in a particular HKEY
     40 */
     41 static std::optional<std::wstring> lookupFirefoxPathInHKEY(HKEY hkey) {
     42  std::wstring current_version = L"CurrentVersion";
     43  wchar_t buffer[MAX_PATH];
     44  // RegGetValueW will store the size of the value (including terminal \0) in
     45  // bytes into this variable.
     46  DWORD value_size = sizeof(buffer);
     47 
     48  // First we need to get the current version of Firefox
     49  LSTATUS status =
     50      RegGetValueW(hkey, getFirefoxRegistryBranding(), current_version.c_str(),
     51                   RRF_RT_REG_SZ, nullptr, buffer, &value_size);
     52  if (status != ERROR_SUCCESS || value_size < 2) {
     53    std::wcout << L"Failed to get firefox current version at node "
     54               << getFirefoxRegistryBranding() << L"status: " << status
     55               << std::endl;
     56    return std::nullopt;
     57  }
     58  DWORD value_len = value_size / sizeof(wchar_t) - 1;
     59  // Then we need to see where that version is installed
     60  std::wstring current_version_string = std::wstring(buffer, value_len);
     61  std::wstring current_version_node =
     62      std::wstring(getFirefoxRegistryBranding()) + L"\\" +
     63      current_version_string + L"\\Main";
     64  std::wstring path_to_exe = L"PathToExe";
     65  value_size = sizeof(buffer);
     66  status = RegGetValueW(hkey, current_version_node.c_str(), path_to_exe.c_str(),
     67                        RRF_RT_REG_SZ, nullptr, buffer, &value_size);
     68  if (status != ERROR_SUCCESS || value_size < 2) {
     69    std::wcout
     70        << L"Failed to get firefox path for current version, at location "
     71        << current_version_node << L" status was " << status << std::endl;
     72    return std::nullopt;
     73  }
     74  value_len = value_size / sizeof(wchar_t) - 1;
     75  // We should have the path in buffer. Note that value_len contains the size of
     76  // the path in bytes, so we need to divide by 2 to get the length in
     77  // characters.
     78  std::wstring firefox_path = std::wstring(buffer, value_len);
     79  return firefox_path;
     80 }
     81 
     82 /**
     83 * Look up Firefox path in registry keys
     84 * @return  the path as a std::wstring if found
     85 */
     86 std::optional<std::wstring> lookupFirefoxPath() {
     87  auto sharedInstallPath = lookupFirefoxPathInHKEY(HKEY_CURRENT_USER);
     88  if (sharedInstallPath.has_value()) {
     89    return sharedInstallPath;
     90  } else {
     91    return lookupFirefoxPathInHKEY(HKEY_LOCAL_MACHINE);
     92  }
     93 }