summaryrefslogtreecommitdiffstats
path: root/chrome/app
diff options
context:
space:
mode:
authorcpu@chromium.org <cpu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-01-25 23:49:16 +0000
committercpu@chromium.org <cpu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-01-25 23:49:16 +0000
commit57d83182d3280f27f57daa5c1778f1fdf1fbfaee (patch)
treec63a7aa4c6995b70b0a07dcf13f4b65937f81de8 /chrome/app
parentbf226999cde8c97a64ba6ac39641b46e10b4fc3e (diff)
downloadchromium_src-57d83182d3280f27f57daa5c1778f1fdf1fbfaee.zip
chromium_src-57d83182d3280f27f57daa5c1778f1fdf1fbfaee.tar.gz
chromium_src-57d83182d3280f27f57daa5c1778f1fdf1fbfaee.tar.bz2
Revert 247151 "Cleanup of windows launch code"
> Cleanup of windows launch code > > The windows startup code was handling aura and non-aura cases which > require different startup logic in metro (immersive mode). Since we > don't support the non-Aura logic we can get rid of a lot of code. > > Tbring gab for the installer constant addition. > > R=ananta@chromium.org, scottmg@chromium.org > TBR=gab > BUG=none > > Review URL: https://codereview.chromium.org/142473002 TBR=cpu@chromium.org Review URL: https://codereview.chromium.org/140123006 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@247156 0039d316-1c4b-4281-b951-d872f2087c98
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, 208 insertions, 107 deletions
diff --git a/chrome/app/chrome_exe_main_win.cc b/chrome/app/chrome_exe_main_win.cc
index 3c93752..51b1edf 100644
--- a/chrome/app/chrome_exe_main_win.cc
+++ b/chrome/app/chrome_exe_main_win.cc
@@ -13,6 +13,7 @@
#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"
@@ -40,6 +41,36 @@ 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
@@ -104,29 +135,9 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE prev, wchar_t*, int) {
if (AttemptFastNotify(*CommandLine::ForCurrentProcess()))
return 0;
- 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;
+ 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);
}
diff --git a/chrome/app/client_util.cc b/chrome/app/client_util.cc
index 054d58f..dd6becd 100644
--- a/chrome/app/client_util.cc
+++ b/chrome/app/client_util.cc
@@ -6,7 +6,6 @@
#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"
@@ -26,6 +25,8 @@
#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"
@@ -147,21 +148,29 @@ 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 LoadModuleWithDirectory(base::string16* dir,
- const wchar_t* dll_name,
- bool pre_read) {
+HMODULE LoadChromeWithDirectory(base::string16* dir) {
::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).
+ // 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)) {
const size_t kStepSize = 1024 * 1024;
size_t percentage = InitPreReadPercentage();
ImagePreReader::PartialPreReadImage(dir->c_str(), percentage, kStepSize);
-#endif
}
+#endif
return ::LoadLibraryExW(dir->c_str(), NULL,
LOAD_WITH_ALTERED_SEARCH_PATH);
@@ -177,13 +186,6 @@ 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() {
@@ -208,8 +210,7 @@ base::string16 GetCurrentModuleVersion() {
//=============================================================================
-MainDllLoader::MainDllLoader()
- : dll_(NULL), metro_mode_(InMetroMode()) {
+MainDllLoader::MainDllLoader() : dll_(NULL) {
}
MainDllLoader::~MainDllLoader() {
@@ -221,16 +222,12 @@ 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(const wchar_t* dll_name,
- base::string16* out_version,
+HMODULE MainDllLoader::Load(base::string16* out_version,
base::string16* out_file) {
const CommandLine& cmd_line = *CommandLine::ForCurrentProcess();
- 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);
+ const base::string16 dir(GetExecutablePath());
+ *out_file = dir;
+ HMODULE dll = LoadChromeWithDirectory(out_file);
if (!dll) {
// Loading from same directory (for developers) failed. Look at the version
// resource in the current module and try loading that.
@@ -240,10 +237,10 @@ HMODULE MainDllLoader::Load(const wchar_t* dll_name,
return NULL;
}
- *out_file = executable_dir;
+ *out_file = dir;
*out_version = version_string;
out_file->append(*out_version).append(1, L'\\');
- dll = LoadModuleWithDirectory(out_file, dll_name, pre_read);
+ dll = LoadChromeWithDirectory(out_file);
if (!dll) {
PLOG(ERROR) << "Failed to load Chrome DLL from " << *out_file;
return NULL;
@@ -251,6 +248,7 @@ HMODULE MainDllLoader::Load(const wchar_t* dll_name,
}
DCHECK(dll);
+
return dll;
}
@@ -259,53 +257,34 @@ HMODULE MainDllLoader::Load(const wchar_t* dll_name,
// 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(dll_name, &version, &file);
+ dll_ = Load(&version, &file);
if (!dll_)
return chrome::RESULT_CODE_MISSING_DATA;
- 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);
- }
+ 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);
}
void MainDllLoader::RelaunchChromeBrowserWithNewCommandLineIfNeeded() {
- if (metro_mode_)
- return;
-
RelaunchChromeBrowserWithNewCommandLineIfNeededFunc relaunch_function =
reinterpret_cast<RelaunchChromeBrowserWithNewCommandLineIfNeededFunc>(
::GetProcAddress(dll_,
@@ -321,7 +300,14 @@ void MainDllLoader::RelaunchChromeBrowserWithNewCommandLineIfNeeded() {
//=============================================================================
class ChromeDllLoader : public MainDllLoader {
- protected:
+ public:
+ virtual base::string16 GetRegistryPath() {
+ base::string16 key(google_update::kRegPathClients);
+ BrowserDistribution* dist = BrowserDistribution::GetDistribution();
+ key.append(L"\\").append(dist->GetAppGuid());
+ return key;
+ }
+
virtual void OnBeforeLaunch(const base::string16& dll_path) {
RecordDidRun(dll_path);
}
@@ -340,12 +326,10 @@ class ChromeDllLoader : public MainDllLoader {
//=============================================================================
class ChromiumDllLoader : public MainDllLoader {
- 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;
+ public:
+ virtual base::string16 GetRegistryPath() {
+ BrowserDistribution* dist = BrowserDistribution::GetDistribution();
+ return dist->GetVersionKey();
}
};
diff --git a/chrome/app/client_util.h b/chrome/app/client_util.h
index 8b6184aa..5b8ebf6 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 the main dll for both chrome and
+// Implements the common aspects of loading chrome.dll for both chrome and
// chromium scenarios, which are in charge of implementing two abstract
// methods: GetRegistryPath() and OnBeforeLaunch().
class MainDllLoader {
@@ -42,25 +42,28 @@ 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) = 0;
+ virtual void OnBeforeLaunch(const base::string16& dll_path) {}
// 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) = 0;
+ virtual int OnBeforeExit(int return_code, const base::string16& dll_path) {
+ return return_code;
+ }
- private:
- HMODULE Load(const wchar_t* dll_name,
- base::string16* out_version,
- base::string16* out_file);
+ protected:
+ // Derived classes must return the relative registry path that holds the
+ // most current version of chrome.dll.
+ virtual base::string16 GetRegistryPath() = 0;
+
+ HMODULE Load(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
new file mode 100644
index 0000000..faaff88
--- /dev/null
+++ b/chrome/app/metro_driver_win.cc
@@ -0,0 +1,70 @@
+// 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
new file mode 100644
index 0000000..b99a9af
--- /dev/null
+++ b/chrome/app/metro_driver_win.h
@@ -0,0 +1,33 @@
+// 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_