Files
palemoon27/toolkit/xre/nsWindowsRestart.cpp
roytam1 ca069b707a import changes from `dev' branch of rmottola/Arctic-Fox:
- Bug 1244228 - fix DrawTargetSkia::OptimizeSourceSurface to still create Skia surfaces for GPU canvases even if creating a GPU surface failed. r=jmuizelaar (fbc02e4dc2)
- Bug 1259621 - use AlphaBoxBlur in DrawTargetSkia::DrawSurfaceWithShadow. r=mchang (2c9df0d317)
- Bug 1257717 - throw InvalidStateError when CreatePattern fails to snapshot source. r=jrmuizel (95fc5c4101)
- Bug 1264246 - verify that SkCanvas::getClipBounds succeeds before using result. r=mchang (20de1e897d)
- Bug 1249033 - Enable Subpixel AA Text on Skia for Dwrite and GDI Fonts. r=jrmuizel (f7402a4c9d)
- Bug 1250787 - ensure that subpixel text is disabled for Skia's Cairo font host so that font rendering matches our font metrics. r=mchang (4d77670f3f)
- Bug 1260454. Disable LCD font smoothing if we have grayscale AA on OS X. r=lsalzman (44bf859df5)
- bug 1263685 - Check if paint has a shader before modifying local matrix in DrawTargetSkia::MaskSurface. r=mchang (7937265238)
- missing bit for bump version (e3b14b6854)
- Bug 1252650 - Add data parameter to NS_CreateServicesFromCategory; r=froydnj (3a3d392669)
- Bug 1252650 - char16_t*/char16ptr_t mismatch fixup. (66d4bb1d1b)
- Bug 1261382 - Add ReadUntil method to Tokenizer r=mayhemer (3c0b05a359)
- Bug 1242963 - nsID stringification helper for logging; r=froydnj (966c73478a)
- Bug 1262400 - remove outer pointers from nsCreateInstance* classes; r=erahm (16680909c0)
- Bug 1257331 - Use LPWSTR instead of LPVOID to prevent C4477 warning; r=froydnj (456b677e25)
- bits of Bug 868814 - Fold mozallo (3580f23f5a)
- Bug 1256027 - Cast a few things in varargs to the expected types for MSVC 2015 warning-compatibility. r=froydnj (6e3e5f1763)
- Bug 1257262 - Removed invalid nsAString:Assign variant. r=bsmedberg (1f4b303f7a)
- bug 761909 - crash reporter plumbing for gonk. r=bsmedberg (e27b276147)
- Bug 1223800 - Accept BHR reports from 50% of beta clients. Up from 1%. r=vladan (fb67094a56)
- Bug 1241507 - Enable BHR reporting on 100% of the Beta population. r=rvitillo (6b0abc7767)
- Bug 1234618. Fix misdetected BHR hangs. r=jchen (4adc7d57a1)
- bits of Bug 1128768: Part 2 - Refactor (f75559fe5b)
- Bug 1168167 - Mark LazyIdleThread::mIdleObserver with MOZ_UNSAFE_REF. r=froydnj (9750c9686d)
- Bug 1250829 - add customized assertions for completion promises to facilitate promise chaining. r=bobbyholley. (66fe29ec68)
- Bug 1191063 - Followup comments. r=me DONTBUILD (a627c0bb62)
- bits of Bug 1172769 (6ce96f8829)
- Bug 1241656 - Lazify AutoTaskDispatcher::mDirectTasks. r=bholley. (48fab6f3fb)
- Bug 1202667 - make TaskQueue dispatching slightly more efficient; r=mccr8 (0c9f19fae5)
- Bug 1202667 - make TaskQueue task running slightly more efficient; r=mccr8 (cee8821a9f)
- Bug 1207031 - Suppress -Wshadow warnings from google-breakpad headers in xpcom/threads. r=froydnj (e2426fcf8a)
- Bug 1222101 - Reorder some thread code (r=jld) a=kwierso (4b816f501e)
- Bug 1257862 - Allow running things from the delayed work queue during a nested event loop. r=khuey,dvander (066ce6ab76)
- Bug 1236789. Part 2 - fix assertions when |aFlags == NS_DISPATCH_TAIL|. r=bholley (d6500cceb0)
- Bug 1254218 - Rely on old-configure.in to detect dladdr(). r=njn (8beefa2792)
- Bug 1257786 - Proper init of LogModule for Nuwa r=khuey (5170b5250b)
- Bug 1236108: Add support for exception-context annotations for content processes to the crash reporter; r=bsmedberg (3441aa3773)
- Bug 1256541: Fix incorrect generation of path for child process .extra files when content sandboxing is disabled; r=bsmedberg (ae8ba562ca)
- bug 1264242 - Write memory info streams for Windows Minidumps of child processes. r=bsmedberg (245b797566)
- Bug 1257486 - Annotate global memory status in the crash reporter for child process; r=bsmedberg (9af844a7dd)
- Bug 1257209 - record uptime in crash metadata/pings, r=gfritzsche (bfe0ea8759)
- Bug 1241613 - Only pass MOZ_BUILDID to the one source that requires it in toolkit/xre. r=mshal (944abe034f)
- Bug 1255655 - Heap-allocate _progname. r=froydnj. (3cce05ccaa)
- Bug 828704: Avoid duplicate -foreground argument when launching Firefox on OSX. r=mstange (2e5c12bdda)
- bug 1166759 - force annotateCrashReport arguments to be UTF-8. r=bsmedberg (5f2c30676a)
- Bug 1261751 - Problems with OS X Sandboxed TempDir and Rules. r=bobowen r=gcp (9ad9272b92)
2024-07-17 22:13:12 +08:00

301 lines
7.3 KiB
C++

/* 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/. */
// This file is not build directly. Instead, it is included in multiple
// shared objects.
#ifdef nsWindowsRestart_cpp
#error "nsWindowsRestart.cpp is not a header file, and must only be included once."
#else
#define nsWindowsRestart_cpp
#endif
#include "nsUTF8Utils.h"
#include <shellapi.h>
// Needed for CreateEnvironmentBlock
#include <userenv.h>
#pragma comment(lib, "userenv.lib")
/**
* Get the length that the string will take and takes into account the
* additional length if the string needs to be quoted and if characters need to
* be escaped.
*/
static int ArgStrLen(const wchar_t *s)
{
int backslashes = 0;
int i = wcslen(s);
BOOL hasDoubleQuote = wcschr(s, L'"') != nullptr;
// Only add doublequotes if the string contains a space or a tab
BOOL addDoubleQuotes = wcspbrk(s, L" \t") != nullptr;
if (addDoubleQuotes) {
i += 2; // initial and final duoblequote
}
if (hasDoubleQuote) {
while (*s) {
if (*s == '\\') {
++backslashes;
} else {
if (*s == '"') {
// Escape the doublequote and all backslashes preceding the doublequote
i += backslashes + 1;
}
backslashes = 0;
}
++s;
}
}
return i;
}
/**
* Copy string "s" to string "d", quoting the argument as appropriate and
* escaping doublequotes along with any backslashes that immediately precede
* doublequotes.
* The CRT parses this to retrieve the original argc/argv that we meant,
* see STDARGV.C in the MSVC CRT sources.
*
* @return the end of the string
*/
static wchar_t* ArgToString(wchar_t *d, const wchar_t *s)
{
int backslashes = 0;
BOOL hasDoubleQuote = wcschr(s, L'"') != nullptr;
// Only add doublequotes if the string contains a space or a tab
BOOL addDoubleQuotes = wcspbrk(s, L" \t") != nullptr;
if (addDoubleQuotes) {
*d = '"'; // initial doublequote
++d;
}
if (hasDoubleQuote) {
int i;
while (*s) {
if (*s == '\\') {
++backslashes;
} else {
if (*s == '"') {
// Escape the doublequote and all backslashes preceding the doublequote
for (i = 0; i <= backslashes; ++i) {
*d = '\\';
++d;
}
}
backslashes = 0;
}
*d = *s;
++d; ++s;
}
} else {
wcscpy(d, s);
d += wcslen(s);
}
if (addDoubleQuotes) {
*d = '"'; // final doublequote
++d;
}
return d;
}
/**
* Creates a command line from a list of arguments. The returned
* string is allocated with "malloc" and should be "free"d.
*
* argv is UTF8
*/
wchar_t*
MakeCommandLine(int argc, wchar_t **argv)
{
int i;
int len = 0;
// The + 1 of the last argument handles the allocation for null termination
for (i = 0; i < argc; ++i)
len += ArgStrLen(argv[i]) + 1;
// Protect against callers that pass 0 arguments
if (len == 0)
len = 1;
wchar_t *s = (wchar_t*) malloc(len * sizeof(wchar_t));
if (!s)
return nullptr;
wchar_t *c = s;
for (i = 0; i < argc; ++i) {
c = ArgToString(c, argv[i]);
if (i + 1 != argc) {
*c = ' ';
++c;
}
}
*c = '\0';
return s;
}
/**
* Convert UTF8 to UTF16 without using the normal XPCOM goop, which we
* can't link to updater.exe.
*/
static char16_t*
AllocConvertUTF8toUTF16(const char *arg)
{
// UTF16 can't be longer in units than UTF8
int len = strlen(arg);
char16_t *s = new char16_t[(len + 1) * sizeof(char16_t)];
if (!s)
return nullptr;
ConvertUTF8toUTF16 convert(s);
convert.write(arg, len);
convert.write_terminator();
return s;
}
static void
FreeAllocStrings(int argc, wchar_t **argv)
{
while (argc) {
--argc;
delete [] argv[argc];
}
delete [] argv;
}
/**
* Launch a child process with the specified arguments.
* @note argv[0] is ignored
* @note The form of this function that takes char **argv expects UTF-8
*/
BOOL
WinLaunchChild(const wchar_t *exePath,
int argc, wchar_t **argv,
HANDLE userToken = nullptr,
HANDLE *hProcess = nullptr);
BOOL
WinLaunchChild(const wchar_t *exePath,
int argc, char **argv,
HANDLE userToken,
HANDLE *hProcess)
{
wchar_t** argvConverted = new wchar_t*[argc];
if (!argvConverted)
return FALSE;
for (int i = 0; i < argc; ++i) {
argvConverted[i] = reinterpret_cast<wchar_t*>(AllocConvertUTF8toUTF16(argv[i]));
if (!argvConverted[i]) {
FreeAllocStrings(i, argvConverted);
return FALSE;
}
}
BOOL ok = WinLaunchChild(exePath, argc, argvConverted, userToken, hProcess);
FreeAllocStrings(argc, argvConverted);
return ok;
}
BOOL
WinLaunchChild(const wchar_t *exePath,
int argc,
wchar_t **argv,
HANDLE userToken,
HANDLE *hProcess)
{
wchar_t *cl;
BOOL ok;
cl = MakeCommandLine(argc, argv);
if (!cl) {
return FALSE;
}
STARTUPINFOW si = {0};
si.cb = sizeof(STARTUPINFOW);
si.lpDesktop = L"winsta0\\Default";
PROCESS_INFORMATION pi = {0};
if (userToken == nullptr) {
ok = CreateProcessW(exePath,
cl,
nullptr, // no special security attributes
nullptr, // no special thread attributes
FALSE, // don't inherit filehandles
0, // creation flags
nullptr, // inherit my environment
nullptr, // use my current directory
&si,
&pi);
} else {
// Create an environment block for the process we're about to start using
// the user's token.
LPVOID environmentBlock = nullptr;
if (!CreateEnvironmentBlock(&environmentBlock, userToken, TRUE)) {
environmentBlock = nullptr;
}
ok = CreateProcessAsUserW(userToken,
exePath,
cl,
nullptr, // no special security attributes
nullptr, // no special thread attributes
FALSE, // don't inherit filehandles
0, // creation flags
environmentBlock,
nullptr, // use my current directory
&si,
&pi);
if (environmentBlock) {
DestroyEnvironmentBlock(environmentBlock);
}
}
if (ok) {
if (hProcess) {
*hProcess = pi.hProcess; // the caller now owns the HANDLE
} else {
CloseHandle(pi.hProcess);
}
CloseHandle(pi.hThread);
} else {
LPVOID lpMsgBuf = nullptr;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
nullptr,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0,
nullptr);
wprintf(L"Error restarting: %s\n", lpMsgBuf ? static_cast<LPTSTR>(lpMsgBuf) : L"(null)");
if (lpMsgBuf)
LocalFree(lpMsgBuf);
}
free(cl);
return ok;
}