diff options
39 files changed, 778 insertions, 728 deletions
diff --git a/chrome/chrome_installer.gypi b/chrome/chrome_installer.gypi index fad6b8c..1e6cd9c 100644 --- a/chrome/chrome_installer.gypi +++ b/chrome/chrome_installer.gypi @@ -98,7 +98,6 @@ 'installer/util/advanced_firewall_manager_win_unittest.cc', 'installer/util/callback_work_item_unittest.cc', 'installer/util/channel_info_unittest.cc', - 'installer/util/copy_reg_key_work_item_unittest.cc', 'installer/util/copy_tree_work_item_unittest.cc', 'installer/util/create_dir_work_item_unittest.cc', 'installer/util/create_reg_key_work_item_unittest.cc', diff --git a/chrome/chrome_installer_util.gypi b/chrome/chrome_installer_util.gypi index 234750f..0faebd7 100644 --- a/chrome/chrome_installer_util.gypi +++ b/chrome/chrome_installer_util.gypi @@ -33,8 +33,6 @@ 'installer/util/chromium_binaries_distribution.h', 'installer/util/conditional_work_item_list.cc', 'installer/util/conditional_work_item_list.h', - 'installer/util/copy_reg_key_work_item.cc', - 'installer/util/copy_reg_key_work_item.h', 'installer/util/copy_tree_work_item.cc', 'installer/util/copy_tree_work_item.h', 'installer/util/create_dir_work_item.cc', diff --git a/chrome/installer/setup/install.cc b/chrome/installer/setup/install.cc index e7cc375..cb675ac 100644 --- a/chrome/installer/setup/install.cc +++ b/chrome/installer/setup/install.cc @@ -136,7 +136,7 @@ void AddChromeToMediaPlayerList() { reg_path.append(installer::kChromeExe); VLOG(1) << "Adding Chrome to Media player list at " << reg_path; scoped_ptr<WorkItem> work_item(WorkItem::CreateCreateRegKeyWorkItem( - HKEY_LOCAL_MACHINE, reg_path)); + HKEY_LOCAL_MACHINE, reg_path, WorkItem::kWow64Default)); // if the operation fails we log the error but still continue if (!work_item.get()->Do()) diff --git a/chrome/installer/setup/install_worker.cc b/chrome/installer/setup/install_worker.cc index 4831d3d..b8bab9b 100644 --- a/chrome/installer/setup/install_worker.cc +++ b/chrome/installer/setup/install_worker.cc @@ -214,9 +214,11 @@ void AddCommandWithParameterWorkItems(const InstallerState& installer_state, GetRegCommandKey(product.distribution(), command_key)); if (installer_state.operation() == InstallerState::UNINSTALL) { - work_item_list->AddDeleteRegKeyWorkItem( - installer_state.root_key(), full_cmd_key)->set_log_message( - "removing " + base::UTF16ToASCII(command_key) + " command"); + work_item_list->AddDeleteRegKeyWorkItem(installer_state.root_key(), + full_cmd_key, + WorkItem::kWow64Default) + ->set_log_message("removing " + base::UTF16ToASCII(command_key) + + " command"); } else { CommandLine cmd_line(installer_state.target_path().Append(app)); cmd_line.AppendSwitchASCII(command_with_parameter, "%1"); @@ -440,7 +442,7 @@ void AddDeleteUninstallShortcutsForMSIWorkItems( base::string16 uninstall_reg(product.distribution()->GetUninstallRegPath()); WorkItem* delete_reg_key = work_item_list->AddDeleteRegKeyWorkItem( - reg_root, uninstall_reg); + reg_root, uninstall_reg, WorkItem::kWow64Default); delete_reg_key->set_ignore_failure(true); // Then attempt to delete the old installation's start menu shortcut. @@ -609,22 +611,25 @@ void AddUninstallDelegateExecuteWorkItems( WorkItemList* list) { VLOG(1) << "Adding unregistration items for DelegateExecute verb handler in " << root; - list->AddDeleteRegKeyWorkItem(root, delegate_execute_path); + list->AddDeleteRegKeyWorkItem(root, + delegate_execute_path, + WorkItem::kWow64Default); // In the past, the ICommandExecuteImpl interface and a TypeLib were both // registered. Remove these since this operation may be updating a machine // that had the old registrations. list->AddDeleteRegKeyWorkItem(root, L"Software\\Classes\\Interface\\" - L"{0BA0D4E9-2259-4963-B9AE-A839F7CB7544}"); + L"{0BA0D4E9-2259-4963-B9AE-A839F7CB7544}", + WorkItem::kWow64Default); list->AddDeleteRegKeyWorkItem(root, L"Software\\Classes\\TypeLib\\" #if defined(GOOGLE_CHROME_BUILD) - L"{4E805ED8-EBA0-4601-9681-12815A56EBFD}" + L"{4E805ED8-EBA0-4601-9681-12815A56EBFD}", #else - L"{7779FB70-B399-454A-AA1A-BAA850032B10}" + L"{7779FB70-B399-454A-AA1A-BAA850032B10}", #endif - ); + WorkItem::kWow64Default); } // Google Chrome Canary, between 20.0.1101.0 (crrev.com/132190) and 20.0.1106.0 @@ -693,12 +698,21 @@ void AddUninstallShortcutWorkItems(const InstallerState& installer_state, &uninstall_arguments); base::string16 update_state_key(browser_dist->GetStateKey()); - install_list->AddCreateRegKeyWorkItem(reg_root, update_state_key); - install_list->AddSetRegValueWorkItem(reg_root, update_state_key, - installer::kUninstallStringField, installer_path.value(), true); - install_list->AddSetRegValueWorkItem(reg_root, update_state_key, + install_list->AddCreateRegKeyWorkItem( + reg_root, update_state_key, WorkItem::kWow64Default); + install_list->AddSetRegValueWorkItem(reg_root, + update_state_key, + WorkItem::kWow64Default, + installer::kUninstallStringField, + installer_path.value(), + true); + install_list->AddSetRegValueWorkItem( + reg_root, + update_state_key, + WorkItem::kWow64Default, installer::kUninstallArgumentsField, - uninstall_arguments.GetCommandLineString(), true); + uninstall_arguments.GetCommandLineString(), + true); // MSI installations will manage their own uninstall shortcuts. if (!installer_state.is_msi() && product.ShouldCreateUninstallEntry()) { @@ -708,15 +722,24 @@ void AddUninstallShortcutWorkItems(const InstallerState& installer_state, quoted_uninstall_cmd.AppendArguments(uninstall_arguments, false); base::string16 uninstall_reg = browser_dist->GetUninstallRegPath(); - install_list->AddCreateRegKeyWorkItem(reg_root, uninstall_reg); - install_list->AddSetRegValueWorkItem(reg_root, uninstall_reg, - installer::kUninstallDisplayNameField, browser_dist->GetDisplayName(), - true); + install_list->AddCreateRegKeyWorkItem( + reg_root, uninstall_reg, WorkItem::kWow64Default); install_list->AddSetRegValueWorkItem(reg_root, - uninstall_reg, installer::kUninstallStringField, - quoted_uninstall_cmd.GetCommandLineString(), true); + uninstall_reg, + WorkItem::kWow64Default, + installer::kUninstallDisplayNameField, + browser_dist->GetDisplayName(), + true); + install_list->AddSetRegValueWorkItem( + reg_root, + uninstall_reg, + WorkItem::kWow64Default, + installer::kUninstallStringField, + quoted_uninstall_cmd.GetCommandLineString(), + true); install_list->AddSetRegValueWorkItem(reg_root, uninstall_reg, + WorkItem::kWow64Default, L"InstallLocation", install_path.value(), true); @@ -725,28 +748,46 @@ void AddUninstallShortcutWorkItems(const InstallerState& installer_state, base::string16 chrome_icon = ShellUtil::FormatIconLocation( install_path.Append(dist->GetIconFilename()).value(), dist->GetIconIndex(BrowserDistribution::SHORTCUT_CHROME)); - install_list->AddSetRegValueWorkItem(reg_root, uninstall_reg, - L"DisplayIcon", chrome_icon, true); - install_list->AddSetRegValueWorkItem(reg_root, uninstall_reg, - L"NoModify", static_cast<DWORD>(1), + install_list->AddSetRegValueWorkItem(reg_root, + uninstall_reg, + WorkItem::kWow64Default, + L"DisplayIcon", + chrome_icon, true); - install_list->AddSetRegValueWorkItem(reg_root, uninstall_reg, - L"NoRepair", static_cast<DWORD>(1), + install_list->AddSetRegValueWorkItem(reg_root, + uninstall_reg, + WorkItem::kWow64Default, + L"NoModify", + static_cast<DWORD>(1), + true); + install_list->AddSetRegValueWorkItem(reg_root, + uninstall_reg, + WorkItem::kWow64Default, + L"NoRepair", + static_cast<DWORD>(1), true); - install_list->AddSetRegValueWorkItem(reg_root, uninstall_reg, + install_list->AddSetRegValueWorkItem(reg_root, + uninstall_reg, + WorkItem::kWow64Default, L"Publisher", browser_dist->GetPublisherName(), true); - install_list->AddSetRegValueWorkItem(reg_root, uninstall_reg, + install_list->AddSetRegValueWorkItem(reg_root, + uninstall_reg, + WorkItem::kWow64Default, L"Version", ASCIIToWide(new_version.GetString()), true); - install_list->AddSetRegValueWorkItem(reg_root, uninstall_reg, + install_list->AddSetRegValueWorkItem(reg_root, + uninstall_reg, + WorkItem::kWow64Default, L"DisplayVersion", ASCIIToWide(new_version.GetString()), true); - install_list->AddSetRegValueWorkItem(reg_root, uninstall_reg, + install_list->AddSetRegValueWorkItem(reg_root, + uninstall_reg, + WorkItem::kWow64Default, L"InstallDate", InstallUtil::GetCurrentDate(), false); @@ -754,10 +795,20 @@ void AddUninstallShortcutWorkItems(const InstallerState& installer_state, const std::vector<uint16>& version_components = new_version.components(); if (version_components.size() == 4) { // Our version should be in major.minor.build.rev. - install_list->AddSetRegValueWorkItem(reg_root, uninstall_reg, - L"VersionMajor", static_cast<DWORD>(version_components[2]), true); - install_list->AddSetRegValueWorkItem(reg_root, uninstall_reg, - L"VersionMinor", static_cast<DWORD>(version_components[3]), true); + install_list->AddSetRegValueWorkItem( + reg_root, + uninstall_reg, + WorkItem::kWow64Default, + L"VersionMajor", + static_cast<DWORD>(version_components[2]), + true); + install_list->AddSetRegValueWorkItem( + reg_root, + uninstall_reg, + WorkItem::kWow64Default, + L"VersionMinor", + static_cast<DWORD>(version_components[3]), + true); } } } @@ -772,12 +823,18 @@ void AddVersionKeyWorkItems(HKEY root, // Create Version key for each distribution (if not already present) and set // the new product version as the last step. base::string16 version_key(dist->GetVersionKey()); - list->AddCreateRegKeyWorkItem(root, version_key); + list->AddCreateRegKeyWorkItem(root, version_key, WorkItem::kWow64Default); base::string16 product_name(dist->GetDisplayName()); - list->AddSetRegValueWorkItem(root, version_key, google_update::kRegNameField, - product_name, true); // overwrite name also - list->AddSetRegValueWorkItem(root, version_key, + list->AddSetRegValueWorkItem(root, + version_key, + WorkItem::kWow64Default, + google_update::kRegNameField, + product_name, + true); // overwrite name also + list->AddSetRegValueWorkItem(root, + version_key, + WorkItem::kWow64Default, google_update::kRegOopcrashesField, static_cast<DWORD>(1), false); // set during first install @@ -788,11 +845,16 @@ void AddVersionKeyWorkItems(HKEY root, base::string16 language(GetCurrentTranslation()); if (LowerCaseEqualsASCII(language, "en-us")) language.resize(2); - list->AddSetRegValueWorkItem(root, version_key, - google_update::kRegLangField, language, + list->AddSetRegValueWorkItem(root, + version_key, + WorkItem::kWow64Default, + google_update::kRegLangField, + language, false); // do not overwrite language } - list->AddSetRegValueWorkItem(root, version_key, + list->AddSetRegValueWorkItem(root, + version_key, + WorkItem::kWow64Default, google_update::kRegVersionField, ASCIIToWide(new_version.GetString()), true); // overwrite version @@ -834,15 +896,22 @@ void AddOemInstallWorkItems(const InstallationState& original_state, VLOG(1) << "Mirroring oeminstall=\"" << oem_install << "\" from " << BrowserDistribution::GetSpecificDistribution(source_type)-> GetDisplayName(); - install_list->AddCreateRegKeyWorkItem(root_key, multi_key); + install_list->AddCreateRegKeyWorkItem( + root_key, multi_key, WorkItem::kWow64Default); // Always overwrite an old value. - install_list->AddSetRegValueWorkItem(root_key, multi_key, + install_list->AddSetRegValueWorkItem(root_key, + multi_key, + WorkItem::kWow64Default, google_update::kRegOemInstallField, - oem_install, true); + oem_install, + true); } else { // Clear any old value. install_list->AddDeleteRegValueWorkItem( - root_key, multi_key, google_update::kRegOemInstallField); + root_key, + multi_key, + WorkItem::kWow64Default, + google_update::kRegOemInstallField); } } } @@ -889,14 +958,21 @@ void AddEulaAcceptedWorkItems(const InstallationState& original_state, VLOG(1) << "Mirroring eulaaccepted=" << eula_accepted << " from " << BrowserDistribution::GetSpecificDistribution(product_type)-> GetDisplayName(); - install_list->AddCreateRegKeyWorkItem(root_key, multi_key); - install_list->AddSetRegValueWorkItem( - root_key, multi_key, google_update::kRegEULAAceptedField, - eula_accepted, true); + install_list->AddCreateRegKeyWorkItem( + root_key, multi_key, WorkItem::kWow64Default); + install_list->AddSetRegValueWorkItem(root_key, + multi_key, + WorkItem::kWow64Default, + google_update::kRegEULAAceptedField, + eula_accepted, + true); } else { // Clear any old value. install_list->AddDeleteRegValueWorkItem( - root_key, multi_key, google_update::kRegEULAAceptedField); + root_key, + multi_key, + WorkItem::kWow64Default, + google_update::kRegEULAAceptedField); } } } @@ -922,8 +998,9 @@ void AddGoogleUpdateWorkItems(const InstallationState& original_state, if (system_install) { install_list->AddCreateRegKeyWorkItem( root_key, - installer_state.multi_package_binaries_distribution()-> - GetStateMediumKey().c_str()); + installer_state.multi_package_binaries_distribution() + ->GetStateMediumKey().c_str(), + WorkItem::kWow64Default); } // Creating the ClientState key for binaries, if we're migrating to multi then @@ -935,11 +1012,13 @@ void AddGoogleUpdateWorkItems(const InstallationState& original_state, const base::string16& brand(chrome_product_state->brand()); if (!brand.empty()) { - install_list->AddCreateRegKeyWorkItem(root_key, multi_key); + install_list->AddCreateRegKeyWorkItem( + root_key, multi_key, WorkItem::kWow64Default); // Write Chrome's brand code to the multi key. Never overwrite the value // if one is already present (although this shouldn't happen). install_list->AddSetRegValueWorkItem(root_key, multi_key, + WorkItem::kWow64Default, google_update::kRegBrandField, brand, false); @@ -982,12 +1061,16 @@ void AddUsageStatsWorkItems(const InstallationState& original_state, if (value_found) { base::string16 state_key( installer_state.multi_package_binaries_distribution()->GetStateKey()); - install_list->AddCreateRegKeyWorkItem(root_key, state_key); + install_list->AddCreateRegKeyWorkItem( + root_key, state_key, WorkItem::kWow64Default); // Overwrite any existing value so that overinstalls (where Omaha writes a // new value into a product's state key) pick up the correct value. - install_list->AddSetRegValueWorkItem(root_key, state_key, + install_list->AddSetRegValueWorkItem(root_key, + state_key, + WorkItem::kWow64Default, google_update::kRegUsageStatsField, - usagestats, true); + usagestats, + true); for (Products::const_iterator scan = products.begin(), end = products.end(); scan != end; ++scan) { @@ -996,16 +1079,23 @@ void AddUsageStatsWorkItems(const InstallationState& original_state, BrowserDistribution* dist = (*scan)->distribution(); if (installer_state.system_install()) { install_list->AddDeleteRegValueWorkItem( - root_key, dist->GetStateMediumKey(), + root_key, + dist->GetStateMediumKey(), + WorkItem::kWow64Default, google_update::kRegUsageStatsField); // Previous versions of Chrome also wrote a value in HKCU even for // system-level installs, so clean that up. install_list->AddDeleteRegValueWorkItem( - HKEY_CURRENT_USER, dist->GetStateKey(), + HKEY_CURRENT_USER, + dist->GetStateKey(), + WorkItem::kWow64Default, google_update::kRegUsageStatsField); } install_list->AddDeleteRegValueWorkItem( - root_key, dist->GetStateKey(), google_update::kRegUsageStatsField); + root_key, + dist->GetStateKey(), + WorkItem::kWow64Default, + google_update::kRegUsageStatsField); } } } @@ -1055,16 +1145,27 @@ bool AppendPostInstallTasks(const InstallerState& installer_state, version_key = dist->GetVersionKey(); if (current_version) { - in_use_update_work_items->AddSetRegValueWorkItem(root, version_key, + in_use_update_work_items->AddSetRegValueWorkItem( + root, + version_key, + WorkItem::kWow64Default, google_update::kRegOldVersionField, - ASCIIToWide(current_version->GetString()), true); + ASCIIToWide(current_version->GetString()), + true); } if (critical_version.IsValid()) { - in_use_update_work_items->AddSetRegValueWorkItem(root, version_key, + in_use_update_work_items->AddSetRegValueWorkItem( + root, + version_key, + WorkItem::kWow64Default, google_update::kRegCriticalVersionField, - ASCIIToWide(critical_version.GetString()), true); + ASCIIToWide(critical_version.GetString()), + true); } else { - in_use_update_work_items->AddDeleteRegValueWorkItem(root, version_key, + in_use_update_work_items->AddDeleteRegValueWorkItem( + root, + version_key, + WorkItem::kWow64Default, google_update::kRegCriticalVersionField); } @@ -1077,8 +1178,12 @@ bool AppendPostInstallTasks(const InstallerState& installer_state, CommandLine product_rename_cmd(rename); products[i]->AppendRenameFlags(&product_rename_cmd); in_use_update_work_items->AddSetRegValueWorkItem( - root, version_key, google_update::kRegRenameCmdField, - product_rename_cmd.GetCommandLineString(), true); + root, + version_key, + WorkItem::kWow64Default, + google_update::kRegRenameCmdField, + product_rename_cmd.GetCommandLineString(), + true); } } @@ -1096,11 +1201,20 @@ bool AppendPostInstallTasks(const InstallerState& installer_state, for (size_t i = 0; i < products.size(); ++i) { BrowserDistribution* dist = products[i]->distribution(); base::string16 version_key(dist->GetVersionKey()); - regular_update_work_items->AddDeleteRegValueWorkItem(root, version_key, + regular_update_work_items->AddDeleteRegValueWorkItem( + root, + version_key, + WorkItem::kWow64Default, google_update::kRegOldVersionField); - regular_update_work_items->AddDeleteRegValueWorkItem(root, version_key, + regular_update_work_items->AddDeleteRegValueWorkItem( + root, + version_key, + WorkItem::kWow64Default, google_update::kRegCriticalVersionField); - regular_update_work_items->AddDeleteRegValueWorkItem(root, version_key, + regular_update_work_items->AddDeleteRegValueWorkItem( + root, + version_key, + WorkItem::kWow64Default, google_update::kRegRenameCmdField); } @@ -1262,9 +1376,13 @@ void AddSetMsiMarkerWorkItem(const InstallerState& installer_state, WorkItemList* work_item_list) { DCHECK(work_item_list); DWORD msi_value = set ? 1 : 0; - WorkItem* set_msi_work_item = work_item_list->AddSetRegValueWorkItem( - installer_state.root_key(), dist->GetStateKey(), - google_update::kRegMSIField, msi_value, true); + WorkItem* set_msi_work_item = + work_item_list->AddSetRegValueWorkItem(installer_state.root_key(), + dist->GetStateKey(), + WorkItem::kWow64Default, + google_update::kRegMSIField, + msi_value, + true); DCHECK(set_msi_work_item); set_msi_work_item->set_ignore_failure(true); set_msi_work_item->set_log_message("Could not write MSI marker!"); @@ -1317,18 +1435,28 @@ void AddDelegateExecuteWorkItems(const InstallerState& installer_state, command.append(delegate_execute.value()).append(1, L'"'); // Register the CommandExecuteImpl class in Software\Classes\CLSID\... - list->AddCreateRegKeyWorkItem(root, delegate_execute_path); - list->AddSetRegValueWorkItem(root, delegate_execute_path, L"", - L"CommandExecuteImpl Class", true); + list->AddCreateRegKeyWorkItem( + root, delegate_execute_path, WorkItem::kWow64Default); + list->AddSetRegValueWorkItem(root, + delegate_execute_path, + WorkItem::kWow64Default, + L"", + L"CommandExecuteImpl Class", + true); base::string16 subkey(delegate_execute_path); subkey.append(L"\\LocalServer32"); - list->AddCreateRegKeyWorkItem(root, subkey); - list->AddSetRegValueWorkItem(root, subkey, L"", command, true); - list->AddSetRegValueWorkItem(root, subkey, L"ServerExecutable", - delegate_execute.value(), true); + list->AddCreateRegKeyWorkItem(root, subkey, WorkItem::kWow64Default); + list->AddSetRegValueWorkItem( + root, subkey, WorkItem::kWow64Default, L"", command, true); + list->AddSetRegValueWorkItem(root, + subkey, + WorkItem::kWow64Default, + L"ServerExecutable", + delegate_execute.value(), + true); subkey.assign(delegate_execute_path).append(L"\\Programmable"); - list->AddCreateRegKeyWorkItem(root, subkey); + list->AddCreateRegKeyWorkItem(root, subkey, WorkItem::kWow64Default); } } @@ -1353,9 +1481,14 @@ void AddActiveSetupWorkItems(const InstallerState& installer_state, const base::string16 active_setup_path(InstallUtil::GetActiveSetupPath(dist)); VLOG(1) << "Adding registration items for Active Setup."; - list->AddCreateRegKeyWorkItem(root, active_setup_path); - list->AddSetRegValueWorkItem(root, active_setup_path, L"", - dist->GetDisplayName(), true); + list->AddCreateRegKeyWorkItem( + root, active_setup_path, WorkItem::kWow64Default); + list->AddSetRegValueWorkItem(root, + active_setup_path, + WorkItem::kWow64Default, + L"", + dist->GetDisplayName(), + true); base::FilePath active_setup_exe(installer_state.GetInstallerDirectory( new_version).Append(kActiveSetupExe)); @@ -1364,19 +1497,35 @@ void AddActiveSetupWorkItems(const InstallerState& installer_state, cmd.AppendSwitch(installer::switches::kVerboseLogging); cmd.AppendSwitch(installer::switches::kSystemLevel); product.AppendProductFlags(&cmd); - list->AddSetRegValueWorkItem(root, active_setup_path, L"StubPath", - cmd.GetCommandLineString(), true); + list->AddSetRegValueWorkItem(root, + active_setup_path, + WorkItem::kWow64Default, + L"StubPath", + cmd.GetCommandLineString(), + true); // TODO(grt): http://crbug.com/75152 Write a reference to a localized // resource. - list->AddSetRegValueWorkItem(root, active_setup_path, L"Localized Name", - dist->GetDisplayName(), true); - - list->AddSetRegValueWorkItem(root, active_setup_path, L"IsInstalled", - static_cast<DWORD>(1U), true); - - list->AddSetRegValueWorkItem(root, active_setup_path, L"Version", - kActiveSetupVersion, true); + list->AddSetRegValueWorkItem(root, + active_setup_path, + WorkItem::kWow64Default, + L"Localized Name", + dist->GetDisplayName(), + true); + + list->AddSetRegValueWorkItem(root, + active_setup_path, + WorkItem::kWow64Default, + L"IsInstalled", + static_cast<DWORD>(1U), + true); + + list->AddSetRegValueWorkItem(root, + active_setup_path, + WorkItem::kWow64Default, + L"Version", + kActiveSetupVersion, + true); } void AddDeleteOldIELowRightsPolicyWorkItems( @@ -1386,7 +1535,8 @@ void AddDeleteOldIELowRightsPolicyWorkItems( base::string16 key_path; GetOldIELowRightsElevationPolicyKeyPath(&key_path); - install_list->AddDeleteRegKeyWorkItem(installer_state.root_key(), key_path); + install_list->AddDeleteRegKeyWorkItem( + installer_state.root_key(), key_path, WorkItem::kWow64Default); } void AppendUninstallCommandLineFlags(const InstallerState& installer_state, @@ -1438,8 +1588,9 @@ void AddOsUpgradeWorkItems(const InstallerState& installer_state, GetRegCommandKey(product.distribution(), kCmdOnOsUpgrade)); if (installer_state.operation() == InstallerState::UNINSTALL) { - install_list->AddDeleteRegKeyWorkItem(root_key, cmd_key)-> - set_log_message("Removing OS upgrade command"); + install_list->AddDeleteRegKeyWorkItem( + root_key, cmd_key, WorkItem::kWow64Default) + ->set_log_message("Removing OS upgrade command"); } else { // Register with Google Update to have setup.exe --on-os-upgrade called on // OS upgrade. @@ -1470,8 +1621,9 @@ void AddQueryEULAAcceptanceWorkItems(const InstallerState& installer_state, base::string16 cmd_key( GetRegCommandKey(product.distribution(), kCmdQueryEULAAcceptance)); if (installer_state.operation() == InstallerState::UNINSTALL) { - work_item_list->AddDeleteRegKeyWorkItem(root_key, cmd_key)-> - set_log_message("Removing query EULA acceptance command"); + work_item_list->AddDeleteRegKeyWorkItem( + root_key, cmd_key, WorkItem::kWow64Default) + ->set_log_message("Removing query EULA acceptance command"); } else { CommandLine cmd_line(installer_state .GetInstallerDirectory(new_version) @@ -1501,9 +1653,9 @@ void AddQuickEnableChromeFrameWorkItems(const InstallerState& installer_state, // Do this even if multi-install Chrome isn't installed to ensure that it is // not left behind in any case. work_item_list->AddDeleteRegKeyWorkItem( - installer_state.root_key(), cmd_key)->set_log_message( - "removing " + base::UTF16ToASCII(kCmdQuickEnableCf) + " command"); - + installer_state.root_key(), cmd_key, WorkItem::kWow64Default) + ->set_log_message("removing " + + base::UTF16ToASCII(kCmdQuickEnableCf) + " command"); } } // namespace installer diff --git a/chrome/installer/setup/install_worker_unittest.cc b/chrome/installer/setup/install_worker_unittest.cc index 9d2a266..0597521 100644 --- a/chrome/installer/setup/install_worker_unittest.cc +++ b/chrome/installer/setup/install_worker_unittest.cc @@ -438,10 +438,11 @@ TEST_F(InstallWorkerTest, TestInstallChromeSingleSystem) { const HKEY kRegRoot = system_level ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; static const wchar_t kRegKeyPath[] = L"Software\\Chromium\\test"; scoped_ptr<CreateRegKeyWorkItem> create_reg_key_work_item( - WorkItem::CreateCreateRegKeyWorkItem(kRegRoot, kRegKeyPath)); + WorkItem::CreateCreateRegKeyWorkItem( + kRegRoot, kRegKeyPath, WorkItem::kWow64Default)); scoped_ptr<SetRegValueWorkItem> set_reg_value_work_item( - WorkItem::CreateSetRegValueWorkItem(kRegRoot, kRegKeyPath, L"", L"", - false)); + WorkItem::CreateSetRegValueWorkItem( + kRegRoot, kRegKeyPath, WorkItem::kWow64Default, L"", L"", false)); scoped_ptr<InstallationState> installation_state( BuildChromeInstallationState(system_level, multi_install)); @@ -683,8 +684,8 @@ class QuickEnableAbsentTest : public InstallWorkerTest { virtual void SetUp() { InstallWorkerTest::SetUp(); root_key_ = system_level_ ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; - delete_reg_key_item_.reset( - WorkItem::CreateDeleteRegKeyWorkItem(root_key_, kRegKeyPath)); + delete_reg_key_item_.reset(WorkItem::CreateDeleteRegKeyWorkItem( + root_key_, kRegKeyPath, WorkItem::kWow64Default)); machine_state_.reset(new MockInstallationState()); EXPECT_CALL(work_item_list_, AddDeleteRegKeyWorkItem(Eq(root_key_), StrCaseEq(kRegKeyPath))) diff --git a/chrome/installer/setup/setup_main.cc b/chrome/installer/setup/setup_main.cc index 57fe5e5..9440759 100644 --- a/chrome/installer/setup/setup_main.cc +++ b/chrome/installer/setup/setup_main.cc @@ -264,11 +264,14 @@ installer::InstallStatus RenameChromeExecutables( ++it) { version_key = (*it)->distribution()->GetVersionKey(); install_list->AddDeleteRegValueWorkItem( - reg_root, version_key, google_update::kRegOldVersionField); + reg_root, version_key, WorkItem::kWow64Default, + google_update::kRegOldVersionField); install_list->AddDeleteRegValueWorkItem( - reg_root, version_key, google_update::kRegCriticalVersionField); + reg_root, version_key, WorkItem::kWow64Default, + google_update::kRegCriticalVersionField); install_list->AddDeleteRegValueWorkItem( - reg_root, version_key, google_update::kRegRenameCmdField); + reg_root, version_key, WorkItem::kWow64Default, + google_update::kRegRenameCmdField); } installer::InstallStatus ret = installer::RENAME_SUCCESSFUL; if (!install_list->Do()) { diff --git a/chrome/installer/setup/uninstall.cc b/chrome/installer/setup/uninstall.cc index 353e390..09a9502 100644 --- a/chrome/installer/setup/uninstall.cc +++ b/chrome/installer/setup/uninstall.cc @@ -46,6 +46,7 @@ #include "chrome/installer/util/self_cleaning_temp_dir.h" #include "chrome/installer/util/shell_util.h" #include "chrome/installer/util/util_constants.h" +#include "chrome/installer/util/work_item.h" #include "content/public/common/result_codes.h" #include "rlz/lib/rlz_lib.h" @@ -94,8 +95,12 @@ void AddChannelValueUpdateWorkItems( !product_state->channel().Equals(channel_info)) { BrowserDistribution* other_dist = BrowserDistribution::GetSpecificDistribution(dist_type); - update_list->AddSetRegValueWorkItem(reg_root, other_dist->GetStateKey(), - google_update::kRegApField, channel_info.value(), true); + update_list->AddSetRegValueWorkItem(reg_root, + other_dist->GetStateKey(), + WorkItem::kWow64Default, + google_update::kRegApField, + channel_info.value(), + true); } else { LOG_IF(ERROR, product_state != NULL && product_state->is_multi_install()) @@ -680,8 +685,8 @@ void RemoveFiletypeRegistration(const InstallerState& installer_state, &ShellUtil::kPotentialFileAssociations[0]; *filetype != NULL; ++filetype) { if (InstallUtil::DeleteRegistryValueIf( - root, (classes_path + *filetype).c_str(), NULL, - prog_id_pred) == InstallUtil::DELETED) { + root, (classes_path + *filetype).c_str(), WorkItem::kWow64Default, + NULL, prog_id_pred) == InstallUtil::DELETED) { cleared_assocs.push_back(*filetype); } } @@ -755,7 +760,8 @@ void UninstallActiveSetupEntries(const InstallerState& installer_state, const base::string16 active_setup_path( InstallUtil::GetActiveSetupPath(distribution)); - InstallUtil::DeleteRegistryKey(HKEY_LOCAL_MACHINE, active_setup_path); + InstallUtil::DeleteRegistryKey(HKEY_LOCAL_MACHINE, active_setup_path, + WorkItem::kWow64Default); // Windows leaves keys behind in HKCU\\Software\\(Wow6432Node\\)?Microsoft\\ // Active Setup\\Installed Components\\{guid} @@ -901,7 +907,7 @@ bool DeleteChromeRegistrationKeys(const InstallerState& installer_state, base::string16 reg_prog_id(ShellUtil::kRegClasses); reg_prog_id.push_back(base::FilePath::kSeparators[0]); reg_prog_id.append(prog_id); - InstallUtil::DeleteRegistryKey(root, reg_prog_id); + InstallUtil::DeleteRegistryKey(root, reg_prog_id, WorkItem::kWow64Default); // Delete Software\Classes\Chrome. base::string16 reg_app_id(ShellUtil::kRegClasses); @@ -909,7 +915,7 @@ bool DeleteChromeRegistrationKeys(const InstallerState& installer_state, // Append the requested suffix manually here (as ShellUtil::GetBrowserModelId // would otherwise try to figure out the currently installed suffix). reg_app_id.append(dist->GetBaseAppId() + browser_entry_suffix); - InstallUtil::DeleteRegistryKey(root, reg_app_id); + InstallUtil::DeleteRegistryKey(root, reg_app_id, WorkItem::kWow64Default); // Delete all Start Menu Internet registrations that refer to this Chrome. { @@ -925,13 +931,14 @@ bool DeleteChromeRegistrationKeys(const InstallerState& installer_state, .append(1, L'\\') .append(client_name); open_key.assign(client_key).append(ShellUtil::kRegShellOpen); - if (InstallUtil::DeleteRegistryKeyIf(root, client_key, open_key, NULL, - open_command_pred) != InstallUtil::NOT_FOUND) { + if (InstallUtil::DeleteRegistryKeyIf(root, client_key, open_key, + WorkItem::kWow64Default, NULL, open_command_pred) + != InstallUtil::NOT_FOUND) { // Delete the default value of SOFTWARE\Clients\StartMenuInternet if it // references this Chrome (i.e., if it was made the default browser). InstallUtil::DeleteRegistryValueIf( - root, ShellUtil::kRegStartMenuInternet, NULL, - InstallUtil::ValueEquals(client_name)); + root, ShellUtil::kRegStartMenuInternet, WorkItem::kWow64Default, + NULL, InstallUtil::ValueEquals(client_name)); // Also delete the value for the default user if we're operating in // HKLM. if (root == HKEY_LOCAL_MACHINE) { @@ -939,7 +946,8 @@ bool DeleteChromeRegistrationKeys(const InstallerState& installer_state, HKEY_USERS, base::string16(L".DEFAULT\\").append( ShellUtil::kRegStartMenuInternet).c_str(), - NULL, InstallUtil::ValueEquals(client_name)); + WorkItem::kWow64Default, NULL, + InstallUtil::ValueEquals(client_name)); } } } @@ -948,6 +956,7 @@ bool DeleteChromeRegistrationKeys(const InstallerState& installer_state, // Delete Software\RegisteredApplications\Chromium InstallUtil::DeleteRegistryValue( root, ShellUtil::kRegRegisteredApplications, + WorkItem::kWow64Default, dist->GetBaseAppName() + browser_entry_suffix); // Delete the App Paths and Applications keys that let Explorer find Chrome: @@ -957,12 +966,12 @@ bool DeleteChromeRegistrationKeys(const InstallerState& installer_state, app_key.append(L"Applications"); app_key.push_back(base::FilePath::kSeparators[0]); app_key.append(installer::kChromeExe); - InstallUtil::DeleteRegistryKey(root, app_key); + InstallUtil::DeleteRegistryKey(root, app_key, WorkItem::kWow64Default); base::string16 app_path_key(ShellUtil::kAppPathsRegistryKey); app_path_key.push_back(base::FilePath::kSeparators[0]); app_path_key.append(installer::kChromeExe); - InstallUtil::DeleteRegistryKey(root, app_path_key); + InstallUtil::DeleteRegistryKey(root, app_path_key, WorkItem::kWow64Default); // Cleanup OpenWithList and OpenWithProgids: // http://msdn.microsoft.com/en-us/library/bb166549 @@ -979,11 +988,13 @@ bool DeleteChromeRegistrationKeys(const InstallerState& installer_state, open_with_list_key.append(L"OpenWithList"); open_with_list_key.push_back(base::FilePath::kSeparators[0]); open_with_list_key.append(installer::kChromeExe); - InstallUtil::DeleteRegistryKey(root, open_with_list_key); + InstallUtil::DeleteRegistryKey( + root, open_with_list_key, WorkItem::kWow64Default); open_with_progids_key.assign(file_assoc_key); open_with_progids_key.append(ShellUtil::kRegOpenWithProgids); - InstallUtil::DeleteRegistryValue(root, open_with_progids_key, prog_id); + InstallUtil::DeleteRegistryValue(root, open_with_progids_key, + WorkItem::kWow64Default, prog_id); } // Cleanup in case Chrome had been made the default browser. @@ -993,7 +1004,7 @@ bool DeleteChromeRegistrationKeys(const InstallerState& installer_state, // being processed; the iteration above will have no hits since registration // lives in HKLM. InstallUtil::DeleteRegistryValueIf( - root, ShellUtil::kRegStartMenuInternet, NULL, + root, ShellUtil::kRegStartMenuInternet, WorkItem::kWow64Default, NULL, InstallUtil::ValueEquals(dist->GetBaseAppName() + browser_entry_suffix)); // Delete each protocol association if it references this Chrome. @@ -1009,7 +1020,8 @@ bool DeleteChromeRegistrationKeys(const InstallerState& installer_state, parent_key.resize(base_length); parent_key.append(*proto); child_key.assign(parent_key).append(ShellUtil::kRegShellOpen); - InstallUtil::DeleteRegistryKeyIf(root, parent_key, child_key, NULL, + InstallUtil::DeleteRegistryKeyIf(root, parent_key, child_key, + WorkItem::kWow64Default, NULL, open_command_pred); } @@ -1042,13 +1054,15 @@ const wchar_t kChromeExtProgId[] = L"ChromiumExt"; ext_prog_id.push_back(base::FilePath::kSeparators[0]); ext_prog_id.append(kChromeExtProgId); ext_prog_id.append(suffix); - InstallUtil::DeleteRegistryKey(roots[i], ext_prog_id); + InstallUtil::DeleteRegistryKey(roots[i], ext_prog_id, + WorkItem::kWow64Default); // Delete Software\Classes\.crx, base::string16 ext_association(ShellUtil::kRegClasses); ext_association.append(L"\\"); ext_association.append(L".crx"); - InstallUtil::DeleteRegistryKey(roots[i], ext_association); + InstallUtil::DeleteRegistryKey(roots[i], ext_association, + WorkItem::kWow64Default); } } @@ -1128,7 +1142,8 @@ InstallStatus UninstallProduct(const InstallationState& original_state, // Delete the key that delegate_execute might make. if (base::win::GetVersion() >= base::win::VERSION_WIN8) { InstallUtil::DeleteRegistryKey(HKEY_CURRENT_USER, - chrome::kMetroRegistryPath); + chrome::kMetroRegistryPath, + WorkItem::kWow64Default); } auto_launch_util::DisableAllAutoStartFeatures( @@ -1165,11 +1180,13 @@ InstallStatus UninstallProduct(const InstallationState& original_state, // Remove Control Panel uninstall link. if (product.ShouldCreateUninstallEntry()) { InstallUtil::DeleteRegistryKey(reg_root, - browser_dist->GetUninstallRegPath()); + browser_dist->GetUninstallRegPath(), + WorkItem::kWow64Default); } // Remove Omaha product key. - InstallUtil::DeleteRegistryKey(reg_root, browser_dist->GetVersionKey()); + InstallUtil::DeleteRegistryKey(reg_root, browser_dist->GetVersionKey(), + WorkItem::kWow64Default); // Also try to delete the MSI value in the ClientState key (it might not be // there). This is due to a Google Update behaviour where an uninstall and a @@ -1261,8 +1278,10 @@ InstallStatus UninstallProduct(const InstallationState& original_state, BrowserDistribution* shadow_app_launcher_dist = BrowserDistribution::GetSpecificDistribution( BrowserDistribution::CHROME_APP_HOST); - InstallUtil::DeleteRegistryKey(reg_root, - shadow_app_launcher_dist->GetVersionKey()); + InstallUtil::DeleteRegistryKey( + reg_root, + shadow_app_launcher_dist->GetVersionKey(), + WorkItem::kWow64Default); } } } @@ -1285,7 +1304,8 @@ InstallStatus UninstallProduct(const InstallationState& original_state, base::string16 reg_path(installer::kMediaPlayerRegPath); reg_path.push_back(base::FilePath::kSeparators[0]); reg_path.append(installer::kChromeExe); - InstallUtil::DeleteRegistryKey(HKEY_LOCAL_MACHINE, reg_path); + InstallUtil::DeleteRegistryKey(HKEY_LOCAL_MACHINE, reg_path, + WorkItem::kWow64Default); } // Unregister any dll servers that we may have registered for this diff --git a/chrome/installer/util/app_command.cc b/chrome/installer/util/app_command.cc index 8f54e72..78d931d 100644 --- a/chrome/installer/util/app_command.cc +++ b/chrome/installer/util/app_command.cc @@ -70,11 +70,15 @@ bool AppCommand::Initialize(const base::win::RegKey& key) { void AppCommand::AddWorkItems(HKEY predefined_root, const base::string16& command_path, WorkItemList* item_list) const { - item_list->AddCreateRegKeyWorkItem(predefined_root, command_path) + item_list->AddCreateRegKeyWorkItem( + predefined_root, command_path, WorkItem::kWow64Default) ->set_log_message("creating AppCommand registry key"); - item_list->AddSetRegValueWorkItem(predefined_root, command_path, + item_list->AddSetRegValueWorkItem(predefined_root, + command_path, + WorkItem::kWow64Default, google_update::kRegCommandLineField, - command_line_, true) + command_line_, + true) ->set_log_message("setting AppCommand CommandLine registry value"); for (int i = 0; i < arraysize(kNameBoolVars); ++i) { @@ -86,13 +90,13 @@ void AppCommand::AddWorkItems(HKEY predefined_root, if (var_data) { item_list->AddSetRegValueWorkItem(predefined_root, command_path, + WorkItem::kWow64Default, var_name, static_cast<DWORD>(1), true); } else { - item_list->AddDeleteRegValueWorkItem(predefined_root, - command_path, - var_name); + item_list->AddDeleteRegValueWorkItem( + predefined_root, command_path, WorkItem::kWow64Default, var_name); } } } diff --git a/chrome/installer/util/copy_reg_key_work_item.cc b/chrome/installer/util/copy_reg_key_work_item.cc deleted file mode 100644 index 9fbac76..0000000 --- a/chrome/installer/util/copy_reg_key_work_item.cc +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Implementation of a work item that replaces the contents of one registry key -// with that of another (i.e., the destination is erased prior to the copy). - -#include "chrome/installer/util/copy_reg_key_work_item.h" - -#include <shlwapi.h> - -#include "base/logging.h" -#include "base/win/registry.h" - -using base::win::RegKey; - -CopyRegKeyWorkItem::~CopyRegKeyWorkItem() { -} - -CopyRegKeyWorkItem::CopyRegKeyWorkItem(HKEY predefined_root, - const std::wstring& source_key_path, - const std::wstring& dest_key_path, - CopyOverWriteOption overwrite_option) - : predefined_root_(predefined_root), - source_key_path_(source_key_path), - dest_key_path_(dest_key_path), - overwrite_option_(overwrite_option), - cleared_destination_(false) { - DCHECK(predefined_root); - // It's a safe bet that we don't want to copy or overwrite one of the root - // trees. - DCHECK(!source_key_path.empty()); - DCHECK(!dest_key_path.empty()); - DCHECK(overwrite_option == ALWAYS || overwrite_option == IF_NOT_PRESENT); -} - -bool CopyRegKeyWorkItem::Do() { - if (source_key_path_.empty() || dest_key_path_.empty()) - return false; - - // Leave immediately if we're not supposed to overwrite an existing key and - // one is there. - if (overwrite_option_ == IF_NOT_PRESENT && - RegKey(predefined_root_, dest_key_path_.c_str(), - KEY_QUERY_VALUE).Valid()) { - return true; - } - - RegistryKeyBackup backup; - RegKey dest_key; - - // Only try to make a backup if we're not configured to ignore failures. - if (!ignore_failure_) { - if (!backup.Initialize(predefined_root_, dest_key_path_.c_str())) { - LOG(ERROR) << "Failed to backup destination for registry key copy."; - return false; - } - } - - // Delete the destination before attempting to copy. - LONG result = SHDeleteKey(predefined_root_, dest_key_path_.c_str()); - if (result != ERROR_SUCCESS && result != ERROR_FILE_NOT_FOUND) { - LOG(ERROR) << "Failed to delete key at " << dest_key_path_ << ", result: " - << result; - } else { - cleared_destination_ = true; - // We've just modified the registry, so remember any backup we may have - // made so that Rollback can take us back where we started. - backup_.swap(backup); - // Make the copy. - result = dest_key.Create(predefined_root_, dest_key_path_.c_str(), - KEY_WRITE); - if (result != ERROR_SUCCESS) { - LOG(ERROR) << "Failed to open destination key at " << dest_key_path_ - << ", result: " << result; - } else { - result = SHCopyKey(predefined_root_, source_key_path_.c_str(), - dest_key.Handle(), 0); - switch (result) { - case ERROR_FILE_NOT_FOUND: - // The source didn't exist, so neither should the destination. - dest_key.Close(); - SHDeleteKey(predefined_root_, dest_key_path_.c_str()); - // Handle like a success. - result = ERROR_SUCCESS; - // -- Fall through to success case. -- - case ERROR_SUCCESS: - break; - default: - LOG(ERROR) << "Failed to copy key from " << source_key_path_ << " to " - << dest_key_path_ << ", result: " << result; - break; - } - } - } - - return ignore_failure_ ? true : (result == ERROR_SUCCESS); -} - -void CopyRegKeyWorkItem::Rollback() { - if (ignore_failure_) - return; - - if (cleared_destination_) { - // Delete anything in the key before restoring the backup in case new data - // was written after Do(). - LONG result = SHDeleteKey(predefined_root_, dest_key_path_.c_str()); - if (result != ERROR_SUCCESS && result != ERROR_FILE_NOT_FOUND) { - LOG(ERROR) << "Failed to delete key at " << dest_key_path_ - << " in rollback, result: " << result; - } - - // Restore the old contents. The restoration takes on its default security - // attributes; any custom attributes are lost. - if (!backup_.WriteTo(predefined_root_, dest_key_path_.c_str())) - LOG(ERROR) << "Failed to restore key in rollback."; - } -} diff --git a/chrome/installer/util/copy_reg_key_work_item.h b/chrome/installer/util/copy_reg_key_work_item.h deleted file mode 100644 index 7a84b63..0000000 --- a/chrome/installer/util/copy_reg_key_work_item.h +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_INSTALLER_UTIL_COPY_REG_KEY_WORK_ITEM_H_ -#define CHROME_INSTALLER_UTIL_COPY_REG_KEY_WORK_ITEM_H_ - -#include <string> - -#include "base/basictypes.h" -#include "base/compiler_specific.h" -#include "chrome/installer/util/registry_key_backup.h" -#include "chrome/installer/util/work_item.h" - -// A WorkItem subclass that replaces the contents of one registry key with that -// of another (i.e., the destination is erased prior to the copy). Be aware -// that in the event of rollback the destination key's values and subkeys are -// restored but the key and its subkeys take on their default security -// descriptors. -class CopyRegKeyWorkItem : public WorkItem { - public: - virtual ~CopyRegKeyWorkItem(); - virtual bool Do() OVERRIDE; - virtual void Rollback() OVERRIDE; - - private: - // Grant WorkItem access to the ctor (required by the existing WorkItem - // design). - friend class WorkItem; - - // Neither |source_key_path| nor |dest_key_path| may be empty. - // Only ALWAYS and IF_NOT_PRESENT are supported for |overwrite_option|. - CopyRegKeyWorkItem(HKEY predefined_key, - const std::wstring& source_key_path, - const std::wstring& dest_key_path, - CopyOverWriteOption overwrite_option); - - // Root key in which we operate. The root key must be one of the predefined - // keys on Windows. - HKEY predefined_root_; - - // Path of the key to be copied. - std::wstring source_key_path_; - - // Path of the destination key. - std::wstring dest_key_path_; - - // WorkItem::ALWAYS or WorkItem::IF_NOT_PRESENT. - CopyOverWriteOption overwrite_option_; - - // Backup of the destination key. - RegistryKeyBackup backup_; - - // Set to true after the destination is cleared for the copy. - bool cleared_destination_; - - DISALLOW_COPY_AND_ASSIGN(CopyRegKeyWorkItem); -}; - -#endif // CHROME_INSTALLER_UTIL_COPY_REG_KEY_WORK_ITEM_H_ diff --git a/chrome/installer/util/copy_reg_key_work_item_unittest.cc b/chrome/installer/util/copy_reg_key_work_item_unittest.cc deleted file mode 100644 index 59399e8..0000000 --- a/chrome/installer/util/copy_reg_key_work_item_unittest.cc +++ /dev/null @@ -1,180 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <windows.h> -#include <shlwapi.h> // NOLINT - -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" -#include "base/win/registry.h" -#include "chrome/installer/util/copy_reg_key_work_item.h" -#include "chrome/installer/util/registry_test_data.h" -#include "chrome/installer/util/work_item.h" -#include "testing/gtest/include/gtest/gtest.h" - -using base::win::RegKey; - -class CopyRegKeyWorkItemTest : public testing::Test { - protected: - static void TearDownTestCase() { - logging::CloseLogFile(); - } - - virtual void SetUp() { - ASSERT_TRUE(test_data_.Initialize(HKEY_CURRENT_USER, L"SOFTWARE\\TmpTmp")); - destination_path_.assign(test_data_.base_path()).append(L"\\Destination"); - } - - RegistryTestData test_data_; - std::wstring destination_path_; -}; - -// Test that copying a key that doesn't exist succeeds, and that rollback does -// nothing. -TEST_F(CopyRegKeyWorkItemTest, TestNoKey) { - const std::wstring key_paths[] = { - std::wstring(test_data_.base_path() + L"\\NoKeyHere"), - std::wstring(test_data_.base_path() + L"\\NoKeyHere\\OrHere") - }; - RegKey key; - for (size_t i = 0; i < arraysize(key_paths); ++i) { - const std::wstring& key_path = key_paths[i]; - scoped_ptr<CopyRegKeyWorkItem> item( - WorkItem::CreateCopyRegKeyWorkItem(test_data_.root_key(), key_path, - destination_path_, - WorkItem::ALWAYS)); - EXPECT_TRUE(item->Do()); - EXPECT_NE(ERROR_SUCCESS, - key.Open(test_data_.root_key(), destination_path_.c_str(), - KEY_READ)); - item->Rollback(); - item.reset(); - EXPECT_NE(ERROR_SUCCESS, - key.Open(test_data_.root_key(), destination_path_.c_str(), - KEY_READ)); - } -} - -// Test that copying an empty key succeeds, and that rollback removes the copy. -TEST_F(CopyRegKeyWorkItemTest, TestEmptyKey) { - RegKey key; - scoped_ptr<CopyRegKeyWorkItem> item( - WorkItem::CreateCopyRegKeyWorkItem(test_data_.root_key(), - test_data_.empty_key_path(), - destination_path_, - WorkItem::ALWAYS)); - EXPECT_TRUE(item->Do()); - RegistryTestData::ExpectEmptyKey(test_data_.root_key(), - destination_path_.c_str()); - item->Rollback(); - item.reset(); - EXPECT_NE(ERROR_SUCCESS, - key.Open(test_data_.root_key(), destination_path_.c_str(), - KEY_READ)); -} - -// Test that copying a key with subkeys and values succeeds, and that rollback -// removes the copy. -TEST_F(CopyRegKeyWorkItemTest, TestNonEmptyKey) { - RegKey key; - scoped_ptr<CopyRegKeyWorkItem> item( - WorkItem::CreateCopyRegKeyWorkItem(test_data_.root_key(), - test_data_.non_empty_key_path(), - destination_path_, - WorkItem::ALWAYS)); - EXPECT_TRUE(item->Do()); - test_data_.ExpectMatchesNonEmptyKey(test_data_.root_key(), - destination_path_.c_str()); - item->Rollback(); - item.reset(); - EXPECT_NE(ERROR_SUCCESS, - key.Open(test_data_.root_key(), destination_path_.c_str(), - KEY_READ)); -} - -// Test that existing data isn't overwritten. -TEST_F(CopyRegKeyWorkItemTest, TestNoOverwrite) { - RegKey key; - // First copy the data into the dest. - EXPECT_EQ(ERROR_SUCCESS, - key.Create(test_data_.root_key(), destination_path_.c_str(), - KEY_WRITE)); - EXPECT_EQ(ERROR_SUCCESS, - SHCopyKey(test_data_.root_key(), - test_data_.non_empty_key_path().c_str(), key.Handle(), - 0)); - key.Close(); - - // Now copy the empty key into the dest, which should do nothing. - scoped_ptr<CopyRegKeyWorkItem> item( - WorkItem::CreateCopyRegKeyWorkItem(test_data_.root_key(), - test_data_.empty_key_path(), - destination_path_, - WorkItem::IF_NOT_PRESENT)); - EXPECT_TRUE(item->Do()); - - // Make sure it's all there. - test_data_.ExpectMatchesNonEmptyKey(test_data_.root_key(), - destination_path_.c_str()); - - // Rollback should do nothing. - item->Rollback(); - item.reset(); - - // Make sure it's still all there. - test_data_.ExpectMatchesNonEmptyKey(test_data_.root_key(), - destination_path_.c_str()); -} - -// Test that copying an empty key over a key with data succeeds, and that -// rollback restores the original data. -TEST_F(CopyRegKeyWorkItemTest, TestOverwriteAndRestore) { - RegKey key; - // First copy the data into the dest. - EXPECT_EQ(ERROR_SUCCESS, - key.Create(test_data_.root_key(), destination_path_.c_str(), - KEY_WRITE)); - EXPECT_EQ(ERROR_SUCCESS, - SHCopyKey(test_data_.root_key(), - test_data_.non_empty_key_path().c_str(), key.Handle(), - 0)); - key.Close(); - - // Now copy the empty key into the dest. - scoped_ptr<CopyRegKeyWorkItem> item( - WorkItem::CreateCopyRegKeyWorkItem(test_data_.root_key(), - test_data_.empty_key_path(), - destination_path_, - WorkItem::ALWAYS)); - EXPECT_TRUE(item->Do()); - - // Make sure the dest is now empty. - RegistryTestData::ExpectEmptyKey(test_data_.root_key(), - destination_path_.c_str()); - - // Restore the data. - item->Rollback(); - item.reset(); - - // Make sure it's all there. - test_data_.ExpectMatchesNonEmptyKey(test_data_.root_key(), - destination_path_.c_str()); -} - -// Test that Rollback does nothing when the item is configured to ignore -// failures. -TEST_F(CopyRegKeyWorkItemTest, TestIgnoreFailRollback) { - // Copy the empty key onto the non-empty key, ignoring failures. - scoped_ptr<CopyRegKeyWorkItem> item( - WorkItem::CreateCopyRegKeyWorkItem(test_data_.root_key(), - test_data_.empty_key_path(), - test_data_.non_empty_key_path(), - WorkItem::ALWAYS)); - item->set_ignore_failure(true); - EXPECT_TRUE(item->Do()); - item->Rollback(); - item.reset(); - RegistryTestData::ExpectEmptyKey(test_data_.root_key(), - test_data_.non_empty_key_path().c_str()); -} diff --git a/chrome/installer/util/create_reg_key_work_item.cc b/chrome/installer/util/create_reg_key_work_item.cc index 69043da..ce65b39 100644 --- a/chrome/installer/util/create_reg_key_work_item.cc +++ b/chrome/installer/util/create_reg_key_work_item.cc @@ -34,10 +34,15 @@ CreateRegKeyWorkItem::~CreateRegKeyWorkItem() { } CreateRegKeyWorkItem::CreateRegKeyWorkItem(HKEY predefined_root, - const std::wstring& path) + const std::wstring& path, + REGSAM wow64_access) : predefined_root_(predefined_root), path_(path), + wow64_access_(wow64_access), key_created_(false) { + DCHECK(wow64_access == 0 || + wow64_access == KEY_WOW64_32KEY || + wow64_access == KEY_WOW64_64KEY); } bool CreateRegKeyWorkItem::Do() { @@ -55,8 +60,10 @@ bool CreateRegKeyWorkItem::Do() { DWORD disposition; key_path.assign(key_list_[i - 1]); - if (key.CreateWithDisposition(predefined_root_, key_path.c_str(), - &disposition, KEY_READ) == ERROR_SUCCESS) { + if (key.CreateWithDisposition(predefined_root_, + key_path.c_str(), + &disposition, + KEY_READ | wow64_access_) == ERROR_SUCCESS) { if (disposition == REG_OPENED_EXISTING_KEY) { if (key_created_) { // This should not happen. Someone created a subkey under the key @@ -91,8 +98,8 @@ void CreateRegKeyWorkItem::Rollback() { std::vector<std::wstring>::iterator itr; for (itr = key_list_.begin(); itr != key_list_.end(); ++itr) { key_path.assign(*itr); - if (SHDeleteEmptyKey(predefined_root_, key_path.c_str()) == - ERROR_SUCCESS) { + RegKey key(predefined_root_, L"", KEY_WRITE | wow64_access_); + if (key.DeleteEmptyKey(key_path.c_str()) == ERROR_SUCCESS) { VLOG(1) << "rollback: delete " << key_path; } else { VLOG(1) << "rollback: can not delete " << key_path; diff --git a/chrome/installer/util/create_reg_key_work_item.h b/chrome/installer/util/create_reg_key_work_item.h index 448cb79..455cb4b 100644 --- a/chrome/installer/util/create_reg_key_work_item.h +++ b/chrome/installer/util/create_reg_key_work_item.h @@ -25,7 +25,9 @@ class CreateRegKeyWorkItem : public WorkItem { private: friend class WorkItem; - CreateRegKeyWorkItem(HKEY predefined_root, const std::wstring& path); + CreateRegKeyWorkItem(HKEY predefined_root, + const std::wstring& path, + REGSAM wow64_access); // Initialize key_list_ by adding all paths of keys from predefined_root_ // to path_. Returns true if key_list_ is non empty. @@ -38,6 +40,9 @@ class CreateRegKeyWorkItem : public WorkItem { // Path of the key to be created. std::wstring path_; + // Whether to force 32-bit or 64-bit view of the target key. + REGSAM wow64_access_; + // List of paths to all keys that need to be created from predefined_root_ // to path_. std::vector<std::wstring> key_list_; diff --git a/chrome/installer/util/create_reg_key_work_item_unittest.cc b/chrome/installer/util/create_reg_key_work_item_unittest.cc index acc3e18..6b4bc15 100644 --- a/chrome/installer/util/create_reg_key_work_item_unittest.cc +++ b/chrome/installer/util/create_reg_key_work_item_unittest.cc @@ -54,8 +54,8 @@ TEST_F(CreateRegKeyWorkItemTest, CreateKey) { key_to_create = key_to_create.AppendASCII("d"); scoped_ptr<CreateRegKeyWorkItem> work_item( - WorkItem::CreateCreateRegKeyWorkItem(HKEY_CURRENT_USER, - key_to_create.value())); + WorkItem::CreateCreateRegKeyWorkItem( + HKEY_CURRENT_USER, key_to_create.value(), WorkItem::kWow64Default)); EXPECT_TRUE(work_item->Do()); @@ -80,8 +80,8 @@ TEST_F(CreateRegKeyWorkItemTest, CreateExistingKey) { key.Create(HKEY_CURRENT_USER, key_to_create.value().c_str(), KEY_READ)); scoped_ptr<CreateRegKeyWorkItem> work_item( - WorkItem::CreateCreateRegKeyWorkItem(HKEY_CURRENT_USER, - key_to_create.value())); + WorkItem::CreateCreateRegKeyWorkItem( + HKEY_CURRENT_USER, key_to_create.value(), WorkItem::kWow64Default)); EXPECT_TRUE(work_item->Do()); @@ -108,8 +108,8 @@ TEST_F(CreateRegKeyWorkItemTest, CreateSharedKey) { key_to_create_3 = key_to_create_3.AppendASCII("ccc"); scoped_ptr<CreateRegKeyWorkItem> work_item( - WorkItem::CreateCreateRegKeyWorkItem(HKEY_CURRENT_USER, - key_to_create_3.value())); + WorkItem::CreateCreateRegKeyWorkItem( + HKEY_CURRENT_USER, key_to_create_3.value(), WorkItem::kWow64Default)); EXPECT_TRUE(work_item->Do()); @@ -147,8 +147,8 @@ TEST_F(CreateRegKeyWorkItemTest, RollbackWithMissingKey) { key_to_create_3 = key_to_create_3.AppendASCII("cccc"); scoped_ptr<CreateRegKeyWorkItem> work_item( - WorkItem::CreateCreateRegKeyWorkItem(HKEY_CURRENT_USER, - key_to_create_3.value())); + WorkItem::CreateCreateRegKeyWorkItem( + HKEY_CURRENT_USER, key_to_create_3.value(), WorkItem::kWow64Default)); EXPECT_TRUE(work_item->Do()); @@ -177,8 +177,8 @@ TEST_F(CreateRegKeyWorkItemTest, RollbackWithSetValue) { key_to_create = key_to_create.AppendASCII("aaaaa"); scoped_ptr<CreateRegKeyWorkItem> work_item( - WorkItem::CreateCreateRegKeyWorkItem(HKEY_CURRENT_USER, - key_to_create.value())); + WorkItem::CreateCreateRegKeyWorkItem( + HKEY_CURRENT_USER, key_to_create.value(), WorkItem::kWow64Default)); EXPECT_TRUE(work_item->Do()); diff --git a/chrome/installer/util/delete_reg_key_work_item.cc b/chrome/installer/util/delete_reg_key_work_item.cc index 462698f..9f48231 100644 --- a/chrome/installer/util/delete_reg_key_work_item.cc +++ b/chrome/installer/util/delete_reg_key_work_item.cc @@ -8,6 +8,7 @@ #include "base/logging.h" #include "base/win/registry.h" +#include "chrome/installer/util/install_util.h" using base::win::RegKey; @@ -15,12 +16,17 @@ DeleteRegKeyWorkItem::~DeleteRegKeyWorkItem() { } DeleteRegKeyWorkItem::DeleteRegKeyWorkItem(HKEY predefined_root, - const std::wstring& path) + const std::wstring& path, + REGSAM wow64_access) : predefined_root_(predefined_root), - path_(path) { + path_(path), + wow64_access_(wow64_access) { DCHECK(predefined_root); // It's a safe bet that we don't want to delete one of the root trees. DCHECK(!path.empty()); + DCHECK(wow64_access == 0 || + wow64_access == KEY_WOW64_32KEY || + wow64_access == KEY_WOW64_64KEY); } bool DeleteRegKeyWorkItem::Do() { @@ -31,17 +37,15 @@ bool DeleteRegKeyWorkItem::Do() { // Only try to make a backup if we're not configured to ignore failures. if (!ignore_failure_) { - if (!backup.Initialize(predefined_root_, path_.c_str())) { + if (!backup.Initialize(predefined_root_, path_.c_str(), wow64_access_)) { LOG(ERROR) << "Failed to backup destination for registry key copy."; return false; } } // Delete the key. - LONG result = SHDeleteKey(predefined_root_, path_.c_str()); - if (result != ERROR_SUCCESS && result != ERROR_FILE_NOT_FOUND) { - LOG(ERROR) << "Failed to delete key at " << path_ << ", result: " - << result; + if (!InstallUtil::DeleteRegistryKey( + predefined_root_, path_.c_str(), wow64_access_)) { return ignore_failure_; } @@ -57,14 +61,12 @@ void DeleteRegKeyWorkItem::Rollback() { // Delete anything in the key before restoring the backup in case someone else // put new data in the key after Do(). - LONG result = SHDeleteKey(predefined_root_, path_.c_str()); - if (result != ERROR_SUCCESS && result != ERROR_FILE_NOT_FOUND) { - LOG(ERROR) << "Failed to delete key at " << path_ << " in rollback, " - "result: " << result; - } + InstallUtil::DeleteRegistryKey(predefined_root_, + path_.c_str(), + wow64_access_); // Restore the old contents. The restoration takes on its default security // attributes; any custom attributes are lost. - if (!backup_.WriteTo(predefined_root_, path_.c_str())) + if (!backup_.WriteTo(predefined_root_, path_.c_str(), wow64_access_)) LOG(ERROR) << "Failed to restore key in rollback."; } diff --git a/chrome/installer/util/delete_reg_key_work_item.h b/chrome/installer/util/delete_reg_key_work_item.h index 4b92b94..51c19f2 100644 --- a/chrome/installer/util/delete_reg_key_work_item.h +++ b/chrome/installer/util/delete_reg_key_work_item.h @@ -30,7 +30,9 @@ class DeleteRegKeyWorkItem : public WorkItem { private: friend class WorkItem; - DeleteRegKeyWorkItem(HKEY predefined_root, const std::wstring& path); + DeleteRegKeyWorkItem(HKEY predefined_root, + const std::wstring& path, + REGSAM wow64_access); // Root key from which we delete the key. The root key can only be // one of the predefined keys on Windows. @@ -39,6 +41,9 @@ class DeleteRegKeyWorkItem : public WorkItem { // Path of the key to be deleted. std::wstring path_; + // Whether to force 32-bit or 64-bit view of the target key. + REGSAM wow64_access_; + // Backup of the deleted key. RegistryKeyBackup backup_; diff --git a/chrome/installer/util/delete_reg_key_work_item_unittest.cc b/chrome/installer/util/delete_reg_key_work_item_unittest.cc index 2127e3d..5e8c435 100644 --- a/chrome/installer/util/delete_reg_key_work_item_unittest.cc +++ b/chrome/installer/util/delete_reg_key_work_item_unittest.cc @@ -37,8 +37,8 @@ TEST_F(DeleteRegKeyWorkItemTest, TestNoKey) { RegKey key; for (size_t i = 0; i < arraysize(key_paths); ++i) { const std::wstring& key_path = key_paths[i]; - scoped_ptr<DeleteRegKeyWorkItem> item( - WorkItem::CreateDeleteRegKeyWorkItem(test_data_.root_key(), key_path)); + scoped_ptr<DeleteRegKeyWorkItem> item(WorkItem::CreateDeleteRegKeyWorkItem( + test_data_.root_key(), key_path, WorkItem::kWow64Default)); EXPECT_TRUE(item->Do()); EXPECT_NE(ERROR_SUCCESS, key.Open(test_data_.root_key(), key_path.c_str(), KEY_READ)); @@ -53,8 +53,8 @@ TEST_F(DeleteRegKeyWorkItemTest, TestNoKey) { TEST_F(DeleteRegKeyWorkItemTest, TestEmptyKey) { RegKey key; const std::wstring& key_path = test_data_.empty_key_path(); - scoped_ptr<DeleteRegKeyWorkItem> item( - WorkItem::CreateDeleteRegKeyWorkItem(test_data_.root_key(), key_path)); + scoped_ptr<DeleteRegKeyWorkItem> item(WorkItem::CreateDeleteRegKeyWorkItem( + test_data_.root_key(), key_path, WorkItem::kWow64Default)); EXPECT_TRUE(item->Do()); EXPECT_NE(ERROR_SUCCESS, key.Open(test_data_.root_key(), key_path.c_str(), KEY_READ)); @@ -69,8 +69,8 @@ TEST_F(DeleteRegKeyWorkItemTest, TestEmptyKey) { TEST_F(DeleteRegKeyWorkItemTest, TestNonEmptyKey) { RegKey key; const std::wstring& key_path = test_data_.non_empty_key_path(); - scoped_ptr<DeleteRegKeyWorkItem> item( - WorkItem::CreateDeleteRegKeyWorkItem(test_data_.root_key(), key_path)); + scoped_ptr<DeleteRegKeyWorkItem> item(WorkItem::CreateDeleteRegKeyWorkItem( + test_data_.root_key(), key_path, WorkItem::kWow64Default)); EXPECT_TRUE(item->Do()); EXPECT_NE(ERROR_SUCCESS, key.Open(test_data_.root_key(), key_path.c_str(), KEY_READ)); @@ -112,8 +112,8 @@ TEST_F(DeleteRegKeyWorkItemTest, DISABLED_TestUndeletableKey) { subkey2.Close(); subkey.Close(); key.Close(); - scoped_ptr<DeleteRegKeyWorkItem> item( - WorkItem::CreateDeleteRegKeyWorkItem(test_data_.root_key(), key_name)); + scoped_ptr<DeleteRegKeyWorkItem> item(WorkItem::CreateDeleteRegKeyWorkItem( + test_data_.root_key(), key_name, WorkItem::kWow64Default)); EXPECT_FALSE(item->Do()); EXPECT_EQ(ERROR_SUCCESS, key.Open(test_data_.root_key(), key_name.c_str(), KEY_QUERY_VALUE)); diff --git a/chrome/installer/util/delete_reg_value_work_item.cc b/chrome/installer/util/delete_reg_value_work_item.cc index 2d2da41..5c859cc 100644 --- a/chrome/installer/util/delete_reg_value_work_item.cc +++ b/chrome/installer/util/delete_reg_value_work_item.cc @@ -13,12 +13,17 @@ using base::win::RegKey; DeleteRegValueWorkItem::DeleteRegValueWorkItem(HKEY predefined_root, const std::wstring& key_path, + REGSAM wow64_access, const std::wstring& value_name) : predefined_root_(predefined_root), key_path_(key_path), value_name_(value_name), + wow64_access_(wow64_access), previous_type_(0), status_(DELETE_VALUE) { + DCHECK(wow64_access == 0 || + wow64_access == KEY_WOW64_32KEY || + wow64_access == KEY_WOW64_64KEY); } DeleteRegValueWorkItem::~DeleteRegValueWorkItem() { @@ -36,8 +41,9 @@ bool DeleteRegValueWorkItem::Do() { RegKey key; DWORD type = 0; DWORD size = 0; - LONG result = key.Open(predefined_root_, key_path_.c_str(), - KEY_READ | KEY_WRITE); + LONG result = key.Open(predefined_root_, + key_path_.c_str(), + KEY_READ | KEY_WRITE | wow64_access_); if (result == ERROR_SUCCESS) result = key.ReadValue(value_name_.c_str(), NULL, &size, &type); @@ -83,8 +89,9 @@ void DeleteRegValueWorkItem::Rollback() { // At this point only possible state is VALUE_DELETED. RegKey key; - LONG result = key.Open(predefined_root_, key_path_.c_str(), - KEY_READ | KEY_WRITE); + LONG result = key.Open(predefined_root_, + key_path_.c_str(), + KEY_READ | KEY_WRITE | wow64_access_); if (result == ERROR_SUCCESS) { // try to restore the previous value DWORD previous_size = static_cast<DWORD>(previous_value_.size()); diff --git a/chrome/installer/util/delete_reg_value_work_item.h b/chrome/installer/util/delete_reg_value_work_item.h index 4557356..582d3bd 100644 --- a/chrome/installer/util/delete_reg_value_work_item.h +++ b/chrome/installer/util/delete_reg_value_work_item.h @@ -38,7 +38,9 @@ class DeleteRegValueWorkItem : public WorkItem { VALUE_UNCHANGED }; - DeleteRegValueWorkItem(HKEY predefined_root, const std::wstring& key_path, + DeleteRegValueWorkItem(HKEY predefined_root, + const std::wstring& key_path, + REGSAM wow64_acccess, const std::wstring& value_name); // Root key of the target key under which the value is set. The root key can @@ -51,6 +53,9 @@ class DeleteRegValueWorkItem : public WorkItem { // Name of the value to be set. std::wstring value_name_; + // Whether to force 32-bit or 64-bit view of the target key. + REGSAM wow64_access_; + DeletionStatus status_; // Previous value. diff --git a/chrome/installer/util/delete_reg_value_work_item_unittest.cc b/chrome/installer/util/delete_reg_value_work_item_unittest.cc index 5a884b1..839fd72 100644 --- a/chrome/installer/util/delete_reg_value_work_item_unittest.cc +++ b/chrome/installer/util/delete_reg_value_work_item_unittest.cc @@ -62,14 +62,14 @@ TEST_F(DeleteRegValueWorkItemTest, DeleteExistingValue) { REG_SZ, NULL, 0)); scoped_ptr<DeleteRegValueWorkItem> work_item1( - WorkItem::CreateDeleteRegValueWorkItem(HKEY_CURRENT_USER, parent_key, - name_str)); + WorkItem::CreateDeleteRegValueWorkItem( + HKEY_CURRENT_USER, parent_key, WorkItem::kWow64Default, name_str)); scoped_ptr<DeleteRegValueWorkItem> work_item2( - WorkItem::CreateDeleteRegValueWorkItem(HKEY_CURRENT_USER, parent_key, - name_dword)); + WorkItem::CreateDeleteRegValueWorkItem( + HKEY_CURRENT_USER, parent_key, WorkItem::kWow64Default, name_dword)); scoped_ptr<DeleteRegValueWorkItem> work_item3( - WorkItem::CreateDeleteRegValueWorkItem(HKEY_CURRENT_USER, parent_key, - name_empty)); + WorkItem::CreateDeleteRegValueWorkItem( + HKEY_CURRENT_USER, parent_key, WorkItem::kWow64Default, name_empty)); EXPECT_TRUE(work_item1->Do()); EXPECT_TRUE(work_item2->Do()); @@ -113,11 +113,11 @@ TEST_F(DeleteRegValueWorkItemTest, DeleteNonExistentValue) { EXPECT_FALSE(key.HasValue(name_dword.c_str())); scoped_ptr<DeleteRegValueWorkItem> work_item1( - WorkItem::CreateDeleteRegValueWorkItem(HKEY_CURRENT_USER, parent_key, - name_str)); + WorkItem::CreateDeleteRegValueWorkItem( + HKEY_CURRENT_USER, parent_key, WorkItem::kWow64Default, name_str)); scoped_ptr<DeleteRegValueWorkItem> work_item2( - WorkItem::CreateDeleteRegValueWorkItem(HKEY_CURRENT_USER, parent_key, - name_dword)); + WorkItem::CreateDeleteRegValueWorkItem( + HKEY_CURRENT_USER, parent_key, WorkItem::kWow64Default, name_dword)); EXPECT_TRUE(work_item1->Do()); EXPECT_TRUE(work_item2->Do()); diff --git a/chrome/installer/util/google_update_settings_unittest.cc b/chrome/installer/util/google_update_settings_unittest.cc index 9eef4e5..71c0262 100644 --- a/chrome/installer/util/google_update_settings_unittest.cc +++ b/chrome/installer/util/google_update_settings_unittest.cc @@ -163,9 +163,14 @@ class GoogleUpdateSettingsTest : public testing::Test { bool CreateApKey(WorkItemList* work_item_list, const std::wstring& value) { HKEY reg_root = HKEY_CURRENT_USER; std::wstring reg_key = GetApKeyPath(); - work_item_list->AddCreateRegKeyWorkItem(reg_root, reg_key); - work_item_list->AddSetRegValueWorkItem(reg_root, reg_key, - google_update::kRegApField, value.c_str(), true); + work_item_list->AddCreateRegKeyWorkItem( + reg_root, reg_key, WorkItem::kWow64Default); + work_item_list->AddSetRegValueWorkItem(reg_root, + reg_key, + WorkItem::kWow64Default, + google_update::kRegApField, + value.c_str(), + true); if (!work_item_list->Do()) { work_item_list->Rollback(); return false; @@ -467,7 +472,8 @@ TEST_F(GoogleUpdateSettingsTest, UpdateInstallStatusTest) { RegKey key; if (key.Open(HKEY_CURRENT_USER, reg_key.c_str(), KEY_ALL_ACCESS) != ERROR_SUCCESS) { - work_item_list->AddCreateRegKeyWorkItem(reg_root, reg_key); + work_item_list->AddCreateRegKeyWorkItem( + reg_root, reg_key, WorkItem::kWow64Default); ASSERT_TRUE(work_item_list->Do()) << "Failed to create ClientState key."; } else if (key.DeleteValue(google_update::kRegApField) == ERROR_SUCCESS) { ap_key_deleted = true; diff --git a/chrome/installer/util/install_util.cc b/chrome/installer/util/install_util.cc index aaa5663..6cdd86a 100644 --- a/chrome/installer/util/install_util.cc +++ b/chrome/installer/util/install_util.cc @@ -286,21 +286,37 @@ void InstallUtil::AddInstallerResultItems( DCHECK(install_list); const HKEY root = system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; DWORD installer_result = (GetInstallReturnCode(status) == 0) ? 0 : 1; - install_list->AddCreateRegKeyWorkItem(root, state_key); - install_list->AddSetRegValueWorkItem(root, state_key, + install_list->AddCreateRegKeyWorkItem( + root, state_key, WorkItem::kWow64Default); + install_list->AddSetRegValueWorkItem(root, + state_key, + WorkItem::kWow64Default, installer::kInstallerResult, - installer_result, true); - install_list->AddSetRegValueWorkItem(root, state_key, + installer_result, + true); + install_list->AddSetRegValueWorkItem(root, + state_key, + WorkItem::kWow64Default, installer::kInstallerError, - static_cast<DWORD>(status), true); + static_cast<DWORD>(status), + true); if (string_resource_id != 0) { base::string16 msg = installer::GetLocalizedString(string_resource_id); - install_list->AddSetRegValueWorkItem(root, state_key, - installer::kInstallerResultUIString, msg, true); + install_list->AddSetRegValueWorkItem(root, + state_key, + WorkItem::kWow64Default, + installer::kInstallerResultUIString, + msg, + true); } if (launch_cmd != NULL && !launch_cmd->empty()) { - install_list->AddSetRegValueWorkItem(root, state_key, - installer::kInstallerSuccessLaunchCmdLine, *launch_cmd, true); + install_list->AddSetRegValueWorkItem( + root, + state_key, + WorkItem::kWow64Default, + installer::kInstallerSuccessLaunchCmdLine, + *launch_cmd, + true); } } @@ -421,10 +437,20 @@ bool InstallUtil::GetEULASentinelFilePath(base::FilePath* path) { // in case of failure. It returns true if deletion is successful (or the key did // not exist), otherwise false. bool InstallUtil::DeleteRegistryKey(HKEY root_key, - const base::string16& key_path) { + const base::string16& key_path, + REGSAM wow64_access) { VLOG(1) << "Deleting registry key " << key_path; - LONG result = ::SHDeleteKey(root_key, key_path.c_str()); - if (result != ERROR_SUCCESS && result != ERROR_FILE_NOT_FOUND) { + RegKey target_key; + LONG result = target_key.Open(root_key, key_path.c_str(), + KEY_READ | KEY_WRITE | wow64_access); + + if (result == ERROR_FILE_NOT_FOUND) + return true; + + if (result == ERROR_SUCCESS) + result = target_key.DeleteKey(L""); + + if (result != ERROR_SUCCESS) { LOG(ERROR) << "Failed to delete registry key: " << key_path << " error: " << result; return false; @@ -437,9 +463,11 @@ bool InstallUtil::DeleteRegistryKey(HKEY root_key, // not exist), otherwise false. bool InstallUtil::DeleteRegistryValue(HKEY reg_root, const base::string16& key_path, + REGSAM wow64_access, const base::string16& value_name) { RegKey key; - LONG result = key.Open(reg_root, key_path.c_str(), KEY_SET_VALUE); + LONG result = key.Open(reg_root, key_path.c_str(), + KEY_SET_VALUE | wow64_access); if (result == ERROR_SUCCESS) result = key.DeleteValue(value_name.c_str()); if (result != ERROR_SUCCESS && result != ERROR_FILE_NOT_FOUND) { @@ -455,6 +483,7 @@ InstallUtil::ConditionalDeleteResult InstallUtil::DeleteRegistryKeyIf( HKEY root_key, const base::string16& key_to_delete_path, const base::string16& key_to_test_path, + const REGSAM wow64_access, const wchar_t* value_name, const RegistryValuePredicate& predicate) { DCHECK(root_key); @@ -462,11 +491,13 @@ InstallUtil::ConditionalDeleteResult InstallUtil::DeleteRegistryKeyIf( RegKey key; base::string16 actual_value; if (key.Open(root_key, key_to_test_path.c_str(), - KEY_QUERY_VALUE) == ERROR_SUCCESS && + KEY_QUERY_VALUE | wow64_access) == ERROR_SUCCESS && key.ReadValue(value_name, &actual_value) == ERROR_SUCCESS && predicate.Evaluate(actual_value)) { key.Close(); - delete_result = DeleteRegistryKey(root_key, key_to_delete_path) + delete_result = DeleteRegistryKey(root_key, + key_to_delete_path, + wow64_access) ? DELETED : DELETE_FAILED; } return delete_result; @@ -476,6 +507,7 @@ InstallUtil::ConditionalDeleteResult InstallUtil::DeleteRegistryKeyIf( InstallUtil::ConditionalDeleteResult InstallUtil::DeleteRegistryValueIf( HKEY root_key, const wchar_t* key_path, + REGSAM wow64_access, const wchar_t* value_name, const RegistryValuePredicate& predicate) { DCHECK(root_key); @@ -484,7 +516,8 @@ InstallUtil::ConditionalDeleteResult InstallUtil::DeleteRegistryValueIf( RegKey key; base::string16 actual_value; if (key.Open(root_key, key_path, - KEY_QUERY_VALUE | KEY_SET_VALUE) == ERROR_SUCCESS && + KEY_QUERY_VALUE | KEY_SET_VALUE | wow64_access) + == ERROR_SUCCESS && key.ReadValue(value_name, &actual_value) == ERROR_SUCCESS && predicate.Evaluate(actual_value)) { LONG result = key.DeleteValue(value_name); diff --git a/chrome/installer/util/install_util.h b/chrome/installer/util/install_util.h index 1c3d0cb..383e582 100644 --- a/chrome/installer/util/install_util.h +++ b/chrome/installer/util/install_util.h @@ -113,11 +113,14 @@ class InstallUtil { static bool GetEULASentinelFilePath(base::FilePath* path); // Deletes the registry key at path key_path under the key given by root_key. - static bool DeleteRegistryKey(HKEY root_key, const base::string16& key_path); + static bool DeleteRegistryKey(HKEY root_key, + const base::string16& key_path, + REGSAM wow64_access); // Deletes the registry value named value_name at path key_path under the key // given by reg_root. static bool DeleteRegistryValue(HKEY reg_root, const base::string16& key_path, + REGSAM wow64_access, const base::string16& value_name); // An interface to a predicate function for use by DeleteRegistryKeyIf and @@ -143,6 +146,7 @@ class InstallUtil { HKEY root_key, const base::string16& key_to_delete_path, const base::string16& key_to_test_path, + REGSAM wow64_access, const wchar_t* value_name, const RegistryValuePredicate& predicate); @@ -152,6 +156,7 @@ class InstallUtil { static ConditionalDeleteResult DeleteRegistryValueIf( HKEY root_key, const wchar_t* key_path, + REGSAM wow64_access, const wchar_t* value_name, const RegistryValuePredicate& predicate); diff --git a/chrome/installer/util/install_util_unittest.cc b/chrome/installer/util/install_util_unittest.cc index f1234b8..42a83f7 100644 --- a/chrome/installer/util/install_util_unittest.cc +++ b/chrome/installer/util/install_util_unittest.cc @@ -13,6 +13,7 @@ #include "chrome/installer/util/google_update_constants.h" #include "chrome/installer/util/install_util.h" #include "chrome/installer/util/product_unittest.h" +#include "chrome/installer/util/work_item.h" #include "testing/gmock/include/gmock/gmock.h" using base::win::RegKey; @@ -194,8 +195,9 @@ TEST_F(InstallUtilTest, DeleteRegistryKeyIf) { KEY_QUERY_VALUE).Valid()); EXPECT_EQ(InstallUtil::NOT_FOUND, InstallUtil::DeleteRegistryKeyIf(root, parent_key_path, - child_key_path, value_name, - pred)); + child_key_path, + WorkItem::kWow64Default, + value_name, pred)); EXPECT_FALSE(RegKey(root, parent_key_path.c_str(), KEY_QUERY_VALUE).Valid()); } @@ -208,8 +210,9 @@ TEST_F(InstallUtilTest, DeleteRegistryKeyIf) { ASSERT_TRUE(RegKey(root, parent_key_path.c_str(), KEY_SET_VALUE).Valid()); EXPECT_EQ(InstallUtil::NOT_FOUND, InstallUtil::DeleteRegistryKeyIf(root, parent_key_path, - child_key_path, value_name, - pred)); + child_key_path, + WorkItem::kWow64Default, + value_name, pred)); EXPECT_TRUE(RegKey(root, parent_key_path.c_str(), KEY_QUERY_VALUE).Valid()); } @@ -222,8 +225,9 @@ TEST_F(InstallUtilTest, DeleteRegistryKeyIf) { ASSERT_TRUE(RegKey(root, child_key_path.c_str(), KEY_SET_VALUE).Valid()); EXPECT_EQ(InstallUtil::NOT_FOUND, InstallUtil::DeleteRegistryKeyIf(root, parent_key_path, - child_key_path, value_name, - pred)); + child_key_path, + WorkItem::kWow64Default, + value_name, pred)); EXPECT_TRUE(RegKey(root, parent_key_path.c_str(), KEY_QUERY_VALUE).Valid()); } @@ -238,8 +242,9 @@ TEST_F(InstallUtilTest, DeleteRegistryKeyIf) { KEY_SET_VALUE).WriteValue(value_name, L"foosball!")); EXPECT_EQ(InstallUtil::NOT_FOUND, InstallUtil::DeleteRegistryKeyIf(root, parent_key_path, - child_key_path, value_name, - pred)); + child_key_path, + WorkItem::kWow64Default, + value_name, pred)); EXPECT_TRUE(RegKey(root, parent_key_path.c_str(), KEY_QUERY_VALUE).Valid()); } @@ -254,8 +259,9 @@ TEST_F(InstallUtilTest, DeleteRegistryKeyIf) { KEY_SET_VALUE).WriteValue(value_name, value)); EXPECT_EQ(InstallUtil::DELETED, InstallUtil::DeleteRegistryKeyIf(root, parent_key_path, - child_key_path, value_name, - pred)); + child_key_path, + WorkItem::kWow64Default, + value_name, pred)); EXPECT_FALSE(RegKey(root, parent_key_path.c_str(), KEY_QUERY_VALUE).Valid()); } @@ -270,8 +276,9 @@ TEST_F(InstallUtilTest, DeleteRegistryKeyIf) { KEY_SET_VALUE).WriteValue(NULL, value)); EXPECT_EQ(InstallUtil::DELETED, InstallUtil::DeleteRegistryKeyIf(root, parent_key_path, - child_key_path, NULL, - pred)); + child_key_path, + WorkItem::kWow64Default, + NULL, pred)); EXPECT_FALSE(RegKey(root, parent_key_path.c_str(), KEY_QUERY_VALUE).Valid()); } @@ -295,6 +302,7 @@ TEST_F(InstallUtilTest, DeleteRegistryValueIf) { ASSERT_FALSE(RegKey(root, key_path.c_str(), KEY_QUERY_VALUE).Valid()); EXPECT_EQ(InstallUtil::NOT_FOUND, InstallUtil::DeleteRegistryValueIf(root, key_path.c_str(), + WorkItem::kWow64Default, value_name, pred)); EXPECT_FALSE(RegKey(root, key_path.c_str(), KEY_QUERY_VALUE).Valid()); } @@ -307,6 +315,7 @@ TEST_F(InstallUtilTest, DeleteRegistryValueIf) { ASSERT_TRUE(RegKey(root, key_path.c_str(), KEY_SET_VALUE).Valid()); EXPECT_EQ(InstallUtil::NOT_FOUND, InstallUtil::DeleteRegistryValueIf(root, key_path.c_str(), + WorkItem::kWow64Default, value_name, pred)); EXPECT_TRUE(RegKey(root, key_path.c_str(), KEY_QUERY_VALUE).Valid()); } @@ -321,6 +330,7 @@ TEST_F(InstallUtilTest, DeleteRegistryValueIf) { KEY_SET_VALUE).WriteValue(value_name, L"foosball!")); EXPECT_EQ(InstallUtil::NOT_FOUND, InstallUtil::DeleteRegistryValueIf(root, key_path.c_str(), + WorkItem::kWow64Default, value_name, pred)); EXPECT_TRUE(RegKey(root, key_path.c_str(), KEY_QUERY_VALUE).Valid()); EXPECT_TRUE(RegKey(root, key_path.c_str(), @@ -337,6 +347,7 @@ TEST_F(InstallUtilTest, DeleteRegistryValueIf) { KEY_SET_VALUE).WriteValue(value_name, value)); EXPECT_EQ(InstallUtil::DELETED, InstallUtil::DeleteRegistryValueIf(root, key_path.c_str(), + WorkItem::kWow64Default, value_name, pred)); EXPECT_TRUE(RegKey(root, key_path.c_str(), KEY_QUERY_VALUE).Valid()); EXPECT_FALSE(RegKey(root, key_path.c_str(), @@ -356,7 +367,8 @@ TEST_F(InstallUtilTest, DeleteRegistryValueIf) { RegKey(root, key_path.c_str(), KEY_SET_VALUE).WriteValue(L"", value)); EXPECT_EQ(InstallUtil::DELETED, - InstallUtil::DeleteRegistryValueIf(root, key_path.c_str(), L"", + InstallUtil::DeleteRegistryValueIf(root, key_path.c_str(), + WorkItem::kWow64Default, L"", pred)); EXPECT_TRUE(RegKey(root, key_path.c_str(), KEY_QUERY_VALUE).Valid()); EXPECT_FALSE(RegKey(root, key_path.c_str(), @@ -377,6 +389,7 @@ TEST_F(InstallUtilTest, DeleteRegistryValueIf) { KEY_SET_VALUE).WriteValue(L"", value)); EXPECT_EQ(InstallUtil::DELETED, InstallUtil::DeleteRegistryValueIf(root, key_path.c_str(), + WorkItem::kWow64Default, NULL, pred)); EXPECT_TRUE(RegKey(root, key_path.c_str(), KEY_QUERY_VALUE).Valid()); EXPECT_FALSE(RegKey(root, key_path.c_str(), diff --git a/chrome/installer/util/registry_key_backup.cc b/chrome/installer/util/registry_key_backup.cc index 9bd520a..7414248 100644 --- a/chrome/installer/util/registry_key_backup.cc +++ b/chrome/installer/util/registry_key_backup.cc @@ -271,14 +271,19 @@ RegistryKeyBackup::RegistryKeyBackup() { RegistryKeyBackup::~RegistryKeyBackup() { } -bool RegistryKeyBackup::Initialize(HKEY root, const wchar_t* key_path) { +bool RegistryKeyBackup::Initialize(HKEY root, + const wchar_t* key_path, + REGSAM wow64_access) { DCHECK(key_path); + DCHECK(wow64_access == 0 || + wow64_access == KEY_WOW64_32KEY || + wow64_access == KEY_WOW64_64KEY); RegKey key; scoped_ptr<KeyData> key_data; // Does the key exist? - LONG result = key.Open(root, key_path, kKeyReadNoNotify); + LONG result = key.Open(root, key_path, kKeyReadNoNotify | wow64_access); if (result == ERROR_SUCCESS) { key_data.reset(new KeyData()); if (!key_data->Initialize(key)) { @@ -295,14 +300,19 @@ bool RegistryKeyBackup::Initialize(HKEY root, const wchar_t* key_path) { return true; } -bool RegistryKeyBackup::WriteTo(HKEY root, const wchar_t* key_path) const { +bool RegistryKeyBackup::WriteTo(HKEY root, + const wchar_t* key_path, + REGSAM wow64_access) const { DCHECK(key_path); + DCHECK(wow64_access == 0 || + wow64_access == KEY_WOW64_32KEY || + wow64_access == KEY_WOW64_64KEY); bool success = false; if (key_data_.get() != NULL) { RegKey dest_key; - LONG result = dest_key.Create(root, key_path, KEY_WRITE); + LONG result = dest_key.Create(root, key_path, KEY_WRITE | wow64_access); if (result != ERROR_SUCCESS) { LOG(ERROR) << "Failed to create destination key at " << key_path << " to write backup, result: " << result; diff --git a/chrome/installer/util/registry_key_backup.h b/chrome/installer/util/registry_key_backup.h index ebee4af..68f29c33 100644 --- a/chrome/installer/util/registry_key_backup.h +++ b/chrome/installer/util/registry_key_backup.h @@ -26,12 +26,12 @@ class RegistryKeyBackup { // Recursively reads |key_path| into this instance. Backing up a non-existent // key is valid. Returns true if the backup was successful; false otherwise, // in which case the state of this instance is not modified. - bool Initialize(HKEY root, const wchar_t* key_path); + bool Initialize(HKEY root, const wchar_t* key_path, REGSAM wow64_acccess); // Writes the contents of this instance into |key|. The contents of // |key_path| are not modified If this instance is uninitialized or was // initialized from a non-existent key. - bool WriteTo(HKEY root, const wchar_t* key_path) const; + bool WriteTo(HKEY root, const wchar_t* key_path, REGSAM wow64_acccess) const; void swap(RegistryKeyBackup& other) { key_data_.swap(other.key_data_); diff --git a/chrome/installer/util/registry_key_backup_unittest.cc b/chrome/installer/util/registry_key_backup_unittest.cc index db33aa4..32bedb4 100644 --- a/chrome/installer/util/registry_key_backup_unittest.cc +++ b/chrome/installer/util/registry_key_backup_unittest.cc @@ -33,7 +33,9 @@ class RegistryKeyBackupTest : public testing::Test { TEST_F(RegistryKeyBackupTest, Uninitialized) { RegistryKeyBackup backup; - EXPECT_TRUE(backup.WriteTo(test_data_.root_key(), destination_path_.c_str())); + EXPECT_TRUE(backup.WriteTo(test_data_.root_key(), + destination_path_.c_str(), + WorkItem::kWow64Default)); EXPECT_FALSE(RegKey(test_data_.root_key(), destination_path_.c_str(), KEY_READ).Valid()); } @@ -45,8 +47,11 @@ TEST_F(RegistryKeyBackupTest, MissingKey) { RegistryKeyBackup backup; EXPECT_TRUE(backup.Initialize(test_data_.root_key(), - non_existent_key_path.c_str())); - EXPECT_TRUE(backup.WriteTo(test_data_.root_key(), destination_path_.c_str())); + non_existent_key_path.c_str(), + WorkItem::kWow64Default)); + EXPECT_TRUE(backup.WriteTo(test_data_.root_key(), + destination_path_.c_str(), + WorkItem::kWow64Default)); EXPECT_FALSE(RegKey(test_data_.root_key(), destination_path_.c_str(), KEY_READ).Valid()); } @@ -56,8 +61,11 @@ TEST_F(RegistryKeyBackupTest, ReadWrite) { RegistryKeyBackup backup; EXPECT_TRUE(backup.Initialize(test_data_.root_key(), - test_data_.non_empty_key_path().c_str())); - EXPECT_TRUE(backup.WriteTo(test_data_.root_key(), destination_path_.c_str())); + test_data_.non_empty_key_path().c_str(), + WorkItem::kWow64Default)); + EXPECT_TRUE(backup.WriteTo(test_data_.root_key(), + destination_path_.c_str(), + WorkItem::kWow64Default)); test_data_.ExpectMatchesNonEmptyKey(test_data_.root_key(), destination_path_.c_str()); } @@ -69,17 +77,20 @@ TEST_F(RegistryKeyBackupTest, Swap) { RegistryKeyBackup other_backup; EXPECT_TRUE(backup.Initialize(test_data_.root_key(), - test_data_.non_empty_key_path().c_str())); + test_data_.non_empty_key_path().c_str(), + WorkItem::kWow64Default)); backup.swap(other_backup); EXPECT_TRUE(other_backup.WriteTo(test_data_.root_key(), - destination_path_.c_str())); + destination_path_.c_str(), + WorkItem::kWow64Default)); // Now make sure the one we started with is truly empty. EXPECT_EQ(ERROR_SUCCESS, RegKey(test_data_.root_key(), L"", KEY_QUERY_VALUE) .DeleteKey(destination_path_.c_str())); EXPECT_TRUE(backup.WriteTo(test_data_.root_key(), - destination_path_.c_str())); + destination_path_.c_str(), + WorkItem::kWow64Default)); EXPECT_FALSE(RegKey(test_data_.root_key(), destination_path_.c_str(), KEY_READ).Valid()); } diff --git a/chrome/installer/util/set_reg_value_work_item.cc b/chrome/installer/util/set_reg_value_work_item.cc index b805a5d..596fe7c 100644 --- a/chrome/installer/util/set_reg_value_work_item.cc +++ b/chrome/installer/util/set_reg_value_work_item.cc @@ -14,6 +14,7 @@ SetRegValueWorkItem::~SetRegValueWorkItem() { SetRegValueWorkItem::SetRegValueWorkItem(HKEY predefined_root, const std::wstring& key_path, + REGSAM wow64_access, const std::wstring& value_name, const std::wstring& value_data, bool overwrite) @@ -21,15 +22,20 @@ SetRegValueWorkItem::SetRegValueWorkItem(HKEY predefined_root, key_path_(key_path), value_name_(value_name), overwrite_(overwrite), + wow64_access_(wow64_access), status_(SET_VALUE), type_(REG_SZ), previous_type_(0) { + DCHECK(wow64_access == 0 || + wow64_access == KEY_WOW64_32KEY || + wow64_access == KEY_WOW64_64KEY); const uint8* data = reinterpret_cast<const uint8*>(value_data.c_str()); value_.assign(data, data + (value_data.length() + 1) * sizeof(wchar_t)); } SetRegValueWorkItem::SetRegValueWorkItem(HKEY predefined_root, const std::wstring& key_path, + REGSAM wow64_access, const std::wstring& value_name, DWORD value_data, bool overwrite) @@ -37,15 +43,20 @@ SetRegValueWorkItem::SetRegValueWorkItem(HKEY predefined_root, key_path_(key_path), value_name_(value_name), overwrite_(overwrite), + wow64_access_(wow64_access), status_(SET_VALUE), type_(REG_DWORD), previous_type_(0) { + DCHECK(wow64_access == 0 || + wow64_access == KEY_WOW64_32KEY || + wow64_access == KEY_WOW64_64KEY); const uint8* data = reinterpret_cast<const uint8*>(&value_data); value_.assign(data, data + sizeof(value_data)); } SetRegValueWorkItem::SetRegValueWorkItem(HKEY predefined_root, const std::wstring& key_path, + REGSAM wow64_access, const std::wstring& value_name, int64 value_data, bool overwrite) @@ -53,9 +64,13 @@ SetRegValueWorkItem::SetRegValueWorkItem(HKEY predefined_root, key_path_(key_path), value_name_(value_name), overwrite_(overwrite), + wow64_access_(wow64_access), status_(SET_VALUE), type_(REG_QWORD), previous_type_(0) { + DCHECK(wow64_access == 0 || + wow64_access == KEY_WOW64_32KEY || + wow64_access == KEY_WOW64_64KEY); const uint8* data = reinterpret_cast<const uint8*>(&value_data); value_.assign(data, data + sizeof(value_data)); } @@ -71,8 +86,9 @@ bool SetRegValueWorkItem::Do() { } status_ = VALUE_UNCHANGED; - result = key.Open(predefined_root_, key_path_.c_str(), - KEY_READ | KEY_SET_VALUE); + result = key.Open(predefined_root_, + key_path_.c_str(), + KEY_READ | KEY_SET_VALUE | wow64_access_); if (result != ERROR_SUCCESS) { VLOG(1) << "can not open " << key_path_ << " error: " << result; return ignore_failure_; @@ -127,7 +143,8 @@ void SetRegValueWorkItem::Rollback() { } base::win::RegKey key; - LONG result = key.Open(predefined_root_, key_path_.c_str(), KEY_SET_VALUE); + LONG result = key.Open( + predefined_root_, key_path_.c_str(), KEY_SET_VALUE | wow64_access_); if (result != ERROR_SUCCESS) { VLOG(1) << "rollback: can not open " << key_path_ << " error: " << result; return; diff --git a/chrome/installer/util/set_reg_value_work_item.h b/chrome/installer/util/set_reg_value_work_item.h index f6bc573..16e6279 100644 --- a/chrome/installer/util/set_reg_value_work_item.h +++ b/chrome/installer/util/set_reg_value_work_item.h @@ -44,16 +44,23 @@ class SetRegValueWorkItem : public WorkItem { SetRegValueWorkItem(HKEY predefined_root, const std::wstring& key_path, + REGSAM wow64_access, const std::wstring& value_name, const std::wstring& value_data, bool overwrite); - SetRegValueWorkItem(HKEY predefined_root, const std::wstring& key_path, - const std::wstring& value_name, DWORD value_data, + SetRegValueWorkItem(HKEY predefined_root, + const std::wstring& key_path, + REGSAM wow64_access, + const std::wstring& value_name, + DWORD value_data, bool overwrite); - SetRegValueWorkItem(HKEY predefined_root, const std::wstring& key_path, - const std::wstring& value_name, int64 value_data, + SetRegValueWorkItem(HKEY predefined_root, + const std::wstring& key_path, + REGSAM wow64_access, + const std::wstring& value_name, + int64 value_data, bool overwrite); // Root key of the target key under which the value is set. The root key can @@ -69,6 +76,9 @@ class SetRegValueWorkItem : public WorkItem { // Whether to overwrite the existing value under the target key. bool overwrite_; + // Whether to force 32-bit or 64-bit view of the target key. + REGSAM wow64_access_; + // Type of data to store DWORD type_; std::vector<uint8> value_; diff --git a/chrome/installer/util/set_reg_value_work_item_unittest.cc b/chrome/installer/util/set_reg_value_work_item_unittest.cc index 27691bb..9f76111 100644 --- a/chrome/installer/util/set_reg_value_work_item_unittest.cc +++ b/chrome/installer/util/set_reg_value_work_item_unittest.cc @@ -58,13 +58,21 @@ TEST_F(SetRegValueWorkItemTest, WriteNewNonOverwrite) { std::wstring name_str(kNameStr); std::wstring data_str(kDataStr1); scoped_ptr<SetRegValueWorkItem> work_item1( - WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, parent_key, - name_str, data_str, false)); + WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, + parent_key, + WorkItem::kWow64Default, + name_str, + data_str, + false)); std::wstring name_dword(kNameDword); scoped_ptr<SetRegValueWorkItem> work_item2( - WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, parent_key, - name_dword, dword1, false)); + WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, + parent_key, + WorkItem::kWow64Default, + name_dword, + dword1, + false)); EXPECT_TRUE(work_item1->Do()); EXPECT_TRUE(work_item2->Do()); @@ -97,13 +105,21 @@ TEST_F(SetRegValueWorkItemTest, WriteNewOverwrite) { std::wstring name_str(kNameStr); std::wstring data_str(kDataStr1); scoped_ptr<SetRegValueWorkItem> work_item1( - WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, parent_key, - name_str, data_str, true)); + WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, + parent_key, + WorkItem::kWow64Default, + name_str, + data_str, + true)); std::wstring name_dword(kNameDword); scoped_ptr<SetRegValueWorkItem> work_item2( - WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, parent_key, - name_dword, dword1, true)); + WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, + parent_key, + WorkItem::kWow64Default, + name_dword, + dword1, + true)); EXPECT_TRUE(work_item1->Do()); EXPECT_TRUE(work_item2->Do()); @@ -142,8 +158,12 @@ TEST_F(SetRegValueWorkItemTest, WriteExistingNonOverwrite) { std::wstring data(kDataStr2); scoped_ptr<SetRegValueWorkItem> work_item( - WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, parent_key, - name, data, false)); + WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, + parent_key, + WorkItem::kWow64Default, + name, + data, + false)); EXPECT_TRUE(work_item->Do()); std::wstring read_out; @@ -160,7 +180,11 @@ TEST_F(SetRegValueWorkItemTest, WriteExistingNonOverwrite) { name.assign(kNameDword); ASSERT_EQ(ERROR_SUCCESS, key.WriteValue(name.c_str(), dword1)); work_item.reset(WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, - parent_key, name, dword2, false)); + parent_key, + WorkItem::kWow64Default, + name, + dword2, + false)); EXPECT_TRUE(work_item->Do()); DWORD read_dword; @@ -196,11 +220,19 @@ TEST_F(SetRegValueWorkItemTest, WriteExistingOverwrite) { std::wstring data(kDataStr2); scoped_ptr<SetRegValueWorkItem> work_item1( - WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, parent_key, - name, data, true)); + WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, + parent_key, + WorkItem::kWow64Default, + name, + data, + true)); scoped_ptr<SetRegValueWorkItem> work_item2( - WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, parent_key, - name_empty, data, true)); + WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, + parent_key, + WorkItem::kWow64Default, + name_empty, + data, + true)); EXPECT_TRUE(work_item1->Do()); EXPECT_TRUE(work_item2->Do()); @@ -231,8 +263,12 @@ TEST_F(SetRegValueWorkItemTest, WriteExistingOverwrite) { name.assign(kNameDword); ASSERT_EQ(ERROR_SUCCESS, key.WriteValue(name.c_str(), dword1)); scoped_ptr<SetRegValueWorkItem> work_item3( - WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, parent_key, name, - dword2, true)); + WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, + parent_key, + WorkItem::kWow64Default, + name, + dword2, + true)); EXPECT_TRUE(work_item3->Do()); DWORD read_dword; @@ -256,11 +292,19 @@ TEST_F(SetRegValueWorkItemTest, WriteNonExistingKey) { std::wstring name(L"name"); std::wstring data(kDataStr1); scoped_ptr<SetRegValueWorkItem> work_item( - WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, parent_key, - name, data, false)); + WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, + parent_key, + WorkItem::kWow64Default, + name, + data, + false)); EXPECT_FALSE(work_item->Do()); work_item.reset(WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, - parent_key, name, dword1, false)); + parent_key, + WorkItem::kWow64Default, + name, + dword1, + false)); EXPECT_FALSE(work_item->Do()); } diff --git a/chrome/installer/util/shell_util.cc b/chrome/installer/util/shell_util.cc index 9e705cc..43de6fa 100644 --- a/chrome/installer/util/shell_util.cc +++ b/chrome/installer/util/shell_util.cc @@ -48,6 +48,7 @@ #include "chrome/installer/util/master_preferences.h" #include "chrome/installer/util/master_preferences_constants.h" #include "chrome/installer/util/util_constants.h" +#include "chrome/installer/util/work_item.h" #include "installer_util_strings.h" // NOLINT @@ -531,11 +532,13 @@ class RegistryEntry { // Generate work_item tasks required to create current registry entry and // add them to the given work item list. void AddToWorkItemList(HKEY root, WorkItemList *items) const { - items->AddCreateRegKeyWorkItem(root, key_path_); + items->AddCreateRegKeyWorkItem(root, key_path_, WorkItem::kWow64Default); if (is_string_) { - items->AddSetRegValueWorkItem(root, key_path_, name_, value_, true); + items->AddSetRegValueWorkItem( + root, key_path_, WorkItem::kWow64Default, name_, value_, true); } else { - items->AddSetRegValueWorkItem(root, key_path_, name_, int_value_, true); + items->AddSetRegValueWorkItem( + root, key_path_, WorkItem::kWow64Default, name_, int_value_, true); } } @@ -1020,7 +1023,8 @@ void RemoveRunVerbOnWindows8(BrowserDistribution* dist, run_verb_key.append(ShellUtil::kRegShellPath); run_verb_key.push_back(base::FilePath::kSeparators[0]); run_verb_key.append(ShellUtil::kRegVerbRun); - InstallUtil::DeleteRegistryKey(root_key, run_verb_key); + InstallUtil::DeleteRegistryKey(root_key, run_verb_key, + WorkItem::kWow64Default); } } diff --git a/chrome/installer/util/work_item.cc b/chrome/installer/util/work_item.cc index cab09ba..3b2db8e 100644 --- a/chrome/installer/util/work_item.cc +++ b/chrome/installer/util/work_item.cc @@ -4,9 +4,10 @@ #include "chrome/installer/util/work_item.h" +#include <windows.h> + #include "chrome/installer/util/callback_work_item.h" #include "chrome/installer/util/conditional_work_item_list.h" -#include "chrome/installer/util/copy_reg_key_work_item.h" #include "chrome/installer/util/copy_tree_work_item.h" #include "chrome/installer/util/create_dir_work_item.h" #include "chrome/installer/util/create_reg_key_work_item.h" @@ -29,15 +30,6 @@ CallbackWorkItem* WorkItem::CreateCallbackWorkItem( return new CallbackWorkItem(callback); } -CopyRegKeyWorkItem* WorkItem::CreateCopyRegKeyWorkItem( - HKEY predefined_root, - const std::wstring& source_key_path, - const std::wstring& dest_key_path, - CopyOverWriteOption overwrite_option) { - return new CopyRegKeyWorkItem(predefined_root, source_key_path, - dest_key_path, overwrite_option); -} - CopyTreeWorkItem* WorkItem::CreateCopyTreeWorkItem( const base::FilePath& source_path, const base::FilePath& dest_path, @@ -54,20 +46,26 @@ CreateDirWorkItem* WorkItem::CreateCreateDirWorkItem( } CreateRegKeyWorkItem* WorkItem::CreateCreateRegKeyWorkItem( - HKEY predefined_root, const std::wstring& path) { - return new CreateRegKeyWorkItem(predefined_root, path); + HKEY predefined_root, + const std::wstring& path, + REGSAM wow64_access) { + return new CreateRegKeyWorkItem(predefined_root, path, wow64_access); } DeleteRegKeyWorkItem* WorkItem::CreateDeleteRegKeyWorkItem( - HKEY predefined_root, const std::wstring& path) { - return new DeleteRegKeyWorkItem(predefined_root, path); + HKEY predefined_root, + const std::wstring& path, + REGSAM wow64_access) { + return new DeleteRegKeyWorkItem(predefined_root, path, wow64_access); } DeleteRegValueWorkItem* WorkItem::CreateDeleteRegValueWorkItem( HKEY predefined_root, const std::wstring& key_path, + REGSAM wow64_access, const std::wstring& value_name) { - return new DeleteRegValueWorkItem(predefined_root, key_path, value_name); + return new DeleteRegValueWorkItem( + predefined_root, key_path, wow64_access, value_name); } DeleteTreeWorkItem* WorkItem::CreateDeleteTreeWorkItem( @@ -91,31 +89,46 @@ MoveTreeWorkItem* WorkItem::CreateMoveTreeWorkItem( SetRegValueWorkItem* WorkItem::CreateSetRegValueWorkItem( HKEY predefined_root, const std::wstring& key_path, + REGSAM wow64_access, const std::wstring& value_name, const std::wstring& value_data, bool overwrite) { - return new SetRegValueWorkItem(predefined_root, key_path, - value_name, value_data, overwrite); + return new SetRegValueWorkItem(predefined_root, + key_path, + wow64_access, + value_name, + value_data, + overwrite); } SetRegValueWorkItem* WorkItem::CreateSetRegValueWorkItem( HKEY predefined_root, const std::wstring& key_path, + REGSAM wow64_access, const std::wstring& value_name, DWORD value_data, bool overwrite) { - return new SetRegValueWorkItem(predefined_root, key_path, - value_name, value_data, overwrite); + return new SetRegValueWorkItem(predefined_root, + key_path, + wow64_access, + value_name, + value_data, + overwrite); } SetRegValueWorkItem* WorkItem::CreateSetRegValueWorkItem( HKEY predefined_root, const std::wstring& key_path, + REGSAM wow64_access, const std::wstring& value_name, int64 value_data, bool overwrite) { - return new SetRegValueWorkItem(predefined_root, key_path, - value_name, value_data, overwrite); + return new SetRegValueWorkItem(predefined_root, + key_path, + wow64_access, + value_name, + value_data, + overwrite); } SelfRegWorkItem* WorkItem::CreateSelfRegWorkItem(const std::wstring& dll_path, diff --git a/chrome/installer/util/work_item.h b/chrome/installer/util/work_item.h index 3011860..b19f5c2 100644 --- a/chrome/installer/util/work_item.h +++ b/chrome/installer/util/work_item.h @@ -18,7 +18,6 @@ #include "base/callback_forward.h" class CallbackWorkItem; -class CopyRegKeyWorkItem; class CopyTreeWorkItem; class CreateDirWorkItem; class CreateRegKeyWorkItem; @@ -38,6 +37,15 @@ class FilePath; // sequence of actions during install/update/uninstall. class WorkItem { public: + // All registry operations can be instructed to operate on a specific view + // of the registry by specifying a REGSAM value to the wow64_access parameter. + // The wow64_access parameter can be one of: + // KEY_WOW64_32KEY - Operate on the 32-bit view. + // KEY_WOW64_64KEY - Operate on the 64-bit view. + // kWow64Default - Operate on the default view (e.g. 32-bit on 32-bit + // systems, and 64-bit on 64-bit systems). + // See http://msdn.microsoft.com/en-us/library/windows/desktop/aa384129.aspx + static const REGSAM kWow64Default = 0; // Possible states enum CopyOverWriteOption { ALWAYS, // Always overwrite regardless of what existed before. @@ -67,13 +75,6 @@ class WorkItem { static CallbackWorkItem* CreateCallbackWorkItem( base::Callback<bool(const CallbackWorkItem&)> callback); - // Create a CopyRegKeyWorkItem that recursively copies a given registry key. - static CopyRegKeyWorkItem* CreateCopyRegKeyWorkItem( - HKEY predefined_root, - const std::wstring& source_key_path, - const std::wstring& dest_key_path, - CopyOverWriteOption overwrite_option); - // Create a CopyTreeWorkItem that recursively copies a file system hierarchy // from source path to destination path. // * If overwrite_option is ALWAYS, the created CopyTreeWorkItem always @@ -93,17 +94,22 @@ class WorkItem { // Create a CreateRegKeyWorkItem that creates a registry key at the given // path. static CreateRegKeyWorkItem* CreateCreateRegKeyWorkItem( - HKEY predefined_root, const std::wstring& path); + HKEY predefined_root, + const std::wstring& path, + REGSAM wow64_access); // Create a DeleteRegKeyWorkItem that deletes a registry key at the given // path. static DeleteRegKeyWorkItem* CreateDeleteRegKeyWorkItem( - HKEY predefined_root, const std::wstring& path); + HKEY predefined_root, + const std::wstring& path, + REGSAM wow64_access); // Create a DeleteRegValueWorkItem that deletes a registry value static DeleteRegValueWorkItem* CreateDeleteRegValueWorkItem( HKEY predefined_root, const std::wstring& key_path, + REGSAM wow64_access, const std::wstring& value_name); // Create a DeleteTreeWorkItem that recursively deletes a file system @@ -127,6 +133,7 @@ class WorkItem { static SetRegValueWorkItem* CreateSetRegValueWorkItem( HKEY predefined_root, const std::wstring& key_path, + REGSAM wow64_access, const std::wstring& value_name, const std::wstring& value_data, bool overwrite); @@ -136,16 +143,20 @@ class WorkItem { static SetRegValueWorkItem* CreateSetRegValueWorkItem( HKEY predefined_root, const std::wstring& key_path, + REGSAM wow64_access, const std::wstring& value_name, - DWORD value_data, bool overwrite); + DWORD value_data, + bool overwrite); // Create a SetRegValueWorkItem that sets a registry value with REG_QWORD type // at the key with specified path. static SetRegValueWorkItem* CreateSetRegValueWorkItem( HKEY predefined_root, const std::wstring& key_path, + REGSAM wow64_access, const std::wstring& value_name, - int64 value_data, bool overwrite); + int64 value_data, + bool overwrite); // Add a SelfRegWorkItem that registers or unregisters a DLL at the // specified path. diff --git a/chrome/installer/util/work_item_list.cc b/chrome/installer/util/work_item_list.cc index fd00773..5656ce1 100644 --- a/chrome/installer/util/work_item_list.cc +++ b/chrome/installer/util/work_item_list.cc @@ -7,7 +7,6 @@ #include "base/files/file_path.h" #include "base/logging.h" #include "chrome/installer/util/callback_work_item.h" -#include "chrome/installer/util/copy_reg_key_work_item.h" #include "chrome/installer/util/copy_tree_work_item.h" #include "chrome/installer/util/create_dir_work_item.h" #include "chrome/installer/util/create_reg_key_work_item.h" @@ -81,17 +80,6 @@ WorkItem* WorkItemList::AddCallbackWorkItem( return item; } -WorkItem* WorkItemList::AddCopyRegKeyWorkItem( - HKEY predefined_root, - const std::wstring& source_key_path, - const std::wstring& dest_key_path, - CopyOverWriteOption overwrite_option) { - WorkItem* item = WorkItem::CreateCopyRegKeyWorkItem( - predefined_root, source_key_path, dest_key_path, overwrite_option); - AddWorkItem(item); - return item; -} - WorkItem* WorkItemList::AddCopyTreeWorkItem( const std::wstring& source_path, const std::wstring& dest_path, @@ -115,15 +103,19 @@ WorkItem* WorkItemList::AddCreateDirWorkItem(const base::FilePath& path) { } WorkItem* WorkItemList::AddCreateRegKeyWorkItem(HKEY predefined_root, - const std::wstring& path) { - WorkItem* item = WorkItem::CreateCreateRegKeyWorkItem(predefined_root, path); + const std::wstring& path, + REGSAM wow64_access) { + WorkItem* item = + WorkItem::CreateCreateRegKeyWorkItem(predefined_root, path, wow64_access); AddWorkItem(item); return item; } WorkItem* WorkItemList::AddDeleteRegKeyWorkItem(HKEY predefined_root, - const std::wstring& path) { - WorkItem* item = WorkItem::CreateDeleteRegKeyWorkItem(predefined_root, path); + const std::wstring& path, + REGSAM wow64_access) { + WorkItem* item = + WorkItem::CreateDeleteRegKeyWorkItem(predefined_root, path, wow64_access); AddWorkItem(item); return item; } @@ -131,9 +123,10 @@ WorkItem* WorkItemList::AddDeleteRegKeyWorkItem(HKEY predefined_root, WorkItem* WorkItemList::AddDeleteRegValueWorkItem( HKEY predefined_root, const std::wstring& key_path, + REGSAM wow64_access, const std::wstring& value_name) { - WorkItem* item = WorkItem::CreateDeleteRegValueWorkItem(predefined_root, - key_path, value_name); + WorkItem* item = WorkItem::CreateDeleteRegValueWorkItem( + predefined_root, key_path, wow64_access, value_name); AddWorkItem(item); return item; } @@ -166,14 +159,15 @@ WorkItem* WorkItemList::AddMoveTreeWorkItem(const std::wstring& source_path, return item; } -WorkItem* WorkItemList::AddSetRegValueWorkItem( - HKEY predefined_root, - const std::wstring& key_path, - const std::wstring& value_name, - const std::wstring& value_data, - bool overwrite) { +WorkItem* WorkItemList::AddSetRegValueWorkItem(HKEY predefined_root, + const std::wstring& key_path, + REGSAM wow64_access, + const std::wstring& value_name, + const std::wstring& value_data, + bool overwrite) { WorkItem* item = WorkItem::CreateSetRegValueWorkItem(predefined_root, key_path, + wow64_access, value_name, value_data, overwrite); @@ -183,11 +177,13 @@ WorkItem* WorkItemList::AddSetRegValueWorkItem( WorkItem* WorkItemList::AddSetRegValueWorkItem(HKEY predefined_root, const std::wstring& key_path, + REGSAM wow64_access, const std::wstring& value_name, DWORD value_data, bool overwrite) { WorkItem* item = WorkItem::CreateSetRegValueWorkItem(predefined_root, key_path, + wow64_access, value_name, value_data, overwrite); @@ -197,12 +193,17 @@ WorkItem* WorkItemList::AddSetRegValueWorkItem(HKEY predefined_root, WorkItem* WorkItemList::AddSetRegValueWorkItem(HKEY predefined_root, const std::wstring& key_path, + REGSAM wow64_access, const std::wstring& value_name, int64 value_data, bool overwrite) { WorkItem* item = reinterpret_cast<WorkItem*>( - WorkItem::CreateSetRegValueWorkItem(predefined_root, key_path, value_name, - value_data, overwrite)); + WorkItem::CreateSetRegValueWorkItem(predefined_root, + key_path, + wow64_access, + value_name, + value_data, + overwrite)); AddWorkItem(item); return item; } diff --git a/chrome/installer/util/work_item_list.h b/chrome/installer/util/work_item_list.h index 1660c37..f00295a 100644 --- a/chrome/installer/util/work_item_list.h +++ b/chrome/installer/util/work_item_list.h @@ -43,12 +43,6 @@ class WorkItemList : public WorkItem { virtual WorkItem* AddCallbackWorkItem( base::Callback<bool(const CallbackWorkItem&)> callback); - // Add a CopyRegKeyWorkItem that recursively copies a given registry key. - virtual WorkItem* AddCopyRegKeyWorkItem(HKEY predefined_root, - const std::wstring& source_key_path, - const std::wstring& dest_key_path, - CopyOverWriteOption overwrite_option); - // Add a CopyTreeWorkItem to the list of work items. // See the NOTE in the documentation for the CopyTreeWorkItem class for // special considerations regarding |temp_dir|. @@ -65,17 +59,20 @@ class WorkItemList : public WorkItem { // Add a CreateRegKeyWorkItem that creates a registry key at the given // path. virtual WorkItem* AddCreateRegKeyWorkItem(HKEY predefined_root, - const std::wstring& path); + const std::wstring& path, + REGSAM wow64_access); // Add a DeleteRegKeyWorkItem that deletes a registry key from the given // path. virtual WorkItem* AddDeleteRegKeyWorkItem(HKEY predefined_root, - const std::wstring& path); + const std::wstring& path, + REGSAM wow64_access); // Add a DeleteRegValueWorkItem that deletes registry value of type REG_SZ // or REG_DWORD. virtual WorkItem* AddDeleteRegValueWorkItem(HKEY predefined_root, const std::wstring& key_path, + REGSAM wow64_access, const std::wstring& value_name); // Add a DeleteTreeWorkItem that recursively deletes a file system @@ -100,6 +97,7 @@ class WorkItemList : public WorkItem { // at the key with specified path. virtual WorkItem* AddSetRegValueWorkItem(HKEY predefined_root, const std::wstring& key_path, + REGSAM wow64_access, const std::wstring& value_name, const std::wstring& value_data, bool overwrite); @@ -108,6 +106,7 @@ class WorkItemList : public WorkItem { // at the key with specified path. virtual WorkItem* AddSetRegValueWorkItem(HKEY predefined_root, const std::wstring& key_path, + REGSAM wow64_access, const std::wstring& value_name, DWORD value_data, bool overwrite); @@ -116,6 +115,7 @@ class WorkItemList : public WorkItem { // at the key with specified path. virtual WorkItem* AddSetRegValueWorkItem(HKEY predefined_root, const std::wstring& key_path, + REGSAM wow64_access, const std::wstring& value_name, int64 value_data, bool overwrite); diff --git a/chrome/installer/util/work_item_list_unittest.cc b/chrome/installer/util/work_item_list_unittest.cc index 0944b07..0671994 100644 --- a/chrome/installer/util/work_item_list_unittest.cc +++ b/chrome/installer/util/work_item_list_unittest.cc @@ -69,15 +69,20 @@ TEST_F(WorkItemListTest, ExecutionSuccess) { key_to_create.push_back(base::FilePath::kSeparators[0]); key_to_create.append(L"ExecutionSuccess"); - work_item.reset(reinterpret_cast<WorkItem*>( - WorkItem::CreateCreateRegKeyWorkItem(HKEY_CURRENT_USER, key_to_create))); + work_item.reset( + reinterpret_cast<WorkItem*>(WorkItem::CreateCreateRegKeyWorkItem( + HKEY_CURRENT_USER, key_to_create, WorkItem::kWow64Default))); work_item_list->AddWorkItem(work_item.release()); std::wstring name(kName); std::wstring data(kDataStr); work_item.reset(reinterpret_cast<WorkItem*>( - WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, key_to_create, - name, data, false))); + WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, + key_to_create, + WorkItem::kWow64Default, + name, + data, + false))); work_item_list->AddWorkItem(work_item.release()); EXPECT_TRUE(work_item_list->Do()); @@ -121,8 +126,9 @@ TEST_F(WorkItemListTest, ExecutionFailAndRollback) { key_to_create.push_back(base::FilePath::kSeparators[0]); key_to_create.append(L"ExecutionFail"); - work_item.reset(reinterpret_cast<WorkItem*>( - WorkItem::CreateCreateRegKeyWorkItem(HKEY_CURRENT_USER, key_to_create))); + work_item.reset( + reinterpret_cast<WorkItem*>(WorkItem::CreateCreateRegKeyWorkItem( + HKEY_CURRENT_USER, key_to_create, WorkItem::kWow64Default))); work_item_list->AddWorkItem(work_item.release()); std::wstring not_created_key(kTestRoot); @@ -131,14 +137,18 @@ TEST_F(WorkItemListTest, ExecutionFailAndRollback) { std::wstring name(kName); std::wstring data(kDataStr); work_item.reset(reinterpret_cast<WorkItem*>( - WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, not_created_key, - name, data, false))); + WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, + not_created_key, + WorkItem::kWow64Default, + name, + data, + false))); work_item_list->AddWorkItem(work_item.release()); // This one will not be executed because we will fail early. - work_item.reset(reinterpret_cast<WorkItem*>( - WorkItem::CreateCreateRegKeyWorkItem(HKEY_CURRENT_USER, - not_created_key))); + work_item.reset( + reinterpret_cast<WorkItem*>(WorkItem::CreateCreateRegKeyWorkItem( + HKEY_CURRENT_USER, not_created_key, WorkItem::kWow64Default))); work_item_list->AddWorkItem(work_item.release()); EXPECT_FALSE(work_item_list->Do()); @@ -182,15 +192,20 @@ TEST_F(WorkItemListTest, ConditionalExecutionSuccess) { std::wstring key_to_create(kTestRoot); key_to_create.push_back(base::FilePath::kSeparators[0]); key_to_create.append(L"ExecutionSuccess"); - work_item.reset(reinterpret_cast<WorkItem*>( - WorkItem::CreateCreateRegKeyWorkItem(HKEY_CURRENT_USER, key_to_create))); + work_item.reset( + reinterpret_cast<WorkItem*>(WorkItem::CreateCreateRegKeyWorkItem( + HKEY_CURRENT_USER, key_to_create, WorkItem::kWow64Default))); conditional_work_item_list->AddWorkItem(work_item.release()); std::wstring name(kName); std::wstring data(kDataStr); work_item.reset(reinterpret_cast<WorkItem*>( - WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, key_to_create, - name, data, false))); + WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, + key_to_create, + WorkItem::kWow64Default, + name, + data, + false))); conditional_work_item_list->AddWorkItem(work_item.release()); work_item_list->AddWorkItem(conditional_work_item_list.release()); @@ -238,15 +253,20 @@ TEST_F(WorkItemListTest, ConditionalExecutionConditionFailure) { std::wstring key_to_create(kTestRoot); key_to_create.push_back(base::FilePath::kSeparators[0]); key_to_create.append(L"ExecutionSuccess"); - work_item.reset(reinterpret_cast<WorkItem*>( - WorkItem::CreateCreateRegKeyWorkItem(HKEY_CURRENT_USER, key_to_create))); + work_item.reset( + reinterpret_cast<WorkItem*>(WorkItem::CreateCreateRegKeyWorkItem( + HKEY_CURRENT_USER, key_to_create, WorkItem::kWow64Default))); conditional_work_item_list->AddWorkItem(work_item.release()); std::wstring name(kName); std::wstring data(kDataStr); work_item.reset(reinterpret_cast<WorkItem*>( - WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, key_to_create, - name, data, false))); + WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, + key_to_create, + WorkItem::kWow64Default, + name, + data, + false))); conditional_work_item_list->AddWorkItem(work_item.release()); work_item_list->AddWorkItem(conditional_work_item_list.release()); diff --git a/chrome/test/mini_installer_test/installer_test_util.cc b/chrome/test/mini_installer_test/installer_test_util.cc index 76d1f97..f8cbb39 100644 --- a/chrome/test/mini_installer_test/installer_test_util.cc +++ b/chrome/test/mini_installer_test/installer_test_util.cc @@ -65,14 +65,15 @@ bool DeleteInstallDirectory(bool system_level, } bool DeleteRegistryKey(bool system_level, - InstallationValidator::InstallationType type) { + InstallationValidator::InstallationType type, + REGSAM wow64_access) { BrowserDistribution* dist = BrowserDistribution::GetSpecificDistribution( ToBrowserDistributionType(type)); base::FilePath::StringType key(google_update::kRegPathClients); key.push_back(base::FilePath::kSeparators[0]); key.append(dist->GetAppGuid()); HKEY root = system_level ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; - return InstallUtil::DeleteRegistryKey(root, key); + return InstallUtil::DeleteRegistryKey(root, key, wow64_access); } bool GetChromeInstallDirectory(bool system_level, base::FilePath* path) { @@ -296,4 +297,4 @@ bool RunAndWaitForCommandToFinish(CommandLine command) { return true; } -} // namespace +} // namespace installer_test diff --git a/chrome/test/mini_installer_test/installer_test_util.h b/chrome/test/mini_installer_test/installer_test_util.h index c55106b..5aeb2d3 100644 --- a/chrome/test/mini_installer_test/installer_test_util.h +++ b/chrome/test/mini_installer_test/installer_test_util.h @@ -33,7 +33,8 @@ bool DeleteInstallDirectory( // Returns true if successful, otherwise false. bool DeleteRegistryKey( bool system_level, - installer::InstallationValidator::InstallationType type); + installer::InstallationValidator::InstallationType type, + REGSAM wow64_access); // Locates the Chrome installation directory based on the // provided |system_level|. Returns true if successful, otherwise false. @@ -81,7 +82,7 @@ bool ValidateInstall( // Returns true if successful, otherwise false. bool RunAndWaitForCommandToFinish(base::CommandLine command); -} // namespace +} // namespace installer_test #endif // CHROME_TEST_MINI_INSTALLER_TEST_INSTALLER_TEST_UTIL_H_ diff --git a/chrome/test/mini_installer_test/test.cc b/chrome/test/mini_installer_test/test.cc index 43b5428..a479cb6 100644 --- a/chrome/test/mini_installer_test/test.cc +++ b/chrome/test/mini_installer_test/test.cc @@ -241,7 +241,7 @@ TEST_F(MiniInstallTest, RepairRegistryOnFullUser) { content::RESULT_CODE_HUNG, NULL); ASSERT_TRUE(installer_test::DeleteRegistryKey( false, // system level - InstallationValidator::CHROME_SINGLE)); + InstallationValidator::CHROME_SINGLE, 0)); // no WOW64 ASSERT_TRUE( installer_test::Install(full_installer_, SwitchBuilder().AddChrome())); ASSERT_TRUE(installer_test::ValidateInstall(false, @@ -255,7 +255,7 @@ TEST_F(MiniInstallTest, RepairRegistryOnFullSys) { InstallationValidator::CHROME_SINGLE, provider_->GetCurrentBuild())); ASSERT_TRUE(installer_test::DeleteRegistryKey( true, // system level - InstallationValidator::CHROME_SINGLE)); + InstallationValidator::CHROME_SINGLE, 0)); // no WOW64 ASSERT_TRUE(installer_test::Install(full_installer_, SwitchBuilder().AddChrome().AddSystemInstall())); ASSERT_TRUE(installer_test::ValidateInstall(true, |