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 "chrome/browser/process_singleton.h" | 5 #include "chrome/browser/process_singleton.h" |
| 6 | 6 |
| 7 #include "base/base_paths.h" | 7 #include "base/base_paths.h" |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/file_path.h" | 9 #include "base/file_path.h" |
| 10 #include "base/path_service.h" | 10 #include "base/path_service.h" |
| 11 #include "base/process_util.h" | 11 #include "base/process_util.h" |
| 12 #include "base/stringprintf.h" | |
| 12 #include "base/utf_string_conversions.h" | 13 #include "base/utf_string_conversions.h" |
| 14 #include "base/win/metro.h" | |
| 13 #include "base/win/scoped_handle.h" | 15 #include "base/win/scoped_handle.h" |
| 14 #include "base/win/wrapped_window_proc.h" | 16 #include "base/win/wrapped_window_proc.h" |
| 15 #include "chrome/browser/ui/simple_message_box.h" | 17 #include "chrome/browser/ui/simple_message_box.h" |
| 16 #include "chrome/common/chrome_constants.h" | 18 #include "chrome/common/chrome_constants.h" |
| 17 #include "chrome/installer/util/wmi.h" | 19 #include "chrome/installer/util/wmi.h" |
| 18 #include "content/public/common/result_codes.h" | 20 #include "content/public/common/result_codes.h" |
| 19 #include "grit/chromium_strings.h" | 21 #include "grit/chromium_strings.h" |
| 20 #include "grit/generated_resources.h" | 22 #include "grit/generated_resources.h" |
| 23 #include "net/base/escape.h" | |
| 21 #include "ui/base/l10n/l10n_util.h" | 24 #include "ui/base/l10n/l10n_util.h" |
| 22 #include "ui/base/win/hwnd_util.h" | 25 #include "ui/base/win/hwnd_util.h" |
| 23 | 26 |
| 24 namespace { | 27 namespace { |
| 25 | 28 |
| 26 const char kLockfile[] = "lockfile"; | 29 const char kLockfile[] = "lockfile"; |
| 27 | 30 |
| 31 const char kSearchUrl[] = | |
| 32 "http://www.google.com/search?q=%s&sourceid=chrome&ie=UTF-8"; | |
| 33 | |
| 28 // Checks the visibility of the enumerated window and signals once a visible | 34 // Checks the visibility of the enumerated window and signals once a visible |
| 29 // window has been found. | 35 // window has been found. |
| 30 BOOL CALLBACK BrowserWindowEnumeration(HWND window, LPARAM param) { | 36 BOOL CALLBACK BrowserWindowEnumeration(HWND window, LPARAM param) { |
| 31 bool* result = reinterpret_cast<bool*>(param); | 37 bool* result = reinterpret_cast<bool*>(param); |
| 32 *result = IsWindowVisible(window) != 0; | 38 *result = IsWindowVisible(window) != 0; |
| 33 // Stops enumeration if a visible window has been found. | 39 // Stops enumeration if a visible window has been found. |
| 34 return !*result; | 40 return !*result; |
| 35 } | 41 } |
| 36 | 42 |
| 37 // This function thunks to the object's version of the windowproc, taking in | 43 // This function thunks to the object's version of the windowproc, taking in |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 105 | 111 |
| 106 // Get command line. | 112 // Get command line. |
| 107 const std::wstring cmd_line = | 113 const std::wstring cmd_line = |
| 108 msg.substr(second_null + 1, third_null - second_null); | 114 msg.substr(second_null + 1, third_null - second_null); |
| 109 *parsed_command_line = CommandLine::FromString(cmd_line); | 115 *parsed_command_line = CommandLine::FromString(cmd_line); |
| 110 return true; | 116 return true; |
| 111 } | 117 } |
| 112 return false; | 118 return false; |
| 113 } | 119 } |
| 114 | 120 |
| 121 // Find any top level, visible chrome window. The name is fragile | |
| 122 // but the file that defines the name warns against modification. | |
| 123 BOOL CALLBACK TopWindowFinder(HWND hwnd, LPARAM result) { | |
|
ananta
2012/08/22 20:58:45
This function is not used anymore. Please delete i
| |
| 124 char classname[128]; | |
| 125 if (::GetClassNameA(hwnd, classname, arraysize(classname))) { | |
| 126 if (IsWindowVisible(hwnd)) { | |
| 127 if (lstrcmpiA("Chrome_WidgetWin_1", classname) == 0) { | |
| 128 *reinterpret_cast<HWND*>(result) = hwnd; | |
| 129 return FALSE; | |
| 130 } | |
| 131 } | |
| 132 } | |
| 133 return TRUE; | |
| 134 } | |
| 135 | |
| 115 } // namespace | 136 } // namespace |
| 116 | 137 |
| 117 // Microsoft's Softricity virtualization breaks the sandbox processes. | 138 // Microsoft's Softricity virtualization breaks the sandbox processes. |
| 118 // So, if we detect the Softricity DLL we use WMI Win32_Process.Create to | 139 // So, if we detect the Softricity DLL we use WMI Win32_Process.Create to |
| 119 // break out of the virtualization environment. | 140 // break out of the virtualization environment. |
| 120 // http://code.google.com/p/chromium/issues/detail?id=43650 | 141 // http://code.google.com/p/chromium/issues/detail?id=43650 |
| 121 bool ProcessSingleton::EscapeVirtualization(const FilePath& user_data_dir) { | 142 bool ProcessSingleton::EscapeVirtualization(const FilePath& user_data_dir) { |
| 122 if (::GetModuleHandle(L"sftldr_wow64.dll") || | 143 if (::GetModuleHandle(L"sftldr_wow64.dll") || |
| 123 ::GetModuleHandle(L"sftldr.dll")) { | 144 ::GetModuleHandle(L"sftldr.dll")) { |
| 124 int process_id; | 145 int process_id; |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 232 } | 253 } |
| 233 | 254 |
| 234 ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcess() { | 255 ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcess() { |
| 235 if (is_virtualized_) | 256 if (is_virtualized_) |
| 236 return PROCESS_NOTIFIED; // We already spawned the process in this case. | 257 return PROCESS_NOTIFIED; // We already spawned the process in this case. |
| 237 if (lock_file_ == INVALID_HANDLE_VALUE && !remote_window_) | 258 if (lock_file_ == INVALID_HANDLE_VALUE && !remote_window_) |
| 238 return LOCK_ERROR; | 259 return LOCK_ERROR; |
| 239 else if (!remote_window_) | 260 else if (!remote_window_) |
| 240 return PROCESS_NONE; | 261 return PROCESS_NONE; |
| 241 | 262 |
| 242 // Found another window, send our command line to it | 263 DWORD process_id = 0; |
| 264 DWORD thread_id = GetWindowThreadProcessId(remote_window_, &process_id); | |
| 265 // It is possible that the process owning this window may have died by now. | |
| 266 if (!thread_id || !process_id) { | |
| 267 remote_window_ = NULL; | |
| 268 return PROCESS_NONE; | |
| 269 } | |
| 270 | |
| 271 if (base::win::IsMetroProcess()) { | |
| 272 // Interesting corner case. We are launched as a metro process but we | |
| 273 // found another chrome running. Since metro enforces single instance then | |
| 274 // the other chrome must be desktop chrome and this must be a search charm | |
| 275 // activation. This scenario is unique; other cases should be properly | |
| 276 // handled by the delegate_execute which will not activate a second chrome. | |
| 277 string16 terms; | |
| 278 base::win::MetroLaunchType launch = base::win::GetMetroLaunchParams(&terms); | |
| 279 if (launch != base::win::METRO_SEARCH) { | |
| 280 LOG(WARNING) << "In metro mode, but and launch is " << launch; | |
| 281 } else { | |
| 282 std::string query = net::EscapeQueryParamValue(UTF16ToUTF8(terms), true); | |
| 283 std::string url = base::StringPrintf(kSearchUrl, query.c_str()); | |
| 284 SHELLEXECUTEINFOA sei = { sizeof(sei) }; | |
| 285 sei.fMask = SEE_MASK_FLAG_LOG_USAGE; | |
| 286 sei.nShow = SW_SHOWNORMAL; | |
| 287 sei.lpFile = url.c_str(); | |
| 288 OutputDebugStringA(sei.lpFile); | |
| 289 sei.lpDirectory = ""; | |
| 290 ::ShellExecuteExA(&sei); | |
| 291 } | |
| 292 return PROCESS_NOTIFIED; | |
| 293 } | |
| 294 // Non-metro mode, send our command line to the other chrome message window. | |
| 243 // format is "START\0<<<current directory>>>\0<<<commandline>>>". | 295 // format is "START\0<<<current directory>>>\0<<<commandline>>>". |
| 244 std::wstring to_send(L"START\0", 6); // want the NULL in the string. | 296 std::wstring to_send(L"START\0", 6); // want the NULL in the string. |
| 245 FilePath cur_dir; | 297 FilePath cur_dir; |
| 246 if (!PathService::Get(base::DIR_CURRENT, &cur_dir)) | 298 if (!PathService::Get(base::DIR_CURRENT, &cur_dir)) |
| 247 return PROCESS_NONE; | 299 return PROCESS_NONE; |
| 248 to_send.append(cur_dir.value()); | 300 to_send.append(cur_dir.value()); |
| 249 to_send.append(L"\0", 1); // Null separator. | 301 to_send.append(L"\0", 1); // Null separator. |
| 250 to_send.append(GetCommandLineW()); | 302 to_send.append(GetCommandLineW()); |
| 251 to_send.append(L"\0", 1); // Null separator. | 303 to_send.append(L"\0", 1); // Null separator. |
| 252 | 304 |
| 253 // Allow the current running browser window making itself the foreground | 305 // Allow the current running browser window making itself the foreground |
| 254 // window (otherwise it will just flash in the taskbar). | 306 // window (otherwise it will just flash in the taskbar). |
| 255 DWORD process_id = 0; | |
| 256 DWORD thread_id = GetWindowThreadProcessId(remote_window_, &process_id); | |
| 257 // It is possible that the process owning this window may have died by now. | |
| 258 if (!thread_id || !process_id) { | |
| 259 remote_window_ = NULL; | |
| 260 return PROCESS_NONE; | |
| 261 } | |
| 262 | |
| 263 AllowSetForegroundWindow(process_id); | 307 AllowSetForegroundWindow(process_id); |
| 264 | 308 |
| 265 COPYDATASTRUCT cds; | 309 COPYDATASTRUCT cds; |
| 266 cds.dwData = 0; | 310 cds.dwData = 0; |
| 267 cds.cbData = static_cast<DWORD>((to_send.length() + 1) * sizeof(wchar_t)); | 311 cds.cbData = static_cast<DWORD>((to_send.length() + 1) * sizeof(wchar_t)); |
| 268 cds.lpData = const_cast<wchar_t*>(to_send.c_str()); | 312 cds.lpData = const_cast<wchar_t*>(to_send.c_str()); |
| 269 DWORD_PTR result = 0; | 313 DWORD_PTR result = 0; |
| 270 if (SendMessageTimeout(remote_window_, | 314 if (SendMessageTimeout(remote_window_, |
| 271 WM_COPYDATA, | 315 WM_COPYDATA, |
| 272 NULL, | 316 NULL, |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 371 switch (message) { | 415 switch (message) { |
| 372 case WM_COPYDATA: | 416 case WM_COPYDATA: |
| 373 return OnCopyData(reinterpret_cast<HWND>(wparam), | 417 return OnCopyData(reinterpret_cast<HWND>(wparam), |
| 374 reinterpret_cast<COPYDATASTRUCT*>(lparam)); | 418 reinterpret_cast<COPYDATASTRUCT*>(lparam)); |
| 375 default: | 419 default: |
| 376 break; | 420 break; |
| 377 } | 421 } |
| 378 | 422 |
| 379 return ::DefWindowProc(hwnd, message, wparam, lparam); | 423 return ::DefWindowProc(hwnd, message, wparam, lparam); |
| 380 } | 424 } |
| OLD | NEW |