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 }