summaryrefslogtreecommitdiffstats
path: root/chrome/app
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/app')
-rw-r--r--chrome/app/chrome_exe_main_win.cc61
-rw-r--r--chrome/app/client_util.cc130
-rw-r--r--chrome/app/client_util.h21
-rw-r--r--chrome/app/metro_driver_win.cc70
-rw-r--r--chrome/app/metro_driver_win.h33
5 files changed, 107 insertions, 208 deletions
diff --git a/chrome/app/chrome_exe_main_win.cc b/chrome/app/chrome_exe_main_win.cc
index 51b1edf..3c93752 100644
--- a/chrome/app/chrome_exe_main_win.cc
+++ b/chrome/app/chrome_exe_main_win.cc
@@ -13,7 +13,6 @@
#include "base/lazy_instance.h"
#include "chrome/app/chrome_breakpad_client.h"
#include "chrome/app/client_util.h"
-#include "chrome/app/metro_driver_win.h"
#include "chrome/browser/chrome_process_finder_win.h"
#include "chrome/browser/policy/policy_path_parser.h"
#include "chrome/common/chrome_constants.h"
@@ -41,36 +40,6 @@ void CheckSafeModeLaunch() {
::SetEnvironmentVariableA(chrome::kSafeModeEnvVar, "1");
}
-int RunChrome(HINSTANCE instance) {
- breakpad::SetBreakpadClient(g_chrome_breakpad_client.Pointer());
-
- CheckSafeModeLaunch();
-
- bool exit_now = true;
- // We restarted because of a previous crash. Ask user if we should relaunch.
- // Only show this for the browser process. See crbug.com/132119.
- const std::string process_type =
- CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
- switches::kProcessType);
- if (process_type.empty()) {
- if (breakpad::ShowRestartDialogIfCrashed(&exit_now)) {
- if (exit_now)
- return content::RESULT_CODE_NORMAL_EXIT;
- }
- }
-
- // Initialize the sandbox services.
- sandbox::SandboxInterfaceInfo sandbox_info = {0};
- content::InitializeSandboxInfo(&sandbox_info);
-
- // Load and launch the chrome dll. *Everything* happens inside.
- MainDllLoader* loader = MakeMainDllLoader();
- int rc = loader->Launch(instance, &sandbox_info);
- loader->RelaunchChromeBrowserWithNewCommandLineIfNeeded();
- delete loader;
- return rc;
-}
-
// List of switches that it's safe to rendezvous early with. Fast start should
// not be done if a command line contains a switch not in this set.
// Note this is currently stored as a list of two because it's probably faster
@@ -135,9 +104,29 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE prev, wchar_t*, int) {
if (AttemptFastNotify(*CommandLine::ForCurrentProcess()))
return 0;
- MetroDriver metro_driver;
- if (metro_driver.in_metro_mode())
- return metro_driver.RunInMetro(instance, &RunChrome);
- // Not in metro mode, proceed as normal.
- return RunChrome(instance);
+ breakpad::SetBreakpadClient(g_chrome_breakpad_client.Pointer());
+ CheckSafeModeLaunch();
+
+ bool exit_now = true;
+ // We restarted because of a previous crash. Ask user if we should relaunch.
+ // Only show this for the browser process. See crbug.com/132119.
+ bool const is_browser =
+ CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
+ switches::kProcessType).empty();
+ if (is_browser) {
+ if (breakpad::ShowRestartDialogIfCrashed(&exit_now)) {
+ if (exit_now)
+ return content::RESULT_CODE_NORMAL_EXIT;
+ }
+ }
+
+ // Initialize the sandbox services.
+ sandbox::SandboxInterfaceInfo sandbox_info = {0};
+ content::InitializeSandboxInfo(&sandbox_info);
+ // Load and launch the chrome dll. *Everything* happens inside.
+ MainDllLoader* loader = MakeMainDllLoader();
+ int rc = loader->Launch(instance, &sandbox_info);
+ loader->RelaunchChromeBrowserWithNewCommandLineIfNeeded();
+ delete loader;
+ return rc;
}
diff --git a/chrome/app/client_util.cc b/chrome/app/client_util.cc
index dd6becd..054d58f 100644
--- a/chrome/app/client_util.cc
+++ b/chrome/app/client_util.cc
@@ -6,6 +6,7 @@
#include <shlwapi.h>
#include "base/command_line.h"
+#include "base/compiler_specific.h"
#include "base/debug/trace_event.h"
#include "base/environment.h"
#include "base/file_version_info.h"
@@ -25,8 +26,6 @@
#include "chrome/common/chrome_result_codes.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/env_vars.h"
-#include "chrome/installer/util/browser_distribution.h"
-#include "chrome/installer/util/channel_info.h"
#include "chrome/installer/util/google_update_constants.h"
#include "chrome/installer/util/google_update_settings.h"
#include "chrome/installer/util/install_util.h"
@@ -148,29 +147,21 @@ size_t InitPreReadPercentage() {
// Expects that |dir| has a trailing backslash. |dir| is modified so it
// contains the full path that was tried. Caller must check for the return
// value not being null to determine if this path contains a valid dll.
-HMODULE LoadChromeWithDirectory(base::string16* dir) {
+HMODULE LoadModuleWithDirectory(base::string16* dir,
+ const wchar_t* dll_name,
+ bool pre_read) {
::SetCurrentDirectoryW(dir->c_str());
- const CommandLine& cmd_line = *CommandLine::ForCurrentProcess();
-#if !defined(CHROME_MULTIPLE_DLL)
- const wchar_t* dll_name = installer::kChromeDll;
-#else
- const wchar_t* dll_name =
- cmd_line.HasSwitch(switches::kProcessType) &&
- cmd_line.GetSwitchValueASCII(switches::kProcessType) != "service"
- ? installer::kChromeChildDll
- : installer::kChromeDll;
-#endif
dir->append(dll_name);
+ if (pre_read) {
#if !defined(WIN_DISABLE_PREREAD)
- // We pre-read the binary to warm the memory caches (fewer hard faults to
- // page parts of the binary in).
- if (!cmd_line.HasSwitch(switches::kProcessType)) {
+ // We pre-read the binary to warm the memory caches (fewer hard faults to
+ // page parts of the binary in).
const size_t kStepSize = 1024 * 1024;
size_t percentage = InitPreReadPercentage();
ImagePreReader::PartialPreReadImage(dir->c_str(), percentage, kStepSize);
- }
#endif
+ }
return ::LoadLibraryExW(dir->c_str(), NULL,
LOAD_WITH_ALTERED_SEARCH_PATH);
@@ -186,6 +177,13 @@ void ClearDidRun(const base::string16& dll_path) {
GoogleUpdateSettings::UpdateDidRunState(false, system_level);
}
+bool InMetroMode() {
+ return (wcsstr(
+ ::GetCommandLineW(), L" -ServerName:DefaultBrowserServer") != NULL);
+}
+
+typedef int (*InitMetro)();
+
} // namespace
base::string16 GetExecutablePath() {
@@ -210,7 +208,8 @@ base::string16 GetCurrentModuleVersion() {
//=============================================================================
-MainDllLoader::MainDllLoader() : dll_(NULL) {
+MainDllLoader::MainDllLoader()
+ : dll_(NULL), metro_mode_(InMetroMode()) {
}
MainDllLoader::~MainDllLoader() {
@@ -222,12 +221,16 @@ MainDllLoader::~MainDllLoader() {
// If that fails then we look at the version resource in the current
// module. This is the expected path for chrome.exe browser instances in an
// installed build.
-HMODULE MainDllLoader::Load(base::string16* out_version,
+HMODULE MainDllLoader::Load(const wchar_t* dll_name,
+ base::string16* out_version,
base::string16* out_file) {
const CommandLine& cmd_line = *CommandLine::ForCurrentProcess();
- const base::string16 dir(GetExecutablePath());
- *out_file = dir;
- HMODULE dll = LoadChromeWithDirectory(out_file);
+ const base::string16 executable_dir(GetExecutablePath());
+ *out_file = executable_dir;
+
+ const bool pre_read = !metro_mode_;
+
+ HMODULE dll = LoadModuleWithDirectory(out_file, dll_name, pre_read);
if (!dll) {
// Loading from same directory (for developers) failed. Look at the version
// resource in the current module and try loading that.
@@ -237,10 +240,10 @@ HMODULE MainDllLoader::Load(base::string16* out_version,
return NULL;
}
- *out_file = dir;
+ *out_file = executable_dir;
*out_version = version_string;
out_file->append(*out_version).append(1, L'\\');
- dll = LoadChromeWithDirectory(out_file);
+ dll = LoadModuleWithDirectory(out_file, dll_name, pre_read);
if (!dll) {
PLOG(ERROR) << "Failed to load Chrome DLL from " << *out_file;
return NULL;
@@ -248,7 +251,6 @@ HMODULE MainDllLoader::Load(base::string16* out_version,
}
DCHECK(dll);
-
return dll;
}
@@ -257,34 +259,53 @@ HMODULE MainDllLoader::Load(base::string16* out_version,
// add custom code in the OnBeforeLaunch callback.
int MainDllLoader::Launch(HINSTANCE instance,
sandbox::SandboxInterfaceInfo* sbox_info) {
+ const CommandLine& cmd_line = *CommandLine::ForCurrentProcess();
+ const std::string process_type =
+ cmd_line.GetSwitchValueASCII(switches::kProcessType);
+
+ const wchar_t* dll_name;
+ if (metro_mode_) {
+ dll_name = installer::kChromeMetroDll;
+ } else {
+#if !defined(CHROME_MULTIPLE_DLL)
+ dll_name = installer::kChromeDll;
+#else
+ dll_name = process_type != "service" ?
+ installer::kChromeChildDll : installer::kChromeDll;
+#endif
+ }
+
base::string16 version;
base::string16 file;
- dll_ = Load(&version, &file);
+ dll_ = Load(dll_name, &version, &file);
if (!dll_)
return chrome::RESULT_CODE_MISSING_DATA;
- scoped_ptr<base::Environment> env(base::Environment::Create());
- env->SetVar(chrome::kChromeVersionEnvVar, base::WideToUTF8(version));
- // TODO(erikwright): Remove this when http://crbug.com/174953 is fixed and
- // widely deployed.
- env->UnSetVar(env_vars::kGoogleUpdateIsMachineEnvVar);
-
- const CommandLine& cmd_line = *CommandLine::ForCurrentProcess();
- std::string process_type =
- cmd_line.GetSwitchValueASCII(switches::kProcessType);
- breakpad::InitCrashReporter(process_type);
- OnBeforeLaunch(file);
-
- DLL_MAIN entry_point =
- reinterpret_cast<DLL_MAIN>(::GetProcAddress(dll_, "ChromeMain"));
- if (!entry_point)
- return chrome::RESULT_CODE_BAD_PROCESS_TYPE;
-
- int rc = entry_point(instance, sbox_info);
- return OnBeforeExit(rc, file);
+ if (metro_mode_) {
+ InitMetro init_metro_fn =
+ reinterpret_cast<InitMetro>(::GetProcAddress(dll_, "InitMetro"));
+ return init_metro_fn();
+ } else {
+ scoped_ptr<base::Environment> env(base::Environment::Create());
+ env->SetVar(chrome::kChromeVersionEnvVar, base::WideToUTF8(version));
+ // TODO(erikwright): Remove this when http://crbug.com/174953 is fixed and
+ // widely deployed.
+ env->UnSetVar(env_vars::kGoogleUpdateIsMachineEnvVar);
+
+ breakpad::InitCrashReporter(process_type);
+ OnBeforeLaunch(file);
+
+ DLL_MAIN chrome_main =
+ reinterpret_cast<DLL_MAIN>(::GetProcAddress(dll_, "ChromeMain"));
+ int rc = chrome_main(instance, sbox_info);
+ return OnBeforeExit(rc, file);
+ }
}
void MainDllLoader::RelaunchChromeBrowserWithNewCommandLineIfNeeded() {
+ if (metro_mode_)
+ return;
+
RelaunchChromeBrowserWithNewCommandLineIfNeededFunc relaunch_function =
reinterpret_cast<RelaunchChromeBrowserWithNewCommandLineIfNeededFunc>(
::GetProcAddress(dll_,
@@ -300,14 +321,7 @@ void MainDllLoader::RelaunchChromeBrowserWithNewCommandLineIfNeeded() {
//=============================================================================
class ChromeDllLoader : public MainDllLoader {
- public:
- virtual base::string16 GetRegistryPath() {
- base::string16 key(google_update::kRegPathClients);
- BrowserDistribution* dist = BrowserDistribution::GetDistribution();
- key.append(L"\\").append(dist->GetAppGuid());
- return key;
- }
-
+ protected:
virtual void OnBeforeLaunch(const base::string16& dll_path) {
RecordDidRun(dll_path);
}
@@ -326,10 +340,12 @@ class ChromeDllLoader : public MainDllLoader {
//=============================================================================
class ChromiumDllLoader : public MainDllLoader {
- public:
- virtual base::string16 GetRegistryPath() {
- BrowserDistribution* dist = BrowserDistribution::GetDistribution();
- return dist->GetVersionKey();
+ protected:
+ virtual void OnBeforeLaunch(const base::string16& dll_path) OVERRIDE {
+ }
+ virtual int OnBeforeExit(int return_code,
+ const base::string16& dll_path) OVERRIDE {
+ return return_code;
}
};
diff --git a/chrome/app/client_util.h b/chrome/app/client_util.h
index 5b8ebf6..8b6184aa 100644
--- a/chrome/app/client_util.h
+++ b/chrome/app/client_util.h
@@ -23,7 +23,7 @@ base::string16 GetExecutablePath();
// string if none found.
base::string16 GetCurrentModuleVersion();
-// Implements the common aspects of loading chrome.dll for both chrome and
+// Implements the common aspects of loading the main dll for both chrome and
// chromium scenarios, which are in charge of implementing two abstract
// methods: GetRegistryPath() and OnBeforeLaunch().
class MainDllLoader {
@@ -42,28 +42,25 @@ class MainDllLoader {
// persistent mode an upgrade is detected.
void RelaunchChromeBrowserWithNewCommandLineIfNeeded();
+ protected:
// Called after chrome.dll has been loaded but before the entry point
// is invoked. Derived classes can implement custom actions here.
// |dll_path| refers to the path of the Chrome dll being loaded.
- virtual void OnBeforeLaunch(const base::string16& dll_path) {}
+ virtual void OnBeforeLaunch(const base::string16& dll_path) = 0;
// Called after the chrome.dll entry point returns and before terminating
// this process. The return value will be used as the process return code.
// |dll_path| refers to the path of the Chrome dll being loaded.
- virtual int OnBeforeExit(int return_code, const base::string16& dll_path) {
- return return_code;
- }
-
- protected:
- // Derived classes must return the relative registry path that holds the
- // most current version of chrome.dll.
- virtual base::string16 GetRegistryPath() = 0;
+ virtual int OnBeforeExit(int return_code, const base::string16& dll_path) = 0;
- HMODULE Load(base::string16* out_version, base::string16* out_file);
+ private:
+ HMODULE Load(const wchar_t* dll_name,
+ base::string16* out_version,
+ base::string16* out_file);
private:
- // Chrome.dll handle.
HMODULE dll_;
+ const bool metro_mode_;
};
// Factory for the MainDllLoader. Caller owns the pointer and should call
diff --git a/chrome/app/metro_driver_win.cc b/chrome/app/metro_driver_win.cc
deleted file mode 100644
index faaff88..0000000
--- a/chrome/app/metro_driver_win.cc
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright (c) 2012 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 "metro_driver_win.h"
-
-#include <string.h>
-
-#include "chrome/app/client_util.h"
-#include "chrome/common/chrome_constants.h"
-
-namespace {
-// This environment variable controls the loading of the metro driver DLL.
-const char* kMetroModeEnvVar = "CHROME_METRO_DLL";
-
-typedef int (*InitMetro)(LPTHREAD_START_ROUTINE thread_proc, void* context);
-
-struct Context {
- MetroDriver::MainFn fn;
- HINSTANCE instance;
-};
-
-DWORD WINAPI MainThread(void* param) {
- Context* context = reinterpret_cast<Context*>(param);
- int rv = context->fn(context->instance);
- delete context;
- return rv;
-}
-
-} // namespace
-
-MetroDriver::MetroDriver() : init_metro_fn_(NULL) {
- if (0 != ::GetEnvironmentVariableA(kMetroModeEnvVar, NULL, 0))
- return;
- // The metro activation always has the |ServerName| parameter. If we dont
- // see it, we are being launched in desktop mode.
- if (!wcsstr(::GetCommandLineW(), L" -ServerName:DefaultBrowserServer")) {
- ::SetEnvironmentVariableA(kMetroModeEnvVar, "0");
- return;
- }
- // We haven't tried to load the metro driver, this probably means we are the
- // browser. Find it or not we set the environment variable because we don't
- // want to keep trying in the child processes.
- HMODULE metro_dll = ::LoadLibraryW(chrome::kMetroDriverDll);
- if (!metro_dll) {
- // It is not next to the build output, so this must be an actual deployment
- // and in that case we need the mainloader to find the current version
- // directory.
- base::string16 version(GetCurrentModuleVersion());
- if (!version.empty()) {
- std::wstring exe_path(GetExecutablePath());
- exe_path.append(version).append(L"\\").append(chrome::kMetroDriverDll);
- metro_dll = ::LoadLibraryW(exe_path.c_str());
- }
- }
- // We set the environment variable always, so we don't keep trying in
- // the child processes.
- ::SetEnvironmentVariableA(kMetroModeEnvVar, metro_dll ? "1" : "0");
- if (!metro_dll)
- return;
- init_metro_fn_ = ::GetProcAddress(metro_dll, "InitMetro");
-}
-
-int MetroDriver::RunInMetro(HINSTANCE instance, MainFn main_fn) {
- Context* context = new Context;
- context->fn = main_fn;
- context->instance = instance;
-
- return reinterpret_cast<InitMetro>(init_metro_fn_)(&MainThread, context);
-}
diff --git a/chrome/app/metro_driver_win.h b/chrome/app/metro_driver_win.h
deleted file mode 100644
index b99a9af..0000000
--- a/chrome/app/metro_driver_win.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (c) 2011 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_APP_METRO_DRIVER_WIN_H_
-#define CHROME_APP_METRO_DRIVER_WIN_H_
-
-#include <Windows.h>
-
-// Helper class to manage the metro driver dll. When present in the system,
-// the main process thread needs to call InitMetro(), normal execution of
-// chrome initialization will continue on a second thread while the main
-// thread will be servicing the metro message loop.
-class MetroDriver {
- public:
- typedef int (*MainFn)(HINSTANCE instance);
-
- MetroDriver();
- // returns true if chrome is being launched in metro. If so we should
- // call RunInMetro(). If not then we should just run chrome as usual.
- bool in_metro_mode() const { return (NULL != init_metro_fn_); }
-
- // Enter the metro main function, which will only return when chrome metro
- // is closed. Once metro has initialized, the dll creates a new thread
- // which runs |main_fn|. This method returns when the chrome metro session
- // is closed by the user.
- int RunInMetro(HINSTANCE instance, MainFn main_fn);
-
- private:
- void* init_metro_fn_;
-};
-
-#endif // CHROME_APP_METRO_DRIVER_WIN_H_