diff options
author | gab@chromium.org <gab@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-04-21 02:42:56 +0000 |
---|---|---|
committer | gab@chromium.org <gab@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-04-21 02:42:56 +0000 |
commit | f8bd599c36b196cf8a2c342cc090c3ce9892f29e (patch) | |
tree | 925826f5c35a229351fa384c3a7953a0814f50bc /chrome | |
parent | 8d7a874ee218f2e33135dd120b7ff7c8d94ed9f6 (diff) | |
download | chromium_src-f8bd599c36b196cf8a2c342cc090c3ce9892f29e.zip chromium_src-f8bd599c36b196cf8a2c342cc090c3ce9892f29e.tar.gz chromium_src-f8bd599c36b196cf8a2c342cc090c3ce9892f29e.tar.bz2 |
HKCR/ChromeHTML Win8 registry requirements
This CL also takes care of adding necessary registry entry for DelegateExecute to open Metro mode in Windows 8 (as well as packaging the necessary new files and installing them in the correct places).
BUG=119242
TEST=Verify all necessary prog id registry keys are correctly placed on a Win8 install.
Verify DelegateExecute binaries, pngs, and VisualElementsManifest.xml land where they belond after running the installer.
Review URL: http://codereview.chromium.org/9918012
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@133333 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/installer/mini_installer/chrome.release | 9 | ||||
-rw-r--r-- | chrome/installer/setup/setup_main.cc | 2 | ||||
-rw-r--r-- | chrome/installer/setup/uninstall.cc | 72 | ||||
-rw-r--r-- | chrome/installer/setup/uninstall.h | 7 | ||||
-rw-r--r-- | chrome/installer/util/browser_distribution.h | 1 | ||||
-rw-r--r-- | chrome/installer/util/google_chrome_distribution.cc | 12 | ||||
-rw-r--r-- | chrome/installer/util/shell_util.cc | 470 | ||||
-rw-r--r-- | chrome/installer/util/shell_util.h | 102 |
8 files changed, 413 insertions, 262 deletions
diff --git a/chrome/installer/mini_installer/chrome.release b/chrome/installer/mini_installer/chrome.release index 78956d7..e937feb 100644 --- a/chrome/installer/mini_installer/chrome.release +++ b/chrome/installer/mini_installer/chrome.release @@ -31,9 +31,16 @@ default_apps\*.crx: %(VersionDir)s\default_apps\ default_apps\external_extensions.json: %(VersionDir)s\default_apps\ [GOOGLE_CHROME] +splash-620x300.png: %(ChromeDir)s\ +Logo.png: %(ChromeDir)s\ +SmallLogo.png: %(ChromeDir)s\ +VisualElementsManifest.xml: %(ChromeDir)s\ +delegate_execute.exe: %(VersionDir)s\ gcswf32.dll: %(VersionDir)s\ +#metro_driver.dll will go in the VersionDir once we fix http://crbug.com/123316 +metro_driver.dll: %(ChromeDir)s\ plugin.vch: %(VersionDir)s\ -FlashPlayerCPLApp.cpl: %(VersionDir)s\ FlashPlayerApp.exe: %(VersionDir)s\ +FlashPlayerCPLApp.cpl: %(VersionDir)s\ PepperFlash\pepflashplayer.dll: %(VersionDir)s\PepperFlash\ PepperFlash\manifest.json: %(VersionDir)s\PepperFlash\ diff --git a/chrome/installer/setup/setup_main.cc b/chrome/installer/setup/setup_main.cc index c99d3e6..ad881c2 100644 --- a/chrome/installer/setup/setup_main.cc +++ b/chrome/installer/setup/setup_main.cc @@ -1023,7 +1023,7 @@ bool HandleNonInstallCmdLineOptions(const InstallationState& original_state, installer::switches::kRegisterURLProtocol); // ShellUtil::RegisterChromeForProtocol performs all registration // done by ShellUtil::RegisterChromeBrowser, as well as registering - // with Winows as capable of handling the supplied protocol. + // with Windows as capable of handling the supplied protocol. if (ShellUtil::RegisterChromeForProtocol(chrome_install->distribution(), chrome_exe, suffix, protocol, false)) status = installer::IN_USE_UPDATED; diff --git a/chrome/installer/setup/uninstall.cc b/chrome/installer/setup/uninstall.cc index 836b384..ba2abb5 100644 --- a/chrome/installer/setup/uninstall.cc +++ b/chrome/installer/setup/uninstall.cc @@ -139,7 +139,7 @@ void ClearRlzProductState() { rlz_lib::ClearProductState(rlz_lib::CHROME, points); // If chrome has been reactivated, clear all events for this brand as well. - std::wstring reactivation_brand_wide; + string16 reactivation_brand_wide; if (GoogleUpdateSettings::GetReactivationBrand(&reactivation_brand_wide)) { std::string reactivation_brand(WideToASCII(reactivation_brand_wide)); rlz_lib::SupplementaryBranding branding(reactivation_brand.c_str()); @@ -158,7 +158,7 @@ namespace installer { // to kill them. void CloseAllChromeProcesses() { for (int j = 0; j < 4; ++j) { - std::wstring wnd_class(L"Chrome_WidgetWin_"); + string16 wnd_class(L"Chrome_WidgetWin_"); wnd_class.append(base::IntToString16(j)); HWND window = FindWindowEx(NULL, NULL, wnd_class.c_str(), NULL); while (window) { @@ -228,9 +228,9 @@ bool CurrentUserHasDefaultBrowser(const InstallerState& installer_state) { const HKEY root = HKEY_LOCAL_MACHINE; ProgramCompare open_command_pred( installer_state.target_path().Append(kChromeExe)); - std::wstring client_open_path; + string16 client_open_path; RegKey client_open_key; - std::wstring reg_exe; + string16 reg_exe; for (RegistryKeyIterator iter(root, ShellUtil::kRegStartMenuInternet); iter.Valid(); ++iter) { client_open_path.assign(ShellUtil::kRegStartMenuInternet) @@ -289,8 +289,7 @@ void DeleteChromeShortcuts(const InstallerState& installer_state, if (shortcut_path.empty()) { LOG(ERROR) << "Failed to get location for shortcut."; } else { - const std::wstring product_name( - product.distribution()->GetAppShortCutName()); + const string16 product_name(product.distribution()->GetAppShortCutName()); shortcut_path = shortcut_path.Append(product_name); FilePath shortcut_link(shortcut_path.Append(product_name + L".lnk")); @@ -537,7 +536,7 @@ bool ShouldDeleteProfile(const InstallerState& installer_state, } bool DeleteChromeRegistrationKeys(BrowserDistribution* dist, HKEY root, - const std::wstring& browser_entry_suffix, + const string16& browser_entry_suffix, const FilePath& target_path, InstallStatus* exit_code) { DCHECK(exit_code); @@ -548,20 +547,29 @@ bool DeleteChromeRegistrationKeys(BrowserDistribution* dist, HKEY root, FilePath chrome_exe(target_path.Append(kChromeExe)); - // Delete Software\Classes\ChromeHTML, - std::wstring html_prog_id(ShellUtil::kRegClasses); + // Delete Software\Classes\ChromeHTML. + // For user-level installs we now only write these entries in HKCU, but since + // old installs did install them to HKLM we will try to remove them in HKLM as + // well anyways. + string16 html_prog_id(ShellUtil::kRegClasses); html_prog_id.push_back(FilePath::kSeparators[0]); html_prog_id.append(ShellUtil::kChromeHTMLProgId); html_prog_id.append(browser_entry_suffix); InstallUtil::DeleteRegistryKey(root, html_prog_id); + // Delete Software\Classes\Chrome (Same comment as above applies for this too) + string16 chrome_app_id(ShellUtil::kRegClasses); + chrome_app_id.push_back(FilePath::kSeparators[0]); + chrome_app_id.append(dist->GetBrowserAppId()); + InstallUtil::DeleteRegistryKey(root, chrome_app_id); + // Delete all Start Menu Internet registrations that refer to this Chrome. { using base::win::RegistryKeyIterator; ProgramCompare open_command_pred(chrome_exe); - std::wstring client_name; - std::wstring client_key; - std::wstring open_key; + string16 client_name; + string16 client_key; + string16 open_key; for (RegistryKeyIterator iter(root, ShellUtil::kRegStartMenuInternet); iter.Valid(); ++iter) { client_name.assign(iter.Name()); @@ -581,7 +589,7 @@ bool DeleteChromeRegistrationKeys(BrowserDistribution* dist, HKEY root, if (root == HKEY_LOCAL_MACHINE) { InstallUtil::DeleteRegistryValueIf( HKEY_USERS, - std::wstring(L".DEFAULT\\").append( + string16(L".DEFAULT\\").append( ShellUtil::kRegStartMenuInternet).c_str(), L"", InstallUtil::ValueEquals(client_name)); } @@ -594,7 +602,7 @@ bool DeleteChromeRegistrationKeys(BrowserDistribution* dist, HKEY root, dist->GetApplicationName() + browser_entry_suffix); // Delete Software\Classes\Applications\chrome.exe - std::wstring app_key(ShellUtil::kRegClasses); + string16 app_key(ShellUtil::kRegClasses); app_key.push_back(FilePath::kSeparators[0]); app_key.append(L"Applications"); app_key.push_back(FilePath::kSeparators[0]); @@ -602,13 +610,13 @@ bool DeleteChromeRegistrationKeys(BrowserDistribution* dist, HKEY root, InstallUtil::DeleteRegistryKey(root, app_key); // Delete the App Paths key that lets explorer find Chrome. - std::wstring app_path_key(ShellUtil::kAppPathsRegistryKey); + string16 app_path_key(ShellUtil::kAppPathsRegistryKey); app_path_key.push_back(FilePath::kSeparators[0]); app_path_key.append(installer::kChromeExe); InstallUtil::DeleteRegistryKey(root, app_path_key); // Cleanup OpenWithList - std::wstring open_with_key; + string16 open_with_key; for (int i = 0; ShellUtil::kFileAssociations[i] != NULL; i++) { open_with_key.assign(ShellUtil::kRegClasses); open_with_key.push_back(FilePath::kSeparators[0]); @@ -633,9 +641,9 @@ bool DeleteChromeRegistrationKeys(BrowserDistribution* dist, HKEY root, // Delete each protocol association if it references this Chrome. ProgramCompare open_command_pred(chrome_exe); - std::wstring parent_key(ShellUtil::kRegClasses); - const std::wstring::size_type base_length = parent_key.size(); - std::wstring child_key; + string16 parent_key(ShellUtil::kRegClasses); + const string16::size_type base_length = parent_key.size(); + string16 child_key; for (const wchar_t* const* proto = &ShellUtil::kPotentialProtocolAssociations[0]; *proto != NULL; @@ -669,20 +677,20 @@ const wchar_t kChromeExtProgId[] = L"ChromiumExt"; HKEY roots[] = { HKEY_LOCAL_MACHINE, HKEY_CURRENT_USER }; for (size_t i = 0; i < arraysize(roots); ++i) { - std::wstring suffix; + string16 suffix; if (roots[i] == HKEY_LOCAL_MACHINE && !ShellUtil::GetUserSpecificDefaultBrowserSuffix(dist, &suffix)) suffix = L""; // Delete Software\Classes\ChromeExt, - std::wstring ext_prog_id(ShellUtil::kRegClasses); + string16 ext_prog_id(ShellUtil::kRegClasses); ext_prog_id.push_back(FilePath::kSeparators[0]); ext_prog_id.append(kChromeExtProgId); ext_prog_id.append(suffix); InstallUtil::DeleteRegistryKey(roots[i], ext_prog_id); // Delete Software\Classes\.crx, - std::wstring ext_association(ShellUtil::kRegClasses); + string16 ext_association(ShellUtil::kRegClasses); ext_association.append(L"\\"); ext_association.append(chrome::kExtensionFileExtension); InstallUtil::DeleteRegistryKey(roots[i], ext_association); @@ -724,7 +732,7 @@ InstallStatus UninstallProduct(const InstallationState& original_state, bool force_uninstall, const CommandLine& cmd_line) { InstallStatus status = installer::UNINSTALL_CONFIRMED; - std::wstring suffix; + string16 suffix; if (!ShellUtil::GetUserSpecificDefaultBrowserSuffix(product.distribution(), &suffix)) suffix = L""; @@ -789,7 +797,7 @@ InstallStatus UninstallProduct(const InstallationState& original_state, // Note that we must retrieve the distribution-specific data before deleting // product.GetVersionKey(). - std::wstring distribution_data(browser_dist->GetDistributionData(reg_root)); + string16 distribution_data(browser_dist->GetDistributionData(reg_root)); // Remove Control Panel uninstall link and Omaha product key. InstallUtil::DeleteRegistryKey(reg_root, browser_dist->GetUninstallRegPath()); @@ -808,10 +816,16 @@ InstallStatus UninstallProduct(const InstallationState& original_state, DeleteChromeRegistrationKeys(product.distribution(), HKEY_CURRENT_USER, suffix, installer_state.target_path(), &ret); - // Registration data is put in HKLM for system level and possibly user level - // installs (when Chrome is made the default browser at install-time). - if (installer_state.system_install() || remove_all && - (!suffix.empty() || CurrentUserHasDefaultBrowser(installer_state))) { + // Chrome is registered in HKLM for all system-level installs and for + // user-level installs for which Chrome has been made the default browser. + // Always remove the HKLM registration for system-level installs. For + // user-level installs, only remove it if both: 1) this uninstall isn't a + // self-destruct following the installation of system-level Chrome (because + // the system-level Chrome owns the HKLM registration now), and 2) this user + // had made Chrome their default browser. + if (installer_state.system_install() || + (remove_all && + (!suffix.empty() || CurrentUserHasDefaultBrowser(installer_state)))) { DeleteChromeRegistrationKeys(product.distribution(), HKEY_LOCAL_MACHINE, suffix, installer_state.target_path(), &ret); } @@ -841,7 +855,7 @@ InstallStatus UninstallProduct(const InstallationState& original_state, // Delete media player registry key that exists only in HKLM. // We don't delete this key in SxS uninstall or Chrome Frame uninstall // as we never set the key for those products. - std::wstring reg_path(installer::kMediaPlayerRegPath); + string16 reg_path(installer::kMediaPlayerRegPath); reg_path.push_back(FilePath::kSeparators[0]); reg_path.append(installer::kChromeExe); InstallUtil::DeleteRegistryKey(HKEY_LOCAL_MACHINE, reg_path); diff --git a/chrome/installer/setup/uninstall.h b/chrome/installer/setup/uninstall.h index a531646..a11ec024 100644 --- a/chrome/installer/setup/uninstall.h +++ b/chrome/installer/setup/uninstall.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -10,8 +10,7 @@ #include <shlobj.h> -#include <string> - +#include "base/string16.h" #include "chrome/installer/util/util_constants.h" class BrowserDistribution; @@ -29,7 +28,7 @@ class Product; // |root| is the registry root (HKLM|HKCU) and |browser_entry_suffix| is the // suffix for default browser entry name in the registry (optional). bool DeleteChromeRegistrationKeys(BrowserDistribution* dist, HKEY root, - const std::wstring& browser_entry_suffix, + const string16& browser_entry_suffix, const FilePath& target_path, InstallStatus* exit_code); diff --git a/chrome/installer/util/browser_distribution.h b/chrome/installer/util/browser_distribution.h index 060c386..e62e030 100644 --- a/chrome/installer/util/browser_distribution.h +++ b/chrome/installer/util/browser_distribution.h @@ -121,6 +121,7 @@ class BrowserDistribution { // |handler_class_uuid| is the CommandExecuteImpl class UUID. // |type_lib_uuid| and |type_lib_version| identify its type library. // |interface_uuid| is the ICommandExecuteImpl interface UUID. + // Only non-null parameters will be set, others will be ignored. virtual bool GetDelegateExecuteHandlerData(string16* handler_class_uuid, string16* type_lib_uuid, string16* type_lib_version, diff --git a/chrome/installer/util/google_chrome_distribution.cc b/chrome/installer/util/google_chrome_distribution.cc index c314ce6..79b7c93 100644 --- a/chrome/installer/util/google_chrome_distribution.cc +++ b/chrome/installer/util/google_chrome_distribution.cc @@ -538,10 +538,14 @@ bool GoogleChromeDistribution::GetDelegateExecuteHandlerData( string16* type_lib_uuid, string16* type_lib_version, string16* interface_uuid) { - *handler_class_uuid = kCommandExecuteImplUuid; - *type_lib_uuid = kDelegateExecuteLibUuid; - *type_lib_version = kDelegateExecuteLibVersion; - *interface_uuid = kICommandExecuteImplUuid; + if (handler_class_uuid) + *handler_class_uuid = kCommandExecuteImplUuid; + if (type_lib_uuid) + *type_lib_uuid = kDelegateExecuteLibUuid; + if (type_lib_version) + *type_lib_version = kDelegateExecuteLibVersion; + if (interface_uuid) + *interface_uuid = kICommandExecuteImplUuid; return true; } diff --git a/chrome/installer/util/shell_util.cc b/chrome/installer/util/shell_util.cc index 5a5957b..3115aeb 100644 --- a/chrome/installer/util/shell_util.cc +++ b/chrome/installer/util/shell_util.cc @@ -56,10 +56,10 @@ class RegistryEntry { // to make Chrome their default browser, which isn't polite. |suffix| is the // user-specific registration suffix; see GetUserSpecificDefaultBrowserSuffix // in shell_util.h for details. - static std::wstring GetBrowserClientKey(BrowserDistribution* dist, - const std::wstring& suffix) { + static string16 GetBrowserClientKey(BrowserDistribution* dist, + const string16& suffix) { DCHECK(suffix.empty() || suffix[0] == L'.'); - return std::wstring(ShellUtil::kRegStartMenuInternet) + return string16(ShellUtil::kRegStartMenuInternet) .append(1, L'\\') .append(dist->GetApplicationName()) .append(suffix); @@ -68,22 +68,66 @@ class RegistryEntry { // Returns the Windows Default Programs capabilities key for Chrome. For // example: // "Software\Clients\StartMenuInternet\Chromium[.user]\Capabilities". - static std::wstring GetCapabilitiesKey(BrowserDistribution* dist, - const std::wstring& suffix) { + static string16 GetCapabilitiesKey(BrowserDistribution* dist, + const string16& suffix) { return GetBrowserClientKey(dist, suffix).append(L"\\Capabilities"); } // This method returns a list of all the registry entries that // are needed to register Chromium ProgIds. + // These entries should be registered in HKCU for user-level installs and in + // HKLM for system-level installs. + // TODO (gab): Extract the Windows 8 only registrations out of this function. static bool GetProgIdEntries(BrowserDistribution* dist, - const std::wstring& chrome_exe, - const std::wstring& suffix, + const string16& chrome_exe, + const string16& suffix, std::list<RegistryEntry*>* entries) { - std::wstring icon_path = ShellUtil::GetChromeIcon(dist, chrome_exe); - std::wstring open_cmd = ShellUtil::GetChromeShellOpenCmd(chrome_exe); + string16 icon_path(ShellUtil::GetChromeIcon(dist, chrome_exe)); + string16 open_cmd(ShellUtil::GetChromeShellOpenCmd(chrome_exe)); + string16 delegate_command(ShellUtil::GetChromeDelegateCommand(chrome_exe)); + // For user-level installs: entries for the app id and DelegateExecute verb + // handler will be in HKCU; thus we do not need a suffix on those entries. + string16 app_id(dist->GetBrowserAppId()); + string16 delegate_guid; + bool set_delegate_execute = + base::win::GetVersion() >= base::win::VERSION_WIN8 && + dist->GetDelegateExecuteHandlerData(&delegate_guid, NULL, NULL, NULL); + + // DelegateExecute ProgId. Needed for Chrome Metro in Windows 8. + if (set_delegate_execute) { + string16 model_id_shell(ShellUtil::kRegClasses); + model_id_shell.push_back(FilePath::kSeparators[0]); + model_id_shell.append(app_id); + model_id_shell.append(ShellUtil::kRegExePath); + model_id_shell.append(ShellUtil::kRegShellPath); + + // <root hkey>\Software\Classes\<app_id>\.exe\shell @=open + entries->push_front(new RegistryEntry(model_id_shell, + ShellUtil::kRegVerbOpen)); + + const wchar_t* const verbs[] = { ShellUtil::kRegVerbOpen, + ShellUtil::kRegVerbRun }; + for (size_t i = 0; i < arraysize(verbs); ++i) { + string16 sub_path(model_id_shell); + sub_path.push_back(FilePath::kSeparators[0]); + sub_path.append(verbs[i]); + + // <root hkey>\Software\Classes\<app_id>\.exe\shell\<verb> + entries->push_front(new RegistryEntry( + sub_path, L"CommandId", L"Browser.Launch")); + + sub_path.push_back(FilePath::kSeparators[0]); + sub_path.append(ShellUtil::kRegCommand); + + // <root hkey>\Software\Classes\<app_id>\.exe\shell\<verb>\command + entries->push_front(new RegistryEntry(sub_path, delegate_command)); + entries->push_front(new RegistryEntry( + sub_path, ShellUtil::kRegDelegateExecute, delegate_guid)); + } + } // File association ProgId - std::wstring chrome_html_prog_id(ShellUtil::kRegClasses); + string16 chrome_html_prog_id(ShellUtil::kRegClasses); chrome_html_prog_id.push_back(FilePath::kSeparators[0]); chrome_html_prog_id.append(ShellUtil::kChromeHTMLProgId); chrome_html_prog_id.append(suffix); @@ -95,6 +139,37 @@ class RegistryEntry { chrome_html_prog_id + ShellUtil::kRegDefaultIcon, icon_path)); entries->push_front(new RegistryEntry( chrome_html_prog_id + ShellUtil::kRegShellOpen, open_cmd)); + if (set_delegate_execute) { + entries->push_front(new RegistryEntry( + chrome_html_prog_id + ShellUtil::kRegShellOpen, + ShellUtil::kRegDelegateExecute, delegate_guid)); + } + + // The following entries are required as of Windows 8, but do not + // depend on the DelegateExecute. + if (base::win::GetVersion() >= base::win::VERSION_WIN8) { + entries->push_front(new RegistryEntry( + chrome_html_prog_id, ShellUtil::kRegAppUserModelId, app_id)); + + // Add \Software\Classes\ChromeHTML\Application entries + string16 chrome_application(chrome_html_prog_id + + ShellUtil::kRegApplication); + entries->push_front(new RegistryEntry( + chrome_application, ShellUtil::kRegAppUserModelId, app_id)); + entries->push_front(new RegistryEntry( + chrome_application, ShellUtil::kRegApplicationIcon, icon_path)); + // TODO(grt): http://crbug.com/75152 Write a reference to a localized + // resource for name, description, and company. + entries->push_front(new RegistryEntry( + chrome_application, ShellUtil::kRegApplicationName, + dist->GetApplicationName().append(suffix))); + entries->push_front(new RegistryEntry( + chrome_application, ShellUtil::kRegApplicationDescription, + dist->GetAppDescription())); + entries->push_front(new RegistryEntry( + chrome_application, ShellUtil::kRegApplicationCompany, + dist->GetPublisherName())); + } return true; } @@ -102,26 +177,26 @@ class RegistryEntry { // This method returns a list of the system level registry entries // needed to declare a capability of handling a protocol. static bool GetProtocolCapabilityEntries(BrowserDistribution* dist, - const std::wstring& suffix, - const std::wstring& protocol, + const string16& suffix, + const string16& protocol, std::list<RegistryEntry*>* entries) { entries->push_front(new RegistryEntry( GetCapabilitiesKey(dist, suffix).append(L"\\URLAssociations"), - protocol, std::wstring(ShellUtil::kChromeHTMLProgId).append(suffix))); + protocol, string16(ShellUtil::kChromeHTMLProgId).append(suffix))); return true; } // This method returns a list of all the system level registry entries that // are needed to register Chromium on the machine. static bool GetSystemEntries(BrowserDistribution* dist, - const std::wstring& chrome_exe, - const std::wstring& suffix, + const string16& chrome_exe, + const string16& suffix, std::list<RegistryEntry*>* entries) { - std::wstring icon_path = ShellUtil::GetChromeIcon(dist, chrome_exe); - std::wstring quoted_exe_path = L"\"" + chrome_exe + L"\""; + string16 icon_path = ShellUtil::GetChromeIcon(dist, chrome_exe); + string16 quoted_exe_path = L"\"" + chrome_exe + L"\""; // Register for the Start Menu "Internet" link (pre-Win7). - const std::wstring start_menu_entry(GetBrowserClientKey(dist, suffix)); + const string16 start_menu_entry(GetBrowserClientKey(dist, suffix)); // Register Chrome's display name. // TODO(grt): http://crbug.com/75152 Also set LocalizedString; see // http://msdn.microsoft.com/en-us/library/windows/desktop/cc144109(v=VS.85).aspx#registering_the_display_name @@ -135,7 +210,7 @@ class RegistryEntry { start_menu_entry + ShellUtil::kRegDefaultIcon, icon_path)); // Register installation information. - std::wstring install_info(start_menu_entry + L"\\InstallInfo"); + string16 install_info(start_menu_entry + L"\\InstallInfo"); // Note: not using CommandLine since it has ambiguous rules for quoting // strings. entries->push_front(new RegistryEntry(install_info, kReinstallCommand, @@ -147,26 +222,26 @@ class RegistryEntry { entries->push_front(new RegistryEntry(install_info, L"IconsVisible", 1)); // Register with Default Programs. - std::wstring app_name(dist->GetApplicationName().append(suffix)); + string16 app_name(dist->GetApplicationName().append(suffix)); // Tell Windows where to find Chrome's Default Programs info. - std::wstring capabilities(GetCapabilitiesKey(dist, suffix)); + string16 capabilities(GetCapabilitiesKey(dist, suffix)); entries->push_front(new RegistryEntry(ShellUtil::kRegRegisteredApplications, app_name, capabilities)); // Write out Chrome's Default Programs info. // TODO(grt): http://crbug.com/75152 Write a reference to a localized // resource rather than this. entries->push_front(new RegistryEntry( - capabilities, L"ApplicationDescription", + capabilities, ShellUtil::kRegApplicationDescription, dist->GetLongAppDescription())); entries->push_front(new RegistryEntry( - capabilities, L"ApplicationIcon", icon_path)); + capabilities, ShellUtil::kRegApplicationIcon, icon_path)); entries->push_front(new RegistryEntry( - capabilities, L"ApplicationName", app_name)); + capabilities, ShellUtil::kRegApplicationName, app_name)); entries->push_front(new RegistryEntry(capabilities + L"\\Startmenu", L"StartMenuInternet", app_name)); - std::wstring html_prog_id(ShellUtil::kChromeHTMLProgId); + string16 html_prog_id(ShellUtil::kChromeHTMLProgId); html_prog_id.append(suffix); for (int i = 0; ShellUtil::kFileAssociations[i] != NULL; i++) { entries->push_front(new RegistryEntry( @@ -182,7 +257,7 @@ class RegistryEntry { // Application Registration. FilePath chrome_path(chrome_exe); - std::wstring app_path_key(ShellUtil::kAppPathsRegistryKey); + string16 app_path_key(ShellUtil::kAppPathsRegistryKey); app_path_key.push_back(FilePath::kSeparators[0]); app_path_key.append(chrome_path.BaseName().value()); entries->push_front(new RegistryEntry(app_path_key, chrome_exe)); @@ -195,12 +270,12 @@ class RegistryEntry { // This method returns a list of all the user level registry entries that // are needed to make Chromium the default handler for a protocol. - static bool GetUserProtocolEntries(const std::wstring& protocol, - const std::wstring& chrome_icon, - const std::wstring& chrome_open, + static bool GetUserProtocolEntries(const string16& protocol, + const string16& chrome_icon, + const string16& chrome_open, std::list<RegistryEntry*>* entries) { // Protocols associations. - std::wstring url_key(ShellUtil::kRegClasses); + string16 url_key(ShellUtil::kRegClasses); url_key.push_back(FilePath::kSeparators[0]); url_key.append(protocol); @@ -211,19 +286,19 @@ class RegistryEntry { ShellUtil::kRegUrlProtocol, L"")); // <root hkey>\Software\Classes\<protocol>\DefaultIcon - std::wstring icon_key = url_key + ShellUtil::kRegDefaultIcon; + string16 icon_key = url_key + ShellUtil::kRegDefaultIcon; entries->push_front(new RegistryEntry(icon_key, chrome_icon)); // <root hkey>\Software\Classes\<protocol>\shell\open\command - std::wstring shell_key = url_key + ShellUtil::kRegShellOpen; + string16 shell_key = url_key + ShellUtil::kRegShellOpen; entries->push_front(new RegistryEntry(shell_key, chrome_open)); // <root hkey>\Software\Classes\<protocol>\shell\open\ddeexec - std::wstring dde_key = url_key + L"\\shell\\open\\ddeexec"; + string16 dde_key = url_key + L"\\shell\\open\\ddeexec"; entries->push_front(new RegistryEntry(dde_key, L"")); // <root hkey>\Software\Classes\<protocol>\shell\@ - std::wstring protocol_shell_key = url_key + ShellUtil::kRegShellPath; + string16 protocol_shell_key = url_key + ShellUtil::kRegShellPath; entries->push_front(new RegistryEntry(protocol_shell_key, L"open")); return true; @@ -232,30 +307,30 @@ class RegistryEntry { // This method returns a list of all the user level registry entries that // are needed to make Chromium default browser. static bool GetUserEntries(BrowserDistribution* dist, - const std::wstring& chrome_exe, - const std::wstring& suffix, + const string16& chrome_exe, + const string16& suffix, std::list<RegistryEntry*>* entries) { // File extension associations. - std::wstring html_prog_id(ShellUtil::kChromeHTMLProgId); + string16 html_prog_id(ShellUtil::kChromeHTMLProgId); html_prog_id.append(suffix); for (int i = 0; ShellUtil::kFileAssociations[i] != NULL; i++) { - std::wstring ext_key(ShellUtil::kRegClasses); + string16 ext_key(ShellUtil::kRegClasses); ext_key.push_back(FilePath::kSeparators[0]); ext_key.append(ShellUtil::kFileAssociations[i]); entries->push_front(new RegistryEntry(ext_key, html_prog_id)); } // Protocols associations. - std::wstring chrome_open = ShellUtil::GetChromeShellOpenCmd(chrome_exe); - std::wstring chrome_icon = ShellUtil::GetChromeIcon(dist, chrome_exe); + string16 chrome_open = ShellUtil::GetChromeShellOpenCmd(chrome_exe); + string16 chrome_icon = ShellUtil::GetChromeIcon(dist, chrome_exe); for (int i = 0; ShellUtil::kBrowserProtocolAssociations[i] != NULL; i++) { GetUserProtocolEntries(ShellUtil::kBrowserProtocolAssociations[i], chrome_icon, chrome_open, entries); } // start->Internet shortcut. - std::wstring start_menu(ShellUtil::kRegStartMenuInternet); - std::wstring app_name = dist->GetApplicationName() + suffix; + string16 start_menu(ShellUtil::kRegStartMenuInternet); + string16 app_name = dist->GetApplicationName() + suffix; entries->push_front(new RegistryEntry(start_menu, app_name)); return true; } @@ -271,68 +346,80 @@ class RegistryEntry { } } - // Checks if the current registry entry exists in HKLM registry and the value - // is same. - bool ExistsInHKLM() const { - RegKey key(HKEY_LOCAL_MACHINE, _key_path.c_str(), KEY_READ); - bool found = false; - if (_is_string) { - std::wstring read_value; - found = (key.ReadValue(_name.c_str(), &read_value) == ERROR_SUCCESS) && - (read_value.size() == _value.size()) && - (std::equal(_value.begin(), _value.end(), read_value.begin(), - base::CaseInsensitiveCompare<wchar_t>())); - } else { - DWORD read_value; - found = (key.ReadValueDW(_name.c_str(), &read_value) == ERROR_SUCCESS) && - (read_value == _int_value); - } - key.Close(); - return found; - } - - // Checks if the current registry entry exists in HKLM registry - // (only the name). - bool NameExistsInHKLM() const { - RegKey key(HKEY_LOCAL_MACHINE, _key_path.c_str(), KEY_READ); - bool found = false; - if (_is_string) { - std::wstring read_value; - found = key.ReadValue(_name.c_str(), &read_value) == ERROR_SUCCESS; - } else { - DWORD read_value; - found = key.ReadValueDW(_name.c_str(), &read_value) == ERROR_SUCCESS; - } - key.Close(); - return found; + // Checks if the current registry entry exists in HKCU\|_key_path|\|_name| + // and value is |_value|. If the key does NOT exist in HKCU, checks for + // the correct name and value in HKLM. + // This mimics Windows' behavior when searching in HKCR (HKCU takes precedence + // over HKLM). For registrations outside of HKCR on versions of Windows up + // to Win7, Chrome's values go in HKLM. This function will make unnecessary + // (but harmless) queries into HKCU in that case. Starting with Windows 8, + // Chrome's values go in HKCU for user-level installs, which takes precedence + // over HKLM. + bool ExistsInRegistry() { + RegistryStatus hkcu_status = StatusInRegistryUnderRoot(HKEY_CURRENT_USER); + return (hkcu_status == SAME_VALUE || + (hkcu_status == DOES_NOT_EXIST && + StatusInRegistryUnderRoot(HKEY_LOCAL_MACHINE) == SAME_VALUE)); } private: + // States this RegistryKey can be in compared to the registry. + enum RegistryStatus { + // |_name| does not exist in the registry + DOES_NOT_EXIST, + // |_name| exists, but its value != |_value| + DIFFERENT_VALUE, + // |_name| exists and its value is |_value| + SAME_VALUE, + }; + // Create a object that represent default value of a key - RegistryEntry(const std::wstring& key_path, const std::wstring& value) + RegistryEntry(const string16& key_path, const string16& value) : _key_path(key_path), _name(), _is_string(true), _value(value), _int_value(0) { } // Create a object that represent a key of type REG_SZ - RegistryEntry(const std::wstring& key_path, const std::wstring& name, - const std::wstring& value) + RegistryEntry(const string16& key_path, const string16& name, + const string16& value) : _key_path(key_path), _name(name), _is_string(true), _value(value), _int_value(0) { } // Create a object that represent a key of integer type - RegistryEntry(const std::wstring& key_path, const std::wstring& name, + RegistryEntry(const string16& key_path, const string16& name, DWORD value) : _key_path(key_path), _name(name), _is_string(false), _value(), _int_value(value) { } - std::wstring _key_path; // key path for the registry entry - std::wstring _name; // name of the registry entry - bool _is_string; // true if current registry entry is of type REG_SZ - std::wstring _value; // string value (useful if _is_string = true) - DWORD _int_value; // integer value (useful if _is_string = false) + string16 _key_path; // key path for the registry entry + string16 _name; // name of the registry entry + bool _is_string; // true if current registry entry is of type REG_SZ + string16 _value; // string value (useful if _is_string = true) + DWORD _int_value; // integer value (useful if _is_string = false) + + // Helper function for ExistsInRegistry(). + // Returns the RegistryStatus of the current registry entry in + // |root|\|_key_path|\|_name|. + RegistryStatus StatusInRegistryUnderRoot(HKEY root) const { + RegKey key(root, _key_path.c_str(), KEY_QUERY_VALUE); + bool found = false; + bool correct_value = false; + if (_is_string) { + string16 read_value; + found = key.ReadValue(_name.c_str(), &read_value) == ERROR_SUCCESS; + correct_value = read_value.size() == _value.size() && + std::equal(_value.begin(), _value.end(), read_value.begin(), + base::CaseInsensitiveCompare<wchar_t>()); + } else { + DWORD read_value; + found = key.ReadValueDW(_name.c_str(), &read_value) == ERROR_SUCCESS; + correct_value = read_value == _int_value; + } + return found ? + (correct_value ? SAME_VALUE : DIFFERENT_VALUE) : DOES_NOT_EXIST; + } DISALLOW_COPY_AND_ASSIGN(RegistryEntry); }; // class RegistryEntry @@ -355,42 +442,39 @@ bool AddRegistryEntries(HKEY root, const std::list<RegistryEntry*>& entries) { return true; } -// This method checks if Chrome is already registered on the local machine. -// It gets all the required registry entries for Chrome and then checks if -// they exist in HKLM. Returns true if all the entries exist, otherwise false. -bool IsChromeRegistered(BrowserDistribution* dist, - const std::wstring& chrome_exe, - const std::wstring& suffix) { +// Checks that all |entries| are present on this computer. +bool AreEntriesRegistered(const std::list<RegistryEntry*>& entries) { bool registered = true; - std::list<RegistryEntry*> entries; - STLElementDeleter<std::list<RegistryEntry*> > entries_deleter(&entries); - RegistryEntry::GetProgIdEntries(dist, chrome_exe, suffix, &entries); - RegistryEntry::GetSystemEntries(dist, chrome_exe, suffix, &entries); for (std::list<RegistryEntry*>::const_iterator itr = entries.begin(); - itr != entries.end() && registered; ++itr) { + registered && itr != entries.end(); ++itr) { // We do not need registered = registered && ... since the loop condition // is set to exit early. - registered = (*itr)->ExistsInHKLM(); + registered = (*itr)->ExistsInRegistry(); } return registered; } +// Checks that all required registry entries for Chrome are already present +// on this computer. +bool IsChromeRegistered(BrowserDistribution* dist, + const string16& chrome_exe, + const string16& suffix) { + std::list<RegistryEntry*> entries; + STLElementDeleter<std::list<RegistryEntry*> > entries_deleter(&entries); + RegistryEntry::GetProgIdEntries(dist, chrome_exe, suffix, &entries); + RegistryEntry::GetSystemEntries(dist, chrome_exe, suffix, &entries); + return AreEntriesRegistered(entries); +} + // This method checks if Chrome is already registered on the local machine // for the requested protocol. It just checks the one value required for this. bool IsChromeRegisteredForProtocol(BrowserDistribution* dist, - const std::wstring& suffix, - const std::wstring& protocol) { - bool registered = true; + const string16& suffix, + const string16& protocol) { std::list<RegistryEntry*> entries; STLElementDeleter<std::list<RegistryEntry*> > entries_deleter(&entries); RegistryEntry::GetProtocolCapabilityEntries(dist, suffix, protocol, &entries); - for (std::list<RegistryEntry*>::const_iterator itr = entries.begin(); - itr != entries.end() && registered; ++itr) { - // We do not need registered = registered && ... since the loop condition - // is set to exit early. - registered = (*itr)->ExistsInHKLM(); - } - return registered; + return AreEntriesRegistered(entries); } // This method registers Chrome on Vista by launching an elevated setup.exe. @@ -400,9 +484,9 @@ bool IsChromeRegisteredForProtocol(BrowserDistribution* dist, // If protocol is non-empty we will also register Chrome as being capable of // handling the protocol. bool ElevateAndRegisterChrome(BrowserDistribution* dist, - const std::wstring& chrome_exe, - const std::wstring& suffix, - const std::wstring& protocol) { + const string16& chrome_exe, + const string16& suffix, + const string16& protocol) { FilePath exe_path = FilePath::FromWStringHack(chrome_exe).DirName() .Append(installer::kSetupExe); @@ -410,7 +494,7 @@ bool ElevateAndRegisterChrome(BrowserDistribution* dist, HKEY reg_root = InstallUtil::IsPerUserInstall(chrome_exe.c_str()) ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE; RegKey key(reg_root, dist->GetUninstallRegPath().c_str(), KEY_READ); - std::wstring uninstall_string; + string16 uninstall_string; key.ReadValue(installer::kUninstallStringField, &uninstall_string); CommandLine command_line = CommandLine::FromString(uninstall_string); exe_path = command_line.GetProgram(); @@ -455,12 +539,12 @@ bool ElevateAndRegisterChrome(BrowserDistribution* dist, // <user>\Local Settings\Application Data\Chromium\Application) the value // of the above key should differ from |chrome_exe| only in user name. bool AnotherUserHasDefaultBrowser(BrowserDistribution* dist, - const std::wstring& chrome_exe) { - const std::wstring reg_key( - RegistryEntry::GetBrowserClientKey(dist, std::wstring()) + const string16& chrome_exe) { + const string16 reg_key( + RegistryEntry::GetBrowserClientKey(dist, string16()) .append(ShellUtil::kRegShellOpen)); RegKey key(HKEY_LOCAL_MACHINE, reg_key.c_str(), KEY_READ); - std::wstring registry_chrome_exe; + string16 registry_chrome_exe; if ((key.ReadValue(L"", ®istry_chrome_exe) != ERROR_SUCCESS) || registry_chrome_exe.length() < 2) return false; @@ -474,19 +558,19 @@ bool AnotherUserHasDefaultBrowser(BrowserDistribution* dist, return false; } - std::vector<std::wstring> v1, v2; + std::vector<string16> v1, v2; base::SplitString(registry_chrome_exe, L'\\', &v1); base::SplitString(chrome_exe, L'\\', &v2); if (v1.empty() || v2.empty() || v1.size() != v2.size()) return false; // Now check that only one of the values within two '\' chars differ. - std::vector<std::wstring>::iterator itr1 = v1.begin(); - std::vector<std::wstring>::iterator itr2 = v2.begin(); + std::vector<string16>::iterator itr1 = v1.begin(); + std::vector<string16>::iterator itr2 = v2.begin(); bool one_mismatch = false; for ( ; itr1 < v1.end() && itr2 < v2.end(); ++itr1, ++itr2) { - std::wstring s1 = *itr1; - std::wstring s2 = *itr2; + string16 s1 = *itr1; + string16 s2 = *itr2; if ((s1.size() != s2.size()) || (!std::equal(s1.begin(), s1.end(), s2.begin(), base::CaseInsensitiveCompare<wchar_t>()))) { @@ -502,7 +586,7 @@ bool AnotherUserHasDefaultBrowser(BrowserDistribution* dist, // Launches the Windows 7 and Windows 8 application association dialog, which // is the only documented way to make a browser the default browser on // Windows 8. -bool LaunchApplicationAssociationDialog(const std::wstring& app_id) { +bool LaunchApplicationAssociationDialog(const string16& app_id) { base::win::ScopedComPtr<IApplicationAssociationRegistrationUI> aarui; HRESULT hr = aarui.CreateInstance(CLSID_ApplicationAssociationRegistrationUI); if (FAILED(hr)) @@ -553,31 +637,29 @@ const wchar_t* ShellUtil::kPotentialProtocolAssociations[] = {L"ftp", L"http", L"https", L"irc", L"mailto", L"mms", L"news", L"nntp", L"sms", L"smsto", L"tel", L"urn", L"webcal", NULL}; const wchar_t* ShellUtil::kRegUrlProtocol = L"URL Protocol"; - -bool ShellUtil::AdminNeededForRegistryCleanup(BrowserDistribution* dist, - const std::wstring& suffix) { - bool cleanup_needed = false; - std::list<RegistryEntry*> entries; - STLElementDeleter<std::list<RegistryEntry*> > entries_deleter(&entries); - RegistryEntry::GetProgIdEntries(dist, L"chrome.exe", suffix, &entries); - RegistryEntry::GetSystemEntries(dist, L"chrome.exe", suffix, &entries); - for (std::list<RegistryEntry*>::const_iterator itr = entries.begin(); - itr != entries.end() && !cleanup_needed; ++itr) { - cleanup_needed = (*itr)->NameExistsInHKLM(); - } - return cleanup_needed; -} +const wchar_t* ShellUtil::kRegApplication = L"\\Application"; +const wchar_t* ShellUtil::kRegAppUserModelId = L"AppUserModelId"; +const wchar_t* ShellUtil::kRegApplicationDescription = + L"ApplicationDescription"; +const wchar_t* ShellUtil::kRegApplicationName = L"ApplicationName"; +const wchar_t* ShellUtil::kRegApplicationIcon = L"ApplicationIcon"; +const wchar_t* ShellUtil::kRegApplicationCompany = L"ApplicationCompany"; +const wchar_t* ShellUtil::kRegExePath = L"\\.exe"; +const wchar_t* ShellUtil::kRegVerbOpen = L"open"; +const wchar_t* ShellUtil::kRegVerbRun = L"run"; +const wchar_t* ShellUtil::kRegCommand = L"command"; +const wchar_t* ShellUtil::kRegDelegateExecute = L"DelegateExecute"; bool ShellUtil::CreateChromeDesktopShortcut(BrowserDistribution* dist, - const std::wstring& chrome_exe, - const std::wstring& description, - const std::wstring& appended_name, - const std::wstring& arguments, - const std::wstring& icon_path, + const string16& chrome_exe, + const string16& description, + const string16& appended_name, + const string16& arguments, + const string16& icon_path, int icon_index, ShellChange shell_change, uint32 options) { - std::wstring shortcut_name; + string16 shortcut_name; bool alternate = (options & ShellUtil::SHORTCUT_ALTERNATE) != 0; if (!ShellUtil::GetChromeShortcutName(dist, alternate, appended_name, &shortcut_name)) @@ -626,10 +708,10 @@ bool ShellUtil::CreateChromeDesktopShortcut(BrowserDistribution* dist, } bool ShellUtil::CreateChromeQuickLaunchShortcut(BrowserDistribution* dist, - const std::wstring& chrome_exe, + const string16& chrome_exe, int shell_change, uint32 options) { - std::wstring shortcut_name; + string16 shortcut_name; if (!ShellUtil::GetChromeShortcutName(dist, false, L"", &shortcut_name)) return false; @@ -668,22 +750,26 @@ bool ShellUtil::CreateChromeQuickLaunchShortcut(BrowserDistribution* dist, return ret; } -std::wstring ShellUtil::GetChromeIcon(BrowserDistribution* dist, - const std::wstring& chrome_exe) { - std::wstring chrome_icon(chrome_exe); +string16 ShellUtil::GetChromeIcon(BrowserDistribution* dist, + const string16& chrome_exe) { + string16 chrome_icon(chrome_exe); chrome_icon.append(L","); chrome_icon.append(base::IntToString16(dist->GetIconIndex())); return chrome_icon; } -std::wstring ShellUtil::GetChromeShellOpenCmd(const std::wstring& chrome_exe) { +string16 ShellUtil::GetChromeShellOpenCmd(const string16& chrome_exe) { return L"\"" + chrome_exe + L"\" -- \"%1\""; } +string16 ShellUtil::GetChromeDelegateCommand(const string16& chrome_exe) { + return L"\"" + chrome_exe + L"\" -- %*"; +} + bool ShellUtil::GetChromeShortcutName(BrowserDistribution* dist, bool alternate, - const std::wstring& appended_name, - std::wstring* shortcut) { + const string16& appended_name, + string16* shortcut) { shortcut->assign(alternate ? dist->GetAlternateApplicationName() : dist->GetAppShortCutName()); if (!appended_name.empty()) { @@ -737,13 +823,13 @@ bool ShellUtil::GetQuickLaunchPath(bool system_level, FilePath* path) { void ShellUtil::GetRegisteredBrowsers( BrowserDistribution* dist, - std::map<std::wstring, std::wstring>* browsers) { + std::map<string16, string16>* browsers) { const HKEY root = HKEY_LOCAL_MACHINE; - const std::wstring base_key(ShellUtil::kRegStartMenuInternet); - std::wstring client_path; + const string16 base_key(ShellUtil::kRegStartMenuInternet); + string16 client_path; RegKey key; - std::wstring name; - std::wstring command; + string16 name; + string16 command; for (base::win::RegistryKeyIterator iter(root, base_key.c_str()); iter.Valid(); ++iter) { client_path.assign(base_key).append(1, L'\\').append(iter.Name()); @@ -759,13 +845,13 @@ void ShellUtil::GetRegisteredBrowsers( continue; } if (!name.empty() && !command.empty() && - name.find(dist->GetApplicationName()) == std::wstring::npos) + name.find(dist->GetApplicationName()) == string16::npos) (*browsers)[name] = command; } } bool ShellUtil::GetUserSpecificDefaultBrowserSuffix(BrowserDistribution* dist, - std::wstring* entry) { + string16* entry) { wchar_t user_name[256]; DWORD size = arraysize(user_name); if (::GetUserName(user_name, &size) == 0 || size < 1) @@ -781,7 +867,7 @@ bool ShellUtil::GetUserSpecificDefaultBrowserSuffix(BrowserDistribution* dist, bool ShellUtil::MakeChromeDefault(BrowserDistribution* dist, int shell_change, - const std::wstring& chrome_exe, + const string16& chrome_exe, bool elevate_if_not_admin) { if (!dist->CanSetAsDefault()) return false; @@ -791,8 +877,8 @@ bool ShellUtil::MakeChromeDefault(BrowserDistribution* dist, bool ret = true; // First use the new "recommended" way on Vista to make Chrome default // browser. - std::wstring app_name = dist->GetApplicationName(); - std::wstring app_suffix; + string16 app_name = dist->GetApplicationName(); + string16 app_suffix; if (ShellUtil::GetUserSpecificDefaultBrowserSuffix(dist, &app_suffix)) app_name += app_suffix; @@ -844,7 +930,7 @@ bool ShellUtil::MakeChromeDefault(BrowserDistribution* dist, std::list<RegistryEntry*> entries; STLElementDeleter<std::list<RegistryEntry*> > entries_deleter(&entries); - std::wstring suffix; + string16 suffix; if (!GetUserSpecificDefaultBrowserSuffix(dist, &suffix)) suffix = L""; RegistryEntry::GetUserEntries(dist, chrome_exe, suffix, &entries); @@ -869,8 +955,8 @@ bool ShellUtil::MakeChromeDefault(BrowserDistribution* dist, } bool ShellUtil::MakeChromeDefaultProtocolClient(BrowserDistribution* dist, - const std::wstring& chrome_exe, - const std::wstring& protocol) { + const string16& chrome_exe, + const string16& protocol) { if (!dist->CanSetAsDefault()) return false; @@ -886,8 +972,8 @@ bool ShellUtil::MakeChromeDefaultProtocolClient(BrowserDistribution* dist, HRESULT hr = pAAR.CreateInstance(CLSID_ApplicationAssociationRegistration, NULL, CLSCTX_INPROC); if (SUCCEEDED(hr)) { - std::wstring app_name = dist->GetApplicationName(); - std::wstring suffix; + string16 app_name = dist->GetApplicationName(); + string16 suffix; if (ShellUtil::GetUserSpecificDefaultBrowserSuffix(dist, &suffix)) app_name += suffix; @@ -907,11 +993,11 @@ bool ShellUtil::MakeChromeDefaultProtocolClient(BrowserDistribution* dist, std::list<RegistryEntry*> entries; STLElementDeleter<std::list<RegistryEntry*> > entries_deleter(&entries); - std::wstring suffix; + string16 suffix; if (!GetUserSpecificDefaultBrowserSuffix(dist, &suffix)) suffix = L""; - std::wstring chrome_open = ShellUtil::GetChromeShellOpenCmd(chrome_exe); - std::wstring chrome_icon = ShellUtil::GetChromeIcon(dist, chrome_exe); + string16 chrome_open = ShellUtil::GetChromeShellOpenCmd(chrome_exe); + string16 chrome_icon = ShellUtil::GetChromeIcon(dist, chrome_exe); RegistryEntry::GetUserProtocolEntries(protocol, chrome_icon, chrome_open, &entries); // Change the default protocol handler for current user. @@ -924,15 +1010,15 @@ bool ShellUtil::MakeChromeDefaultProtocolClient(BrowserDistribution* dist, } bool ShellUtil::RegisterChromeBrowser(BrowserDistribution* dist, - const std::wstring& chrome_exe, - const std::wstring& unique_suffix, + const string16& chrome_exe, + const string16& unique_suffix, bool elevate_if_not_admin) { if (!dist->CanSetAsDefault()) return false; // First figure out we need to append a suffix to the registry entries to // make them unique. - std::wstring suffix; + string16 suffix; if (!unique_suffix.empty()) { suffix = unique_suffix; } else if (InstallUtil::IsPerUserInstall(chrome_exe.c_str()) && @@ -947,11 +1033,17 @@ bool ShellUtil::RegisterChromeBrowser(BrowserDistribution* dist, // If user is an admin try to register and return the status. if (IsUserAnAdmin()) { - std::list<RegistryEntry*> entries; - STLElementDeleter<std::list<RegistryEntry*> > entries_deleter(&entries); - RegistryEntry::GetProgIdEntries(dist, chrome_exe, suffix, &entries); - RegistryEntry::GetSystemEntries(dist, chrome_exe, suffix, &entries); - return AddRegistryEntries(HKEY_LOCAL_MACHINE, entries); + std::list<RegistryEntry*> progids; + STLElementDeleter<std::list<RegistryEntry*> > progids_deleter(&progids); + std::list<RegistryEntry*> sys_entries; + STLElementDeleter<std::list<RegistryEntry*> > sys_deleter(&sys_entries); + RegistryEntry::GetProgIdEntries(dist, chrome_exe, suffix, &progids); + RegistryEntry::GetSystemEntries(dist, chrome_exe, suffix, &sys_entries); + return AddRegistryEntries( + InstallUtil::IsPerUserInstall(chrome_exe.c_str()) ? + HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE, + progids) && + AddRegistryEntries(HKEY_LOCAL_MACHINE, sys_entries); } // If user is not an admin and OS is Vista, try to elevate and register. @@ -969,16 +1061,16 @@ bool ShellUtil::RegisterChromeBrowser(BrowserDistribution* dist, } bool ShellUtil::RegisterChromeForProtocol(BrowserDistribution* dist, - const std::wstring& chrome_exe, - const std::wstring& unique_suffix, - const std::wstring& protocol, + const string16& chrome_exe, + const string16& unique_suffix, + const string16& protocol, bool elevate_if_not_admin) { if (!dist->CanSetAsDefault()) return false; // Figure out we need to append a suffix to the registry entries to // make them unique. - std::wstring suffix; + string16 suffix; if (!unique_suffix.empty()) { suffix = unique_suffix; } else if (InstallUtil::IsPerUserInstall(chrome_exe.c_str()) && @@ -1022,7 +1114,7 @@ bool ShellUtil::RemoveChromeDesktopShortcut(BrowserDistribution* dist, // Only SHORTCUT_ALTERNATE is a valid option for this function. DCHECK(!options || options == ShellUtil::SHORTCUT_ALTERNATE); - std::wstring shortcut_name; + string16 shortcut_name; bool alternate = (options & ShellUtil::SHORTCUT_ALTERNATE) != 0; if (!ShellUtil::GetChromeShortcutName(dist, alternate, L"", &shortcut_name)) @@ -1052,11 +1144,11 @@ bool ShellUtil::RemoveChromeDesktopShortcut(BrowserDistribution* dist, } bool ShellUtil::RemoveChromeDesktopShortcutsWithAppendedNames( - const std::vector<std::wstring>& appended_names) { + const std::vector<string16>& appended_names) { FilePath shortcut_path; bool ret = true; if (ShellUtil::GetDesktopPath(false, &shortcut_path)) { - for (std::vector<std::wstring>::const_iterator it = + for (std::vector<string16>::const_iterator it = appended_names.begin(); it != appended_names.end(); ++it) { @@ -1071,7 +1163,7 @@ bool ShellUtil::RemoveChromeDesktopShortcutsWithAppendedNames( bool ShellUtil::RemoveChromeQuickLaunchShortcut(BrowserDistribution* dist, int shell_change) { - std::wstring shortcut_name; + string16 shortcut_name; if (!ShellUtil::GetChromeShortcutName(dist, false, L"", &shortcut_name)) return false; @@ -1102,14 +1194,14 @@ bool ShellUtil::RemoveChromeQuickLaunchShortcut(BrowserDistribution* dist, } bool ShellUtil::UpdateChromeShortcut(BrowserDistribution* dist, - const std::wstring& chrome_exe, - const std::wstring& shortcut, - const std::wstring& arguments, - const std::wstring& description, - const std::wstring& icon_path, + const string16& chrome_exe, + const string16& shortcut, + const string16& arguments, + const string16& description, + const string16& icon_path, int icon_index, uint32 options) { - std::wstring chrome_path = FilePath(chrome_exe).DirName().value(); + string16 chrome_path = FilePath(chrome_exe).DirName().value(); FilePath prefs_path(chrome_path); prefs_path = prefs_path.AppendASCII(installer::kDefaultMasterPrefs); diff --git a/chrome/installer/util/shell_util.h b/chrome/installer/util/shell_util.h index 8f55943..85e5fbd 100644 --- a/chrome/installer/util/shell_util.h +++ b/chrome/installer/util/shell_util.h @@ -13,10 +13,10 @@ #include <windows.h> #include <map> -#include <string> #include <vector> #include "base/basictypes.h" +#include "base/string16.h" #include "chrome/installer/util/work_item_list.h" class BrowserDistribution; @@ -88,10 +88,39 @@ class ShellUtil { // Registry value name that is needed for ChromeHTML ProgId static const wchar_t* kRegUrlProtocol; - // Checks if we need Admin rights for registry cleanup by checking if any - // entry exists in HKLM. - static bool AdminNeededForRegistryCleanup(BrowserDistribution* dist, - const std::wstring& suffix); + // Relative registry path from \Software\Classes\ChromeHTML to the ProgId + // Application definitions. + static const wchar_t* kRegApplication; + + // Registry value name for the AppUserModelId of an application. + static const wchar_t* kRegAppUserModelId; + + // Registry value name for the description of an application. + static const wchar_t* kRegApplicationDescription; + + // Registry value name for an application's name. + static const wchar_t* kRegApplicationName; + + // Registry value name for the path to an application's icon. + static const wchar_t* kRegApplicationIcon; + + // Registry value name for an application's company. + static const wchar_t* kRegApplicationCompany; + + // Relative path of ".exe" registry key. + static const wchar_t* kRegExePath; + + // Registry value name of the open verb. + static const wchar_t* kRegVerbOpen; + + // Registry value name of the run verb. + static const wchar_t* kRegVerbRun; + + // Registry value name for command entries. + static const wchar_t* kRegCommand; + + // Registry value name for the DelegateExecute verb handler. + static const wchar_t* kRegDelegateExecute; // Creates Chrome shortcut on the Desktop. // |dist| gives the type of browser distribution currently in use. @@ -109,11 +138,11 @@ class ShellUtil { // |options|: bitfield for which the options come from ChromeShortcutOptions. // Returns true iff the method causes a shortcut to be created / updated. static bool CreateChromeDesktopShortcut(BrowserDistribution* dist, - const std::wstring& chrome_exe, - const std::wstring& description, - const std::wstring& appended_name, - const std::wstring& arguments, - const std::wstring& icon_path, + const string16& chrome_exe, + const string16& description, + const string16& appended_name, + const string16& arguments, + const string16& icon_path, int icon_index, ShellChange shell_change, uint32 options); @@ -127,7 +156,7 @@ class ShellUtil { // system. // |options|: bitfield for which the options come from ChromeShortcutOptions. static bool CreateChromeQuickLaunchShortcut(BrowserDistribution* dist, - const std::wstring& chrome_exe, + const string16& chrome_exe, int shell_change, uint32 options); @@ -135,13 +164,19 @@ class ShellUtil { // chrome.exe path passed in as input, to generate the full path for // Chrome icon that can be used as value for Windows registry keys. // |chrome_exe| full path to chrome.exe. - static std::wstring GetChromeIcon(BrowserDistribution* dist, - const std::wstring& chrome_exe); + static string16 GetChromeIcon(BrowserDistribution* dist, + const string16& chrome_exe); // This method returns the command to open URLs/files using chrome. Typically // this command is written to the registry under shell\open\command key. - // chrome_exe: the full path to chrome.exe - static std::wstring GetChromeShellOpenCmd(const std::wstring& chrome_exe); + // |chrome_exe|: the full path to chrome.exe + static string16 GetChromeShellOpenCmd(const string16& chrome_exe); + + // This method returns the command to be called by the DelegateExecute verb + // handler to launch chrome on Windows 8. Typically this command is written to + // the registry under the HKCR\Chrome\.exe\shell\(open|run)\command key. + // |chrome_exe|: the full path to chrome.exe + static string16 GetChromeDelegateCommand(const string16& chrome_exe); // Returns the localized name of Chrome shortcut in |shortcut|. If // |appended_name| is not empty, it is included in the shortcut name. If @@ -149,8 +184,8 @@ class ShellUtil { // certain scenarios is used. static bool GetChromeShortcutName(BrowserDistribution* dist, bool alternate, - const std::wstring& appended_name, - std::wstring* shortcut); + const string16& appended_name, + string16* shortcut); // Gets the desktop path for the current user or all users (if system_level // is true) and returns it in 'path' argument. Return true if successful, @@ -167,8 +202,7 @@ class ShellUtil { // Gets a mapping of all registered browser (on local machine) names and // their reinstall command (which usually sets browser as default). static void GetRegisteredBrowsers(BrowserDistribution* dist, - std::map<std::wstring, - std::wstring>* browsers); + std::map<string16, string16>* browsers); // This function gets a suffix (user's login name) that can be added // to Chromium default browser entry in the registry to create a unique name @@ -178,7 +212,7 @@ class ShellUtil { // existence of Default Browser registry key with this suffix and // returns true if it exists. In all other cases it returns false. static bool GetUserSpecificDefaultBrowserSuffix(BrowserDistribution* dist, - std::wstring* entry); + string16* entry); // Make Chrome the default browser. This function works by going through // the url protocols and file associations that are related to general @@ -200,15 +234,15 @@ class ShellUtil { // Chrome registration. static bool MakeChromeDefault(BrowserDistribution* dist, int shell_change, - const std::wstring& chrome_exe, + const string16& chrome_exe, bool elevate_if_not_admin); // Make Chrome the default application for a protocol. // chrome_exe: The chrome.exe path to register as default browser. // protocol: The protocol to register as the default handler for. static bool MakeChromeDefaultProtocolClient(BrowserDistribution* dist, - const std::wstring& chrome_exe, - const std::wstring& protocol); + const string16& chrome_exe, + const string16& protocol); // This method adds Chrome to the list that shows up in Add/Remove Programs-> // Set Program Access and Defaults and also creates Chrome ProgIds under @@ -232,8 +266,8 @@ class ShellUtil { // |elevate_if_not_admin| if true will make this method try alternate methods // as described above. static bool RegisterChromeBrowser(BrowserDistribution* dist, - const std::wstring& chrome_exe, - const std::wstring& unique_suffix, + const string16& chrome_exe, + const string16& unique_suffix, bool elevate_if_not_admin); // This method declares to Windows that Chrome is capable of handling the @@ -254,9 +288,9 @@ class ShellUtil { // |elevate_if_not_admin| if true will make this method try alternate methods // as described above. static bool RegisterChromeForProtocol(BrowserDistribution* dist, - const std::wstring& chrome_exe, - const std::wstring& unique_suffix, - const std::wstring& protocol, + const string16& chrome_exe, + const string16& unique_suffix, + const string16& protocol, bool elevate_if_not_admin); // Remove Chrome shortcut from Desktop. @@ -274,7 +308,7 @@ class ShellUtil { // list of shortcut file names as obtained from // ShellUtil::GetChromeShortcutName. static bool RemoveChromeDesktopShortcutsWithAppendedNames( - const std::vector<std::wstring>& appended_names); + const std::vector<string16>& appended_names); // Remove Chrome shortcut from Quick Launch Bar. // If shell_change is CURRENT_USER, the shortcut is removed from @@ -303,11 +337,11 @@ class ShellUtil { // shortcut if it doesn't exist. // |options|: bitfield for which the options come from ChromeShortcutOptions. static bool UpdateChromeShortcut(BrowserDistribution* dist, - const std::wstring& chrome_exe, - const std::wstring& shortcut, - const std::wstring& arguments, - const std::wstring& description, - const std::wstring& icon_path, + const string16& chrome_exe, + const string16& shortcut, + const string16& arguments, + const string16& description, + const string16& icon_path, int icon_index, uint32 options); |