1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 : * vim: sw=4 ts=4 et :
3 : * ***** BEGIN LICENSE BLOCK *****
4 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 : *
6 : * The contents of this file are subject to the Mozilla Public License Version
7 : * 1.1 (the "License"); you may not use this file except in compliance with
8 : * the License. You may obtain a copy of the License at
9 : * http://www.mozilla.org/MPL/
10 : *
11 : * Software distributed under the License is distributed on an "AS IS" basis,
12 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 : * for the specific language governing rights and limitations under the
14 : * License.
15 : *
16 : * The Original Code is Mozilla Plugin App.
17 : *
18 : * The Initial Developer of the Original Code is
19 : * Ben Turner <bent.mozilla@gmail.com>.
20 : * Portions created by the Initial Developer are Copyright (C) 2009
21 : * the Initial Developer. All Rights Reserved.
22 : *
23 : * Contributor(s):
24 : * Chris Jones <jones.chris.g@gmail.com>
25 : *
26 : * Alternatively, the contents of this file may be used under the terms of
27 : * either the GNU General Public License Version 2 or later (the "GPL"), or
28 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 : * in which case the provisions of the GPL or the LGPL are applicable instead
30 : * of those above. If you wish to allow use of your version of this file only
31 : * under the terms of either the GPL or the LGPL, and not to allow others to
32 : * use your version of this file under the terms of the MPL, indicate your
33 : * decision by deleting the provisions above and replace them with the notice
34 : * and other provisions required by the GPL or the LGPL. If you do not delete
35 : * the provisions above, a recipient may use your version of this file under
36 : * the terms of any one of the MPL, the GPL or the LGPL.
37 : *
38 : * ***** END LICENSE BLOCK ***** */
39 :
40 : #include "mozilla/ipc/IOThreadChild.h"
41 : #include "mozilla/plugins/PluginProcessChild.h"
42 :
43 : #include "prlink.h"
44 :
45 : #include "base/command_line.h"
46 : #include "base/string_util.h"
47 : #include "chrome/common/chrome_switches.h"
48 :
49 : #ifdef XP_WIN
50 : #include <objbase.h>
51 : #endif
52 :
53 : using mozilla::ipc::IOThreadChild;
54 :
55 : #ifdef OS_WIN
56 : #include "nsSetDllDirectory.h"
57 : #include <algorithm>
58 :
59 : namespace {
60 :
61 : std::size_t caseInsensitiveFind(std::string aHaystack, std::string aNeedle) {
62 : std::transform(aHaystack.begin(), aHaystack.end(), aHaystack.begin(), ::tolower);
63 : std::transform(aNeedle.begin(), aNeedle.end(), aNeedle.begin(), ::tolower);
64 : return aHaystack.find(aNeedle);
65 : }
66 :
67 : }
68 : #endif
69 :
70 : namespace mozilla {
71 : namespace plugins {
72 :
73 : bool
74 0 : PluginProcessChild::Init()
75 : {
76 : #if defined(XP_MACOSX)
77 : // Remove the trigger for "dyld interposing" that we added in
78 : // GeckoChildProcessHost::PerformAsyncLaunchInternal(), in the host
79 : // process just before we were launched. Dyld interposing will still
80 : // happen in our process (the plugin child process). But we don't want
81 : // it to happen in any processes that the plugin might launch from our
82 : // process.
83 : nsCString interpose(PR_GetEnv("DYLD_INSERT_LIBRARIES"));
84 : if (!interpose.IsEmpty()) {
85 : // If we added the path to libplugin_child_interpose.dylib to an
86 : // existing DYLD_INSERT_LIBRARIES, we appended it to the end, after a
87 : // ":" path seperator.
88 : PRInt32 lastSeparatorPos = interpose.RFind(":");
89 : PRInt32 lastTriggerPos = interpose.RFind("libplugin_child_interpose.dylib");
90 : bool needsReset = false;
91 : if (lastTriggerPos != -1) {
92 : if (lastSeparatorPos == -1) {
93 : interpose.Truncate();
94 : needsReset = true;
95 : } else if (lastTriggerPos > lastSeparatorPos) {
96 : interpose.SetLength(lastSeparatorPos);
97 : needsReset = true;
98 : }
99 : }
100 : if (needsReset) {
101 : nsCString setInterpose("DYLD_INSERT_LIBRARIES=");
102 : if (!interpose.IsEmpty()) {
103 : setInterpose.Append(interpose);
104 : }
105 : // Values passed to PR_SetEnv() must be seperately allocated.
106 : char* setInterposePtr = strdup(PromiseFlatCString(setInterpose).get());
107 : PR_SetEnv(setInterposePtr);
108 : }
109 : }
110 : #endif
111 :
112 : #ifdef XP_WIN
113 : // Drag-and-drop needs OleInitialize to be called, and Silverlight depends
114 : // on the host calling CoInitialize (which is called by OleInitialize).
115 : ::OleInitialize(NULL);
116 : #endif
117 :
118 : // Certain plugins, such as flash, steal the unhandled exception filter
119 : // thus we never get crash reports when they fault. This call fixes it.
120 0 : message_loop()->set_exception_restoration(true);
121 :
122 0 : std::string pluginFilename;
123 :
124 : #if defined(OS_POSIX)
125 : // NB: need to be very careful in ensuring that the first arg
126 : // (after the binary name) here is indeed the plugin module path.
127 : // Keep in sync with dom/plugins/PluginModuleParent.
128 0 : std::vector<std::string> values = CommandLine::ForCurrentProcess()->argv();
129 0 : NS_ABORT_IF_FALSE(values.size() >= 2, "not enough args");
130 :
131 0 : pluginFilename = UnmungePluginDsoPath(values[1]);
132 :
133 : #elif defined(OS_WIN)
134 : std::vector<std::wstring> values =
135 : CommandLine::ForCurrentProcess()->GetLooseValues();
136 : NS_ABORT_IF_FALSE(values.size() >= 1, "not enough loose args");
137 :
138 : pluginFilename = WideToUTF8(values[0]);
139 :
140 : bool protectCurrentDirectory = true;
141 : // Don't use SetDllDirectory for Shockwave Director
142 : const std::string shockwaveDirectorPluginFilename("\\np32dsw.dll");
143 : std::size_t index = caseInsensitiveFind(pluginFilename, shockwaveDirectorPluginFilename);
144 : if (index != std::string::npos &&
145 : index + shockwaveDirectorPluginFilename.length() == pluginFilename.length()) {
146 : protectCurrentDirectory = false;
147 : }
148 : if (protectCurrentDirectory) {
149 : SanitizeEnvironmentVariables();
150 : SetDllDirectory(L"");
151 : }
152 :
153 : #else
154 : # error Sorry
155 : #endif
156 :
157 0 : if (NS_FAILED(nsRegion::InitStatic())) {
158 0 : NS_ERROR("Could not initialize nsRegion");
159 0 : return false;
160 : }
161 :
162 : mPlugin.Init(pluginFilename, ParentHandle(),
163 : IOThreadChild::message_loop(),
164 0 : IOThreadChild::channel());
165 :
166 0 : return true;
167 : }
168 :
169 : void
170 0 : PluginProcessChild::CleanUp()
171 : {
172 : #ifdef XP_WIN
173 : ::OleUninitialize();
174 : #endif
175 0 : nsRegion::ShutdownStatic();
176 0 : }
177 :
178 : } // namespace plugins
179 : } // namespace mozilla
|