Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(322)

Side by Side Diff: chrome/installer/util/shell_util.cc

Issue 10667006: Revert 143782 - Use a better registration suffix that will always be unique while respecting the MS… (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/installer/util/shell_util.h ('k') | chrome/installer/util/shell_util_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « chrome/installer/util/shell_util.h ('k') | chrome/installer/util/shell_util_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698