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" |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
97 // registrations must be preserved). | 97 // registrations must be preserved). |
98 base::string16 new_style_suffix; | 98 base::string16 new_style_suffix; |
99 if (ShellUtil::GetUserSpecificRegistrySuffix(&new_style_suffix) && | 99 if (ShellUtil::GetUserSpecificRegistrySuffix(&new_style_suffix) && |
100 suffix == new_style_suffix && chrome_html.length() > 39) { | 100 suffix == new_style_suffix && chrome_html.length() > 39) { |
101 NOTREACHED(); | 101 NOTREACHED(); |
102 chrome_html.erase(39); | 102 chrome_html.erase(39); |
103 } | 103 } |
104 return chrome_html; | 104 return chrome_html; |
105 } | 105 } |
106 | 106 |
| 107 // Returns the browser's application name. This application name will be |
| 108 // suffixed as is appropriate for the current install. This is the name that is |
| 109 // registered with Default Programs on Windows and that should thus be used to |
| 110 // "make chrome default" and such. |
| 111 base::string16 GetApplicationName(const base::FilePath& chrome_exe) { |
| 112 return install_static::GetBaseAppName().append( |
| 113 ShellUtil::GetCurrentInstallationSuffix(chrome_exe)); |
| 114 } |
| 115 |
107 // This class is used to initialize and cache a base 32 encoding of the md5 hash | 116 // This class is used to initialize and cache a base 32 encoding of the md5 hash |
108 // of this user's sid preceded by a dot. | 117 // of this user's sid preceded by a dot. |
109 // This is guaranteed to be unique on the machine and 27 characters long | 118 // This is guaranteed to be unique on the machine and 27 characters long |
110 // (including the '.'). | 119 // (including the '.'). |
111 // This is then meant to be used as a suffix on all registrations that may | 120 // This is then meant to be used as a suffix on all registrations that may |
112 // conflict with another user-level Chrome install. | 121 // conflict with another user-level Chrome install. |
113 class UserSpecificRegistrySuffix { | 122 class UserSpecificRegistrySuffix { |
114 public: | 123 public: |
115 // All the initialization is done in the constructor to be able to build the | 124 // All the initialization is done in the constructor to be able to build the |
116 // suffix in a thread-safe manner when used in conjunction with a | 125 // suffix in a thread-safe manner when used in conjunction with a |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
191 base::string16 delegate_clsid; | 200 base::string16 delegate_clsid; |
192 }; | 201 }; |
193 | 202 |
194 // Returns the Windows browser client registration key for Chrome. For example: | 203 // Returns the Windows browser client registration key for Chrome. For example: |
195 // "Software\Clients\StartMenuInternet\Chromium[.user]". Strictly speaking, we | 204 // "Software\Clients\StartMenuInternet\Chromium[.user]". Strictly speaking, we |
196 // should use the name of the executable (e.g., "chrome.exe"), but that ship has | 205 // should use the name of the executable (e.g., "chrome.exe"), but that ship has |
197 // sailed. The cost of switching now is re-prompting users to make Chrome their | 206 // sailed. The cost of switching now is re-prompting users to make Chrome their |
198 // default browser, which isn't polite. |suffix| is the user-specific | 207 // default browser, which isn't polite. |suffix| is the user-specific |
199 // registration suffix; see GetUserSpecificDefaultBrowserSuffix in shell_util.h | 208 // registration suffix; see GetUserSpecificDefaultBrowserSuffix in shell_util.h |
200 // for details. | 209 // for details. |
201 base::string16 GetBrowserClientKey(BrowserDistribution* dist, | 210 base::string16 GetBrowserClientKey(const base::string16& suffix) { |
202 const base::string16& suffix) { | |
203 DCHECK(suffix.empty() || suffix[0] == L'.'); | 211 DCHECK(suffix.empty() || suffix[0] == L'.'); |
204 return base::string16(ShellUtil::kRegStartMenuInternet) | 212 return base::string16(ShellUtil::kRegStartMenuInternet) |
205 .append(1, L'\\') | 213 .append(1, L'\\') |
206 .append(dist->GetBaseAppName()) | 214 .append(install_static::GetBaseAppName()) |
207 .append(suffix); | 215 .append(suffix); |
208 } | 216 } |
209 | 217 |
210 // Returns the Windows Default Programs capabilities key for Chrome. For | 218 // Returns the Windows Default Programs capabilities key for Chrome. For |
211 // example: | 219 // example: |
212 // "Software\Clients\StartMenuInternet\Chromium[.user]\Capabilities". | 220 // "Software\Clients\StartMenuInternet\Chromium[.user]\Capabilities". |
213 base::string16 GetCapabilitiesKey(BrowserDistribution* dist, | 221 base::string16 GetCapabilitiesKey(const base::string16& suffix) { |
214 const base::string16& suffix) { | 222 return GetBrowserClientKey(suffix).append(L"\\Capabilities"); |
215 return GetBrowserClientKey(dist, suffix).append(L"\\Capabilities"); | |
216 } | 223 } |
217 | 224 |
218 // DelegateExecute ProgId. Needed for Chrome Metro in Windows 8. This is only | 225 // DelegateExecute ProgId. Needed for Chrome Metro in Windows 8. This is only |
219 // needed for registring a web browser, not for general associations. | 226 // needed for registring a web browser, not for general associations. |
220 ScopedVector<RegistryEntry> GetChromeDelegateExecuteEntries( | 227 ScopedVector<RegistryEntry> GetChromeDelegateExecuteEntries( |
221 const base::FilePath& chrome_exe, | 228 const base::FilePath& chrome_exe, |
222 const ApplicationInfo& app_info) { | 229 const ApplicationInfo& app_info) { |
223 ScopedVector<RegistryEntry> entries; | 230 ScopedVector<RegistryEntry> entries; |
224 | 231 |
225 base::string16 app_id_shell_key(ShellUtil::kRegClasses); | 232 base::string16 app_id_shell_key(ShellUtil::kRegClasses); |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
342 } | 349 } |
343 } | 350 } |
344 | 351 |
345 // This method returns a list of all the registry entries that are needed to | 352 // This method returns a list of all the registry entries that are needed to |
346 // register this installation's ProgId and AppId. These entries need to be | 353 // register this installation's ProgId and AppId. These entries need to be |
347 // registered in HKLM prior to Win8. | 354 // registered in HKLM prior to Win8. |
348 void GetChromeProgIdEntries(BrowserDistribution* dist, | 355 void GetChromeProgIdEntries(BrowserDistribution* dist, |
349 const base::FilePath& chrome_exe, | 356 const base::FilePath& chrome_exe, |
350 const base::string16& suffix, | 357 const base::string16& suffix, |
351 ScopedVector<RegistryEntry>* entries) { | 358 ScopedVector<RegistryEntry>* entries) { |
352 // Assert that this is only called with the one relevant distribution. | |
353 // TODO(grt): Remove this when BrowserDistribution goes away. | |
354 DCHECK_EQ(BrowserDistribution::GetDistribution(), dist); | |
355 int chrome_icon_index = install_static::GetIconResourceIndex(); | 359 int chrome_icon_index = install_static::GetIconResourceIndex(); |
356 | 360 |
357 ApplicationInfo app_info; | 361 ApplicationInfo app_info; |
358 app_info.prog_id = GetBrowserProgId(suffix); | 362 app_info.prog_id = GetBrowserProgId(suffix); |
359 app_info.file_type_name = install_static::GetProgIdDescription(); | 363 app_info.file_type_name = install_static::GetProgIdDescription(); |
360 // File types associated with Chrome are just given the Chrome icon. | 364 // File types associated with Chrome are just given the Chrome icon. |
361 app_info.file_type_icon_path = chrome_exe; | 365 app_info.file_type_icon_path = chrome_exe; |
362 app_info.file_type_icon_index = chrome_icon_index; | 366 app_info.file_type_icon_index = chrome_icon_index; |
363 app_info.command_line = ShellUtil::GetChromeShellOpenCmd(chrome_exe); | 367 app_info.command_line = ShellUtil::GetChromeShellOpenCmd(chrome_exe); |
364 // For user-level installs: entries for the app id will be in HKCU; thus we | 368 // For user-level installs: entries for the app id will be in HKCU; thus we |
(...skipping 22 matching lines...) Expand all Loading... |
387 entry->set_removal_flag(RegistryEntry::RemovalFlag::KEY); | 391 entry->set_removal_flag(RegistryEntry::RemovalFlag::KEY); |
388 // Move |delegate_execute_entries| to |entries|. | 392 // Move |delegate_execute_entries| to |entries|. |
389 entries->insert(entries->end(), delegate_execute_entries.begin(), | 393 entries->insert(entries->end(), delegate_execute_entries.begin(), |
390 delegate_execute_entries.end()); | 394 delegate_execute_entries.end()); |
391 delegate_execute_entries.weak_clear(); | 395 delegate_execute_entries.weak_clear(); |
392 } | 396 } |
393 } | 397 } |
394 | 398 |
395 // This method returns a list of the registry entries needed to declare a | 399 // This method returns a list of the registry entries needed to declare a |
396 // capability of handling a protocol on Windows. | 400 // capability of handling a protocol on Windows. |
397 void GetProtocolCapabilityEntries(BrowserDistribution* dist, | 401 void GetProtocolCapabilityEntries(const base::string16& suffix, |
398 const base::string16& suffix, | |
399 const base::string16& protocol, | 402 const base::string16& protocol, |
400 ScopedVector<RegistryEntry>* entries) { | 403 ScopedVector<RegistryEntry>* entries) { |
401 entries->push_back(new RegistryEntry( | 404 entries->push_back( |
402 GetCapabilitiesKey(dist, suffix).append(L"\\URLAssociations"), protocol, | 405 new RegistryEntry(GetCapabilitiesKey(suffix).append(L"\\URLAssociations"), |
403 GetBrowserProgId(suffix))); | 406 protocol, GetBrowserProgId(suffix))); |
404 } | 407 } |
405 | 408 |
406 // This method returns a list of the registry entries required to register this | 409 // This method returns a list of the registry entries required to register this |
407 // installation in "RegisteredApplications" on Windows (to appear in Default | 410 // installation in "RegisteredApplications" on Windows (to appear in Default |
408 // Programs, StartMenuInternet, etc.). These entries need to be registered in | 411 // Programs, StartMenuInternet, etc.). These entries need to be registered in |
409 // HKLM prior to Win8. If |suffix| is not empty, these entries are guaranteed to | 412 // HKLM prior to Win8. If |suffix| is not empty, these entries are guaranteed to |
410 // be unique on this machine. | 413 // be unique on this machine. |
411 void GetShellIntegrationEntries(BrowserDistribution* dist, | 414 void GetShellIntegrationEntries(BrowserDistribution* dist, |
412 const base::FilePath& chrome_exe, | 415 const base::FilePath& chrome_exe, |
413 const base::string16& suffix, | 416 const base::string16& suffix, |
414 ScopedVector<RegistryEntry>* entries) { | 417 ScopedVector<RegistryEntry>* entries) { |
415 DCHECK_EQ(BrowserDistribution::GetDistribution(), dist); | |
416 const base::string16 icon_path(ShellUtil::FormatIconLocation( | 418 const base::string16 icon_path(ShellUtil::FormatIconLocation( |
417 chrome_exe, install_static::GetIconResourceIndex())); | 419 chrome_exe, install_static::GetIconResourceIndex())); |
418 const base::string16 quoted_exe_path(L"\"" + chrome_exe.value() + L"\""); | 420 const base::string16 quoted_exe_path(L"\"" + chrome_exe.value() + L"\""); |
419 | 421 |
420 // Register for the Start Menu "Internet" link (pre-Win7). | 422 // Register for the Start Menu "Internet" link (pre-Win7). |
421 const base::string16 start_menu_entry(GetBrowserClientKey(dist, suffix)); | 423 const base::string16 start_menu_entry(GetBrowserClientKey(suffix)); |
422 // Register Chrome's display name. | 424 // Register Chrome's display name. |
423 // TODO(grt): http://crbug.com/75152 Also set LocalizedString; see | 425 // TODO(grt): http://crbug.com/75152 Also set LocalizedString; see |
424 // http://msdn.microsoft.com/en-us/library/windows/desktop/cc144109(v=VS.85).a
spx#registering_the_display_name | 426 // http://msdn.microsoft.com/en-us/library/windows/desktop/cc144109(v=VS.85).a
spx#registering_the_display_name |
425 entries->push_back( | 427 entries->push_back( |
426 new RegistryEntry(start_menu_entry, dist->GetDisplayName())); | 428 new RegistryEntry(start_menu_entry, dist->GetDisplayName())); |
427 // Register the "open" verb for launching Chrome via the "Internet" link. | 429 // Register the "open" verb for launching Chrome via the "Internet" link. |
428 entries->push_back(new RegistryEntry( | 430 entries->push_back(new RegistryEntry( |
429 start_menu_entry + ShellUtil::kRegShellOpen, quoted_exe_path)); | 431 start_menu_entry + ShellUtil::kRegShellOpen, quoted_exe_path)); |
430 // Register Chrome's icon for the Start Menu "Internet" link. | 432 // Register Chrome's icon for the Start Menu "Internet" link. |
431 entries->push_back(new RegistryEntry( | 433 entries->push_back(new RegistryEntry( |
432 start_menu_entry + ShellUtil::kRegDefaultIcon, icon_path)); | 434 start_menu_entry + ShellUtil::kRegDefaultIcon, icon_path)); |
433 | 435 |
434 // Register installation information. | 436 // Register installation information. |
435 base::string16 install_info(start_menu_entry + L"\\InstallInfo"); | 437 base::string16 install_info(start_menu_entry + L"\\InstallInfo"); |
436 // Note: not using CommandLine since it has ambiguous rules for quoting | 438 // Note: not using CommandLine since it has ambiguous rules for quoting |
437 // strings. | 439 // strings. |
438 entries->push_back( | 440 entries->push_back( |
439 new RegistryEntry(install_info, kReinstallCommand, | 441 new RegistryEntry(install_info, kReinstallCommand, |
440 quoted_exe_path + L" --" + | 442 quoted_exe_path + L" --" + |
441 base::ASCIIToUTF16(switches::kMakeDefaultBrowser))); | 443 base::ASCIIToUTF16(switches::kMakeDefaultBrowser))); |
442 entries->push_back(new RegistryEntry( | 444 entries->push_back(new RegistryEntry( |
443 install_info, L"HideIconsCommand", | 445 install_info, L"HideIconsCommand", |
444 quoted_exe_path + L" --" + base::ASCIIToUTF16(switches::kHideIcons))); | 446 quoted_exe_path + L" --" + base::ASCIIToUTF16(switches::kHideIcons))); |
445 entries->push_back(new RegistryEntry( | 447 entries->push_back(new RegistryEntry( |
446 install_info, L"ShowIconsCommand", | 448 install_info, L"ShowIconsCommand", |
447 quoted_exe_path + L" --" + base::ASCIIToUTF16(switches::kShowIcons))); | 449 quoted_exe_path + L" --" + base::ASCIIToUTF16(switches::kShowIcons))); |
448 entries->push_back(new RegistryEntry(install_info, L"IconsVisible", 1)); | 450 entries->push_back(new RegistryEntry(install_info, L"IconsVisible", 1)); |
449 | 451 |
450 // Register with Default Programs. | 452 // Register with Default Programs. |
451 const base::string16 reg_app_name(dist->GetBaseAppName().append(suffix)); | 453 const base::string16 reg_app_name( |
| 454 install_static::GetBaseAppName().append(suffix)); |
452 // Tell Windows where to find Chrome's Default Programs info. | 455 // Tell Windows where to find Chrome's Default Programs info. |
453 const base::string16 capabilities(GetCapabilitiesKey(dist, suffix)); | 456 const base::string16 capabilities(GetCapabilitiesKey(suffix)); |
454 entries->push_back(new RegistryEntry(ShellUtil::kRegRegisteredApplications, | 457 entries->push_back(new RegistryEntry(ShellUtil::kRegRegisteredApplications, |
455 reg_app_name, capabilities)); | 458 reg_app_name, capabilities)); |
456 // Write out Chrome's Default Programs info. | 459 // Write out Chrome's Default Programs info. |
457 // TODO(grt): http://crbug.com/75152 Write a reference to a localized | 460 // TODO(grt): http://crbug.com/75152 Write a reference to a localized |
458 // resource rather than this. | 461 // resource rather than this. |
459 entries->push_back(new RegistryEntry(capabilities, | 462 entries->push_back(new RegistryEntry(capabilities, |
460 ShellUtil::kRegApplicationDescription, | 463 ShellUtil::kRegApplicationDescription, |
461 dist->GetLongAppDescription())); | 464 dist->GetLongAppDescription())); |
462 entries->push_back(new RegistryEntry( | 465 entries->push_back(new RegistryEntry( |
463 capabilities, ShellUtil::kRegApplicationIcon, icon_path)); | 466 capabilities, ShellUtil::kRegApplicationIcon, icon_path)); |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
581 | 584 |
582 // <root hkey>\Software\Classes\<protocol>\shell\@ | 585 // <root hkey>\Software\Classes\<protocol>\shell\@ |
583 base::string16 protocol_shell_key = url_key + ShellUtil::kRegShellPath; | 586 base::string16 protocol_shell_key = url_key + ShellUtil::kRegShellPath; |
584 entries->push_back(new RegistryEntry(protocol_shell_key, L"open")); | 587 entries->push_back(new RegistryEntry(protocol_shell_key, L"open")); |
585 } | 588 } |
586 | 589 |
587 // This method returns a list of all the user level registry entries that are | 590 // This method returns a list of all the user level registry entries that are |
588 // needed to make Chromium default browser on XP. Some of these entries are | 591 // needed to make Chromium default browser on XP. Some of these entries are |
589 // irrelevant in recent versions of Windows, but we register them anyways as | 592 // irrelevant in recent versions of Windows, but we register them anyways as |
590 // some legacy apps are hardcoded to lookup those values. | 593 // some legacy apps are hardcoded to lookup those values. |
591 void GetXPStyleDefaultBrowserUserEntries(BrowserDistribution* dist, | 594 void GetXPStyleDefaultBrowserUserEntries(const base::FilePath& chrome_exe, |
592 const base::FilePath& chrome_exe, | |
593 const base::string16& suffix, | 595 const base::string16& suffix, |
594 ScopedVector<RegistryEntry>* entries) { | 596 ScopedVector<RegistryEntry>* entries) { |
595 DCHECK_EQ(BrowserDistribution::GetDistribution(), dist); | |
596 // File extension associations. | 597 // File extension associations. |
597 base::string16 html_prog_id(GetBrowserProgId(suffix)); | 598 base::string16 html_prog_id(GetBrowserProgId(suffix)); |
598 for (int i = 0; ShellUtil::kDefaultFileAssociations[i] != NULL; i++) { | 599 for (int i = 0; ShellUtil::kDefaultFileAssociations[i] != NULL; i++) { |
599 GetAppDefaultRegistrationEntries( | 600 GetAppDefaultRegistrationEntries( |
600 html_prog_id, ShellUtil::kDefaultFileAssociations[i], true, entries); | 601 html_prog_id, ShellUtil::kDefaultFileAssociations[i], true, entries); |
601 } | 602 } |
602 | 603 |
603 // Protocols associations. | 604 // Protocols associations. |
604 base::string16 chrome_open = ShellUtil::GetChromeShellOpenCmd(chrome_exe); | 605 base::string16 chrome_open = ShellUtil::GetChromeShellOpenCmd(chrome_exe); |
605 base::string16 chrome_icon = ShellUtil::FormatIconLocation( | 606 base::string16 chrome_icon = ShellUtil::FormatIconLocation( |
606 chrome_exe, install_static::GetIconResourceIndex()); | 607 chrome_exe, install_static::GetIconResourceIndex()); |
607 for (int i = 0; ShellUtil::kBrowserProtocolAssociations[i] != NULL; i++) { | 608 for (int i = 0; ShellUtil::kBrowserProtocolAssociations[i] != NULL; i++) { |
608 GetXPStyleUserProtocolEntries(ShellUtil::kBrowserProtocolAssociations[i], | 609 GetXPStyleUserProtocolEntries(ShellUtil::kBrowserProtocolAssociations[i], |
609 chrome_icon, chrome_open, entries); | 610 chrome_icon, chrome_open, entries); |
610 } | 611 } |
611 | 612 |
612 // start->Internet shortcut. | 613 // start->Internet shortcut. |
613 base::string16 start_menu(ShellUtil::kRegStartMenuInternet); | 614 base::string16 start_menu(ShellUtil::kRegStartMenuInternet); |
614 base::string16 app_name = dist->GetBaseAppName() + suffix; | 615 base::string16 app_name = install_static::GetBaseAppName().append(suffix); |
615 entries->push_back(new RegistryEntry(start_menu, app_name)); | 616 entries->push_back(new RegistryEntry(start_menu, app_name)); |
616 } | 617 } |
617 | 618 |
618 // Checks that all |entries| are present on this computer (or absent if their | 619 // Checks that all |entries| are present on this computer (or absent if their |
619 // |removal_flag_| is set). |look_for_in| is passed to | 620 // |removal_flag_| is set). |look_for_in| is passed to |
620 // RegistryEntry::ExistsInRegistry(). Documentation for it can be found there. | 621 // RegistryEntry::ExistsInRegistry(). Documentation for it can be found there. |
621 bool AreEntriesAsDesired(const ScopedVector<RegistryEntry>& entries, | 622 bool AreEntriesAsDesired(const ScopedVector<RegistryEntry>& entries, |
622 uint32_t look_for_in) { | 623 uint32_t look_for_in) { |
623 for (const auto* entry : entries) { | 624 for (const auto* entry : entries) { |
624 if (entry->ExistsInRegistry(look_for_in) != !entry->IsFlaggedForRemoval()) | 625 if (entry->ExistsInRegistry(look_for_in) != !entry->IsFlaggedForRemoval()) |
(...skipping 19 matching lines...) Expand all Loading... |
644 ScopedVector<RegistryEntry> entries; | 645 ScopedVector<RegistryEntry> entries; |
645 GetChromeProgIdEntries(dist, chrome_exe, suffix, &entries); | 646 GetChromeProgIdEntries(dist, chrome_exe, suffix, &entries); |
646 GetShellIntegrationEntries(dist, chrome_exe, suffix, &entries); | 647 GetShellIntegrationEntries(dist, chrome_exe, suffix, &entries); |
647 GetChromeAppRegistrationEntries(chrome_exe, suffix, &entries); | 648 GetChromeAppRegistrationEntries(chrome_exe, suffix, &entries); |
648 return AreEntriesAsDesired(entries, look_for_in); | 649 return AreEntriesAsDesired(entries, look_for_in); |
649 } | 650 } |
650 | 651 |
651 // This method checks if Chrome is already registered on the local machine | 652 // This method checks if Chrome is already registered on the local machine |
652 // for the requested protocol. It just checks the one value required for this. | 653 // for the requested protocol. It just checks the one value required for this. |
653 // See RegistryEntry::ExistsInRegistry for the behavior of |look_for_in|. | 654 // See RegistryEntry::ExistsInRegistry for the behavior of |look_for_in|. |
654 bool IsChromeRegisteredForProtocol(BrowserDistribution* dist, | 655 bool IsChromeRegisteredForProtocol(const base::string16& suffix, |
655 const base::string16& suffix, | |
656 const base::string16& protocol, | 656 const base::string16& protocol, |
657 uint32_t look_for_in) { | 657 uint32_t look_for_in) { |
658 ScopedVector<RegistryEntry> entries; | 658 ScopedVector<RegistryEntry> entries; |
659 GetProtocolCapabilityEntries(dist, suffix, protocol, &entries); | 659 GetProtocolCapabilityEntries(suffix, protocol, &entries); |
660 return AreEntriesAsDesired(entries, look_for_in); | 660 return AreEntriesAsDesired(entries, look_for_in); |
661 } | 661 } |
662 | 662 |
663 // This method registers Chrome by launching an elevated setup.exe. That will | 663 // 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 | 664 // 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 | 665 // 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 | 666 // 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 | 667 // 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 | 668 // installs on Windows 7 where setup.exe did not have permission to register |
669 // Chrome during install. It may also be used on all OSs for system-level | 669 // Chrome during install. It may also be used on all OSs for system-level |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
786 // |suffix|. | 786 // |suffix|. |
787 // |confirmation_level| is the level of verification desired as described in | 787 // |confirmation_level| is the level of verification desired as described in |
788 // the RegistrationConfirmationLevel enum above. | 788 // the RegistrationConfirmationLevel enum above. |
789 // |suffix| can be the empty string (this is used to support old installs | 789 // |suffix| can be the empty string (this is used to support old installs |
790 // where we used to not suffix user-level installs if they were the first to | 790 // where we used to not suffix user-level installs if they were the first to |
791 // request the non-suffixed registry entries on the machine). | 791 // request the non-suffixed registry entries on the machine). |
792 // NOTE: This a quick check that only validates that a single registry entry | 792 // NOTE: This a quick check that only validates that a single registry entry |
793 // points to |chrome_exe|. This should only be used at run-time to determine | 793 // points to |chrome_exe|. This should only be used at run-time to determine |
794 // how Chrome is registered, not to know whether the registration is complete | 794 // how Chrome is registered, not to know whether the registration is complete |
795 // at install-time (IsChromeRegistered() can be used for that). | 795 // at install-time (IsChromeRegistered() can be used for that). |
796 bool QuickIsChromeRegistered(BrowserDistribution* dist, | 796 bool QuickIsChromeRegistered(const base::FilePath& chrome_exe, |
797 const base::FilePath& chrome_exe, | |
798 const base::string16& suffix, | 797 const base::string16& suffix, |
799 RegistrationConfirmationLevel confirmation_level) { | 798 RegistrationConfirmationLevel confirmation_level) { |
800 // Assert that this is only called with the one relevant distribution. | |
801 // TODO(grt): Remove this when BrowserDistribution goes away. | |
802 DCHECK_EQ(BrowserDistribution::GetDistribution(), dist); | |
803 // Get the appropriate key to look for based on the level desired. | 799 // Get the appropriate key to look for based on the level desired. |
804 base::string16 reg_key; | 800 base::string16 reg_key; |
805 switch (confirmation_level) { | 801 switch (confirmation_level) { |
806 case CONFIRM_PROGID_REGISTRATION: | 802 case CONFIRM_PROGID_REGISTRATION: |
807 // Software\Classes\ChromeHTML|suffix| | 803 // Software\Classes\ChromeHTML|suffix| |
808 reg_key = ShellUtil::kRegClasses; | 804 reg_key = ShellUtil::kRegClasses; |
809 reg_key.push_back(base::FilePath::kSeparators[0]); | 805 reg_key.push_back(base::FilePath::kSeparators[0]); |
810 reg_key.append(install_static::GetProgIdPrefix()); | 806 reg_key.append(install_static::GetProgIdPrefix()); |
811 reg_key.append(suffix); | 807 reg_key.append(suffix); |
812 break; | 808 break; |
813 case CONFIRM_SHELL_REGISTRATION: | 809 case CONFIRM_SHELL_REGISTRATION: |
814 case CONFIRM_SHELL_REGISTRATION_IN_HKLM: | 810 case CONFIRM_SHELL_REGISTRATION_IN_HKLM: |
815 // Software\Clients\StartMenuInternet\Google Chrome|suffix| | 811 // Software\Clients\StartMenuInternet\Google Chrome|suffix| |
816 reg_key = GetBrowserClientKey(dist, suffix); | 812 reg_key = GetBrowserClientKey(suffix); |
817 break; | 813 break; |
818 default: | 814 default: |
819 NOTREACHED(); | 815 NOTREACHED(); |
820 break; | 816 break; |
821 } | 817 } |
822 reg_key.append(ShellUtil::kRegShellOpen); | 818 reg_key.append(ShellUtil::kRegShellOpen); |
823 | 819 |
824 // ProgId registrations are allowed to reside in HKCU for user-level installs | 820 // ProgId registrations are allowed to reside in HKCU for user-level installs |
825 // (and values there have priority over values in HKLM). The same is true for | 821 // (and values there have priority over values in HKLM). The same is true for |
826 // shell integration entries as of Windows 8. | 822 // shell integration entries as of Windows 8. |
(...skipping 19 matching lines...) Expand all Loading... |
846 // Sets |suffix| to a 27 character string that is specific to this user on this | 842 // Sets |suffix| to a 27 character string that is specific to this user on this |
847 // machine (on user-level installs only). | 843 // machine (on user-level installs only). |
848 // To support old-style user-level installs however, |suffix| is cleared if the | 844 // To support old-style user-level installs however, |suffix| is cleared if the |
849 // user currently owns the non-suffixed HKLM registrations. | 845 // user currently owns the non-suffixed HKLM registrations. |
850 // |suffix| can also be set to the user's username if the current install is | 846 // |suffix| can also be set to the user's username if the current install is |
851 // suffixed as per the old-style registrations. | 847 // suffixed as per the old-style registrations. |
852 // |suffix| is cleared on system-level installs. | 848 // |suffix| is cleared on system-level installs. |
853 // |suffix| should then be appended to all Chrome properties that may conflict | 849 // |suffix| should then be appended to all Chrome properties that may conflict |
854 // with other Chrome user-level installs. | 850 // with other Chrome user-level installs. |
855 // Returns true unless one of the underlying calls fails. | 851 // Returns true unless one of the underlying calls fails. |
856 bool GetInstallationSpecificSuffix(BrowserDistribution* dist, | 852 bool GetInstallationSpecificSuffix(const base::FilePath& chrome_exe, |
857 const base::FilePath& chrome_exe, | |
858 base::string16* suffix) { | 853 base::string16* suffix) { |
859 if (!InstallUtil::IsPerUserInstall() || | 854 if (!InstallUtil::IsPerUserInstall() || |
860 QuickIsChromeRegistered(dist, chrome_exe, base::string16(), | 855 QuickIsChromeRegistered(chrome_exe, base::string16(), |
861 CONFIRM_SHELL_REGISTRATION)) { | 856 CONFIRM_SHELL_REGISTRATION)) { |
862 // No suffix on system-level installs and user-level installs already | 857 // No suffix on system-level installs and user-level installs already |
863 // registered with no suffix. | 858 // registered with no suffix. |
864 suffix->clear(); | 859 suffix->clear(); |
865 return true; | 860 return true; |
866 } | 861 } |
867 | 862 |
868 // Get the old suffix for the check below. | 863 // Get the old suffix for the check below. |
869 if (!ShellUtil::GetOldUserSpecificRegistrySuffix(suffix)) { | 864 if (!ShellUtil::GetOldUserSpecificRegistrySuffix(suffix)) { |
870 NOTREACHED(); | 865 NOTREACHED(); |
871 return false; | 866 return false; |
872 } | 867 } |
873 if (QuickIsChromeRegistered(dist, chrome_exe, *suffix, | 868 if (QuickIsChromeRegistered(chrome_exe, *suffix, |
874 CONFIRM_SHELL_REGISTRATION)) { | 869 CONFIRM_SHELL_REGISTRATION)) { |
875 // Username suffix for installs that are suffixed as per the old-style. | 870 // Username suffix for installs that are suffixed as per the old-style. |
876 return true; | 871 return true; |
877 } | 872 } |
878 | 873 |
879 return ShellUtil::GetUserSpecificRegistrySuffix(suffix); | 874 return ShellUtil::GetUserSpecificRegistrySuffix(suffix); |
880 } | 875 } |
881 | 876 |
882 // Returns the root registry key (HKLM or HKCU) under which registrations must | 877 // Returns the root registry key (HKLM or HKCU) under which registrations must |
883 // be placed for this install. As of Windows 8 everything can go in HKCU for | 878 // be placed for this install. As of Windows 8 everything can go in HKCU for |
884 // per-user installs. | 879 // per-user installs. |
885 HKEY DetermineRegistrationRoot(bool is_per_user) { | 880 HKEY DetermineRegistrationRoot(bool is_per_user) { |
886 return is_per_user && base::win::GetVersion() >= base::win::VERSION_WIN8 ? | 881 return is_per_user && base::win::GetVersion() >= base::win::VERSION_WIN8 ? |
887 HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE; | 882 HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE; |
888 } | 883 } |
889 | 884 |
890 // Associates Chrome with supported protocols and file associations. This should | 885 // Associates Chrome with supported protocols and file associations. This should |
891 // not be required on Vista+ but since some applications still read | 886 // not be required on Vista+ but since some applications still read |
892 // Software\Classes\http key directly, we have to do this on Vista+ as well. | 887 // Software\Classes\http key directly, we have to do this on Vista+ as well. |
893 bool RegisterChromeAsDefaultXPStyle(BrowserDistribution* dist, | 888 bool RegisterChromeAsDefaultXPStyle(int shell_change, |
894 int shell_change, | |
895 const base::FilePath& chrome_exe) { | 889 const base::FilePath& chrome_exe) { |
896 bool ret = true; | 890 bool ret = true; |
897 ScopedVector<RegistryEntry> entries; | 891 ScopedVector<RegistryEntry> entries; |
898 GetXPStyleDefaultBrowserUserEntries( | 892 GetXPStyleDefaultBrowserUserEntries( |
899 dist, chrome_exe, | 893 chrome_exe, ShellUtil::GetCurrentInstallationSuffix(chrome_exe), |
900 ShellUtil::GetCurrentInstallationSuffix(dist, chrome_exe), &entries); | 894 &entries); |
901 | 895 |
902 // Change the default browser for current user. | 896 // Change the default browser for current user. |
903 if ((shell_change & ShellUtil::CURRENT_USER) && | 897 if ((shell_change & ShellUtil::CURRENT_USER) && |
904 !ShellUtil::AddRegistryEntries(HKEY_CURRENT_USER, entries)) { | 898 !ShellUtil::AddRegistryEntries(HKEY_CURRENT_USER, entries)) { |
905 ret = false; | 899 ret = false; |
906 LOG(ERROR) << "Could not make Chrome default browser (XP/current user)."; | 900 LOG(ERROR) << "Could not make Chrome default browser (XP/current user)."; |
907 } | 901 } |
908 | 902 |
909 // Chrome as default browser at system level. | 903 // Chrome as default browser at system level. |
910 if ((shell_change & ShellUtil::SYSTEM_LEVEL) && | 904 if ((shell_change & ShellUtil::SYSTEM_LEVEL) && |
911 !ShellUtil::AddRegistryEntries(HKEY_LOCAL_MACHINE, entries)) { | 905 !ShellUtil::AddRegistryEntries(HKEY_LOCAL_MACHINE, entries)) { |
912 ret = false; | 906 ret = false; |
913 LOG(ERROR) << "Could not make Chrome default browser (XP/system level)."; | 907 LOG(ERROR) << "Could not make Chrome default browser (XP/system level)."; |
914 } | 908 } |
915 | 909 |
916 return ret; | 910 return ret; |
917 } | 911 } |
918 | 912 |
919 // Associates Chrome with |protocol| in the registry. This should not be | 913 // Associates Chrome with |protocol| in the registry. This should not be |
920 // required on Vista+ but since some applications still read these registry | 914 // required on Vista+ but since some applications still read these registry |
921 // keys directly, we have to do this on Vista+ as well. | 915 // keys directly, we have to do this on Vista+ as well. |
922 // See http://msdn.microsoft.com/library/aa767914.aspx for more details. | 916 // See http://msdn.microsoft.com/library/aa767914.aspx for more details. |
923 bool RegisterChromeAsDefaultProtocolClientXPStyle( | 917 bool RegisterChromeAsDefaultProtocolClientXPStyle( |
924 BrowserDistribution* dist, | |
925 const base::FilePath& chrome_exe, | 918 const base::FilePath& chrome_exe, |
926 const base::string16& protocol) { | 919 const base::string16& protocol) { |
927 DCHECK_EQ(BrowserDistribution::GetDistribution(), dist); | |
928 ScopedVector<RegistryEntry> entries; | 920 ScopedVector<RegistryEntry> entries; |
929 const base::string16 chrome_open( | 921 const base::string16 chrome_open( |
930 ShellUtil::GetChromeShellOpenCmd(chrome_exe)); | 922 ShellUtil::GetChromeShellOpenCmd(chrome_exe)); |
931 const base::string16 chrome_icon(ShellUtil::FormatIconLocation( | 923 const base::string16 chrome_icon(ShellUtil::FormatIconLocation( |
932 chrome_exe, install_static::GetIconResourceIndex())); | 924 chrome_exe, install_static::GetIconResourceIndex())); |
933 GetXPStyleUserProtocolEntries(protocol, chrome_icon, chrome_open, &entries); | 925 GetXPStyleUserProtocolEntries(protocol, chrome_icon, chrome_open, &entries); |
934 // Change the default protocol handler for current user. | 926 // Change the default protocol handler for current user. |
935 if (!ShellUtil::AddRegistryEntries(HKEY_CURRENT_USER, entries)) { | 927 if (!ShellUtil::AddRegistryEntries(HKEY_CURRENT_USER, entries)) { |
936 LOG(ERROR) << "Could not make Chrome default protocol client (XP)."; | 928 LOG(ERROR) << "Could not make Chrome default protocol client (XP)."; |
937 return false; | 929 return false; |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1036 const base::FilePath& chrome_exe, | 1028 const base::FilePath& chrome_exe, |
1037 const wchar_t* const* protocols, | 1029 const wchar_t* const* protocols, |
1038 size_t num_protocols) { | 1030 size_t num_protocols) { |
1039 base::win::ScopedComPtr<IApplicationAssociationRegistration> registration; | 1031 base::win::ScopedComPtr<IApplicationAssociationRegistration> registration; |
1040 HRESULT hr = registration.CreateInstance( | 1032 HRESULT hr = registration.CreateInstance( |
1041 CLSID_ApplicationAssociationRegistration, NULL, CLSCTX_INPROC); | 1033 CLSID_ApplicationAssociationRegistration, NULL, CLSCTX_INPROC); |
1042 if (FAILED(hr)) | 1034 if (FAILED(hr)) |
1043 return ShellUtil::UNKNOWN_DEFAULT; | 1035 return ShellUtil::UNKNOWN_DEFAULT; |
1044 | 1036 |
1045 base::string16 prog_id(install_static::GetProgIdPrefix()); | 1037 base::string16 prog_id(install_static::GetProgIdPrefix()); |
1046 BrowserDistribution* dist = BrowserDistribution::GetDistribution(); | 1038 prog_id += ShellUtil::GetCurrentInstallationSuffix(chrome_exe); |
1047 prog_id += ShellUtil::GetCurrentInstallationSuffix(dist, chrome_exe); | |
1048 | 1039 |
1049 for (size_t i = 0; i < num_protocols; ++i) { | 1040 for (size_t i = 0; i < num_protocols; ++i) { |
1050 base::win::ScopedCoMem<wchar_t> current_app; | 1041 base::win::ScopedCoMem<wchar_t> current_app; |
1051 hr = registration->QueryCurrentDefault(protocols[i], AT_URLPROTOCOL, | 1042 hr = registration->QueryCurrentDefault(protocols[i], AT_URLPROTOCOL, |
1052 AL_EFFECTIVE, ¤t_app); | 1043 AL_EFFECTIVE, ¤t_app); |
1053 if (FAILED(hr) || prog_id.compare(current_app) != 0) | 1044 if (FAILED(hr) || prog_id.compare(current_app) != 0) |
1054 return ShellUtil::NOT_DEFAULT; | 1045 return ShellUtil::NOT_DEFAULT; |
1055 } | 1046 } |
1056 | 1047 |
1057 return ShellUtil::IS_DEFAULT; | 1048 return ShellUtil::IS_DEFAULT; |
1058 } | 1049 } |
1059 | 1050 |
1060 // Probe using IApplicationAssociationRegistration::QueryAppIsDefault (Vista and | 1051 // Probe using IApplicationAssociationRegistration::QueryAppIsDefault (Vista and |
1061 // Windows 7); see ProbeProtocolHandlers. | 1052 // Windows 7); see ProbeProtocolHandlers. |
1062 ShellUtil::DefaultState ProbeAppIsDefaultHandlers( | 1053 ShellUtil::DefaultState ProbeAppIsDefaultHandlers( |
1063 const base::FilePath& chrome_exe, | 1054 const base::FilePath& chrome_exe, |
1064 const wchar_t* const* protocols, | 1055 const wchar_t* const* protocols, |
1065 size_t num_protocols) { | 1056 size_t num_protocols) { |
1066 base::win::ScopedComPtr<IApplicationAssociationRegistration> registration; | 1057 base::win::ScopedComPtr<IApplicationAssociationRegistration> registration; |
1067 HRESULT hr = registration.CreateInstance( | 1058 HRESULT hr = registration.CreateInstance( |
1068 CLSID_ApplicationAssociationRegistration, NULL, CLSCTX_INPROC); | 1059 CLSID_ApplicationAssociationRegistration, NULL, CLSCTX_INPROC); |
1069 if (FAILED(hr)) | 1060 if (FAILED(hr)) |
1070 return ShellUtil::UNKNOWN_DEFAULT; | 1061 return ShellUtil::UNKNOWN_DEFAULT; |
1071 | 1062 |
1072 BrowserDistribution* dist = BrowserDistribution::GetDistribution(); | 1063 base::string16 app_name(GetApplicationName(chrome_exe)); |
1073 base::string16 app_name(ShellUtil::GetApplicationName(dist, chrome_exe)); | |
1074 | 1064 |
1075 BOOL result; | 1065 BOOL result; |
1076 for (size_t i = 0; i < num_protocols; ++i) { | 1066 for (size_t i = 0; i < num_protocols; ++i) { |
1077 result = TRUE; | 1067 result = TRUE; |
1078 hr = registration->QueryAppIsDefault(protocols[i], AT_URLPROTOCOL, | 1068 hr = registration->QueryAppIsDefault(protocols[i], AT_URLPROTOCOL, |
1079 AL_EFFECTIVE, app_name.c_str(), &result); | 1069 AL_EFFECTIVE, app_name.c_str(), &result); |
1080 if (FAILED(hr) || result == FALSE) | 1070 if (FAILED(hr) || result == FALSE) |
1081 return ShellUtil::NOT_DEFAULT; | 1071 return ShellUtil::NOT_DEFAULT; |
1082 } | 1072 } |
1083 | 1073 |
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1410 icon_index(0), | 1400 icon_index(0), |
1411 pin_to_taskbar(false), | 1401 pin_to_taskbar(false), |
1412 options(0U) {} | 1402 options(0U) {} |
1413 | 1403 |
1414 ShellUtil::ShortcutProperties::ShortcutProperties( | 1404 ShellUtil::ShortcutProperties::ShortcutProperties( |
1415 const ShortcutProperties& other) = default; | 1405 const ShortcutProperties& other) = default; |
1416 | 1406 |
1417 ShellUtil::ShortcutProperties::~ShortcutProperties() { | 1407 ShellUtil::ShortcutProperties::~ShortcutProperties() { |
1418 } | 1408 } |
1419 | 1409 |
1420 bool ShellUtil::QuickIsChromeRegisteredInHKLM(BrowserDistribution* dist, | 1410 bool ShellUtil::QuickIsChromeRegisteredInHKLM(const base::FilePath& chrome_exe, |
1421 const base::FilePath& chrome_exe, | |
1422 const base::string16& suffix) { | 1411 const base::string16& suffix) { |
1423 return QuickIsChromeRegistered(dist, chrome_exe, suffix, | 1412 return QuickIsChromeRegistered(chrome_exe, suffix, |
1424 CONFIRM_SHELL_REGISTRATION_IN_HKLM); | 1413 CONFIRM_SHELL_REGISTRATION_IN_HKLM); |
1425 } | 1414 } |
1426 | 1415 |
1427 bool ShellUtil::ShortcutLocationIsSupported(ShortcutLocation location) { | 1416 bool ShellUtil::ShortcutLocationIsSupported(ShortcutLocation location) { |
1428 switch (location) { | 1417 switch (location) { |
1429 case SHORTCUT_LOCATION_DESKTOP: // Falls through. | 1418 case SHORTCUT_LOCATION_DESKTOP: // Falls through. |
1430 case SHORTCUT_LOCATION_QUICK_LAUNCH: // Falls through. | 1419 case SHORTCUT_LOCATION_QUICK_LAUNCH: // Falls through. |
1431 case SHORTCUT_LOCATION_START_MENU_ROOT: // Falls through. | 1420 case SHORTCUT_LOCATION_START_MENU_ROOT: // Falls through. |
1432 case SHORTCUT_LOCATION_START_MENU_CHROME_DIR_DEPRECATED: // Falls through. | 1421 case SHORTCUT_LOCATION_START_MENU_CHROME_DIR_DEPRECATED: // Falls through. |
1433 case SHORTCUT_LOCATION_START_MENU_CHROME_APPS_DIR: | 1422 case SHORTCUT_LOCATION_START_MENU_CHROME_APPS_DIR: |
1434 return true; | 1423 return true; |
1435 case SHORTCUT_LOCATION_TASKBAR_PINS: | 1424 case SHORTCUT_LOCATION_TASKBAR_PINS: |
1436 return base::win::GetVersion() >= base::win::VERSION_WIN7; | 1425 return base::win::GetVersion() >= base::win::VERSION_WIN7; |
1437 case SHORTCUT_LOCATION_APP_SHORTCUTS: | 1426 case SHORTCUT_LOCATION_APP_SHORTCUTS: |
1438 return base::win::GetVersion() >= base::win::VERSION_WIN8; | 1427 return base::win::GetVersion() >= base::win::VERSION_WIN8; |
1439 default: | 1428 default: |
1440 NOTREACHED(); | 1429 NOTREACHED(); |
1441 return false; | 1430 return false; |
1442 } | 1431 } |
1443 } | 1432 } |
1444 | 1433 |
1445 bool ShellUtil::GetShortcutPath(ShortcutLocation location, | 1434 bool ShellUtil::GetShortcutPath(ShortcutLocation location, |
1446 BrowserDistribution* dist, | 1435 BrowserDistribution* dist, |
1447 ShellChange level, | 1436 ShellChange level, |
1448 base::FilePath* path) { | 1437 base::FilePath* path) { |
| 1438 // Assert that this is only called with the one relevant distribution. |
| 1439 // TODO(grt): Remove this when BrowserDistribution goes away. |
| 1440 DCHECK_EQ(BrowserDistribution::GetDistribution(), dist); |
1449 DCHECK(path); | 1441 DCHECK(path); |
1450 DCHECK_EQ(BrowserDistribution::GetDistribution(), dist); | |
1451 int dir_key = -1; | 1442 int dir_key = -1; |
1452 base::string16 folder_to_append; | 1443 base::string16 folder_to_append; |
1453 switch (location) { | 1444 switch (location) { |
1454 case SHORTCUT_LOCATION_DESKTOP: | 1445 case SHORTCUT_LOCATION_DESKTOP: |
1455 dir_key = (level == CURRENT_USER) ? base::DIR_USER_DESKTOP : | 1446 dir_key = (level == CURRENT_USER) ? base::DIR_USER_DESKTOP : |
1456 base::DIR_COMMON_DESKTOP; | 1447 base::DIR_COMMON_DESKTOP; |
1457 break; | 1448 break; |
1458 case SHORTCUT_LOCATION_QUICK_LAUNCH: | 1449 case SHORTCUT_LOCATION_QUICK_LAUNCH: |
1459 // There is no support for a system-level Quick Launch shortcut. | 1450 // There is no support for a system-level Quick Launch shortcut. |
1460 DCHECK_EQ(level, CURRENT_USER); | 1451 DCHECK_EQ(level, CURRENT_USER); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1496 if (!folder_to_append.empty()) | 1487 if (!folder_to_append.empty()) |
1497 *path = path->Append(folder_to_append); | 1488 *path = path->Append(folder_to_append); |
1498 | 1489 |
1499 return true; | 1490 return true; |
1500 } | 1491 } |
1501 | 1492 |
1502 bool ShellUtil::MoveExistingShortcut(ShortcutLocation old_location, | 1493 bool ShellUtil::MoveExistingShortcut(ShortcutLocation old_location, |
1503 ShortcutLocation new_location, | 1494 ShortcutLocation new_location, |
1504 BrowserDistribution* dist, | 1495 BrowserDistribution* dist, |
1505 const ShortcutProperties& properties) { | 1496 const ShortcutProperties& properties) { |
| 1497 // Assert that this is only called with the one relevant distribution. |
| 1498 // TODO(grt): Remove this when BrowserDistribution goes away. |
| 1499 DCHECK_EQ(BrowserDistribution::GetDistribution(), dist); |
1506 // Explicitly whitelist locations to which this is applicable. | 1500 // Explicitly whitelist locations to which this is applicable. |
1507 if (old_location != SHORTCUT_LOCATION_START_MENU_CHROME_DIR_DEPRECATED || | 1501 if (old_location != SHORTCUT_LOCATION_START_MENU_CHROME_DIR_DEPRECATED || |
1508 new_location != SHORTCUT_LOCATION_START_MENU_ROOT) { | 1502 new_location != SHORTCUT_LOCATION_START_MENU_ROOT) { |
1509 NOTREACHED(); | 1503 NOTREACHED(); |
1510 return false; | 1504 return false; |
1511 } | 1505 } |
1512 | 1506 |
1513 base::string16 shortcut_name( | 1507 base::string16 shortcut_name( |
1514 ExtractShortcutNameFromProperties(dist, properties)); | 1508 ExtractShortcutNameFromProperties(dist, properties)); |
1515 | 1509 |
1516 base::FilePath old_shortcut_path; | 1510 base::FilePath old_shortcut_path; |
1517 base::FilePath new_shortcut_path; | 1511 base::FilePath new_shortcut_path; |
1518 GetShortcutPath(old_location, dist, properties.level, &old_shortcut_path); | 1512 GetShortcutPath(old_location, dist, properties.level, &old_shortcut_path); |
1519 GetShortcutPath(new_location, dist, properties.level, &new_shortcut_path); | 1513 GetShortcutPath(new_location, dist, properties.level, &new_shortcut_path); |
1520 old_shortcut_path = old_shortcut_path.Append(shortcut_name); | 1514 old_shortcut_path = old_shortcut_path.Append(shortcut_name); |
1521 new_shortcut_path = new_shortcut_path.Append(shortcut_name); | 1515 new_shortcut_path = new_shortcut_path.Append(shortcut_name); |
1522 | 1516 |
1523 bool result = base::Move(old_shortcut_path, new_shortcut_path); | 1517 bool result = base::Move(old_shortcut_path, new_shortcut_path); |
1524 RemoveShortcutFolderIfEmpty(old_location, dist, properties.level); | 1518 RemoveShortcutFolderIfEmpty(old_location, dist, properties.level); |
1525 return result; | 1519 return result; |
1526 } | 1520 } |
1527 | 1521 |
1528 bool ShellUtil::CreateOrUpdateShortcut( | 1522 bool ShellUtil::CreateOrUpdateShortcut( |
1529 ShortcutLocation location, | 1523 ShortcutLocation location, |
1530 BrowserDistribution* dist, | 1524 BrowserDistribution* dist, |
1531 const ShortcutProperties& properties, | 1525 const ShortcutProperties& properties, |
1532 ShortcutOperation operation) { | 1526 ShortcutOperation operation) { |
| 1527 // Assert that this is only called with the one relevant distribution. |
| 1528 // TODO(grt): Remove this when BrowserDistribution goes away. |
| 1529 DCHECK_EQ(BrowserDistribution::GetDistribution(), dist); |
1533 // Explicitly whitelist locations to which this is applicable. | 1530 // Explicitly whitelist locations to which this is applicable. |
1534 if (location != SHORTCUT_LOCATION_DESKTOP && | 1531 if (location != SHORTCUT_LOCATION_DESKTOP && |
1535 location != SHORTCUT_LOCATION_QUICK_LAUNCH && | 1532 location != SHORTCUT_LOCATION_QUICK_LAUNCH && |
1536 location != SHORTCUT_LOCATION_START_MENU_ROOT && | 1533 location != SHORTCUT_LOCATION_START_MENU_ROOT && |
1537 location != SHORTCUT_LOCATION_START_MENU_CHROME_DIR_DEPRECATED && | 1534 location != SHORTCUT_LOCATION_START_MENU_CHROME_DIR_DEPRECATED && |
1538 location != SHORTCUT_LOCATION_START_MENU_CHROME_APPS_DIR) { | 1535 location != SHORTCUT_LOCATION_START_MENU_CHROME_APPS_DIR) { |
1539 NOTREACHED(); | 1536 NOTREACHED(); |
1540 return false; | 1537 return false; |
1541 } | 1538 } |
1542 | 1539 |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1631 const base::FilePath& chrome_exe) { | 1628 const base::FilePath& chrome_exe) { |
1632 return L"\"" + chrome_exe.value() + L"\" -- \"%1\""; | 1629 return L"\"" + chrome_exe.value() + L"\" -- \"%1\""; |
1633 } | 1630 } |
1634 | 1631 |
1635 base::string16 ShellUtil::GetChromeDelegateCommand( | 1632 base::string16 ShellUtil::GetChromeDelegateCommand( |
1636 const base::FilePath& chrome_exe) { | 1633 const base::FilePath& chrome_exe) { |
1637 return L"\"" + chrome_exe.value() + L"\" -- %*"; | 1634 return L"\"" + chrome_exe.value() + L"\" -- %*"; |
1638 } | 1635 } |
1639 | 1636 |
1640 void ShellUtil::GetRegisteredBrowsers( | 1637 void ShellUtil::GetRegisteredBrowsers( |
1641 BrowserDistribution* dist, | |
1642 std::map<base::string16, base::string16>* browsers) { | 1638 std::map<base::string16, base::string16>* browsers) { |
1643 DCHECK(dist); | |
1644 DCHECK(browsers); | 1639 DCHECK(browsers); |
1645 | 1640 |
1646 const base::string16 base_key(kRegStartMenuInternet); | 1641 const base::string16 base_key(kRegStartMenuInternet); |
1647 base::string16 client_path; | 1642 base::string16 client_path; |
1648 RegKey key; | 1643 RegKey key; |
1649 base::string16 name; | 1644 base::string16 name; |
1650 base::string16 command; | 1645 base::string16 command; |
1651 | 1646 |
1652 // HKCU has precedence over HKLM for these registrations: http://goo.gl/xjczJ. | 1647 // HKCU has precedence over HKLM for these registrations: http://goo.gl/xjczJ. |
1653 // Look in HKCU second to override any identical values found in HKLM. | 1648 // Look in HKCU second to override any identical values found in HKLM. |
1654 const HKEY roots[] = { HKEY_LOCAL_MACHINE, HKEY_CURRENT_USER }; | 1649 const HKEY roots[] = { HKEY_LOCAL_MACHINE, HKEY_CURRENT_USER }; |
1655 for (const HKEY root : roots) { | 1650 for (const HKEY root : roots) { |
1656 for (base::win::RegistryKeyIterator iter(root, base_key.c_str()); | 1651 for (base::win::RegistryKeyIterator iter(root, base_key.c_str()); |
1657 iter.Valid(); ++iter) { | 1652 iter.Valid(); ++iter) { |
1658 client_path.assign(base_key).append(1, L'\\').append(iter.Name()); | 1653 client_path.assign(base_key).append(1, L'\\').append(iter.Name()); |
1659 // Read the browser's name (localized according to install language). | 1654 // Read the browser's name (localized according to install language). |
1660 if (key.Open(root, client_path.c_str(), | 1655 if (key.Open(root, client_path.c_str(), KEY_QUERY_VALUE) != |
1661 KEY_QUERY_VALUE) != ERROR_SUCCESS || | 1656 ERROR_SUCCESS || |
1662 key.ReadValue(NULL, &name) != ERROR_SUCCESS || | 1657 key.ReadValue(NULL, &name) != ERROR_SUCCESS || name.empty() || |
1663 name.empty() || | 1658 name.find(install_static::GetBaseAppName()) != base::string16::npos) { |
1664 name.find(dist->GetBaseAppName()) != base::string16::npos) { | |
1665 continue; | 1659 continue; |
1666 } | 1660 } |
1667 // Read the browser's reinstall command. | 1661 // Read the browser's reinstall command. |
1668 if (key.Open(root, (client_path + L"\\InstallInfo").c_str(), | 1662 if (key.Open(root, (client_path + L"\\InstallInfo").c_str(), |
1669 KEY_QUERY_VALUE) == ERROR_SUCCESS && | 1663 KEY_QUERY_VALUE) == ERROR_SUCCESS && |
1670 key.ReadValue(kReinstallCommand, &command) == ERROR_SUCCESS && | 1664 key.ReadValue(kReinstallCommand, &command) == ERROR_SUCCESS && |
1671 !command.empty()) { | 1665 !command.empty()) { |
1672 (*browsers)[name] = command; | 1666 (*browsers)[name] = command; |
1673 } | 1667 } |
1674 } | 1668 } |
1675 } | 1669 } |
1676 } | 1670 } |
1677 | 1671 |
1678 base::string16 ShellUtil::GetCurrentInstallationSuffix( | 1672 base::string16 ShellUtil::GetCurrentInstallationSuffix( |
1679 BrowserDistribution* dist, | |
1680 const base::FilePath& chrome_exe) { | 1673 const base::FilePath& chrome_exe) { |
1681 // This method is somewhat the opposite of GetInstallationSpecificSuffix(). | 1674 // This method is somewhat the opposite of GetInstallationSpecificSuffix(). |
1682 // In this case we are not trying to determine the current suffix for the | 1675 // In this case we are not trying to determine the current suffix for the |
1683 // upcoming installation (i.e. not trying to stick to a currently bad | 1676 // upcoming installation (i.e. not trying to stick to a currently bad |
1684 // registration style if one is present). | 1677 // registration style if one is present). |
1685 // Here we want to determine which suffix we should use at run-time. | 1678 // Here we want to determine which suffix we should use at run-time. |
1686 // In order of preference, we prefer (for user-level installs): | 1679 // In order of preference, we prefer (for user-level installs): |
1687 // 1) Base 32 encoding of the md5 hash of the user's sid (new-style). | 1680 // 1) Base 32 encoding of the md5 hash of the user's sid (new-style). |
1688 // 2) Username (old-style). | 1681 // 2) Username (old-style). |
1689 // 3) Unsuffixed (even worse). | 1682 // 3) Unsuffixed (even worse). |
1690 base::string16 tested_suffix; | 1683 base::string16 tested_suffix; |
1691 if (InstallUtil::IsPerUserInstall() && | 1684 if (InstallUtil::IsPerUserInstall() && |
1692 (!GetUserSpecificRegistrySuffix(&tested_suffix) || | 1685 (!GetUserSpecificRegistrySuffix(&tested_suffix) || |
1693 !QuickIsChromeRegistered(dist, chrome_exe, tested_suffix, | 1686 !QuickIsChromeRegistered(chrome_exe, tested_suffix, |
1694 CONFIRM_PROGID_REGISTRATION)) && | 1687 CONFIRM_PROGID_REGISTRATION)) && |
1695 (!GetOldUserSpecificRegistrySuffix(&tested_suffix) || | 1688 (!GetOldUserSpecificRegistrySuffix(&tested_suffix) || |
1696 !QuickIsChromeRegistered(dist, chrome_exe, tested_suffix, | 1689 !QuickIsChromeRegistered(chrome_exe, tested_suffix, |
1697 CONFIRM_PROGID_REGISTRATION)) && | 1690 CONFIRM_PROGID_REGISTRATION)) && |
1698 !QuickIsChromeRegistered(dist, chrome_exe, tested_suffix.erase(), | 1691 !QuickIsChromeRegistered(chrome_exe, tested_suffix.erase(), |
1699 CONFIRM_PROGID_REGISTRATION)) { | 1692 CONFIRM_PROGID_REGISTRATION)) { |
1700 // If Chrome is not registered under any of the possible suffixes (e.g. | 1693 // If Chrome is not registered under any of the possible suffixes (e.g. |
1701 // tests, Canary, etc.): use the new-style suffix at run-time. | 1694 // tests, Canary, etc.): use the new-style suffix at run-time. |
1702 if (!GetUserSpecificRegistrySuffix(&tested_suffix)) | 1695 if (!GetUserSpecificRegistrySuffix(&tested_suffix)) |
1703 NOTREACHED(); | 1696 NOTREACHED(); |
1704 } | 1697 } |
1705 return tested_suffix; | 1698 return tested_suffix; |
1706 } | 1699 } |
1707 | 1700 |
1708 base::string16 ShellUtil::GetApplicationName(BrowserDistribution* dist, | |
1709 const base::FilePath& chrome_exe) { | |
1710 base::string16 app_name = dist->GetBaseAppName(); | |
1711 app_name += GetCurrentInstallationSuffix(dist, chrome_exe); | |
1712 return app_name; | |
1713 } | |
1714 | |
1715 base::string16 ShellUtil::GetBrowserModelId(bool is_per_user_install) { | 1701 base::string16 ShellUtil::GetBrowserModelId(bool is_per_user_install) { |
1716 base::string16 app_id(install_static::GetBaseAppId()); | 1702 base::string16 app_id(install_static::GetBaseAppId()); |
1717 base::string16 suffix; | 1703 base::string16 suffix; |
1718 | 1704 |
1719 // TODO(robertshield): Temporary hack to make the kRegisterChromeBrowserSuffix | 1705 // TODO(robertshield): Temporary hack to make the kRegisterChromeBrowserSuffix |
1720 // apply to all registry values computed down in these murky depths. | 1706 // apply to all registry values computed down in these murky depths. |
1721 base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess(); | 1707 base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess(); |
1722 if (command_line.HasSwitch( | 1708 if (command_line.HasSwitch( |
1723 installer::switches::kRegisterChromeBrowserSuffix)) { | 1709 installer::switches::kRegisterChromeBrowserSuffix)) { |
1724 suffix = command_line.GetSwitchValueNative( | 1710 suffix = command_line.GetSwitchValueNative( |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1835 if (base::win::GetVersion() >= base::win::VERSION_WIN10) | 1821 if (base::win::GetVersion() >= base::win::VERSION_WIN10) |
1836 return InteractiveSetDefaultMode::SYSTEM_SETTINGS; | 1822 return InteractiveSetDefaultMode::SYSTEM_SETTINGS; |
1837 | 1823 |
1838 return InteractiveSetDefaultMode::INTENT_PICKER; | 1824 return InteractiveSetDefaultMode::INTENT_PICKER; |
1839 } | 1825 } |
1840 | 1826 |
1841 bool ShellUtil::MakeChromeDefault(BrowserDistribution* dist, | 1827 bool ShellUtil::MakeChromeDefault(BrowserDistribution* dist, |
1842 int shell_change, | 1828 int shell_change, |
1843 const base::FilePath& chrome_exe, | 1829 const base::FilePath& chrome_exe, |
1844 bool elevate_if_not_admin) { | 1830 bool elevate_if_not_admin) { |
1845 DCHECK(!(shell_change & SYSTEM_LEVEL) || IsUserAnAdmin()); | |
1846 | |
1847 // Assert that this is only called with the one relevant distribution. | 1831 // Assert that this is only called with the one relevant distribution. |
1848 // TODO(grt): Remove this when BrowserDistribution goes away. | 1832 // TODO(grt): Remove this when BrowserDistribution goes away. |
1849 DCHECK_EQ(BrowserDistribution::GetDistribution(), dist); | 1833 DCHECK_EQ(BrowserDistribution::GetDistribution(), dist); |
| 1834 DCHECK(!(shell_change & SYSTEM_LEVEL) || IsUserAnAdmin()); |
| 1835 |
1850 if (!install_static::SupportsSetAsDefaultBrowser()) | 1836 if (!install_static::SupportsSetAsDefaultBrowser()) |
1851 return false; | 1837 return false; |
1852 | 1838 |
1853 // Windows 8 does not permit making a browser default just like that. | 1839 // Windows 8 does not permit making a browser default just like that. |
1854 // This process needs to be routed through the system's UI. Use | 1840 // This process needs to be routed through the system's UI. Use |
1855 // ShowMakeChromeDefaultSystemUI instead (below). | 1841 // ShowMakeChromeDefaultSystemUI instead (below). |
1856 if (!CanMakeChromeDefaultUnattended()) { | 1842 if (!CanMakeChromeDefaultUnattended()) { |
1857 return false; | 1843 return false; |
1858 } | 1844 } |
1859 | 1845 |
1860 if (!RegisterChromeBrowser( | 1846 if (!RegisterChromeBrowser( |
1861 dist, chrome_exe, base::string16(), elevate_if_not_admin)) { | 1847 dist, chrome_exe, base::string16(), elevate_if_not_admin)) { |
1862 return false; | 1848 return false; |
1863 } | 1849 } |
1864 | 1850 |
1865 bool ret = true; | 1851 bool ret = true; |
1866 // First use the new "recommended" way on Vista to make Chrome default | 1852 // First use the new "recommended" way on Vista to make Chrome default |
1867 // browser. | 1853 // browser. |
1868 base::string16 app_name = GetApplicationName(dist, chrome_exe); | 1854 base::string16 app_name = GetApplicationName(chrome_exe); |
1869 | 1855 |
1870 if (base::win::GetVersion() >= base::win::VERSION_VISTA) { | 1856 if (base::win::GetVersion() >= base::win::VERSION_VISTA) { |
1871 // On Windows Vista and Win7 we still can set ourselves via the | 1857 // On Windows Vista and Win7 we still can set ourselves via the |
1872 // the IApplicationAssociationRegistration interface. | 1858 // the IApplicationAssociationRegistration interface. |
1873 VLOG(1) << "Registering Chrome as default browser on Vista."; | 1859 VLOG(1) << "Registering Chrome as default browser on Vista."; |
1874 base::win::ScopedComPtr<IApplicationAssociationRegistration> pAAR; | 1860 base::win::ScopedComPtr<IApplicationAssociationRegistration> pAAR; |
1875 HRESULT hr = pAAR.CreateInstance(CLSID_ApplicationAssociationRegistration, | 1861 HRESULT hr = pAAR.CreateInstance(CLSID_ApplicationAssociationRegistration, |
1876 NULL, CLSCTX_INPROC); | 1862 NULL, CLSCTX_INPROC); |
1877 if (SUCCEEDED(hr)) { | 1863 if (SUCCEEDED(hr)) { |
1878 for (int i = 0; kBrowserProtocolAssociations[i] != NULL; i++) { | 1864 for (int i = 0; kBrowserProtocolAssociations[i] != NULL; i++) { |
(...skipping 13 matching lines...) Expand all Loading... |
1892 if (!SUCCEEDED(hr)) { | 1878 if (!SUCCEEDED(hr)) { |
1893 ret = false; | 1879 ret = false; |
1894 LOG(ERROR) << "Failed to register as default for file extension " | 1880 LOG(ERROR) << "Failed to register as default for file extension " |
1895 << kDefaultFileAssociations[i] | 1881 << kDefaultFileAssociations[i] |
1896 << " (" << hr << ")"; | 1882 << " (" << hr << ")"; |
1897 } | 1883 } |
1898 } | 1884 } |
1899 } | 1885 } |
1900 } | 1886 } |
1901 | 1887 |
1902 if (!RegisterChromeAsDefaultXPStyle(dist, shell_change, chrome_exe)) | 1888 if (!RegisterChromeAsDefaultXPStyle(shell_change, chrome_exe)) |
1903 ret = false; | 1889 ret = false; |
1904 | 1890 |
1905 // Send Windows notification event so that it can update icons for | 1891 // Send Windows notification event so that it can update icons for |
1906 // file associations. | 1892 // file associations. |
1907 SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL); | 1893 SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL); |
1908 return ret; | 1894 return ret; |
1909 } | 1895 } |
1910 | 1896 |
1911 bool ShellUtil::ShowMakeChromeDefaultSystemUI( | 1897 bool ShellUtil::ShowMakeChromeDefaultSystemUI( |
1912 BrowserDistribution* dist, | 1898 BrowserDistribution* dist, |
1913 const base::FilePath& chrome_exe) { | 1899 const base::FilePath& chrome_exe) { |
1914 DCHECK(!CanMakeChromeDefaultUnattended()); | |
1915 | |
1916 // Assert that this is only called with the one relevant distribution. | 1900 // Assert that this is only called with the one relevant distribution. |
1917 // TODO(grt): Remove this when BrowserDistribution goes away. | 1901 // TODO(grt): Remove this when BrowserDistribution goes away. |
1918 DCHECK_EQ(BrowserDistribution::GetDistribution(), dist); | 1902 DCHECK_EQ(BrowserDistribution::GetDistribution(), dist); |
| 1903 DCHECK(!CanMakeChromeDefaultUnattended()); |
| 1904 |
1919 if (!install_static::SupportsSetAsDefaultBrowser()) | 1905 if (!install_static::SupportsSetAsDefaultBrowser()) |
1920 return false; | 1906 return false; |
1921 | 1907 |
1922 if (!RegisterChromeBrowser(dist, chrome_exe, base::string16(), true)) | 1908 if (!RegisterChromeBrowser(dist, chrome_exe, base::string16(), true)) |
1923 return false; | 1909 return false; |
1924 | 1910 |
1925 bool succeeded = true; | 1911 bool succeeded = true; |
1926 bool is_default = (GetChromeDefaultState() == IS_DEFAULT); | 1912 bool is_default = (GetChromeDefaultState() == IS_DEFAULT); |
1927 if (!is_default) { | 1913 if (!is_default) { |
1928 switch (GetInteractiveSetDefaultMode()) { | 1914 switch (GetInteractiveSetDefaultMode()) { |
(...skipping 12 matching lines...) Expand all Loading... |
1941 // So we launch the settings dialog. Quoting from MSDN: "The Open With | 1927 // So we launch the settings dialog. Quoting from MSDN: "The Open With |
1942 // dialog box can no longer be used to change the default program used | 1928 // dialog box can no longer be used to change the default program used |
1943 // to open a file extension. You can only use SHOpenWithDialog to open | 1929 // to open a file extension. You can only use SHOpenWithDialog to open |
1944 // a single file." | 1930 // a single file." |
1945 succeeded = LaunchDefaultAppsSettingsModernDialog(L"http"); | 1931 succeeded = LaunchDefaultAppsSettingsModernDialog(L"http"); |
1946 break; | 1932 break; |
1947 } | 1933 } |
1948 is_default = (succeeded && GetChromeDefaultState() == IS_DEFAULT); | 1934 is_default = (succeeded && GetChromeDefaultState() == IS_DEFAULT); |
1949 } | 1935 } |
1950 if (succeeded && is_default) | 1936 if (succeeded && is_default) |
1951 RegisterChromeAsDefaultXPStyle(dist, CURRENT_USER, chrome_exe); | 1937 RegisterChromeAsDefaultXPStyle(CURRENT_USER, chrome_exe); |
1952 return succeeded; | 1938 return succeeded; |
1953 } | 1939 } |
1954 | 1940 |
1955 bool ShellUtil::MakeChromeDefaultProtocolClient( | 1941 bool ShellUtil::MakeChromeDefaultProtocolClient( |
1956 BrowserDistribution* dist, | 1942 BrowserDistribution* dist, |
1957 const base::FilePath& chrome_exe, | 1943 const base::FilePath& chrome_exe, |
1958 const base::string16& protocol) { | 1944 const base::string16& protocol) { |
1959 // Assert that this is only called with the one relevant distribution. | 1945 // Assert that this is only called with the one relevant distribution. |
1960 // TODO(grt): Remove this when BrowserDistribution goes away. | 1946 // TODO(grt): Remove this when BrowserDistribution goes away. |
1961 DCHECK_EQ(BrowserDistribution::GetDistribution(), dist); | 1947 DCHECK_EQ(BrowserDistribution::GetDistribution(), dist); |
(...skipping 13 matching lines...) Expand all Loading... |
1975 bool ret = true; | 1961 bool ret = true; |
1976 // First use the new "recommended" way on Vista to make Chrome default | 1962 // First use the new "recommended" way on Vista to make Chrome default |
1977 // protocol handler. | 1963 // protocol handler. |
1978 if (base::win::GetVersion() >= base::win::VERSION_VISTA) { | 1964 if (base::win::GetVersion() >= base::win::VERSION_VISTA) { |
1979 VLOG(1) << "Registering Chrome as default handler for " << protocol | 1965 VLOG(1) << "Registering Chrome as default handler for " << protocol |
1980 << " on Vista."; | 1966 << " on Vista."; |
1981 base::win::ScopedComPtr<IApplicationAssociationRegistration> pAAR; | 1967 base::win::ScopedComPtr<IApplicationAssociationRegistration> pAAR; |
1982 HRESULT hr = pAAR.CreateInstance(CLSID_ApplicationAssociationRegistration, | 1968 HRESULT hr = pAAR.CreateInstance(CLSID_ApplicationAssociationRegistration, |
1983 NULL, CLSCTX_INPROC); | 1969 NULL, CLSCTX_INPROC); |
1984 if (SUCCEEDED(hr)) { | 1970 if (SUCCEEDED(hr)) { |
1985 base::string16 app_name = GetApplicationName(dist, chrome_exe); | 1971 base::string16 app_name = GetApplicationName(chrome_exe); |
1986 hr = pAAR->SetAppAsDefault(app_name.c_str(), protocol.c_str(), | 1972 hr = pAAR->SetAppAsDefault(app_name.c_str(), protocol.c_str(), |
1987 AT_URLPROTOCOL); | 1973 AT_URLPROTOCOL); |
1988 } | 1974 } |
1989 if (!SUCCEEDED(hr)) { | 1975 if (!SUCCEEDED(hr)) { |
1990 ret = false; | 1976 ret = false; |
1991 LOG(ERROR) << "Could not make Chrome default protocol client (Vista):" | 1977 LOG(ERROR) << "Could not make Chrome default protocol client (Vista):" |
1992 << " HRESULT=" << hr << "."; | 1978 << " HRESULT=" << hr << "."; |
1993 } | 1979 } |
1994 } | 1980 } |
1995 | 1981 |
1996 // Now use the old way to associate Chrome with the desired protocol. This | 1982 // Now use the old way to associate Chrome with the desired protocol. This |
1997 // should not be required on Vista+, but since some applications still read | 1983 // should not be required on Vista+, but since some applications still read |
1998 // Software\Classes\<protocol> key directly, do this on Vista+ also. | 1984 // Software\Classes\<protocol> key directly, do this on Vista+ also. |
1999 if (!RegisterChromeAsDefaultProtocolClientXPStyle(dist, chrome_exe, protocol)) | 1985 if (!RegisterChromeAsDefaultProtocolClientXPStyle(chrome_exe, protocol)) |
2000 ret = false; | 1986 ret = false; |
2001 | 1987 |
2002 return ret; | 1988 return ret; |
2003 } | 1989 } |
2004 | 1990 |
2005 bool ShellUtil::ShowMakeChromeDefaultProtocolClientSystemUI( | 1991 bool ShellUtil::ShowMakeChromeDefaultProtocolClientSystemUI( |
2006 BrowserDistribution* dist, | 1992 BrowserDistribution* dist, |
2007 const base::FilePath& chrome_exe, | 1993 const base::FilePath& chrome_exe, |
2008 const base::string16& protocol) { | 1994 const base::string16& protocol) { |
2009 DCHECK(!CanMakeChromeDefaultUnattended()); | |
2010 | |
2011 // Assert that this is only called with the one relevant distribution. | 1995 // Assert that this is only called with the one relevant distribution. |
2012 // TODO(grt): Remove this when BrowserDistribution goes away. | 1996 // TODO(grt): Remove this when BrowserDistribution goes away. |
2013 DCHECK_EQ(BrowserDistribution::GetDistribution(), dist); | 1997 DCHECK_EQ(BrowserDistribution::GetDistribution(), dist); |
| 1998 DCHECK(!CanMakeChromeDefaultUnattended()); |
| 1999 |
2014 if (!install_static::SupportsSetAsDefaultBrowser()) | 2000 if (!install_static::SupportsSetAsDefaultBrowser()) |
2015 return false; | 2001 return false; |
2016 | 2002 |
2017 if (!RegisterChromeForProtocol( | 2003 if (!RegisterChromeForProtocol( |
2018 dist, chrome_exe, base::string16(), protocol, true)) | 2004 dist, chrome_exe, base::string16(), protocol, true)) |
2019 return false; | 2005 return false; |
2020 | 2006 |
2021 bool succeeded = true; | 2007 bool succeeded = true; |
2022 bool is_default = ( | 2008 bool is_default = ( |
2023 GetChromeDefaultProtocolClientState(protocol) == IS_DEFAULT); | 2009 GetChromeDefaultProtocolClientState(protocol) == IS_DEFAULT); |
(...skipping 13 matching lines...) Expand all Loading... |
2037 case SYSTEM_SETTINGS: | 2023 case SYSTEM_SETTINGS: |
2038 // On Windows 10, you can't even launch the associations dialog. | 2024 // On Windows 10, you can't even launch the associations dialog. |
2039 // So we launch the settings dialog. | 2025 // So we launch the settings dialog. |
2040 succeeded = LaunchDefaultAppsSettingsModernDialog(protocol.c_str()); | 2026 succeeded = LaunchDefaultAppsSettingsModernDialog(protocol.c_str()); |
2041 break; | 2027 break; |
2042 } | 2028 } |
2043 is_default = (succeeded && | 2029 is_default = (succeeded && |
2044 GetChromeDefaultProtocolClientState(protocol) == IS_DEFAULT); | 2030 GetChromeDefaultProtocolClientState(protocol) == IS_DEFAULT); |
2045 } | 2031 } |
2046 if (succeeded && is_default) | 2032 if (succeeded && is_default) |
2047 RegisterChromeAsDefaultProtocolClientXPStyle(dist, chrome_exe, protocol); | 2033 RegisterChromeAsDefaultProtocolClientXPStyle(chrome_exe, protocol); |
2048 return succeeded; | 2034 return succeeded; |
2049 } | 2035 } |
2050 | 2036 |
2051 bool ShellUtil::RegisterChromeBrowser(BrowserDistribution* dist, | 2037 bool ShellUtil::RegisterChromeBrowser(BrowserDistribution* dist, |
2052 const base::FilePath& chrome_exe, | 2038 const base::FilePath& chrome_exe, |
2053 const base::string16& unique_suffix, | 2039 const base::string16& unique_suffix, |
2054 bool elevate_if_not_admin) { | 2040 bool elevate_if_not_admin) { |
| 2041 // Assert that this is only called with the one relevant distribution. |
| 2042 // TODO(grt): Remove this when BrowserDistribution goes away. |
2055 DCHECK_EQ(BrowserDistribution::GetDistribution(), dist); | 2043 DCHECK_EQ(BrowserDistribution::GetDistribution(), dist); |
2056 base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess(); | 2044 base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess(); |
2057 | 2045 |
2058 base::string16 suffix; | 2046 base::string16 suffix; |
2059 if (!unique_suffix.empty()) { | 2047 if (!unique_suffix.empty()) { |
2060 suffix = unique_suffix; | 2048 suffix = unique_suffix; |
2061 } else if (command_line.HasSwitch( | 2049 } else if (command_line.HasSwitch( |
2062 installer::switches::kRegisterChromeBrowserSuffix)) { | 2050 installer::switches::kRegisterChromeBrowserSuffix)) { |
2063 suffix = command_line.GetSwitchValueNative( | 2051 suffix = command_line.GetSwitchValueNative( |
2064 installer::switches::kRegisterChromeBrowserSuffix); | 2052 installer::switches::kRegisterChromeBrowserSuffix); |
2065 } else if (!GetInstallationSpecificSuffix(dist, chrome_exe, &suffix)) { | 2053 } else if (!GetInstallationSpecificSuffix(chrome_exe, &suffix)) { |
2066 return false; | 2054 return false; |
2067 } | 2055 } |
2068 | 2056 |
2069 RemoveRunVerbOnWindows8(); | 2057 RemoveRunVerbOnWindows8(); |
2070 | 2058 |
2071 bool user_level = InstallUtil::IsPerUserInstall(); | 2059 bool user_level = InstallUtil::IsPerUserInstall(); |
2072 HKEY root = DetermineRegistrationRoot(user_level); | 2060 HKEY root = DetermineRegistrationRoot(user_level); |
2073 | 2061 |
2074 // Look only in HKLM for system-level installs (otherwise, if a user-level | 2062 // Look only in HKLM for system-level installs (otherwise, if a user-level |
2075 // install is also present, it will lead IsChromeRegistered() to think this | 2063 // install is also present, it will lead IsChromeRegistered() to think this |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2131 } | 2119 } |
2132 SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL); | 2120 SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL); |
2133 return result; | 2121 return result; |
2134 } | 2122 } |
2135 | 2123 |
2136 bool ShellUtil::RegisterChromeForProtocol(BrowserDistribution* dist, | 2124 bool ShellUtil::RegisterChromeForProtocol(BrowserDistribution* dist, |
2137 const base::FilePath& chrome_exe, | 2125 const base::FilePath& chrome_exe, |
2138 const base::string16& unique_suffix, | 2126 const base::string16& unique_suffix, |
2139 const base::string16& protocol, | 2127 const base::string16& protocol, |
2140 bool elevate_if_not_admin) { | 2128 bool elevate_if_not_admin) { |
| 2129 // Assert that this is only called with the one relevant distribution. |
| 2130 // TODO(grt): Remove this when BrowserDistribution goes away. |
| 2131 DCHECK_EQ(BrowserDistribution::GetDistribution(), dist); |
2141 base::string16 suffix; | 2132 base::string16 suffix; |
2142 if (!unique_suffix.empty()) { | 2133 if (!unique_suffix.empty()) { |
2143 suffix = unique_suffix; | 2134 suffix = unique_suffix; |
2144 } else if (!GetInstallationSpecificSuffix(dist, chrome_exe, &suffix)) { | 2135 } else if (!GetInstallationSpecificSuffix(chrome_exe, &suffix)) { |
2145 return false; | 2136 return false; |
2146 } | 2137 } |
2147 | 2138 |
2148 bool user_level = InstallUtil::IsPerUserInstall(); | 2139 bool user_level = InstallUtil::IsPerUserInstall(); |
2149 HKEY root = DetermineRegistrationRoot(user_level); | 2140 HKEY root = DetermineRegistrationRoot(user_level); |
2150 | 2141 |
2151 // Look only in HKLM for system-level installs (otherwise, if a user-level | 2142 // Look only in HKLM for system-level installs (otherwise, if a user-level |
2152 // install is also present, it could lead IsChromeRegisteredForProtocol() to | 2143 // install is also present, it could lead IsChromeRegisteredForProtocol() to |
2153 // think this system-level install isn't registered properly as it may be | 2144 // think this system-level install isn't registered properly as it may be |
2154 // shadowed by the user-level install's registrations). | 2145 // shadowed by the user-level install's registrations). |
2155 uint32_t look_for_in = user_level ? RegistryEntry::LOOK_IN_HKCU_THEN_HKLM | 2146 uint32_t look_for_in = user_level ? RegistryEntry::LOOK_IN_HKCU_THEN_HKLM |
2156 : RegistryEntry::LOOK_IN_HKLM; | 2147 : RegistryEntry::LOOK_IN_HKLM; |
2157 | 2148 |
2158 // Check if chrome is already registered with this suffix. | 2149 // Check if chrome is already registered with this suffix. |
2159 if (IsChromeRegisteredForProtocol(dist, suffix, protocol, look_for_in)) | 2150 if (IsChromeRegisteredForProtocol(suffix, protocol, look_for_in)) |
2160 return true; | 2151 return true; |
2161 | 2152 |
2162 if (root == HKEY_CURRENT_USER || IsUserAnAdmin()) { | 2153 if (root == HKEY_CURRENT_USER || IsUserAnAdmin()) { |
2163 // We can do this operation directly. | 2154 // We can do this operation directly. |
2164 // First, make sure Chrome is fully registered on this machine. | 2155 // First, make sure Chrome is fully registered on this machine. |
2165 if (!RegisterChromeBrowser(dist, chrome_exe, suffix, false)) | 2156 if (!RegisterChromeBrowser(dist, chrome_exe, suffix, false)) |
2166 return false; | 2157 return false; |
2167 | 2158 |
2168 // Write in the capabillity for the protocol. | 2159 // Write in the capabillity for the protocol. |
2169 ScopedVector<RegistryEntry> entries; | 2160 ScopedVector<RegistryEntry> entries; |
2170 GetProtocolCapabilityEntries(dist, suffix, protocol, &entries); | 2161 GetProtocolCapabilityEntries(suffix, protocol, &entries); |
2171 return AddRegistryEntries(root, entries); | 2162 return AddRegistryEntries(root, entries); |
2172 } else if (elevate_if_not_admin && | 2163 } else if (elevate_if_not_admin && |
2173 base::win::GetVersion() >= base::win::VERSION_VISTA) { | 2164 base::win::GetVersion() >= base::win::VERSION_VISTA) { |
2174 // Elevate to do the whole job | 2165 // Elevate to do the whole job |
2175 return ElevateAndRegisterChrome(dist, chrome_exe, suffix, protocol); | 2166 return ElevateAndRegisterChrome(dist, chrome_exe, suffix, protocol); |
2176 } else { | 2167 } else { |
2177 // Admin rights are required to register capabilities before Windows 8. | 2168 // Admin rights are required to register capabilities before Windows 8. |
2178 return false; | 2169 return false; |
2179 } | 2170 } |
2180 } | 2171 } |
2181 | 2172 |
2182 // static | 2173 // static |
2183 bool ShellUtil::RemoveShortcuts(ShortcutLocation location, | 2174 bool ShellUtil::RemoveShortcuts(ShortcutLocation location, |
2184 BrowserDistribution* dist, | 2175 BrowserDistribution* dist, |
2185 ShellChange level, | 2176 ShellChange level, |
2186 const base::FilePath& target_exe) { | 2177 const base::FilePath& target_exe) { |
| 2178 // Assert that this is only called with the one relevant distribution. |
| 2179 // TODO(grt): Remove this when BrowserDistribution goes away. |
| 2180 DCHECK_EQ(BrowserDistribution::GetDistribution(), dist); |
2187 if (!ShortcutLocationIsSupported(location)) | 2181 if (!ShortcutLocationIsSupported(location)) |
2188 return true; // Vacuous success. | 2182 return true; // Vacuous success. |
2189 | 2183 |
2190 FilterTargetEq shortcut_filter(target_exe, false); | 2184 FilterTargetEq shortcut_filter(target_exe, false); |
2191 // Main operation to apply to each shortcut in the directory specified. | 2185 // Main operation to apply to each shortcut in the directory specified. |
2192 ShortcutOperationCallback shortcut_operation( | 2186 ShortcutOperationCallback shortcut_operation( |
2193 location == SHORTCUT_LOCATION_TASKBAR_PINS | 2187 location == SHORTCUT_LOCATION_TASKBAR_PINS |
2194 ? base::Bind(&ShortcutOpUnpinFromTaskbar) | 2188 ? base::Bind(&ShortcutOpUnpinFromTaskbar) |
2195 : base::Bind(&ShortcutOpDelete)); | 2189 : base::Bind(&ShortcutOpDelete)); |
2196 bool success = BatchShortcutAction(shortcut_filter.AsShortcutFilterCallback(), | 2190 bool success = BatchShortcutAction(shortcut_filter.AsShortcutFilterCallback(), |
2197 shortcut_operation, location, dist, level, | 2191 shortcut_operation, location, dist, level, |
2198 NULL); | 2192 NULL); |
2199 // Remove chrome-specific shortcut folders if they are now empty. | 2193 // Remove chrome-specific shortcut folders if they are now empty. |
2200 if (success && | 2194 if (success && |
2201 (location == SHORTCUT_LOCATION_START_MENU_CHROME_DIR_DEPRECATED || | 2195 (location == SHORTCUT_LOCATION_START_MENU_CHROME_DIR_DEPRECATED || |
2202 location == SHORTCUT_LOCATION_START_MENU_CHROME_APPS_DIR || | 2196 location == SHORTCUT_LOCATION_START_MENU_CHROME_APPS_DIR || |
2203 location == SHORTCUT_LOCATION_APP_SHORTCUTS)) { | 2197 location == SHORTCUT_LOCATION_APP_SHORTCUTS)) { |
2204 success = RemoveShortcutFolderIfEmpty(location, dist, level); | 2198 success = RemoveShortcutFolderIfEmpty(location, dist, level); |
2205 } | 2199 } |
2206 return success; | 2200 return success; |
2207 } | 2201 } |
2208 | 2202 |
2209 // static | 2203 // static |
2210 bool ShellUtil::RetargetShortcutsWithArgs( | 2204 bool ShellUtil::RetargetShortcutsWithArgs( |
2211 ShortcutLocation location, | 2205 ShortcutLocation location, |
2212 BrowserDistribution* dist, | 2206 BrowserDistribution* dist, |
2213 ShellChange level, | 2207 ShellChange level, |
2214 const base::FilePath& old_target_exe, | 2208 const base::FilePath& old_target_exe, |
2215 const base::FilePath& new_target_exe) { | 2209 const base::FilePath& new_target_exe) { |
| 2210 // Assert that this is only called with the one relevant distribution. |
| 2211 // TODO(grt): Remove this when BrowserDistribution goes away. |
| 2212 DCHECK_EQ(BrowserDistribution::GetDistribution(), dist); |
2216 if (!ShortcutLocationIsSupported(location)) | 2213 if (!ShortcutLocationIsSupported(location)) |
2217 return true; // Vacuous success. | 2214 return true; // Vacuous success. |
2218 | 2215 |
2219 FilterTargetEq shortcut_filter(old_target_exe, true); | 2216 FilterTargetEq shortcut_filter(old_target_exe, true); |
2220 ShortcutOperationCallback shortcut_operation( | 2217 ShortcutOperationCallback shortcut_operation( |
2221 base::Bind(&ShortcutOpRetarget, old_target_exe, new_target_exe)); | 2218 base::Bind(&ShortcutOpRetarget, old_target_exe, new_target_exe)); |
2222 return BatchShortcutAction(shortcut_filter.AsShortcutFilterCallback(), | 2219 return BatchShortcutAction(shortcut_filter.AsShortcutFilterCallback(), |
2223 shortcut_operation, location, dist, level, NULL); | 2220 shortcut_operation, location, dist, level, NULL); |
2224 } | 2221 } |
2225 | 2222 |
2226 // static | 2223 // static |
2227 bool ShellUtil::ShortcutListMaybeRemoveUnknownArgs( | 2224 bool ShellUtil::ShortcutListMaybeRemoveUnknownArgs( |
2228 ShortcutLocation location, | 2225 ShortcutLocation location, |
2229 BrowserDistribution* dist, | 2226 BrowserDistribution* dist, |
2230 ShellChange level, | 2227 ShellChange level, |
2231 const base::FilePath& chrome_exe, | 2228 const base::FilePath& chrome_exe, |
2232 bool do_removal, | 2229 bool do_removal, |
2233 const scoped_refptr<SharedCancellationFlag>& cancel, | 2230 const scoped_refptr<SharedCancellationFlag>& cancel, |
2234 std::vector<std::pair<base::FilePath, base::string16> >* shortcuts) { | 2231 std::vector<std::pair<base::FilePath, base::string16> >* shortcuts) { |
| 2232 // Assert that this is only called with the one relevant distribution. |
| 2233 // TODO(grt): Remove this when BrowserDistribution goes away. |
| 2234 DCHECK_EQ(BrowserDistribution::GetDistribution(), dist); |
2235 if (!ShortcutLocationIsSupported(location)) | 2235 if (!ShortcutLocationIsSupported(location)) |
2236 return false; | 2236 return false; |
2237 DCHECK(dist); | 2237 DCHECK(dist); |
2238 FilterTargetEq shortcut_filter(chrome_exe, true); | 2238 FilterTargetEq shortcut_filter(chrome_exe, true); |
2239 ShortcutOperationCallback shortcut_operation( | 2239 ShortcutOperationCallback shortcut_operation( |
2240 base::Bind(&ShortcutOpListOrRemoveUnknownArgs, do_removal, shortcuts)); | 2240 base::Bind(&ShortcutOpListOrRemoveUnknownArgs, do_removal, shortcuts)); |
2241 return BatchShortcutAction(shortcut_filter.AsShortcutFilterCallback(), | 2241 return BatchShortcutAction(shortcut_filter.AsShortcutFilterCallback(), |
2242 shortcut_operation, location, dist, level, cancel); | 2242 shortcut_operation, location, dist, level, cancel); |
2243 } | 2243 } |
2244 | 2244 |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2325 itr != entries.end(); ++itr) | 2325 itr != entries.end(); ++itr) |
2326 (*itr)->AddToWorkItemList(root, items.get()); | 2326 (*itr)->AddToWorkItemList(root, items.get()); |
2327 | 2327 |
2328 // Apply all the registry changes and if there is a problem, rollback | 2328 // Apply all the registry changes and if there is a problem, rollback |
2329 if (!items->Do()) { | 2329 if (!items->Do()) { |
2330 items->Rollback(); | 2330 items->Rollback(); |
2331 return false; | 2331 return false; |
2332 } | 2332 } |
2333 return true; | 2333 return true; |
2334 } | 2334 } |
OLD | NEW |