blob: f28d31a83f7dfa3748c43d429ebba625fe7bbf91 [file] [log] [blame]
[email protected]4bdde602010-06-16 03:17:351// Copyright (c) 2010 The Chromium Authors. All rights reserved.
[email protected]d032f492009-09-29 00:33:462// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "build/build_config.h"
6
[email protected]e15a4fa2010-02-11 23:09:297#include "chrome/browser/nacl_host/nacl_process_host.h"
[email protected]d032f492009-09-29 00:33:468
9#if defined(OS_POSIX)
10#include <fcntl.h>
11#endif
12
[email protected]103607e2010-02-01 18:57:0913#include "base/command_line.h"
[email protected]d032f492009-09-29 00:33:4614#include "chrome/browser/renderer_host/resource_message_filter.h"
[email protected]d032f492009-09-29 00:33:4615#include "chrome/common/chrome_switches.h"
16#include "chrome/common/logging_chrome.h"
[email protected]103607e2010-02-01 18:57:0917#include "chrome/common/nacl_cmd_line.h"
[email protected]d032f492009-09-29 00:33:4618#include "chrome/common/nacl_messages.h"
[email protected]fb1277e82009-11-21 20:32:3019#include "chrome/common/render_messages.h"
[email protected]d032f492009-09-29 00:33:4620#include "ipc/ipc_switches.h"
21
[email protected]d032f492009-09-29 00:33:4622#if defined(OS_POSIX)
23#include "ipc/ipc_channel_posix.h"
[email protected]4bdde602010-06-16 03:17:3524#elif defined(OS_WIN)
25#include "chrome/browser/nacl_host/nacl_broker_service_win.h"
[email protected]d032f492009-09-29 00:33:4626#endif
27
28NaClProcessHost::NaClProcessHost(
[email protected]f08e47d2009-10-15 21:46:1529 ResourceDispatcherHost *resource_dispatcher_host,
30 const std::wstring& url)
[email protected]103607e2010-02-01 18:57:0931 : ChildProcessHost(NACL_LOADER_PROCESS, resource_dispatcher_host),
[email protected]fb1277e82009-11-21 20:32:3032 resource_dispatcher_host_(resource_dispatcher_host),
33 reply_msg_(NULL),
[email protected]103607e2010-02-01 18:57:0934 descriptor_(0),
35 running_on_wow64_(false) {
[email protected]f08e47d2009-10-15 21:46:1536 set_name(url);
[email protected]103607e2010-02-01 18:57:0937#if defined(OS_WIN)
38 CheckIsWow64();
39#endif
[email protected]d032f492009-09-29 00:33:4640}
41
[email protected]fb1277e82009-11-21 20:32:3042NaClProcessHost::~NaClProcessHost() {
43 if (!reply_msg_)
44 return;
45
46 // OnProcessLaunched didn't get called because the process couldn't launch.
47 // Don't keep the renderer hanging.
48 reply_msg_->set_reply_error();
49 resource_message_filter_->Send(reply_msg_);
50}
51
52bool NaClProcessHost::Launch(ResourceMessageFilter* resource_message_filter,
[email protected]d032f492009-09-29 00:33:4653 const int descriptor,
[email protected]fb1277e82009-11-21 20:32:3054 IPC::Message* reply_msg) {
[email protected]d8c7cbcc2009-10-02 19:00:3155#ifdef DISABLE_NACL
56 NOTIMPLEMENTED() << "Native Client disabled at build time";
57 return false;
58#else
[email protected]d032f492009-09-29 00:33:4659 // Create a connected socket
[email protected]fb1277e82009-11-21 20:32:3060 if (nacl::SocketPair(pair_) == -1)
[email protected]d032f492009-09-29 00:33:4661 return false;
[email protected]d032f492009-09-29 00:33:4662
63 // Launch the process
[email protected]fb1277e82009-11-21 20:32:3064 descriptor_ = descriptor;
65 if (!LaunchSelLdr()) {
66 nacl::Close(pair_[0]);
[email protected]d032f492009-09-29 00:33:4667 return false;
68 }
69
[email protected]fb1277e82009-11-21 20:32:3070 resource_message_filter_ = resource_message_filter;
71 reply_msg_ = reply_msg;
[email protected]f08e47d2009-10-15 21:46:1572
[email protected]d032f492009-09-29 00:33:4673 return true;
[email protected]d8c7cbcc2009-10-02 19:00:3174#endif // DISABLE_NACL
[email protected]d032f492009-09-29 00:33:4675}
76
[email protected]fb1277e82009-11-21 20:32:3077bool NaClProcessHost::LaunchSelLdr() {
[email protected]d032f492009-09-29 00:33:4678 if (!CreateChannel())
79 return false;
80
81 // Build command line for nacl.
[email protected]7c4ea142010-01-26 05:15:4282 FilePath exe_path = GetChildPath(true);
[email protected]fb1277e82009-11-21 20:32:3083 if (exe_path.empty())
[email protected]d032f492009-09-29 00:33:4684 return false;
85
[email protected]fb1277e82009-11-21 20:32:3086 CommandLine* cmd_line = new CommandLine(exe_path);
[email protected]103607e2010-02-01 18:57:0987 nacl::CopyNaClCommandLineArguments(cmd_line);
[email protected]599e6642010-01-27 18:52:1388
[email protected]fb1277e82009-11-21 20:32:3089 cmd_line->AppendSwitchWithValue(switches::kProcessType,
[email protected]103607e2010-02-01 18:57:0990 switches::kNaClLoaderProcess);
[email protected]d032f492009-09-29 00:33:4691
[email protected]fb1277e82009-11-21 20:32:3092 cmd_line->AppendSwitchWithValue(switches::kProcessChannelID,
93 ASCIIToWide(channel_id()));
[email protected]d032f492009-09-29 00:33:4694
[email protected]103607e2010-02-01 18:57:0995 // On Windows we might need to start the broker process to launch a new loader
[email protected]d032f492009-09-29 00:33:4696#if defined(OS_WIN)
[email protected]103607e2010-02-01 18:57:0997 if (running_on_wow64_) {
98 NaClBrokerService::GetInstance()->Init(resource_dispatcher_host_);
[email protected]2a4d7542010-03-17 02:06:3399 return NaClBrokerService::GetInstance()->LaunchLoader(this,
100 ASCIIToWide(channel_id()));
[email protected]4bdde602010-06-16 03:17:35101 } else {
102 ChildProcessHost::Launch(FilePath(), cmd_line);
103 }
[email protected]103607e2010-02-01 18:57:09104#elif defined(OS_POSIX)
[email protected]4bdde602010-06-16 03:17:35105 ChildProcessHost::Launch(true, // use_zygote
106 base::environment_vector(),
107 cmd_line);
[email protected]103607e2010-02-01 18:57:09108#endif
[email protected]d032f492009-09-29 00:33:46109
[email protected]fb1277e82009-11-21 20:32:30110 return true;
[email protected]d032f492009-09-29 00:33:46111}
112
[email protected]103607e2010-02-01 18:57:09113void NaClProcessHost::OnProcessLaunchedByBroker(base::ProcessHandle handle) {
114 set_handle(handle);
115 OnProcessLaunched();
116}
117
[email protected]cd69619b2010-05-05 02:41:38118bool NaClProcessHost::DidChildCrash() {
119 if (running_on_wow64_)
120 return base::DidProcessCrash(NULL, handle());
121 return ChildProcessHost::DidChildCrash();
[email protected]103607e2010-02-01 18:57:09122}
123
[email protected]16e70ae2010-03-08 21:41:28124void NaClProcessHost::OnChildDied() {
125#if defined(OS_WIN)
126 NaClBrokerService::GetInstance()->OnLoaderDied();
127#endif
128 ChildProcessHost::OnChildDied();
129}
130
[email protected]fb1277e82009-11-21 20:32:30131void NaClProcessHost::OnProcessLaunched() {
132 nacl::FileDescriptor imc_handle;
133 base::ProcessHandle nacl_process_handle;
[email protected]16e70ae2010-03-08 21:41:28134#if defined(OS_WIN)
[email protected]fb1277e82009-11-21 20:32:30135 // Duplicate the IMC handle
[email protected]103607e2010-02-01 18:57:09136 // We assume the size of imc_handle has the same size as HANDLE, so the cast
137 // below is safe.
138 DCHECK(sizeof(HANDLE) == sizeof(imc_handle));
[email protected]fb1277e82009-11-21 20:32:30139 DuplicateHandle(base::GetCurrentProcessHandle(),
140 reinterpret_cast<HANDLE>(pair_[0]),
141 resource_message_filter_->handle(),
[email protected]103607e2010-02-01 18:57:09142 reinterpret_cast<HANDLE*>(&imc_handle),
[email protected]fb1277e82009-11-21 20:32:30143 GENERIC_READ | GENERIC_WRITE,
144 FALSE,
145 DUPLICATE_CLOSE_SOURCE);
146
147 // Duplicate the process handle
148 DuplicateHandle(base::GetCurrentProcessHandle(),
149 handle(),
150 resource_message_filter_->handle(),
151 &nacl_process_handle,
152 PROCESS_DUP_HANDLE,
153 FALSE,
154 0);
[email protected]fb1277e82009-11-21 20:32:30155#else
156 int flags = fcntl(pair_[0], F_GETFD);
157 if (flags != -1) {
158 flags |= FD_CLOEXEC;
159 fcntl(pair_[0], F_SETFD, flags);
160 }
161 // No need to dup the imc_handle - we don't pass it anywhere else so
162 // it cannot be closed.
163 imc_handle.fd = pair_[0];
164 imc_handle.auto_close = true;
165
166 // We use pid as process handle on Posix
167 nacl_process_handle = handle();
[email protected]fb1277e82009-11-21 20:32:30168#endif
169
170 // Get the pid of the NaCl process
171 base::ProcessId nacl_process_id = base::GetProcId(handle());
172
173 ViewHostMsg_LaunchNaCl::WriteReplyParams(
174 reply_msg_, imc_handle, nacl_process_handle, nacl_process_id);
175 resource_message_filter_->Send(reply_msg_);
176 resource_message_filter_ = NULL;
177 reply_msg_ = NULL;
178
179 SendStartMessage();
180}
181
182void NaClProcessHost::SendStartMessage() {
[email protected]d032f492009-09-29 00:33:46183 nacl::FileDescriptor channel;
184#if defined(OS_WIN)
185 if (!DuplicateHandle(GetCurrentProcess(),
[email protected]fb1277e82009-11-21 20:32:30186 reinterpret_cast<HANDLE>(pair_[1]),
187 handle(),
[email protected]d032f492009-09-29 00:33:46188 reinterpret_cast<HANDLE*>(&channel),
189 GENERIC_READ | GENERIC_WRITE,
190 FALSE, DUPLICATE_CLOSE_SOURCE)) {
[email protected]fb1277e82009-11-21 20:32:30191 return;
[email protected]d032f492009-09-29 00:33:46192 }
193#else
[email protected]fb1277e82009-11-21 20:32:30194 channel.fd = dup(pair_[1]);
[email protected]d032f492009-09-29 00:33:46195 channel.auto_close = true;
196#endif
[email protected]fb1277e82009-11-21 20:32:30197 Send(new NaClProcessMsg_Start(descriptor_, channel));
[email protected]d032f492009-09-29 00:33:46198}
199
200void NaClProcessHost::OnMessageReceived(const IPC::Message& msg) {
201 NOTREACHED() << "Invalid message with type = " << msg.type();
202}
203
204URLRequestContext* NaClProcessHost::GetRequestContext(
205 uint32 request_id,
206 const ViewHostMsg_Resource_Request& request_data) {
207 return NULL;
208}
[email protected]103607e2010-02-01 18:57:09209
210#if defined(OS_WIN)
211// TODO(gregoryd): invoke CheckIsWow64 only once, not for each NaClProcessHost
212typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
213void NaClProcessHost::CheckIsWow64() {
214 LPFN_ISWOW64PROCESS fnIsWow64Process;
215
216 fnIsWow64Process = (LPFN_ISWOW64PROCESS) GetProcAddress(
217 GetModuleHandle(TEXT("kernel32")),
218 "IsWow64Process");
219
220 if (fnIsWow64Process != NULL) {
221 BOOL bIsWow64 = FALSE;
222 if (fnIsWow64Process(GetCurrentProcess(),&bIsWow64)) {
223 if (bIsWow64) {
224 running_on_wow64_ = true;
225 }
226 }
227 }
228}
229#endif