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 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
418 string16 key(ShellUtil::kRegClasses); | 418 string16 key(ShellUtil::kRegClasses); |
419 key.push_back(FilePath::kSeparators[0]); | 419 key.push_back(FilePath::kSeparators[0]); |
420 key.append(ShellUtil::kFileAssociations[i]); | 420 key.append(ShellUtil::kFileAssociations[i]); |
421 key.push_back(FilePath::kSeparators[0]); | 421 key.push_back(FilePath::kSeparators[0]); |
422 key.append(ShellUtil::kRegOpenWithProgids); | 422 key.append(ShellUtil::kRegOpenWithProgids); |
423 entries->push_back(new RegistryEntry(key, html_prog_id, string16())); | 423 entries->push_back(new RegistryEntry(key, html_prog_id, string16())); |
424 } | 424 } |
425 } | 425 } |
426 | 426 |
427 // This method returns a list of all the user level registry entries that | 427 // This method returns a list of all the user level registry entries that |
428 // are needed to make Chromium the default handler for a protocol. | 428 // are needed to make Chromium the default handler for a protocol on XP. |
429 static void GetUserProtocolEntries(const string16& protocol, | 429 static void GetUserProtocolEntriesForXP( |
grt (UTC plus 2)
2012/10/06 01:16:24
in general, i really like this change. the name g
gab
2012/10/09 14:14:52
Right, I was going to go with "XPStyle" instead of
| |
430 const string16& chrome_icon, | 430 const string16& protocol, |
431 const string16& chrome_open, | 431 const string16& chrome_icon, |
432 ScopedVector<RegistryEntry>* entries) { | 432 const string16& chrome_open, |
433 ScopedVector<RegistryEntry>* entries) { | |
433 // Protocols associations. | 434 // Protocols associations. |
434 string16 url_key(ShellUtil::kRegClasses); | 435 string16 url_key(ShellUtil::kRegClasses); |
435 url_key.push_back(FilePath::kSeparators[0]); | 436 url_key.push_back(FilePath::kSeparators[0]); |
436 url_key.append(protocol); | 437 url_key.append(protocol); |
437 | 438 |
438 // This registry value tells Windows that this 'class' is a URL scheme | 439 // This registry value tells Windows that this 'class' is a URL scheme |
439 // so IE, explorer and other apps will route it to our handler. | 440 // so IE, explorer and other apps will route it to our handler. |
440 // <root hkey>\Software\Classes\<protocol>\URL Protocol | 441 // <root hkey>\Software\Classes\<protocol>\URL Protocol |
441 entries->push_back(new RegistryEntry(url_key, | 442 entries->push_back(new RegistryEntry(url_key, |
442 ShellUtil::kRegUrlProtocol, L"")); | 443 ShellUtil::kRegUrlProtocol, L"")); |
443 | 444 |
444 // <root hkey>\Software\Classes\<protocol>\DefaultIcon | 445 // <root hkey>\Software\Classes\<protocol>\DefaultIcon |
445 string16 icon_key = url_key + ShellUtil::kRegDefaultIcon; | 446 string16 icon_key = url_key + ShellUtil::kRegDefaultIcon; |
446 entries->push_back(new RegistryEntry(icon_key, chrome_icon)); | 447 entries->push_back(new RegistryEntry(icon_key, chrome_icon)); |
447 | 448 |
448 // <root hkey>\Software\Classes\<protocol>\shell\open\command | 449 // <root hkey>\Software\Classes\<protocol>\shell\open\command |
449 string16 shell_key = url_key + ShellUtil::kRegShellOpen; | 450 string16 shell_key = url_key + ShellUtil::kRegShellOpen; |
450 entries->push_back(new RegistryEntry(shell_key, chrome_open)); | 451 entries->push_back(new RegistryEntry(shell_key, chrome_open)); |
451 | 452 |
452 // <root hkey>\Software\Classes\<protocol>\shell\open\ddeexec | 453 // <root hkey>\Software\Classes\<protocol>\shell\open\ddeexec |
453 string16 dde_key = url_key + L"\\shell\\open\\ddeexec"; | 454 string16 dde_key = url_key + L"\\shell\\open\\ddeexec"; |
454 entries->push_back(new RegistryEntry(dde_key, L"")); | 455 entries->push_back(new RegistryEntry(dde_key, L"")); |
455 | 456 |
456 // <root hkey>\Software\Classes\<protocol>\shell\@ | 457 // <root hkey>\Software\Classes\<protocol>\shell\@ |
457 string16 protocol_shell_key = url_key + ShellUtil::kRegShellPath; | 458 string16 protocol_shell_key = url_key + ShellUtil::kRegShellPath; |
458 entries->push_back(new RegistryEntry(protocol_shell_key, L"open")); | 459 entries->push_back(new RegistryEntry(protocol_shell_key, L"open")); |
459 } | 460 } |
460 | 461 |
461 // This method returns a list of all the user level registry entries that | 462 // This method returns a list of all the user level registry entries that |
462 // are needed to make Chromium default browser. | 463 // are needed to make Chromium default browser on XP. |
463 // Some of these entries are irrelevant in recent versions of Windows, but | 464 // Some of these entries are irrelevant in recent versions of Windows, but |
464 // we register them anyways as some legacy apps are hardcoded to lookup those | 465 // we register them anyways as some legacy apps are hardcoded to lookup those |
465 // values. | 466 // values. |
466 static void GetDefaultBrowserUserEntries( | 467 static void GetDefaultBrowserUserEntriesForXP( |
467 BrowserDistribution* dist, | 468 BrowserDistribution* dist, |
468 const string16& chrome_exe, | 469 const string16& chrome_exe, |
469 const string16& suffix, | 470 const string16& suffix, |
470 ScopedVector<RegistryEntry>* entries) { | 471 ScopedVector<RegistryEntry>* entries) { |
471 // File extension associations. | 472 // File extension associations. |
472 string16 html_prog_id(GetBrowserProgId(suffix)); | 473 string16 html_prog_id(GetBrowserProgId(suffix)); |
473 for (int i = 0; ShellUtil::kFileAssociations[i] != NULL; i++) { | 474 for (int i = 0; ShellUtil::kFileAssociations[i] != NULL; i++) { |
474 string16 ext_key(ShellUtil::kRegClasses); | 475 string16 ext_key(ShellUtil::kRegClasses); |
475 ext_key.push_back(FilePath::kSeparators[0]); | 476 ext_key.push_back(FilePath::kSeparators[0]); |
476 ext_key.append(ShellUtil::kFileAssociations[i]); | 477 ext_key.append(ShellUtil::kFileAssociations[i]); |
477 entries->push_back(new RegistryEntry(ext_key, html_prog_id)); | 478 entries->push_back(new RegistryEntry(ext_key, html_prog_id)); |
478 } | 479 } |
479 | 480 |
480 // Protocols associations. | 481 // Protocols associations. |
481 string16 chrome_open = ShellUtil::GetChromeShellOpenCmd(chrome_exe); | 482 string16 chrome_open = ShellUtil::GetChromeShellOpenCmd(chrome_exe); |
482 string16 chrome_icon = ShellUtil::GetChromeIcon(dist, chrome_exe); | 483 string16 chrome_icon = ShellUtil::GetChromeIcon(dist, chrome_exe); |
483 for (int i = 0; ShellUtil::kBrowserProtocolAssociations[i] != NULL; i++) { | 484 for (int i = 0; ShellUtil::kBrowserProtocolAssociations[i] != NULL; i++) { |
484 GetUserProtocolEntries(ShellUtil::kBrowserProtocolAssociations[i], | 485 GetUserProtocolEntriesForXP(ShellUtil::kBrowserProtocolAssociations[i], |
485 chrome_icon, chrome_open, entries); | 486 chrome_icon, chrome_open, entries); |
486 } | 487 } |
487 | 488 |
488 // start->Internet shortcut. | 489 // start->Internet shortcut. |
489 string16 start_menu(ShellUtil::kRegStartMenuInternet); | 490 string16 start_menu(ShellUtil::kRegStartMenuInternet); |
490 string16 app_name = dist->GetBaseAppName() + suffix; | 491 string16 app_name = dist->GetBaseAppName() + suffix; |
491 entries->push_back(new RegistryEntry(start_menu, app_name)); | 492 entries->push_back(new RegistryEntry(start_menu, app_name)); |
492 } | 493 } |
493 | 494 |
494 // Generate work_item tasks required to create current registry entry and | 495 // Generate work_item tasks required to create current registry entry and |
495 // add them to the given work item list. | 496 // add them to the given work item list. |
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
874 } | 875 } |
875 if (QuickIsChromeRegistered(dist, chrome_exe, *suffix, | 876 if (QuickIsChromeRegistered(dist, chrome_exe, *suffix, |
876 CONFIRM_SHELL_REGISTRATION)) { | 877 CONFIRM_SHELL_REGISTRATION)) { |
877 // Username suffix for installs that are suffixed as per the old-style. | 878 // Username suffix for installs that are suffixed as per the old-style. |
878 return true; | 879 return true; |
879 } | 880 } |
880 | 881 |
881 return ShellUtil::GetUserSpecificRegistrySuffix(suffix); | 882 return ShellUtil::GetUserSpecificRegistrySuffix(suffix); |
882 } | 883 } |
883 | 884 |
884 // Returns the root registry key (HKLM or HKCU) into which shell integration | 885 // Returns the root registry key (HKLM or HKCU) under which registrations must |
885 // registration for default protocols must be placed. As of Windows 8 everything | 886 // be placed for this install. As of Windows 8 everything can go in HKCU for |
886 // can go in HKCU for per-user installs. | 887 // per-user installs. |
887 HKEY DetermineShellIntegrationRoot(bool is_per_user) { | 888 HKEY DetermineRegistrationRoot(bool is_per_user) { |
888 return is_per_user && base::win::GetVersion() >= base::win::VERSION_WIN8 ? | 889 return is_per_user && base::win::GetVersion() >= base::win::VERSION_WIN8 ? |
889 HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE; | 890 HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE; |
890 } | 891 } |
891 | 892 |
892 // Associates Chrome with supported protocols and file associations. This should | 893 // Associates Chrome with supported protocols and file associations. This should |
893 // not be required on Vista+ but since some applications still read | 894 // not be required on Vista+ but since some applications still read |
894 // Software\Classes\http key directly, we have to do this on Vista+ as well. | 895 // Software\Classes\http key directly, we have to do this on Vista+ as well. |
895 bool RegisterChromeAsDefaultForXP(BrowserDistribution* dist, | 896 bool RegisterChromeAsDefaultForXP(BrowserDistribution* dist, |
896 int shell_change, | 897 int shell_change, |
897 const string16& chrome_exe) { | 898 const string16& chrome_exe) { |
898 bool ret = true; | 899 bool ret = true; |
899 ScopedVector<RegistryEntry> entries; | 900 ScopedVector<RegistryEntry> entries; |
900 RegistryEntry::GetDefaultBrowserUserEntries( | 901 RegistryEntry::GetDefaultBrowserUserEntriesForXP( |
901 dist, chrome_exe, | 902 dist, chrome_exe, |
902 ShellUtil::GetCurrentInstallationSuffix(dist, chrome_exe), &entries); | 903 ShellUtil::GetCurrentInstallationSuffix(dist, chrome_exe), &entries); |
903 | 904 |
904 // Change the default browser for current user. | 905 // Change the default browser for current user. |
905 if ((shell_change & ShellUtil::CURRENT_USER) && | 906 if ((shell_change & ShellUtil::CURRENT_USER) && |
906 !AddRegistryEntries(HKEY_CURRENT_USER, entries)) { | 907 !AddRegistryEntries(HKEY_CURRENT_USER, entries)) { |
907 ret = false; | 908 ret = false; |
908 LOG(ERROR) << "Could not make Chrome default browser (XP/current user)."; | 909 LOG(ERROR) << "Could not make Chrome default browser (XP/current user)."; |
909 } | 910 } |
910 | 911 |
(...skipping 10 matching lines...) Expand all Loading... | |
921 // Associates Chrome with |protocol| in the registry. This should not be | 922 // Associates Chrome with |protocol| in the registry. This should not be |
922 // required on Vista+ but since some applications still read these registry | 923 // required on Vista+ but since some applications still read these registry |
923 // keys directly, we have to do this on Vista+ as well. | 924 // keys directly, we have to do this on Vista+ as well. |
924 // See http://msdn.microsoft.com/library/aa767914.aspx for more details. | 925 // See http://msdn.microsoft.com/library/aa767914.aspx for more details. |
925 bool RegisterChromeAsDefaultProtocolClientForXP(BrowserDistribution* dist, | 926 bool RegisterChromeAsDefaultProtocolClientForXP(BrowserDistribution* dist, |
926 const string16& chrome_exe, | 927 const string16& chrome_exe, |
927 const string16& protocol) { | 928 const string16& protocol) { |
928 ScopedVector<RegistryEntry> entries; | 929 ScopedVector<RegistryEntry> entries; |
929 const string16 chrome_open(ShellUtil::GetChromeShellOpenCmd(chrome_exe)); | 930 const string16 chrome_open(ShellUtil::GetChromeShellOpenCmd(chrome_exe)); |
930 const string16 chrome_icon(ShellUtil::GetChromeIcon(dist, chrome_exe)); | 931 const string16 chrome_icon(ShellUtil::GetChromeIcon(dist, chrome_exe)); |
931 RegistryEntry::GetUserProtocolEntries(protocol, chrome_icon, chrome_open, | 932 RegistryEntry::GetUserProtocolEntriesForXP(protocol, chrome_icon, chrome_open, |
932 &entries); | 933 &entries); |
933 // Change the default protocol handler for current user. | 934 // Change the default protocol handler for current user. |
934 if (!AddRegistryEntries(HKEY_CURRENT_USER, entries)) { | 935 if (!AddRegistryEntries(HKEY_CURRENT_USER, entries)) { |
935 LOG(ERROR) << "Could not make Chrome default protocol client (XP)."; | 936 LOG(ERROR) << "Could not make Chrome default protocol client (XP)."; |
936 return false; | 937 return false; |
937 } | 938 } |
938 | 939 |
939 return true; | 940 return true; |
940 } | 941 } |
941 | 942 |
942 // Returns |properties.shortcut_name| if the property is set, otherwise it | 943 // Returns |properties.shortcut_name| if the property is set, otherwise it |
(...skipping 511 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1454 AT_URLPROTOCOL); | 1455 AT_URLPROTOCOL); |
1455 } | 1456 } |
1456 if (!SUCCEEDED(hr)) { | 1457 if (!SUCCEEDED(hr)) { |
1457 ret = false; | 1458 ret = false; |
1458 LOG(ERROR) << "Could not make Chrome default protocol client (Vista):" | 1459 LOG(ERROR) << "Could not make Chrome default protocol client (Vista):" |
1459 << " HRESULT=" << hr << "."; | 1460 << " HRESULT=" << hr << "."; |
1460 } | 1461 } |
1461 } | 1462 } |
1462 | 1463 |
1463 // Now use the old way to associate Chrome with the desired protocol. This | 1464 // Now use the old way to associate Chrome with the desired protocol. This |
1464 // should not be required on Vista but since some applications still read | 1465 // should not be required on Vista+, but since some applications still read |
1465 // Software\Classes\http key directly, we have to do this on Vista also. | 1466 // Software\Classes\<protocol> key directly, do this on Vista+ also. |
1466 if (!RegisterChromeAsDefaultProtocolClientForXP(dist, chrome_exe, protocol)) | 1467 if (!RegisterChromeAsDefaultProtocolClientForXP(dist, chrome_exe, protocol)) |
1467 ret = false; | 1468 ret = false; |
1468 | 1469 |
1469 return ret; | 1470 return ret; |
1470 } | 1471 } |
1471 | 1472 |
1472 bool ShellUtil::ShowMakeChromeDefaultProtocolClientSystemUI( | 1473 bool ShellUtil::ShowMakeChromeDefaultProtocolClientSystemUI( |
1473 BrowserDistribution* dist, | 1474 BrowserDistribution* dist, |
1474 const string16& chrome_exe, | 1475 const string16& chrome_exe, |
1475 const string16& protocol) { | 1476 const string16& protocol) { |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1510 } | 1511 } |
1511 | 1512 |
1512 // TODO(grt): remove this on or after 2012-08-01; see impl for details. | 1513 // TODO(grt): remove this on or after 2012-08-01; see impl for details. |
1513 RemoveBadWindows8RegistrationIfNeeded(dist, chrome_exe); | 1514 RemoveBadWindows8RegistrationIfNeeded(dist, chrome_exe); |
1514 | 1515 |
1515 // Check if Chromium is already registered with this suffix. | 1516 // Check if Chromium is already registered with this suffix. |
1516 if (IsChromeRegistered(dist, chrome_exe, suffix)) | 1517 if (IsChromeRegistered(dist, chrome_exe, suffix)) |
1517 return true; | 1518 return true; |
1518 | 1519 |
1519 bool user_level = InstallUtil::IsPerUserInstall(chrome_exe.c_str()); | 1520 bool user_level = InstallUtil::IsPerUserInstall(chrome_exe.c_str()); |
1520 HKEY root = DetermineShellIntegrationRoot(user_level); | 1521 HKEY root = DetermineRegistrationRoot(user_level); |
1521 | 1522 |
1522 // Do the full registration if we can do it at user-level or if the user is an | 1523 // Do the full registration if we can do it at user-level or if the user is an |
1523 // admin. | 1524 // admin. |
1524 if (root == HKEY_CURRENT_USER || IsUserAnAdmin()) { | 1525 if (root == HKEY_CURRENT_USER || IsUserAnAdmin()) { |
1525 ScopedVector<RegistryEntry> progid_and_appreg_entries; | 1526 ScopedVector<RegistryEntry> progid_and_appreg_entries; |
1526 ScopedVector<RegistryEntry> shell_entries; | 1527 ScopedVector<RegistryEntry> shell_entries; |
1527 RegistryEntry::GetProgIdEntries(dist, chrome_exe, suffix, | 1528 RegistryEntry::GetProgIdEntries(dist, chrome_exe, suffix, |
1528 &progid_and_appreg_entries); | 1529 &progid_and_appreg_entries); |
1529 RegistryEntry::GetAppRegistrationEntries(chrome_exe, suffix, | 1530 RegistryEntry::GetAppRegistrationEntries(chrome_exe, suffix, |
1530 &progid_and_appreg_entries); | 1531 &progid_and_appreg_entries); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1582 if (!unique_suffix.empty()) { | 1583 if (!unique_suffix.empty()) { |
1583 suffix = unique_suffix; | 1584 suffix = unique_suffix; |
1584 } else if (!GetInstallationSpecificSuffix(dist, chrome_exe, &suffix)) { | 1585 } else if (!GetInstallationSpecificSuffix(dist, chrome_exe, &suffix)) { |
1585 return false; | 1586 return false; |
1586 } | 1587 } |
1587 | 1588 |
1588 // Check if Chromium is already registered with this suffix. | 1589 // Check if Chromium is already registered with this suffix. |
1589 if (IsChromeRegisteredForProtocol(dist, suffix, protocol)) | 1590 if (IsChromeRegisteredForProtocol(dist, suffix, protocol)) |
1590 return true; | 1591 return true; |
1591 | 1592 |
1592 HKEY root = DetermineShellIntegrationRoot( | 1593 HKEY root = DetermineRegistrationRoot( |
1593 InstallUtil::IsPerUserInstall(chrome_exe.c_str())); | 1594 InstallUtil::IsPerUserInstall(chrome_exe.c_str())); |
1594 | 1595 |
1595 if (root == HKEY_CURRENT_USER || IsUserAnAdmin()) { | 1596 if (root == HKEY_CURRENT_USER || IsUserAnAdmin()) { |
1596 // We can do this operation directly. | 1597 // We can do this operation directly. |
1597 // First, make sure Chrome is fully registered on this machine. | 1598 // First, make sure Chrome is fully registered on this machine. |
1598 if (!RegisterChromeBrowser(dist, chrome_exe, suffix, false)) | 1599 if (!RegisterChromeBrowser(dist, chrome_exe, suffix, false)) |
1599 return false; | 1600 return false; |
1600 | 1601 |
1601 // Write in the capabillity for the protocol. | 1602 // Write in the capabillity for the protocol. |
1602 ScopedVector<RegistryEntry> entries; | 1603 ScopedVector<RegistryEntry> entries; |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1731 // are any left...). | 1732 // are any left...). |
1732 if (free_bits >= 8 && next_byte_index < size) { | 1733 if (free_bits >= 8 && next_byte_index < size) { |
1733 free_bits -= 8; | 1734 free_bits -= 8; |
1734 bit_stream += bytes[next_byte_index++] << free_bits; | 1735 bit_stream += bytes[next_byte_index++] << free_bits; |
1735 } | 1736 } |
1736 } | 1737 } |
1737 | 1738 |
1738 DCHECK_EQ(ret.length(), encoded_length); | 1739 DCHECK_EQ(ret.length(), encoded_length); |
1739 return ret; | 1740 return ret; |
1740 } | 1741 } |
OLD | NEW |