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 // This file defines functions that integrate Chrome in Windows shell. These | 5 // This file defines functions that integrate Chrome in Windows shell. These |
6 // functions can be used by Chrome as well as Chrome installer. All of the | 6 // functions can be used by Chrome as well as Chrome installer. All of the |
7 // work is done by the local functions defined in anonymous namespace in | 7 // work is done by the local functions defined in anonymous namespace in |
8 // this class. | 8 // this class. |
9 | 9 |
10 #include "chrome/installer/util/shell_util.h" | 10 #include "chrome/installer/util/shell_util.h" |
11 | 11 |
12 #include <windows.h> | 12 #include <windows.h> |
13 #include <shlobj.h> | 13 #include <shlobj.h> |
14 #include <shobjidl.h> | 14 #include <shobjidl.h> |
15 | 15 |
| 16 #include <algorithm> |
| 17 #include <iterator> |
16 #include <limits> | 18 #include <limits> |
17 #include <memory> | 19 #include <memory> |
18 #include <string> | 20 #include <string> |
| 21 #include <utility> |
19 | 22 |
20 #include "base/bind.h" | 23 #include "base/bind.h" |
21 #include "base/command_line.h" | 24 #include "base/command_line.h" |
22 #include "base/files/file_enumerator.h" | 25 #include "base/files/file_enumerator.h" |
23 #include "base/files/file_path.h" | 26 #include "base/files/file_path.h" |
24 #include "base/files/file_util.h" | 27 #include "base/files/file_util.h" |
25 #include "base/lazy_instance.h" | 28 #include "base/lazy_instance.h" |
26 #include "base/logging.h" | 29 #include "base/logging.h" |
27 #include "base/macros.h" | 30 #include "base/macros.h" |
28 #include "base/md5.h" | 31 #include "base/md5.h" |
29 #include "base/memory/scoped_vector.h" | 32 #include "base/memory/ptr_util.h" |
30 #include "base/metrics/histogram_macros.h" | 33 #include "base/metrics/histogram_macros.h" |
31 #include "base/path_service.h" | 34 #include "base/path_service.h" |
32 #include "base/strings/string16.h" | 35 #include "base/strings/string16.h" |
33 #include "base/strings/string_number_conversions.h" | 36 #include "base/strings/string_number_conversions.h" |
34 #include "base/strings/string_piece.h" | 37 #include "base/strings/string_piece.h" |
35 #include "base/strings/string_split.h" | 38 #include "base/strings/string_split.h" |
36 #include "base/strings/string_util.h" | 39 #include "base/strings/string_util.h" |
37 #include "base/strings/stringprintf.h" | 40 #include "base/strings/stringprintf.h" |
38 #include "base/strings/utf_string_conversions.h" | 41 #include "base/strings/utf_string_conversions.h" |
39 #include "base/synchronization/cancellation_flag.h" | 42 #include "base/synchronization/cancellation_flag.h" |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
217 | 220 |
218 // Returns the Windows Default Programs capabilities key for Chrome. For | 221 // Returns the Windows Default Programs capabilities key for Chrome. For |
219 // example: | 222 // example: |
220 // "Software\Clients\StartMenuInternet\Chromium[.user]\Capabilities". | 223 // "Software\Clients\StartMenuInternet\Chromium[.user]\Capabilities". |
221 base::string16 GetCapabilitiesKey(const base::string16& suffix) { | 224 base::string16 GetCapabilitiesKey(const base::string16& suffix) { |
222 return GetBrowserClientKey(suffix).append(L"\\Capabilities"); | 225 return GetBrowserClientKey(suffix).append(L"\\Capabilities"); |
223 } | 226 } |
224 | 227 |
225 // DelegateExecute ProgId. Needed for Chrome Metro in Windows 8. This is only | 228 // DelegateExecute ProgId. Needed for Chrome Metro in Windows 8. This is only |
226 // needed for registring a web browser, not for general associations. | 229 // needed for registring a web browser, not for general associations. |
227 ScopedVector<RegistryEntry> GetChromeDelegateExecuteEntries( | 230 std::vector<std::unique_ptr<RegistryEntry>> GetChromeDelegateExecuteEntries( |
228 const base::FilePath& chrome_exe, | 231 const base::FilePath& chrome_exe, |
229 const ApplicationInfo& app_info) { | 232 const ApplicationInfo& app_info) { |
230 ScopedVector<RegistryEntry> entries; | 233 std::vector<std::unique_ptr<RegistryEntry>> entries; |
231 | 234 |
232 base::string16 app_id_shell_key(ShellUtil::kRegClasses); | 235 base::string16 app_id_shell_key(ShellUtil::kRegClasses); |
233 app_id_shell_key.push_back(base::FilePath::kSeparators[0]); | 236 app_id_shell_key.push_back(base::FilePath::kSeparators[0]); |
234 app_id_shell_key.append(app_info.app_id); | 237 app_id_shell_key.append(app_info.app_id); |
235 app_id_shell_key.append(ShellUtil::kRegExePath); | 238 app_id_shell_key.append(ShellUtil::kRegExePath); |
236 app_id_shell_key.append(ShellUtil::kRegShellPath); | 239 app_id_shell_key.append(ShellUtil::kRegShellPath); |
237 | 240 |
238 // <root hkey>\Software\Classes\<app_id>\.exe\shell @=open | 241 // <root hkey>\Software\Classes\<app_id>\.exe\shell @=open |
239 entries.push_back( | 242 entries.push_back(base::MakeUnique<RegistryEntry>(app_id_shell_key, |
240 new RegistryEntry(app_id_shell_key, ShellUtil::kRegVerbOpen)); | 243 ShellUtil::kRegVerbOpen)); |
241 | 244 |
242 // The command to execute when opening this application via the Metro UI. | 245 // The command to execute when opening this application via the Metro UI. |
243 const base::string16 delegate_command( | 246 const base::string16 delegate_command( |
244 ShellUtil::GetChromeDelegateCommand(chrome_exe)); | 247 ShellUtil::GetChromeDelegateCommand(chrome_exe)); |
245 | 248 |
246 // Each of Chrome's shortcuts has an appid; which, as of Windows 8, is | 249 // Each of Chrome's shortcuts has an appid; which, as of Windows 8, is |
247 // registered to handle some verbs. This registration has the side-effect | 250 // registered to handle some verbs. This registration has the side-effect |
248 // that these verbs now show up in the shortcut's context menu. We | 251 // that these verbs now show up in the shortcut's context menu. We |
249 // mitigate this side-effect by making the context menu entries | 252 // mitigate this side-effect by making the context menu entries |
250 // user readable/localized strings. See relevant MSDN article: | 253 // user readable/localized strings. See relevant MSDN article: |
251 // http://msdn.microsoft.com/en-US/library/windows/desktop/cc144171.aspx | 254 // http://msdn.microsoft.com/en-US/library/windows/desktop/cc144171.aspx |
252 static const struct { | 255 static const struct { |
253 const wchar_t* verb; | 256 const wchar_t* verb; |
254 int name_id; | 257 int name_id; |
255 } verbs[] = { | 258 } verbs[] = { |
256 {ShellUtil::kRegVerbOpen, -1}, | 259 {ShellUtil::kRegVerbOpen, -1}, |
257 {ShellUtil::kRegVerbOpenNewWindow, IDS_SHORTCUT_NEW_WINDOW_BASE}, | 260 {ShellUtil::kRegVerbOpenNewWindow, IDS_SHORTCUT_NEW_WINDOW_BASE}, |
258 }; | 261 }; |
259 for (const auto& verb_and_id : verbs) { | 262 for (const auto& verb_and_id : verbs) { |
260 base::string16 sub_path(app_id_shell_key); | 263 base::string16 sub_path(app_id_shell_key); |
261 sub_path.push_back(base::FilePath::kSeparators[0]); | 264 sub_path.push_back(base::FilePath::kSeparators[0]); |
262 sub_path.append(verb_and_id.verb); | 265 sub_path.append(verb_and_id.verb); |
263 | 266 |
264 // <root hkey>\Software\Classes\<app_id>\.exe\shell\<verb> | 267 // <root hkey>\Software\Classes\<app_id>\.exe\shell\<verb> |
265 if (verb_and_id.name_id != -1) { | 268 if (verb_and_id.name_id != -1) { |
266 // TODO(grt): http://crbug.com/75152 Write a reference to a localized | 269 // TODO(grt): http://crbug.com/75152 Write a reference to a localized |
267 // resource. | 270 // resource. |
268 const base::string16 verb_name( | 271 const base::string16 verb_name( |
269 installer::GetLocalizedString(verb_and_id.name_id)); | 272 installer::GetLocalizedString(verb_and_id.name_id)); |
270 entries.push_back(new RegistryEntry(sub_path, verb_name.c_str())); | 273 entries.push_back( |
| 274 base::MakeUnique<RegistryEntry>(sub_path, verb_name.c_str())); |
271 } | 275 } |
272 entries.push_back( | 276 entries.push_back(base::MakeUnique<RegistryEntry>(sub_path, L"CommandId", |
273 new RegistryEntry(sub_path, L"CommandId", L"Browser.Launch")); | 277 L"Browser.Launch")); |
274 | 278 |
275 sub_path.push_back(base::FilePath::kSeparators[0]); | 279 sub_path.push_back(base::FilePath::kSeparators[0]); |
276 sub_path.append(ShellUtil::kRegCommand); | 280 sub_path.append(ShellUtil::kRegCommand); |
277 | 281 |
278 // <root hkey>\Software\Classes\<app_id>\.exe\shell\<verb>\command | 282 // <root hkey>\Software\Classes\<app_id>\.exe\shell\<verb>\command |
279 entries.push_back(new RegistryEntry(sub_path, delegate_command)); | 283 entries.push_back( |
280 entries.push_back(new RegistryEntry( | 284 base::MakeUnique<RegistryEntry>(sub_path, delegate_command)); |
| 285 entries.push_back(base::MakeUnique<RegistryEntry>( |
281 sub_path, ShellUtil::kRegDelegateExecute, app_info.delegate_clsid)); | 286 sub_path, ShellUtil::kRegDelegateExecute, app_info.delegate_clsid)); |
282 } | 287 } |
283 | 288 |
284 return entries; | 289 return entries; |
285 } | 290 } |
286 | 291 |
287 // Gets the registry entries to register an application in the Windows registry. | 292 // Gets the registry entries to register an application in the Windows registry. |
288 // |app_info| provides all of the information needed. | 293 // |app_info| provides all of the information needed. |
289 void GetProgIdEntries(const ApplicationInfo& app_info, | 294 void GetProgIdEntries(const ApplicationInfo& app_info, |
290 ScopedVector<RegistryEntry>* entries) { | 295 std::vector<std::unique_ptr<RegistryEntry>>* entries) { |
291 // Basic sanity checks. | 296 // Basic sanity checks. |
292 DCHECK(!app_info.prog_id.empty()); | 297 DCHECK(!app_info.prog_id.empty()); |
293 DCHECK_NE(L'.', app_info.prog_id[0]); | 298 DCHECK_NE(L'.', app_info.prog_id[0]); |
294 | 299 |
295 // File association ProgId | 300 // File association ProgId |
296 base::string16 prog_id_path(ShellUtil::kRegClasses); | 301 base::string16 prog_id_path(ShellUtil::kRegClasses); |
297 prog_id_path.push_back(base::FilePath::kSeparators[0]); | 302 prog_id_path.push_back(base::FilePath::kSeparators[0]); |
298 prog_id_path.append(app_info.prog_id); | 303 prog_id_path.append(app_info.prog_id); |
299 entries->push_back(new RegistryEntry(prog_id_path, app_info.file_type_name)); | 304 entries->push_back( |
300 entries->push_back(new RegistryEntry( | 305 base::MakeUnique<RegistryEntry>(prog_id_path, app_info.file_type_name)); |
| 306 entries->push_back(base::MakeUnique<RegistryEntry>( |
301 prog_id_path + ShellUtil::kRegDefaultIcon, | 307 prog_id_path + ShellUtil::kRegDefaultIcon, |
302 ShellUtil::FormatIconLocation(app_info.file_type_icon_path, | 308 ShellUtil::FormatIconLocation(app_info.file_type_icon_path, |
303 app_info.file_type_icon_index))); | 309 app_info.file_type_icon_index))); |
304 entries->push_back(new RegistryEntry(prog_id_path + ShellUtil::kRegShellOpen, | 310 entries->push_back(base::MakeUnique<RegistryEntry>( |
305 app_info.command_line)); | 311 prog_id_path + ShellUtil::kRegShellOpen, app_info.command_line)); |
306 if (!app_info.delegate_clsid.empty()) { | 312 if (!app_info.delegate_clsid.empty()) { |
307 entries->push_back(new RegistryEntry( | 313 entries->push_back(base::MakeUnique<RegistryEntry>( |
308 prog_id_path + ShellUtil::kRegShellOpen, ShellUtil::kRegDelegateExecute, | 314 prog_id_path + ShellUtil::kRegShellOpen, ShellUtil::kRegDelegateExecute, |
309 app_info.delegate_clsid)); | 315 app_info.delegate_clsid)); |
310 // TODO(scottmg): Simplify after Metro removal. https://crbug.com/558054. | 316 // TODO(scottmg): Simplify after Metro removal. https://crbug.com/558054. |
311 entries->back()->set_removal_flag(RegistryEntry::RemovalFlag::VALUE); | 317 entries->back()->set_removal_flag(RegistryEntry::RemovalFlag::VALUE); |
312 } | 318 } |
313 | 319 |
314 // The following entries are required as of Windows 8, but do not | 320 // The following entries are required as of Windows 8, but do not |
315 // depend on the DelegateExecute verb handler being set. | 321 // depend on the DelegateExecute verb handler being set. |
316 if (base::win::GetVersion() >= base::win::VERSION_WIN8) { | 322 if (base::win::GetVersion() >= base::win::VERSION_WIN8) { |
317 if (!app_info.app_id.empty()) { | 323 if (!app_info.app_id.empty()) { |
318 entries->push_back(new RegistryEntry( | 324 entries->push_back(base::MakeUnique<RegistryEntry>( |
319 prog_id_path, ShellUtil::kRegAppUserModelId, app_info.app_id)); | 325 prog_id_path, ShellUtil::kRegAppUserModelId, app_info.app_id)); |
320 } | 326 } |
321 | 327 |
322 // Add \Software\Classes\<prog_id>\Application entries | 328 // Add \Software\Classes\<prog_id>\Application entries |
323 base::string16 application_path(prog_id_path + ShellUtil::kRegApplication); | 329 base::string16 application_path(prog_id_path + ShellUtil::kRegApplication); |
324 if (!app_info.app_id.empty()) { | 330 if (!app_info.app_id.empty()) { |
325 entries->push_back(new RegistryEntry( | 331 entries->push_back(base::MakeUnique<RegistryEntry>( |
326 application_path, ShellUtil::kRegAppUserModelId, app_info.app_id)); | 332 application_path, ShellUtil::kRegAppUserModelId, app_info.app_id)); |
327 } | 333 } |
328 if (!app_info.application_icon_path.empty()) { | 334 if (!app_info.application_icon_path.empty()) { |
329 entries->push_back(new RegistryEntry( | 335 entries->push_back(base::MakeUnique<RegistryEntry>( |
330 application_path, ShellUtil::kRegApplicationIcon, | 336 application_path, ShellUtil::kRegApplicationIcon, |
331 ShellUtil::FormatIconLocation(app_info.application_icon_path, | 337 ShellUtil::FormatIconLocation(app_info.application_icon_path, |
332 app_info.application_icon_index))); | 338 app_info.application_icon_index))); |
333 } | 339 } |
334 if (!app_info.application_name.empty()) { | 340 if (!app_info.application_name.empty()) { |
335 entries->push_back(new RegistryEntry(application_path, | 341 entries->push_back(base::MakeUnique<RegistryEntry>( |
336 ShellUtil::kRegApplicationName, | 342 application_path, ShellUtil::kRegApplicationName, |
337 app_info.application_name)); | 343 app_info.application_name)); |
338 } | 344 } |
339 if (!app_info.application_description.empty()) { | 345 if (!app_info.application_description.empty()) { |
340 entries->push_back(new RegistryEntry( | 346 entries->push_back(base::MakeUnique<RegistryEntry>( |
341 application_path, ShellUtil::kRegApplicationDescription, | 347 application_path, ShellUtil::kRegApplicationDescription, |
342 app_info.application_description)); | 348 app_info.application_description)); |
343 } | 349 } |
344 if (!app_info.publisher_name.empty()) { | 350 if (!app_info.publisher_name.empty()) { |
345 entries->push_back(new RegistryEntry(application_path, | 351 entries->push_back(base::MakeUnique<RegistryEntry>( |
346 ShellUtil::kRegApplicationCompany, | 352 application_path, ShellUtil::kRegApplicationCompany, |
347 app_info.publisher_name)); | 353 app_info.publisher_name)); |
348 } | 354 } |
349 } | 355 } |
350 } | 356 } |
351 | 357 |
352 // This method returns a list of all the registry entries that are needed to | 358 // This method returns a list of all the registry entries that are needed to |
353 // register this installation's ProgId and AppId. These entries need to be | 359 // register this installation's ProgId and AppId. These entries need to be |
354 // registered in HKLM prior to Win8. | 360 // registered in HKLM prior to Win8. |
355 void GetChromeProgIdEntries(BrowserDistribution* dist, | 361 void GetChromeProgIdEntries( |
356 const base::FilePath& chrome_exe, | 362 BrowserDistribution* dist, |
357 const base::string16& suffix, | 363 const base::FilePath& chrome_exe, |
358 ScopedVector<RegistryEntry>* entries) { | 364 const base::string16& suffix, |
| 365 std::vector<std::unique_ptr<RegistryEntry>>* entries) { |
359 int chrome_icon_index = install_static::GetIconResourceIndex(); | 366 int chrome_icon_index = install_static::GetIconResourceIndex(); |
360 | 367 |
361 ApplicationInfo app_info; | 368 ApplicationInfo app_info; |
362 app_info.prog_id = GetBrowserProgId(suffix); | 369 app_info.prog_id = GetBrowserProgId(suffix); |
363 app_info.file_type_name = install_static::GetProgIdDescription(); | 370 app_info.file_type_name = install_static::GetProgIdDescription(); |
364 // File types associated with Chrome are just given the Chrome icon. | 371 // File types associated with Chrome are just given the Chrome icon. |
365 app_info.file_type_icon_path = chrome_exe; | 372 app_info.file_type_icon_path = chrome_exe; |
366 app_info.file_type_icon_index = chrome_icon_index; | 373 app_info.file_type_icon_index = chrome_icon_index; |
367 app_info.command_line = ShellUtil::GetChromeShellOpenCmd(chrome_exe); | 374 app_info.command_line = ShellUtil::GetChromeShellOpenCmd(chrome_exe); |
368 // For user-level installs: entries for the app id will be in HKCU; thus we | 375 // For user-level installs: entries for the app id will be in HKCU; thus we |
369 // do not need a suffix on those entries. | 376 // do not need a suffix on those entries. |
370 app_info.app_id = | 377 app_info.app_id = |
371 ShellUtil::GetBrowserModelId(InstallUtil::IsPerUserInstall()); | 378 ShellUtil::GetBrowserModelId(InstallUtil::IsPerUserInstall()); |
372 | 379 |
373 // TODO(grt): http://crbug.com/75152 Write a reference to a localized | 380 // TODO(grt): http://crbug.com/75152 Write a reference to a localized |
374 // resource for name, description, and company. | 381 // resource for name, description, and company. |
375 app_info.application_name = dist->GetDisplayName(); | 382 app_info.application_name = dist->GetDisplayName(); |
376 app_info.application_icon_path = chrome_exe; | 383 app_info.application_icon_path = chrome_exe; |
377 app_info.application_icon_index = chrome_icon_index; | 384 app_info.application_icon_index = chrome_icon_index; |
378 app_info.application_description = dist->GetAppDescription(); | 385 app_info.application_description = dist->GetAppDescription(); |
379 app_info.publisher_name = dist->GetPublisherName(); | 386 app_info.publisher_name = dist->GetPublisherName(); |
380 app_info.delegate_clsid = install_static::GetLegacyCommandExecuteImplClsid(); | 387 app_info.delegate_clsid = install_static::GetLegacyCommandExecuteImplClsid(); |
381 | 388 |
382 GetProgIdEntries(app_info, entries); | 389 GetProgIdEntries(app_info, entries); |
383 | 390 |
384 if (!app_info.delegate_clsid.empty()) { | 391 if (!app_info.delegate_clsid.empty()) { |
385 ScopedVector<RegistryEntry> delegate_execute_entries = | 392 auto delegate_execute_entries = |
386 GetChromeDelegateExecuteEntries(chrome_exe, app_info); | 393 GetChromeDelegateExecuteEntries(chrome_exe, app_info); |
387 // Remove the keys (not only their values) so that Windows will continue | 394 // Remove the keys (not only their values) so that Windows will continue |
388 // to launch Chrome without a pesky association error. | 395 // to launch Chrome without a pesky association error. |
389 // TODO(scottmg): Simplify after Metro removal. https://crbug.com/558054. | 396 // TODO(scottmg): Simplify after Metro removal. https://crbug.com/558054. |
390 for (RegistryEntry* entry : delegate_execute_entries) | 397 for (const auto& entry : delegate_execute_entries) |
391 entry->set_removal_flag(RegistryEntry::RemovalFlag::KEY); | 398 entry->set_removal_flag(RegistryEntry::RemovalFlag::KEY); |
392 // Move |delegate_execute_entries| to |entries|. | 399 // Move |delegate_execute_entries| to |entries|. |
393 entries->insert(entries->end(), delegate_execute_entries.begin(), | 400 std::move(delegate_execute_entries.begin(), delegate_execute_entries.end(), |
394 delegate_execute_entries.end()); | 401 std::back_inserter(*entries)); |
395 delegate_execute_entries.weak_clear(); | |
396 } | 402 } |
397 } | 403 } |
398 | 404 |
399 // This method returns a list of the registry entries needed to declare a | 405 // This method returns a list of the registry entries needed to declare a |
400 // capability of handling a protocol on Windows. | 406 // capability of handling a protocol on Windows. |
401 void GetProtocolCapabilityEntries(const base::string16& suffix, | 407 void GetProtocolCapabilityEntries( |
402 const base::string16& protocol, | 408 const base::string16& suffix, |
403 ScopedVector<RegistryEntry>* entries) { | 409 const base::string16& protocol, |
404 entries->push_back( | 410 std::vector<std::unique_ptr<RegistryEntry>>* entries) { |
405 new RegistryEntry(GetCapabilitiesKey(suffix).append(L"\\URLAssociations"), | 411 entries->push_back(base::MakeUnique<RegistryEntry>( |
406 protocol, GetBrowserProgId(suffix))); | 412 GetCapabilitiesKey(suffix).append(L"\\URLAssociations"), protocol, |
| 413 GetBrowserProgId(suffix))); |
407 } | 414 } |
408 | 415 |
409 // This method returns a list of the registry entries required to register this | 416 // This method returns a list of the registry entries required to register this |
410 // installation in "RegisteredApplications" on Windows (to appear in Default | 417 // installation in "RegisteredApplications" on Windows (to appear in Default |
411 // Programs, StartMenuInternet, etc.). These entries need to be registered in | 418 // Programs, StartMenuInternet, etc.). These entries need to be registered in |
412 // HKLM prior to Win8. If |suffix| is not empty, these entries are guaranteed to | 419 // HKLM prior to Win8. If |suffix| is not empty, these entries are guaranteed to |
413 // be unique on this machine. | 420 // be unique on this machine. |
414 void GetShellIntegrationEntries(BrowserDistribution* dist, | 421 void GetShellIntegrationEntries( |
415 const base::FilePath& chrome_exe, | 422 BrowserDistribution* dist, |
416 const base::string16& suffix, | 423 const base::FilePath& chrome_exe, |
417 ScopedVector<RegistryEntry>* entries) { | 424 const base::string16& suffix, |
| 425 std::vector<std::unique_ptr<RegistryEntry>>* entries) { |
418 const base::string16 icon_path(ShellUtil::FormatIconLocation( | 426 const base::string16 icon_path(ShellUtil::FormatIconLocation( |
419 chrome_exe, install_static::GetIconResourceIndex())); | 427 chrome_exe, install_static::GetIconResourceIndex())); |
420 const base::string16 quoted_exe_path(L"\"" + chrome_exe.value() + L"\""); | 428 const base::string16 quoted_exe_path(L"\"" + chrome_exe.value() + L"\""); |
421 | 429 |
422 // Register for the Start Menu "Internet" link (pre-Win7). | 430 // Register for the Start Menu "Internet" link (pre-Win7). |
423 const base::string16 start_menu_entry(GetBrowserClientKey(suffix)); | 431 const base::string16 start_menu_entry(GetBrowserClientKey(suffix)); |
424 // Register Chrome's display name. | 432 // Register Chrome's display name. |
425 // TODO(grt): http://crbug.com/75152 Also set LocalizedString; see | 433 // TODO(grt): http://crbug.com/75152 Also set LocalizedString; see |
426 // http://msdn.microsoft.com/en-us/library/windows/desktop/cc144109(v=VS.85).a
spx#registering_the_display_name | 434 // http://msdn.microsoft.com/en-us/library/windows/desktop/cc144109(v=VS.85).a
spx#registering_the_display_name |
427 entries->push_back( | 435 entries->push_back(base::MakeUnique<RegistryEntry>(start_menu_entry, |
428 new RegistryEntry(start_menu_entry, dist->GetDisplayName())); | 436 dist->GetDisplayName())); |
429 // Register the "open" verb for launching Chrome via the "Internet" link. | 437 // Register the "open" verb for launching Chrome via the "Internet" link. |
430 entries->push_back(new RegistryEntry( | 438 entries->push_back(base::MakeUnique<RegistryEntry>( |
431 start_menu_entry + ShellUtil::kRegShellOpen, quoted_exe_path)); | 439 start_menu_entry + ShellUtil::kRegShellOpen, quoted_exe_path)); |
432 // Register Chrome's icon for the Start Menu "Internet" link. | 440 // Register Chrome's icon for the Start Menu "Internet" link. |
433 entries->push_back(new RegistryEntry( | 441 entries->push_back(base::MakeUnique<RegistryEntry>( |
434 start_menu_entry + ShellUtil::kRegDefaultIcon, icon_path)); | 442 start_menu_entry + ShellUtil::kRegDefaultIcon, icon_path)); |
435 | 443 |
436 // Register installation information. | 444 // Register installation information. |
437 base::string16 install_info(start_menu_entry + L"\\InstallInfo"); | 445 base::string16 install_info(start_menu_entry + L"\\InstallInfo"); |
438 // Note: not using CommandLine since it has ambiguous rules for quoting | 446 // Note: not using CommandLine since it has ambiguous rules for quoting |
439 // strings. | 447 // strings. |
440 entries->push_back( | 448 entries->push_back(base::MakeUnique<RegistryEntry>( |
441 new RegistryEntry(install_info, kReinstallCommand, | 449 install_info, kReinstallCommand, |
442 quoted_exe_path + L" --" + | 450 quoted_exe_path + L" --" + |
443 base::ASCIIToUTF16(switches::kMakeDefaultBrowser))); | 451 base::ASCIIToUTF16(switches::kMakeDefaultBrowser))); |
444 entries->push_back(new RegistryEntry( | 452 entries->push_back(base::MakeUnique<RegistryEntry>( |
445 install_info, L"HideIconsCommand", | 453 install_info, L"HideIconsCommand", |
446 quoted_exe_path + L" --" + base::ASCIIToUTF16(switches::kHideIcons))); | 454 quoted_exe_path + L" --" + base::ASCIIToUTF16(switches::kHideIcons))); |
447 entries->push_back(new RegistryEntry( | 455 entries->push_back(base::MakeUnique<RegistryEntry>( |
448 install_info, L"ShowIconsCommand", | 456 install_info, L"ShowIconsCommand", |
449 quoted_exe_path + L" --" + base::ASCIIToUTF16(switches::kShowIcons))); | 457 quoted_exe_path + L" --" + base::ASCIIToUTF16(switches::kShowIcons))); |
450 entries->push_back(new RegistryEntry(install_info, L"IconsVisible", 1)); | 458 entries->push_back( |
| 459 base::MakeUnique<RegistryEntry>(install_info, L"IconsVisible", 1)); |
451 | 460 |
452 // Register with Default Programs. | 461 // Register with Default Programs. |
453 const base::string16 reg_app_name( | 462 const base::string16 reg_app_name( |
454 install_static::GetBaseAppName().append(suffix)); | 463 install_static::GetBaseAppName().append(suffix)); |
455 // Tell Windows where to find Chrome's Default Programs info. | 464 // Tell Windows where to find Chrome's Default Programs info. |
456 const base::string16 capabilities(GetCapabilitiesKey(suffix)); | 465 const base::string16 capabilities(GetCapabilitiesKey(suffix)); |
457 entries->push_back(new RegistryEntry(ShellUtil::kRegRegisteredApplications, | 466 entries->push_back(base::MakeUnique<RegistryEntry>( |
458 reg_app_name, capabilities)); | 467 ShellUtil::kRegRegisteredApplications, reg_app_name, capabilities)); |
459 // Write out Chrome's Default Programs info. | 468 // Write out Chrome's Default Programs info. |
460 // TODO(grt): http://crbug.com/75152 Write a reference to a localized | 469 // TODO(grt): http://crbug.com/75152 Write a reference to a localized |
461 // resource rather than this. | 470 // resource rather than this. |
462 entries->push_back(new RegistryEntry(capabilities, | 471 entries->push_back(base::MakeUnique<RegistryEntry>( |
463 ShellUtil::kRegApplicationDescription, | 472 capabilities, ShellUtil::kRegApplicationDescription, |
464 dist->GetLongAppDescription())); | 473 dist->GetLongAppDescription())); |
465 entries->push_back(new RegistryEntry( | 474 entries->push_back(base::MakeUnique<RegistryEntry>( |
466 capabilities, ShellUtil::kRegApplicationIcon, icon_path)); | 475 capabilities, ShellUtil::kRegApplicationIcon, icon_path)); |
467 entries->push_back(new RegistryEntry( | 476 entries->push_back(base::MakeUnique<RegistryEntry>( |
468 capabilities, ShellUtil::kRegApplicationName, dist->GetDisplayName())); | 477 capabilities, ShellUtil::kRegApplicationName, dist->GetDisplayName())); |
469 | 478 |
470 entries->push_back(new RegistryEntry(capabilities + L"\\Startmenu", | 479 entries->push_back(base::MakeUnique<RegistryEntry>( |
471 L"StartMenuInternet", reg_app_name)); | 480 capabilities + L"\\Startmenu", L"StartMenuInternet", reg_app_name)); |
472 | 481 |
473 const base::string16 html_prog_id(GetBrowserProgId(suffix)); | 482 const base::string16 html_prog_id(GetBrowserProgId(suffix)); |
474 for (int i = 0; ShellUtil::kPotentialFileAssociations[i] != NULL; i++) { | 483 for (int i = 0; ShellUtil::kPotentialFileAssociations[i] != NULL; i++) { |
475 entries->push_back(new RegistryEntry( | 484 entries->push_back(base::MakeUnique<RegistryEntry>( |
476 capabilities + L"\\FileAssociations", | 485 capabilities + L"\\FileAssociations", |
477 ShellUtil::kPotentialFileAssociations[i], html_prog_id)); | 486 ShellUtil::kPotentialFileAssociations[i], html_prog_id)); |
478 } | 487 } |
479 for (int i = 0; ShellUtil::kPotentialProtocolAssociations[i] != NULL; i++) { | 488 for (int i = 0; ShellUtil::kPotentialProtocolAssociations[i] != NULL; i++) { |
480 entries->push_back(new RegistryEntry( | 489 entries->push_back(base::MakeUnique<RegistryEntry>( |
481 capabilities + L"\\URLAssociations", | 490 capabilities + L"\\URLAssociations", |
482 ShellUtil::kPotentialProtocolAssociations[i], html_prog_id)); | 491 ShellUtil::kPotentialProtocolAssociations[i], html_prog_id)); |
483 } | 492 } |
484 } | 493 } |
485 | 494 |
486 // Gets the registry entries to register an application as a handler for a | 495 // Gets the registry entries to register an application as a handler for a |
487 // particular file extension. |prog_id| is the ProgId used by Windows for the | 496 // particular file extension. |prog_id| is the ProgId used by Windows for the |
488 // application. |ext| is the file extension, which must begin with a '.'. | 497 // application. |ext| is the file extension, which must begin with a '.'. |
489 void GetAppExtRegistrationEntries(const base::string16& prog_id, | 498 void GetAppExtRegistrationEntries( |
490 const base::string16& ext, | 499 const base::string16& prog_id, |
491 ScopedVector<RegistryEntry>* entries) { | 500 const base::string16& ext, |
| 501 std::vector<std::unique_ptr<RegistryEntry>>* entries) { |
492 // In HKEY_CURRENT_USER\Software\Classes\EXT\OpenWithProgids, create an | 502 // In HKEY_CURRENT_USER\Software\Classes\EXT\OpenWithProgids, create an |
493 // empty value with this class's ProgId. | 503 // empty value with this class's ProgId. |
494 base::string16 key_name(ShellUtil::kRegClasses); | 504 base::string16 key_name(ShellUtil::kRegClasses); |
495 key_name.push_back(base::FilePath::kSeparators[0]); | 505 key_name.push_back(base::FilePath::kSeparators[0]); |
496 key_name.append(ext); | 506 key_name.append(ext); |
497 key_name.push_back(base::FilePath::kSeparators[0]); | 507 key_name.push_back(base::FilePath::kSeparators[0]); |
498 key_name.append(ShellUtil::kRegOpenWithProgids); | 508 key_name.append(ShellUtil::kRegOpenWithProgids); |
499 entries->push_back(new RegistryEntry(key_name, prog_id, base::string16())); | 509 entries->push_back( |
| 510 base::MakeUnique<RegistryEntry>(key_name, prog_id, base::string16())); |
500 } | 511 } |
501 | 512 |
502 // This method returns a list of the registry entries required for this | 513 // This method returns a list of the registry entries required for this |
503 // installation to be registered in the Windows shell. | 514 // installation to be registered in the Windows shell. |
504 // In particular: | 515 // In particular: |
505 // - App Paths | 516 // - App Paths |
506 // http://msdn.microsoft.com/en-us/library/windows/desktop/ee872121 | 517 // http://msdn.microsoft.com/en-us/library/windows/desktop/ee872121 |
507 // - File Associations | 518 // - File Associations |
508 // http://msdn.microsoft.com/en-us/library/bb166549 | 519 // http://msdn.microsoft.com/en-us/library/bb166549 |
509 // These entries need to be registered in HKLM prior to Win8. | 520 // These entries need to be registered in HKLM prior to Win8. |
510 void GetChromeAppRegistrationEntries(const base::FilePath& chrome_exe, | 521 void GetChromeAppRegistrationEntries( |
511 const base::string16& suffix, | 522 const base::FilePath& chrome_exe, |
512 ScopedVector<RegistryEntry>* entries) { | 523 const base::string16& suffix, |
| 524 std::vector<std::unique_ptr<RegistryEntry>>* entries) { |
513 base::string16 app_path_key(ShellUtil::kAppPathsRegistryKey); | 525 base::string16 app_path_key(ShellUtil::kAppPathsRegistryKey); |
514 app_path_key.push_back(base::FilePath::kSeparators[0]); | 526 app_path_key.push_back(base::FilePath::kSeparators[0]); |
515 app_path_key.append(chrome_exe.BaseName().value()); | 527 app_path_key.append(chrome_exe.BaseName().value()); |
516 entries->push_back(new RegistryEntry(app_path_key, chrome_exe.value())); | 528 entries->push_back( |
517 entries->push_back(new RegistryEntry(app_path_key, | 529 base::MakeUnique<RegistryEntry>(app_path_key, chrome_exe.value())); |
518 ShellUtil::kAppPathsRegistryPathName, | 530 entries->push_back(base::MakeUnique<RegistryEntry>( |
519 chrome_exe.DirName().value())); | 531 app_path_key, ShellUtil::kAppPathsRegistryPathName, |
| 532 chrome_exe.DirName().value())); |
520 | 533 |
521 const base::string16 html_prog_id(GetBrowserProgId(suffix)); | 534 const base::string16 html_prog_id(GetBrowserProgId(suffix)); |
522 for (int i = 0; ShellUtil::kPotentialFileAssociations[i] != NULL; i++) { | 535 for (int i = 0; ShellUtil::kPotentialFileAssociations[i] != NULL; i++) { |
523 GetAppExtRegistrationEntries( | 536 GetAppExtRegistrationEntries( |
524 html_prog_id, ShellUtil::kPotentialFileAssociations[i], entries); | 537 html_prog_id, ShellUtil::kPotentialFileAssociations[i], entries); |
525 } | 538 } |
526 } | 539 } |
527 | 540 |
528 // Gets the registry entries to register an application as the default handler | 541 // Gets the registry entries to register an application as the default handler |
529 // for a particular file extension. |prog_id| is the ProgId used by Windows for | 542 // for a particular file extension. |prog_id| is the ProgId used by Windows for |
530 // the application. |ext| is the file extension, which must begin with a '.'. If | 543 // the application. |ext| is the file extension, which must begin with a '.'. If |
531 // |overwrite_existing|, always sets the default handler; otherwise only sets if | 544 // |overwrite_existing|, always sets the default handler; otherwise only sets if |
532 // there is no existing default. | 545 // there is no existing default. |
533 // | 546 // |
534 // This has no effect on Windows 8. Windows 8 ignores the default and lets the | 547 // This has no effect on Windows 8. Windows 8 ignores the default and lets the |
535 // user choose. If there is only one handler for a file, it will automatically | 548 // user choose. If there is only one handler for a file, it will automatically |
536 // become the default. Otherwise, the first time the user opens a file, they are | 549 // become the default. Otherwise, the first time the user opens a file, they are |
537 // presented with the dialog to set the default handler. (This is roughly | 550 // presented with the dialog to set the default handler. (This is roughly |
538 // equivalent to being called with |overwrite_existing| false.) | 551 // equivalent to being called with |overwrite_existing| false.) |
539 void GetAppDefaultRegistrationEntries(const base::string16& prog_id, | 552 void GetAppDefaultRegistrationEntries( |
540 const base::string16& ext, | 553 const base::string16& prog_id, |
541 bool overwrite_existing, | 554 const base::string16& ext, |
542 ScopedVector<RegistryEntry>* entries) { | 555 bool overwrite_existing, |
| 556 std::vector<std::unique_ptr<RegistryEntry>>* entries) { |
543 // Set the default value of HKEY_CURRENT_USER\Software\Classes\EXT to this | 557 // Set the default value of HKEY_CURRENT_USER\Software\Classes\EXT to this |
544 // class's name. | 558 // class's name. |
545 base::string16 key_name(ShellUtil::kRegClasses); | 559 base::string16 key_name(ShellUtil::kRegClasses); |
546 key_name.push_back(base::FilePath::kSeparators[0]); | 560 key_name.push_back(base::FilePath::kSeparators[0]); |
547 key_name.append(ext); | 561 key_name.append(ext); |
548 std::unique_ptr<RegistryEntry> default_association( | 562 auto default_association = base::MakeUnique<RegistryEntry>(key_name, prog_id); |
549 new RegistryEntry(key_name, prog_id)); | |
550 if (overwrite_existing || | 563 if (overwrite_existing || |
551 !default_association->KeyExistsInRegistry(RegistryEntry::LOOK_IN_HKCU)) { | 564 !default_association->KeyExistsInRegistry(RegistryEntry::LOOK_IN_HKCU)) { |
552 entries->push_back(default_association.release()); | 565 entries->push_back(std::move(default_association)); |
553 } | 566 } |
554 } | 567 } |
555 | 568 |
556 // This method returns a list of all the user level registry entries that are | 569 // This method returns a list of all the user level registry entries that are |
557 // needed to make Chromium the default handler for a protocol on XP. | 570 // needed to make Chromium the default handler for a protocol on XP. |
558 void GetXPStyleUserProtocolEntries(const base::string16& protocol, | 571 void GetXPStyleUserProtocolEntries( |
559 const base::string16& chrome_icon, | 572 const base::string16& protocol, |
560 const base::string16& chrome_open, | 573 const base::string16& chrome_icon, |
561 ScopedVector<RegistryEntry>* entries) { | 574 const base::string16& chrome_open, |
| 575 std::vector<std::unique_ptr<RegistryEntry>>* entries) { |
562 // Protocols associations. | 576 // Protocols associations. |
563 base::string16 url_key(ShellUtil::kRegClasses); | 577 base::string16 url_key(ShellUtil::kRegClasses); |
564 url_key.push_back(base::FilePath::kSeparators[0]); | 578 url_key.push_back(base::FilePath::kSeparators[0]); |
565 url_key.append(protocol); | 579 url_key.append(protocol); |
566 | 580 |
567 // This registry value tells Windows that this 'class' is a URL scheme | 581 // This registry value tells Windows that this 'class' is a URL scheme |
568 // so IE, explorer and other apps will route it to our handler. | 582 // so IE, explorer and other apps will route it to our handler. |
569 // <root hkey>\Software\Classes\<protocol>\URL Protocol | 583 // <root hkey>\Software\Classes\<protocol>\URL Protocol |
570 entries->push_back( | 584 entries->push_back(base::MakeUnique<RegistryEntry>( |
571 new RegistryEntry(url_key, ShellUtil::kRegUrlProtocol, base::string16())); | 585 url_key, ShellUtil::kRegUrlProtocol, base::string16())); |
572 | 586 |
573 // <root hkey>\Software\Classes\<protocol>\DefaultIcon | 587 // <root hkey>\Software\Classes\<protocol>\DefaultIcon |
574 base::string16 icon_key = url_key + ShellUtil::kRegDefaultIcon; | 588 base::string16 icon_key = url_key + ShellUtil::kRegDefaultIcon; |
575 entries->push_back(new RegistryEntry(icon_key, chrome_icon)); | 589 entries->push_back(base::MakeUnique<RegistryEntry>(icon_key, chrome_icon)); |
576 | 590 |
577 // <root hkey>\Software\Classes\<protocol>\shell\open\command | 591 // <root hkey>\Software\Classes\<protocol>\shell\open\command |
578 base::string16 shell_key = url_key + ShellUtil::kRegShellOpen; | 592 base::string16 shell_key = url_key + ShellUtil::kRegShellOpen; |
579 entries->push_back(new RegistryEntry(shell_key, chrome_open)); | 593 entries->push_back(base::MakeUnique<RegistryEntry>(shell_key, chrome_open)); |
580 | 594 |
581 // <root hkey>\Software\Classes\<protocol>\shell\open\ddeexec | 595 // <root hkey>\Software\Classes\<protocol>\shell\open\ddeexec |
582 base::string16 dde_key = url_key + L"\\shell\\open\\ddeexec"; | 596 base::string16 dde_key = url_key + L"\\shell\\open\\ddeexec"; |
583 entries->push_back(new RegistryEntry(dde_key, base::string16())); | 597 entries->push_back( |
| 598 base::MakeUnique<RegistryEntry>(dde_key, base::string16())); |
584 | 599 |
585 // <root hkey>\Software\Classes\<protocol>\shell\@ | 600 // <root hkey>\Software\Classes\<protocol>\shell\@ |
586 base::string16 protocol_shell_key = url_key + ShellUtil::kRegShellPath; | 601 base::string16 protocol_shell_key = url_key + ShellUtil::kRegShellPath; |
587 entries->push_back(new RegistryEntry(protocol_shell_key, L"open")); | 602 entries->push_back( |
| 603 base::MakeUnique<RegistryEntry>(protocol_shell_key, L"open")); |
588 } | 604 } |
589 | 605 |
590 // This method returns a list of all the user level registry entries that are | 606 // This method returns a list of all the user level registry entries that are |
591 // needed to make Chromium default browser on XP. Some of these entries are | 607 // needed to make Chromium default browser on XP. Some of these entries are |
592 // irrelevant in recent versions of Windows, but we register them anyways as | 608 // irrelevant in recent versions of Windows, but we register them anyways as |
593 // some legacy apps are hardcoded to lookup those values. | 609 // some legacy apps are hardcoded to lookup those values. |
594 void GetXPStyleDefaultBrowserUserEntries(const base::FilePath& chrome_exe, | 610 void GetXPStyleDefaultBrowserUserEntries( |
595 const base::string16& suffix, | 611 const base::FilePath& chrome_exe, |
596 ScopedVector<RegistryEntry>* entries) { | 612 const base::string16& suffix, |
| 613 std::vector<std::unique_ptr<RegistryEntry>>* entries) { |
597 // File extension associations. | 614 // File extension associations. |
598 base::string16 html_prog_id(GetBrowserProgId(suffix)); | 615 base::string16 html_prog_id(GetBrowserProgId(suffix)); |
599 for (int i = 0; ShellUtil::kDefaultFileAssociations[i] != NULL; i++) { | 616 for (int i = 0; ShellUtil::kDefaultFileAssociations[i] != NULL; i++) { |
600 GetAppDefaultRegistrationEntries( | 617 GetAppDefaultRegistrationEntries( |
601 html_prog_id, ShellUtil::kDefaultFileAssociations[i], true, entries); | 618 html_prog_id, ShellUtil::kDefaultFileAssociations[i], true, entries); |
602 } | 619 } |
603 | 620 |
604 // Protocols associations. | 621 // Protocols associations. |
605 base::string16 chrome_open = ShellUtil::GetChromeShellOpenCmd(chrome_exe); | 622 base::string16 chrome_open = ShellUtil::GetChromeShellOpenCmd(chrome_exe); |
606 base::string16 chrome_icon = ShellUtil::FormatIconLocation( | 623 base::string16 chrome_icon = ShellUtil::FormatIconLocation( |
607 chrome_exe, install_static::GetIconResourceIndex()); | 624 chrome_exe, install_static::GetIconResourceIndex()); |
608 for (int i = 0; ShellUtil::kBrowserProtocolAssociations[i] != NULL; i++) { | 625 for (int i = 0; ShellUtil::kBrowserProtocolAssociations[i] != NULL; i++) { |
609 GetXPStyleUserProtocolEntries(ShellUtil::kBrowserProtocolAssociations[i], | 626 GetXPStyleUserProtocolEntries(ShellUtil::kBrowserProtocolAssociations[i], |
610 chrome_icon, chrome_open, entries); | 627 chrome_icon, chrome_open, entries); |
611 } | 628 } |
612 | 629 |
613 // start->Internet shortcut. | 630 // start->Internet shortcut. |
614 base::string16 start_menu(ShellUtil::kRegStartMenuInternet); | 631 base::string16 start_menu(ShellUtil::kRegStartMenuInternet); |
615 base::string16 app_name = install_static::GetBaseAppName().append(suffix); | 632 base::string16 app_name = install_static::GetBaseAppName().append(suffix); |
616 entries->push_back(new RegistryEntry(start_menu, app_name)); | 633 entries->push_back(base::MakeUnique<RegistryEntry>(start_menu, app_name)); |
617 } | 634 } |
618 | 635 |
619 // Checks that all |entries| are present on this computer (or absent if their | 636 // Checks that all |entries| are present on this computer (or absent if their |
620 // |removal_flag_| is set). |look_for_in| is passed to | 637 // |removal_flag_| is set). |look_for_in| is passed to |
621 // RegistryEntry::ExistsInRegistry(). Documentation for it can be found there. | 638 // RegistryEntry::ExistsInRegistry(). Documentation for it can be found there. |
622 bool AreEntriesAsDesired(const ScopedVector<RegistryEntry>& entries, | 639 bool AreEntriesAsDesired( |
623 uint32_t look_for_in) { | 640 const std::vector<std::unique_ptr<RegistryEntry>>& entries, |
624 for (const auto* entry : entries) { | 641 uint32_t look_for_in) { |
| 642 for (const auto& entry : entries) { |
625 if (entry->ExistsInRegistry(look_for_in) != !entry->IsFlaggedForRemoval()) | 643 if (entry->ExistsInRegistry(look_for_in) != !entry->IsFlaggedForRemoval()) |
626 return false; | 644 return false; |
627 } | 645 } |
628 return true; | 646 return true; |
629 } | 647 } |
630 | 648 |
631 // Checks that all required registry entries for Chrome are already present on | 649 // Checks that all required registry entries for Chrome are already present on |
632 // this computer (or absent if their |removal_flag_| is set). | 650 // this computer (or absent if their |removal_flag_| is set). |
633 // See RegistryEntry::ExistsInRegistry for the behavior of |look_for_in|. | 651 // See RegistryEntry::ExistsInRegistry for the behavior of |look_for_in|. |
634 // Note: between r133333 and r154145 we were registering parts of Chrome in HKCU | 652 // Note: between r133333 and r154145 we were registering parts of Chrome in HKCU |
635 // and parts in HKLM for user-level installs; we now always register everything | 653 // and parts in HKLM for user-level installs; we now always register everything |
636 // under a single registry root. Not doing so caused http://crbug.com/144910 for | 654 // under a single registry root. Not doing so caused http://crbug.com/144910 for |
637 // users who first-installed Chrome in that revision range (those users are | 655 // users who first-installed Chrome in that revision range (those users are |
638 // still impacted by http://crbug.com/144910). This method will keep returning | 656 // still impacted by http://crbug.com/144910). This method will keep returning |
639 // true for affected users (i.e. who have all the registrations, but over both | 657 // true for affected users (i.e. who have all the registrations, but over both |
640 // registry roots). | 658 // registry roots). |
641 bool IsChromeRegistered(BrowserDistribution* dist, | 659 bool IsChromeRegistered(BrowserDistribution* dist, |
642 const base::FilePath& chrome_exe, | 660 const base::FilePath& chrome_exe, |
643 const base::string16& suffix, | 661 const base::string16& suffix, |
644 uint32_t look_for_in) { | 662 uint32_t look_for_in) { |
645 ScopedVector<RegistryEntry> entries; | 663 std::vector<std::unique_ptr<RegistryEntry>> entries; |
646 GetChromeProgIdEntries(dist, chrome_exe, suffix, &entries); | 664 GetChromeProgIdEntries(dist, chrome_exe, suffix, &entries); |
647 GetShellIntegrationEntries(dist, chrome_exe, suffix, &entries); | 665 GetShellIntegrationEntries(dist, chrome_exe, suffix, &entries); |
648 GetChromeAppRegistrationEntries(chrome_exe, suffix, &entries); | 666 GetChromeAppRegistrationEntries(chrome_exe, suffix, &entries); |
649 return AreEntriesAsDesired(entries, look_for_in); | 667 return AreEntriesAsDesired(entries, look_for_in); |
650 } | 668 } |
651 | 669 |
652 // This method checks if Chrome is already registered on the local machine | 670 // This method checks if Chrome is already registered on the local machine |
653 // for the requested protocol. It just checks the one value required for this. | 671 // for the requested protocol. It just checks the one value required for this. |
654 // See RegistryEntry::ExistsInRegistry for the behavior of |look_for_in|. | 672 // See RegistryEntry::ExistsInRegistry for the behavior of |look_for_in|. |
655 bool IsChromeRegisteredForProtocol(const base::string16& suffix, | 673 bool IsChromeRegisteredForProtocol(const base::string16& suffix, |
656 const base::string16& protocol, | 674 const base::string16& protocol, |
657 uint32_t look_for_in) { | 675 uint32_t look_for_in) { |
658 ScopedVector<RegistryEntry> entries; | 676 std::vector<std::unique_ptr<RegistryEntry>> entries; |
659 GetProtocolCapabilityEntries(suffix, protocol, &entries); | 677 GetProtocolCapabilityEntries(suffix, protocol, &entries); |
660 return AreEntriesAsDesired(entries, look_for_in); | 678 return AreEntriesAsDesired(entries, look_for_in); |
661 } | 679 } |
662 | 680 |
663 // This method registers Chrome by launching an elevated setup.exe. That will | 681 // This method registers Chrome by launching an elevated setup.exe. That will |
664 // show the user the standard elevation prompt. If the user accepts it the new | 682 // show the user the standard elevation prompt. If the user accepts it the new |
665 // process will make the necessary changes and return SUCCESS that we capture | 683 // process will make the necessary changes and return SUCCESS that we capture |
666 // and return. If protocol is non-empty we will also register Chrome as being | 684 // and return. If protocol is non-empty we will also register Chrome as being |
667 // capable of handling the protocol. This is most commonly used on per-user | 685 // capable of handling the protocol. This is most commonly used on per-user |
668 // installs on Windows 7 where setup.exe did not have permission to register | 686 // installs on Windows 7 where setup.exe did not have permission to register |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
881 return is_per_user && base::win::GetVersion() >= base::win::VERSION_WIN8 ? | 899 return is_per_user && base::win::GetVersion() >= base::win::VERSION_WIN8 ? |
882 HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE; | 900 HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE; |
883 } | 901 } |
884 | 902 |
885 // Associates Chrome with supported protocols and file associations. This should | 903 // Associates Chrome with supported protocols and file associations. This should |
886 // not be required on Vista+ but since some applications still read | 904 // not be required on Vista+ but since some applications still read |
887 // Software\Classes\http key directly, we have to do this on Vista+ as well. | 905 // Software\Classes\http key directly, we have to do this on Vista+ as well. |
888 bool RegisterChromeAsDefaultXPStyle(int shell_change, | 906 bool RegisterChromeAsDefaultXPStyle(int shell_change, |
889 const base::FilePath& chrome_exe) { | 907 const base::FilePath& chrome_exe) { |
890 bool ret = true; | 908 bool ret = true; |
891 ScopedVector<RegistryEntry> entries; | 909 std::vector<std::unique_ptr<RegistryEntry>> entries; |
892 GetXPStyleDefaultBrowserUserEntries( | 910 GetXPStyleDefaultBrowserUserEntries( |
893 chrome_exe, ShellUtil::GetCurrentInstallationSuffix(chrome_exe), | 911 chrome_exe, ShellUtil::GetCurrentInstallationSuffix(chrome_exe), |
894 &entries); | 912 &entries); |
895 | 913 |
896 // Change the default browser for current user. | 914 // Change the default browser for current user. |
897 if ((shell_change & ShellUtil::CURRENT_USER) && | 915 if ((shell_change & ShellUtil::CURRENT_USER) && |
898 !ShellUtil::AddRegistryEntries(HKEY_CURRENT_USER, entries)) { | 916 !ShellUtil::AddRegistryEntries(HKEY_CURRENT_USER, entries)) { |
899 ret = false; | 917 ret = false; |
900 LOG(ERROR) << "Could not make Chrome default browser (XP/current user)."; | 918 LOG(ERROR) << "Could not make Chrome default browser (XP/current user)."; |
901 } | 919 } |
902 | 920 |
903 // Chrome as default browser at system level. | 921 // Chrome as default browser at system level. |
904 if ((shell_change & ShellUtil::SYSTEM_LEVEL) && | 922 if ((shell_change & ShellUtil::SYSTEM_LEVEL) && |
905 !ShellUtil::AddRegistryEntries(HKEY_LOCAL_MACHINE, entries)) { | 923 !ShellUtil::AddRegistryEntries(HKEY_LOCAL_MACHINE, entries)) { |
906 ret = false; | 924 ret = false; |
907 LOG(ERROR) << "Could not make Chrome default browser (XP/system level)."; | 925 LOG(ERROR) << "Could not make Chrome default browser (XP/system level)."; |
908 } | 926 } |
909 | 927 |
910 return ret; | 928 return ret; |
911 } | 929 } |
912 | 930 |
913 // Associates Chrome with |protocol| in the registry. This should not be | 931 // Associates Chrome with |protocol| in the registry. This should not be |
914 // required on Vista+ but since some applications still read these registry | 932 // required on Vista+ but since some applications still read these registry |
915 // keys directly, we have to do this on Vista+ as well. | 933 // keys directly, we have to do this on Vista+ as well. |
916 // See http://msdn.microsoft.com/library/aa767914.aspx for more details. | 934 // See http://msdn.microsoft.com/library/aa767914.aspx for more details. |
917 bool RegisterChromeAsDefaultProtocolClientXPStyle( | 935 bool RegisterChromeAsDefaultProtocolClientXPStyle( |
918 const base::FilePath& chrome_exe, | 936 const base::FilePath& chrome_exe, |
919 const base::string16& protocol) { | 937 const base::string16& protocol) { |
920 ScopedVector<RegistryEntry> entries; | 938 std::vector<std::unique_ptr<RegistryEntry>> entries; |
921 const base::string16 chrome_open( | 939 const base::string16 chrome_open( |
922 ShellUtil::GetChromeShellOpenCmd(chrome_exe)); | 940 ShellUtil::GetChromeShellOpenCmd(chrome_exe)); |
923 const base::string16 chrome_icon(ShellUtil::FormatIconLocation( | 941 const base::string16 chrome_icon(ShellUtil::FormatIconLocation( |
924 chrome_exe, install_static::GetIconResourceIndex())); | 942 chrome_exe, install_static::GetIconResourceIndex())); |
925 GetXPStyleUserProtocolEntries(protocol, chrome_icon, chrome_open, &entries); | 943 GetXPStyleUserProtocolEntries(protocol, chrome_icon, chrome_open, &entries); |
926 // Change the default protocol handler for current user. | 944 // Change the default protocol handler for current user. |
927 if (!ShellUtil::AddRegistryEntries(HKEY_CURRENT_USER, entries)) { | 945 if (!ShellUtil::AddRegistryEntries(HKEY_CURRENT_USER, entries)) { |
928 LOG(ERROR) << "Could not make Chrome default protocol client (XP)."; | 946 LOG(ERROR) << "Could not make Chrome default protocol client (XP)."; |
929 return false; | 947 return false; |
930 } | 948 } |
(...skipping 1136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2067 : RegistryEntry::LOOK_IN_HKLM; | 2085 : RegistryEntry::LOOK_IN_HKLM; |
2068 | 2086 |
2069 // Check if chrome is already registered with this suffix. | 2087 // Check if chrome is already registered with this suffix. |
2070 if (IsChromeRegistered(dist, chrome_exe, suffix, look_for_in)) | 2088 if (IsChromeRegistered(dist, chrome_exe, suffix, look_for_in)) |
2071 return true; | 2089 return true; |
2072 | 2090 |
2073 bool result = true; | 2091 bool result = true; |
2074 if (root == HKEY_CURRENT_USER || IsUserAnAdmin()) { | 2092 if (root == HKEY_CURRENT_USER || IsUserAnAdmin()) { |
2075 // Do the full registration if we can do it at user-level or if the user is | 2093 // Do the full registration if we can do it at user-level or if the user is |
2076 // an admin. | 2094 // an admin. |
2077 ScopedVector<RegistryEntry> progid_and_appreg_entries; | 2095 std::vector<std::unique_ptr<RegistryEntry>> progid_and_appreg_entries; |
2078 ScopedVector<RegistryEntry> shell_entries; | 2096 std::vector<std::unique_ptr<RegistryEntry>> shell_entries; |
2079 GetChromeProgIdEntries(dist, chrome_exe, suffix, | 2097 GetChromeProgIdEntries(dist, chrome_exe, suffix, |
2080 &progid_and_appreg_entries); | 2098 &progid_and_appreg_entries); |
2081 GetChromeAppRegistrationEntries(chrome_exe, suffix, | 2099 GetChromeAppRegistrationEntries(chrome_exe, suffix, |
2082 &progid_and_appreg_entries); | 2100 &progid_and_appreg_entries); |
2083 GetShellIntegrationEntries(dist, chrome_exe, suffix, &shell_entries); | 2101 GetShellIntegrationEntries(dist, chrome_exe, suffix, &shell_entries); |
2084 result = (AddRegistryEntries(root, progid_and_appreg_entries) && | 2102 result = (AddRegistryEntries(root, progid_and_appreg_entries) && |
2085 AddRegistryEntries(root, shell_entries)); | 2103 AddRegistryEntries(root, shell_entries)); |
2086 } else if (elevate_if_not_admin && | 2104 } else if (elevate_if_not_admin && |
2087 base::win::GetVersion() >= base::win::VERSION_VISTA && | 2105 base::win::GetVersion() >= base::win::VERSION_VISTA && |
2088 ElevateAndRegisterChrome(dist, chrome_exe, suffix, base::string16())) { | 2106 ElevateAndRegisterChrome(dist, chrome_exe, suffix, base::string16())) { |
2089 // If the user is not an admin and OS is between Vista and Windows 7 | 2107 // If the user is not an admin and OS is between Vista and Windows 7 |
2090 // inclusively, try to elevate and register. This is only intended for | 2108 // inclusively, try to elevate and register. This is only intended for |
2091 // user-level installs as system-level installs should always be run with | 2109 // user-level installs as system-level installs should always be run with |
2092 // admin rights. | 2110 // admin rights. |
2093 result = true; | 2111 result = true; |
2094 } else { | 2112 } else { |
2095 // If we got to this point then all we can do is create ProgId and basic app | 2113 // If we got to this point then all we can do is create ProgId and basic app |
2096 // registrations under HKCU. | 2114 // registrations under HKCU. |
2097 ScopedVector<RegistryEntry> entries; | 2115 std::vector<std::unique_ptr<RegistryEntry>> entries; |
2098 GetChromeProgIdEntries(dist, chrome_exe, base::string16(), &entries); | 2116 GetChromeProgIdEntries(dist, chrome_exe, base::string16(), &entries); |
2099 // Prefer to use |suffix|; unless Chrome's ProgIds are already registered | 2117 // Prefer to use |suffix|; unless Chrome's ProgIds are already registered |
2100 // with no suffix (as per the old registration style): in which case some | 2118 // with no suffix (as per the old registration style): in which case some |
2101 // other registry entries could refer to them and since we were not able to | 2119 // other registry entries could refer to them and since we were not able to |
2102 // set our HKLM entries above, we are better off not altering these here. | 2120 // set our HKLM entries above, we are better off not altering these here. |
2103 if (!AreEntriesAsDesired(entries, RegistryEntry::LOOK_IN_HKCU)) { | 2121 if (!AreEntriesAsDesired(entries, RegistryEntry::LOOK_IN_HKCU)) { |
2104 if (!suffix.empty()) { | 2122 if (!suffix.empty()) { |
2105 entries.clear(); | 2123 entries.clear(); |
2106 GetChromeProgIdEntries(dist, chrome_exe, suffix, &entries); | 2124 GetChromeProgIdEntries(dist, chrome_exe, suffix, &entries); |
2107 GetChromeAppRegistrationEntries(chrome_exe, suffix, &entries); | 2125 GetChromeAppRegistrationEntries(chrome_exe, suffix, &entries); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2150 if (IsChromeRegisteredForProtocol(suffix, protocol, look_for_in)) | 2168 if (IsChromeRegisteredForProtocol(suffix, protocol, look_for_in)) |
2151 return true; | 2169 return true; |
2152 | 2170 |
2153 if (root == HKEY_CURRENT_USER || IsUserAnAdmin()) { | 2171 if (root == HKEY_CURRENT_USER || IsUserAnAdmin()) { |
2154 // We can do this operation directly. | 2172 // We can do this operation directly. |
2155 // First, make sure Chrome is fully registered on this machine. | 2173 // First, make sure Chrome is fully registered on this machine. |
2156 if (!RegisterChromeBrowser(dist, chrome_exe, suffix, false)) | 2174 if (!RegisterChromeBrowser(dist, chrome_exe, suffix, false)) |
2157 return false; | 2175 return false; |
2158 | 2176 |
2159 // Write in the capabillity for the protocol. | 2177 // Write in the capabillity for the protocol. |
2160 ScopedVector<RegistryEntry> entries; | 2178 std::vector<std::unique_ptr<RegistryEntry>> entries; |
2161 GetProtocolCapabilityEntries(suffix, protocol, &entries); | 2179 GetProtocolCapabilityEntries(suffix, protocol, &entries); |
2162 return AddRegistryEntries(root, entries); | 2180 return AddRegistryEntries(root, entries); |
2163 } else if (elevate_if_not_admin && | 2181 } else if (elevate_if_not_admin && |
2164 base::win::GetVersion() >= base::win::VERSION_VISTA) { | 2182 base::win::GetVersion() >= base::win::VERSION_VISTA) { |
2165 // Elevate to do the whole job | 2183 // Elevate to do the whole job |
2166 return ElevateAndRegisterChrome(dist, chrome_exe, suffix, protocol); | 2184 return ElevateAndRegisterChrome(dist, chrome_exe, suffix, protocol); |
2167 } else { | 2185 } else { |
2168 // Admin rights are required to register capabilities before Windows 8. | 2186 // Admin rights are required to register capabilities before Windows 8. |
2169 return false; | 2187 return false; |
2170 } | 2188 } |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2262 return true; | 2280 return true; |
2263 } | 2281 } |
2264 | 2282 |
2265 // static | 2283 // static |
2266 bool ShellUtil::AddFileAssociations( | 2284 bool ShellUtil::AddFileAssociations( |
2267 const base::string16& prog_id, | 2285 const base::string16& prog_id, |
2268 const base::CommandLine& command_line, | 2286 const base::CommandLine& command_line, |
2269 const base::string16& file_type_name, | 2287 const base::string16& file_type_name, |
2270 const base::FilePath& icon_path, | 2288 const base::FilePath& icon_path, |
2271 const std::set<base::string16>& file_extensions) { | 2289 const std::set<base::string16>& file_extensions) { |
2272 ScopedVector<RegistryEntry> entries; | 2290 std::vector<std::unique_ptr<RegistryEntry>> entries; |
2273 | 2291 |
2274 // Create a class for this app. | 2292 // Create a class for this app. |
2275 ApplicationInfo app_info; | 2293 ApplicationInfo app_info; |
2276 app_info.prog_id = prog_id; | 2294 app_info.prog_id = prog_id; |
2277 app_info.file_type_name = file_type_name; | 2295 app_info.file_type_name = file_type_name; |
2278 app_info.file_type_icon_path = icon_path; | 2296 app_info.file_type_icon_path = icon_path; |
2279 app_info.file_type_icon_index = 0; | 2297 app_info.file_type_icon_index = 0; |
2280 app_info.command_line = command_line.GetCommandLineStringWithPlaceholders(); | 2298 app_info.command_line = command_line.GetCommandLineStringWithPlaceholders(); |
2281 GetProgIdEntries(app_info, &entries); | 2299 GetProgIdEntries(app_info, &entries); |
2282 | 2300 |
(...skipping 27 matching lines...) Expand all Loading... |
2310 key_path.append(prog_id); | 2328 key_path.append(prog_id); |
2311 return InstallUtil::DeleteRegistryKey( | 2329 return InstallUtil::DeleteRegistryKey( |
2312 HKEY_CURRENT_USER, key_path, WorkItem::kWow64Default); | 2330 HKEY_CURRENT_USER, key_path, WorkItem::kWow64Default); |
2313 | 2331 |
2314 // TODO(mgiuca): Remove the extension association entries. This requires that | 2332 // TODO(mgiuca): Remove the extension association entries. This requires that |
2315 // the extensions associated with a particular prog_id are stored in that | 2333 // the extensions associated with a particular prog_id are stored in that |
2316 // prog_id's key. | 2334 // prog_id's key. |
2317 } | 2335 } |
2318 | 2336 |
2319 // static | 2337 // static |
2320 bool ShellUtil::AddRegistryEntries(HKEY root, | 2338 bool ShellUtil::AddRegistryEntries( |
2321 const ScopedVector<RegistryEntry>& entries) { | 2339 HKEY root, |
| 2340 const std::vector<std::unique_ptr<RegistryEntry>>& entries) { |
2322 std::unique_ptr<WorkItemList> items(WorkItem::CreateWorkItemList()); | 2341 std::unique_ptr<WorkItemList> items(WorkItem::CreateWorkItemList()); |
2323 | 2342 |
2324 for (ScopedVector<RegistryEntry>::const_iterator itr = entries.begin(); | 2343 for (const auto& entry : entries) |
2325 itr != entries.end(); ++itr) | 2344 entry->AddToWorkItemList(root, items.get()); |
2326 (*itr)->AddToWorkItemList(root, items.get()); | |
2327 | 2345 |
2328 // Apply all the registry changes and if there is a problem, rollback | 2346 // Apply all the registry changes and if there is a problem, rollback |
2329 if (!items->Do()) { | 2347 if (!items->Do()) { |
2330 items->Rollback(); | 2348 items->Rollback(); |
2331 return false; | 2349 return false; |
2332 } | 2350 } |
2333 return true; | 2351 return true; |
2334 } | 2352 } |
OLD | NEW |