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 "win8/delegate_execute/chrome_util.h" | 5 #include "win8/delegate_execute/chrome_util.h" |
| 6 | 6 |
| 7 #include <windows.h> | 7 #include <windows.h> |
| 8 #include <atlbase.h> | 8 #include <atlbase.h> |
| 9 #include <shlobj.h> | 9 #include <shlobj.h> |
| 10 | 10 |
| 11 #include <algorithm> | 11 #include <algorithm> |
| 12 #include <limits> | 12 #include <limits> |
| 13 #include <string> | 13 #include <string> |
| 14 | 14 |
| 15 #include "base/file_util.h" | 15 #include "base/file_util.h" |
| 16 #include "base/files/file_path.h" | 16 #include "base/files/file_path.h" |
| 17 #include "base/md5.h" | 17 #include "base/md5.h" |
| 18 #include "base/process/kill.h" | 18 #include "base/process/kill.h" |
| 19 #include "base/process/launch.h" | 19 #include "base/process/launch.h" |
| 20 #include "base/process/process_handle.h" | 20 #include "base/process/process_handle.h" |
| 21 #include "base/strings/string_util.h" | 21 #include "base/strings/string_util.h" |
| 22 #include "base/strings/utf_string_conversions.h" | 22 #include "base/strings/utf_string_conversions.h" |
| 23 #include "base/win/registry.h" | 23 #include "base/win/registry.h" |
| 24 #include "base/win/scoped_comptr.h" | 24 #include "base/win/scoped_comptr.h" |
| 25 #include "base/win/scoped_handle.h" | 25 #include "base/win/scoped_handle.h" |
| 26 #include "base/win/win_util.h" | 26 #include "base/win/win_util.h" |
| 27 #include "chrome/installer/util/browser_distribution.h" | |
| 28 #include "chrome/installer/util/install_util.h" | |
| 29 #include "chrome/installer/util/util_constants.h" | |
| 27 #include "google_update/google_update_idl.h" | 30 #include "google_update/google_update_idl.h" |
| 28 | 31 |
| 29 namespace { | 32 namespace { |
| 30 | 33 |
| 31 #if defined(GOOGLE_CHROME_BUILD) | 34 #if defined(GOOGLE_CHROME_BUILD) |
| 32 const wchar_t kAppUserModelId[] = L"Chrome"; | |
| 33 #else // GOOGLE_CHROME_BUILD | |
| 34 const wchar_t kAppUserModelId[] = L"Chromium"; | |
| 35 #endif // GOOGLE_CHROME_BUILD | |
| 36 | |
| 37 #if defined(GOOGLE_CHROME_BUILD) | |
| 38 | 35 |
| 39 // TODO(grt): These constants live in installer_util. Consider moving them | 36 // TODO(grt): These constants live in installer_util. Consider moving them |
| 40 // into common_constants to allow for reuse. | 37 // into common_constants to allow for reuse. |
| 41 const base::FilePath::CharType kNewChromeExe[] = | 38 const base::FilePath::CharType kNewChromeExe[] = |
| 42 FILE_PATH_LITERAL("new_chrome.exe"); | 39 FILE_PATH_LITERAL("new_chrome.exe"); |
| 43 const wchar_t kRenameCommandValue[] = L"cmd"; | 40 const wchar_t kRenameCommandValue[] = L"cmd"; |
| 44 const wchar_t kChromeAppGuid[] = L"{8A69D345-D564-463c-AFF1-A69D9E530F96}"; | 41 const wchar_t kRegPathChromeClientBase[] = |
| 45 const wchar_t kRegPathChromeClient[] = | 42 L"Software\\Google\\Update\\Clients\\"; |
| 46 L"Software\\Google\\Update\\Clients\\" | |
| 47 L"{8A69D345-D564-463c-AFF1-A69D9E530F96}"; | |
| 48 const int kExitCodeRenameSuccessful = 23; | |
| 49 | 43 |
| 50 // Returns the name of the global event used to detect if |chrome_exe| is in | 44 // Returns the name of the global event used to detect if |chrome_exe| is in |
| 51 // use by a browser process. | 45 // use by a browser process. |
| 52 // TODO(grt): Move this somewhere central so it can be used by both this | 46 // TODO(grt): Move this somewhere central so it can be used by both this |
| 53 // IsBrowserRunning (below) and IsBrowserAlreadyRunning (browser_util_win.cc). | 47 // IsBrowserRunning (below) and IsBrowserAlreadyRunning (browser_util_win.cc). |
| 54 string16 GetEventName(const base::FilePath& chrome_exe) { | 48 string16 GetEventName(const base::FilePath& chrome_exe) { |
| 55 static wchar_t const kEventPrefix[] = L"Global\\"; | 49 static wchar_t const kEventPrefix[] = L"Global\\"; |
| 56 const size_t prefix_len = arraysize(kEventPrefix) - 1; | 50 const size_t prefix_len = arraysize(kEventPrefix) - 1; |
| 57 string16 name; | 51 string16 name; |
| 58 name.reserve(prefix_len + chrome_exe.value().size()); | 52 name.reserve(prefix_len + chrome_exe.value().size()); |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 81 | 75 |
| 82 // Returns true if the file new_chrome.exe exists in the same directory as | 76 // Returns true if the file new_chrome.exe exists in the same directory as |
| 83 // |chrome_exe|. | 77 // |chrome_exe|. |
| 84 bool NewChromeExeExists(const base::FilePath& chrome_exe) { | 78 bool NewChromeExeExists(const base::FilePath& chrome_exe) { |
| 85 base::FilePath new_chrome_exe(chrome_exe.DirName().Append(kNewChromeExe)); | 79 base::FilePath new_chrome_exe(chrome_exe.DirName().Append(kNewChromeExe)); |
| 86 return base::PathExists(new_chrome_exe); | 80 return base::PathExists(new_chrome_exe); |
| 87 } | 81 } |
| 88 | 82 |
| 89 bool GetUpdateCommand(bool is_per_user, string16* update_command) { | 83 bool GetUpdateCommand(bool is_per_user, string16* update_command) { |
| 90 const HKEY root = is_per_user ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE; | 84 const HKEY root = is_per_user ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE; |
| 91 base::win::RegKey key(root, kRegPathChromeClient, KEY_QUERY_VALUE); | 85 BrowserDistribution* dist = BrowserDistribution::GetDistribution(); |
| 86 string16 reg_path_chrome_client = kRegPathChromeClientBase; | |
| 87 reg_path_chrome_client.append(dist->GetAppGuid()); | |
| 88 base::win::RegKey key(root, reg_path_chrome_client.c_str(), KEY_QUERY_VALUE); | |
| 92 | 89 |
| 93 return key.ReadValue(kRenameCommandValue, update_command) == ERROR_SUCCESS; | 90 return key.ReadValue(kRenameCommandValue, update_command) == ERROR_SUCCESS; |
| 94 } | 91 } |
| 95 | 92 |
| 96 #endif // GOOGLE_CHROME_BUILD | 93 #endif // GOOGLE_CHROME_BUILD |
| 97 | 94 |
| 98 // TODO(grt): This code also lives in installer_util. Refactor for reuse. | 95 // TODO(grt): This code also lives in installer_util. Refactor for reuse. |
| 99 bool IsPerUserInstall(const base::FilePath& chrome_exe) { | 96 bool IsPerUserInstall(const base::FilePath& chrome_exe) { |
| 100 wchar_t program_files_path[MAX_PATH] = {0}; | 97 wchar_t program_files_path[MAX_PATH] = {0}; |
| 101 if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PROGRAM_FILES, NULL, | 98 if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PROGRAM_FILES, NULL, |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 220 } else { | 217 } else { |
| 221 // Run the update command via Google Update. | 218 // Run the update command via Google Update. |
| 222 HRESULT hr = S_OK; | 219 HRESULT hr = S_OK; |
| 223 base::win::ScopedComPtr<IProcessLauncher> process_launcher; | 220 base::win::ScopedComPtr<IProcessLauncher> process_launcher; |
| 224 hr = process_launcher.CreateInstance(__uuidof(ProcessLauncherClass)); | 221 hr = process_launcher.CreateInstance(__uuidof(ProcessLauncherClass)); |
| 225 if (FAILED(hr)) { | 222 if (FAILED(hr)) { |
| 226 AtlTrace("%hs. Failed to Create ProcessLauncher; hr=0x%X.\n", | 223 AtlTrace("%hs. Failed to Create ProcessLauncher; hr=0x%X.\n", |
| 227 __FUNCTION__, hr); | 224 __FUNCTION__, hr); |
| 228 } else { | 225 } else { |
| 229 ULONG_PTR handle = 0; | 226 ULONG_PTR handle = 0; |
| 227 BrowserDistribution* dist = BrowserDistribution::GetDistribution(); | |
| 230 hr = process_launcher->LaunchCmdElevated( | 228 hr = process_launcher->LaunchCmdElevated( |
| 231 kChromeAppGuid, kRenameCommandValue, GetCurrentProcessId(), &handle); | 229 dist->GetAppGuid().c_str(), kRenameCommandValue, |
| 230 GetCurrentProcessId(), &handle); | |
| 232 if (FAILED(hr)) { | 231 if (FAILED(hr)) { |
| 233 AtlTrace("%hs. Failed to launch command to finalize update; " | 232 AtlTrace("%hs. Failed to launch command to finalize update; " |
| 234 "hr=0x%X.\n", __FUNCTION__, hr); | 233 "hr=0x%X.\n", __FUNCTION__, hr); |
| 235 } else { | 234 } else { |
| 236 process_handle = reinterpret_cast<base::ProcessHandle>(handle); | 235 process_handle = reinterpret_cast<base::ProcessHandle>(handle); |
| 237 } | 236 } |
| 238 } | 237 } |
| 239 } | 238 } |
| 240 | 239 |
| 241 // Wait for the update to complete and report the results. | 240 // Wait for the update to complete and report the results. |
| 242 if (process_handle != base::kNullProcessHandle) { | 241 if (process_handle != base::kNullProcessHandle) { |
| 243 int exit_code = 0; | 242 int exit_code = 0; |
| 244 // WaitForExitCode will close the handle in all cases. | 243 // WaitForExitCode will close the handle in all cases. |
| 245 if (!base::WaitForExitCode(process_handle, &exit_code)) { | 244 if (!base::WaitForExitCode(process_handle, &exit_code)) { |
| 246 AtlTrace("%hs. Failed to get result when finalizing update.\n", | 245 AtlTrace("%hs. Failed to get result when finalizing update.\n", |
| 247 __FUNCTION__); | 246 __FUNCTION__); |
| 248 } else if (exit_code != kExitCodeRenameSuccessful) { | 247 } else if (exit_code != installer::RENAME_SUCCESSFUL) { |
| 249 AtlTrace("%hs. Failed to finalize update with exit code %d.\n", | 248 AtlTrace("%hs. Failed to finalize update with exit code %d.\n", |
| 250 __FUNCTION__, exit_code); | 249 __FUNCTION__, exit_code); |
| 251 } else { | 250 } else { |
| 252 AtlTrace("%hs. Finalized pending update.\n", __FUNCTION__); | 251 AtlTrace("%hs. Finalized pending update.\n", __FUNCTION__); |
| 253 } | 252 } |
| 254 } | 253 } |
| 255 #endif | 254 #endif |
| 256 } | 255 } |
| 257 | 256 |
| 258 // TODO(gab): This code also lives in shell_util. Refactor for reuse. | |
| 259 string16 GetAppId(const base::FilePath& chrome_exe) { | |
| 260 string16 app_id(kAppUserModelId); | |
| 261 string16 suffix; | |
| 262 if (IsPerUserInstall(chrome_exe) && | |
| 263 !GetUserSpecificRegistrySuffix(&suffix)) { | |
|
gab
2013/09/06 18:40:08
You can likely get rid of these local methods copi
zturner
2013/09/06 20:53:16
Done.
| |
| 264 AtlTrace("%hs. GetUserSpecificRegistrySuffix failed.\n", | |
| 265 __FUNCTION__); | |
| 266 } | |
| 267 return app_id.append(suffix); | |
| 268 } | |
| 269 | |
| 270 } // delegate_execute | 257 } // delegate_execute |
| OLD | NEW |