Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <windows.h> // NOLINT | 5 #include <windows.h> // NOLINT |
| 6 #include <shlwapi.h> // NOLINT | 6 #include <shlwapi.h> // NOLINT |
| 7 | 7 |
| 8 #include "chrome/app/main_dll_loader_win.h" | 8 #include "chrome/app/main_dll_loader_win.h" |
| 9 | 9 |
| 10 #include "base/base_paths.h" | 10 #include "base/base_paths.h" |
| 11 #include "base/base_switches.h" | 11 #include "base/base_switches.h" |
| 12 #include "base/command_line.h" | 12 #include "base/command_line.h" |
| 13 #include "base/compiler_specific.h" | 13 #include "base/compiler_specific.h" |
| 14 #include "base/environment.h" | 14 #include "base/environment.h" |
| 15 #include "base/lazy_instance.h" | 15 #include "base/lazy_instance.h" |
| 16 #include "base/logging.h" | 16 #include "base/logging.h" |
| 17 #include "base/memory/scoped_ptr.h" | 17 #include "base/memory/scoped_ptr.h" |
| 18 #include "base/path_service.h" | 18 #include "base/path_service.h" |
| 19 #include "base/strings/string16.h" | 19 #include "base/strings/string16.h" |
| 20 #include "base/strings/string_util.h" | 20 #include "base/strings/string_util.h" |
| 21 #include "base/strings/stringprintf.h" | 21 #include "base/strings/stringprintf.h" |
| 22 #include "base/strings/utf_string_conversions.h" | 22 #include "base/strings/utf_string_conversions.h" |
| 23 #include "base/trace_event/trace_event.h" | 23 #include "base/trace_event/trace_event.h" |
| 24 #include "base/win/metro.h" | |
| 24 #include "base/win/scoped_handle.h" | 25 #include "base/win/scoped_handle.h" |
| 25 #include "base/win/windows_version.h" | 26 #include "base/win/windows_version.h" |
| 26 #include "chrome/app/chrome_crash_reporter_client.h" | 27 #include "chrome/app/chrome_crash_reporter_client.h" |
| 27 #include "chrome/app/chrome_watcher_client_win.h" | 28 #include "chrome/app/chrome_watcher_client_win.h" |
| 28 #include "chrome/app/chrome_watcher_command_line_win.h" | 29 #include "chrome/app/chrome_watcher_command_line_win.h" |
| 29 #include "chrome/app/image_pre_reader_win.h" | 30 #include "chrome/app/image_pre_reader_win.h" |
| 30 #include "chrome/app/kasko_client.h" | 31 #include "chrome/app/kasko_client.h" |
| 31 #include "chrome/chrome_watcher/chrome_watcher_main_api.h" | 32 #include "chrome/chrome_watcher/chrome_watcher_main_api.h" |
| 32 #include "chrome/common/chrome_constants.h" | 33 #include "chrome/common/chrome_constants.h" |
| 33 #include "chrome/common/chrome_paths.h" | 34 #include "chrome/common/chrome_paths.h" |
| 34 #include "chrome/common/chrome_result_codes.h" | 35 #include "chrome/common/chrome_result_codes.h" |
| 35 #include "chrome/common/chrome_switches.h" | 36 #include "chrome/common/chrome_switches.h" |
| 36 #include "chrome/common/env_vars.h" | 37 #include "chrome/common/env_vars.h" |
| 37 #include "chrome/installer/util/google_update_constants.h" | 38 #include "chrome/installer/util/google_update_constants.h" |
| 38 #include "chrome/installer/util/google_update_settings.h" | 39 #include "chrome/installer/util/google_update_settings.h" |
| 39 #include "chrome/installer/util/install_util.h" | 40 #include "chrome/installer/util/install_util.h" |
| 40 #include "chrome/installer/util/module_util_win.h" | 41 #include "chrome/installer/util/module_util_win.h" |
| 41 #include "chrome/installer/util/util_constants.h" | 42 #include "chrome/installer/util/util_constants.h" |
| 42 #include "components/crash/content/app/breakpad_win.h" | |
| 43 #include "components/crash/content/app/crash_reporter_client.h" | 43 #include "components/crash/content/app/crash_reporter_client.h" |
| 44 #include "components/crash/content/app/crashpad.h" | |
| 44 #include "content/public/app/sandbox_helper_win.h" | 45 #include "content/public/app/sandbox_helper_win.h" |
| 45 #include "content/public/common/content_switches.h" | 46 #include "content/public/common/content_switches.h" |
| 46 #include "sandbox/win/src/sandbox.h" | 47 #include "sandbox/win/src/sandbox.h" |
| 47 | 48 |
| 48 namespace { | 49 namespace { |
| 49 // The entry point signature of chrome.dll. | 50 // The entry point signature of chrome.dll. |
| 50 typedef int (*DLL_MAIN)(HINSTANCE, sandbox::SandboxInterfaceInfo*); | 51 typedef int (*DLL_MAIN)(HINSTANCE, sandbox::SandboxInterfaceInfo*); |
| 51 | 52 |
| 52 typedef void (*RelaunchChromeBrowserWithNewCommandLineIfNeededFunc)(); | 53 typedef void (*RelaunchChromeBrowserWithNewCommandLineIfNeededFunc)(); |
| 53 | 54 |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 75 void RecordDidRun(const base::FilePath& dll_path) { | 76 void RecordDidRun(const base::FilePath& dll_path) { |
| 76 bool system_level = !InstallUtil::IsPerUserInstall(dll_path); | 77 bool system_level = !InstallUtil::IsPerUserInstall(dll_path); |
| 77 GoogleUpdateSettings::UpdateDidRunState(true, system_level); | 78 GoogleUpdateSettings::UpdateDidRunState(true, system_level); |
| 78 } | 79 } |
| 79 | 80 |
| 80 void ClearDidRun(const base::FilePath& dll_path) { | 81 void ClearDidRun(const base::FilePath& dll_path) { |
| 81 bool system_level = !InstallUtil::IsPerUserInstall(dll_path); | 82 bool system_level = !InstallUtil::IsPerUserInstall(dll_path); |
| 82 GoogleUpdateSettings::UpdateDidRunState(false, system_level); | 83 GoogleUpdateSettings::UpdateDidRunState(false, system_level); |
| 83 } | 84 } |
| 84 | 85 |
| 85 bool InMetroMode() { | 86 typedef int (*InitMetro)(); |
| 86 return (wcsstr( | 87 |
| 87 ::GetCommandLineW(), L" -ServerName:DefaultBrowserServer") != nullptr); | 88 // Returns the directory in which the currently running executable resides. |
| 89 base::FilePath GetExecutableDir() { | |
| 90 base::char16 path[MAX_PATH]; | |
| 91 ::GetModuleFileNameW(nullptr, path, MAX_PATH); | |
| 92 return base::FilePath(path).DirName(); | |
| 88 } | 93 } |
| 89 | 94 |
| 90 typedef int (*InitMetro)(); | 95 bool WrapMessageBoxWithSEH(const wchar_t* text, |
| 96 const wchar_t* caption, | |
| 97 UINT flags, | |
| 98 bool* exit_now) { | |
| 99 // We wrap the call to MessageBoxW with a SEH handler because it some | |
|
Mark Mentovai
2015/11/10 17:21:17
it→on
scottmg
2015/11/16 21:48:39
Done.
| |
| 100 // machines with CursorXP, PeaDict or with FontExplorer installed it crashes | |
| 101 // uncontrollably here. Being this a best effort deal we better go away. | |
| 102 __try { | |
| 103 *exit_now = (IDOK != ::MessageBoxW(NULL, text, caption, flags)); | |
|
Mark Mentovai
2015/11/10 17:21:17
and maybe restyle this copied stuff to modern stan
scottmg
2015/11/16 21:48:39
Done.
| |
| 104 } __except(EXCEPTION_EXECUTE_HANDLER) { | |
| 105 // Its not safe to continue executing, exit silently here. | |
| 106 ::TerminateProcess( | |
| 107 ::GetCurrentProcess(), | |
| 108 g_chrome_crash_client.Pointer()->GetResultCodeRespawnFailed()); | |
| 109 } | |
| 110 | |
| 111 return true; | |
| 112 } | |
| 113 | |
| 114 // This function is executed by the child process that DumpDoneCallback() | |
| 115 // spawned and basically just shows the 'chrome has crashed' dialog if | |
| 116 // the CHROME_CRASHED environment variable is present. | |
| 117 bool ShowRestartDialogIfCrashed(bool* exit_now) { | |
| 118 // If we are being launched in metro mode don't try to show the dialog. | |
| 119 if (base::win::IsMetroProcess()) | |
| 120 return false; | |
| 121 | |
| 122 base::string16 message; | |
| 123 base::string16 title; | |
| 124 bool is_rtl_locale; | |
| 125 if (!g_chrome_crash_client.Pointer()->ShouldShowRestartDialog( | |
| 126 &title, &message, &is_rtl_locale)) { | |
| 127 return false; | |
| 128 } | |
| 129 | |
| 130 // If the UI layout is right-to-left, we need to pass the appropriate MB_XXX | |
| 131 // flags so that an RTL message box is displayed. | |
| 132 UINT flags = MB_OKCANCEL | MB_ICONWARNING; | |
| 133 if (is_rtl_locale) | |
| 134 flags |= MB_RIGHT | MB_RTLREADING; | |
| 135 | |
| 136 return WrapMessageBoxWithSEH(message.c_str(), title.c_str(), flags, exit_now); | |
| 137 } | |
| 91 | 138 |
| 92 } // namespace | 139 } // namespace |
| 93 | 140 |
| 94 //============================================================================= | 141 //============================================================================= |
| 95 | 142 |
| 96 MainDllLoader::MainDllLoader() | 143 MainDllLoader::MainDllLoader() |
| 97 : dll_(nullptr), metro_mode_(InMetroMode()) { | 144 : dll_(nullptr), metro_mode_(base::win::IsMetroProcess()) { |
|
cpu_(ooo_6.6-7.5)
2015/11/10 03:06:50
note that IsProcessImmersive() does not exist in w
scottmg
2015/11/16 21:48:39
Hmm, is that OK? IsMetroProcess https://code.googl
| |
| 98 } | 145 } |
| 99 | 146 |
| 100 MainDllLoader::~MainDllLoader() { | 147 MainDllLoader::~MainDllLoader() { |
| 101 } | 148 } |
| 102 | 149 |
| 103 // Loading chrome is an interesting affair. First we try loading from the | 150 // Loading chrome is an interesting affair. First we try loading from the |
| 104 // current directory to support run-what-you-compile and other development | 151 // current directory to support run-what-you-compile and other development |
| 105 // scenarios. | 152 // scenarios. |
| 106 // If that fails then we look at the version resource in the current | 153 // If that fails then we look at the version resource in the current |
| 107 // module. This is the expected path for chrome.exe browser instances in an | 154 // module. This is the expected path for chrome.exe browser instances in an |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 151 if (metro_mode_) { | 198 if (metro_mode_) { |
| 152 HMODULE metro_dll = Load(&version, &file); | 199 HMODULE metro_dll = Load(&version, &file); |
| 153 if (!metro_dll) | 200 if (!metro_dll) |
| 154 return chrome::RESULT_CODE_MISSING_DATA; | 201 return chrome::RESULT_CODE_MISSING_DATA; |
| 155 | 202 |
| 156 InitMetro chrome_metro_main = | 203 InitMetro chrome_metro_main = |
| 157 reinterpret_cast<InitMetro>(::GetProcAddress(metro_dll, "InitMetro")); | 204 reinterpret_cast<InitMetro>(::GetProcAddress(metro_dll, "InitMetro")); |
| 158 return chrome_metro_main(); | 205 return chrome_metro_main(); |
| 159 } | 206 } |
| 160 | 207 |
| 208 chrome::RegisterPathProvider(); | |
| 209 | |
| 161 if (process_type_ == "watcher") { | 210 if (process_type_ == "watcher") { |
| 162 chrome::RegisterPathProvider(); | |
| 163 | 211 |
| 164 base::win::ScopedHandle parent_process; | 212 base::win::ScopedHandle parent_process; |
| 165 base::win::ScopedHandle on_initialized_event; | 213 base::win::ScopedHandle on_initialized_event; |
| 166 DWORD main_thread_id = 0; | 214 DWORD main_thread_id = 0; |
| 167 if (!InterpretChromeWatcherCommandLine(cmd_line, &parent_process, | 215 if (!InterpretChromeWatcherCommandLine(cmd_line, &parent_process, |
| 168 &main_thread_id, | 216 &main_thread_id, |
| 169 &on_initialized_event)) { | 217 &on_initialized_event)) { |
| 170 return chrome::RESULT_CODE_UNSUPPORTED_PARAM; | 218 return chrome::RESULT_CODE_UNSUPPORTED_PARAM; |
| 171 } | 219 } |
| 172 | 220 |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 202 message_window_name.c_str(), channel_name.c_str()); | 250 message_window_name.c_str(), channel_name.c_str()); |
| 203 } | 251 } |
| 204 | 252 |
| 205 // Initialize the sandbox services. | 253 // Initialize the sandbox services. |
| 206 sandbox::SandboxInterfaceInfo sandbox_info = {0}; | 254 sandbox::SandboxInterfaceInfo sandbox_info = {0}; |
| 207 content::InitializeSandboxInfo(&sandbox_info); | 255 content::InitializeSandboxInfo(&sandbox_info); |
| 208 | 256 |
| 209 crash_reporter::SetCrashReporterClient(g_chrome_crash_client.Pointer()); | 257 crash_reporter::SetCrashReporterClient(g_chrome_crash_client.Pointer()); |
| 210 bool exit_now = true; | 258 bool exit_now = true; |
| 211 if (process_type_.empty()) { | 259 if (process_type_.empty()) { |
| 212 if (breakpad::ShowRestartDialogIfCrashed(&exit_now)) { | 260 if (ShowRestartDialogIfCrashed(&exit_now)) { |
| 213 // We restarted because of a previous crash. Ask user if we should | 261 // We restarted because of a previous crash. Ask user if we should |
| 214 // Relaunch. Only for the browser process. See crbug.com/132119. | 262 // Relaunch. Only for the browser process. See crbug.com/132119. |
| 215 if (exit_now) | 263 if (exit_now) |
| 216 return content::RESULT_CODE_NORMAL_EXIT; | 264 return content::RESULT_CODE_NORMAL_EXIT; |
| 217 } | 265 } |
| 218 } | 266 } |
| 219 breakpad::InitCrashReporter(process_type_); | 267 |
| 268 crash_reporter::InitializeCrashpad(process_type_ == "", process_type_); | |
| 220 | 269 |
| 221 dll_ = Load(&version, &file); | 270 dll_ = Load(&version, &file); |
| 222 if (!dll_) | 271 if (!dll_) |
| 223 return chrome::RESULT_CODE_MISSING_DATA; | 272 return chrome::RESULT_CODE_MISSING_DATA; |
| 224 | 273 |
| 225 scoped_ptr<base::Environment> env(base::Environment::Create()); | 274 scoped_ptr<base::Environment> env(base::Environment::Create()); |
| 226 env->SetVar(chrome::kChromeVersionEnvVar, base::WideToUTF8(version)); | 275 env->SetVar(chrome::kChromeVersionEnvVar, base::WideToUTF8(version)); |
| 227 | 276 |
| 228 OnBeforeLaunch(process_type_, file); | 277 OnBeforeLaunch(process_type_, file); |
| 229 DLL_MAIN chrome_main = | 278 DLL_MAIN chrome_main = |
| 230 reinterpret_cast<DLL_MAIN>(::GetProcAddress(dll_, "ChromeMain")); | 279 reinterpret_cast<DLL_MAIN>(::GetProcAddress(dll_, "ChromeMain")); |
| 231 int rc = chrome_main(instance, &sandbox_info); | 280 int rc = chrome_main(instance, &sandbox_info); |
| 232 rc = OnBeforeExit(rc, file); | 281 rc = OnBeforeExit(rc, file); |
| 233 // Sandboxed processes close some system DLL handles after lockdown so ignore | |
| 234 // EXCEPTION_INVALID_HANDLE generated on Windows 10 during shutdown of these | |
| 235 // processes. | |
| 236 // TODO(wfh): Check whether MS have fixed this in Win10 RTM. crbug.com/456193 | |
| 237 if (base::win::GetVersion() >= base::win::VERSION_WIN10) | |
|
cpu_(ooo_6.6-7.5)
2015/11/10 03:06:50
scary ..
scottmg
2015/11/16 21:48:39
Yeah, I asked Will about this one, and he said it
| |
| 238 breakpad::ConsumeInvalidHandleExceptions(); | |
| 239 return rc; | 282 return rc; |
| 240 } | 283 } |
| 241 | 284 |
| 242 void MainDllLoader::RelaunchChromeBrowserWithNewCommandLineIfNeeded() { | 285 void MainDllLoader::RelaunchChromeBrowserWithNewCommandLineIfNeeded() { |
| 243 if (!dll_) | 286 if (!dll_) |
| 244 return; | 287 return; |
| 245 | 288 |
| 246 RelaunchChromeBrowserWithNewCommandLineIfNeededFunc relaunch_function = | 289 RelaunchChromeBrowserWithNewCommandLineIfNeededFunc relaunch_function = |
| 247 reinterpret_cast<RelaunchChromeBrowserWithNewCommandLineIfNeededFunc>( | 290 reinterpret_cast<RelaunchChromeBrowserWithNewCommandLineIfNeededFunc>( |
| 248 ::GetProcAddress(dll_, | 291 ::GetProcAddress(dll_, |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 342 } | 385 } |
| 343 }; | 386 }; |
| 344 | 387 |
| 345 MainDllLoader* MakeMainDllLoader() { | 388 MainDllLoader* MakeMainDllLoader() { |
| 346 #if defined(GOOGLE_CHROME_BUILD) | 389 #if defined(GOOGLE_CHROME_BUILD) |
| 347 return new ChromeDllLoader(); | 390 return new ChromeDllLoader(); |
| 348 #else | 391 #else |
| 349 return new ChromiumDllLoader(); | 392 return new ChromiumDllLoader(); |
| 350 #endif | 393 #endif |
| 351 } | 394 } |
| OLD | NEW |