tor-browser

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

pbproxy.cpp (3271B)


      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 
      5 #include <windows.h>
      6 #include <processthreadsapi.h>
      7 #include <winbase.h>
      8 #include <winuser.h>
      9 #include <shlwapi.h>
     10 #include <string>
     11 
     12 // Max command line length, per CreateProcessW docs
     13 #define MAX_CMD_LENGTH 32767
     14 #define EXTRA_ERR_MSG_LENGTH 39
     15 #define ERR_GET_OUR_PATH L"844fa30e-0860-11ed-898b-373276936058"
     16 #define ERR_GET_APP_DIR L"811237de-0904-11ed-8745-c7c269742323"
     17 #define ERR_GET_APP_EXE L"8964fd30-0860-11ed-8374-576505ba4488"
     18 #define ERR_LAUNCHING_APP L"89d2ca2c-0860-11ed-883c-bf345b8391bc"
     19 
     20 void raiseError(DWORD err, std::wstring uuid) {
     21  LPWSTR winerr;
     22  if (err && ::FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
     23                                  FORMAT_MESSAGE_FROM_SYSTEM |
     24                                  FORMAT_MESSAGE_IGNORE_INSERTS,
     25                              nullptr, err, 0, (LPWSTR)&winerr, 0, nullptr)) {
     26    std::wstring errmsg(winerr);
     27    errmsg += L"\n\n" + uuid;
     28    ::MessageBoxW(nullptr, errmsg.c_str(), MOZ_APP_NAME " private_browsing.exe",
     29                  MB_OK | MB_ICONERROR | MB_SETFOREGROUND);
     30  } else {
     31    ::MessageBoxW(nullptr, uuid.c_str(), MOZ_APP_NAME " private_browsing.exe",
     32                  MB_OK | MB_ICONERROR | MB_SETFOREGROUND);
     33  }
     34 }
     35 
     36 /*
     37 * A very simple wrapper that always launches Firefox in Private Browsing
     38 * mode. Any arguments given to this program will be forwarded to Firefox,
     39 * as well the information provided by GetStartupInfoW() (the latter is mainly
     40 * done to ensure that Firefox's `launch_method` Telemetry works, which
     41 * depends on shortcut information).
     42 *
     43 * Any errors that happen during this process will pop up a MessageBox
     44 * with a Windows error (if present) and a unique UUID for debugability --
     45 * but these are very unlikely to be seen in practice.
     46 */
     47 int WINAPI wWinMain(HINSTANCE, HINSTANCE, LPWSTR aCmdLine, int) {
     48  wchar_t app[MAX_PATH];
     49  DWORD ret = GetModuleFileNameW(nullptr, app, MAX_PATH);
     50  if (!ret ||
     51      (ret == MAX_PATH && ::GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
     52    ret = ::GetLastError();
     53    raiseError(ret, ERR_GET_OUR_PATH);
     54    return ret;
     55  }
     56  if (!PathRemoveFileSpecW(app)) {
     57    raiseError(0, ERR_GET_APP_DIR);
     58    return 1;
     59  }
     60  if (!PathAppendW(app, MOZ_APP_NAME L".exe")) {
     61    raiseError(0, ERR_GET_APP_EXE);
     62    return 1;
     63  }
     64 
     65  std::wstring cmdLine(L"\"");
     66  cmdLine += app;
     67  cmdLine += L"\" -private-window";
     68  if (wcslen(aCmdLine) > 0) {
     69    cmdLine += L" ";
     70    cmdLine += aCmdLine;
     71  }
     72  DWORD creationFlags = CREATE_UNICODE_ENVIRONMENT;
     73  // Mainly used to pass along shortcut information to ensure
     74  // launch_method Telemetry will be accurate.
     75  STARTUPINFOW startupInfo = {0};
     76  startupInfo.cb = sizeof(STARTUPINFOW);
     77  GetStartupInfoW(&startupInfo);
     78  PROCESS_INFORMATION pi;
     79 
     80  bool rv =
     81      ::CreateProcessW(app, cmdLine.data(), nullptr, nullptr, FALSE,
     82                       creationFlags, nullptr, nullptr, &startupInfo, &pi);
     83 
     84  if (!rv) {
     85    ret = ::GetLastError();
     86    raiseError(ret, ERR_LAUNCHING_APP);
     87    return ret;
     88  }
     89 
     90  ::CloseHandle(pi.hProcess);
     91  ::CloseHandle(pi.hThread);
     92 
     93  return 0;
     94 }