Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(828)

Side by Side Diff: win8/delegate_execute/chrome_util.cc

Issue 23258005: Give SxS distribution its own registration GUIDs. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: More code cleanup, and remove DebugEnableSetAsDefault Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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();
gab 2013/09/10 19:08:57 Did you make sure that GetDistribution() returns t
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,
102 SHGFP_TYPE_CURRENT, program_files_path))) { 99 SHGFP_TYPE_CURRENT, program_files_path))) {
103 return !StartsWith(chrome_exe.value().c_str(), program_files_path, false); 100 return !StartsWith(chrome_exe.value().c_str(), program_files_path, false);
104 } else { 101 } else {
105 NOTREACHED(); 102 NOTREACHED();
106 } 103 }
107 return true; 104 return true;
108 } 105 }
109 106
110 // TODO(gab): This code also lives in shell_util. Refactor for reuse. 107 // TODO(gab): This code also lives in shell_util. Refactor for reuse.
111 string16 ByteArrayToBase32(const uint8* bytes, size_t size) { 108 string16 ByteArrayToBase32(const uint8* bytes, size_t size) {
gab 2013/09/10 19:08:57 Can remove this method now.
112 static const char kEncoding[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"; 109 static const char kEncoding[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
113 110
114 // Eliminate special cases first. 111 // Eliminate special cases first.
115 if (size == 0) { 112 if (size == 0) {
116 return string16(); 113 return string16();
117 } else if (size == 1) { 114 } else if (size == 1) {
118 string16 ret; 115 string16 ret;
119 ret.push_back(kEncoding[(bytes[0] & 0xf8) >> 3]); 116 ret.push_back(kEncoding[(bytes[0] & 0xf8) >> 3]);
120 ret.push_back(kEncoding[(bytes[0] & 0x07) << 2]); 117 ret.push_back(kEncoding[(bytes[0] & 0x07) << 2]);
121 return ret; 118 return ret;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 } 150 }
154 151
155 if (ret.length() != encoded_length) { 152 if (ret.length() != encoded_length) {
156 AtlTrace("%hs. Encoding doesn't match expected length.\n", __FUNCTION__); 153 AtlTrace("%hs. Encoding doesn't match expected length.\n", __FUNCTION__);
157 return string16(); 154 return string16();
158 } 155 }
159 return ret; 156 return ret;
160 } 157 }
161 158
162 // TODO(gab): This code also lives in shell_util. Refactor for reuse. 159 // TODO(gab): This code also lives in shell_util. Refactor for reuse.
163 bool GetUserSpecificRegistrySuffix(string16* suffix) { 160 bool GetUserSpecificRegistrySuffix(string16* suffix) {
gab 2013/09/10 19:08:57 Can remove this method now.
164 string16 user_sid; 161 string16 user_sid;
165 if (!base::win::GetUserSidString(&user_sid)) { 162 if (!base::win::GetUserSidString(&user_sid)) {
166 AtlTrace("%hs. GetUserSidString failed.\n", __FUNCTION__); 163 AtlTrace("%hs. GetUserSidString failed.\n", __FUNCTION__);
167 return false; 164 return false;
168 } 165 }
169 COMPILE_ASSERT(sizeof(base::MD5Digest) == 16, size_of_MD5_not_as_expected_); 166 COMPILE_ASSERT(sizeof(base::MD5Digest) == 16, size_of_MD5_not_as_expected_);
170 base::MD5Digest md5_digest; 167 base::MD5Digest md5_digest;
171 std::string user_sid_ascii(UTF16ToASCII(user_sid)); 168 std::string user_sid_ascii(UTF16ToASCII(user_sid));
172 base::MD5Sum(user_sid_ascii.c_str(), user_sid_ascii.length(), &md5_digest); 169 base::MD5Sum(user_sid_ascii.c_str(), user_sid_ascii.length(), &md5_digest);
173 const string16 base32_md5( 170 const string16 base32_md5(
(...skipping 19 matching lines...) Expand all
193 190
194 void UpdateChromeIfNeeded(const base::FilePath& chrome_exe) { 191 void UpdateChromeIfNeeded(const base::FilePath& chrome_exe) {
195 #if defined(GOOGLE_CHROME_BUILD) 192 #if defined(GOOGLE_CHROME_BUILD)
196 // Nothing to do if a browser is already running or if there's no 193 // Nothing to do if a browser is already running or if there's no
197 // new_chrome.exe. 194 // new_chrome.exe.
198 if (IsBrowserRunning(chrome_exe) || !NewChromeExeExists(chrome_exe)) 195 if (IsBrowserRunning(chrome_exe) || !NewChromeExeExists(chrome_exe))
199 return; 196 return;
200 197
201 base::ProcessHandle process_handle = base::kNullProcessHandle; 198 base::ProcessHandle process_handle = base::kNullProcessHandle;
202 199
203 if (IsPerUserInstall(chrome_exe)) { 200 if (IsPerUserInstall(chrome_exe)) {
gab 2013/09/10 19:08:57 This can now use InstallUtil::IsPerUserInstall().
204 // Read the update command from the registry. 201 // Read the update command from the registry.
205 string16 update_command; 202 string16 update_command;
206 if (!GetUpdateCommand(true, &update_command)) { 203 if (!GetUpdateCommand(true, &update_command)) {
207 AtlTrace("%hs. Failed to read update command from registry.\n", 204 AtlTrace("%hs. Failed to read update command from registry.\n",
208 __FUNCTION__); 205 __FUNCTION__);
209 } else { 206 } else {
210 // Run the update command. 207 // Run the update command.
211 base::LaunchOptions launch_options; 208 base::LaunchOptions launch_options;
212 launch_options.start_hidden = true; 209 launch_options.start_hidden = true;
213 if (!base::LaunchProcess(update_command, launch_options, 210 if (!base::LaunchProcess(update_command, launch_options,
214 &process_handle)) { 211 &process_handle)) {
215 AtlTrace("%hs. Failed to launch command to finalize update; " 212 AtlTrace("%hs. Failed to launch command to finalize update; "
216 "error %u.\n", __FUNCTION__, ::GetLastError()); 213 "error %u.\n", __FUNCTION__, ::GetLastError());
217 process_handle = base::kNullProcessHandle; 214 process_handle = base::kNullProcessHandle;
218 } 215 }
219 } 216 }
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)) {
264 AtlTrace("%hs. GetUserSpecificRegistrySuffix failed.\n",
265 __FUNCTION__);
266 }
267 return app_id.append(suffix);
268 }
269
270 } // delegate_execute 257 } // delegate_execute
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698