From d768d99a05bb25d2b97bcdd3c08e887ae3a1c98d Mon Sep 17 00:00:00 2001 From: Jim Mathies Date: Tue, 18 Dec 2012 10:24:42 -0600 Subject: [PATCH] Bug 820200 - Pass application directory to XRE_InitEmbedding2 in content process. r=bsmedberg --- dom/ipc/ContentProcess.cpp | 6 ++++ dom/ipc/ContentProcess.h | 2 ++ ipc/glue/GeckoChildProcessHost.cpp | 51 ++++++++++++++++++++++++++++-- ipc/glue/ScopedXREEmbed.cpp | 18 ++++++++++- ipc/glue/ScopedXREEmbed.h | 6 ++++ toolkit/xre/nsEmbedFunctions.cpp | 17 +++++++--- 6 files changed, 93 insertions(+), 7 deletions(-) diff --git a/dom/ipc/ContentProcess.cpp b/dom/ipc/ContentProcess.cpp index 65e66a682aa7..455b9303ee17 100644 --- a/dom/ipc/ContentProcess.cpp +++ b/dom/ipc/ContentProcess.cpp @@ -13,6 +13,12 @@ using mozilla::ipc::IOThreadChild; namespace mozilla { namespace dom { +void +ContentProcess::SetAppDir(const nsACString& aPath) +{ + mXREEmbed.SetAppDir(aPath); +} + bool ContentProcess::Init() { diff --git a/dom/ipc/ContentProcess.h b/dom/ipc/ContentProcess.h index d30cb3ad6dff..57ae5a2f7552 100644 --- a/dom/ipc/ContentProcess.h +++ b/dom/ipc/ContentProcess.h @@ -36,6 +36,8 @@ public: virtual bool Init() MOZ_OVERRIDE; virtual void CleanUp() MOZ_OVERRIDE; + void SetAppDir(const nsACString& aPath); + private: ContentChild mContent; mozilla::ipc::ScopedXREEmbed mXREEmbed; diff --git a/ipc/glue/GeckoChildProcessHost.cpp b/ipc/glue/GeckoChildProcessHost.cpp index 18553295fe37..8c7e9886a8e0 100644 --- a/ipc/glue/GeckoChildProcessHost.cpp +++ b/ipc/glue/GeckoChildProcessHost.cpp @@ -410,6 +410,40 @@ GeckoChildProcessHost::PerformAsyncLaunch(std::vector aExtraOpts, b return retval; } +void +#if defined(XP_WIN) +AddAppDirToCommandLine(CommandLine& aCmdLine) +#else +AddAppDirToCommandLine(std::vector& aCmdLine) +#endif +{ + // Content processes need access to application resources, so pass + // the full application directory path to the child process. + if (ShouldHaveDirectoryService()) { + nsCOMPtr directoryService(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID)); + NS_ASSERTION(directoryService, "Expected XPCOM to be available"); + if (directoryService) { + nsCOMPtr appDir; + // NS_XPCOM_CURRENT_PROCESS_DIR really means the app dir, not the + // current process dir. + nsresult rv = directoryService->Get(NS_XPCOM_CURRENT_PROCESS_DIR, + NS_GET_IID(nsIFile), + getter_AddRefs(appDir)); + if (NS_SUCCEEDED(rv)) { + nsAutoCString path; + appDir->GetNativePath(path); +#if defined(XP_WIN) + aCmdLine.AppendLooseValue(UTF8ToWide("-appdir")); + aCmdLine.AppendLooseValue(UTF8ToWide(path.get())); +#else + aCmdLine.push_back("-appdir"); + aCmdLine.push_back(path.get()); +#endif + } + } + } +} + bool GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector& aExtraOpts, base::ProcessArchitecture arch) { @@ -575,6 +609,9 @@ GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector& aExt } } + // Add the application directory path (-appdir path) + AddAppDirToCommandLine(childArgv); + childArgv.push_back(pidstring); #if defined(MOZ_CRASHREPORTER) @@ -674,8 +711,6 @@ GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector& aExt cmdLine.AppendLooseValue(UTF8ToWide(*it)); } - cmdLine.AppendLooseValue(std::wstring(mGroupId.get())); - if (Omnijar::IsInitialized()) { // Make sure the child process can find the omnijar // See XRE_InitCommandLine in nsAppRunner.cpp @@ -692,6 +727,17 @@ GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector& aExt } } + // Add the application directory path (-appdir path) + AddAppDirToCommandLine(cmdLine); + + // XXX Command line params past this point are expected to be at + // the end of the command line string, and in a specific order. + // See XRE_InitChildProcess in nsEmbedFunction. + + // Win app model id + cmdLine.AppendLooseValue(std::wstring(mGroupId.get())); + + // Process id cmdLine.AppendLooseValue(UTF8ToWide(pidstring)); #if defined(MOZ_CRASHREPORTER) @@ -699,6 +745,7 @@ GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector& aExt UTF8ToWide(CrashReporter::GetChildNotificationPipe())); #endif + // Process type cmdLine.AppendLooseValue(UTF8ToWide(childProcessType)); base::LaunchApp(cmdLine, false, false, &process); diff --git a/ipc/glue/ScopedXREEmbed.cpp b/ipc/glue/ScopedXREEmbed.cpp index 6a6347631a9a..e3b8d377c606 100644 --- a/ipc/glue/ScopedXREEmbed.cpp +++ b/ipc/glue/ScopedXREEmbed.cpp @@ -28,6 +28,19 @@ ScopedXREEmbed::~ScopedXREEmbed() NS_LogTerm(); } +void +ScopedXREEmbed::SetAppDir(const nsACString& aPath) +{ + bool flag; + nsresult rv = + XRE_GetFileFromPath(aPath.BeginReading(), getter_AddRefs(mAppDir)); + if (NS_FAILED(rv) || + NS_FAILED(mAppDir->Exists(&flag)) || !flag) { + NS_WARNING("Invalid application directory passed to content process."); + mAppDir = nullptr; + } +} + void ScopedXREEmbed::Start() { @@ -80,7 +93,10 @@ ScopedXREEmbed::Start() } #endif - rv = XRE_InitEmbedding2(localFile, localFile, nullptr); + if (mAppDir) + rv = XRE_InitEmbedding2(localFile, mAppDir, nullptr); + else + rv = XRE_InitEmbedding2(localFile, localFile, nullptr); if (NS_FAILED(rv)) return; diff --git a/ipc/glue/ScopedXREEmbed.h b/ipc/glue/ScopedXREEmbed.h index ca23de9a3ec9..5b4f88d0c320 100644 --- a/ipc/glue/ScopedXREEmbed.h +++ b/ipc/glue/ScopedXREEmbed.h @@ -5,6 +5,10 @@ #ifndef __IPC_GLUE_SCOPEDXREEMBED_H__ #define __IPC_GLUE_SCOPEDXREEMBED_H__ +#include "nsString.h" +#include "nsAutoPtr.h" +#include "nsIFile.h" + namespace mozilla { namespace ipc { @@ -16,9 +20,11 @@ public: void Start(); void Stop(); + void SetAppDir(const nsACString& aPath); private: bool mShouldKillEmbedding; + nsCOMPtr mAppDir; }; } /* namespace ipc */ diff --git a/toolkit/xre/nsEmbedFunctions.cpp b/toolkit/xre/nsEmbedFunctions.cpp index ce1480e41045..fd3b130eeaad 100644 --- a/toolkit/xre/nsEmbedFunctions.cpp +++ b/toolkit/xre/nsEmbedFunctions.cpp @@ -403,8 +403,7 @@ XRE_InitChildProcess(int aArgc, // On Win7+, register the application user model id passed in by // parent. This insures windows created by the container properly // group with the parent app on the Win7 taskbar. - const char* const appModelUserId = aArgv[aArgc-1]; - --aArgc; + const char* const appModelUserId = aArgv[--aArgc]; if (appModelUserId) { // '-' implies no support if (*appModelUserId != '-') { @@ -460,8 +459,18 @@ XRE_InitChildProcess(int aArgc, process = new PluginProcessChild(parentHandle); break; - case GeckoProcessType_Content: - process = new ContentProcess(parentHandle); + case GeckoProcessType_Content: { + process = new ContentProcess(parentHandle); + // If passed in grab the application path for xpcom init + nsCString appDir; + for (int idx = aArgc; idx > 0; idx--) { + if (aArgv[idx] && !strcmp(aArgv[idx], "-appdir")) { + appDir.Assign(nsDependentCString(aArgv[idx+1])); + static_cast(process.get())->SetAppDir(appDir); + break; + } + } + } break; case GeckoProcessType_IPDLUnitTest: