Index: chrome/installer/util/install_util.cc |
diff --git a/chrome/installer/util/install_util.cc b/chrome/installer/util/install_util.cc |
index f7dccea263c8bc2f0c43b040dd191b70324d294e..32a660e1727a5086a777c5dd32ff33a23190b191 100644 |
--- a/chrome/installer/util/install_util.cc |
+++ b/chrome/installer/util/install_util.cc |
@@ -19,6 +19,8 @@ |
#include "base/memory/scoped_ptr.h" |
#include "base/path_service.h" |
#include "base/process/launch.h" |
+#include "base/strings/string_number_conversions.h" |
+#include "base/strings/string_split.h" |
#include "base/strings/string_util.h" |
#include "base/strings/utf_string_conversions.h" |
#include "base/sys_info.h" |
@@ -26,14 +28,17 @@ |
#include "base/version.h" |
#include "base/win/metro.h" |
#include "base/win/registry.h" |
+#include "base/win/win_util.h" |
#include "base/win/windows_version.h" |
#include "chrome/common/chrome_constants.h" |
#include "chrome/common/chrome_paths.h" |
+#include "chrome/installer/util/app_registration_data.h" |
#include "chrome/installer/util/browser_distribution.h" |
#include "chrome/installer/util/google_update_constants.h" |
#include "chrome/installer/util/helper.h" |
#include "chrome/installer/util/installation_state.h" |
#include "chrome/installer/util/l10n_string_util.h" |
+#include "chrome/installer/util/update_active_setup_version_work_item.h" |
#include "chrome/installer/util/util_constants.h" |
#include "chrome/installer/util/work_item_list.h" |
@@ -162,6 +167,90 @@ void InstallUtil::TriggerActiveSetupCommand() { |
PLOG(ERROR) << cmd.GetCommandLineString(); |
} |
+bool InstallUtil::UpdateLastOSUpgradeHandledByActiveSetup( |
gab
2015/07/09 20:54:44
@grt: This duplicates a bit of logic from a few pl
|
+ BrowserDistribution* dist) { |
+ static const wchar_t kLastOSUpgradeHandledRegName[] = L"LastOSUpgradeHandled"; |
+ |
+ // FIRST: Find out the value of the last OS upgrade handled, defaults to 0 if |
+ // none was ever handled. |
+ DWORD last_os_upgrade_handled = 0; |
+ |
+ base::string16 last_upgrade_handled_key_path = |
+ dist->GetAppRegistrationData().GetStateMediumKey(); |
+ last_upgrade_handled_key_path.push_back(L'\\'); |
+ last_upgrade_handled_key_path.append(kLastOSUpgradeHandledRegName); |
+ |
+ base::string16 user_specific_value; |
+ // This should never fail. If it does, the beacon will be written in the key's |
+ // default value, which is okay since the majority case is likely a machine |
+ // with a single user. |
+ if (!base::win::GetUserSidString(&user_specific_value)) |
+ NOTREACHED(); |
+ |
+ base::win::RegKey last_upgrade_key; |
+ if (last_upgrade_key.Open( |
+ HKEY_LOCAL_MACHINE, last_upgrade_handled_key_path.c_str(), |
+ KEY_WOW64_32KEY | KEY_QUERY_VALUE) == ERROR_SUCCESS) { |
+ last_upgrade_key.ReadValueDW(user_specific_value.c_str(), |
+ &last_os_upgrade_handled); |
+ } |
+ |
+ // SECOND: Find out the value of the latest OS upgrade registered in the |
+ // Active Setup version (bumped on every major OS upgrade), defaults to 0 if |
+ // no OS upgrade was ever encountered by this install. |
+ DWORD latest_os_upgrade = 0; |
grt (UTC plus 2)
2015/07/10 18:15:24
does this method always return false without updat
gab
2015/07/13 18:19:01
Tweaked the order and made sure it only ever retur
|
+ |
+ const base::string16 active_setup_key_path(GetActiveSetupPath(dist)); |
+ |
+ base::win::RegKey active_setup_key; |
+ if (active_setup_key.Open(HKEY_LOCAL_MACHINE, active_setup_key_path.c_str(), |
+ KEY_QUERY_VALUE) == ERROR_SUCCESS) { |
+ base::string16 existing_version; |
+ if (active_setup_key.ReadValue(L"Version", |
+ &existing_version) == ERROR_SUCCESS) { |
+ std::vector<base::string16> version_components = |
+ base::SplitString(existing_version, L",", base::TRIM_WHITESPACE, |
+ base::SPLIT_WANT_NONEMPTY); |
+ unsigned latest_os_upgrade_uint = 0; |
+ if (version_components.size() == 4U && |
+ base::StringToUint( |
+ version_components[UpdateActiveSetupVersionWorkItem:: |
+ VersionComponent::OS_UPGRADES], |
+ &latest_os_upgrade_uint)) { |
+ latest_os_upgrade = static_cast<DWORD>(latest_os_upgrade_uint); |
+ } else { |
+ LOG(ERROR) << "Failed to parse OS_UPGRADES component of " |
+ << existing_version; |
+ } |
+ } |
+ } |
+ |
+ // THIRD: Figure out whether the latest OS upgrade has been handled already. |
+ |
+ if (last_os_upgrade_handled >= latest_os_upgrade) { |
+ LOG_IF(ERROR, last_os_upgrade_handled > latest_os_upgrade) |
+ << "Last OS upgrade handled is somehow ahead of the latest OS upgrade?"; |
+ VLOG_IF(1, last_os_upgrade_handled == latest_os_upgrade) |
+ << "Latest OS upgrade already handled."; |
+ return false; |
+ } |
+ |
+ // At this point |last_os_upgrade_handled < latest_os_upgrade| so, |
+ // FOURTH: store the fact that the latest OS upgrade has been handled and |
+ // return true for the caller to act accordingly. |
+ |
+ if (last_upgrade_key.Create( |
+ HKEY_LOCAL_MACHINE, last_upgrade_handled_key_path.c_str(), |
+ KEY_WOW64_32KEY | KEY_SET_VALUE) != ERROR_SUCCESS || |
+ last_upgrade_key.WriteValue(user_specific_value.c_str(), |
+ latest_os_upgrade) != ERROR_SUCCESS) { |
+ LOG(ERROR) << "Failed to save latest_os_upgrade value (" |
+ << latest_os_upgrade << ") to " << last_upgrade_handled_key_path; |
+ } |
+ |
+ return true; |
+} |
+ |
bool InstallUtil::ExecuteExeAsAdmin(const base::CommandLine& cmd, |
DWORD* exit_code) { |
base::FilePath::StringType program(cmd.GetProgram().value()); |