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 10 matching lines...) Expand all Loading... |
21 #include "base/memory/scoped_ptr.h" | 21 #include "base/memory/scoped_ptr.h" |
22 #include "base/path_service.h" | 22 #include "base/path_service.h" |
23 #include "base/stl_util.h" | 23 #include "base/stl_util.h" |
24 #include "base/string_number_conversions.h" | 24 #include "base/string_number_conversions.h" |
25 #include "base/string_split.h" | 25 #include "base/string_split.h" |
26 #include "base/string_util.h" | 26 #include "base/string_util.h" |
27 #include "base/utf_string_conversions.h" | 27 #include "base/utf_string_conversions.h" |
28 #include "base/values.h" | 28 #include "base/values.h" |
29 #include "base/win/registry.h" | 29 #include "base/win/registry.h" |
30 #include "base/win/scoped_comptr.h" | 30 #include "base/win/scoped_comptr.h" |
31 #include "base/win/win_util.h" | |
32 #include "base/win/windows_version.h" | 31 #include "base/win/windows_version.h" |
33 #include "chrome/common/chrome_constants.h" | 32 #include "chrome/common/chrome_constants.h" |
34 #include "chrome/common/chrome_switches.h" | 33 #include "chrome/common/chrome_switches.h" |
35 #include "chrome/installer/util/browser_distribution.h" | 34 #include "chrome/installer/util/browser_distribution.h" |
36 #include "chrome/installer/util/install_util.h" | 35 #include "chrome/installer/util/install_util.h" |
37 #include "chrome/installer/util/master_preferences.h" | 36 #include "chrome/installer/util/master_preferences.h" |
38 #include "chrome/installer/util/master_preferences_constants.h" | 37 #include "chrome/installer/util/master_preferences_constants.h" |
39 | 38 |
40 using base::win::RegKey; | 39 using base::win::RegKey; |
41 | 40 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
79 VER_SET_CONDITION(condition_mask, VER_BUILDNUMBER, VER_GREATER_EQUAL); | 78 VER_SET_CONDITION(condition_mask, VER_BUILDNUMBER, VER_GREATER_EQUAL); |
80 VER_SET_CONDITION(condition_mask, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL); | 79 VER_SET_CONDITION(condition_mask, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL); |
81 VER_SET_CONDITION(condition_mask, VER_SERVICEPACKMINOR, VER_GREATER_EQUAL); | 80 VER_SET_CONDITION(condition_mask, VER_SERVICEPACKMINOR, VER_GREATER_EQUAL); |
82 | 81 |
83 DWORD type_mask = VER_MAJORVERSION | VER_MINORVERSION | VER_BUILDNUMBER | | 82 DWORD type_mask = VER_MAJORVERSION | VER_MINORVERSION | VER_BUILDNUMBER | |
84 VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR; | 83 VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR; |
85 | 84 |
86 return VerifyVersionInfo(&min_version_info, type_mask, condition_mask) != 0; | 85 return VerifyVersionInfo(&min_version_info, type_mask, condition_mask) != 0; |
87 } | 86 } |
88 | 87 |
89 // Sets |suffix| to the base 32 encoding of the md5 hash of this user's username | |
90 // preceded by a dot. | |
91 // This is guaranteed to be unique on the machine and 27 characters long | |
92 // (including the '.'). | |
93 // This suffix is then meant to be added to all registration that may conflict | |
94 // with another user-level Chrome install. | |
95 // Note that prior to Chrome 21, the suffix registered used to be the user's | |
96 // username (see GetOldUserSpecificRegistrySuffix() below). We still honor old | |
97 // installs registered that way, but it was wrong because some of the characters | |
98 // allowed in a username are not allowed in a ProgId. | |
99 // Returns true unless the OS call to retrieve the username fails. | |
100 bool GetNewUserSpecificRegistrySuffix(string16* suffix) { | |
101 wchar_t user_name[256]; | |
102 DWORD size = arraysize(user_name); | |
103 if (::GetUserName(user_name, &size) == 0 || size < 1) { | |
104 NOTREACHED(); | |
105 return false; | |
106 } | |
107 base::MD5Digest md5_digest; | |
108 base::MD5Sum(user_name, size, &md5_digest); | |
109 const string16 base32_md5(ShellUtil::MD5DigestToBase32(md5_digest)); | |
110 // The value returned by the base32 algorithm above must never change and must | |
111 // always be 26 characters long (i.e. if someone ever moves this to base and | |
112 // implements the full base32 algorithm (i.e. with appended '=' signs in the | |
113 // output), they must provide a flag to allow this method to still request | |
114 // the output with no appended '=' signs). | |
115 DCHECK_EQ(base32_md5.length(), 26U); | |
116 suffix->reserve(27); | |
117 suffix->assign(1, L'.'); | |
118 suffix->append(base32_md5); | |
119 return true; | |
120 } | |
121 | |
122 // Sets |suffix| to this user's username preceded by a dot. This suffix is then | |
123 // meant to be added to all registration that may conflict with another | |
124 // user-level Chrome install. | |
125 // Returns true unless the OS call to retrieve the username fails. | |
126 bool GetOldUserSpecificRegistrySuffix(string16* suffix) { | |
127 wchar_t user_name[256]; | |
128 DWORD size = arraysize(user_name); | |
129 if (::GetUserName(user_name, &size) == 0 || size < 1) { | |
130 NOTREACHED(); | |
131 return false; | |
132 } | |
133 suffix->reserve(size); | |
134 suffix->assign(1, L'.'); | |
135 suffix->append(user_name, size - 1); | |
136 return true; | |
137 } | |
138 | |
139 // Returns the current (or installed) browser's ProgId (e.g. | |
140 // "ChromeHTML|suffix|"). | |
141 // |suffix| can be the empty string. | |
142 string16 GetBrowserProgId(const string16& suffix) { | |
143 string16 chrome_html(ShellUtil::kChromeHTMLProgId); | |
144 chrome_html.append(suffix); | |
145 | |
146 // ProgIds cannot be longer than 39 characters. | |
147 // Ref: http://msdn.microsoft.com/en-us/library/aa911706.aspx. | |
148 // Make all new registrations comply with this requirement (existing | |
149 // registrations must be preserved). | |
150 // Note: since |new_style_suffix| will always be the same for this user, only | |
151 // initialize it once, re-use the derived value in subsequent calls. | |
152 static string16 new_style_suffix; | |
153 if ((!new_style_suffix.empty() || | |
154 GetNewUserSpecificRegistrySuffix(&new_style_suffix)) && | |
155 suffix.compare(new_style_suffix) == 0 && chrome_html.length() > 39) { | |
156 NOTREACHED(); | |
157 chrome_html.erase(39); | |
158 } | |
159 return chrome_html; | |
160 } | |
161 | |
162 // This class represents a single registry entry. The objective is to | 88 // This class represents a single registry entry. The objective is to |
163 // encapsulate all the registry entries required for registering Chrome at one | 89 // encapsulate all the registry entries required for registering Chrome at one |
164 // place. This class can not be instantiated outside the class and the objects | 90 // place. This class can not be instantiated outside the class and the objects |
165 // of this class type can be obtained only by calling a static method of this | 91 // of this class type can be obtained only by calling a static method of this |
166 // class. | 92 // class. |
167 class RegistryEntry { | 93 class RegistryEntry { |
168 public: | 94 public: |
169 // A bit-field enum of places to look for this key in the Windows registry. | 95 // A bit-field enum of places to look for this key in the Windows registry. |
170 enum LookForIn { | 96 enum LookForIn { |
171 LOOK_IN_HKCU = 1 << 0, | 97 LOOK_IN_HKCU = 1 << 0, |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
248 // <root hkey>\Software\Classes\<app_id>\.exe\shell\<verb>\command | 174 // <root hkey>\Software\Classes\<app_id>\.exe\shell\<verb>\command |
249 entries->push_front(new RegistryEntry(sub_path, delegate_command)); | 175 entries->push_front(new RegistryEntry(sub_path, delegate_command)); |
250 entries->push_front(new RegistryEntry( | 176 entries->push_front(new RegistryEntry( |
251 sub_path, ShellUtil::kRegDelegateExecute, delegate_guid)); | 177 sub_path, ShellUtil::kRegDelegateExecute, delegate_guid)); |
252 } | 178 } |
253 } | 179 } |
254 | 180 |
255 // File association ProgId | 181 // File association ProgId |
256 string16 chrome_html_prog_id(ShellUtil::kRegClasses); | 182 string16 chrome_html_prog_id(ShellUtil::kRegClasses); |
257 chrome_html_prog_id.push_back(FilePath::kSeparators[0]); | 183 chrome_html_prog_id.push_back(FilePath::kSeparators[0]); |
258 chrome_html_prog_id.append(GetBrowserProgId(suffix)); | 184 chrome_html_prog_id.append(ShellUtil::kChromeHTMLProgId); |
| 185 chrome_html_prog_id.append(suffix); |
259 entries->push_front(new RegistryEntry( | 186 entries->push_front(new RegistryEntry( |
260 chrome_html_prog_id, ShellUtil::kChromeHTMLProgIdDesc)); | 187 chrome_html_prog_id, ShellUtil::kChromeHTMLProgIdDesc)); |
261 entries->push_front(new RegistryEntry( | 188 entries->push_front(new RegistryEntry( |
262 chrome_html_prog_id, ShellUtil::kRegUrlProtocol, L"")); | 189 chrome_html_prog_id, ShellUtil::kRegUrlProtocol, L"")); |
263 entries->push_front(new RegistryEntry( | 190 entries->push_front(new RegistryEntry( |
264 chrome_html_prog_id + ShellUtil::kRegDefaultIcon, icon_path)); | 191 chrome_html_prog_id + ShellUtil::kRegDefaultIcon, icon_path)); |
265 entries->push_front(new RegistryEntry( | 192 entries->push_front(new RegistryEntry( |
266 chrome_html_prog_id + ShellUtil::kRegShellOpen, open_cmd)); | 193 chrome_html_prog_id + ShellUtil::kRegShellOpen, open_cmd)); |
267 if (set_delegate_execute) { | 194 if (set_delegate_execute) { |
268 entries->push_front(new RegistryEntry( | 195 entries->push_front(new RegistryEntry( |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
300 } | 227 } |
301 | 228 |
302 // This method returns a list of the registry entries needed to declare a | 229 // This method returns a list of the registry entries needed to declare a |
303 // capability of handling a protocol on Windows. | 230 // capability of handling a protocol on Windows. |
304 static bool GetProtocolCapabilityEntries(BrowserDistribution* dist, | 231 static bool GetProtocolCapabilityEntries(BrowserDistribution* dist, |
305 const string16& suffix, | 232 const string16& suffix, |
306 const string16& protocol, | 233 const string16& protocol, |
307 std::list<RegistryEntry*>* entries) { | 234 std::list<RegistryEntry*>* entries) { |
308 entries->push_front(new RegistryEntry( | 235 entries->push_front(new RegistryEntry( |
309 GetCapabilitiesKey(dist, suffix).append(L"\\URLAssociations"), | 236 GetCapabilitiesKey(dist, suffix).append(L"\\URLAssociations"), |
310 protocol, GetBrowserProgId(suffix))); | 237 protocol, string16(ShellUtil::kChromeHTMLProgId).append(suffix))); |
311 return true; | 238 return true; |
312 } | 239 } |
313 | 240 |
314 // This method returns a list of all the registry entries required to fully | 241 // This method returns a list of all the registry entries required to fully |
315 // integrate Chrome with Windows (i.e. StartMenuInternet, Default Programs, | 242 // integrate Chrome with Windows (i.e. StartMenuInternet, Default Programs, |
316 // AppPaths, etc.). This entries need to be registered in HKLM prior to Win8. | 243 // AppPaths, etc.). This entries need to be registered in HKLM prior to Win8. |
317 static bool GetShellIntegrationEntries(BrowserDistribution* dist, | 244 static bool GetShellIntegrationEntries(BrowserDistribution* dist, |
318 const string16& chrome_exe, | 245 const string16& chrome_exe, |
319 const string16& suffix, | 246 const string16& suffix, |
320 std::list<RegistryEntry*>* entries) { | 247 std::list<RegistryEntry*>* entries) { |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
361 dist->GetLongAppDescription())); | 288 dist->GetLongAppDescription())); |
362 entries->push_front(new RegistryEntry( | 289 entries->push_front(new RegistryEntry( |
363 capabilities, ShellUtil::kRegApplicationIcon, icon_path)); | 290 capabilities, ShellUtil::kRegApplicationIcon, icon_path)); |
364 entries->push_front(new RegistryEntry( | 291 entries->push_front(new RegistryEntry( |
365 capabilities, ShellUtil::kRegApplicationName, | 292 capabilities, ShellUtil::kRegApplicationName, |
366 dist->GetAppShortCutName())); | 293 dist->GetAppShortCutName())); |
367 | 294 |
368 entries->push_front(new RegistryEntry(capabilities + L"\\Startmenu", | 295 entries->push_front(new RegistryEntry(capabilities + L"\\Startmenu", |
369 L"StartMenuInternet", reg_app_name)); | 296 L"StartMenuInternet", reg_app_name)); |
370 | 297 |
371 string16 html_prog_id(GetBrowserProgId(suffix)); | 298 string16 html_prog_id(ShellUtil::kChromeHTMLProgId); |
| 299 html_prog_id.append(suffix); |
372 for (int i = 0; ShellUtil::kFileAssociations[i] != NULL; i++) { | 300 for (int i = 0; ShellUtil::kFileAssociations[i] != NULL; i++) { |
373 entries->push_front(new RegistryEntry( | 301 entries->push_front(new RegistryEntry( |
374 capabilities + L"\\FileAssociations", | 302 capabilities + L"\\FileAssociations", |
375 ShellUtil::kFileAssociations[i], html_prog_id)); | 303 ShellUtil::kFileAssociations[i], html_prog_id)); |
376 } | 304 } |
377 for (int i = 0; ShellUtil::kPotentialProtocolAssociations[i] != NULL; | 305 for (int i = 0; ShellUtil::kPotentialProtocolAssociations[i] != NULL; |
378 i++) { | 306 i++) { |
379 entries->push_front(new RegistryEntry( | 307 entries->push_front(new RegistryEntry( |
380 capabilities + L"\\URLAssociations", | 308 capabilities + L"\\URLAssociations", |
381 ShellUtil::kPotentialProtocolAssociations[i], html_prog_id)); | 309 ShellUtil::kPotentialProtocolAssociations[i], html_prog_id)); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
430 return true; | 358 return true; |
431 } | 359 } |
432 | 360 |
433 // This method returns a list of all the user level registry entries that | 361 // This method returns a list of all the user level registry entries that |
434 // are needed to make Chromium default browser. | 362 // are needed to make Chromium default browser. |
435 static bool GetUserEntries(BrowserDistribution* dist, | 363 static bool GetUserEntries(BrowserDistribution* dist, |
436 const string16& chrome_exe, | 364 const string16& chrome_exe, |
437 const string16& suffix, | 365 const string16& suffix, |
438 std::list<RegistryEntry*>* entries) { | 366 std::list<RegistryEntry*>* entries) { |
439 // File extension associations. | 367 // File extension associations. |
440 string16 html_prog_id(GetBrowserProgId(suffix)); | 368 string16 html_prog_id(ShellUtil::kChromeHTMLProgId); |
| 369 html_prog_id.append(suffix); |
441 for (int i = 0; ShellUtil::kFileAssociations[i] != NULL; i++) { | 370 for (int i = 0; ShellUtil::kFileAssociations[i] != NULL; i++) { |
442 string16 ext_key(ShellUtil::kRegClasses); | 371 string16 ext_key(ShellUtil::kRegClasses); |
443 ext_key.push_back(FilePath::kSeparators[0]); | 372 ext_key.push_back(FilePath::kSeparators[0]); |
444 ext_key.append(ShellUtil::kFileAssociations[i]); | 373 ext_key.append(ShellUtil::kFileAssociations[i]); |
445 entries->push_front(new RegistryEntry(ext_key, html_prog_id)); | 374 entries->push_front(new RegistryEntry(ext_key, html_prog_id)); |
446 } | 375 } |
447 | 376 |
448 // Protocols associations. | 377 // Protocols associations. |
449 string16 chrome_open = ShellUtil::GetChromeShellOpenCmd(chrome_exe); | 378 string16 chrome_open = ShellUtil::GetChromeShellOpenCmd(chrome_exe); |
450 string16 chrome_icon = ShellUtil::GetChromeIcon(dist, chrome_exe); | 379 string16 chrome_icon = ShellUtil::GetChromeIcon(dist, chrome_exe); |
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
741 | 670 |
742 // <root hkey>\Software\Classes\<app_id> | 671 // <root hkey>\Software\Classes\<app_id> |
743 string16 key(ShellUtil::kRegClasses); | 672 string16 key(ShellUtil::kRegClasses); |
744 key.push_back(FilePath::kSeparators[0]); | 673 key.push_back(FilePath::kSeparators[0]); |
745 key.append(app_id); | 674 key.append(app_id); |
746 InstallUtil::DeleteRegistryKey(root_key, key); | 675 InstallUtil::DeleteRegistryKey(root_key, key); |
747 | 676 |
748 // <root hkey>\Software\Classes\ChromiumHTML[.user]\shell\open\command | 677 // <root hkey>\Software\Classes\ChromiumHTML[.user]\shell\open\command |
749 key = ShellUtil::kRegClasses; | 678 key = ShellUtil::kRegClasses; |
750 key.push_back(FilePath::kSeparators[0]); | 679 key.push_back(FilePath::kSeparators[0]); |
751 key.append(GetBrowserProgId(installation_suffix)); | 680 key.append(ShellUtil::kChromeHTMLProgId); |
| 681 key.append(installation_suffix); |
752 key.append(ShellUtil::kRegShellOpen); | 682 key.append(ShellUtil::kRegShellOpen); |
753 InstallUtil::DeleteRegistryValue(root_key, key, | 683 InstallUtil::DeleteRegistryValue(root_key, key, |
754 ShellUtil::kRegDelegateExecute); | 684 ShellUtil::kRegDelegateExecute); |
755 } | 685 } |
756 } | 686 } |
757 | 687 |
758 // Returns true if the current install's |chrome_exe| has been registered with | 688 // Returns true if the current install's |chrome_exe| has been registered with |
759 // |suffix|. | 689 // |suffix|. |
760 // |confirmation_level| is the level of verification desired as described in | 690 // |confirmation_level| is the level of verification desired as described in |
761 // the RegistrationConfirmationLevel enum above. | 691 // the RegistrationConfirmationLevel enum above. |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
810 // Assert that |reg_key| points to |chrome_exe| in HKLM. | 740 // Assert that |reg_key| points to |chrome_exe| in HKLM. |
811 const RegKey key_hklm(HKEY_LOCAL_MACHINE, reg_key.c_str(), KEY_QUERY_VALUE); | 741 const RegKey key_hklm(HKEY_LOCAL_MACHINE, reg_key.c_str(), KEY_QUERY_VALUE); |
812 string16 hklm_value; | 742 string16 hklm_value; |
813 if (key_hklm.ReadValue(L"", &hklm_value) == ERROR_SUCCESS) { | 743 if (key_hklm.ReadValue(L"", &hklm_value) == ERROR_SUCCESS) { |
814 return InstallUtil::ProgramCompare( | 744 return InstallUtil::ProgramCompare( |
815 FilePath(chrome_exe)).Evaluate(hklm_value); | 745 FilePath(chrome_exe)).Evaluate(hklm_value); |
816 } | 746 } |
817 return false; | 747 return false; |
818 } | 748 } |
819 | 749 |
820 // Sets |suffix| to a 27 characters string that is specific to this user on | 750 // Sets |suffix| to this user's username preceded by a dot. This suffix is then |
821 // this machine, on user-level installs, preferably. | 751 // meant to be added to all registration that may conflict with another |
| 752 // user-level Chrome install. |
| 753 // Returns true unless the OS call to retrieve the username fails. |
| 754 bool GetUserSpecificRegistrySuffix(string16* suffix) { |
| 755 wchar_t user_name[256]; |
| 756 DWORD size = arraysize(user_name); |
| 757 if (::GetUserName(user_name, &size) == 0 || size < 1) { |
| 758 PLOG(DFATAL) << "GetUserName failed"; |
| 759 return false; |
| 760 } |
| 761 suffix->reserve(size); |
| 762 suffix->assign(1, L'.'); |
| 763 suffix->append(user_name, size - 1); |
| 764 return true; |
| 765 } |
| 766 |
| 767 // Sets |suffix| to the current user's username, preceded by a dot, on |
| 768 // user-level installs. |
822 // To support old-style user-level installs however, |suffix| is cleared if | 769 // To support old-style user-level installs however, |suffix| is cleared if |
823 // the user currently owns the non-suffixed HKLM registrations. | 770 // the user currently owns the non-suffixed HKLM registrations. |
824 // |suffix| can also be set to the user's username if the current install | 771 // |suffix| is also cleared on system-level installs. |
825 // is suffixed as per the old-style registrations. | |
826 // |suffix| is cleared on system-level installs. | |
827 // |suffix| should then be appended to all Chrome properties that may conflict | 772 // |suffix| should then be appended to all Chrome properties that may conflict |
828 // with other Chrome user-level installs. | 773 // with other Chrome user-level installs. |
829 // Returns true unless one of the underlying calls fails. | 774 // Returns true unless one of the underlying calls fails. |
830 bool GetInstallationSpecificSuffix(BrowserDistribution* dist, | 775 bool GetInstallationSpecificSuffix(BrowserDistribution* dist, |
831 const string16& chrome_exe, | 776 const string16& chrome_exe, |
832 string16* suffix) { | 777 string16* suffix) { |
833 if (!InstallUtil::IsPerUserInstall(chrome_exe.c_str()) || | 778 if (!InstallUtil::IsPerUserInstall(chrome_exe.c_str()) || |
834 QuickIsChromeRegistered(dist, chrome_exe, string16(), | 779 QuickIsChromeRegistered(dist, chrome_exe, string16(), |
835 CONFIRM_SHELL_REGISTRATION)) { | 780 CONFIRM_SHELL_REGISTRATION)) { |
836 // No suffix on system-level installs and user-level installs already | 781 // No suffix on system-level installs and user-level installs already |
837 // registered with no suffix. | 782 // registered with no suffix. |
838 suffix->clear(); | 783 suffix->clear(); |
839 return true; | 784 return true; |
| 785 } else { |
| 786 return GetUserSpecificRegistrySuffix(suffix); |
840 } | 787 } |
841 | |
842 string16 old_suffix; | |
843 // Get the |old_suffix| for the check below. | |
844 if (!GetOldUserSpecificRegistrySuffix(&old_suffix)) { | |
845 NOTREACHED(); | |
846 return false; | |
847 } | |
848 if (QuickIsChromeRegistered(dist, chrome_exe, old_suffix, | |
849 CONFIRM_SHELL_REGISTRATION)) { | |
850 // Username suffix for installs that are suffixed as per the old-style. | |
851 suffix->assign(old_suffix); | |
852 return true; | |
853 } | |
854 | |
855 return GetNewUserSpecificRegistrySuffix(suffix); | |
856 } | 788 } |
857 | 789 |
858 // Returns the root registry key (HKLM or HKCU) into which shell integration | 790 // Returns the root registry key (HKLM or HKCU) into which shell integration |
859 // registration for default protocols must be placed. As of Windows 8 everything | 791 // registration for default protocols must be placed. As of Windows 8 everything |
860 // can go in HKCU for per-user installs. | 792 // can go in HKCU for per-user installs. |
861 HKEY DetermineShellIntegrationRoot(bool is_per_user) { | 793 HKEY DetermineShellIntegrationRoot(bool is_per_user) { |
862 return is_per_user && base::win::GetVersion() >= base::win::VERSION_WIN8 ? | 794 return is_per_user && base::win::GetVersion() >= base::win::VERSION_WIN8 ? |
863 HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE; | 795 HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE; |
864 } | 796 } |
865 | 797 |
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1121 key.ReadValue(kReinstallCommand, &command) == ERROR_SUCCESS && | 1053 key.ReadValue(kReinstallCommand, &command) == ERROR_SUCCESS && |
1122 !command.empty()) { | 1054 !command.empty()) { |
1123 (*browsers)[name] = command; | 1055 (*browsers)[name] = command; |
1124 } | 1056 } |
1125 } | 1057 } |
1126 } | 1058 } |
1127 } | 1059 } |
1128 | 1060 |
1129 string16 ShellUtil::GetCurrentInstallationSuffix(BrowserDistribution* dist, | 1061 string16 ShellUtil::GetCurrentInstallationSuffix(BrowserDistribution* dist, |
1130 const string16& chrome_exe) { | 1062 const string16& chrome_exe) { |
1131 // This method is somewhat the opposite of GetInstallationSpecificSuffix(). | |
1132 // In this case we are not trying to determine the current suffix for the | |
1133 // upcoming installation (i.e. not trying to stick to a currently bad | |
1134 // registration style if one is present). | |
1135 // Here we want to determine which suffix we should use at run-time. | |
1136 // In order of preference, we prefer (for user-level installs): | |
1137 // 1) Base 32 encoding of the md5 hash of the username (new-style). | |
1138 // 2) Username (old-style). | |
1139 // 3) Unsuffixed (even worse). | |
1140 string16 tested_suffix; | 1063 string16 tested_suffix; |
1141 if (!InstallUtil::IsPerUserInstall(chrome_exe.c_str()) || | 1064 if (!InstallUtil::IsPerUserInstall(chrome_exe.c_str()) || |
1142 ((!GetNewUserSpecificRegistrySuffix(&tested_suffix) || | 1065 !GetUserSpecificRegistrySuffix(&tested_suffix) || |
1143 !QuickIsChromeRegistered(dist, chrome_exe, tested_suffix, | 1066 !QuickIsChromeRegistered(dist, chrome_exe, tested_suffix, |
1144 CONFIRM_PROGID_REGISTRATION)) && | 1067 CONFIRM_PROGID_REGISTRATION)) { |
1145 (!GetOldUserSpecificRegistrySuffix(&tested_suffix) || | |
1146 !QuickIsChromeRegistered(dist, chrome_exe, tested_suffix, | |
1147 CONFIRM_PROGID_REGISTRATION)))) { | |
1148 // The current installation's suffix should only be empty on system-level | |
1149 // installs and unsuffixed (old-style) user-level installs. | |
1150 DCHECK(!InstallUtil::IsPerUserInstall(chrome_exe.c_str()) || | |
1151 QuickIsChromeRegistered(dist, chrome_exe, string16(), | |
1152 CONFIRM_PROGID_REGISTRATION)); | |
1153 return string16(); | 1068 return string16(); |
1154 } | 1069 } |
1155 return tested_suffix; | 1070 return tested_suffix; |
1156 } | 1071 } |
1157 | 1072 |
1158 string16 ShellUtil::GetApplicationName(BrowserDistribution* dist, | 1073 string16 ShellUtil::GetApplicationName(BrowserDistribution* dist, |
1159 const string16& chrome_exe) { | 1074 const string16& chrome_exe) { |
1160 string16 app_name = dist->GetBaseAppName(); | 1075 string16 app_name = dist->GetBaseAppName(); |
1161 app_name += GetCurrentInstallationSuffix(dist, chrome_exe); | 1076 app_name += GetCurrentInstallationSuffix(dist, chrome_exe); |
1162 return app_name; | 1077 return app_name; |
1163 } | 1078 } |
1164 | 1079 |
1165 string16 ShellUtil::GetBrowserModelId(BrowserDistribution* dist, | 1080 string16 ShellUtil::GetBrowserModelId(BrowserDistribution* dist, |
1166 const string16& chrome_exe) { | 1081 const string16& chrome_exe) { |
1167 string16 app_id(dist->GetBaseAppId()); | 1082 string16 app_id(dist->GetBaseAppId()); |
1168 string16 suffix; | 1083 string16 suffix; |
1169 if (InstallUtil::IsPerUserInstall(chrome_exe.c_str()) && | 1084 if (InstallUtil::IsPerUserInstall(chrome_exe.c_str()) && |
1170 !GetNewUserSpecificRegistrySuffix(&suffix)) { | 1085 !GetUserSpecificRegistrySuffix(&suffix)) { |
1171 NOTREACHED(); | 1086 NOTREACHED(); |
1172 } | 1087 } |
1173 // There is only one component (i.e. the suffixed appid) in this case, but it | 1088 // There is only one component (i.e. the suffixed appid) in this case, but it |
1174 // is still necessary to go through the appid constructor to make sure the | 1089 // is still necessary to go through the appid constructor to make sure the |
1175 // returned appid is truncated if necessary. | 1090 // returned appid is truncated if necessary. |
1176 std::vector<string16> components(1, app_id.append(suffix)); | 1091 std::vector<string16> components(1, app_id.append(suffix)); |
1177 return BuildAppModelId(components); | 1092 return BuildAppModelId(components); |
1178 } | 1093 } |
1179 | 1094 |
1180 string16 ShellUtil::BuildAppModelId( | 1095 string16 ShellUtil::BuildAppModelId( |
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1599 chrome_exe.c_str(), | 1514 chrome_exe.c_str(), |
1600 shortcut.c_str(), | 1515 shortcut.c_str(), |
1601 chrome_path.value().c_str(), | 1516 chrome_path.value().c_str(), |
1602 arguments.c_str(), | 1517 arguments.c_str(), |
1603 description.c_str(), | 1518 description.c_str(), |
1604 icon_path.c_str(), | 1519 icon_path.c_str(), |
1605 icon_index, | 1520 icon_index, |
1606 app_id.c_str(), | 1521 app_id.c_str(), |
1607 ConvertShellUtilShortcutOptionsToFileUtil(options)); | 1522 ConvertShellUtilShortcutOptionsToFileUtil(options)); |
1608 } | 1523 } |
1609 | |
1610 string16 ShellUtil::MD5DigestToBase32(const base::MD5Digest& digest) { | |
1611 COMPILE_ASSERT(sizeof(base::MD5Digest) == 16, size_of_MD5_not_as_expected_); | |
1612 string16 encoding(ByteArrayToBase32(digest.a, 16)); | |
1613 // This must always remain 26 characters as callers which write to solid | |
1614 // state depend on this. | |
1615 DCHECK_EQ(encoding.length(), 26U); | |
1616 return encoding; | |
1617 } | |
1618 | |
1619 string16 ShellUtil::ByteArrayToBase32(const unsigned char bytes[], int size) { | |
1620 static char const kEncoding[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"; | |
1621 | |
1622 // Eliminate special cases first. | |
1623 if (size == 0) { | |
1624 return string16(); | |
1625 } else if (size == 1) { | |
1626 string16 ret; | |
1627 ret.push_back(kEncoding[(bytes[0] & 0xf8) >> 3]); | |
1628 ret.push_back(kEncoding[(bytes[0] & 0x07) << 2]); | |
1629 return ret; | |
1630 } | |
1631 | |
1632 // Overestimate the number of bits in the string by 4 so that dividing by 5 | |
1633 // is the equivalent of rounding up the actual number of bits divided by 5. | |
1634 const int kEncodedLength = (size * 8 + 4) / 5; | |
1635 | |
1636 string16 ret; | |
1637 ret.reserve(kEncodedLength); | |
1638 | |
1639 // A bit stream which will be read from the left and appended to from the | |
1640 // right as it's emptied. | |
1641 uint16 bit_stream = (bytes[0] << 8) + bytes[1]; | |
1642 int next_byte_index = 2; | |
1643 int free_bits = 0; | |
1644 while (free_bits < 16) { | |
1645 // Extract the 5 leftmost bits in the stream | |
1646 ret.push_back(kEncoding[(bit_stream & 0xf800) >> 11]); | |
1647 bit_stream <<= 5; | |
1648 free_bits += 5; | |
1649 | |
1650 // If there is enough room in the bit stream, inject another byte (if there | |
1651 // are any left...). | |
1652 if (free_bits >= 8 && next_byte_index < size) { | |
1653 free_bits -= 8; | |
1654 bit_stream += bytes[next_byte_index++] << free_bits; | |
1655 } | |
1656 } | |
1657 | |
1658 DCHECK_EQ(ret.length(), static_cast<size_t>(kEncodedLength)); | |
1659 return ret; | |
1660 } | |
OLD | NEW |