| Index: chrome/installer/util/shell_util.cc
|
| diff --git a/chrome/installer/util/shell_util.cc b/chrome/installer/util/shell_util.cc
|
| index 4b6b74cd9ea43cb066c7006038b974c7700e6f05..af9108282b1f6516357f75f1e69404c3fa07a483 100644
|
| --- a/chrome/installer/util/shell_util.cc
|
| +++ b/chrome/installer/util/shell_util.cc
|
| @@ -221,83 +221,19 @@ class RegistryEntry {
|
| // user-specific registration suffix; see GetUserSpecificDefaultBrowserSuffix
|
| // in shell_util.h for details.
|
| static base::string16 GetBrowserClientKey(BrowserDistribution* dist,
|
| - const base::string16& suffix) {
|
| - DCHECK(suffix.empty() || suffix[0] == L'.');
|
| - return base::string16(ShellUtil::kRegStartMenuInternet)
|
| - .append(1, L'\\')
|
| - .append(dist->GetBaseAppName())
|
| - .append(suffix);
|
| - }
|
| + const base::string16& suffix);
|
|
|
| // Returns the Windows Default Programs capabilities key for Chrome. For
|
| // example:
|
| // "Software\Clients\StartMenuInternet\Chromium[.user]\Capabilities".
|
| static base::string16 GetCapabilitiesKey(BrowserDistribution* dist,
|
| - const base::string16& suffix) {
|
| - return GetBrowserClientKey(dist, suffix).append(L"\\Capabilities");
|
| - }
|
| + const base::string16& suffix);
|
|
|
| // DelegateExecute ProgId. Needed for Chrome Metro in Windows 8. This is
|
| // only needed for registring a web browser, not for general associations.
|
| static ScopedVector<RegistryEntry> GetChromeDelegateExecuteEntries(
|
| const base::FilePath& chrome_exe,
|
| - const ApplicationInfo& app_info) {
|
| - ScopedVector<RegistryEntry> entries;
|
| -
|
| - base::string16 app_id_shell_key(ShellUtil::kRegClasses);
|
| - app_id_shell_key.push_back(base::FilePath::kSeparators[0]);
|
| - app_id_shell_key.append(app_info.app_id);
|
| - app_id_shell_key.append(ShellUtil::kRegExePath);
|
| - app_id_shell_key.append(ShellUtil::kRegShellPath);
|
| -
|
| - // <root hkey>\Software\Classes\<app_id>\.exe\shell @=open
|
| - entries.push_back(
|
| - new RegistryEntry(app_id_shell_key, ShellUtil::kRegVerbOpen));
|
| -
|
| - // The command to execute when opening this application via the Metro UI.
|
| - const base::string16 delegate_command(
|
| - ShellUtil::GetChromeDelegateCommand(chrome_exe));
|
| -
|
| - // Each of Chrome's shortcuts has an appid; which, as of Windows 8, is
|
| - // registered to handle some verbs. This registration has the side-effect
|
| - // that these verbs now show up in the shortcut's context menu. We
|
| - // mitigate this side-effect by making the context menu entries
|
| - // user readable/localized strings. See relevant MSDN article:
|
| - // http://msdn.microsoft.com/en-US/library/windows/desktop/cc144171.aspx
|
| - static const struct {
|
| - const wchar_t* verb;
|
| - int name_id;
|
| - } verbs[] = {
|
| - {ShellUtil::kRegVerbOpen, -1},
|
| - {ShellUtil::kRegVerbOpenNewWindow, IDS_SHORTCUT_NEW_WINDOW_BASE},
|
| - };
|
| - for (const auto& verb_and_id : verbs) {
|
| - base::string16 sub_path(app_id_shell_key);
|
| - sub_path.push_back(base::FilePath::kSeparators[0]);
|
| - sub_path.append(verb_and_id.verb);
|
| -
|
| - // <root hkey>\Software\Classes\<app_id>\.exe\shell\<verb>
|
| - if (verb_and_id.name_id != -1) {
|
| - // TODO(grt): http://crbug.com/75152 Write a reference to a localized
|
| - // resource.
|
| - const base::string16 verb_name(
|
| - installer::GetLocalizedString(verb_and_id.name_id));
|
| - entries.push_back(new RegistryEntry(sub_path, verb_name.c_str()));
|
| - }
|
| - entries.push_back(
|
| - new RegistryEntry(sub_path, L"CommandId", L"Browser.Launch"));
|
| -
|
| - sub_path.push_back(base::FilePath::kSeparators[0]);
|
| - sub_path.append(ShellUtil::kRegCommand);
|
| -
|
| - // <root hkey>\Software\Classes\<app_id>\.exe\shell\<verb>\command
|
| - entries.push_back(new RegistryEntry(sub_path, delegate_command));
|
| - entries.push_back(new RegistryEntry(
|
| - sub_path, ShellUtil::kRegDelegateExecute, app_info.delegate_clsid));
|
| - }
|
| -
|
| - return entries.Pass();
|
| - }
|
| + const ApplicationInfo& app_info);
|
|
|
| // This method returns a list of all the registry entries that
|
| // are needed to register this installation's ProgId and AppId.
|
| @@ -305,121 +241,12 @@ class RegistryEntry {
|
| static void GetChromeProgIdEntries(BrowserDistribution* dist,
|
| const base::FilePath& chrome_exe,
|
| const base::string16& suffix,
|
| - ScopedVector<RegistryEntry>* entries) {
|
| - int chrome_icon_index =
|
| - dist->GetIconIndex(BrowserDistribution::SHORTCUT_CHROME);
|
| -
|
| - ApplicationInfo app_info;
|
| - app_info.prog_id = GetBrowserProgId(suffix);
|
| - app_info.file_type_name = dist->GetBrowserProgIdDesc();
|
| - // File types associated with Chrome are just given the Chrome icon.
|
| - app_info.file_type_icon_path = chrome_exe;
|
| - app_info.file_type_icon_index = chrome_icon_index;
|
| - app_info.command_line = ShellUtil::GetChromeShellOpenCmd(chrome_exe);
|
| - // For user-level installs: entries for the app id will be in HKCU; thus we
|
| - // do not need a suffix on those entries.
|
| - app_info.app_id = ShellUtil::GetBrowserModelId(
|
| - dist, InstallUtil::IsPerUserInstall(chrome_exe));
|
| -
|
| - // TODO(grt): http://crbug.com/75152 Write a reference to a localized
|
| - // resource for name, description, and company.
|
| - app_info.application_name = dist->GetDisplayName();
|
| - app_info.application_icon_path = chrome_exe;
|
| - app_info.application_icon_index = chrome_icon_index;
|
| - app_info.application_description = dist->GetAppDescription();
|
| - app_info.publisher_name = dist->GetPublisherName();
|
| -
|
| - app_info.delegate_clsid = dist->GetCommandExecuteImplClsid();
|
| -
|
| - GetProgIdEntries(app_info, entries);
|
| -
|
| - if (!app_info.delegate_clsid.empty()) {
|
| - ScopedVector<RegistryEntry> delegate_execute_entries =
|
| - GetChromeDelegateExecuteEntries(chrome_exe, app_info);
|
| - if (!base::win::IsChromeMetroSupported()) {
|
| - // Remove the keys (not only their values) so that Windows will continue
|
| - // to launch Chrome without a pesky association error.
|
| - for (RegistryEntry* entry : delegate_execute_entries)
|
| - entry->set_removal_flag(RemovalFlag::KEY);
|
| - }
|
| - // Move |delegate_execute_entries| to |entries|.
|
| - entries->insert(entries->end(), delegate_execute_entries.begin(),
|
| - delegate_execute_entries.end());
|
| - delegate_execute_entries.weak_clear();
|
| - }
|
| - }
|
| + ScopedVector<RegistryEntry>* entries);
|
|
|
| // Gets the registry entries to register an application in the Windows
|
| // registry. |app_info| provides all of the information needed.
|
| static void GetProgIdEntries(const ApplicationInfo& app_info,
|
| - ScopedVector<RegistryEntry>* entries) {
|
| - // Basic sanity checks.
|
| - DCHECK(!app_info.prog_id.empty());
|
| - DCHECK_NE(L'.', app_info.prog_id[0]);
|
| -
|
| - // File association ProgId
|
| - base::string16 prog_id_path(ShellUtil::kRegClasses);
|
| - prog_id_path.push_back(base::FilePath::kSeparators[0]);
|
| - prog_id_path.append(app_info.prog_id);
|
| - entries->push_back(
|
| - new RegistryEntry(prog_id_path, app_info.file_type_name));
|
| - entries->push_back(new RegistryEntry(
|
| - prog_id_path + ShellUtil::kRegDefaultIcon,
|
| - ShellUtil::FormatIconLocation(app_info.file_type_icon_path,
|
| - app_info.file_type_icon_index)));
|
| - entries->push_back(new RegistryEntry(
|
| - prog_id_path + ShellUtil::kRegShellOpen, app_info.command_line));
|
| - if (!app_info.delegate_clsid.empty()) {
|
| - entries->push_back(
|
| - new RegistryEntry(prog_id_path + ShellUtil::kRegShellOpen,
|
| - ShellUtil::kRegDelegateExecute,
|
| - app_info.delegate_clsid));
|
| - // If Metro is not supported, remove the DelegateExecute entry instead of
|
| - // adding it.
|
| - if (!base::win::IsChromeMetroSupported())
|
| - entries->back()->set_removal_flag(RemovalFlag::VALUE);
|
| - }
|
| -
|
| - // The following entries are required as of Windows 8, but do not
|
| - // depend on the DelegateExecute verb handler being set.
|
| - if (base::win::GetVersion() >= base::win::VERSION_WIN8) {
|
| - if (!app_info.app_id.empty()) {
|
| - entries->push_back(new RegistryEntry(
|
| - prog_id_path, ShellUtil::kRegAppUserModelId, app_info.app_id));
|
| - }
|
| -
|
| - // Add \Software\Classes\<prog_id>\Application entries
|
| - base::string16 application_path(prog_id_path +
|
| - ShellUtil::kRegApplication);
|
| - if (!app_info.app_id.empty()) {
|
| - entries->push_back(new RegistryEntry(
|
| - application_path, ShellUtil::kRegAppUserModelId, app_info.app_id));
|
| - }
|
| - if (!app_info.application_icon_path.empty()) {
|
| - entries->push_back(new RegistryEntry(
|
| - application_path,
|
| - ShellUtil::kRegApplicationIcon,
|
| - ShellUtil::FormatIconLocation(app_info.application_icon_path,
|
| - app_info.application_icon_index)));
|
| - }
|
| - if (!app_info.application_name.empty()) {
|
| - entries->push_back(new RegistryEntry(application_path,
|
| - ShellUtil::kRegApplicationName,
|
| - app_info.application_name));
|
| - }
|
| - if (!app_info.application_description.empty()) {
|
| - entries->push_back(
|
| - new RegistryEntry(application_path,
|
| - ShellUtil::kRegApplicationDescription,
|
| - app_info.application_description));
|
| - }
|
| - if (!app_info.publisher_name.empty()) {
|
| - entries->push_back(new RegistryEntry(application_path,
|
| - ShellUtil::kRegApplicationCompany,
|
| - app_info.publisher_name));
|
| - }
|
| - }
|
| - }
|
| + ScopedVector<RegistryEntry>* entries);
|
|
|
| // This method returns a list of the registry entries needed to declare a
|
| // capability of handling a protocol on Windows.
|
| @@ -427,11 +254,7 @@ class RegistryEntry {
|
| BrowserDistribution* dist,
|
| const base::string16& suffix,
|
| const base::string16& protocol,
|
| - ScopedVector<RegistryEntry>* entries) {
|
| - entries->push_back(new RegistryEntry(
|
| - GetCapabilitiesKey(dist, suffix).append(L"\\URLAssociations"),
|
| - protocol, GetBrowserProgId(suffix)));
|
| - }
|
| + ScopedVector<RegistryEntry>* entries);
|
|
|
| // This method returns a list of the registry entries required to register
|
| // this installation in "RegisteredApplications" on Windows (to appear in
|
| @@ -442,76 +265,7 @@ class RegistryEntry {
|
| static void GetShellIntegrationEntries(BrowserDistribution* dist,
|
| const base::FilePath& chrome_exe,
|
| const base::string16& suffix,
|
| - ScopedVector<RegistryEntry>* entries) {
|
| - const base::string16 icon_path(
|
| - ShellUtil::FormatIconLocation(
|
| - chrome_exe,
|
| - dist->GetIconIndex(BrowserDistribution::SHORTCUT_CHROME)));
|
| - const base::string16 quoted_exe_path(L"\"" + chrome_exe.value() + L"\"");
|
| -
|
| - // Register for the Start Menu "Internet" link (pre-Win7).
|
| - const base::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
|
| - entries->push_back(new RegistryEntry(
|
| - start_menu_entry, dist->GetDisplayName()));
|
| - // Register the "open" verb for launching Chrome via the "Internet" link.
|
| - entries->push_back(new RegistryEntry(
|
| - start_menu_entry + ShellUtil::kRegShellOpen, quoted_exe_path));
|
| - // Register Chrome's icon for the Start Menu "Internet" link.
|
| - entries->push_back(new RegistryEntry(
|
| - start_menu_entry + ShellUtil::kRegDefaultIcon, icon_path));
|
| -
|
| - // Register installation information.
|
| - base::string16 install_info(start_menu_entry + L"\\InstallInfo");
|
| - // Note: not using CommandLine since it has ambiguous rules for quoting
|
| - // strings.
|
| - entries->push_back(new RegistryEntry(install_info, kReinstallCommand,
|
| - quoted_exe_path + L" --" +
|
| - base::ASCIIToUTF16(switches::kMakeDefaultBrowser)));
|
| - entries->push_back(new RegistryEntry(install_info, L"HideIconsCommand",
|
| - quoted_exe_path + L" --" +
|
| - base::ASCIIToUTF16(switches::kHideIcons)));
|
| - entries->push_back(new RegistryEntry(install_info, L"ShowIconsCommand",
|
| - quoted_exe_path + L" --" +
|
| - base::ASCIIToUTF16(switches::kShowIcons)));
|
| - entries->push_back(new RegistryEntry(install_info, L"IconsVisible", 1));
|
| -
|
| - // Register with Default Programs.
|
| - const base::string16 reg_app_name(dist->GetBaseAppName().append(suffix));
|
| - // Tell Windows where to find Chrome's Default Programs info.
|
| - const base::string16 capabilities(GetCapabilitiesKey(dist, suffix));
|
| - entries->push_back(new RegistryEntry(ShellUtil::kRegRegisteredApplications,
|
| - reg_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_back(new RegistryEntry(
|
| - capabilities, ShellUtil::kRegApplicationDescription,
|
| - dist->GetLongAppDescription()));
|
| - entries->push_back(new RegistryEntry(
|
| - capabilities, ShellUtil::kRegApplicationIcon, icon_path));
|
| - entries->push_back(new RegistryEntry(
|
| - capabilities, ShellUtil::kRegApplicationName,
|
| - dist->GetDisplayName()));
|
| -
|
| - entries->push_back(new RegistryEntry(capabilities + L"\\Startmenu",
|
| - L"StartMenuInternet", reg_app_name));
|
| -
|
| - const base::string16 html_prog_id(GetBrowserProgId(suffix));
|
| - for (int i = 0; ShellUtil::kPotentialFileAssociations[i] != NULL; i++) {
|
| - entries->push_back(new RegistryEntry(
|
| - capabilities + L"\\FileAssociations",
|
| - ShellUtil::kPotentialFileAssociations[i], html_prog_id));
|
| - }
|
| - for (int i = 0; ShellUtil::kPotentialProtocolAssociations[i] != NULL;
|
| - i++) {
|
| - entries->push_back(new RegistryEntry(
|
| - capabilities + L"\\URLAssociations",
|
| - ShellUtil::kPotentialProtocolAssociations[i], html_prog_id));
|
| - }
|
| - }
|
| + ScopedVector<RegistryEntry>* entries);
|
|
|
| // This method returns a list of the registry entries required for this
|
| // installation to be registered in the Windows shell.
|
| @@ -524,21 +278,7 @@ class RegistryEntry {
|
| static void GetChromeAppRegistrationEntries(
|
| const base::FilePath& chrome_exe,
|
| const base::string16& suffix,
|
| - ScopedVector<RegistryEntry>* entries) {
|
| - base::string16 app_path_key(ShellUtil::kAppPathsRegistryKey);
|
| - app_path_key.push_back(base::FilePath::kSeparators[0]);
|
| - app_path_key.append(chrome_exe.BaseName().value());
|
| - entries->push_back(new RegistryEntry(app_path_key, chrome_exe.value()));
|
| - entries->push_back(new RegistryEntry(app_path_key,
|
| - ShellUtil::kAppPathsRegistryPathName,
|
| - chrome_exe.DirName().value()));
|
| -
|
| - const base::string16 html_prog_id(GetBrowserProgId(suffix));
|
| - for (int i = 0; ShellUtil::kPotentialFileAssociations[i] != NULL; i++) {
|
| - GetAppExtRegistrationEntries(
|
| - html_prog_id, ShellUtil::kPotentialFileAssociations[i], entries);
|
| - }
|
| - }
|
| + ScopedVector<RegistryEntry>* entries);
|
|
|
| // Gets the registry entries to register an application as a handler for a
|
| // particular file extension. |prog_id| is the ProgId used by Windows for the
|
| @@ -546,16 +286,7 @@ class RegistryEntry {
|
| static void GetAppExtRegistrationEntries(
|
| const base::string16& prog_id,
|
| const base::string16& ext,
|
| - ScopedVector<RegistryEntry>* entries) {
|
| - // In HKEY_CURRENT_USER\Software\Classes\EXT\OpenWithProgids, create an
|
| - // empty value with this class's ProgId.
|
| - base::string16 key_name(ShellUtil::kRegClasses);
|
| - key_name.push_back(base::FilePath::kSeparators[0]);
|
| - key_name.append(ext);
|
| - key_name.push_back(base::FilePath::kSeparators[0]);
|
| - key_name.append(ShellUtil::kRegOpenWithProgids);
|
| - entries->push_back(new RegistryEntry(key_name, prog_id, base::string16()));
|
| - }
|
| + ScopedVector<RegistryEntry>* entries);
|
|
|
| // Gets the registry entries to register an application as the default handler
|
| // for a particular file extension. |prog_id| is the ProgId used by Windows
|
| @@ -572,20 +303,7 @@ class RegistryEntry {
|
| const base::string16& prog_id,
|
| const base::string16& ext,
|
| bool overwrite_existing,
|
| - ScopedVector<RegistryEntry>* entries) {
|
| - // Set the default value of HKEY_CURRENT_USER\Software\Classes\EXT to this
|
| - // class's name.
|
| - base::string16 key_name(ShellUtil::kRegClasses);
|
| - key_name.push_back(base::FilePath::kSeparators[0]);
|
| - key_name.append(ext);
|
| - scoped_ptr<RegistryEntry> default_association(
|
| - new RegistryEntry(key_name, prog_id));
|
| - if (overwrite_existing ||
|
| - !default_association->KeyExistsInRegistry(
|
| - RegistryEntry::LOOK_IN_HKCU)) {
|
| - entries->push_back(default_association.release());
|
| - }
|
| - }
|
| + ScopedVector<RegistryEntry>* entries);
|
|
|
| // This method returns a list of all the user level registry entries that
|
| // are needed to make Chromium the default handler for a protocol on XP.
|
| @@ -593,34 +311,7 @@ class RegistryEntry {
|
| const base::string16& protocol,
|
| const base::string16& chrome_icon,
|
| const base::string16& chrome_open,
|
| - ScopedVector<RegistryEntry>* entries) {
|
| - // Protocols associations.
|
| - base::string16 url_key(ShellUtil::kRegClasses);
|
| - url_key.push_back(base::FilePath::kSeparators[0]);
|
| - url_key.append(protocol);
|
| -
|
| - // This registry value tells Windows that this 'class' is a URL scheme
|
| - // so IE, explorer and other apps will route it to our handler.
|
| - // <root hkey>\Software\Classes\<protocol>\URL Protocol
|
| - entries->push_back(new RegistryEntry(url_key,
|
| - ShellUtil::kRegUrlProtocol, base::string16()));
|
| -
|
| - // <root hkey>\Software\Classes\<protocol>\DefaultIcon
|
| - base::string16 icon_key = url_key + ShellUtil::kRegDefaultIcon;
|
| - entries->push_back(new RegistryEntry(icon_key, chrome_icon));
|
| -
|
| - // <root hkey>\Software\Classes\<protocol>\shell\open\command
|
| - base::string16 shell_key = url_key + ShellUtil::kRegShellOpen;
|
| - entries->push_back(new RegistryEntry(shell_key, chrome_open));
|
| -
|
| - // <root hkey>\Software\Classes\<protocol>\shell\open\ddeexec
|
| - base::string16 dde_key = url_key + L"\\shell\\open\\ddeexec";
|
| - entries->push_back(new RegistryEntry(dde_key, base::string16()));
|
| -
|
| - // <root hkey>\Software\Classes\<protocol>\shell\@
|
| - base::string16 protocol_shell_key = url_key + ShellUtil::kRegShellPath;
|
| - entries->push_back(new RegistryEntry(protocol_shell_key, L"open"));
|
| - }
|
| + ScopedVector<RegistryEntry>* entries);
|
|
|
| // This method returns a list of all the user level registry entries that
|
| // are needed to make Chromium default browser on XP.
|
| @@ -631,30 +322,7 @@ class RegistryEntry {
|
| BrowserDistribution* dist,
|
| const base::FilePath& chrome_exe,
|
| const base::string16& suffix,
|
| - ScopedVector<RegistryEntry>* entries) {
|
| - // File extension associations.
|
| - base::string16 html_prog_id(GetBrowserProgId(suffix));
|
| - for (int i = 0; ShellUtil::kDefaultFileAssociations[i] != NULL; i++) {
|
| - GetAppDefaultRegistrationEntries(
|
| - html_prog_id, ShellUtil::kDefaultFileAssociations[i], true, entries);
|
| - }
|
| -
|
| - // Protocols associations.
|
| - base::string16 chrome_open = ShellUtil::GetChromeShellOpenCmd(chrome_exe);
|
| - base::string16 chrome_icon =
|
| - ShellUtil::FormatIconLocation(
|
| - chrome_exe,
|
| - dist->GetIconIndex(BrowserDistribution::SHORTCUT_CHROME));
|
| - for (int i = 0; ShellUtil::kBrowserProtocolAssociations[i] != NULL; i++) {
|
| - GetXPStyleUserProtocolEntries(ShellUtil::kBrowserProtocolAssociations[i],
|
| - chrome_icon, chrome_open, entries);
|
| - }
|
| -
|
| - // start->Internet shortcut.
|
| - base::string16 start_menu(ShellUtil::kRegStartMenuInternet);
|
| - base::string16 app_name = dist->GetBaseAppName() + suffix;
|
| - entries->push_back(new RegistryEntry(start_menu, app_name));
|
| - }
|
| + ScopedVector<RegistryEntry>* entries);
|
|
|
| // Flags this RegistryKey with |removal_flag|, indicating that it should be
|
| // removed rather than created. Note that this will not result in cleaning up
|
| @@ -669,24 +337,7 @@ class RegistryEntry {
|
| // Generates work_item tasks required to create (or potentially delete based
|
| // on |removal_flag_|) the current RegistryEntry and add them to the given
|
| // work item list.
|
| - void AddToWorkItemList(HKEY root, WorkItemList *items) const {
|
| - if (removal_flag_ == RemovalFlag::VALUE) {
|
| - items->AddDeleteRegValueWorkItem(root, key_path_, WorkItem::kWow64Default,
|
| - name_);
|
| - } else if (removal_flag_ == RemovalFlag::KEY) {
|
| - items->AddDeleteRegKeyWorkItem(root, key_path_, WorkItem::kWow64Default);
|
| - } else {
|
| - DCHECK(removal_flag_ == RemovalFlag::NONE);
|
| - items->AddCreateRegKeyWorkItem(root, key_path_, WorkItem::kWow64Default);
|
| - if (is_string_) {
|
| - items->AddSetRegValueWorkItem(root, key_path_, WorkItem::kWow64Default,
|
| - name_, value_, true);
|
| - } else {
|
| - items->AddSetRegValueWorkItem(root, key_path_, WorkItem::kWow64Default,
|
| - name_, int_value_, true);
|
| - }
|
| - }
|
| - }
|
| + void AddToWorkItemList(HKEY root, WorkItemList* items) const;
|
|
|
| // Returns true if this key is flagged for removal.
|
| bool IsFlaggedForRemoval() const {
|
| @@ -705,31 +356,13 @@ class RegistryEntry {
|
| // registrations outside of HKCR on versions of Windows prior to Win8,
|
| // Chrome's values go in HKLM. This function will make unnecessary (but
|
| // harmless) queries into HKCU in that case.
|
| - bool ExistsInRegistry(uint32 look_for_in) const {
|
| - DCHECK(look_for_in);
|
| -
|
| - RegistryStatus status = DOES_NOT_EXIST;
|
| - if (look_for_in & LOOK_IN_HKCU)
|
| - status = StatusInRegistryUnderRoot(HKEY_CURRENT_USER);
|
| - if (status == DOES_NOT_EXIST && (look_for_in & LOOK_IN_HKLM))
|
| - status = StatusInRegistryUnderRoot(HKEY_LOCAL_MACHINE);
|
| - return status == SAME_VALUE;
|
| - }
|
| + bool ExistsInRegistry(uint32 look_for_in) const;
|
|
|
| // Checks if the current registry entry exists in \|key_path_|\|name_|,
|
| // regardless of value. Same lookup rules as ExistsInRegistry.
|
| // Unlike ExistsInRegistry, this returns true if some other value is present
|
| // with the same key.
|
| - bool KeyExistsInRegistry(uint32 look_for_in) const {
|
| - DCHECK(look_for_in);
|
| -
|
| - RegistryStatus status = DOES_NOT_EXIST;
|
| - if (look_for_in & LOOK_IN_HKCU)
|
| - status = StatusInRegistryUnderRoot(HKEY_CURRENT_USER);
|
| - if (status == DOES_NOT_EXIST && (look_for_in & LOOK_IN_HKLM))
|
| - status = StatusInRegistryUnderRoot(HKEY_LOCAL_MACHINE);
|
| - return status != DOES_NOT_EXIST;
|
| - }
|
| + bool KeyExistsInRegistry(uint32 look_for_in) const;
|
|
|
| private:
|
| // States this RegistryKey can be in compared to the registry.
|
| @@ -743,41 +376,23 @@ class RegistryEntry {
|
| };
|
|
|
| // Create a object that represent default value of a key
|
| - RegistryEntry(const base::string16& key_path, const base::string16& value)
|
| - : key_path_(key_path),
|
| - name_(),
|
| - is_string_(true),
|
| - value_(value),
|
| - int_value_(0),
|
| - removal_flag_(RemovalFlag::NONE) {}
|
| + RegistryEntry(const base::string16& key_path, const base::string16& value);
|
|
|
| // Create a object that represent a key of type REG_SZ
|
| RegistryEntry(const base::string16& key_path,
|
| const base::string16& name,
|
| - const base::string16& value)
|
| - : key_path_(key_path),
|
| - name_(name),
|
| - is_string_(true),
|
| - value_(value),
|
| - int_value_(0),
|
| - removal_flag_(RemovalFlag::NONE) {}
|
| + const base::string16& value);
|
|
|
| // Create a object that represent a key of integer type
|
| RegistryEntry(const base::string16& key_path,
|
| const base::string16& name,
|
| - DWORD value)
|
| - : key_path_(key_path),
|
| - name_(name),
|
| - is_string_(false),
|
| - value_(),
|
| - int_value_(value),
|
| - removal_flag_(RemovalFlag::NONE) {}
|
| + DWORD value);
|
|
|
| base::string16 key_path_; // key path for the registry entry
|
| base::string16 name_; // name of the registry entry
|
| - bool is_string_; // true if current registry entry is of type REG_SZ
|
| + bool is_string_; // true if current registry entry is of type REG_SZ
|
| base::string16 value_; // string value (useful if is_string_ = true)
|
| - DWORD int_value_; // integer value (useful if is_string_ = false)
|
| + DWORD int_value_; // integer value (useful if is_string_ = false)
|
|
|
| // Identifies whether this RegistryEntry is flagged for removal (i.e. no
|
| // longer relevant on the configuration it was created under).
|
| @@ -786,35 +401,500 @@ class RegistryEntry {
|
| // 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;
|
| + RegistryStatus StatusInRegistryUnderRoot(HKEY root) const;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(RegistryEntry);
|
| +}; // class RegistryEntry
|
| +
|
| +// static
|
| +base::string16 RegistryEntry::GetBrowserClientKey(
|
| + BrowserDistribution* dist,
|
| + const base::string16& suffix) {
|
| + DCHECK(suffix.empty() || suffix[0] == L'.');
|
| + return base::string16(ShellUtil::kRegStartMenuInternet)
|
| + .append(1, L'\\')
|
| + .append(dist->GetBaseAppName())
|
| + .append(suffix);
|
| +}
|
| +
|
| +// static
|
| +base::string16 RegistryEntry::GetCapabilitiesKey(BrowserDistribution* dist,
|
| + const base::string16& suffix) {
|
| + return GetBrowserClientKey(dist, suffix).append(L"\\Capabilities");
|
| +}
|
| +
|
| +// static
|
| +ScopedVector<RegistryEntry> RegistryEntry::GetChromeDelegateExecuteEntries(
|
| + const base::FilePath& chrome_exe,
|
| + const RegistryEntry::ApplicationInfo& app_info) {
|
| + ScopedVector<RegistryEntry> entries;
|
| +
|
| + base::string16 app_id_shell_key(ShellUtil::kRegClasses);
|
| + app_id_shell_key.push_back(base::FilePath::kSeparators[0]);
|
| + app_id_shell_key.append(app_info.app_id);
|
| + app_id_shell_key.append(ShellUtil::kRegExePath);
|
| + app_id_shell_key.append(ShellUtil::kRegShellPath);
|
| +
|
| + // <root hkey>\Software\Classes\<app_id>\.exe\shell @=open
|
| + entries.push_back(
|
| + new RegistryEntry(app_id_shell_key, ShellUtil::kRegVerbOpen));
|
| +
|
| + // The command to execute when opening this application via the Metro UI.
|
| + const base::string16 delegate_command(
|
| + ShellUtil::GetChromeDelegateCommand(chrome_exe));
|
| +
|
| + // Each of Chrome's shortcuts has an appid; which, as of Windows 8, is
|
| + // registered to handle some verbs. This registration has the side-effect
|
| + // that these verbs now show up in the shortcut's context menu. We
|
| + // mitigate this side-effect by making the context menu entries
|
| + // user readable/localized strings. See relevant MSDN article:
|
| + // http://msdn.microsoft.com/en-US/library/windows/desktop/cc144171.aspx
|
| + static const struct {
|
| + const wchar_t* verb;
|
| + int name_id;
|
| + } verbs[] = {
|
| + {ShellUtil::kRegVerbOpen, -1},
|
| + {ShellUtil::kRegVerbOpenNewWindow, IDS_SHORTCUT_NEW_WINDOW_BASE},
|
| + };
|
| + for (const auto& verb_and_id : verbs) {
|
| + base::string16 sub_path(app_id_shell_key);
|
| + sub_path.push_back(base::FilePath::kSeparators[0]);
|
| + sub_path.append(verb_and_id.verb);
|
| +
|
| + // <root hkey>\Software\Classes\<app_id>\.exe\shell\<verb>
|
| + if (verb_and_id.name_id != -1) {
|
| + // TODO(grt): http://crbug.com/75152 Write a reference to a localized
|
| + // resource.
|
| + const base::string16 verb_name(
|
| + installer::GetLocalizedString(verb_and_id.name_id));
|
| + entries.push_back(new RegistryEntry(sub_path, verb_name.c_str()));
|
| + }
|
| + entries.push_back(
|
| + new RegistryEntry(sub_path, L"CommandId", L"Browser.Launch"));
|
| +
|
| + sub_path.push_back(base::FilePath::kSeparators[0]);
|
| + sub_path.append(ShellUtil::kRegCommand);
|
| +
|
| + // <root hkey>\Software\Classes\<app_id>\.exe\shell\<verb>\command
|
| + entries.push_back(new RegistryEntry(sub_path, delegate_command));
|
| + entries.push_back(new RegistryEntry(
|
| + sub_path, ShellUtil::kRegDelegateExecute, app_info.delegate_clsid));
|
| + }
|
| +
|
| + return entries.Pass();
|
| +}
|
| +
|
| +// static
|
| +void RegistryEntry::GetChromeProgIdEntries(
|
| + BrowserDistribution* dist,
|
| + const base::FilePath& chrome_exe,
|
| + const base::string16& suffix,
|
| + ScopedVector<RegistryEntry>* entries) {
|
| + int chrome_icon_index =
|
| + dist->GetIconIndex(BrowserDistribution::SHORTCUT_CHROME);
|
| +
|
| + ApplicationInfo app_info;
|
| + app_info.prog_id = GetBrowserProgId(suffix);
|
| + app_info.file_type_name = dist->GetBrowserProgIdDesc();
|
| + // File types associated with Chrome are just given the Chrome icon.
|
| + app_info.file_type_icon_path = chrome_exe;
|
| + app_info.file_type_icon_index = chrome_icon_index;
|
| + app_info.command_line = ShellUtil::GetChromeShellOpenCmd(chrome_exe);
|
| + // For user-level installs: entries for the app id will be in HKCU; thus we
|
| + // do not need a suffix on those entries.
|
| + app_info.app_id = ShellUtil::GetBrowserModelId(
|
| + dist, InstallUtil::IsPerUserInstall(chrome_exe));
|
| +
|
| + // TODO(grt): http://crbug.com/75152 Write a reference to a localized
|
| + // resource for name, description, and company.
|
| + app_info.application_name = dist->GetDisplayName();
|
| + app_info.application_icon_path = chrome_exe;
|
| + app_info.application_icon_index = chrome_icon_index;
|
| + app_info.application_description = dist->GetAppDescription();
|
| + app_info.publisher_name = dist->GetPublisherName();
|
| +
|
| + app_info.delegate_clsid = dist->GetCommandExecuteImplClsid();
|
| +
|
| + GetProgIdEntries(app_info, entries);
|
| +
|
| + if (!app_info.delegate_clsid.empty()) {
|
| + ScopedVector<RegistryEntry> delegate_execute_entries =
|
| + GetChromeDelegateExecuteEntries(chrome_exe, app_info);
|
| + if (!base::win::IsChromeMetroSupported()) {
|
| + // Remove the keys (not only their values) so that Windows will continue
|
| + // to launch Chrome without a pesky association error.
|
| + for (RegistryEntry* entry : delegate_execute_entries)
|
| + entry->set_removal_flag(RemovalFlag::KEY);
|
| + }
|
| + // Move |delegate_execute_entries| to |entries|.
|
| + entries->insert(entries->end(), delegate_execute_entries.begin(),
|
| + delegate_execute_entries.end());
|
| + delegate_execute_entries.weak_clear();
|
| + }
|
| +}
|
| +
|
| +// static
|
| +void RegistryEntry::GetProgIdEntries(
|
| + const RegistryEntry::ApplicationInfo& app_info,
|
| + ScopedVector<RegistryEntry>* entries) {
|
| + // Basic sanity checks.
|
| + DCHECK(!app_info.prog_id.empty());
|
| + DCHECK_NE(L'.', app_info.prog_id[0]);
|
| +
|
| + // File association ProgId
|
| + base::string16 prog_id_path(ShellUtil::kRegClasses);
|
| + prog_id_path.push_back(base::FilePath::kSeparators[0]);
|
| + prog_id_path.append(app_info.prog_id);
|
| + entries->push_back(new RegistryEntry(prog_id_path, app_info.file_type_name));
|
| + entries->push_back(new RegistryEntry(
|
| + prog_id_path + ShellUtil::kRegDefaultIcon,
|
| + ShellUtil::FormatIconLocation(app_info.file_type_icon_path,
|
| + app_info.file_type_icon_index)));
|
| + entries->push_back(new RegistryEntry(prog_id_path + ShellUtil::kRegShellOpen,
|
| + app_info.command_line));
|
| + if (!app_info.delegate_clsid.empty()) {
|
| + entries->push_back(new RegistryEntry(
|
| + prog_id_path + ShellUtil::kRegShellOpen, ShellUtil::kRegDelegateExecute,
|
| + app_info.delegate_clsid));
|
| + // If Metro is not supported, remove the DelegateExecute entry instead of
|
| + // adding it.
|
| + if (!base::win::IsChromeMetroSupported())
|
| + entries->back()->set_removal_flag(RemovalFlag::VALUE);
|
| + }
|
| +
|
| + // The following entries are required as of Windows 8, but do not
|
| + // depend on the DelegateExecute verb handler being set.
|
| + if (base::win::GetVersion() >= base::win::VERSION_WIN8) {
|
| + if (!app_info.app_id.empty()) {
|
| + entries->push_back(new RegistryEntry(
|
| + prog_id_path, ShellUtil::kRegAppUserModelId, app_info.app_id));
|
| + }
|
| +
|
| + // Add \Software\Classes\<prog_id>\Application entries
|
| + base::string16 application_path(prog_id_path + ShellUtil::kRegApplication);
|
| + if (!app_info.app_id.empty()) {
|
| + entries->push_back(new RegistryEntry(
|
| + application_path, ShellUtil::kRegAppUserModelId, app_info.app_id));
|
| + }
|
| + if (!app_info.application_icon_path.empty()) {
|
| + entries->push_back(new RegistryEntry(
|
| + application_path, ShellUtil::kRegApplicationIcon,
|
| + ShellUtil::FormatIconLocation(app_info.application_icon_path,
|
| + app_info.application_icon_index)));
|
| + }
|
| + if (!app_info.application_name.empty()) {
|
| + entries->push_back(new RegistryEntry(application_path,
|
| + ShellUtil::kRegApplicationName,
|
| + app_info.application_name));
|
| + }
|
| + if (!app_info.application_description.empty()) {
|
| + entries->push_back(new RegistryEntry(
|
| + application_path, ShellUtil::kRegApplicationDescription,
|
| + app_info.application_description));
|
| + }
|
| + if (!app_info.publisher_name.empty()) {
|
| + entries->push_back(new RegistryEntry(application_path,
|
| + ShellUtil::kRegApplicationCompany,
|
| + app_info.publisher_name));
|
| + }
|
| + }
|
| +}
|
| +
|
| +// static
|
| +void RegistryEntry::GetProtocolCapabilityEntries(
|
| + BrowserDistribution* dist,
|
| + const base::string16& suffix,
|
| + const base::string16& protocol,
|
| + ScopedVector<RegistryEntry>* entries) {
|
| + entries->push_back(new RegistryEntry(
|
| + GetCapabilitiesKey(dist, suffix).append(L"\\URLAssociations"), protocol,
|
| + GetBrowserProgId(suffix)));
|
| +}
|
| +
|
| +// static
|
| +void RegistryEntry::GetShellIntegrationEntries(
|
| + BrowserDistribution* dist,
|
| + const base::FilePath& chrome_exe,
|
| + const base::string16& suffix,
|
| + ScopedVector<RegistryEntry>* entries) {
|
| + const base::string16 icon_path(ShellUtil::FormatIconLocation(
|
| + chrome_exe, dist->GetIconIndex(BrowserDistribution::SHORTCUT_CHROME)));
|
| + const base::string16 quoted_exe_path(L"\"" + chrome_exe.value() + L"\"");
|
| +
|
| + // Register for the Start Menu "Internet" link (pre-Win7).
|
| + const base::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
|
| + entries->push_back(
|
| + new RegistryEntry(start_menu_entry, dist->GetDisplayName()));
|
| + // Register the "open" verb for launching Chrome via the "Internet" link.
|
| + entries->push_back(new RegistryEntry(
|
| + start_menu_entry + ShellUtil::kRegShellOpen, quoted_exe_path));
|
| + // Register Chrome's icon for the Start Menu "Internet" link.
|
| + entries->push_back(new RegistryEntry(
|
| + start_menu_entry + ShellUtil::kRegDefaultIcon, icon_path));
|
| +
|
| + // Register installation information.
|
| + base::string16 install_info(start_menu_entry + L"\\InstallInfo");
|
| + // Note: not using CommandLine since it has ambiguous rules for quoting
|
| + // strings.
|
| + entries->push_back(
|
| + new RegistryEntry(install_info, kReinstallCommand,
|
| + quoted_exe_path + L" --" +
|
| + base::ASCIIToUTF16(switches::kMakeDefaultBrowser)));
|
| + entries->push_back(new RegistryEntry(
|
| + install_info, L"HideIconsCommand",
|
| + quoted_exe_path + L" --" + base::ASCIIToUTF16(switches::kHideIcons)));
|
| + entries->push_back(new RegistryEntry(
|
| + install_info, L"ShowIconsCommand",
|
| + quoted_exe_path + L" --" + base::ASCIIToUTF16(switches::kShowIcons)));
|
| + entries->push_back(new RegistryEntry(install_info, L"IconsVisible", 1));
|
| +
|
| + // Register with Default Programs.
|
| + const base::string16 reg_app_name(dist->GetBaseAppName().append(suffix));
|
| + // Tell Windows where to find Chrome's Default Programs info.
|
| + const base::string16 capabilities(GetCapabilitiesKey(dist, suffix));
|
| + entries->push_back(new RegistryEntry(ShellUtil::kRegRegisteredApplications,
|
| + reg_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_back(new RegistryEntry(capabilities,
|
| + ShellUtil::kRegApplicationDescription,
|
| + dist->GetLongAppDescription()));
|
| + entries->push_back(new RegistryEntry(
|
| + capabilities, ShellUtil::kRegApplicationIcon, icon_path));
|
| + entries->push_back(new RegistryEntry(
|
| + capabilities, ShellUtil::kRegApplicationName, dist->GetDisplayName()));
|
| +
|
| + entries->push_back(new RegistryEntry(capabilities + L"\\Startmenu",
|
| + L"StartMenuInternet", reg_app_name));
|
| +
|
| + const base::string16 html_prog_id(GetBrowserProgId(suffix));
|
| + for (int i = 0; ShellUtil::kPotentialFileAssociations[i] != NULL; i++) {
|
| + entries->push_back(new RegistryEntry(
|
| + capabilities + L"\\FileAssociations",
|
| + ShellUtil::kPotentialFileAssociations[i], html_prog_id));
|
| + }
|
| + for (int i = 0; ShellUtil::kPotentialProtocolAssociations[i] != NULL; i++) {
|
| + entries->push_back(new RegistryEntry(
|
| + capabilities + L"\\URLAssociations",
|
| + ShellUtil::kPotentialProtocolAssociations[i], html_prog_id));
|
| + }
|
| +}
|
| +
|
| +// static
|
| +void RegistryEntry::GetChromeAppRegistrationEntries(
|
| + const base::FilePath& chrome_exe,
|
| + const base::string16& suffix,
|
| + ScopedVector<RegistryEntry>* entries) {
|
| + base::string16 app_path_key(ShellUtil::kAppPathsRegistryKey);
|
| + app_path_key.push_back(base::FilePath::kSeparators[0]);
|
| + app_path_key.append(chrome_exe.BaseName().value());
|
| + entries->push_back(new RegistryEntry(app_path_key, chrome_exe.value()));
|
| + entries->push_back(new RegistryEntry(app_path_key,
|
| + ShellUtil::kAppPathsRegistryPathName,
|
| + chrome_exe.DirName().value()));
|
| +
|
| + const base::string16 html_prog_id(GetBrowserProgId(suffix));
|
| + for (int i = 0; ShellUtil::kPotentialFileAssociations[i] != NULL; i++) {
|
| + GetAppExtRegistrationEntries(
|
| + html_prog_id, ShellUtil::kPotentialFileAssociations[i], entries);
|
| + }
|
| +}
|
| +
|
| +// static
|
| +void RegistryEntry::GetAppExtRegistrationEntries(
|
| + const base::string16& prog_id,
|
| + const base::string16& ext,
|
| + ScopedVector<RegistryEntry>* entries) {
|
| + // In HKEY_CURRENT_USER\Software\Classes\EXT\OpenWithProgids, create an
|
| + // empty value with this class's ProgId.
|
| + base::string16 key_name(ShellUtil::kRegClasses);
|
| + key_name.push_back(base::FilePath::kSeparators[0]);
|
| + key_name.append(ext);
|
| + key_name.push_back(base::FilePath::kSeparators[0]);
|
| + key_name.append(ShellUtil::kRegOpenWithProgids);
|
| + entries->push_back(new RegistryEntry(key_name, prog_id, base::string16()));
|
| +}
|
| +
|
| +// static
|
| +void RegistryEntry::GetAppDefaultRegistrationEntries(
|
| + const base::string16& prog_id,
|
| + const base::string16& ext,
|
| + bool overwrite_existing,
|
| + ScopedVector<RegistryEntry>* entries) {
|
| + // Set the default value of HKEY_CURRENT_USER\Software\Classes\EXT to this
|
| + // class's name.
|
| + base::string16 key_name(ShellUtil::kRegClasses);
|
| + key_name.push_back(base::FilePath::kSeparators[0]);
|
| + key_name.append(ext);
|
| + scoped_ptr<RegistryEntry> default_association(
|
| + new RegistryEntry(key_name, prog_id));
|
| + if (overwrite_existing ||
|
| + !default_association->KeyExistsInRegistry(RegistryEntry::LOOK_IN_HKCU)) {
|
| + entries->push_back(default_association.release());
|
| + }
|
| +}
|
| +
|
| +// static
|
| +void RegistryEntry::GetXPStyleUserProtocolEntries(
|
| + const base::string16& protocol,
|
| + const base::string16& chrome_icon,
|
| + const base::string16& chrome_open,
|
| + ScopedVector<RegistryEntry>* entries) {
|
| + // Protocols associations.
|
| + base::string16 url_key(ShellUtil::kRegClasses);
|
| + url_key.push_back(base::FilePath::kSeparators[0]);
|
| + url_key.append(protocol);
|
| +
|
| + // This registry value tells Windows that this 'class' is a URL scheme
|
| + // so IE, explorer and other apps will route it to our handler.
|
| + // <root hkey>\Software\Classes\<protocol>\URL Protocol
|
| + entries->push_back(
|
| + new RegistryEntry(url_key, ShellUtil::kRegUrlProtocol, base::string16()));
|
| +
|
| + // <root hkey>\Software\Classes\<protocol>\DefaultIcon
|
| + base::string16 icon_key = url_key + ShellUtil::kRegDefaultIcon;
|
| + entries->push_back(new RegistryEntry(icon_key, chrome_icon));
|
| +
|
| + // <root hkey>\Software\Classes\<protocol>\shell\open\command
|
| + base::string16 shell_key = url_key + ShellUtil::kRegShellOpen;
|
| + entries->push_back(new RegistryEntry(shell_key, chrome_open));
|
| +
|
| + // <root hkey>\Software\Classes\<protocol>\shell\open\ddeexec
|
| + base::string16 dde_key = url_key + L"\\shell\\open\\ddeexec";
|
| + entries->push_back(new RegistryEntry(dde_key, base::string16()));
|
| +
|
| + // <root hkey>\Software\Classes\<protocol>\shell\@
|
| + base::string16 protocol_shell_key = url_key + ShellUtil::kRegShellPath;
|
| + entries->push_back(new RegistryEntry(protocol_shell_key, L"open"));
|
| +}
|
| +
|
| +// static
|
| +void RegistryEntry::GetXPStyleDefaultBrowserUserEntries(
|
| + BrowserDistribution* dist,
|
| + const base::FilePath& chrome_exe,
|
| + const base::string16& suffix,
|
| + ScopedVector<RegistryEntry>* entries) {
|
| + // File extension associations.
|
| + base::string16 html_prog_id(GetBrowserProgId(suffix));
|
| + for (int i = 0; ShellUtil::kDefaultFileAssociations[i] != NULL; i++) {
|
| + GetAppDefaultRegistrationEntries(
|
| + html_prog_id, ShellUtil::kDefaultFileAssociations[i], true, entries);
|
| + }
|
| +
|
| + // Protocols associations.
|
| + base::string16 chrome_open = ShellUtil::GetChromeShellOpenCmd(chrome_exe);
|
| + base::string16 chrome_icon = ShellUtil::FormatIconLocation(
|
| + chrome_exe, dist->GetIconIndex(BrowserDistribution::SHORTCUT_CHROME));
|
| + for (int i = 0; ShellUtil::kBrowserProtocolAssociations[i] != NULL; i++) {
|
| + GetXPStyleUserProtocolEntries(ShellUtil::kBrowserProtocolAssociations[i],
|
| + chrome_icon, chrome_open, entries);
|
| + }
|
| +
|
| + // start->Internet shortcut.
|
| + base::string16 start_menu(ShellUtil::kRegStartMenuInternet);
|
| + base::string16 app_name = dist->GetBaseAppName() + suffix;
|
| + entries->push_back(new RegistryEntry(start_menu, app_name));
|
| +}
|
| +
|
| +void RegistryEntry::AddToWorkItemList(HKEY root, WorkItemList* items) const {
|
| + if (removal_flag_ == RemovalFlag::VALUE) {
|
| + items->AddDeleteRegValueWorkItem(root, key_path_, WorkItem::kWow64Default,
|
| + name_);
|
| + } else if (removal_flag_ == RemovalFlag::KEY) {
|
| + items->AddDeleteRegKeyWorkItem(root, key_path_, WorkItem::kWow64Default);
|
| + } else {
|
| + DCHECK(removal_flag_ == RemovalFlag::NONE);
|
| + items->AddCreateRegKeyWorkItem(root, key_path_, WorkItem::kWow64Default);
|
| if (is_string_) {
|
| - base::string16 read_value;
|
| - found = key.ReadValue(name_.c_str(), &read_value) == ERROR_SUCCESS;
|
| - if (found) {
|
| - correct_value = read_value.size() == value_.size() &&
|
| - ::CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE,
|
| - read_value.data(),
|
| - base::saturated_cast<int>(read_value.size()),
|
| - value_.data(),
|
| - base::saturated_cast<int>(value_.size()))
|
| - == CSTR_EQUAL;
|
| - }
|
| + items->AddSetRegValueWorkItem(root, key_path_, WorkItem::kWow64Default,
|
| + name_, value_, true);
|
| } else {
|
| - DWORD read_value;
|
| - found = key.ReadValueDW(name_.c_str(), &read_value) == ERROR_SUCCESS;
|
| - if (found)
|
| - correct_value = read_value == int_value_;
|
| + items->AddSetRegValueWorkItem(root, key_path_, WorkItem::kWow64Default,
|
| + name_, int_value_, true);
|
| }
|
| - return found ?
|
| - (correct_value ? SAME_VALUE : DIFFERENT_VALUE) : DOES_NOT_EXIST;
|
| }
|
| +}
|
|
|
| - DISALLOW_COPY_AND_ASSIGN(RegistryEntry);
|
| -}; // class RegistryEntry
|
| +bool RegistryEntry::ExistsInRegistry(uint32 look_for_in) const {
|
| + DCHECK(look_for_in);
|
| +
|
| + RegistryStatus status = DOES_NOT_EXIST;
|
| + if (look_for_in & LOOK_IN_HKCU)
|
| + status = StatusInRegistryUnderRoot(HKEY_CURRENT_USER);
|
| + if (status == DOES_NOT_EXIST && (look_for_in & LOOK_IN_HKLM))
|
| + status = StatusInRegistryUnderRoot(HKEY_LOCAL_MACHINE);
|
| + return status == SAME_VALUE;
|
| +}
|
| +
|
| +bool RegistryEntry::KeyExistsInRegistry(uint32 look_for_in) const {
|
| + DCHECK(look_for_in);
|
| +
|
| + RegistryStatus status = DOES_NOT_EXIST;
|
| + if (look_for_in & LOOK_IN_HKCU)
|
| + status = StatusInRegistryUnderRoot(HKEY_CURRENT_USER);
|
| + if (status == DOES_NOT_EXIST && (look_for_in & LOOK_IN_HKLM))
|
| + status = StatusInRegistryUnderRoot(HKEY_LOCAL_MACHINE);
|
| + return status != DOES_NOT_EXIST;
|
| +}
|
|
|
| +RegistryEntry::RegistryEntry(const base::string16& key_path,
|
| + const base::string16& value)
|
| + : key_path_(key_path),
|
| + name_(),
|
| + is_string_(true),
|
| + value_(value),
|
| + int_value_(0),
|
| + removal_flag_(RemovalFlag::NONE) {}
|
| +
|
| +RegistryEntry::RegistryEntry(const base::string16& key_path,
|
| + const base::string16& name,
|
| + const base::string16& value)
|
| + : key_path_(key_path),
|
| + name_(name),
|
| + is_string_(true),
|
| + value_(value),
|
| + int_value_(0),
|
| + removal_flag_(RemovalFlag::NONE) {}
|
| +
|
| +RegistryEntry::RegistryEntry(const base::string16& key_path,
|
| + const base::string16& name,
|
| + DWORD value)
|
| + : key_path_(key_path),
|
| + name_(name),
|
| + is_string_(false),
|
| + value_(),
|
| + int_value_(value),
|
| + removal_flag_(RemovalFlag::NONE) {}
|
| +
|
| +RegistryEntry::RegistryStatus RegistryEntry::StatusInRegistryUnderRoot(
|
| + HKEY root) const {
|
| + RegKey key(root, key_path_.c_str(), KEY_QUERY_VALUE);
|
| + bool found = false;
|
| + bool correct_value = false;
|
| + if (is_string_) {
|
| + base::string16 read_value;
|
| + found = key.ReadValue(name_.c_str(), &read_value) == ERROR_SUCCESS;
|
| + if (found) {
|
| + correct_value =
|
| + read_value.size() == value_.size() &&
|
| + ::CompareString(
|
| + LOCALE_USER_DEFAULT, NORM_IGNORECASE, read_value.data(),
|
| + base::saturated_cast<int>(read_value.size()), value_.data(),
|
| + base::saturated_cast<int>(value_.size())) == CSTR_EQUAL;
|
| + }
|
| + } else {
|
| + DWORD read_value;
|
| + found = key.ReadValueDW(name_.c_str(), &read_value) == ERROR_SUCCESS;
|
| + if (found)
|
| + correct_value = read_value == int_value_;
|
| + }
|
| + return found ? (correct_value ? SAME_VALUE : DIFFERENT_VALUE)
|
| + : DOES_NOT_EXIST;
|
| +}
|
|
|
| // This method converts all the RegistryEntries from the given list to
|
| // Set/CreateRegWorkItems and runs them using WorkItemList.
|
|
|