summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/app/chrome_dll_main.cc10
-rw-r--r--chrome/app/client_util.cc16
-rw-r--r--chrome/app/dummy_main_functions.cc4
-rw-r--r--chrome/browser/memory_details.cc2
-rw-r--r--chrome/browser/nacl_host/nacl_broker_host.cc74
-rw-r--r--chrome/browser/nacl_host/nacl_broker_host.h46
-rw-r--r--chrome/browser/nacl_host/nacl_broker_service.cc69
-rw-r--r--chrome/browser/nacl_host/nacl_broker_service.h57
-rw-r--r--chrome/browser/nacl_process_host.cc110
-rw-r--r--chrome/browser/nacl_process_host.h13
-rwxr-xr-xchrome/chrome_browser.gypi5
-rw-r--r--chrome/chrome_common.gypi3
-rw-r--r--chrome/common/child_process_host.cc8
-rw-r--r--chrome/common/child_process_host.h2
-rw-r--r--chrome/common/child_process_info.cc4
-rw-r--r--chrome/common/child_process_info.h3
-rw-r--r--chrome/common/chrome_constants.cc1
-rw-r--r--chrome/common/chrome_constants.h1
-rw-r--r--chrome/common/chrome_switches.cc8
-rw-r--r--chrome/common/chrome_switches.h3
-rw-r--r--chrome/common/nacl_cmd_line.cc44
-rw-r--r--chrome/common/nacl_cmd_line.h16
-rw-r--r--chrome/common/nacl_messages_internal.h11
-rw-r--r--chrome/common/nacl_types.h20
-rw-r--r--chrome/common/sandbox_init_wrapper_mac.cc2
-rw-r--r--chrome/common/sandbox_init_wrapper_win.cc2
-rw-r--r--chrome/common/sandbox_policy.cc20
-rw-r--r--chrome/installer/util/util_constants.cc1
-rw-r--r--chrome/installer/util/util_constants.h1
-rw-r--r--chrome/nacl.gypi4
-rw-r--r--chrome/nacl/broker_thread.cc72
-rw-r--r--chrome/nacl/broker_thread.h37
-rw-r--r--chrome/nacl/nacl_main.cc67
-rw-r--r--chrome/nacl/nacl_thread.cc2
-rw-r--r--chrome/nacl/nacl_thread.h2
-rw-r--r--chrome/renderer/render_process.cc2
36 files changed, 665 insertions, 77 deletions
diff --git a/chrome/app/chrome_dll_main.cc b/chrome/app/chrome_dll_main.cc
index 1e3cb83..1603d32 100644
--- a/chrome/app/chrome_dll_main.cc
+++ b/chrome/app/chrome_dll_main.cc
@@ -93,7 +93,7 @@ extern int NaClMain(const MainFunctionParams&);
extern int UtilityMain(const MainFunctionParams&);
extern int ProfileImportMain(const MainFunctionParams&);
extern int ZygoteMain(const MainFunctionParams&);
-#ifdef NACL_WIN64
+#if defined(_WIN64)
extern int NaClBrokerMain(const MainFunctionParams&);
#endif
@@ -261,7 +261,7 @@ static void AdjustLinuxOOMScore(const std::string& process_type) {
} else if (process_type == switches::kProfileImportProcess) {
NOTIMPLEMENTED();
#ifndef DISABLE_NACL
- } else if (process_type == switches::kNaClProcess) {
+ } else if (process_type == switches::kNaClLoaderProcess) {
score = kPluginScore;
#endif
} else if (process_type == switches::kZygoteProcess ||
@@ -686,9 +686,13 @@ int ChromeMain(int argc, char** argv) {
} else if (process_type == switches::kWorkerProcess) {
rv = WorkerMain(main_params);
#ifndef DISABLE_NACL
- } else if (process_type == switches::kNaClProcess) {
+ } else if (process_type == switches::kNaClLoaderProcess) {
rv = NaClMain(main_params);
#endif
+#ifdef _WIN64 // The broker process is used only on Win64.
+ } else if (process_type == switches::kNaClBrokerProcess) {
+ rv = NaClBrokerMain(main_params);
+#endif
} else if (process_type == switches::kZygoteProcess) {
#if defined(OS_LINUX)
if (ZygoteMain(main_params)) {
diff --git a/chrome/app/client_util.cc b/chrome/app/client_util.cc
index 993f468..a4bc50b 100644
--- a/chrome/app/client_util.cc
+++ b/chrome/app/client_util.cc
@@ -7,6 +7,7 @@
#include "chrome/app/breakpad_win.h"
#include "chrome/app/client_util.h"
+#include "chrome/common/chrome_switches.h"
#include "chrome/common/result_codes.h"
#include "chrome/installer/util/browser_distribution.h"
#include "chrome/installer/util/install_util.h"
@@ -83,7 +84,22 @@ bool EnvQueryStr(const wchar_t* key_name, std::wstring* value) {
// value not being null to dermine if this path contains a valid dll.
HMODULE LoadChromeWithDirectory(std::wstring* dir) {
::SetCurrentDirectoryW(dir->c_str());
+#ifdef _WIN64
+ const CommandLine& cmd_line = *CommandLine::ForCurrentProcess();
+ if ((cmd_line.GetSwitchValueASCII(switches::kProcessType) ==
+ switches::kNaClBrokerProcess) ||
+ (cmd_line.GetSwitchValueASCII(switches::kProcessType) ==
+ switches::kNaClLoaderProcess)) {
+ // Load the 64-bit DLL when running in a 64-bit process.
+ dir->append(installer_util::kChromeNaCl64Dll);
+ } else {
+ // Only NaCl broker and loader can be launched as Win64 processes.
+ NOTREACHED();
+ return NULL;
+ }
+#else
dir->append(installer_util::kChromeDll);
+#endif
return ::LoadLibraryExW(dir->c_str(), NULL,
LOAD_WITH_ALTERED_SEARCH_PATH);
}
diff --git a/chrome/app/dummy_main_functions.cc b/chrome/app/dummy_main_functions.cc
index 192720e..c8b7c5e 100644
--- a/chrome/app/dummy_main_functions.cc
+++ b/chrome/app/dummy_main_functions.cc
@@ -35,10 +35,6 @@ int ZygoteMain(const MainFunctionParams& parameters) {
return ResultCodes::BAD_PROCESS_TYPE;
}
-int NaClBrokerMain(const MainFunctionParams& parameters) {
- return ResultCodes::BAD_PROCESS_TYPE;
-}
-
int DiagnosticsMain(const CommandLine& command_line) {
return 1;
}
diff --git a/chrome/browser/memory_details.cc b/chrome/browser/memory_details.cc
index f212698..4c7e2fb 100644
--- a/chrome/browser/memory_details.cc
+++ b/chrome/browser/memory_details.cc
@@ -209,7 +209,7 @@ void MemoryDetails::UpdateHistograms() {
case ChildProcessInfo::SANDBOX_HELPER_PROCESS:
UMA_HISTOGRAM_MEMORY_KB("Memory.SandboxHelper", sample);
break;
- case ChildProcessInfo::NACL_PROCESS:
+ case ChildProcessInfo::NACL_LOADER_PROCESS:
UMA_HISTOGRAM_MEMORY_KB("Memory.NativeClient", sample);
break;
default:
diff --git a/chrome/browser/nacl_host/nacl_broker_host.cc b/chrome/browser/nacl_host/nacl_broker_host.cc
new file mode 100644
index 0000000..8abc228
--- /dev/null
+++ b/chrome/browser/nacl_host/nacl_broker_host.cc
@@ -0,0 +1,74 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/nacl_host/nacl_broker_host.h"
+
+#include "base/command_line.h"
+#include "ipc/ipc_switches.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/nacl_host/nacl_broker_service.h"
+#include "chrome/browser/nacl_process_host.h"
+#include "chrome/common/chrome_constants.h"
+#include "chrome/common/chrome_switches.h"
+#include "chrome/common/nacl_cmd_line.h"
+#include "chrome/common/nacl_messages.h"
+
+NaClBrokerHost::NaClBrokerHost(
+ ResourceDispatcherHost* resource_dispatcher_host)
+ : ChildProcessHost(NACL_BROKER_PROCESS, resource_dispatcher_host) {
+}
+
+NaClBrokerHost::~NaClBrokerHost() {
+}
+
+URLRequestContext* NaClBrokerHost::GetRequestContext(
+ uint32 request_id,
+ const ViewHostMsg_Resource_Request& request_data) {
+ return NULL;
+}
+
+bool NaClBrokerHost::Init() {
+ // Create the channel that will be used for communicating with the broker.
+ if (!CreateChannel())
+ return false;
+
+ // Create the path to the nacl broker/loader executable.
+ FilePath exe_path = GetChildPath(false);
+ if (exe_path.empty())
+ return false;
+
+ FilePath nacl_path = exe_path.DirName().Append(chrome::kNaClAppName);
+ CommandLine* cmd_line = new CommandLine(nacl_path);
+ nacl::CopyNaClCommandLineArguments(cmd_line);
+
+ cmd_line->AppendSwitchWithValue(switches::kProcessType,
+ switches::kNaClBrokerProcess);
+
+ cmd_line->AppendSwitchWithValue(switches::kProcessChannelID,
+ ASCIIToWide(channel_id()));
+
+ ChildProcessHost::Launch(FilePath(), cmd_line);
+ return true;
+}
+
+void NaClBrokerHost::OnMessageReceived(const IPC::Message& msg) {
+ IPC_BEGIN_MESSAGE_MAP(NaClBrokerHost, msg)
+ IPC_MESSAGE_HANDLER(NaClProcessMsg_BrokerReady, OnBrokerReady)
+ IPC_MESSAGE_HANDLER(NaClProcessMsg_LoaderLaunched, OnLoaderLaunched)
+ IPC_END_MESSAGE_MAP()
+}
+
+void NaClBrokerHost::OnBrokerReady() {
+ NaClBrokerService::GetInstance()->OnBrokerStarted();
+}
+
+bool NaClBrokerHost::LaunchLoader(
+ const std::wstring& loader_channel_id) {
+ return Send(new NaClProcessMsg_LaunchLoaderThroughBroker(loader_channel_id));
+}
+
+void NaClBrokerHost::OnLoaderLaunched(const std::wstring& loader_channel_id,
+ base::ProcessHandle handle) {
+ NaClBrokerService::GetInstance()->OnLoaderLaunched(loader_channel_id, handle);
+}
diff --git a/chrome/browser/nacl_host/nacl_broker_host.h b/chrome/browser/nacl_host/nacl_broker_host.h
new file mode 100644
index 0000000..f526aa1
--- /dev/null
+++ b/chrome/browser/nacl_host/nacl_broker_host.h
@@ -0,0 +1,46 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_NACL_HOST_NACL_BROKER_HOST_H_
+#define CHROME_BROWSER_NACL_HOST_NACL_BROKER_HOST_H_
+
+#include "base/basictypes.h"
+#include "base/process.h"
+#include "chrome/common/child_process_host.h"
+#include "ipc/ipc_message.h"
+
+class NaClBrokerHost : public ChildProcessHost {
+ public:
+ explicit NaClBrokerHost(ResourceDispatcherHost* resource_dispatcher_host);
+ ~NaClBrokerHost();
+
+ // This function starts the broker process. It needs to be called
+ // before loaders can be launched.
+ bool Init();
+
+ // Send a message to the broker process, causing it to launch
+ // a Native Client loader process.
+ bool LaunchLoader(const std::wstring& loader_channel_id);
+
+ private:
+ // ResourceDispatcherHost::Receiver implementation:
+ virtual URLRequestContext* GetRequestContext(
+ uint32 request_id,
+ const ViewHostMsg_Resource_Request& request_data);
+
+ virtual bool CanShutdown() { return true; }
+
+ // Handler for NaClProcessMsg_BrokerReady message (sent by the broker process)
+ void OnBrokerReady();
+ // Handler for NaClProcessMsg_LoaderLaunched message
+ void OnLoaderLaunched(const std::wstring& loader_channel_id,
+ base::ProcessHandle handle);
+
+ // IPC::Channel::Listener
+ virtual void OnMessageReceived(const IPC::Message& msg);
+
+ DISALLOW_COPY_AND_ASSIGN(NaClBrokerHost);
+};
+
+#endif // CHROME_BROWSER_NACL_HOST_NACL_BROKER_HOST_H_
diff --git a/chrome/browser/nacl_host/nacl_broker_service.cc b/chrome/browser/nacl_host/nacl_broker_service.cc
new file mode 100644
index 0000000..ef659cd
--- /dev/null
+++ b/chrome/browser/nacl_host/nacl_broker_service.cc
@@ -0,0 +1,69 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/nacl_host/nacl_broker_service.h"
+
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/nacl_process_host.h"
+#include "chrome/common/chrome_switches.h"
+
+NaClBrokerService* NaClBrokerService::GetInstance() {
+ return Singleton<NaClBrokerService>::get();
+}
+
+NaClBrokerService::NaClBrokerService()
+ : broker_started_(false),
+ broker_host_(NULL),
+ resource_dispatcher_host_(NULL),
+ initialized_(false) {
+}
+
+void NaClBrokerService::Init(ResourceDispatcherHost* resource_dispatcher_host) {
+ if (initialized_) {
+ return;
+ }
+ resource_dispatcher_host_ = resource_dispatcher_host;
+ StartBroker();
+ initialized_ = true;
+}
+
+bool NaClBrokerService::StartBroker() {
+ broker_host_.reset(new NaClBrokerHost(resource_dispatcher_host_));
+ if (!broker_host_->Init()) {
+ // Initialization failed, we will not retry in the future
+ broker_host_.reset(NULL);
+ }
+ return (broker_host_ != NULL);
+}
+
+bool NaClBrokerService::LaunchLoader(NaClProcessHost* nacl_process_host,
+ const std::wstring& loader_channel_id) {
+ if (broker_started_) {
+ broker_host_->LaunchLoader(loader_channel_id);
+ } else {
+ // Add task to the list
+ pending_launches_[loader_channel_id] = nacl_process_host;
+ }
+ return true;
+}
+
+void NaClBrokerService::OnBrokerStarted() {
+ PendingLaunchesMap::iterator it;
+ for (it = pending_launches_.begin(); it != pending_launches_.end(); it++) {
+ broker_host_->LaunchLoader(it->first);
+ }
+ broker_started_ = true;
+}
+
+void NaClBrokerService::OnLoaderLaunched(const std::wstring& channel_id,
+ base::ProcessHandle handle) {
+ NaClProcessHost* client;
+ PendingLaunchesMap::iterator it = pending_launches_.find(channel_id);
+ if (pending_launches_.end() == it) {
+ NOTREACHED();
+ }
+ client = it->second;
+ client->OnProcessLaunchedByBroker(handle);
+ pending_launches_.erase(it);
+}
diff --git a/chrome/browser/nacl_host/nacl_broker_service.h b/chrome/browser/nacl_host/nacl_broker_service.h
new file mode 100644
index 0000000..75e089d
--- /dev/null
+++ b/chrome/browser/nacl_host/nacl_broker_service.h
@@ -0,0 +1,57 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_NACL_HOST_NACL_BROKER_SERVICE_H_
+#define CHROME_BROWSER_NACL_HOST_NACL_BROKER_SERVICE_H_
+
+#include <map>
+
+#include "base/basictypes.h"
+#include "base/singleton.h"
+#include "chrome/browser/nacl_host/nacl_broker_host.h"
+
+class NaClProcessHost;
+
+class NaClBrokerService {
+ public:
+ // Returns the NaClBrokerService singleton.
+ static NaClBrokerService* GetInstance();
+
+ void Init(ResourceDispatcherHost* resource_dispatcher_host);
+
+ // Can be called several times, must be called before LaunchLoader.
+ bool StartBroker();
+
+ // Send a message to the broker process, causing it to launch
+ // a Native Client loader process.
+ bool LaunchLoader(NaClProcessHost* client,
+ const std::wstring& loader_channel_id);
+
+ // Called by NaClBrokerHost to notify the service
+ // that the broker was launched.
+ void OnBrokerStarted();
+
+ // Called by NaClBrokerHost to notify the service that a loader was launched.
+ void OnLoaderLaunched(const std::wstring& channel_id,
+ base::ProcessHandle handle);
+
+ private:
+ typedef std::map<std::wstring, NaClProcessHost*>
+ PendingLaunchesMap;
+
+ friend struct DefaultSingletonTraits<NaClBrokerService>;
+
+ NaClBrokerService();
+ ~NaClBrokerService() {}
+
+ bool broker_started_;
+ scoped_ptr<NaClBrokerHost> broker_host_;
+ bool initialized_;
+ ResourceDispatcherHost* resource_dispatcher_host_;
+ PendingLaunchesMap pending_launches_;
+
+ DISALLOW_COPY_AND_ASSIGN(NaClBrokerService);
+};
+
+#endif // CHROME_BROWSER_NACL_HOST_NACL_BROKER_SERVICE_H_
diff --git a/chrome/browser/nacl_process_host.cc b/chrome/browser/nacl_process_host.cc
index f736ab7..9f57620 100644
--- a/chrome/browser/nacl_process_host.cc
+++ b/chrome/browser/nacl_process_host.cc
@@ -10,9 +10,12 @@
#include <fcntl.h>
#endif
+#include "base/command_line.h"
+#include "chrome/browser/nacl_host/nacl_broker_service.h"
#include "chrome/browser/renderer_host/resource_message_filter.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/logging_chrome.h"
+#include "chrome/common/nacl_cmd_line.h"
#include "chrome/common/nacl_messages.h"
#include "chrome/common/render_messages.h"
#include "ipc/ipc_switches.h"
@@ -24,11 +27,15 @@
NaClProcessHost::NaClProcessHost(
ResourceDispatcherHost *resource_dispatcher_host,
const std::wstring& url)
- : ChildProcessHost(NACL_PROCESS, resource_dispatcher_host),
+ : ChildProcessHost(NACL_LOADER_PROCESS, resource_dispatcher_host),
resource_dispatcher_host_(resource_dispatcher_host),
reply_msg_(NULL),
- descriptor_(0) {
+ descriptor_(0),
+ running_on_wow64_(false) {
set_name(url);
+#if defined(OS_WIN)
+ CheckIsWow64();
+#endif
}
NaClProcessHost::~NaClProcessHost() {
@@ -77,73 +84,67 @@ bool NaClProcessHost::LaunchSelLdr() {
return false;
CommandLine* cmd_line = new CommandLine(exe_path);
- if (logging::DialogsAreSuppressed())
- cmd_line->AppendSwitch(switches::kNoErrorDialogs);
-
- // Propagate the following switches to the plugin command line (along with
- // any associated values) if present in the browser command line.
- // TODO(gregoryd): check which flags of those below can be supported.
- static const char* const switch_names[] = {
- switches::kNoSandbox,
- switches::kTestSandbox,
- switches::kDisableBreakpad,
- switches::kFullMemoryCrashReport,
- switches::kEnableLogging,
- switches::kDisableLogging,
- switches::kLoggingLevel,
- switches::kEnableDCHECK,
- switches::kSilentDumpOnDCHECK,
- switches::kMemoryProfiling,
-#if defined(OS_MACOSX)
- // TODO(dspringer): remove this when NaCl x86-32 security issues are fixed
- switches::kEnableNaClOnMac,
-#endif
- };
-
- const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess();
+ nacl::CopyNaClCommandLineArguments(cmd_line);
#if defined(OS_MACOSX)
-// TODO(dspringer): NaCl is temporalrily disabled on the Mac by default, but it
-// can be enabled with the --enable-nacl cmd-line switch. Remove this check
-// when the security issues in the Mac PIC code are resolved.
- if (!browser_command_line.HasSwitch(switches::kEnableNaClOnMac))
+ // TODO(dspringer): NaCl is temporalrily disabled on the Mac by default, but
+ // it can be enabled with the --enable-nacl cmd-line switch. Remove this check
+ // when the security issues in the Mac PIC code are resolved.
+ if (!cmd_line->HasSwitch(switches::kEnableNaCl))
return false;
#endif
- for (size_t i = 0; i < arraysize(switch_names); ++i) {
- if (browser_command_line.HasSwitch(switch_names[i])) {
- cmd_line->AppendSwitchWithValue(switch_names[i],
- browser_command_line.GetSwitchValueASCII(switch_names[i]));
- }
- }
-
cmd_line->AppendSwitchWithValue(switches::kProcessType,
- switches::kNaClProcess);
+ switches::kNaClLoaderProcess);
cmd_line->AppendSwitchWithValue(switches::kProcessChannelID,
ASCIIToWide(channel_id()));
- ChildProcessHost::Launch(
+ // On Windows we might need to start the broker process to launch a new loader
#if defined(OS_WIN)
- FilePath(),
+ if (running_on_wow64_) {
+ NaClBrokerService::GetInstance()->Init(resource_dispatcher_host_);
+ NaClBrokerService::GetInstance()->LaunchLoader(this,
+ ASCIIToWide(channel_id()));
+ } else
+#endif
+ ChildProcessHost::Launch(
+#if defined(OS_WIN)
+ FilePath(),
#elif defined(OS_POSIX)
- false,
- base::environment_vector(),
+ false,
+ base::environment_vector(),
#endif
- cmd_line);
+ cmd_line);
return true;
}
+void NaClProcessHost::OnProcessLaunchedByBroker(base::ProcessHandle handle) {
+ set_handle(handle);
+ OnProcessLaunched();
+}
+
+bool NaClProcessHost::DidChildCrash() {
+ if (running_on_wow64_) {
+ bool child_exited;
+ return base::DidProcessCrash(&child_exited, handle());
+ }
+ return ChildProcessHost::DidChildCrash();
+}
+
void NaClProcessHost::OnProcessLaunched() {
nacl::FileDescriptor imc_handle;
base::ProcessHandle nacl_process_handle;
#if NACL_WINDOWS
// Duplicate the IMC handle
+ // We assume the size of imc_handle has the same size as HANDLE, so the cast
+ // below is safe.
+ DCHECK(sizeof(HANDLE) == sizeof(imc_handle));
DuplicateHandle(base::GetCurrentProcessHandle(),
reinterpret_cast<HANDLE>(pair_[0]),
resource_message_filter_->handle(),
- &imc_handle,
+ reinterpret_cast<HANDLE*>(&imc_handle),
GENERIC_READ | GENERIC_WRITE,
FALSE,
DUPLICATE_CLOSE_SOURCE);
@@ -212,3 +213,24 @@ URLRequestContext* NaClProcessHost::GetRequestContext(
const ViewHostMsg_Resource_Request& request_data) {
return NULL;
}
+
+#if defined(OS_WIN)
+// TODO(gregoryd): invoke CheckIsWow64 only once, not for each NaClProcessHost
+typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
+void NaClProcessHost::CheckIsWow64() {
+ LPFN_ISWOW64PROCESS fnIsWow64Process;
+
+ fnIsWow64Process = (LPFN_ISWOW64PROCESS) GetProcAddress(
+ GetModuleHandle(TEXT("kernel32")),
+ "IsWow64Process");
+
+ if (fnIsWow64Process != NULL) {
+ BOOL bIsWow64 = FALSE;
+ if (fnIsWow64Process(GetCurrentProcess(),&bIsWow64)) {
+ if (bIsWow64) {
+ running_on_wow64_ = true;
+ }
+ }
+ }
+}
+#endif
diff --git a/chrome/browser/nacl_process_host.h b/chrome/browser/nacl_process_host.h
index 8159836..ca416f6 100644
--- a/chrome/browser/nacl_process_host.h
+++ b/chrome/browser/nacl_process_host.h
@@ -33,6 +33,11 @@ class NaClProcessHost : public ChildProcessHost {
virtual void OnMessageReceived(const IPC::Message& msg);
+ void OnProcessLaunchedByBroker(base::ProcessHandle handle);
+
+ protected:
+ virtual bool DidChildCrash();
+
private:
bool LaunchSelLdr();
@@ -47,6 +52,11 @@ class NaClProcessHost : public ChildProcessHost {
virtual bool CanShutdown() { return true; }
+#if defined(OS_WIN)
+ // Check whether the browser process is running on WOW64 - Windows only
+ void CheckIsWow64();
+#endif
+
private:
ResourceDispatcherHost* resource_dispatcher_host_;
@@ -63,6 +73,9 @@ class NaClProcessHost : public ChildProcessHost {
// The NaCl specific descriptor for this process.
int descriptor_;
+ // Windows platform flag
+ bool running_on_wow64_;
+
DISALLOW_COPY_AND_ASSIGN(NaClProcessHost);
};
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 6adda93..b9a7475 100755
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -2205,6 +2205,11 @@
'../views/views.gyp:views',
],
'sources': [
+ # NaCl broker is used on Windows only
+ 'browser/nacl_host/nacl_broker_host.cc',
+ 'browser/nacl_host/nacl_broker_host.h',
+ 'browser/nacl_host/nacl_broker_service.cc',
+ 'browser/nacl_host/nacl_broker_service.h',
'browser/net/ssl_config_service_manager_system.cc',
# Using built-in rule in vstudio for midl.
'browser/history/history_indexer.idl',
diff --git a/chrome/chrome_common.gypi b/chrome/chrome_common.gypi
index ffb4bb3..c0205b2 100644
--- a/chrome/chrome_common.gypi
+++ b/chrome/chrome_common.gypi
@@ -60,7 +60,10 @@
'common/main_function_params.h',
'common/message_router.cc',
'common/message_router.h',
+ 'common/nacl_cmd_line.cc',
+ 'common/nacl_cmd_line.h',
'common/nacl_messages.h',
+ 'common/nacl_types.h',
'common/nacl_messages_internal.h',
'common/notification_details.h',
'common/notification_observer.h',
diff --git a/chrome/common/child_process_host.cc b/chrome/common/child_process_host.cc
index 9fb6b52..51c6de4 100644
--- a/chrome/common/child_process_host.cc
+++ b/chrome/common/child_process_host.cc
@@ -177,9 +177,13 @@ void ChildProcessHost::Notify(NotificationType type) {
ChromeThread::UI, FROM_HERE, new ChildNotificationTask(type, this));
}
+bool ChildProcessHost::DidChildCrash() {
+ return child_process_->DidProcessCrash();
+}
+
void ChildProcessHost::OnChildDied() {
- if (child_process_->GetHandle()) {
- bool did_crash = child_process_->DidProcessCrash();
+ if (handle() != base::kNullProcessHandle) {
+ bool did_crash = DidChildCrash();
if (did_crash) {
OnProcessCrashed();
// Report that this child process crashed.
diff --git a/chrome/common/child_process_host.h b/chrome/common/child_process_host.h
index ec6e86d..22d5cc3 100644
--- a/chrome/common/child_process_host.h
+++ b/chrome/common/child_process_host.h
@@ -116,6 +116,8 @@ class ChildProcessHost : public ResourceDispatcherHost::Receiver,
bool opening_channel() { return opening_channel_; }
const std::string& channel_id() { return channel_id_; }
+ virtual bool DidChildCrash();
+
private:
// Sends the given notification to the notification service on the UI thread.
void Notify(NotificationType type);
diff --git a/chrome/common/child_process_info.cc b/chrome/common/child_process_info.cc
index c915e80..473512f 100644
--- a/chrome/common/child_process_info.cc
+++ b/chrome/common/child_process_info.cc
@@ -54,7 +54,7 @@ std::wstring ChildProcessInfo::GetTypeNameInEnglish(
return L"Zygote";
case SANDBOX_HELPER_PROCESS:
return L"Sandbox helper";
- case NACL_PROCESS:
+ case NACL_LOADER_PROCESS:
return L"Native Client module";
case UNKNOWN_PROCESS:
default:
@@ -77,7 +77,7 @@ std::wstring ChildProcessInfo::GetLocalizedTitle() const {
message_id = IDS_TASK_MANAGER_UTILITY_PREFIX;
} else if (type_ == ChildProcessInfo::PROFILE_IMPORT_PROCESS) {
message_id = IDS_TASK_MANAGER_PROFILE_IMPORT_PREFIX;
- } else if (type_ == ChildProcessInfo::NACL_PROCESS) {
+ } else if (type_ == ChildProcessInfo::NACL_LOADER_PROCESS) {
message_id = IDS_TASK_MANAGER_NACL_PREFIX;
} else {
DCHECK(false) << "Need localized name for child process type.";
diff --git a/chrome/common/child_process_info.h b/chrome/common/child_process_info.h
index 5726675..1607417 100644
--- a/chrome/common/child_process_info.h
+++ b/chrome/common/child_process_info.h
@@ -20,11 +20,12 @@ class ChildProcessInfo {
RENDER_PROCESS,
PLUGIN_PROCESS,
WORKER_PROCESS,
- NACL_PROCESS,
+ NACL_LOADER_PROCESS,
UTILITY_PROCESS,
PROFILE_IMPORT_PROCESS,
ZYGOTE_PROCESS,
SANDBOX_HELPER_PROCESS,
+ NACL_BROKER_PROCESS,
GPU_PROCESS
};
diff --git a/chrome/common/chrome_constants.cc b/chrome/common/chrome_constants.cc
index c75ab65..8226cd8 100644
--- a/chrome/common/chrome_constants.cc
+++ b/chrome/common/chrome_constants.cc
@@ -52,6 +52,7 @@ const FilePath::CharType kHelperProcessExecutablePath[] =
const FilePath::CharType kFrameworkName[] =
FPL(PRODUCT_STRING " Framework.framework");
#endif // OS_MACOSX
+const wchar_t kNaClAppName[] = L"nacl";
#if defined(GOOGLE_CHROME_BUILD)
const wchar_t kBrowserAppName[] = L"Chrome";
const char kStatsFilename[] = "ChromeStats2";
diff --git a/chrome/common/chrome_constants.h b/chrome/common/chrome_constants.h
index c8121d0..fc271e0 100644
--- a/chrome/common/chrome_constants.h
+++ b/chrome/common/chrome_constants.h
@@ -31,6 +31,7 @@ extern const wchar_t kNotSignedInProfile[];
extern const wchar_t kNotSignedInID[];
extern const char kStatsFilename[];
extern const wchar_t kBrowserResourcesDll[];
+extern const wchar_t kNaClAppName[];
extern const FilePath::CharType kExtensionFileExtension[];
// filenames
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc
index 574752a..c9bc494 100644
--- a/chrome/common/chrome_switches.cc
+++ b/chrome/common/chrome_switches.cc
@@ -384,8 +384,12 @@ const char kMessageLoopHistogrammer[] = "message-loop-histogrammer";
// and performance tests.
const char kMetricsRecordingOnly[] = "metrics-recording-only";
-// Causes the process to run as a NativeClient's sel_ldr subprocess.
-const char kNaClProcess[] = "nacl";
+// Causes the process to run as a NativeClient broker
+// (used for launching NaCl loader processes on 64-bit Windows).
+const char kNaClBrokerProcess[] = "nacl-broker";
+
+// Causes the process to run as a NativeClient loader.
+const char kNaClLoaderProcess[] = "nacl-loader";
// Causes the Native Client process to display a dialog on launch.
const char kNaClStartupDialog[] = "nacl-startup-dialog";
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h
index 4f8d4d6..856df24 100644
--- a/chrome/common/chrome_switches.h
+++ b/chrome/common/chrome_switches.h
@@ -121,7 +121,8 @@ extern const char kMediaCacheSize[];
extern const char kMemoryProfiling[];
extern const char kMessageLoopHistogrammer[];
extern const char kMetricsRecordingOnly[];
-extern const char kNaClProcess[];
+extern const char kNaClBrokerProcess[];
+extern const char kNaClLoaderProcess[];
extern const char kNaClStartupDialog[];
extern const char kNewTabPage[];
extern const char kNoDefaultBrowserCheck[];
diff --git a/chrome/common/nacl_cmd_line.cc b/chrome/common/nacl_cmd_line.cc
new file mode 100644
index 0000000..2212c68
--- /dev/null
+++ b/chrome/common/nacl_cmd_line.cc
@@ -0,0 +1,44 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/command_line.h"
+#include "chrome/common/chrome_constants.h"
+#include "chrome/common/chrome_switches.h"
+#include "chrome/common/logging_chrome.h"
+
+namespace nacl {
+ void CopyNaClCommandLineArguments(CommandLine* cmd_line) {
+ const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess();
+ if (logging::DialogsAreSuppressed())
+ cmd_line->AppendSwitch(switches::kNoErrorDialogs);
+
+ // Propagate the following switches to the NaCl loader command line (along
+ // with any associated values) if present in the browser command line.
+ // TODO(gregoryd): check which flags of those below can be supported.
+ static const char* const switch_names[] = {
+ switches::kNoSandbox,
+ switches::kTestSandbox,
+ switches::kDisableBreakpad,
+ switches::kFullMemoryCrashReport,
+ switches::kEnableLogging,
+ switches::kDisableLogging,
+ switches::kLoggingLevel,
+ switches::kEnableDCHECK,
+ switches::kSilentDumpOnDCHECK,
+ switches::kMemoryProfiling,
+#if defined(OS_MACOSX)
+ // TODO(dspringer): remove this when NaCl x86-32 security issues are fixed
+ switches::kEnableNaClOnMac,
+#endif
+ };
+
+ for (size_t i = 0; i < arraysize(switch_names); ++i) {
+ if (browser_command_line.HasSwitch(switch_names[i])) {
+ cmd_line->AppendSwitchWithValue(
+ switch_names[i],
+ browser_command_line.GetSwitchValueASCII(switch_names[i]));
+ }
+ }
+ }
+}
diff --git a/chrome/common/nacl_cmd_line.h b/chrome/common/nacl_cmd_line.h
new file mode 100644
index 0000000..1091e11
--- /dev/null
+++ b/chrome/common/nacl_cmd_line.h
@@ -0,0 +1,16 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_COMMON_NACL_CMD_LINE_H_
+#define CHROME_COMMON_NACL_CMD_LINE_H_
+
+#include "base/command_line.h"
+
+namespace nacl {
+ // Copy all the relevant arguments from the command line of the current
+ // process to cmd_line that will be used for launching the NaCl loader/broker.
+ void CopyNaClCommandLineArguments(CommandLine* cmd_line);
+}
+
+#endif // CHROME_COMMON_NACL_CMD_LINE_H_
diff --git a/chrome/common/nacl_messages_internal.h b/chrome/common/nacl_messages_internal.h
index 3794255..11dfba7 100644
--- a/chrome/common/nacl_messages_internal.h
+++ b/chrome/common/nacl_messages_internal.h
@@ -14,5 +14,16 @@ IPC_BEGIN_MESSAGES(NaClProcess)
int /* descriptor id */,
nacl::FileDescriptor /* handle value */)
+ // Tells the NaCl broker to launch a NaCl loader process.
+ IPC_MESSAGE_CONTROL1(NaClProcessMsg_LaunchLoaderThroughBroker,
+ std::wstring /* channel ID for the loader */)
+
+ // Notify the browser process that the loader was launched successfully.
+ IPC_MESSAGE_CONTROL2(NaClProcessMsg_LoaderLaunched,
+ std::wstring, /* channel ID for the loader */
+ base::ProcessHandle /* loader process handle */)
+
+ // Notify the browser process that the broker is ready (sent by the broker)
+ IPC_MESSAGE_CONTROL0(NaClProcessMsg_BrokerReady)
IPC_END_MESSAGES(NaClProcess)
diff --git a/chrome/common/nacl_types.h b/chrome/common/nacl_types.h
index 394edd3..5c5f5dc 100644
--- a/chrome/common/nacl_types.h
+++ b/chrome/common/nacl_types.h
@@ -6,15 +6,23 @@
#ifndef CHROME_COMMON_NACL_TYPES_H_
#define CHROME_COMMON_NACL_TYPES_H_
-// TODO(gregoryd): add a Windows definition for base::FileDescriptor,
-// replace the macros with inline functions.
+#if defined(OS_POSIX)
+#include "base/file_descriptor_posix.h"
+#endif
+
+// TODO(gregoryd): add a Windows definition for base::FileDescriptor
namespace nacl {
#if defined(OS_WIN)
-typedef HANDLE FileDescriptor;
-#define NATIVE_HANDLE(desc) (desc)
+ // We assume that HANDLE always uses less than 32 bits
+ typedef int FileDescriptor;
+ inline HANDLE ToNativeHandle(const FileDescriptor& desc) {
+ return reinterpret_cast<HANDLE>(desc);
+ }
#elif defined(OS_POSIX)
-typedef base::FileDescriptor FileDescriptor;
-#define NATIVE_HANDLE(desc) ((desc).fd)
+ typedef base::FileDescriptor FileDescriptor;
+ inline int ToNativeHandle(const FileDescriptor& desc) {
+ return desc.fd;
+ }
#endif
}
diff --git a/chrome/common/sandbox_init_wrapper_mac.cc b/chrome/common/sandbox_init_wrapper_mac.cc
index 3341b08..a47240d 100644
--- a/chrome/common/sandbox_init_wrapper_mac.cc
+++ b/chrome/common/sandbox_init_wrapper_mac.cc
@@ -39,7 +39,7 @@ bool SandboxInitWrapper::InitializeSandbox(const CommandLine& command_line,
} else if (process_type == switches::kWorkerProcess) {
// Worker process sandbox.
sandbox_process_type = sandbox::SANDBOX_TYPE_WORKER;
- } else if ((process_type == switches::kNaClProcess) ||
+ } else if ((process_type == switches::kNaClLoaderProcess) ||
(process_type == switches::kPluginProcess) ||
(process_type == switches::kProfileImportProcess)) {
return true;
diff --git a/chrome/common/sandbox_init_wrapper_win.cc b/chrome/common/sandbox_init_wrapper_win.cc
index 0bfba24..5d4399a 100644
--- a/chrome/common/sandbox_init_wrapper_win.cc
+++ b/chrome/common/sandbox_init_wrapper_win.cc
@@ -21,7 +21,7 @@ bool SandboxInitWrapper::InitializeSandbox(const CommandLine& command_line,
if ((process_type == switches::kRendererProcess) ||
(process_type == switches::kExtensionProcess) ||
(process_type == switches::kWorkerProcess) ||
- (process_type == switches::kNaClProcess) ||
+ (process_type == switches::kNaClLoaderProcess) ||
(process_type == switches::kUtilityProcess) ||
(process_type == switches::kPluginProcess &&
command_line.HasSwitch(switches::kSafePlugins))) {
diff --git a/chrome/common/sandbox_policy.cc b/chrome/common/sandbox_policy.cc
index 9e70b08..a79a962 100644
--- a/chrome/common/sandbox_policy.cc
+++ b/chrome/common/sandbox_policy.cc
@@ -23,6 +23,13 @@
#include "sandbox/src/sandbox.h"
#include "webkit/glue/plugins/plugin_list.h"
+#ifdef NACL_WIN64
+ // The sandbox can be used also by the NaCl broker process. In this case we
+ // define a global variable g_broker_services instead of g_browser_process.
+ // This can be changed if we discover that the broker process needs to be more
+ // similar to the browser process.
+ extern sandbox::BrokerServices* g_broker_services;
+#endif
namespace {
// The DLLs listed here are known (or under strong suspicion) of causing crashes
@@ -342,10 +349,12 @@ base::ProcessHandle StartProcessWithAccess(CommandLine* cmd_line,
type = ChildProcessInfo::PLUGIN_PROCESS;
} else if (type_str == switches::kWorkerProcess) {
type = ChildProcessInfo::WORKER_PROCESS;
- } else if (type_str == switches::kNaClProcess) {
- type = ChildProcessInfo::NACL_PROCESS;
+ } else if (type_str == switches::kNaClLoaderProcess) {
+ type = ChildProcessInfo::NACL_LOADER_PROCESS;
} else if (type_str == switches::kUtilityProcess) {
type = ChildProcessInfo::UTILITY_PROCESS;
+ } else if (type_str == switches::kNaClBrokerProcess) {
+ type = ChildProcessInfo::NACL_BROKER_PROCESS;
} else if (type_str == switches::kGpuProcess) {
type = ChildProcessInfo::GPU_PROCESS;
} else {
@@ -379,10 +388,15 @@ base::ProcessHandle StartProcessWithAccess(CommandLine* cmd_line,
return process;
}
+#ifdef NACL_WIN64
+ // When running in the broker we get the BrokerServices pointer from a global
+ // variable. It is initialized in NaClBrokerMain.
+ sandbox::BrokerServices* broker_service = g_broker_services;
+#else
// spawn the child process in the sandbox
sandbox::BrokerServices* broker_service =
g_browser_process->broker_services();
-
+#endif
sandbox::ResultCode result;
PROCESS_INFORMATION target = {0};
sandbox::TargetPolicy* policy = broker_service->CreatePolicy();
diff --git a/chrome/installer/util/util_constants.cc b/chrome/installer/util/util_constants.cc
index 5505685..6b89abf 100644
--- a/chrome/installer/util/util_constants.cc
+++ b/chrome/installer/util/util_constants.cc
@@ -113,6 +113,7 @@ const wchar_t kChromeExe[] = L"chrome.exe";
const wchar_t kChromeOldExe[] = L"old_chrome.exe";
const wchar_t kChromeNewExe[] = L"new_chrome.exe";
const wchar_t kChromeDll[] = L"chrome.dll";
+const wchar_t kChromeNaCl64Dll[] = L"chrome_nacl_win64.dll";
const wchar_t kChromeFrameDll[] = L"npchrome_frame.dll";
const wchar_t kSetupExe[] = L"setup.exe";
const wchar_t kInstallerDir[] = L"Installer";
diff --git a/chrome/installer/util/util_constants.h b/chrome/installer/util/util_constants.h
index f510cdc..b3a4eed 100644
--- a/chrome/installer/util/util_constants.h
+++ b/chrome/installer/util/util_constants.h
@@ -81,6 +81,7 @@ extern const wchar_t kChromeExe[];
extern const wchar_t kChromeOldExe[];
extern const wchar_t kChromeNewExe[];
extern const wchar_t kChromeDll[];
+extern const wchar_t kChromeNaCl64Dll[];
extern const wchar_t kChromeFrameDll[];
extern const wchar_t kSetupExe[];
extern const wchar_t kInstallerDir[];
diff --git a/chrome/nacl.gypi b/chrome/nacl.gypi
index 696b60d..d142af7 100644
--- a/chrome/nacl.gypi
+++ b/chrome/nacl.gypi
@@ -86,6 +86,10 @@
'chrome_strings',
'common_nacl_win64',
],
+ 'sources': [
+ 'nacl/broker_thread.cc',
+ 'nacl/broker_thread.h',
+ ],
'defines': [
'<@(nacl_win64_defines)',
],
diff --git a/chrome/nacl/broker_thread.cc b/chrome/nacl/broker_thread.cc
new file mode 100644
index 0000000..0b4bbd2
--- /dev/null
+++ b/chrome/nacl/broker_thread.cc
@@ -0,0 +1,72 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/nacl/broker_thread.h"
+
+#include "base/base_switches.h"
+#include "base/command_line.h"
+#include "base/path_service.h"
+#include "base/process_util.h"
+#include "chrome/common/sandbox_policy.h"
+#include "chrome/common/chrome_switches.h"
+#include "chrome/common/nacl_cmd_line.h"
+#include "chrome/common/nacl_messages.h"
+#include "ipc/ipc_switches.h"
+
+NaClBrokerThread::NaClBrokerThread()
+ : browser_handle_(0),
+ broker_services_(NULL) {
+}
+
+NaClBrokerThread::~NaClBrokerThread() {
+ base::CloseProcessHandle(browser_handle_);
+}
+
+NaClBrokerThread* NaClBrokerThread::current() {
+ return static_cast<NaClBrokerThread*>(ChildThread::current());
+}
+
+void NaClBrokerThread::OnControlMessageReceived(const IPC::Message& msg) {
+ IPC_BEGIN_MESSAGE_MAP(NaClBrokerThread, msg)
+ IPC_MESSAGE_HANDLER(NaClProcessMsg_LaunchLoaderThroughBroker,
+ OnLaunchLoaderThroughBroker)
+ IPC_END_MESSAGE_MAP()
+}
+
+void NaClBrokerThread::OnLaunchLoaderThroughBroker(
+ const std::wstring& loader_channel_id) {
+ base::ProcessHandle loader_process = 0;
+ base::ProcessHandle loader_handle_in_browser = 0;
+
+ // Create the path to the nacl broker/loader executable - it's the executable
+ // this code is running in.
+ FilePath exe_path;
+ PathService::Get(base::FILE_EXE, &exe_path);
+ if (!exe_path.empty()) {
+ CommandLine* cmd_line = new CommandLine(exe_path);
+ nacl::CopyNaClCommandLineArguments(cmd_line);
+
+ cmd_line->AppendSwitchWithValue(switches::kProcessType,
+ switches::kNaClLoaderProcess);
+
+ cmd_line->AppendSwitchWithValue(switches::kProcessChannelID,
+ loader_channel_id);
+
+ loader_process = sandbox::StartProcessWithAccess(cmd_line, FilePath());
+ if (loader_process) {
+ DuplicateHandle(::GetCurrentProcess(), loader_process,
+ browser_handle_, &loader_handle_in_browser,
+ PROCESS_DUP_HANDLE, FALSE, 0);
+ }
+ }
+ Send(new NaClProcessMsg_LoaderLaunched(loader_channel_id,
+ loader_handle_in_browser));
+}
+
+void NaClBrokerThread::OnChannelConnected(int32 peer_pid) {
+ bool res = base::OpenProcessHandle(peer_pid, &browser_handle_);
+ DCHECK(res);
+ Send(new NaClProcessMsg_BrokerReady());
+}
+
diff --git a/chrome/nacl/broker_thread.h b/chrome/nacl/broker_thread.h
new file mode 100644
index 0000000..d88919f
--- /dev/null
+++ b/chrome/nacl/broker_thread.h
@@ -0,0 +1,37 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_NACL_BROKER_THREAD_H_
+#define CHROME_NACL_BROKER_THREAD_H_
+
+#include "chrome/common/child_thread.h"
+#include "chrome/common/nacl_types.h"
+
+#if defined(OS_WIN)
+#include "sandbox/src/sandbox.h"
+#endif
+
+// The BrokerThread class represents the thread that handles the messages from
+// the browser process and starts NaCl loader processes.
+class NaClBrokerThread : public ChildThread {
+ public:
+ NaClBrokerThread();
+ ~NaClBrokerThread();
+ // Returns the one NaCl thread.
+ static NaClBrokerThread* current();
+
+ virtual void OnChannelConnected(int32 peer_pid);
+
+ private:
+ virtual void OnControlMessageReceived(const IPC::Message& msg);
+ void OnLaunchLoaderThroughBroker(const std::wstring& loader_channel_id);
+ void OnShareBrowserHandle(int browser_handle);
+
+ base::ProcessHandle browser_handle_;
+ sandbox::BrokerServices* broker_services_;
+
+ DISALLOW_COPY_AND_ASSIGN(NaClBrokerThread);
+};
+
+#endif // CHROME_NACL_BROKER_THREAD_H_
diff --git a/chrome/nacl/nacl_main.cc b/chrome/nacl/nacl_main.cc
index 72bc8a2..ffda8ab 100644
--- a/chrome/nacl/nacl_main.cc
+++ b/chrome/nacl/nacl_main.cc
@@ -20,8 +20,66 @@
#include "chrome/common/chrome_switches.h"
#include "chrome/common/logging_chrome.h"
#include "chrome/common/main_function_params.h"
+#include "chrome/common/result_codes.h"
+#if defined(OS_WIN)
+#include "chrome/nacl/broker_thread.h"
+#endif
#include "chrome/nacl/nacl_thread.h"
+#ifdef _WIN64
+
+sandbox::BrokerServices* g_broker_services = NULL;
+
+// main() routine for the NaCl broker process.
+// This is necessary for supporting NaCl in Chrome on Win64.
+int NaClBrokerMain(const MainFunctionParams& parameters) {
+ // The main thread of the broker.
+ MessageLoopForIO main_message_loop;
+ std::wstring app_name = chrome::kNaClAppName;
+ PlatformThread::SetName(WideToASCII(app_name + L"_NaClBrokerMain").c_str());
+
+ SystemMonitor system_monitor;
+ HighResolutionTimerManager hi_res_timer_manager;
+
+ const CommandLine& parsed_command_line = parameters.command_line_;
+
+ DLOG(INFO) << "Started NaCL broker with " <<
+ parsed_command_line.command_line_string();
+
+ // NOTE: this code is duplicated from browser_main.cc
+ // IMPORTANT: This piece of code needs to run as early as possible in the
+ // process because it will initialize the sandbox broker, which requires the
+ // process to swap its window station. During this time all the UI will be
+ // broken. This has to run before threads and windows are created.
+ sandbox::BrokerServices* broker_services =
+ parameters.sandbox_info_.BrokerServices();
+ if (broker_services) {
+ g_broker_services = broker_services;
+ if (!parsed_command_line.HasSwitch(switches::kNoSandbox)) {
+ bool use_winsta = !parsed_command_line.HasSwitch(
+ switches::kDisableAltWinstation);
+ // Precreate the desktop and window station used by the renderers.
+ sandbox::TargetPolicy* policy = broker_services->CreatePolicy();
+ sandbox::ResultCode result = policy->CreateAlternateDesktop(use_winsta);
+ CHECK(sandbox::SBOX_ERROR_FAILED_TO_SWITCH_BACK_WINSTATION != result);
+ policy->Release();
+ }
+ }
+
+ {
+ ChildProcess broker_process;
+ broker_process.set_main_thread(new NaClBrokerThread());
+ MessageLoop::current()->Run();
+ }
+
+ return 0;
+}
+#else
+int NaClBrokerMain(const MainFunctionParams& parameters) {
+ return ResultCodes::BAD_PROCESS_TYPE;
+}
+#endif // _WIN64
+
// This function provides some ways to test crash and assertion handling
// behavior of the renderer.
static void HandleNaClTestParameters(const CommandLine& command_line) {
@@ -48,7 +106,7 @@ static void LaunchNaClChildProcess() {
}
#endif
-// main() routine for running as the sel_ldr process.
+// main() routine for the NaCl loader process.
int NaClMain(const MainFunctionParams& parameters) {
const CommandLine& parsed_command_line = parameters.command_line_;
@@ -60,7 +118,12 @@ int NaClMain(const MainFunctionParams& parameters) {
// The main thread of the plugin services IO.
MessageLoopForIO main_message_loop;
+ // NaCl code runs in a different binary on Win64.
+#ifdef _WIN64
+ std::wstring app_name = chrome::kNaClAppName;
+#else
std::wstring app_name = chrome::kBrowserAppName;
+#endif
PlatformThread::SetName(WideToASCII(app_name + L"_NaClMain").c_str());
SystemMonitor system_monitor;
@@ -70,7 +133,7 @@ int NaClMain(const MainFunctionParams& parameters) {
sandbox::TargetServices* target_services =
parameters.sandbox_info_.TargetServices();
- DLOG(INFO) << "Started plugin with " <<
+ DLOG(INFO) << "Started NaCl loader with " <<
parsed_command_line.command_line_string();
HMODULE sandbox_test_module = NULL;
diff --git a/chrome/nacl/nacl_thread.cc b/chrome/nacl/nacl_thread.cc
index 4c9dd5f05..0f05f06 100644
--- a/chrome/nacl/nacl_thread.cc
+++ b/chrome/nacl/nacl_thread.cc
@@ -36,5 +36,5 @@ void NaClThread::OnControlMessageReceived(const IPC::Message& msg) {
void NaClThread::OnStartSelLdr(int channel_descriptor,
nacl::FileDescriptor handle) {
- SelMain(channel_descriptor, NATIVE_HANDLE(handle));
+ SelMain(channel_descriptor, nacl::ToNativeHandle(handle));
}
diff --git a/chrome/nacl/nacl_thread.h b/chrome/nacl/nacl_thread.h
index fd8fe76..8893819 100644
--- a/chrome/nacl/nacl_thread.h
+++ b/chrome/nacl/nacl_thread.h
@@ -10,8 +10,6 @@
#include "chrome/common/child_thread.h"
#include "chrome/common/nacl_types.h"
-class NotificationService;
-
// The NaClThread class represents a background thread where NaCl app gets
// started.
class NaClThread : public ChildThread {
diff --git a/chrome/renderer/render_process.cc b/chrome/renderer/render_process.cc
index ac372ed..5a5bfe7 100644
--- a/chrome/renderer/render_process.cc
+++ b/chrome/renderer/render_process.cc
@@ -150,7 +150,7 @@ bool RenderProcess::LaunchNaClProcess(const char* url,
reinterpret_cast<base::ProcessId*>(nacl_process_id)))) {
return false;
}
- *imc_handle = NATIVE_HANDLE(imc_descriptor);
+ *imc_handle = nacl::ToNativeHandle(imc_descriptor);
*nacl_process_handle = nacl_process;
return true;
}