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 28 matching lines...) Expand all Loading... | |
| 82 GoogleUpdateSettings::UpdateDidRunState(false, system_level); | 83 GoogleUpdateSettings::UpdateDidRunState(false, system_level); |
| 83 } | 84 } |
| 84 | 85 |
| 85 bool InMetroMode() { | 86 bool InMetroMode() { |
| 86 return (wcsstr( | 87 return (wcsstr( |
| 87 ::GetCommandLineW(), L" -ServerName:DefaultBrowserServer") != nullptr); | 88 ::GetCommandLineW(), L" -ServerName:DefaultBrowserServer") != nullptr); |
| 88 } | 89 } |
| 89 | 90 |
| 90 typedef int (*InitMetro)(); | 91 typedef int (*InitMetro)(); |
| 91 | 92 |
| 93 // Returns the directory in which the currently running executable resides. | |
| 94 base::FilePath GetExecutableDir() { | |
| 95 base::char16 path[MAX_PATH]; | |
| 96 ::GetModuleFileNameW(nullptr, path, MAX_PATH); | |
| 97 return base::FilePath(path).DirName(); | |
| 98 } | |
| 99 | |
| 100 bool WrapMessageBoxWithSEH(const wchar_t* text, | |
| 101 const wchar_t* caption, | |
| 102 UINT flags, | |
| 103 bool* exit_now) { | |
| 104 // We wrap the call to MessageBoxW with a SEH handler because it some | |
| 105 // machines with CursorXP, PeaDict or with FontExplorer installed it crashes | |
| 106 // uncontrollably here. Being this a best effort deal we better go away. | |
| 107 __try { | |
| 108 *exit_now = (IDOK != ::MessageBoxW(NULL, text, caption, flags)); | |
| 109 } __except(EXCEPTION_EXECUTE_HANDLER) { | |
| 110 // Its not safe to continue executing, exit silently here. | |
| 111 ::TerminateProcess( | |
| 112 ::GetCurrentProcess(), | |
| 113 g_chrome_crash_client.Pointer()->GetResultCodeRespawnFailed()); | |
| 114 } | |
| 115 | |
| 116 return true; | |
| 117 } | |
| 118 | |
| 119 // This function is executed by the child process that DumpDoneCallback() | |
| 120 // spawned and basically just shows the 'chrome has crashed' dialog if | |
| 121 // the CHROME_CRASHED environment variable is present. | |
| 122 bool ShowRestartDialogIfCrashed(bool* exit_now) { | |
| 123 // If we are being launched in metro mode don't try to show the dialog. | |
| 124 if (base::win::IsMetroProcess()) | |
|
cpu_(ooo_6.6-7.5)
2015/11/07 01:53:17
mmm .. see line 86
scottmg
2015/11/09 18:29:56
Removed the local one.
| |
| 125 return false; | |
| 126 | |
| 127 base::string16 message; | |
| 128 base::string16 title; | |
| 129 bool is_rtl_locale; | |
| 130 if (!g_chrome_crash_client.Pointer()->ShouldShowRestartDialog( | |
| 131 &title, &message, &is_rtl_locale)) { | |
| 132 return false; | |
| 133 } | |
| 134 | |
| 135 // If the UI layout is right-to-left, we need to pass the appropriate MB_XXX | |
| 136 // flags so that an RTL message box is displayed. | |
| 137 UINT flags = MB_OKCANCEL | MB_ICONWARNING; | |
| 138 if (is_rtl_locale) | |
| 139 flags |= MB_RIGHT | MB_RTLREADING; | |
| 140 | |
| 141 return WrapMessageBoxWithSEH(message.c_str(), title.c_str(), flags, exit_now); | |
| 142 } | |
| 143 | |
| 92 } // namespace | 144 } // namespace |
| 93 | 145 |
| 94 //============================================================================= | 146 //============================================================================= |
| 95 | 147 |
| 96 MainDllLoader::MainDllLoader() | 148 MainDllLoader::MainDllLoader() |
| 97 : dll_(nullptr), metro_mode_(InMetroMode()) { | 149 : dll_(nullptr), metro_mode_(InMetroMode()) { |
| 98 } | 150 } |
| 99 | 151 |
| 100 MainDllLoader::~MainDllLoader() { | 152 MainDllLoader::~MainDllLoader() { |
| 101 } | 153 } |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 151 if (metro_mode_) { | 203 if (metro_mode_) { |
| 152 HMODULE metro_dll = Load(&version, &file); | 204 HMODULE metro_dll = Load(&version, &file); |
| 153 if (!metro_dll) | 205 if (!metro_dll) |
| 154 return chrome::RESULT_CODE_MISSING_DATA; | 206 return chrome::RESULT_CODE_MISSING_DATA; |
| 155 | 207 |
| 156 InitMetro chrome_metro_main = | 208 InitMetro chrome_metro_main = |
| 157 reinterpret_cast<InitMetro>(::GetProcAddress(metro_dll, "InitMetro")); | 209 reinterpret_cast<InitMetro>(::GetProcAddress(metro_dll, "InitMetro")); |
| 158 return chrome_metro_main(); | 210 return chrome_metro_main(); |
| 159 } | 211 } |
| 160 | 212 |
| 213 chrome::RegisterPathProvider(); | |
| 214 | |
| 161 if (process_type_ == "watcher") { | 215 if (process_type_ == "watcher") { |
| 162 chrome::RegisterPathProvider(); | |
| 163 | 216 |
| 164 base::win::ScopedHandle parent_process; | 217 base::win::ScopedHandle parent_process; |
| 165 base::win::ScopedHandle on_initialized_event; | 218 base::win::ScopedHandle on_initialized_event; |
| 166 DWORD main_thread_id = 0; | 219 DWORD main_thread_id = 0; |
| 167 if (!InterpretChromeWatcherCommandLine(cmd_line, &parent_process, | 220 if (!InterpretChromeWatcherCommandLine(cmd_line, &parent_process, |
| 168 &main_thread_id, | 221 &main_thread_id, |
| 169 &on_initialized_event)) { | 222 &on_initialized_event)) { |
| 170 return chrome::RESULT_CODE_UNSUPPORTED_PARAM; | 223 return chrome::RESULT_CODE_UNSUPPORTED_PARAM; |
| 171 } | 224 } |
| 172 | 225 |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 202 message_window_name.c_str(), channel_name.c_str()); | 255 message_window_name.c_str(), channel_name.c_str()); |
| 203 } | 256 } |
| 204 | 257 |
| 205 // Initialize the sandbox services. | 258 // Initialize the sandbox services. |
| 206 sandbox::SandboxInterfaceInfo sandbox_info = {0}; | 259 sandbox::SandboxInterfaceInfo sandbox_info = {0}; |
| 207 content::InitializeSandboxInfo(&sandbox_info); | 260 content::InitializeSandboxInfo(&sandbox_info); |
| 208 | 261 |
| 209 crash_reporter::SetCrashReporterClient(g_chrome_crash_client.Pointer()); | 262 crash_reporter::SetCrashReporterClient(g_chrome_crash_client.Pointer()); |
| 210 bool exit_now = true; | 263 bool exit_now = true; |
| 211 if (process_type_.empty()) { | 264 if (process_type_.empty()) { |
| 212 if (breakpad::ShowRestartDialogIfCrashed(&exit_now)) { | 265 if (ShowRestartDialogIfCrashed(&exit_now)) { |
| 213 // We restarted because of a previous crash. Ask user if we should | 266 // We restarted because of a previous crash. Ask user if we should |
| 214 // Relaunch. Only for the browser process. See crbug.com/132119. | 267 // Relaunch. Only for the browser process. See crbug.com/132119. |
| 215 if (exit_now) | 268 if (exit_now) |
| 216 return content::RESULT_CODE_NORMAL_EXIT; | 269 return content::RESULT_CODE_NORMAL_EXIT; |
| 217 } | 270 } |
| 218 } | 271 } |
| 219 breakpad::InitCrashReporter(process_type_); | 272 |
| 273 crash_reporter::InitializeCrashpad(process_type_ == "", process_type_); | |
| 220 | 274 |
| 221 dll_ = Load(&version, &file); | 275 dll_ = Load(&version, &file); |
| 222 if (!dll_) | 276 if (!dll_) |
| 223 return chrome::RESULT_CODE_MISSING_DATA; | 277 return chrome::RESULT_CODE_MISSING_DATA; |
| 224 | 278 |
| 225 scoped_ptr<base::Environment> env(base::Environment::Create()); | 279 scoped_ptr<base::Environment> env(base::Environment::Create()); |
| 226 env->SetVar(chrome::kChromeVersionEnvVar, base::WideToUTF8(version)); | 280 env->SetVar(chrome::kChromeVersionEnvVar, base::WideToUTF8(version)); |
| 227 | 281 |
| 228 OnBeforeLaunch(process_type_, file); | 282 OnBeforeLaunch(process_type_, file); |
| 229 DLL_MAIN chrome_main = | 283 DLL_MAIN chrome_main = |
| 230 reinterpret_cast<DLL_MAIN>(::GetProcAddress(dll_, "ChromeMain")); | 284 reinterpret_cast<DLL_MAIN>(::GetProcAddress(dll_, "ChromeMain")); |
| 231 int rc = chrome_main(instance, &sandbox_info); | 285 int rc = chrome_main(instance, &sandbox_info); |
| 232 rc = OnBeforeExit(rc, file); | 286 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) | |
| 238 breakpad::ConsumeInvalidHandleExceptions(); | |
| 239 return rc; | 287 return rc; |
| 240 } | 288 } |
| 241 | 289 |
| 242 void MainDllLoader::RelaunchChromeBrowserWithNewCommandLineIfNeeded() { | 290 void MainDllLoader::RelaunchChromeBrowserWithNewCommandLineIfNeeded() { |
| 243 if (!dll_) | 291 if (!dll_) |
| 244 return; | 292 return; |
| 245 | 293 |
| 246 RelaunchChromeBrowserWithNewCommandLineIfNeededFunc relaunch_function = | 294 RelaunchChromeBrowserWithNewCommandLineIfNeededFunc relaunch_function = |
| 247 reinterpret_cast<RelaunchChromeBrowserWithNewCommandLineIfNeededFunc>( | 295 reinterpret_cast<RelaunchChromeBrowserWithNewCommandLineIfNeededFunc>( |
| 248 ::GetProcAddress(dll_, | 296 ::GetProcAddress(dll_, |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 342 } | 390 } |
| 343 }; | 391 }; |
| 344 | 392 |
| 345 MainDllLoader* MakeMainDllLoader() { | 393 MainDllLoader* MakeMainDllLoader() { |
| 346 #if defined(GOOGLE_CHROME_BUILD) | 394 #if defined(GOOGLE_CHROME_BUILD) |
| 347 return new ChromeDllLoader(); | 395 return new ChromeDllLoader(); |
| 348 #else | 396 #else |
| 349 return new ChromiumDllLoader(); | 397 return new ChromiumDllLoader(); |
| 350 #endif | 398 #endif |
| 351 } | 399 } |
| OLD | NEW |