diff options
Diffstat (limited to 'browser/app/pbproxy/pbproxy.cpp')
-rw-r--r-- | browser/app/pbproxy/pbproxy.cpp | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/browser/app/pbproxy/pbproxy.cpp b/browser/app/pbproxy/pbproxy.cpp new file mode 100644 index 0000000000..841cd654a1 --- /dev/null +++ b/browser/app/pbproxy/pbproxy.cpp @@ -0,0 +1,94 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include <windows.h> +#include <processthreadsapi.h> +#include <winbase.h> +#include <winuser.h> +#include <shlwapi.h> +#include <string> + +// Max command line length, per CreateProcessW docs +#define MAX_CMD_LENGTH 32767 +#define EXTRA_ERR_MSG_LENGTH 39 +#define ERR_GET_OUR_PATH L"844fa30e-0860-11ed-898b-373276936058" +#define ERR_GET_APP_DIR L"811237de-0904-11ed-8745-c7c269742323" +#define ERR_GET_APP_EXE L"8964fd30-0860-11ed-8374-576505ba4488" +#define ERR_LAUNCHING_APP L"89d2ca2c-0860-11ed-883c-bf345b8391bc" + +void raiseError(DWORD err, std::wstring uuid) { + LPWSTR winerr; + if (err && ::FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + nullptr, err, 0, (LPWSTR)&winerr, 0, nullptr)) { + std::wstring errmsg(winerr); + errmsg += L"\n\n" + uuid; + ::MessageBoxW(nullptr, errmsg.c_str(), MOZ_APP_NAME " private_browsing.exe", + MB_OK | MB_ICONERROR | MB_SETFOREGROUND); + } else { + ::MessageBoxW(nullptr, uuid.c_str(), MOZ_APP_NAME " private_browsing.exe", + MB_OK | MB_ICONERROR | MB_SETFOREGROUND); + } +} + +/* + * A very simple wrapper that always launches Firefox in Private Browsing + * mode. Any arguments given to this program will be forwarded to Firefox, + * as well the information provided by GetStartupInfoW() (the latter is mainly + * done to ensure that Firefox's `launch_method` Telemetry works, which + * depends on shortcut information). + * + * Any errors that happen during this process will pop up a MessageBox + * with a Windows error (if present) and a unique UUID for debugability -- + * but these are very unlikely to be seen in practice. + */ +int WINAPI wWinMain(HINSTANCE, HINSTANCE, LPWSTR aCmdLine, int) { + wchar_t app[MAX_PATH]; + DWORD ret = GetModuleFileNameW(nullptr, app, MAX_PATH); + if (!ret || + (ret == MAX_PATH && ::GetLastError() == ERROR_INSUFFICIENT_BUFFER)) { + ret = ::GetLastError(); + raiseError(ret, ERR_GET_OUR_PATH); + return ret; + } + if (!PathRemoveFileSpecW(app)) { + raiseError(0, ERR_GET_APP_DIR); + return 1; + } + if (!PathAppendW(app, MOZ_APP_NAME L".exe")) { + raiseError(0, ERR_GET_APP_EXE); + return 1; + } + + std::wstring cmdLine(L"\""); + cmdLine += app; + cmdLine += L"\" -private-window"; + if (wcslen(aCmdLine) > 0) { + cmdLine += L" "; + cmdLine += aCmdLine; + } + DWORD creationFlags = CREATE_UNICODE_ENVIRONMENT; + // Mainly used to pass along shortcut information to ensure + // launch_method Telemetry will be accurate. + STARTUPINFOW startupInfo = {0}; + startupInfo.cb = sizeof(STARTUPINFOW); + GetStartupInfoW(&startupInfo); + PROCESS_INFORMATION pi; + + bool rv = + ::CreateProcessW(app, cmdLine.data(), nullptr, nullptr, FALSE, + creationFlags, nullptr, nullptr, &startupInfo, &pi); + + if (!rv) { + ret = ::GetLastError(); + raiseError(ret, ERR_LAUNCHING_APP); + return ret; + } + + ::CloseHandle(pi.hProcess); + ::CloseHandle(pi.hThread); + + return 0; +} |