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

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

Issue 1578833003: Moved shell_util functions into new shell_registry_util module. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase. Created 4 years, 11 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
« no previous file with comments | « chrome/installer/util/shell_registry_util.cc ('k') | no next file » | 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 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 #include "chrome/common/chrome_switches.h" 46 #include "chrome/common/chrome_switches.h"
47 #include "chrome/installer/util/beacons.h" 47 #include "chrome/installer/util/beacons.h"
48 #include "chrome/installer/util/browser_distribution.h" 48 #include "chrome/installer/util/browser_distribution.h"
49 #include "chrome/installer/util/install_util.h" 49 #include "chrome/installer/util/install_util.h"
50 #include "chrome/installer/util/installer_util_strings.h" 50 #include "chrome/installer/util/installer_util_strings.h"
51 #include "chrome/installer/util/l10n_string_util.h" 51 #include "chrome/installer/util/l10n_string_util.h"
52 #include "chrome/installer/util/master_preferences.h" 52 #include "chrome/installer/util/master_preferences.h"
53 #include "chrome/installer/util/master_preferences_constants.h" 53 #include "chrome/installer/util/master_preferences_constants.h"
54 #include "chrome/installer/util/registry_entry.h" 54 #include "chrome/installer/util/registry_entry.h"
55 #include "chrome/installer/util/scoped_user_protocol_entry.h" 55 #include "chrome/installer/util/scoped_user_protocol_entry.h"
56 #include "chrome/installer/util/shell_registry_util.h"
56 #include "chrome/installer/util/util_constants.h" 57 #include "chrome/installer/util/util_constants.h"
57 #include "chrome/installer/util/work_item.h" 58 #include "chrome/installer/util/work_item.h"
58 59
59 using base::win::RegKey; 60 using base::win::RegKey;
60 61
61 namespace { 62 namespace {
62 63
63 // An enum used to tell QuickIsChromeRegistered() which level of registration 64 // An enum used to tell QuickIsChromeRegistered() which level of registration
64 // the caller wants to confirm. 65 // the caller wants to confirm.
65 enum RegistrationConfirmationLevel { 66 enum RegistrationConfirmationLevel {
66 // Only look for Chrome's ProgIds. 67 // Only look for Chrome's ProgIds.
67 // This is sufficient when we are trying to determine the suffix of the 68 // This is sufficient when we are trying to determine the suffix of the
68 // currently running Chrome as shell integration registrations might not be 69 // currently running Chrome as shell integration registrations might not be
69 // present. 70 // present.
70 CONFIRM_PROGID_REGISTRATION = 0, 71 CONFIRM_PROGID_REGISTRATION = 0,
71 // Confirm that Chrome is fully integrated with Windows (i.e. registered with 72 // Confirm that Chrome is fully integrated with Windows (i.e. registered with
72 // Defaut Programs). These registrations can be in HKCU as of Windows 8. 73 // Defaut Programs). These registrations can be in HKCU as of Windows 8.
73 // Note: Shell registration implies ProgId registration. 74 // Note: Shell registration implies ProgId registration.
74 CONFIRM_SHELL_REGISTRATION, 75 CONFIRM_SHELL_REGISTRATION,
75 // Same as CONFIRM_SHELL_REGISTRATION, but only look in HKLM (used when 76 // Same as CONFIRM_SHELL_REGISTRATION, but only look in HKLM (used when
76 // uninstalling to know whether elevation is required to clean up the 77 // uninstalling to know whether elevation is required to clean up the
77 // registry). 78 // registry).
78 CONFIRM_SHELL_REGISTRATION_IN_HKLM, 79 CONFIRM_SHELL_REGISTRATION_IN_HKLM,
79 }; 80 };
80 81
81 const wchar_t kReinstallCommand[] = L"ReinstallCommand";
82
83 // Returns the current (or installed) browser's ProgId (e.g.
84 // "ChromeHTML|suffix|").
85 // |suffix| can be the empty string.
86 base::string16 GetBrowserProgId(const base::string16& suffix) {
87 BrowserDistribution* dist = BrowserDistribution::GetDistribution();
88 base::string16 chrome_html(dist->GetBrowserProgIdPrefix());
89 chrome_html.append(suffix);
90
91 // ProgIds cannot be longer than 39 characters.
92 // Ref: http://msdn.microsoft.com/en-us/library/aa911706.aspx.
93 // Make all new registrations comply with this requirement (existing
94 // registrations must be preserved).
95 base::string16 new_style_suffix;
96 if (ShellUtil::GetUserSpecificRegistrySuffix(&new_style_suffix) &&
97 suffix == new_style_suffix && chrome_html.length() > 39) {
98 NOTREACHED();
99 chrome_html.erase(39);
100 }
101 return chrome_html;
102 }
103
104 // This class is used to initialize and cache a base 32 encoding of the md5 hash 82 // This class is used to initialize and cache a base 32 encoding of the md5 hash
105 // of this user's sid preceded by a dot. 83 // of this user's sid preceded by a dot.
106 // This is guaranteed to be unique on the machine and 27 characters long 84 // This is guaranteed to be unique on the machine and 27 characters long
107 // (including the '.'). 85 // (including the '.').
108 // This is then meant to be used as a suffix on all registrations that may 86 // This is then meant to be used as a suffix on all registrations that may
109 // conflict with another user-level Chrome install. 87 // conflict with another user-level Chrome install.
110 class UserSpecificRegistrySuffix { 88 class UserSpecificRegistrySuffix {
111 public: 89 public:
112 // All the initialization is done in the constructor to be able to build the 90 // All the initialization is done in the constructor to be able to build the
113 // suffix in a thread-safe manner when used in conjunction with a 91 // suffix in a thread-safe manner when used in conjunction with a
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
149 127
150 bool UserSpecificRegistrySuffix::GetSuffix(base::string16* suffix) { 128 bool UserSpecificRegistrySuffix::GetSuffix(base::string16* suffix) {
151 if (suffix_.empty()) { 129 if (suffix_.empty()) {
152 NOTREACHED(); 130 NOTREACHED();
153 return false; 131 return false;
154 } 132 }
155 suffix->assign(suffix_); 133 suffix->assign(suffix_);
156 return true; 134 return true;
157 } 135 }
158 136
159 // Details about a Windows application, to be entered into the registry for the
160 // purpose of file associations.
161 struct ApplicationInfo {
162 ApplicationInfo() : file_type_icon_index(0), application_icon_index(0) {}
163
164 // The ProgId used by Windows for file associations with this application.
165 // Must not be empty or start with a '.'.
166 base::string16 prog_id;
167 // The friendly name, and the path of the icon that will be used for files of
168 // these types when associated with this application by default. (They are NOT
169 // the name/icon that will represent the application under the Open With
170 // menu.)
171 base::string16 file_type_name;
172 base::FilePath file_type_icon_path;
173 int file_type_icon_index;
174 // The command to execute when opening a file via this association. It should
175 // contain "%1" (to tell Windows to pass the filename as an argument).
176 // TODO(mgiuca): |command_line| should be a base::CommandLine.
177 base::string16 command_line;
178 // The AppUserModelId used by Windows 8 for this application. Distinct from
179 // |prog_id|.
180 base::string16 app_id;
181
182 // User-visible details about this application. Any of these may be empty.
183 base::string16 application_name;
184 base::FilePath application_icon_path;
185 int application_icon_index;
186 base::string16 application_description;
187 base::string16 publisher_name;
188
189 // The CLSID for the application's DelegateExecute handler. May be empty.
190 base::string16 delegate_clsid;
191 };
192
193 // Returns the Windows browser client registration key for Chrome. For example:
194 // "Software\Clients\StartMenuInternet\Chromium[.user]". Strictly speaking, we
195 // should use the name of the executable (e.g., "chrome.exe"), but that ship has
196 // sailed. The cost of switching now is re-prompting users to make Chrome their
197 // default browser, which isn't polite. |suffix| is the user-specific
198 // registration suffix; see GetUserSpecificDefaultBrowserSuffix in shell_util.h
199 // for details.
200 base::string16 GetBrowserClientKey(BrowserDistribution* dist,
201 const base::string16& suffix) {
202 DCHECK(suffix.empty() || suffix[0] == L'.');
203 return base::string16(ShellUtil::kRegStartMenuInternet)
204 .append(1, L'\\')
205 .append(dist->GetBaseAppName())
206 .append(suffix);
207 }
208
209 // Returns the Windows Default Programs capabilities key for Chrome. For
210 // example:
211 // "Software\Clients\StartMenuInternet\Chromium[.user]\Capabilities".
212 base::string16 GetCapabilitiesKey(BrowserDistribution* dist,
213 const base::string16& suffix) {
214 return GetBrowserClientKey(dist, suffix).append(L"\\Capabilities");
215 }
216
217 // DelegateExecute ProgId. Needed for Chrome Metro in Windows 8. This is only
218 // needed for registring a web browser, not for general associations.
219 ScopedVector<RegistryEntry> GetChromeDelegateExecuteEntries(
220 const base::FilePath& chrome_exe,
221 const ApplicationInfo& app_info) {
222 ScopedVector<RegistryEntry> entries;
223
224 base::string16 app_id_shell_key(ShellUtil::kRegClasses);
225 app_id_shell_key.push_back(base::FilePath::kSeparators[0]);
226 app_id_shell_key.append(app_info.app_id);
227 app_id_shell_key.append(ShellUtil::kRegExePath);
228 app_id_shell_key.append(ShellUtil::kRegShellPath);
229
230 // <root hkey>\Software\Classes\<app_id>\.exe\shell @=open
231 entries.push_back(
232 new RegistryEntry(app_id_shell_key, ShellUtil::kRegVerbOpen));
233
234 // The command to execute when opening this application via the Metro UI.
235 const base::string16 delegate_command(
236 ShellUtil::GetChromeDelegateCommand(chrome_exe));
237
238 // Each of Chrome's shortcuts has an appid; which, as of Windows 8, is
239 // registered to handle some verbs. This registration has the side-effect
240 // that these verbs now show up in the shortcut's context menu. We
241 // mitigate this side-effect by making the context menu entries
242 // user readable/localized strings. See relevant MSDN article:
243 // http://msdn.microsoft.com/en-US/library/windows/desktop/cc144171.aspx
244 static const struct {
245 const wchar_t* verb;
246 int name_id;
247 } verbs[] = {
248 {ShellUtil::kRegVerbOpen, -1},
249 {ShellUtil::kRegVerbOpenNewWindow, IDS_SHORTCUT_NEW_WINDOW_BASE},
250 };
251 for (const auto& verb_and_id : verbs) {
252 base::string16 sub_path(app_id_shell_key);
253 sub_path.push_back(base::FilePath::kSeparators[0]);
254 sub_path.append(verb_and_id.verb);
255
256 // <root hkey>\Software\Classes\<app_id>\.exe\shell\<verb>
257 if (verb_and_id.name_id != -1) {
258 // TODO(grt): http://crbug.com/75152 Write a reference to a localized
259 // resource.
260 const base::string16 verb_name(
261 installer::GetLocalizedString(verb_and_id.name_id));
262 entries.push_back(new RegistryEntry(sub_path, verb_name.c_str()));
263 }
264 entries.push_back(
265 new RegistryEntry(sub_path, L"CommandId", L"Browser.Launch"));
266
267 sub_path.push_back(base::FilePath::kSeparators[0]);
268 sub_path.append(ShellUtil::kRegCommand);
269
270 // <root hkey>\Software\Classes\<app_id>\.exe\shell\<verb>\command
271 entries.push_back(new RegistryEntry(sub_path, delegate_command));
272 entries.push_back(new RegistryEntry(
273 sub_path, ShellUtil::kRegDelegateExecute, app_info.delegate_clsid));
274 }
275
276 return entries;
277 }
278
279 // Gets the registry entries to register an application in the Windows registry.
280 // |app_info| provides all of the information needed.
281 void GetProgIdEntries(const ApplicationInfo& app_info,
282 ScopedVector<RegistryEntry>* entries) {
283 // Basic sanity checks.
284 DCHECK(!app_info.prog_id.empty());
285 DCHECK_NE(L'.', app_info.prog_id[0]);
286
287 // File association ProgId
288 base::string16 prog_id_path(ShellUtil::kRegClasses);
289 prog_id_path.push_back(base::FilePath::kSeparators[0]);
290 prog_id_path.append(app_info.prog_id);
291 entries->push_back(new RegistryEntry(prog_id_path, app_info.file_type_name));
292 entries->push_back(new RegistryEntry(
293 prog_id_path + ShellUtil::kRegDefaultIcon,
294 ShellUtil::FormatIconLocation(app_info.file_type_icon_path,
295 app_info.file_type_icon_index)));
296 entries->push_back(new RegistryEntry(prog_id_path + ShellUtil::kRegShellOpen,
297 app_info.command_line));
298 if (!app_info.delegate_clsid.empty()) {
299 entries->push_back(new RegistryEntry(
300 prog_id_path + ShellUtil::kRegShellOpen, ShellUtil::kRegDelegateExecute,
301 app_info.delegate_clsid));
302 // TODO(scottmg): Simplify after Metro removal. https://crbug.com/558054.
303 entries->back()->set_removal_flag(RegistryEntry::RemovalFlag::VALUE);
304 }
305
306 // The following entries are required as of Windows 8, but do not
307 // depend on the DelegateExecute verb handler being set.
308 if (base::win::GetVersion() >= base::win::VERSION_WIN8) {
309 if (!app_info.app_id.empty()) {
310 entries->push_back(new RegistryEntry(
311 prog_id_path, ShellUtil::kRegAppUserModelId, app_info.app_id));
312 }
313
314 // Add \Software\Classes\<prog_id>\Application entries
315 base::string16 application_path(prog_id_path + ShellUtil::kRegApplication);
316 if (!app_info.app_id.empty()) {
317 entries->push_back(new RegistryEntry(
318 application_path, ShellUtil::kRegAppUserModelId, app_info.app_id));
319 }
320 if (!app_info.application_icon_path.empty()) {
321 entries->push_back(new RegistryEntry(
322 application_path, ShellUtil::kRegApplicationIcon,
323 ShellUtil::FormatIconLocation(app_info.application_icon_path,
324 app_info.application_icon_index)));
325 }
326 if (!app_info.application_name.empty()) {
327 entries->push_back(new RegistryEntry(application_path,
328 ShellUtil::kRegApplicationName,
329 app_info.application_name));
330 }
331 if (!app_info.application_description.empty()) {
332 entries->push_back(new RegistryEntry(
333 application_path, ShellUtil::kRegApplicationDescription,
334 app_info.application_description));
335 }
336 if (!app_info.publisher_name.empty()) {
337 entries->push_back(new RegistryEntry(application_path,
338 ShellUtil::kRegApplicationCompany,
339 app_info.publisher_name));
340 }
341 }
342 }
343
344 // This method returns a list of all the registry entries that are needed to
345 // register this installation's ProgId and AppId. These entries need to be
346 // registered in HKLM prior to Win8.
347 void GetChromeProgIdEntries(BrowserDistribution* dist,
348 const base::FilePath& chrome_exe,
349 const base::string16& suffix,
350 ScopedVector<RegistryEntry>* entries) {
351 int chrome_icon_index =
352 dist->GetIconIndex(BrowserDistribution::SHORTCUT_CHROME);
353
354 ApplicationInfo app_info;
355 app_info.prog_id = GetBrowserProgId(suffix);
356 app_info.file_type_name = dist->GetBrowserProgIdDesc();
357 // File types associated with Chrome are just given the Chrome icon.
358 app_info.file_type_icon_path = chrome_exe;
359 app_info.file_type_icon_index = chrome_icon_index;
360 app_info.command_line = ShellUtil::GetChromeShellOpenCmd(chrome_exe);
361 // For user-level installs: entries for the app id will be in HKCU; thus we
362 // do not need a suffix on those entries.
363 app_info.app_id = ShellUtil::GetBrowserModelId(
364 dist, InstallUtil::IsPerUserInstall(chrome_exe));
365
366 // TODO(grt): http://crbug.com/75152 Write a reference to a localized
367 // resource for name, description, and company.
368 app_info.application_name = dist->GetDisplayName();
369 app_info.application_icon_path = chrome_exe;
370 app_info.application_icon_index = chrome_icon_index;
371 app_info.application_description = dist->GetAppDescription();
372 app_info.publisher_name = dist->GetPublisherName();
373
374 app_info.delegate_clsid = dist->GetCommandExecuteImplClsid();
375
376 GetProgIdEntries(app_info, entries);
377
378 if (!app_info.delegate_clsid.empty()) {
379 ScopedVector<RegistryEntry> delegate_execute_entries =
380 GetChromeDelegateExecuteEntries(chrome_exe, app_info);
381 // Remove the keys (not only their values) so that Windows will continue
382 // to launch Chrome without a pesky association error.
383 // TODO(scottmg): Simplify after Metro removal. https://crbug.com/558054.
384 for (RegistryEntry* entry : delegate_execute_entries)
385 entry->set_removal_flag(RegistryEntry::RemovalFlag::KEY);
386 // Move |delegate_execute_entries| to |entries|.
387 entries->insert(entries->end(), delegate_execute_entries.begin(),
388 delegate_execute_entries.end());
389 delegate_execute_entries.weak_clear();
390 }
391 }
392
393 // This method returns a list of the registry entries needed to declare a
394 // capability of handling a protocol on Windows.
395 void GetProtocolCapabilityEntries(BrowserDistribution* dist,
396 const base::string16& suffix,
397 const base::string16& protocol,
398 ScopedVector<RegistryEntry>* entries) {
399 entries->push_back(new RegistryEntry(
400 GetCapabilitiesKey(dist, suffix).append(L"\\URLAssociations"), protocol,
401 GetBrowserProgId(suffix)));
402 }
403
404 // This method returns a list of the registry entries required to register this
405 // installation in "RegisteredApplications" on Windows (to appear in Default
406 // Programs, StartMenuInternet, etc.). These entries need to be registered in
407 // HKLM prior to Win8. If |suffix| is not empty, these entries are guaranteed to
408 // be unique on this machine.
409 void GetShellIntegrationEntries(BrowserDistribution* dist,
410 const base::FilePath& chrome_exe,
411 const base::string16& suffix,
412 ScopedVector<RegistryEntry>* entries) {
413 const base::string16 icon_path(ShellUtil::FormatIconLocation(
414 chrome_exe, dist->GetIconIndex(BrowserDistribution::SHORTCUT_CHROME)));
415 const base::string16 quoted_exe_path(L"\"" + chrome_exe.value() + L"\"");
416
417 // Register for the Start Menu "Internet" link (pre-Win7).
418 const base::string16 start_menu_entry(GetBrowserClientKey(dist, suffix));
419 // Register Chrome's display name.
420 // TODO(grt): http://crbug.com/75152 Also set LocalizedString; see
421 // http://msdn.microsoft.com/en-us/library/windows/desktop/cc144109(v=VS.85).a spx#registering_the_display_name
422 entries->push_back(
423 new RegistryEntry(start_menu_entry, dist->GetDisplayName()));
424 // Register the "open" verb for launching Chrome via the "Internet" link.
425 entries->push_back(new RegistryEntry(
426 start_menu_entry + ShellUtil::kRegShellOpen, quoted_exe_path));
427 // Register Chrome's icon for the Start Menu "Internet" link.
428 entries->push_back(new RegistryEntry(
429 start_menu_entry + ShellUtil::kRegDefaultIcon, icon_path));
430
431 // Register installation information.
432 base::string16 install_info(start_menu_entry + L"\\InstallInfo");
433 // Note: not using CommandLine since it has ambiguous rules for quoting
434 // strings.
435 entries->push_back(
436 new RegistryEntry(install_info, kReinstallCommand,
437 quoted_exe_path + L" --" +
438 base::ASCIIToUTF16(switches::kMakeDefaultBrowser)));
439 entries->push_back(new RegistryEntry(
440 install_info, L"HideIconsCommand",
441 quoted_exe_path + L" --" + base::ASCIIToUTF16(switches::kHideIcons)));
442 entries->push_back(new RegistryEntry(
443 install_info, L"ShowIconsCommand",
444 quoted_exe_path + L" --" + base::ASCIIToUTF16(switches::kShowIcons)));
445 entries->push_back(new RegistryEntry(install_info, L"IconsVisible", 1));
446
447 // Register with Default Programs.
448 const base::string16 reg_app_name(dist->GetBaseAppName().append(suffix));
449 // Tell Windows where to find Chrome's Default Programs info.
450 const base::string16 capabilities(GetCapabilitiesKey(dist, suffix));
451 entries->push_back(new RegistryEntry(ShellUtil::kRegRegisteredApplications,
452 reg_app_name, capabilities));
453 // Write out Chrome's Default Programs info.
454 // TODO(grt): http://crbug.com/75152 Write a reference to a localized
455 // resource rather than this.
456 entries->push_back(new RegistryEntry(capabilities,
457 ShellUtil::kRegApplicationDescription,
458 dist->GetLongAppDescription()));
459 entries->push_back(new RegistryEntry(
460 capabilities, ShellUtil::kRegApplicationIcon, icon_path));
461 entries->push_back(new RegistryEntry(
462 capabilities, ShellUtil::kRegApplicationName, dist->GetDisplayName()));
463
464 entries->push_back(new RegistryEntry(capabilities + L"\\Startmenu",
465 L"StartMenuInternet", reg_app_name));
466
467 const base::string16 html_prog_id(GetBrowserProgId(suffix));
468 for (int i = 0; ShellUtil::kPotentialFileAssociations[i] != NULL; i++) {
469 entries->push_back(new RegistryEntry(
470 capabilities + L"\\FileAssociations",
471 ShellUtil::kPotentialFileAssociations[i], html_prog_id));
472 }
473 for (int i = 0; ShellUtil::kPotentialProtocolAssociations[i] != NULL; i++) {
474 entries->push_back(new RegistryEntry(
475 capabilities + L"\\URLAssociations",
476 ShellUtil::kPotentialProtocolAssociations[i], html_prog_id));
477 }
478 }
479
480 // Gets the registry entries to register an application as a handler for a
481 // particular file extension. |prog_id| is the ProgId used by Windows for the
482 // application. |ext| is the file extension, which must begin with a '.'.
483 void GetAppExtRegistrationEntries(const base::string16& prog_id,
484 const base::string16& ext,
485 ScopedVector<RegistryEntry>* entries) {
486 // In HKEY_CURRENT_USER\Software\Classes\EXT\OpenWithProgids, create an
487 // empty value with this class's ProgId.
488 base::string16 key_name(ShellUtil::kRegClasses);
489 key_name.push_back(base::FilePath::kSeparators[0]);
490 key_name.append(ext);
491 key_name.push_back(base::FilePath::kSeparators[0]);
492 key_name.append(ShellUtil::kRegOpenWithProgids);
493 entries->push_back(new RegistryEntry(key_name, prog_id, base::string16()));
494 }
495
496 // This method returns a list of the registry entries required for this
497 // installation to be registered in the Windows shell.
498 // In particular:
499 // - App Paths
500 // http://msdn.microsoft.com/en-us/library/windows/desktop/ee872121
501 // - File Associations
502 // http://msdn.microsoft.com/en-us/library/bb166549
503 // These entries need to be registered in HKLM prior to Win8.
504 void GetChromeAppRegistrationEntries(const base::FilePath& chrome_exe,
505 const base::string16& suffix,
506 ScopedVector<RegistryEntry>* entries) {
507 base::string16 app_path_key(ShellUtil::kAppPathsRegistryKey);
508 app_path_key.push_back(base::FilePath::kSeparators[0]);
509 app_path_key.append(chrome_exe.BaseName().value());
510 entries->push_back(new RegistryEntry(app_path_key, chrome_exe.value()));
511 entries->push_back(new RegistryEntry(app_path_key,
512 ShellUtil::kAppPathsRegistryPathName,
513 chrome_exe.DirName().value()));
514
515 const base::string16 html_prog_id(GetBrowserProgId(suffix));
516 for (int i = 0; ShellUtil::kPotentialFileAssociations[i] != NULL; i++) {
517 GetAppExtRegistrationEntries(
518 html_prog_id, ShellUtil::kPotentialFileAssociations[i], entries);
519 }
520 }
521
522 // Gets the registry entries to register an application as the default handler
523 // for a particular file extension. |prog_id| is the ProgId used by Windows for
524 // the application. |ext| is the file extension, which must begin with a '.'. If
525 // |overwrite_existing|, always sets the default handler; otherwise only sets if
526 // there is no existing default.
527 //
528 // This has no effect on Windows 8. Windows 8 ignores the default and lets the
529 // user choose. If there is only one handler for a file, it will automatically
530 // become the default. Otherwise, the first time the user opens a file, they are
531 // presented with the dialog to set the default handler. (This is roughly
532 // equivalent to being called with |overwrite_existing| false.)
533 void GetAppDefaultRegistrationEntries(const base::string16& prog_id,
534 const base::string16& ext,
535 bool overwrite_existing,
536 ScopedVector<RegistryEntry>* entries) {
537 // Set the default value of HKEY_CURRENT_USER\Software\Classes\EXT to this
538 // class's name.
539 base::string16 key_name(ShellUtil::kRegClasses);
540 key_name.push_back(base::FilePath::kSeparators[0]);
541 key_name.append(ext);
542 scoped_ptr<RegistryEntry> default_association(
543 new RegistryEntry(key_name, prog_id));
544 if (overwrite_existing ||
545 !default_association->KeyExistsInRegistry(RegistryEntry::LOOK_IN_HKCU)) {
546 entries->push_back(default_association.release());
547 }
548 }
549
550 // This method returns a list of all the user level registry entries that are
551 // needed to make Chromium the default handler for a protocol on XP.
552 void GetXPStyleUserProtocolEntries(const base::string16& protocol,
553 const base::string16& chrome_icon,
554 const base::string16& chrome_open,
555 ScopedVector<RegistryEntry>* entries) {
556 // Protocols associations.
557 base::string16 url_key(ShellUtil::kRegClasses);
558 url_key.push_back(base::FilePath::kSeparators[0]);
559 url_key.append(protocol);
560
561 // This registry value tells Windows that this 'class' is a URL scheme
562 // so IE, explorer and other apps will route it to our handler.
563 // <root hkey>\Software\Classes\<protocol>\URL Protocol
564 entries->push_back(
565 new RegistryEntry(url_key, ShellUtil::kRegUrlProtocol, base::string16()));
566
567 // <root hkey>\Software\Classes\<protocol>\DefaultIcon
568 base::string16 icon_key = url_key + ShellUtil::kRegDefaultIcon;
569 entries->push_back(new RegistryEntry(icon_key, chrome_icon));
570
571 // <root hkey>\Software\Classes\<protocol>\shell\open\command
572 base::string16 shell_key = url_key + ShellUtil::kRegShellOpen;
573 entries->push_back(new RegistryEntry(shell_key, chrome_open));
574
575 // <root hkey>\Software\Classes\<protocol>\shell\open\ddeexec
576 base::string16 dde_key = url_key + L"\\shell\\open\\ddeexec";
577 entries->push_back(new RegistryEntry(dde_key, base::string16()));
578
579 // <root hkey>\Software\Classes\<protocol>\shell\@
580 base::string16 protocol_shell_key = url_key + ShellUtil::kRegShellPath;
581 entries->push_back(new RegistryEntry(protocol_shell_key, L"open"));
582 }
583
584 // This method returns a list of all the user level registry entries that are
585 // needed to make Chromium default browser on XP. Some of these entries are
586 // irrelevant in recent versions of Windows, but we register them anyways as
587 // some legacy apps are hardcoded to lookup those values.
588 void GetXPStyleDefaultBrowserUserEntries(BrowserDistribution* dist,
589 const base::FilePath& chrome_exe,
590 const base::string16& suffix,
591 ScopedVector<RegistryEntry>* entries) {
592 // File extension associations.
593 base::string16 html_prog_id(GetBrowserProgId(suffix));
594 for (int i = 0; ShellUtil::kDefaultFileAssociations[i] != NULL; i++) {
595 GetAppDefaultRegistrationEntries(
596 html_prog_id, ShellUtil::kDefaultFileAssociations[i], true, entries);
597 }
598
599 // Protocols associations.
600 base::string16 chrome_open = ShellUtil::GetChromeShellOpenCmd(chrome_exe);
601 base::string16 chrome_icon = ShellUtil::FormatIconLocation(
602 chrome_exe, dist->GetIconIndex(BrowserDistribution::SHORTCUT_CHROME));
603 for (int i = 0; ShellUtil::kBrowserProtocolAssociations[i] != NULL; i++) {
604 GetXPStyleUserProtocolEntries(ShellUtil::kBrowserProtocolAssociations[i],
605 chrome_icon, chrome_open, entries);
606 }
607
608 // start->Internet shortcut.
609 base::string16 start_menu(ShellUtil::kRegStartMenuInternet);
610 base::string16 app_name = dist->GetBaseAppName() + suffix;
611 entries->push_back(new RegistryEntry(start_menu, app_name));
612 }
613
614 // Checks that all |entries| are present on this computer (or absent if their 137 // Checks that all |entries| are present on this computer (or absent if their
615 // |removal_flag_| is set). |look_for_in| is passed to 138 // |removal_flag_| is set). |look_for_in| is passed to
616 // RegistryEntry::ExistsInRegistry(). Documentation for it can be found there. 139 // RegistryEntry::ExistsInRegistry(). Documentation for it can be found there.
617 bool AreEntriesAsDesired(const ScopedVector<RegistryEntry>& entries, 140 bool AreEntriesAsDesired(const ScopedVector<RegistryEntry>& entries,
618 uint32_t look_for_in) { 141 uint32_t look_for_in) {
619 for (const auto* entry : entries) { 142 for (const auto* entry : entries) {
620 if (entry->ExistsInRegistry(look_for_in) != !entry->IsFlaggedForRemoval()) 143 if (entry->ExistsInRegistry(look_for_in) != !entry->IsFlaggedForRemoval())
621 return false; 144 return false;
622 } 145 }
623 return true; 146 return true;
624 } 147 }
625 148
626 // Checks that all required registry entries for Chrome are already present on 149 // Checks that all required registry entries for Chrome are already present on
627 // this computer (or absent if their |removal_flag_| is set). 150 // this computer (or absent if their |removal_flag_| is set).
628 // See RegistryEntry::ExistsInRegistry for the behavior of |look_for_in|. 151 // See RegistryEntry::ExistsInRegistry for the behavior of |look_for_in|.
629 // Note: between r133333 and r154145 we were registering parts of Chrome in HKCU 152 // Note: between r133333 and r154145 we were registering parts of Chrome in HKCU
630 // and parts in HKLM for user-level installs; we now always register everything 153 // and parts in HKLM for user-level installs; we now always register everything
631 // under a single registry root. Not doing so caused http://crbug.com/144910 for 154 // under a single registry root. Not doing so caused http://crbug.com/144910 for
632 // users who first-installed Chrome in that revision range (those users are 155 // users who first-installed Chrome in that revision range (those users are
633 // still impacted by http://crbug.com/144910). This method will keep returning 156 // still impacted by http://crbug.com/144910). This method will keep returning
634 // true for affected users (i.e. who have all the registrations, but over both 157 // true for affected users (i.e. who have all the registrations, but over both
635 // registry roots). 158 // registry roots).
636 bool IsChromeRegistered(BrowserDistribution* dist, 159 bool IsChromeRegistered(BrowserDistribution* dist,
637 const base::FilePath& chrome_exe, 160 const base::FilePath& chrome_exe,
638 const base::string16& suffix, 161 const base::string16& suffix,
639 uint32_t look_for_in) { 162 uint32_t look_for_in) {
640 ScopedVector<RegistryEntry> entries; 163 ScopedVector<RegistryEntry> entries;
641 GetChromeProgIdEntries(dist, chrome_exe, suffix, &entries); 164 installer_util::GetChromeProgIdEntries(dist, chrome_exe, suffix, &entries);
642 GetShellIntegrationEntries(dist, chrome_exe, suffix, &entries); 165 installer_util::GetShellIntegrationEntries(dist, chrome_exe, suffix,
643 GetChromeAppRegistrationEntries(chrome_exe, suffix, &entries); 166 &entries);
167 installer_util::GetChromeAppRegistrationEntries(chrome_exe, suffix, &entries);
644 return AreEntriesAsDesired(entries, look_for_in); 168 return AreEntriesAsDesired(entries, look_for_in);
645 } 169 }
646 170
647 // This method checks if Chrome is already registered on the local machine 171 // This method checks if Chrome is already registered on the local machine
648 // for the requested protocol. It just checks the one value required for this. 172 // for the requested protocol. It just checks the one value required for this.
649 // See RegistryEntry::ExistsInRegistry for the behavior of |look_for_in|. 173 // See RegistryEntry::ExistsInRegistry for the behavior of |look_for_in|.
650 bool IsChromeRegisteredForProtocol(BrowserDistribution* dist, 174 bool IsChromeRegisteredForProtocol(BrowserDistribution* dist,
651 const base::string16& suffix, 175 const base::string16& suffix,
652 const base::string16& protocol, 176 const base::string16& protocol,
653 uint32_t look_for_in) { 177 uint32_t look_for_in) {
654 ScopedVector<RegistryEntry> entries; 178 ScopedVector<RegistryEntry> entries;
655 GetProtocolCapabilityEntries(dist, suffix, protocol, &entries); 179 installer_util::GetProtocolCapabilityEntries(dist, suffix, protocol,
180 &entries);
656 return AreEntriesAsDesired(entries, look_for_in); 181 return AreEntriesAsDesired(entries, look_for_in);
657 } 182 }
658 183
659 // This method registers Chrome on Vista by launching an elevated setup.exe. 184 // This method registers Chrome on Vista by launching an elevated setup.exe.
660 // That will show the user the standard Vista elevation prompt. If the user 185 // That will show the user the standard Vista elevation prompt. If the user
661 // accepts it the new process will make the necessary changes and return SUCCESS 186 // accepts it the new process will make the necessary changes and return SUCCESS
662 // that we capture and return. 187 // that we capture and return.
663 // If protocol is non-empty we will also register Chrome as being capable of 188 // If protocol is non-empty we will also register Chrome as being capable of
664 // handling the protocol. 189 // handling the protocol.
665 bool ElevateAndRegisterChrome(BrowserDistribution* dist, 190 bool ElevateAndRegisterChrome(BrowserDistribution* dist,
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
766 case CONFIRM_PROGID_REGISTRATION: 291 case CONFIRM_PROGID_REGISTRATION:
767 // Software\Classes\ChromeHTML|suffix| 292 // Software\Classes\ChromeHTML|suffix|
768 reg_key = ShellUtil::kRegClasses; 293 reg_key = ShellUtil::kRegClasses;
769 reg_key.push_back(base::FilePath::kSeparators[0]); 294 reg_key.push_back(base::FilePath::kSeparators[0]);
770 reg_key.append(dist->GetBrowserProgIdPrefix()); 295 reg_key.append(dist->GetBrowserProgIdPrefix());
771 reg_key.append(suffix); 296 reg_key.append(suffix);
772 break; 297 break;
773 case CONFIRM_SHELL_REGISTRATION: 298 case CONFIRM_SHELL_REGISTRATION:
774 case CONFIRM_SHELL_REGISTRATION_IN_HKLM: 299 case CONFIRM_SHELL_REGISTRATION_IN_HKLM:
775 // Software\Clients\StartMenuInternet\Google Chrome|suffix| 300 // Software\Clients\StartMenuInternet\Google Chrome|suffix|
776 reg_key = GetBrowserClientKey(dist, suffix); 301 reg_key = installer_util::GetBrowserClientKey(dist, suffix);
777 break; 302 break;
778 default: 303 default:
779 NOTREACHED(); 304 NOTREACHED();
780 break; 305 break;
781 } 306 }
782 reg_key.append(ShellUtil::kRegShellOpen); 307 reg_key.append(ShellUtil::kRegShellOpen);
783 308
784 // ProgId registrations are allowed to reside in HKCU for user-level installs 309 // ProgId registrations are allowed to reside in HKCU for user-level installs
785 // (and values there have priority over values in HKLM). The same is true for 310 // (and values there have priority over values in HKLM). The same is true for
786 // shell integration entries as of Windows 8. 311 // shell integration entries as of Windows 8.
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
848 } 373 }
849 374
850 // Associates Chrome with supported protocols and file associations. This should 375 // Associates Chrome with supported protocols and file associations. This should
851 // not be required on Vista+ but since some applications still read 376 // not be required on Vista+ but since some applications still read
852 // Software\Classes\http key directly, we have to do this on Vista+ as well. 377 // Software\Classes\http key directly, we have to do this on Vista+ as well.
853 bool RegisterChromeAsDefaultXPStyle(BrowserDistribution* dist, 378 bool RegisterChromeAsDefaultXPStyle(BrowserDistribution* dist,
854 int shell_change, 379 int shell_change,
855 const base::FilePath& chrome_exe) { 380 const base::FilePath& chrome_exe) {
856 bool ret = true; 381 bool ret = true;
857 ScopedVector<RegistryEntry> entries; 382 ScopedVector<RegistryEntry> entries;
858 GetXPStyleDefaultBrowserUserEntries( 383 installer_util::GetXPStyleDefaultBrowserUserEntries(
859 dist, chrome_exe, 384 dist, chrome_exe,
860 ShellUtil::GetCurrentInstallationSuffix(dist, chrome_exe), &entries); 385 ShellUtil::GetCurrentInstallationSuffix(dist, chrome_exe), &entries);
861 386
862 // Change the default browser for current user. 387 // Change the default browser for current user.
863 if ((shell_change & ShellUtil::CURRENT_USER) && 388 if ((shell_change & ShellUtil::CURRENT_USER) &&
864 !ShellUtil::AddRegistryEntries(HKEY_CURRENT_USER, entries)) { 389 !ShellUtil::AddRegistryEntries(HKEY_CURRENT_USER, entries)) {
865 ret = false; 390 ret = false;
866 LOG(ERROR) << "Could not make Chrome default browser (XP/current user)."; 391 LOG(ERROR) << "Could not make Chrome default browser (XP/current user).";
867 } 392 }
868 393
(...skipping 15 matching lines...) Expand all
884 BrowserDistribution* dist, 409 BrowserDistribution* dist,
885 const base::FilePath& chrome_exe, 410 const base::FilePath& chrome_exe,
886 const base::string16& protocol) { 411 const base::string16& protocol) {
887 ScopedVector<RegistryEntry> entries; 412 ScopedVector<RegistryEntry> entries;
888 const base::string16 chrome_open( 413 const base::string16 chrome_open(
889 ShellUtil::GetChromeShellOpenCmd(chrome_exe)); 414 ShellUtil::GetChromeShellOpenCmd(chrome_exe));
890 const base::string16 chrome_icon( 415 const base::string16 chrome_icon(
891 ShellUtil::FormatIconLocation( 416 ShellUtil::FormatIconLocation(
892 chrome_exe, 417 chrome_exe,
893 dist->GetIconIndex(BrowserDistribution::SHORTCUT_CHROME))); 418 dist->GetIconIndex(BrowserDistribution::SHORTCUT_CHROME)));
894 GetXPStyleUserProtocolEntries(protocol, chrome_icon, chrome_open, &entries); 419 installer_util::GetXPStyleUserProtocolEntries(protocol, chrome_icon,
420 chrome_open, &entries);
895 // Change the default protocol handler for current user. 421 // Change the default protocol handler for current user.
896 if (!ShellUtil::AddRegistryEntries(HKEY_CURRENT_USER, entries)) { 422 if (!ShellUtil::AddRegistryEntries(HKEY_CURRENT_USER, entries)) {
897 LOG(ERROR) << "Could not make Chrome default protocol client (XP)."; 423 LOG(ERROR) << "Could not make Chrome default protocol client (XP).";
898 return false; 424 return false;
899 } 425 }
900 426
901 return true; 427 return true;
902 } 428 }
903 429
904 // Returns |properties.shortcut_name| if the property is set, otherwise it 430 // Returns |properties.shortcut_name| if the property is set, otherwise it
(...skipping 720 matching lines...) Expand 10 before | Expand all | Expand 10 after
1625 if (key.Open(root, client_path.c_str(), 1151 if (key.Open(root, client_path.c_str(),
1626 KEY_QUERY_VALUE) != ERROR_SUCCESS || 1152 KEY_QUERY_VALUE) != ERROR_SUCCESS ||
1627 key.ReadValue(NULL, &name) != ERROR_SUCCESS || 1153 key.ReadValue(NULL, &name) != ERROR_SUCCESS ||
1628 name.empty() || 1154 name.empty() ||
1629 name.find(dist->GetBaseAppName()) != base::string16::npos) { 1155 name.find(dist->GetBaseAppName()) != base::string16::npos) {
1630 continue; 1156 continue;
1631 } 1157 }
1632 // Read the browser's reinstall command. 1158 // Read the browser's reinstall command.
1633 if (key.Open(root, (client_path + L"\\InstallInfo").c_str(), 1159 if (key.Open(root, (client_path + L"\\InstallInfo").c_str(),
1634 KEY_QUERY_VALUE) == ERROR_SUCCESS && 1160 KEY_QUERY_VALUE) == ERROR_SUCCESS &&
1635 key.ReadValue(kReinstallCommand, &command) == ERROR_SUCCESS && 1161 key.ReadValue(installer_util::kReinstallCommand, &command) ==
1162 ERROR_SUCCESS &&
1636 !command.empty()) { 1163 !command.empty()) {
1637 (*browsers)[name] = command; 1164 (*browsers)[name] = command;
1638 } 1165 }
1639 } 1166 }
1640 } 1167 }
1641 } 1168 }
1642 1169
1643 base::string16 ShellUtil::GetCurrentInstallationSuffix( 1170 base::string16 ShellUtil::GetCurrentInstallationSuffix(
1644 BrowserDistribution* dist, 1171 BrowserDistribution* dist,
1645 const base::FilePath& chrome_exe) { 1172 const base::FilePath& chrome_exe) {
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after
2032 // Check if chrome is already registered with this suffix. 1559 // Check if chrome is already registered with this suffix.
2033 if (IsChromeRegistered(dist, chrome_exe, suffix, look_for_in)) 1560 if (IsChromeRegistered(dist, chrome_exe, suffix, look_for_in))
2034 return true; 1561 return true;
2035 1562
2036 bool result = true; 1563 bool result = true;
2037 if (root == HKEY_CURRENT_USER || IsUserAnAdmin()) { 1564 if (root == HKEY_CURRENT_USER || IsUserAnAdmin()) {
2038 // Do the full registration if we can do it at user-level or if the user is 1565 // Do the full registration if we can do it at user-level or if the user is
2039 // an admin. 1566 // an admin.
2040 ScopedVector<RegistryEntry> progid_and_appreg_entries; 1567 ScopedVector<RegistryEntry> progid_and_appreg_entries;
2041 ScopedVector<RegistryEntry> shell_entries; 1568 ScopedVector<RegistryEntry> shell_entries;
2042 GetChromeProgIdEntries(dist, chrome_exe, suffix, 1569 installer_util::GetChromeProgIdEntries(dist, chrome_exe, suffix,
2043 &progid_and_appreg_entries); 1570 &progid_and_appreg_entries);
2044 GetChromeAppRegistrationEntries(chrome_exe, suffix, 1571 installer_util::GetChromeAppRegistrationEntries(chrome_exe, suffix,
2045 &progid_and_appreg_entries); 1572 &progid_and_appreg_entries);
2046 GetShellIntegrationEntries(dist, chrome_exe, suffix, &shell_entries); 1573 installer_util::GetShellIntegrationEntries(dist, chrome_exe, suffix,
1574 &shell_entries);
2047 result = (AddRegistryEntries(root, progid_and_appreg_entries) && 1575 result = (AddRegistryEntries(root, progid_and_appreg_entries) &&
2048 AddRegistryEntries(root, shell_entries)); 1576 AddRegistryEntries(root, shell_entries));
2049 } else if (elevate_if_not_admin && 1577 } else if (elevate_if_not_admin &&
2050 base::win::GetVersion() >= base::win::VERSION_VISTA && 1578 base::win::GetVersion() >= base::win::VERSION_VISTA &&
2051 ElevateAndRegisterChrome(dist, chrome_exe, suffix, base::string16())) { 1579 ElevateAndRegisterChrome(dist, chrome_exe, suffix, base::string16())) {
2052 // If the user is not an admin and OS is between Vista and Windows 7 1580 // If the user is not an admin and OS is between Vista and Windows 7
2053 // inclusively, try to elevate and register. This is only intended for 1581 // inclusively, try to elevate and register. This is only intended for
2054 // user-level installs as system-level installs should always be run with 1582 // user-level installs as system-level installs should always be run with
2055 // admin rights. 1583 // admin rights.
2056 result = true; 1584 result = true;
2057 } else { 1585 } else {
2058 // If we got to this point then all we can do is create ProgId and basic app 1586 // If we got to this point then all we can do is create ProgId and basic app
2059 // registrations under HKCU. 1587 // registrations under HKCU.
2060 ScopedVector<RegistryEntry> entries; 1588 ScopedVector<RegistryEntry> entries;
2061 GetChromeProgIdEntries(dist, chrome_exe, base::string16(), &entries); 1589 installer_util::GetChromeProgIdEntries(dist, chrome_exe, base::string16(),
1590 &entries);
2062 // Prefer to use |suffix|; unless Chrome's ProgIds are already registered 1591 // Prefer to use |suffix|; unless Chrome's ProgIds are already registered
2063 // with no suffix (as per the old registration style): in which case some 1592 // with no suffix (as per the old registration style): in which case some
2064 // other registry entries could refer to them and since we were not able to 1593 // other registry entries could refer to them and since we were not able to
2065 // set our HKLM entries above, we are better off not altering these here. 1594 // set our HKLM entries above, we are better off not altering these here.
2066 if (!AreEntriesAsDesired(entries, RegistryEntry::LOOK_IN_HKCU)) { 1595 if (!AreEntriesAsDesired(entries, RegistryEntry::LOOK_IN_HKCU)) {
2067 if (!suffix.empty()) { 1596 if (!suffix.empty()) {
2068 entries.clear(); 1597 entries.clear();
2069 GetChromeProgIdEntries(dist, chrome_exe, suffix, &entries); 1598 installer_util::GetChromeProgIdEntries(dist, chrome_exe, suffix,
2070 GetChromeAppRegistrationEntries(chrome_exe, suffix, &entries); 1599 &entries);
1600 installer_util::GetChromeAppRegistrationEntries(chrome_exe, suffix,
1601 &entries);
2071 } 1602 }
2072 result = AddRegistryEntries(HKEY_CURRENT_USER, entries); 1603 result = AddRegistryEntries(HKEY_CURRENT_USER, entries);
2073 } else { 1604 } else {
2074 // The ProgId is registered unsuffixed in HKCU, also register the app with 1605 // The ProgId is registered unsuffixed in HKCU, also register the app with
2075 // Windows in HKCU (this was not done in the old registration style and 1606 // Windows in HKCU (this was not done in the old registration style and
2076 // thus needs to be done after the above check for the unsuffixed 1607 // thus needs to be done after the above check for the unsuffixed
2077 // registration). 1608 // registration).
2078 entries.clear(); 1609 entries.clear();
2079 GetChromeAppRegistrationEntries(chrome_exe, base::string16(), &entries); 1610 installer_util::GetChromeAppRegistrationEntries(
1611 chrome_exe, base::string16(), &entries);
2080 result = AddRegistryEntries(HKEY_CURRENT_USER, entries); 1612 result = AddRegistryEntries(HKEY_CURRENT_USER, entries);
2081 } 1613 }
2082 } 1614 }
2083 SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL); 1615 SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL);
2084 return result; 1616 return result;
2085 } 1617 }
2086 1618
2087 bool ShellUtil::RegisterChromeForProtocol(BrowserDistribution* dist, 1619 bool ShellUtil::RegisterChromeForProtocol(BrowserDistribution* dist,
2088 const base::FilePath& chrome_exe, 1620 const base::FilePath& chrome_exe,
2089 const base::string16& unique_suffix, 1621 const base::string16& unique_suffix,
(...skipping 26 matching lines...) Expand all
2116 return true; 1648 return true;
2117 1649
2118 if (root == HKEY_CURRENT_USER || IsUserAnAdmin()) { 1650 if (root == HKEY_CURRENT_USER || IsUserAnAdmin()) {
2119 // We can do this operation directly. 1651 // We can do this operation directly.
2120 // First, make sure Chrome is fully registered on this machine. 1652 // First, make sure Chrome is fully registered on this machine.
2121 if (!RegisterChromeBrowser(dist, chrome_exe, suffix, false)) 1653 if (!RegisterChromeBrowser(dist, chrome_exe, suffix, false))
2122 return false; 1654 return false;
2123 1655
2124 // Write in the capabillity for the protocol. 1656 // Write in the capabillity for the protocol.
2125 ScopedVector<RegistryEntry> entries; 1657 ScopedVector<RegistryEntry> entries;
2126 GetProtocolCapabilityEntries(dist, suffix, protocol, &entries); 1658 installer_util::GetProtocolCapabilityEntries(dist, suffix, protocol,
1659 &entries);
2127 return AddRegistryEntries(root, entries); 1660 return AddRegistryEntries(root, entries);
2128 } else if (elevate_if_not_admin && 1661 } else if (elevate_if_not_admin &&
2129 base::win::GetVersion() >= base::win::VERSION_VISTA) { 1662 base::win::GetVersion() >= base::win::VERSION_VISTA) {
2130 // Elevate to do the whole job 1663 // Elevate to do the whole job
2131 return ElevateAndRegisterChrome(dist, chrome_exe, suffix, protocol); 1664 return ElevateAndRegisterChrome(dist, chrome_exe, suffix, protocol);
2132 } else { 1665 } else {
2133 // Admin rights are required to register capabilities before Windows 8. 1666 // Admin rights are required to register capabilities before Windows 8.
2134 return false; 1667 return false;
2135 } 1668 }
2136 } 1669 }
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
2269 // static 1802 // static
2270 bool ShellUtil::AddFileAssociations( 1803 bool ShellUtil::AddFileAssociations(
2271 const base::string16& prog_id, 1804 const base::string16& prog_id,
2272 const base::CommandLine& command_line, 1805 const base::CommandLine& command_line,
2273 const base::string16& file_type_name, 1806 const base::string16& file_type_name,
2274 const base::FilePath& icon_path, 1807 const base::FilePath& icon_path,
2275 const std::set<base::string16>& file_extensions) { 1808 const std::set<base::string16>& file_extensions) {
2276 ScopedVector<RegistryEntry> entries; 1809 ScopedVector<RegistryEntry> entries;
2277 1810
2278 // Create a class for this app. 1811 // Create a class for this app.
2279 ApplicationInfo app_info; 1812 installer_util::ApplicationInfo app_info;
2280 app_info.prog_id = prog_id; 1813 app_info.prog_id = prog_id;
2281 app_info.file_type_name = file_type_name; 1814 app_info.file_type_name = file_type_name;
2282 app_info.file_type_icon_path = icon_path; 1815 app_info.file_type_icon_path = icon_path;
2283 app_info.file_type_icon_index = 0; 1816 app_info.file_type_icon_index = 0;
2284 app_info.command_line = command_line.GetCommandLineStringWithPlaceholders(); 1817 app_info.command_line = command_line.GetCommandLineStringWithPlaceholders();
2285 GetProgIdEntries(app_info, &entries); 1818 installer_util::GetProgIdEntries(app_info, &entries);
2286 1819
2287 // Associate each extension that the app can handle with the class. Set this 1820 // Associate each extension that the app can handle with the class. Set this
2288 // app as the default handler if and only if there is no existing default. 1821 // app as the default handler if and only if there is no existing default.
2289 for (std::set<base::string16>::const_iterator it = file_extensions.begin(); 1822 for (std::set<base::string16>::const_iterator it = file_extensions.begin();
2290 it != file_extensions.end(); 1823 it != file_extensions.end();
2291 ++it) { 1824 ++it) {
2292 // Do not allow empty file extensions, or extensions beginning with a '.'. 1825 // Do not allow empty file extensions, or extensions beginning with a '.'.
2293 DCHECK(!it->empty()); 1826 DCHECK(!it->empty());
2294 DCHECK_NE(L'.', (*it)[0]); 1827 DCHECK_NE(L'.', (*it)[0]);
2295 base::string16 ext(1, L'.'); 1828 base::string16 ext(1, L'.');
2296 ext.append(*it); 1829 ext.append(*it);
2297 GetAppExtRegistrationEntries(prog_id, ext, &entries); 1830 installer_util::GetAppExtRegistrationEntries(prog_id, ext, &entries);
2298 1831
2299 // Regstering as the default will have no effect on Windows 8 (see 1832 // Regstering as the default will have no effect on Windows 8 (see
2300 // documentation for GetAppDefaultRegistrationEntries). However, if our app 1833 // documentation for GetAppDefaultRegistrationEntries). However, if our app
2301 // is the only handler, it will automatically become the default, so the 1834 // is the only handler, it will automatically become the default, so the
2302 // same effect is achieved. 1835 // same effect is achieved.
2303 GetAppDefaultRegistrationEntries(prog_id, ext, false, &entries); 1836 installer_util::GetAppDefaultRegistrationEntries(prog_id, ext, false,
1837 &entries);
2304 } 1838 }
2305 1839
2306 return AddRegistryEntries(HKEY_CURRENT_USER, entries); 1840 return AddRegistryEntries(HKEY_CURRENT_USER, entries);
2307 } 1841 }
2308 1842
2309 // static 1843 // static
2310 bool ShellUtil::DeleteFileAssociations(const base::string16& prog_id) { 1844 bool ShellUtil::DeleteFileAssociations(const base::string16& prog_id) {
2311 // Delete the key HKEY_CURRENT_USER\Software\Classes\PROGID. 1845 // Delete the key HKEY_CURRENT_USER\Software\Classes\PROGID.
2312 base::string16 key_path(kRegClasses); 1846 base::string16 key_path(kRegClasses);
2313 key_path.push_back(base::FilePath::kSeparators[0]); 1847 key_path.push_back(base::FilePath::kSeparators[0]);
(...skipping 15 matching lines...) Expand all
2329 itr != entries.end(); ++itr) 1863 itr != entries.end(); ++itr)
2330 (*itr)->AddToWorkItemList(root, items.get()); 1864 (*itr)->AddToWorkItemList(root, items.get());
2331 1865
2332 // Apply all the registry changes and if there is a problem, rollback 1866 // Apply all the registry changes and if there is a problem, rollback
2333 if (!items->Do()) { 1867 if (!items->Do()) {
2334 items->Rollback(); 1868 items->Rollback();
2335 return false; 1869 return false;
2336 } 1870 }
2337 return true; 1871 return true;
2338 } 1872 }
OLDNEW
« no previous file with comments | « chrome/installer/util/shell_registry_util.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698