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. |