| Index: chrome/installer/util/shell_util.cc
|
| diff --git a/chrome/installer/util/shell_util.cc b/chrome/installer/util/shell_util.cc
|
| index edcfb5c156135149378876042238b414763c170d..42a9c6bf12137ca71368525250a3a123853e503d 100644
|
| --- a/chrome/installer/util/shell_util.cc
|
| +++ b/chrome/installer/util/shell_util.cc
|
| @@ -154,6 +154,40 @@ bool UserSpecificRegistrySuffix::GetSuffix(base::string16* suffix) {
|
| return true;
|
| }
|
|
|
| +// Details about a Windows application, to be entered into the registry for the
|
| +// purpose of file associations.
|
| +struct ApplicationInfo {
|
| + ApplicationInfo() : file_type_icon_index(0), application_icon_index(0) {}
|
| +
|
| + // The ProgId used by Windows for file associations with this application.
|
| + // Must not be empty or start with a '.'.
|
| + base::string16 prog_id;
|
| + // The friendly name, and the path of the icon that will be used for files of
|
| + // these types when associated with this application by default. (They are NOT
|
| + // the name/icon that will represent the application under the Open With
|
| + // menu.)
|
| + base::string16 file_type_name;
|
| + base::FilePath file_type_icon_path;
|
| + int file_type_icon_index;
|
| + // The command to execute when opening a file via this association. It should
|
| + // contain "%1" (to tell Windows to pass the filename as an argument).
|
| + // TODO(mgiuca): |command_line| should be a base::CommandLine.
|
| + base::string16 command_line;
|
| + // The AppUserModelId used by Windows 8 for this application. Distinct from
|
| + // |prog_id|.
|
| + base::string16 app_id;
|
| +
|
| + // User-visible details about this application. Any of these may be empty.
|
| + base::string16 application_name;
|
| + base::FilePath application_icon_path;
|
| + int application_icon_index;
|
| + base::string16 application_description;
|
| + base::string16 publisher_name;
|
| +
|
| + // The CLSID for the application's DelegateExecute handler. May be empty.
|
| + base::string16 delegate_clsid;
|
| +};
|
| +
|
| // This class represents a single registry entry (a key and its value). A
|
| // collection of registry entries should be collected into a list and written
|
| // transactionally using a WorkItemList. This is preferred to writing to the
|
| @@ -177,41 +211,6 @@ class RegistryEntry {
|
| KEY,
|
| };
|
|
|
| - // Details about a Windows application, to be entered into the registry for
|
| - // the purpose of file associations.
|
| - struct ApplicationInfo {
|
| - ApplicationInfo() : file_type_icon_index(0), application_icon_index(0) {}
|
| -
|
| - // The ProgId used by Windows for file associations with this application.
|
| - // Must not be empty or start with a '.'.
|
| - base::string16 prog_id;
|
| - // The friendly name, and the path of the icon that will be used for files
|
| - // of these types when associated with this application by default. (They
|
| - // are NOT the name/icon that will represent the application under the Open
|
| - // With menu.)
|
| - base::string16 file_type_name;
|
| - base::FilePath file_type_icon_path;
|
| - int file_type_icon_index;
|
| - // The command to execute when opening a file via this association. It
|
| - // should contain "%1" (to tell Windows to pass the filename as an
|
| - // argument).
|
| - // TODO(mgiuca): |command_line| should be a base::CommandLine.
|
| - base::string16 command_line;
|
| - // The AppUserModelId used by Windows 8 for this application. Distinct from
|
| - // |prog_id|.
|
| - base::string16 app_id;
|
| -
|
| - // User-visible details about this application. Any of these may be empty.
|
| - base::string16 application_name;
|
| - base::FilePath application_icon_path;
|
| - int application_icon_index;
|
| - base::string16 application_description;
|
| - base::string16 publisher_name;
|
| -
|
| - // The CLSID for the application's DelegateExecute handler. May be empty.
|
| - base::string16 delegate_clsid;
|
| - };
|
| -
|
| // Create an object that represent default value of a key.
|
| RegistryEntry(const base::string16& key_path, const base::string16& value);
|
|
|
| @@ -225,117 +224,6 @@ class RegistryEntry {
|
| const base::string16& name,
|
| DWORD value);
|
|
|
| - // Returns the Windows browser client registration key for Chrome. For
|
| - // example: "Software\Clients\StartMenuInternet\Chromium[.user]". Strictly
|
| - // speaking, we should use the name of the executable (e.g., "chrome.exe"),
|
| - // but that ship has sailed. The cost of switching now is re-prompting users
|
| - // 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 base::string16 GetBrowserClientKey(BrowserDistribution* dist,
|
| - 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);
|
| -
|
| - // 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);
|
| -
|
| - // This method returns a list of all the registry entries that
|
| - // are needed to register this installation's ProgId and AppId.
|
| - // These entries need to be registered in HKLM prior to Win8.
|
| - static void GetChromeProgIdEntries(BrowserDistribution* dist,
|
| - const base::FilePath& chrome_exe,
|
| - const base::string16& suffix,
|
| - 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);
|
| -
|
| - // This method returns a list of the registry entries needed to declare a
|
| - // capability of handling a protocol on Windows.
|
| - static void GetProtocolCapabilityEntries(
|
| - BrowserDistribution* dist,
|
| - const base::string16& suffix,
|
| - const base::string16& protocol,
|
| - ScopedVector<RegistryEntry>* entries);
|
| -
|
| - // This method returns a list of the registry entries required to register
|
| - // this installation in "RegisteredApplications" on Windows (to appear in
|
| - // Default Programs, StartMenuInternet, etc.).
|
| - // These entries need to be registered in HKLM prior to Win8.
|
| - // If |suffix| is not empty, these entries are guaranteed to be unique on this
|
| - // machine.
|
| - static void GetShellIntegrationEntries(BrowserDistribution* dist,
|
| - const base::FilePath& chrome_exe,
|
| - const base::string16& suffix,
|
| - ScopedVector<RegistryEntry>* entries);
|
| -
|
| - // This method returns a list of the registry entries required for this
|
| - // installation to be registered in the Windows shell.
|
| - // In particular:
|
| - // - App Paths
|
| - // http://msdn.microsoft.com/en-us/library/windows/desktop/ee872121
|
| - // - File Associations
|
| - // http://msdn.microsoft.com/en-us/library/bb166549
|
| - // These entries need to be registered in HKLM prior to Win8.
|
| - static void GetChromeAppRegistrationEntries(
|
| - const base::FilePath& chrome_exe,
|
| - const base::string16& suffix,
|
| - 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
|
| - // application. |ext| is the file extension, which must begin with a '.'.
|
| - static void GetAppExtRegistrationEntries(
|
| - const base::string16& prog_id,
|
| - const base::string16& ext,
|
| - 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
|
| - // for the application. |ext| is the file extension, which must begin with a
|
| - // '.'. If |overwrite_existing|, always sets the default handler; otherwise
|
| - // only sets if there is no existing default.
|
| - //
|
| - // This has no effect on Windows 8. Windows 8 ignores the default and lets the
|
| - // user choose. If there is only one handler for a file, it will automatically
|
| - // become the default. Otherwise, the first time the user opens a file, they
|
| - // are presented with the dialog to set the default handler. (This is roughly
|
| - // equivalent to being called with |overwrite_existing| false.)
|
| - static void GetAppDefaultRegistrationEntries(
|
| - const base::string16& prog_id,
|
| - const base::string16& ext,
|
| - bool overwrite_existing,
|
| - 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.
|
| - static void GetXPStyleUserProtocolEntries(
|
| - const base::string16& protocol,
|
| - const base::string16& chrome_icon,
|
| - const base::string16& chrome_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.
|
| - // Some of these entries are irrelevant in recent versions of Windows, but
|
| - // we register them anyways as some legacy apps are hardcoded to lookup those
|
| - // values.
|
| - static void GetXPStyleDefaultBrowserUserEntries(
|
| - BrowserDistribution* dist,
|
| - const base::FilePath& chrome_exe,
|
| - const base::string16& suffix,
|
| - 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
|
| // the entire registry hierarchy below RegistryEntry even if it is left empty
|
| @@ -434,10 +322,82 @@ RegistryEntry::RegistryEntry(const base::string16& key_path,
|
| int_value_(value),
|
| removal_flag_(RemovalFlag::NONE) {}
|
|
|
| -// static
|
| -base::string16 RegistryEntry::GetBrowserClientKey(
|
| - BrowserDistribution* dist,
|
| - const base::string16& suffix) {
|
| +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_) {
|
| + items->AddSetRegValueWorkItem(root, key_path_, WorkItem::kWow64Default,
|
| + name_, value_, true);
|
| + } else {
|
| + items->AddSetRegValueWorkItem(root, key_path_, WorkItem::kWow64Default,
|
| + name_, int_value_, true);
|
| + }
|
| + }
|
| +}
|
| +
|
| +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::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;
|
| +}
|
| +
|
| +// Returns the Windows browser client registration key for Chrome. For example:
|
| +// "Software\Clients\StartMenuInternet\Chromium[.user]". Strictly speaking, we
|
| +// should use the name of the executable (e.g., "chrome.exe"), but that ship has
|
| +// sailed. The cost of switching now is re-prompting users 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.
|
| +base::string16 GetBrowserClientKey(BrowserDistribution* dist,
|
| + const base::string16& suffix) {
|
| DCHECK(suffix.empty() || suffix[0] == L'.');
|
| return base::string16(ShellUtil::kRegStartMenuInternet)
|
| .append(1, L'\\')
|
| @@ -445,16 +405,19 @@ base::string16 RegistryEntry::GetBrowserClientKey(
|
| .append(suffix);
|
| }
|
|
|
| -// static
|
| -base::string16 RegistryEntry::GetCapabilitiesKey(BrowserDistribution* dist,
|
| - const base::string16& suffix) {
|
| +// Returns the Windows Default Programs capabilities key for Chrome. For
|
| +// example:
|
| +// "Software\Clients\StartMenuInternet\Chromium[.user]\Capabilities".
|
| +base::string16 GetCapabilitiesKey(BrowserDistribution* dist,
|
| + const base::string16& suffix) {
|
| return GetBrowserClientKey(dist, suffix).append(L"\\Capabilities");
|
| }
|
|
|
| -// static
|
| -ScopedVector<RegistryEntry> RegistryEntry::GetChromeDelegateExecuteEntries(
|
| +// DelegateExecute ProgId. Needed for Chrome Metro in Windows 8. This is only
|
| +// needed for registring a web browser, not for general associations.
|
| +ScopedVector<RegistryEntry> GetChromeDelegateExecuteEntries(
|
| const base::FilePath& chrome_exe,
|
| - const RegistryEntry::ApplicationInfo& app_info) {
|
| + const ApplicationInfo& app_info) {
|
| ScopedVector<RegistryEntry> entries;
|
|
|
| base::string16 app_id_shell_key(ShellUtil::kRegClasses);
|
| @@ -512,59 +475,10 @@ ScopedVector<RegistryEntry> RegistryEntry::GetChromeDelegateExecuteEntries(
|
| 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) {
|
| +// Gets the registry entries to register an application in the Windows registry.
|
| +// |app_info| provides all of the information needed.
|
| +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]);
|
| @@ -587,7 +501,7 @@ void RegistryEntry::GetProgIdEntries(
|
| // If Metro is not supported, remove the DelegateExecute entry instead of
|
| // adding it.
|
| if (!base::win::IsChromeMetroSupported())
|
| - entries->back()->set_removal_flag(RemovalFlag::VALUE);
|
| + entries->back()->set_removal_flag(RegistryEntry::RemovalFlag::VALUE);
|
| }
|
|
|
| // The following entries are required as of Windows 8, but do not
|
| @@ -628,23 +542,76 @@ void RegistryEntry::GetProgIdEntries(
|
| }
|
| }
|
|
|
| -// static
|
| -void RegistryEntry::GetProtocolCapabilityEntries(
|
| - BrowserDistribution* dist,
|
| - const base::string16& suffix,
|
| - const base::string16& protocol,
|
| - ScopedVector<RegistryEntry>* entries) {
|
| +// This method returns a list of all the registry entries that are needed to
|
| +// register this installation's ProgId and AppId. These entries need to be
|
| +// registered in HKLM prior to Win8.
|
| +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(RegistryEntry::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();
|
| + }
|
| +}
|
| +
|
| +// This method returns a list of the registry entries needed to declare a
|
| +// capability of handling a protocol on Windows.
|
| +void 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) {
|
| +// This method returns a list of the registry entries required to register this
|
| +// installation in "RegisteredApplications" on Windows (to appear in Default
|
| +// Programs, StartMenuInternet, etc.). These entries need to be registered in
|
| +// HKLM prior to Win8. If |suffix| is not empty, these entries are guaranteed to
|
| +// be unique on this machine.
|
| +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"\"");
|
| @@ -712,11 +679,33 @@ void RegistryEntry::GetShellIntegrationEntries(
|
| }
|
| }
|
|
|
| -// static
|
| -void RegistryEntry::GetChromeAppRegistrationEntries(
|
| - const base::FilePath& chrome_exe,
|
| - const base::string16& suffix,
|
| - 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
|
| +// application. |ext| is the file extension, which must begin with a '.'.
|
| +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()));
|
| +}
|
| +
|
| +// This method returns a list of the registry entries required for this
|
| +// installation to be registered in the Windows shell.
|
| +// In particular:
|
| +// - App Paths
|
| +// http://msdn.microsoft.com/en-us/library/windows/desktop/ee872121
|
| +// - File Associations
|
| +// http://msdn.microsoft.com/en-us/library/bb166549
|
| +// These entries need to be registered in HKLM prior to Win8.
|
| +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());
|
| @@ -732,27 +721,21 @@ void RegistryEntry::GetChromeAppRegistrationEntries(
|
| }
|
| }
|
|
|
| -// 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) {
|
| +// 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 for
|
| +// the application. |ext| is the file extension, which must begin with a '.'. If
|
| +// |overwrite_existing|, always sets the default handler; otherwise only sets if
|
| +// there is no existing default.
|
| +//
|
| +// This has no effect on Windows 8. Windows 8 ignores the default and lets the
|
| +// user choose. If there is only one handler for a file, it will automatically
|
| +// become the default. Otherwise, the first time the user opens a file, they are
|
| +// presented with the dialog to set the default handler. (This is roughly
|
| +// equivalent to being called with |overwrite_existing| false.)
|
| +void 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);
|
| @@ -766,12 +749,12 @@ void RegistryEntry::GetAppDefaultRegistrationEntries(
|
| }
|
| }
|
|
|
| -// static
|
| -void RegistryEntry::GetXPStyleUserProtocolEntries(
|
| - const base::string16& protocol,
|
| - const base::string16& chrome_icon,
|
| - const base::string16& chrome_open,
|
| - 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.
|
| +void 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]);
|
| @@ -800,12 +783,14 @@ void RegistryEntry::GetXPStyleUserProtocolEntries(
|
| 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) {
|
| +// This method returns a list of all the user level registry entries that are
|
| +// needed to make Chromium default browser on XP. Some of these entries are
|
| +// irrelevant in recent versions of Windows, but we register them anyways as
|
| +// some legacy apps are hardcoded to lookup those values.
|
| +void 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++) {
|
| @@ -828,73 +813,6 @@ void RegistryEntry::GetXPStyleDefaultBrowserUserEntries(
|
| 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_) {
|
| - items->AddSetRegValueWorkItem(root, key_path_, WorkItem::kWow64Default,
|
| - name_, value_, true);
|
| - } else {
|
| - items->AddSetRegValueWorkItem(root, key_path_, WorkItem::kWow64Default,
|
| - name_, int_value_, true);
|
| - }
|
| - }
|
| -}
|
| -
|
| -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::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.
|
| bool AddRegistryEntries(HKEY root, const ScopedVector<RegistryEntry>& entries) {
|
| @@ -939,9 +857,9 @@ bool IsChromeRegistered(BrowserDistribution* dist,
|
| const base::string16& suffix,
|
| uint32 look_for_in) {
|
| ScopedVector<RegistryEntry> entries;
|
| - RegistryEntry::GetChromeProgIdEntries(dist, chrome_exe, suffix, &entries);
|
| - RegistryEntry::GetShellIntegrationEntries(dist, chrome_exe, suffix, &entries);
|
| - RegistryEntry::GetChromeAppRegistrationEntries(chrome_exe, suffix, &entries);
|
| + GetChromeProgIdEntries(dist, chrome_exe, suffix, &entries);
|
| + GetShellIntegrationEntries(dist, chrome_exe, suffix, &entries);
|
| + GetChromeAppRegistrationEntries(chrome_exe, suffix, &entries);
|
| return AreEntriesAsDesired(entries, look_for_in);
|
| }
|
|
|
| @@ -953,7 +871,7 @@ bool IsChromeRegisteredForProtocol(BrowserDistribution* dist,
|
| const base::string16& protocol,
|
| uint32 look_for_in) {
|
| ScopedVector<RegistryEntry> entries;
|
| - RegistryEntry::GetProtocolCapabilityEntries(dist, suffix, protocol, &entries);
|
| + GetProtocolCapabilityEntries(dist, suffix, protocol, &entries);
|
| return AreEntriesAsDesired(entries, look_for_in);
|
| }
|
|
|
| @@ -1074,7 +992,7 @@ bool QuickIsChromeRegistered(BrowserDistribution* dist,
|
| case CONFIRM_SHELL_REGISTRATION:
|
| case CONFIRM_SHELL_REGISTRATION_IN_HKLM:
|
| // Software\Clients\StartMenuInternet\Google Chrome|suffix|
|
| - reg_key = RegistryEntry::GetBrowserClientKey(dist, suffix);
|
| + reg_key = GetBrowserClientKey(dist, suffix);
|
| break;
|
| default:
|
| NOTREACHED();
|
| @@ -1156,7 +1074,7 @@ bool RegisterChromeAsDefaultXPStyle(BrowserDistribution* dist,
|
| const base::FilePath& chrome_exe) {
|
| bool ret = true;
|
| ScopedVector<RegistryEntry> entries;
|
| - RegistryEntry::GetXPStyleDefaultBrowserUserEntries(
|
| + GetXPStyleDefaultBrowserUserEntries(
|
| dist, chrome_exe,
|
| ShellUtil::GetCurrentInstallationSuffix(dist, chrome_exe), &entries);
|
|
|
| @@ -1192,8 +1110,7 @@ bool RegisterChromeAsDefaultProtocolClientXPStyle(
|
| ShellUtil::FormatIconLocation(
|
| chrome_exe,
|
| dist->GetIconIndex(BrowserDistribution::SHORTCUT_CHROME)));
|
| - RegistryEntry::GetXPStyleUserProtocolEntries(protocol, chrome_icon,
|
| - chrome_open, &entries);
|
| + GetXPStyleUserProtocolEntries(protocol, chrome_icon, chrome_open, &entries);
|
| // Change the default protocol handler for current user.
|
| if (!AddRegistryEntries(HKEY_CURRENT_USER, entries)) {
|
| LOG(ERROR) << "Could not make Chrome default protocol client (XP).";
|
| @@ -2319,12 +2236,11 @@ bool ShellUtil::RegisterChromeBrowser(BrowserDistribution* dist,
|
| // an admin.
|
| ScopedVector<RegistryEntry> progid_and_appreg_entries;
|
| ScopedVector<RegistryEntry> shell_entries;
|
| - RegistryEntry::GetChromeProgIdEntries(
|
| - dist, chrome_exe, suffix, &progid_and_appreg_entries);
|
| - RegistryEntry::GetChromeAppRegistrationEntries(
|
| - chrome_exe, suffix, &progid_and_appreg_entries);
|
| - RegistryEntry::GetShellIntegrationEntries(
|
| - dist, chrome_exe, suffix, &shell_entries);
|
| + GetChromeProgIdEntries(dist, chrome_exe, suffix,
|
| + &progid_and_appreg_entries);
|
| + GetChromeAppRegistrationEntries(chrome_exe, suffix,
|
| + &progid_and_appreg_entries);
|
| + GetShellIntegrationEntries(dist, chrome_exe, suffix, &shell_entries);
|
| result = (AddRegistryEntries(root, progid_and_appreg_entries) &&
|
| AddRegistryEntries(root, shell_entries));
|
| } else if (elevate_if_not_admin &&
|
| @@ -2339,8 +2255,7 @@ bool ShellUtil::RegisterChromeBrowser(BrowserDistribution* dist,
|
| // If we got to this point then all we can do is create ProgId and basic app
|
| // registrations under HKCU.
|
| ScopedVector<RegistryEntry> entries;
|
| - RegistryEntry::GetChromeProgIdEntries(
|
| - dist, chrome_exe, base::string16(), &entries);
|
| + GetChromeProgIdEntries(dist, chrome_exe, base::string16(), &entries);
|
| // Prefer to use |suffix|; unless Chrome's ProgIds are already registered
|
| // with no suffix (as per the old registration style): in which case some
|
| // other registry entries could refer to them and since we were not able to
|
| @@ -2348,10 +2263,8 @@ bool ShellUtil::RegisterChromeBrowser(BrowserDistribution* dist,
|
| if (!AreEntriesAsDesired(entries, RegistryEntry::LOOK_IN_HKCU)) {
|
| if (!suffix.empty()) {
|
| entries.clear();
|
| - RegistryEntry::GetChromeProgIdEntries(
|
| - dist, chrome_exe, suffix, &entries);
|
| - RegistryEntry::GetChromeAppRegistrationEntries(
|
| - chrome_exe, suffix, &entries);
|
| + GetChromeProgIdEntries(dist, chrome_exe, suffix, &entries);
|
| + GetChromeAppRegistrationEntries(chrome_exe, suffix, &entries);
|
| }
|
| result = AddRegistryEntries(HKEY_CURRENT_USER, entries);
|
| } else {
|
| @@ -2360,8 +2273,7 @@ bool ShellUtil::RegisterChromeBrowser(BrowserDistribution* dist,
|
| // thus needs to be done after the above check for the unsuffixed
|
| // registration).
|
| entries.clear();
|
| - RegistryEntry::GetChromeAppRegistrationEntries(
|
| - chrome_exe, base::string16(), &entries);
|
| + GetChromeAppRegistrationEntries(chrome_exe, base::string16(), &entries);
|
| result = AddRegistryEntries(HKEY_CURRENT_USER, entries);
|
| }
|
| }
|
| @@ -2408,8 +2320,7 @@ bool ShellUtil::RegisterChromeForProtocol(BrowserDistribution* dist,
|
|
|
| // Write in the capabillity for the protocol.
|
| ScopedVector<RegistryEntry> entries;
|
| - RegistryEntry::GetProtocolCapabilityEntries(dist, suffix, protocol,
|
| - &entries);
|
| + GetProtocolCapabilityEntries(dist, suffix, protocol, &entries);
|
| return AddRegistryEntries(root, entries);
|
| } else if (elevate_if_not_admin &&
|
| base::win::GetVersion() >= base::win::VERSION_VISTA) {
|
| @@ -2562,13 +2473,13 @@ bool ShellUtil::AddFileAssociations(
|
| ScopedVector<RegistryEntry> entries;
|
|
|
| // Create a class for this app.
|
| - RegistryEntry::ApplicationInfo app_info;
|
| + ApplicationInfo app_info;
|
| app_info.prog_id = prog_id;
|
| app_info.file_type_name = file_type_name;
|
| app_info.file_type_icon_path = icon_path;
|
| app_info.file_type_icon_index = 0;
|
| app_info.command_line = command_line.GetCommandLineStringWithPlaceholders();
|
| - RegistryEntry::GetProgIdEntries(app_info, &entries);
|
| + GetProgIdEntries(app_info, &entries);
|
|
|
| // Associate each extension that the app can handle with the class. Set this
|
| // app as the default handler if and only if there is no existing default.
|
| @@ -2580,14 +2491,13 @@ bool ShellUtil::AddFileAssociations(
|
| DCHECK_NE(L'.', (*it)[0]);
|
| base::string16 ext(1, L'.');
|
| ext.append(*it);
|
| - RegistryEntry::GetAppExtRegistrationEntries(prog_id, ext, &entries);
|
| + GetAppExtRegistrationEntries(prog_id, ext, &entries);
|
|
|
| // Regstering as the default will have no effect on Windows 8 (see
|
| // documentation for GetAppDefaultRegistrationEntries). However, if our app
|
| // is the only handler, it will automatically become the default, so the
|
| // same effect is achieved.
|
| - RegistryEntry::GetAppDefaultRegistrationEntries(
|
| - prog_id, ext, false, &entries);
|
| + GetAppDefaultRegistrationEntries(prog_id, ext, false, &entries);
|
| }
|
|
|
| return AddRegistryEntries(HKEY_CURRENT_USER, entries);
|
|
|