1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "chrome/installer/util/google_update_settings.h" 6 7 #include <algorithm> 8 9 #include "base/command_line.h" 10 #include "base/files/file_path.h" 11 #include "base/logging.h" 12 #include "base/metrics/histogram.h" 13 #include "base/path_service.h" 14 #include "base/strings/string_number_conversions.h" 15 #include "base/strings/string_util.h" 16 #include "base/strings/utf_string_conversions.h" 17 #include "base/threading/thread_restrictions.h" 18 #include "base/time/time.h" 19 #include "base/win/registry.h" 20 #include "base/win/win_util.h" 21 #include "chrome/common/chrome_switches.h" 22 #include "chrome/installer/util/app_registration_data.h" 23 #include "chrome/installer/util/browser_distribution.h" 24 #include "chrome/installer/util/channel_info.h" 25 #include "chrome/installer/util/google_update_constants.h" 26 #include "chrome/installer/util/google_update_experiment_util.h" 27 #include "chrome/installer/util/install_util.h" 28 #include "chrome/installer/util/installation_state.h" 29 #include "chrome/installer/util/product.h" 30 31 using base::win::RegKey; 32 using installer::InstallationState; 33 34 const wchar_t GoogleUpdateSettings::kPoliciesKey[] = 35 L"SOFTWARE\\Policies\\Google\\Update"; 36 const wchar_t GoogleUpdateSettings::kUpdatePolicyValue[] = L"UpdateDefault"; 37 const wchar_t GoogleUpdateSettings::kUpdateOverrideValuePrefix[] = L"Update"; 38 const wchar_t GoogleUpdateSettings::kCheckPeriodOverrideMinutes[] = 39 L"AutoUpdateCheckPeriodMinutes"; 40 41 // Don't allow update periods longer than six weeks. 42 const int GoogleUpdateSettings::kCheckPeriodOverrideMinutesMax = 43 60 * 24 * 7 * 6; 44 45 const GoogleUpdateSettings::UpdatePolicy 46 GoogleUpdateSettings::kDefaultUpdatePolicy = 47 #if defined(GOOGLE_CHROME_BUILD) 48 GoogleUpdateSettings::AUTOMATIC_UPDATES; 49 #else 50 GoogleUpdateSettings::UPDATES_DISABLED; 51 #endif 52 53 namespace { 54 55 bool ReadGoogleUpdateStrKey(const wchar_t* const name, base::string16* value) { 56 BrowserDistribution* dist = BrowserDistribution::GetDistribution(); 57 base::string16 reg_path = dist->GetStateKey(); 58 RegKey key(HKEY_CURRENT_USER, reg_path.c_str(), KEY_READ | KEY_WOW64_32KEY); 59 if (key.ReadValue(name, value) != ERROR_SUCCESS) { 60 RegKey hklm_key( 61 HKEY_LOCAL_MACHINE, reg_path.c_str(), KEY_READ | KEY_WOW64_32KEY); 62 return (hklm_key.ReadValue(name, value) == ERROR_SUCCESS); 63 } 64 return true; 65 } 66 67 // Updates a registry key |name| to be |value| for the given |app_reg_data|. 68 // If this is a |system_install|, then update the value under HKLM (istead of 69 // HKCU for user-installs) using a group of keys (one for each OS user) and also 70 // include the method to |aggregate| these values when reporting. 71 bool WriteGoogleUpdateStrKeyInternal(const AppRegistrationData& app_reg_data, 72 bool system_install, 73 const wchar_t* const name, 74 const base::string16& value, 75 const wchar_t* const aggregate) { 76 const REGSAM kAccess = KEY_SET_VALUE | KEY_WOW64_32KEY; 77 if (system_install) { 78 DCHECK(aggregate); 79 // Machine installs require each OS user to write a unique key under a 80 // named key in HKLM as well as an "aggregation" function that describes 81 // how the values of multiple users are to be combined. 82 base::string16 uniquename; 83 if (!base::win::GetUserSidString(&uniquename)) { 84 NOTREACHED(); 85 return false; 86 } 87 88 base::string16 reg_path(app_reg_data.GetStateMediumKey()); 89 reg_path.append(L"\\"); 90 reg_path.append(name); 91 RegKey key(HKEY_LOCAL_MACHINE, reg_path.c_str(), kAccess); 92 key.WriteValue(google_update::kRegAggregateMethod, aggregate); 93 return (key.WriteValue(uniquename.c_str(), value.c_str()) == ERROR_SUCCESS); 94 } else { 95 // User installs are easy: just write the values to HKCU tree. 96 RegKey key(HKEY_CURRENT_USER, app_reg_data.GetStateKey().c_str(), kAccess); 97 return (key.WriteValue(name, value.c_str()) == ERROR_SUCCESS); 98 } 99 } 100 101 bool WriteGoogleUpdateStrKey(const wchar_t* const name, 102 const base::string16& value) { 103 BrowserDistribution* dist = BrowserDistribution::GetDistribution(); 104 return WriteGoogleUpdateStrKeyInternal( 105 dist->GetAppRegistrationData(), false, name, value, NULL); 106 } 107 108 bool ClearGoogleUpdateStrKey(const wchar_t* const name) { 109 BrowserDistribution* dist = BrowserDistribution::GetDistribution(); 110 base::string16 reg_path = dist->GetStateKey(); 111 RegKey key(HKEY_CURRENT_USER, 112 reg_path.c_str(), 113 KEY_READ | KEY_WRITE | KEY_WOW64_32KEY); 114 base::string16 value; 115 if (key.ReadValue(name, &value) != ERROR_SUCCESS) 116 return false; 117 return (key.WriteValue(name, L"") == ERROR_SUCCESS); 118 } 119 120 bool RemoveGoogleUpdateStrKey(const wchar_t* const name) { 121 BrowserDistribution* dist = BrowserDistribution::GetDistribution(); 122 base::string16 reg_path = dist->GetStateKey(); 123 RegKey key(HKEY_CURRENT_USER, 124 reg_path.c_str(), 125 KEY_READ | KEY_WRITE | KEY_WOW64_32KEY); 126 if (!key.HasValue(name)) 127 return true; 128 return (key.DeleteValue(name) == ERROR_SUCCESS); 129 } 130 131 bool GetChromeChannelInternal(bool system_install, 132 bool add_multi_modifier, 133 base::string16* channel) { 134 BrowserDistribution* dist = BrowserDistribution::GetDistribution(); 135 136 // Shortcut in case this distribution knows what channel it is (canary). 137 if (dist->GetChromeChannel(channel)) 138 return true; 139 140 // Determine whether or not chrome is multi-install. If so, updates are 141 // delivered under the binaries' app guid, so that's where the relevant 142 // channel is found. 143 installer::ProductState state; 144 installer::ChannelInfo channel_info; 145 ignore_result(state.Initialize(system_install, dist)); 146 if (!state.is_multi_install()) { 147 // Use the channel info that was just read for this single-install chrome. 148 channel_info = state.channel(); 149 } else { 150 // Read the channel info from the binaries' state key. 151 HKEY root_key = system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; 152 dist = BrowserDistribution::GetSpecificDistribution( 153 BrowserDistribution::CHROME_BINARIES); 154 RegKey key(root_key, dist->GetStateKey().c_str(), 155 KEY_READ | KEY_WOW64_32KEY); 156 157 if (!channel_info.Initialize(key)) { 158 channel->assign(installer::kChromeChannelUnknown); 159 return false; 160 } 161 } 162 163 if (!channel_info.GetChannelName(channel)) 164 channel->assign(installer::kChromeChannelUnknown); 165 166 // Tag the channel name if this is a multi-install. 167 if (add_multi_modifier && state.is_multi_install()) { 168 if (!channel->empty()) 169 channel->push_back(L'-'); 170 channel->push_back(L'm'); 171 } 172 173 return true; 174 } 175 176 // Populates |update_policy| with the UpdatePolicy enum value corresponding to a 177 // DWORD read from the registry and returns true if |value| is within range. 178 // If |value| is out of range, returns false without modifying |update_policy|. 179 bool GetUpdatePolicyFromDword( 180 const DWORD value, 181 GoogleUpdateSettings::UpdatePolicy* update_policy) { 182 switch (value) { 183 case GoogleUpdateSettings::UPDATES_DISABLED: 184 case GoogleUpdateSettings::AUTOMATIC_UPDATES: 185 case GoogleUpdateSettings::MANUAL_UPDATES_ONLY: 186 case GoogleUpdateSettings::AUTO_UPDATES_ONLY: 187 *update_policy = static_cast<GoogleUpdateSettings::UpdatePolicy>(value); 188 return true; 189 default: 190 LOG(WARNING) << "Unexpected update policy override value: " << value; 191 } 192 return false; 193 } 194 195 // Convenience routine: GoogleUpdateSettings::UpdateDidRunStateForApp() 196 // specialized for Chrome Binaries. 197 bool UpdateDidRunStateForBinaries(bool did_run) { 198 BrowserDistribution* dist = BrowserDistribution::GetSpecificDistribution( 199 BrowserDistribution::CHROME_BINARIES); 200 return GoogleUpdateSettings::UpdateDidRunStateForApp( 201 dist->GetAppRegistrationData(), did_run); 202 } 203 204 } // namespace 205 206 bool GoogleUpdateSettings::IsSystemInstall() { 207 bool system_install = false; 208 base::FilePath module_dir; 209 if (!PathService::Get(base::DIR_MODULE, &module_dir)) { 210 LOG(WARNING) 211 << "Failed to get directory of module; assuming per-user install."; 212 } else { 213 system_install = !InstallUtil::IsPerUserInstall(module_dir.value().c_str()); 214 } 215 return system_install; 216 } 217 218 bool GoogleUpdateSettings::GetCollectStatsConsent() { 219 return GetCollectStatsConsentAtLevel(IsSystemInstall()); 220 } 221 222 // Older versions of Chrome unconditionally read from HKCU\...\ClientState\... 223 // and then HKLM\...\ClientState\.... This means that system-level Chrome 224 // never checked ClientStateMedium (which has priority according to Google 225 // Update) and gave preference to a value in HKCU (which was never checked by 226 // Google Update). From now on, Chrome follows Google Update's policy. 227 bool GoogleUpdateSettings::GetCollectStatsConsentAtLevel(bool system_install) { 228 BrowserDistribution* dist = BrowserDistribution::GetDistribution(); 229 230 // Consent applies to all products in a multi-install package. 231 if (InstallUtil::IsMultiInstall(dist, system_install)) { 232 dist = BrowserDistribution::GetSpecificDistribution( 233 BrowserDistribution::CHROME_BINARIES); 234 } 235 236 RegKey key; 237 DWORD value = 0; 238 bool have_value = false; 239 const REGSAM kAccess = KEY_QUERY_VALUE | KEY_WOW64_32KEY; 240 241 // For system-level installs, try ClientStateMedium first. 242 have_value = 243 system_install && 244 key.Open(HKEY_LOCAL_MACHINE, dist->GetStateMediumKey().c_str(), 245 kAccess) == ERROR_SUCCESS && 246 key.ReadValueDW(google_update::kRegUsageStatsField, 247 &value) == ERROR_SUCCESS; 248 249 // Otherwise, try ClientState. 250 if (!have_value) { 251 have_value = 252 key.Open(system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, 253 dist->GetStateKey().c_str(), 254 kAccess) == ERROR_SUCCESS && 255 key.ReadValueDW(google_update::kRegUsageStatsField, 256 &value) == ERROR_SUCCESS; 257 } 258 259 // Google Update specifically checks that the value is 1, so we do the same. 260 return have_value && value == 1; 261 } 262 263 bool GoogleUpdateSettings::SetCollectStatsConsent(bool consented) { 264 return SetCollectStatsConsentAtLevel(IsSystemInstall(), consented); 265 } 266 267 bool GoogleUpdateSettings::SetCollectStatsConsentAtLevel(bool system_install, 268 bool consented) { 269 // Google Update writes and expects 1 for true, 0 for false. 270 DWORD value = consented ? 1 : 0; 271 272 BrowserDistribution* dist = BrowserDistribution::GetDistribution(); 273 274 // Consent applies to all products in a multi-install package. 275 if (InstallUtil::IsMultiInstall(dist, system_install)) { 276 dist = BrowserDistribution::GetSpecificDistribution( 277 BrowserDistribution::CHROME_BINARIES); 278 } 279 280 // Write to ClientStateMedium for system-level; ClientState otherwise. 281 HKEY root_key = system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; 282 base::string16 reg_path = 283 system_install ? dist->GetStateMediumKey() : dist->GetStateKey(); 284 RegKey key; 285 LONG result = key.Create( 286 root_key, reg_path.c_str(), KEY_SET_VALUE | KEY_WOW64_32KEY); 287 if (result != ERROR_SUCCESS) { 288 LOG(ERROR) << "Failed opening key " << reg_path << " to set " 289 << google_update::kRegUsageStatsField << "; result: " << result; 290 } else { 291 result = key.WriteValue(google_update::kRegUsageStatsField, value); 292 LOG_IF(ERROR, result != ERROR_SUCCESS) << "Failed setting " 293 << google_update::kRegUsageStatsField << " in key " << reg_path 294 << "; result: " << result; 295 } 296 return (result == ERROR_SUCCESS); 297 } 298 299 scoped_ptr<metrics::ClientInfo> GoogleUpdateSettings::LoadMetricsClientInfo() { 300 base::string16 client_id_16; 301 if (!ReadGoogleUpdateStrKey(google_update::kRegMetricsId, &client_id_16) || 302 client_id_16.empty()) { 303 return scoped_ptr<metrics::ClientInfo>(); 304 } 305 306 scoped_ptr<metrics::ClientInfo> client_info(new metrics::ClientInfo); 307 client_info->client_id = base::UTF16ToUTF8(client_id_16); 308 309 base::string16 installation_date_str; 310 if (ReadGoogleUpdateStrKey(google_update::kRegMetricsIdInstallDate, 311 &installation_date_str)) { 312 base::StringToInt64(installation_date_str, &client_info->installation_date); 313 } 314 315 base::string16 reporting_enbaled_date_date_str; 316 if (ReadGoogleUpdateStrKey(google_update::kRegMetricsIdEnabledDate, 317 &reporting_enbaled_date_date_str)) { 318 base::StringToInt64(reporting_enbaled_date_date_str, 319 &client_info->reporting_enabled_date); 320 } 321 322 return client_info.Pass(); 323 } 324 325 void GoogleUpdateSettings::StoreMetricsClientInfo( 326 const metrics::ClientInfo& client_info) { 327 // Attempt a best-effort at backing |client_info| in the registry (but don't 328 // handle/report failures). 329 WriteGoogleUpdateStrKey(google_update::kRegMetricsId, 330 base::UTF8ToUTF16(client_info.client_id)); 331 WriteGoogleUpdateStrKey(google_update::kRegMetricsIdInstallDate, 332 base::Int64ToString16(client_info.installation_date)); 333 WriteGoogleUpdateStrKey( 334 google_update::kRegMetricsIdEnabledDate, 335 base::Int64ToString16(client_info.reporting_enabled_date)); 336 } 337 338 // EULA consent is only relevant for system-level installs. 339 bool GoogleUpdateSettings::SetEULAConsent( 340 const InstallationState& machine_state, 341 BrowserDistribution* dist, 342 bool consented) { 343 DCHECK(dist); 344 const DWORD eula_accepted = consented ? 1 : 0; 345 const REGSAM kAccess = KEY_SET_VALUE | KEY_WOW64_32KEY; 346 base::string16 reg_path = dist->GetStateMediumKey(); 347 bool succeeded = true; 348 RegKey key; 349 350 // Write the consent value into the product's ClientStateMedium key. 351 if (key.Create(HKEY_LOCAL_MACHINE, reg_path.c_str(), 352 kAccess) != ERROR_SUCCESS || 353 key.WriteValue(google_update::kRegEULAAceptedField, 354 eula_accepted) != ERROR_SUCCESS) { 355 succeeded = false; 356 } 357 358 // If this is a multi-install, also write it into the binaries' key. 359 // --mutli-install is not provided on the command-line, so deduce it from 360 // the product's state. 361 const installer::ProductState* product_state = 362 machine_state.GetProductState(true, dist->GetType()); 363 if (product_state != NULL && product_state->is_multi_install()) { 364 dist = BrowserDistribution::GetSpecificDistribution( 365 BrowserDistribution::CHROME_BINARIES); 366 reg_path = dist->GetStateMediumKey(); 367 if (key.Create(HKEY_LOCAL_MACHINE, reg_path.c_str(), 368 kAccess) != ERROR_SUCCESS || 369 key.WriteValue(google_update::kRegEULAAceptedField, 370 eula_accepted) != ERROR_SUCCESS) { 371 succeeded = false; 372 } 373 } 374 375 return succeeded; 376 } 377 378 int GoogleUpdateSettings::GetLastRunTime() { 379 base::string16 time_s; 380 if (!ReadGoogleUpdateStrKey(google_update::kRegLastRunTimeField, &time_s)) 381 return -1; 382 int64 time_i; 383 if (!base::StringToInt64(time_s, &time_i)) 384 return -1; 385 base::TimeDelta td = 386 base::Time::NowFromSystemTime() - base::Time::FromInternalValue(time_i); 387 return td.InDays(); 388 } 389 390 bool GoogleUpdateSettings::SetLastRunTime() { 391 int64 time = base::Time::NowFromSystemTime().ToInternalValue(); 392 return WriteGoogleUpdateStrKey(google_update::kRegLastRunTimeField, 393 base::Int64ToString16(time)); 394 } 395 396 bool GoogleUpdateSettings::RemoveLastRunTime() { 397 return RemoveGoogleUpdateStrKey(google_update::kRegLastRunTimeField); 398 } 399 400 bool GoogleUpdateSettings::GetBrowser(base::string16* browser) { 401 return ReadGoogleUpdateStrKey(google_update::kRegBrowserField, browser); 402 } 403 404 bool GoogleUpdateSettings::GetLanguage(base::string16* language) { 405 return ReadGoogleUpdateStrKey(google_update::kRegLangField, language); 406 } 407 408 bool GoogleUpdateSettings::GetBrand(base::string16* brand) { 409 return ReadGoogleUpdateStrKey(google_update::kRegRLZBrandField, brand); 410 } 411 412 bool GoogleUpdateSettings::GetReactivationBrand(base::string16* brand) { 413 return ReadGoogleUpdateStrKey(google_update::kRegRLZReactivationBrandField, 414 brand); 415 } 416 417 bool GoogleUpdateSettings::GetClient(base::string16* client) { 418 return ReadGoogleUpdateStrKey(google_update::kRegClientField, client); 419 } 420 421 bool GoogleUpdateSettings::SetClient(const base::string16& client) { 422 return WriteGoogleUpdateStrKey(google_update::kRegClientField, client); 423 } 424 425 bool GoogleUpdateSettings::GetReferral(base::string16* referral) { 426 return ReadGoogleUpdateStrKey(google_update::kRegReferralField, referral); 427 } 428 429 bool GoogleUpdateSettings::ClearReferral() { 430 return ClearGoogleUpdateStrKey(google_update::kRegReferralField); 431 } 432 433 bool GoogleUpdateSettings::UpdateDidRunStateForApp( 434 const AppRegistrationData& app_reg_data, 435 bool did_run) { 436 return WriteGoogleUpdateStrKeyInternal(app_reg_data, 437 false, // user level. 438 google_update::kRegDidRunField, 439 did_run ? L"1" : L"0", 440 NULL); 441 } 442 443 bool GoogleUpdateSettings::UpdateDidRunState(bool did_run, bool system_level) { 444 BrowserDistribution* dist = BrowserDistribution::GetDistribution(); 445 bool result = UpdateDidRunStateForApp(dist->GetAppRegistrationData(), 446 did_run); 447 // Update state for binaries, even if the previous call was unsuccessful. 448 if (InstallUtil::IsMultiInstall(dist, system_level)) 449 result = UpdateDidRunStateForBinaries(did_run) && result; 450 return result; 451 } 452 453 base::string16 GoogleUpdateSettings::GetChromeChannel(bool system_install) { 454 base::string16 channel; 455 GetChromeChannelInternal(system_install, false, &channel); 456 return channel; 457 } 458 459 bool GoogleUpdateSettings::GetChromeChannelAndModifiers( 460 bool system_install, 461 base::string16* channel) { 462 return GetChromeChannelInternal(system_install, true, channel); 463 } 464 465 void GoogleUpdateSettings::UpdateInstallStatus(bool system_install, 466 installer::ArchiveType archive_type, int install_return_code, 467 const base::string16& product_guid) { 468 DCHECK(archive_type != installer::UNKNOWN_ARCHIVE_TYPE || 469 install_return_code != 0); 470 HKEY reg_root = (system_install) ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; 471 472 RegKey key; 473 installer::ChannelInfo channel_info; 474 base::string16 reg_key(google_update::kRegPathClientState); 475 reg_key.append(L"\\"); 476 reg_key.append(product_guid); 477 LONG result = key.Open(reg_root, 478 reg_key.c_str(), 479 KEY_QUERY_VALUE | KEY_SET_VALUE | KEY_WOW64_32KEY); 480 if (result == ERROR_SUCCESS) 481 channel_info.Initialize(key); 482 else if (result != ERROR_FILE_NOT_FOUND) 483 LOG(ERROR) << "Failed to open " << reg_key << "; Error: " << result; 484 485 if (UpdateGoogleUpdateApKey(archive_type, install_return_code, 486 &channel_info)) { 487 // We have a modified channel_info value to write. 488 // Create the app's ClientState key if it doesn't already exist. 489 if (!key.Valid()) { 490 result = key.Open(reg_root, 491 google_update::kRegPathClientState, 492 KEY_CREATE_SUB_KEY | KEY_WOW64_32KEY); 493 if (result == ERROR_SUCCESS) 494 result = key.CreateKey(product_guid.c_str(), 495 KEY_SET_VALUE | KEY_WOW64_32KEY); 496 497 if (result != ERROR_SUCCESS) { 498 LOG(ERROR) << "Failed to create " << reg_key << "; Error: " << result; 499 return; 500 } 501 } 502 if (!channel_info.Write(&key)) { 503 LOG(ERROR) << "Failed to write to application's ClientState key " 504 << google_update::kRegApField << " = " << channel_info.value(); 505 } 506 } 507 } 508 509 bool GoogleUpdateSettings::UpdateGoogleUpdateApKey( 510 installer::ArchiveType archive_type, int install_return_code, 511 installer::ChannelInfo* value) { 512 DCHECK(archive_type != installer::UNKNOWN_ARCHIVE_TYPE || 513 install_return_code != 0); 514 bool modified = false; 515 516 if (archive_type == installer::FULL_ARCHIVE_TYPE || !install_return_code) { 517 if (value->SetFullSuffix(false)) { 518 VLOG(1) << "Removed incremental installer failure key; " 519 "switching to channel: " 520 << value->value(); 521 modified = true; 522 } 523 } else if (archive_type == installer::INCREMENTAL_ARCHIVE_TYPE) { 524 if (value->SetFullSuffix(true)) { 525 VLOG(1) << "Incremental installer failed; switching to channel: " 526 << value->value(); 527 modified = true; 528 } else { 529 VLOG(1) << "Incremental installer failure; already on channel: " 530 << value->value(); 531 } 532 } else { 533 // It's okay if we don't know the archive type. In this case, leave the 534 // "-full" suffix as we found it. 535 DCHECK_EQ(installer::UNKNOWN_ARCHIVE_TYPE, archive_type); 536 } 537 538 if (value->SetMultiFailSuffix(false)) { 539 VLOG(1) << "Removed multi-install failure key; switching to channel: " 540 << value->value(); 541 modified = true; 542 } 543 544 return modified; 545 } 546 547 void GoogleUpdateSettings::UpdateProfileCounts(int profiles_active, 548 int profiles_signedin) { 549 BrowserDistribution* dist = BrowserDistribution::GetDistribution(); 550 bool system_install = IsSystemInstall(); 551 WriteGoogleUpdateStrKeyInternal(dist->GetAppRegistrationData(), 552 system_install, 553 google_update::kRegProfilesActive, 554 base::Int64ToString16(profiles_active), 555 L"sum()"); 556 WriteGoogleUpdateStrKeyInternal(dist->GetAppRegistrationData(), 557 system_install, 558 google_update::kRegProfilesSignedIn, 559 base::Int64ToString16(profiles_signedin), 560 L"sum()"); 561 } 562 563 int GoogleUpdateSettings::DuplicateGoogleUpdateSystemClientKey() { 564 BrowserDistribution* dist = BrowserDistribution::GetDistribution(); 565 base::string16 reg_path = dist->GetStateKey(); 566 567 // Minimum access needed is to be able to write to this key. 568 RegKey reg_key( 569 HKEY_LOCAL_MACHINE, reg_path.c_str(), KEY_SET_VALUE | KEY_WOW64_32KEY); 570 if (!reg_key.Valid()) 571 return 0; 572 573 HANDLE target_handle = 0; 574 if (!DuplicateHandle(GetCurrentProcess(), reg_key.Handle(), 575 GetCurrentProcess(), &target_handle, KEY_SET_VALUE, 576 TRUE, DUPLICATE_SAME_ACCESS)) { 577 return 0; 578 } 579 return reinterpret_cast<int>(target_handle); 580 } 581 582 bool GoogleUpdateSettings::WriteGoogleUpdateSystemClientKey( 583 int handle, const base::string16& key, const base::string16& value) { 584 HKEY reg_key = reinterpret_cast<HKEY>(reinterpret_cast<void*>(handle)); 585 DWORD size = static_cast<DWORD>(value.size()) * sizeof(wchar_t); 586 LSTATUS status = RegSetValueEx(reg_key, key.c_str(), 0, REG_SZ, 587 reinterpret_cast<const BYTE*>(value.c_str()), size); 588 return status == ERROR_SUCCESS; 589 } 590 591 GoogleUpdateSettings::UpdatePolicy GoogleUpdateSettings::GetAppUpdatePolicy( 592 const base::string16& app_guid, 593 bool* is_overridden) { 594 bool found_override = false; 595 UpdatePolicy update_policy = kDefaultUpdatePolicy; 596 597 #if defined(GOOGLE_CHROME_BUILD) 598 DCHECK(!app_guid.empty()); 599 RegKey policy_key; 600 601 // Google Update Group Policy settings are always in HKLM. 602 // TODO(wfh): Check if policies should go into Wow6432Node or not. 603 if (policy_key.Open(HKEY_LOCAL_MACHINE, kPoliciesKey, KEY_QUERY_VALUE) == 604 ERROR_SUCCESS) { 605 DWORD value = 0; 606 base::string16 app_update_override(kUpdateOverrideValuePrefix); 607 app_update_override.append(app_guid); 608 // First try to read and comprehend the app-specific override. 609 found_override = (policy_key.ReadValueDW(app_update_override.c_str(), 610 &value) == ERROR_SUCCESS && 611 GetUpdatePolicyFromDword(value, &update_policy)); 612 613 // Failing that, try to read and comprehend the default override. 614 if (!found_override && 615 policy_key.ReadValueDW(kUpdatePolicyValue, &value) == ERROR_SUCCESS) { 616 GetUpdatePolicyFromDword(value, &update_policy); 617 } 618 } 619 #endif // defined(GOOGLE_CHROME_BUILD) 620 621 if (is_overridden != NULL) 622 *is_overridden = found_override; 623 624 return update_policy; 625 } 626 627 // static 628 bool GoogleUpdateSettings::AreAutoupdatesEnabled() { 629 #if defined(GOOGLE_CHROME_BUILD) 630 // Check the auto-update check period override. If it is 0 or exceeds the 631 // maximum timeout, then for all intents and purposes auto updates are 632 // disabled. 633 RegKey policy_key; 634 DWORD value = 0; 635 if (policy_key.Open(HKEY_LOCAL_MACHINE, kPoliciesKey, 636 KEY_QUERY_VALUE) == ERROR_SUCCESS && 637 policy_key.ReadValueDW(kCheckPeriodOverrideMinutes, 638 &value) == ERROR_SUCCESS && 639 (value == 0 || value > kCheckPeriodOverrideMinutesMax)) { 640 return false; 641 } 642 643 // Auto updates are subtly broken when Chrome and the binaries have different 644 // overrides in place. If this Chrome cannot possibly be multi-install by 645 // virtue of being a side-by-side installation, simply check Chrome's policy. 646 BrowserDistribution* dist = BrowserDistribution::GetDistribution(); 647 UpdatePolicy app_policy = GetAppUpdatePolicy(dist->GetAppGuid(), nullptr); 648 if (InstallUtil::IsChromeSxSProcess()) 649 return app_policy == AUTOMATIC_UPDATES || app_policy == AUTO_UPDATES_ONLY; 650 651 // Otherwise, check for consistency between Chrome and the binaries regardless 652 // of whether or not this Chrome is multi-install since the next update likely 653 // will attempt to migrate it to such. 654 BrowserDistribution* binaries = BrowserDistribution::GetSpecificDistribution( 655 BrowserDistribution::CHROME_BINARIES); 656 return (GetAppUpdatePolicy(binaries->GetAppGuid(), nullptr) == app_policy && 657 (app_policy == AUTOMATIC_UPDATES || app_policy == AUTO_UPDATES_ONLY)); 658 #else // defined(GOOGLE_CHROME_BUILD) 659 // Chromium does not auto update. 660 return false; 661 #endif // !defined(GOOGLE_CHROME_BUILD) 662 } 663 664 // static 665 bool GoogleUpdateSettings::ReenableAutoupdates() { 666 #if defined(GOOGLE_CHROME_BUILD) 667 int needs_reset_count = 0; 668 int did_reset_count = 0; 669 670 // Reset overrides for Chrome and for the binaries if this Chrome supports 671 // multi-install. 672 std::vector<base::string16> app_guids; 673 app_guids.push_back(BrowserDistribution::GetDistribution()->GetAppGuid()); 674 if (!InstallUtil::IsChromeSxSProcess()) { 675 app_guids.push_back(BrowserDistribution::GetSpecificDistribution( 676 BrowserDistribution::CHROME_BINARIES)->GetAppGuid()); 677 } 678 679 UpdatePolicy update_policy = kDefaultUpdatePolicy; 680 RegKey policy_key; 681 if (policy_key.Open(HKEY_LOCAL_MACHINE, kPoliciesKey, 682 KEY_SET_VALUE | KEY_QUERY_VALUE) == ERROR_SUCCESS) { 683 // Set to true while app-specific overrides are present that allow automatic 684 // updates. When this is the case, the defaults are irrelevant and don't 685 // need to be checked or reset. 686 bool automatic_updates_allowed_by_overrides = true; 687 DWORD value = 0; 688 for (const base::string16& app_guid : app_guids) { 689 // First check the app-specific override value and reset that if needed. 690 // Note that this intentionally sets the override to AUTOMATIC_UPDATES 691 // even if it was previously AUTO_UPDATES_ONLY. The thinking is that 692 // AUTOMATIC_UPDATES is marginally more likely to let a user update and 693 // this code is only called when a stuck user asks for updates. 694 base::string16 app_update_override(kUpdateOverrideValuePrefix); 695 app_update_override.append(app_guid); 696 if (policy_key.ReadValueDW(app_update_override.c_str(), 697 &value) != ERROR_SUCCESS) { 698 automatic_updates_allowed_by_overrides = false; 699 } else if (!GetUpdatePolicyFromDword(value, &update_policy) || 700 update_policy != GoogleUpdateSettings::AUTOMATIC_UPDATES) { 701 automatic_updates_allowed_by_overrides = false; 702 ++needs_reset_count; 703 if (policy_key.WriteValue( 704 app_update_override.c_str(), 705 static_cast<DWORD>(GoogleUpdateSettings::AUTOMATIC_UPDATES)) == 706 ERROR_SUCCESS) { 707 ++did_reset_count; 708 } 709 } 710 } 711 712 // If there were no app-specific override policies, see if there's a global 713 // policy preventing updates and delete it if so. 714 if (!automatic_updates_allowed_by_overrides && 715 policy_key.ReadValueDW(kUpdatePolicyValue, &value) == ERROR_SUCCESS && 716 (!GetUpdatePolicyFromDword(value, &update_policy) || 717 update_policy != GoogleUpdateSettings::AUTOMATIC_UPDATES)) { 718 ++needs_reset_count; 719 if (policy_key.DeleteValue(kUpdatePolicyValue) == ERROR_SUCCESS) 720 ++did_reset_count; 721 } 722 723 // Check the auto-update check period override. If it is 0 or exceeds 724 // the maximum timeout, delete the override value. 725 if (policy_key.ReadValueDW(kCheckPeriodOverrideMinutes, 726 &value) == ERROR_SUCCESS && 727 (value == 0 || value > kCheckPeriodOverrideMinutesMax)) { 728 ++needs_reset_count; 729 if (policy_key.DeleteValue(kCheckPeriodOverrideMinutes) == ERROR_SUCCESS) 730 ++did_reset_count; 731 } 732 733 // Return whether the number of successful resets is the same as the 734 // number of things that appeared to need resetting. 735 return (needs_reset_count == did_reset_count); 736 } else { 737 // For some reason we couldn't open the policy key with the desired 738 // permissions to make changes (the most likely reason is that there is no 739 // policy set). Simply return whether or not we think updates are enabled. 740 return AreAutoupdatesEnabled(); 741 } 742 743 #endif 744 // Non Google Chrome isn't going to autoupdate. 745 return true; 746 } 747 748 void GoogleUpdateSettings::RecordChromeUpdatePolicyHistograms() { 749 const bool is_multi_install = InstallUtil::IsMultiInstall( 750 BrowserDistribution::GetDistribution(), IsSystemInstall()); 751 const base::string16 app_guid = 752 BrowserDistribution::GetSpecificDistribution( 753 is_multi_install ? BrowserDistribution::CHROME_BINARIES : 754 BrowserDistribution::CHROME_BROWSER)->GetAppGuid(); 755 756 bool is_overridden = false; 757 const UpdatePolicy update_policy = GetAppUpdatePolicy(app_guid, 758 &is_overridden); 759 UMA_HISTOGRAM_BOOLEAN("GoogleUpdate.UpdatePolicyIsOverridden", is_overridden); 760 UMA_HISTOGRAM_ENUMERATION("GoogleUpdate.EffectivePolicy", update_policy, 761 UPDATE_POLICIES_COUNT); 762 } 763 764 base::string16 GoogleUpdateSettings::GetUninstallCommandLine( 765 bool system_install) { 766 const HKEY root_key = system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; 767 base::string16 cmd_line; 768 RegKey update_key; 769 770 if (update_key.Open(root_key, google_update::kRegPathGoogleUpdate, 771 KEY_QUERY_VALUE | KEY_WOW64_32KEY) == ERROR_SUCCESS) { 772 update_key.ReadValue(google_update::kRegUninstallCmdLine, &cmd_line); 773 } 774 775 return cmd_line; 776 } 777 778 Version GoogleUpdateSettings::GetGoogleUpdateVersion(bool system_install) { 779 const HKEY root_key = system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; 780 base::string16 version; 781 RegKey key; 782 783 if (key.Open(root_key, 784 google_update::kRegPathGoogleUpdate, 785 KEY_QUERY_VALUE | KEY_WOW64_32KEY) == ERROR_SUCCESS && 786 key.ReadValue(google_update::kRegGoogleUpdateVersion, &version) == 787 ERROR_SUCCESS) { 788 return Version(base::UTF16ToUTF8(version)); 789 } 790 791 return Version(); 792 } 793 794 base::Time GoogleUpdateSettings::GetGoogleUpdateLastStartedAU( 795 bool system_install) { 796 const HKEY root_key = system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; 797 RegKey update_key; 798 799 if (update_key.Open(root_key, 800 google_update::kRegPathGoogleUpdate, 801 KEY_QUERY_VALUE | KEY_WOW64_32KEY) == ERROR_SUCCESS) { 802 DWORD last_start; 803 if (update_key.ReadValueDW(google_update::kRegLastStartedAUField, 804 &last_start) == ERROR_SUCCESS) { 805 return base::Time::FromTimeT(last_start); 806 } 807 } 808 809 return base::Time(); 810 } 811 812 base::Time GoogleUpdateSettings::GetGoogleUpdateLastChecked( 813 bool system_install) { 814 const HKEY root_key = system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; 815 RegKey update_key; 816 817 if (update_key.Open(root_key, 818 google_update::kRegPathGoogleUpdate, 819 KEY_QUERY_VALUE | KEY_WOW64_32KEY) == ERROR_SUCCESS) { 820 DWORD last_check; 821 if (update_key.ReadValueDW(google_update::kRegLastCheckedField, 822 &last_check) == ERROR_SUCCESS) { 823 return base::Time::FromTimeT(last_check); 824 } 825 } 826 827 return base::Time(); 828 } 829 830 bool GoogleUpdateSettings::GetUpdateDetailForApp(bool system_install, 831 const wchar_t* app_guid, 832 ProductData* data) { 833 DCHECK(app_guid); 834 DCHECK(data); 835 836 bool product_found = false; 837 838 const HKEY root_key = system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; 839 base::string16 clientstate_reg_path(google_update::kRegPathClientState); 840 clientstate_reg_path.append(L"\\"); 841 clientstate_reg_path.append(app_guid); 842 843 RegKey clientstate; 844 if (clientstate.Open(root_key, 845 clientstate_reg_path.c_str(), 846 KEY_QUERY_VALUE | KEY_WOW64_32KEY) == ERROR_SUCCESS) { 847 base::string16 version; 848 DWORD dword_value; 849 if ((clientstate.ReadValueDW(google_update::kRegLastCheckSuccessField, 850 &dword_value) == ERROR_SUCCESS) && 851 (clientstate.ReadValue(google_update::kRegVersionField, 852 &version) == ERROR_SUCCESS)) { 853 product_found = true; 854 data->version = base::UTF16ToASCII(version); 855 data->last_success = base::Time::FromTimeT(dword_value); 856 data->last_result = 0; 857 data->last_error_code = 0; 858 data->last_extra_code = 0; 859 860 if (clientstate.ReadValueDW(google_update::kRegLastInstallerResultField, 861 &dword_value) == ERROR_SUCCESS) { 862 // Google Update convention is that if an installer writes an result 863 // code that is invalid, it is clamped to an exit code result. 864 const DWORD kMaxValidInstallResult = 4; // INSTALLER_RESULT_EXIT_CODE 865 data->last_result = std::min(dword_value, kMaxValidInstallResult); 866 } 867 if (clientstate.ReadValueDW(google_update::kRegLastInstallerErrorField, 868 &dword_value) == ERROR_SUCCESS) { 869 data->last_error_code = dword_value; 870 } 871 if (clientstate.ReadValueDW(google_update::kRegLastInstallerExtraField, 872 &dword_value) == ERROR_SUCCESS) { 873 data->last_extra_code = dword_value; 874 } 875 } 876 } 877 878 return product_found; 879 } 880 881 bool GoogleUpdateSettings::GetUpdateDetailForGoogleUpdate(bool system_install, 882 ProductData* data) { 883 return GetUpdateDetailForApp(system_install, 884 google_update::kGoogleUpdateUpgradeCode, 885 data); 886 } 887 888 bool GoogleUpdateSettings::GetUpdateDetail(bool system_install, 889 ProductData* data) { 890 BrowserDistribution* dist = BrowserDistribution::GetDistribution(); 891 return GetUpdateDetailForApp(system_install, 892 dist->GetAppGuid().c_str(), 893 data); 894 } 895 896 bool GoogleUpdateSettings::SetExperimentLabels( 897 bool system_install, 898 const base::string16& experiment_labels) { 899 HKEY reg_root = system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; 900 901 // Use the browser distribution and install level to write to the correct 902 // client state/app guid key. 903 bool success = false; 904 BrowserDistribution* dist = BrowserDistribution::GetDistribution(); 905 if (dist->ShouldSetExperimentLabels()) { 906 base::string16 client_state_path( 907 system_install ? dist->GetStateMediumKey() : dist->GetStateKey()); 908 RegKey client_state( 909 reg_root, client_state_path.c_str(), KEY_SET_VALUE | KEY_WOW64_32KEY); 910 if (experiment_labels.empty()) { 911 success = client_state.DeleteValue(google_update::kExperimentLabels) 912 == ERROR_SUCCESS; 913 } else { 914 success = client_state.WriteValue(google_update::kExperimentLabels, 915 experiment_labels.c_str()) == ERROR_SUCCESS; 916 } 917 } 918 919 return success; 920 } 921 922 bool GoogleUpdateSettings::ReadExperimentLabels( 923 bool system_install, 924 base::string16* experiment_labels) { 925 HKEY reg_root = system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; 926 927 // If this distribution does not set the experiment labels, don't bother 928 // reading. 929 BrowserDistribution* dist = BrowserDistribution::GetDistribution(); 930 if (!dist->ShouldSetExperimentLabels()) 931 return false; 932 933 base::string16 client_state_path( 934 system_install ? dist->GetStateMediumKey() : dist->GetStateKey()); 935 936 RegKey client_state; 937 LONG result = client_state.Open( 938 reg_root, client_state_path.c_str(), KEY_QUERY_VALUE | KEY_WOW64_32KEY); 939 if (result == ERROR_SUCCESS) { 940 result = client_state.ReadValue(google_update::kExperimentLabels, 941 experiment_labels); 942 } 943 944 // If the key or value was not present, return the empty string. 945 if (result == ERROR_FILE_NOT_FOUND || result == ERROR_PATH_NOT_FOUND) { 946 experiment_labels->clear(); 947 return true; 948 } 949 950 return result == ERROR_SUCCESS; 951 } 952