Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 // | 4 // |
| 5 // 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 |