/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* 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"nsXULAppAPI.h" #include"mozilla/XREAppData.h" #include"XREChildData.h" #include"XREShellData.h" #include"application.ini.h" #include"mozilla/Bootstrap.h" #include"mozilla/ProcessType.h" #include"mozilla/RuntimeExceptionModule.h" #include"mozilla/ScopeExit.h" #include"BrowserDefines.h" #ifdefined(XP_WIN) # include <windows.h> # include <stdlib.h> #elifdefined(XP_UNIX) # include <sys/resource.h> # include <unistd.h> # include <fcntl.h> #endif
#ifdef XP_WIN # include "mozilla/PreXULSkeletonUI.h" # include "freestanding/SharedSection.h" # include "LauncherProcessWin.h" # include "mozilla/GeckoArgs.h" # include "mozilla/mscom/ProcessRuntime.h" # include "mozilla/WindowsDllBlocklist.h" # include "mozilla/WindowsDpiInitialization.h" # include "mozilla/WindowsProcessMitigations.h"
# define XRE_WANT_ENVIRON # include "nsWindowsWMain.cpp"
# define strcasecmp _stricmp # ifdef MOZ_SANDBOX # include "mozilla/sandboxing/SandboxInitialization.h" # include "mozilla/sandboxing/sandboxLogging.h" # endif #endif #include"BinaryPath.h"
#include"nsXPCOMPrivate.h"// for MAXPATHLEN and XPCOM_DLL
#ifdef MOZ_LINUX_32_SSE2_STARTUP_ERROR # include <cpuid.h> # include "mozilla/Unused.h"
staticbool IsSSE2Available() { // The rest of the app has been compiled to assume that SSE2 is present // unconditionally, so we can't use the normal copy of SSE.cpp here. // Since SSE.cpp caches the results and we need them only transiently, // instead of #including SSE.cpp here, let's just inline the specific check // that's needed. unsignedint level = 1u; unsignedint eax, ebx, ecx, edx; unsignedint bits = (1u << 26); unsignedint max = __get_cpuid_max(0, nullptr); if (level > max) { returnfalse;
}
__cpuid_count(level, 0, eax, ebx, ecx, edx); return (edx & bits) == bits;
}
staticconstchar sSSE2Message[] = "This browser version requires a processor with the SSE2 instruction " "set extension.\nYou may be able to obtain a version that does not " "require SSE2 from your Linux distribution.\n";
__attribute__((constructor)) staticvoid SSE2Check() { if (IsSSE2Available()) { return;
} // Using write() in order to avoid jemalloc-based buffering. Ignoring return // values, since there isn't much we could do on failure and there is no // point in trying to recover from errors.
MOZ_UNUSED(write(STDERR_FILENO, sSSE2Message, std::size(sSSE2Message) - 1)); // _exit() instead of exit() to avoid running the usual "at exit" code.
_exit(255);
} #endif
if (appDataFile && *appDataFile) {
config.appData = nullptr;
config.appDataPath = appDataFile;
} else { // no -app flag so we use the compiled-in app data
config.appData = &sAppData;
config.appDataPath = kDesktopFolder;
}
UniqueFreePtr<char> exePath = BinaryPath::Get(); if (!exePath) {
Output("Couldn't find the application directory.\n"); return NS_ERROR_FAILURE;
}
auto bootstrapResult =
mozilla::GetBootstrap(exePath.get(), aLibLoadingStrategy); if (bootstrapResult.isErr()) {
Output("Couldn't load XPCOM.\n"); return NS_ERROR_FAILURE;
}
gBootstrap = bootstrapResult.unwrap();
// This will set this thread as the main thread.
gBootstrap->NS_LogInit();
return NS_OK;
}
#ifdef HAS_DLL_BLOCKLIST // NB: This must be extern, as this value is checked elsewhere
uint32_t gBlocklistInitFlags = eDllBlocklistInitFlagDefault; #endif
#ifdefined(XP_UNIX) staticvoid ReserveDefaultFileDescriptors() { // Reserve the lower positions of the file descriptors to make sure // we don't reuse stdin/stdout/stderr in case they we closed // before launch. // Otherwise code explicitly writing to fd 1 or 2 might accidentally // write to something else, like in bug 1820896 where FD 1 is // reused for the X server display connection. int fd = open("/dev/null", O_RDONLY); for (int i = 0; i < 2; i++) {
mozilla::Unused << dup(fd);
}
} #endif
#ifdef MOZ_BROWSER_CAN_BE_CONTENTPROC if (argc > 1 && IsArg(argv[1], "contentproc")) { // Set the process type and gecko child id.
SetGeckoProcessType(argv[--argc]);
SetGeckoChildID(argv[--argc]);
# ifdefined(MOZ_ENABLE_FORKSERVER) if (GetGeckoProcessType() == GeckoProcessType_ForkServer) {
nsresult rv = InitXPCOMGlue(LibLoadingStrategy::NoReadAhead); if (NS_FAILED(rv)) { return 255;
}
// Run a fork server in this process, single thread. When it returns, it // means the fork server have been stopped or a new child process is // created. // // For the latter case, XRE_ForkServer() will return false, running in a // child process just forked from the fork server process. argc & argv // will be updated with the values passing from the chrome process, as // will GeckoProcessType and GeckoChildID. With the new values, this // function continues the reset of the code acting as a child process. if (gBootstrap->XRE_ForkServer(&argc, &argv)) { // Return from the fork server in the fork server process. // Stop the fork server. // InitXPCOMGlue calls NS_LogInit, so we need to balance it here.
gBootstrap->NS_LogTerm(); return 0;
}
} # endif
} #endif
// Register an external module to report on otherwise uncatchable exceptions. // Note that in child processes this must be called after Gecko process type // has been set.
CrashReporter::RegisterRuntimeExceptionModule();
// Make sure we unregister the runtime exception module before returning. auto unregisterRuntimeExceptionModule =
MakeScopeExit([] { CrashReporter::UnregisterRuntimeExceptionModule(); });
#ifdef MOZ_BROWSER_CAN_BE_CONTENTPROC // We are launching as a content process, delegate to the appropriate // main if (GetGeckoProcessType() != GeckoProcessType_Default) { # ifdefined(XP_WIN) && defined(MOZ_SANDBOX) // We need to set whether our process is supposed to have win32k locked down // from the command line setting before DllBlocklist_Initialize, // GetInitializedTargetServices and WindowsDpiInitialization.
Maybe<bool> win32kLockedDown =
mozilla::geckoargs::sWin32kLockedDown.Get(argc, argv); if (win32kLockedDown.isSome() && *win32kLockedDown) {
mozilla::SetWin32kLockedDownInPolicy();
} # endif
# ifdefined(XP_WIN) && defined(MOZ_SANDBOX) // We need to initialize the sandbox TargetServices before InitXPCOMGlue // because we might need the sandbox broker to give access to some files. if (IsSandboxedProcess() && !sandboxing::GetInitializedTargetServices()) {
Output("Failed to initialize the sandbox target services."); return 255;
} # endif # ifdefined(XP_WIN) // Ideally, we would be able to set our DPI awareness in // firefox.exe.manifest Unfortunately, that would cause Win32k calls when // user32.dll gets loaded, which would be incompatible with Win32k Lockdown // // MSDN says that it's allowed-but-not-recommended to initialize DPI // programatically, as long as it's done before any HWNDs are created. // Thus, we do it almost as soon as we possibly can
{ auto result = mozilla::WindowsDpiInitialization();
(void)result; // Ignore errors since some tools block DPI calls
} # endif
nsresult rv = InitXPCOMGlue(LibLoadingStrategy::NoReadAhead); if (NS_FAILED(rv)) { return 255;
}
XREChildData childData;
# ifdefined(XP_WIN) && defined(MOZ_SANDBOX) if (IsSandboxedProcess()) {
childData.sandboxTargetServices =
mozilla::sandboxing::GetInitializedTargetServices(); if (!childData.sandboxTargetServices) { return 1;
}
// We will likely only ever support this as a command line argument on Windows // and OSX, so we're ifdefing here just to not create any expectations. #ifdefined(XP_WIN) || defined(XP_MACOSX) if (argc > 1 && IsArg(argv[1], "silentmode")) {
::putenv(const_cast<char*>("MOZ_APP_SILENT_START=1")); # ifdefined(XP_WIN) // On windows We also want to set a separate variable, which we want to // persist across restarts, which will let us keep the process alive // even if the last window is closed.
::putenv(const_cast<char*>("MOZ_APP_ALLOW_WINDOWLESS=1")); # endif # ifdefined(XP_MACOSX)
::putenv(const_cast<char*>("MOZ_APP_NO_DOCK=1")); # endif
} #endif
#ifdefined(XP_WIN)
// Ideally, we would be able to set our DPI awareness in firefox.exe.manifest // Unfortunately, that would cause Win32k calls when user32.dll gets loaded, // which would be incompatible with Win32k Lockdown // // MSDN says that it's allowed-but-not-recommended to initialize DPI // programatically, as long as it's done before any HWNDs are created. // Thus, we do it almost as soon as we possibly can
{ auto result = mozilla::WindowsDpiInitialization();
(void)result; // Ignore errors since some tools block DPI calls
}
// Once the browser process hits the main function, we no longer need // a writable section handle because all dependent modules have been // loaded.
mozilla::freestanding::gSharedSection.ConvertToReadOnly();
#ifdef XP_MACOSX // Allow writes again. While we would like to catch writes from static // destructors to allow early exits to use _exit, we know that there is // at least one such write that we don't control (see bug 826029). For // now we enable writes again and early exits will have to use exit instead // of _exit.
gBootstrap->XRE_StopLateWriteChecks(); #endif
gBootstrap.reset();
return result;
}
¤ Dauer der Verarbeitung: 0.2 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.