blob: 843906844d2c87fd33c300c067f7c53de85ff83d [file] [log] [blame]
// Copyright 2020 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 "chrome/updater/activity.h"
#include <string>
#include "base/logging.h"
#include "base/strings/strcat.h"
#include "base/strings/utf_string_conversions.h"
#include "base/win/registry.h"
#include "base/win/windows_types.h"
#include "chrome/updater/updater_scope.h"
#include "chrome/updater/win/constants.h"
namespace updater {
namespace {
constexpr wchar_t kDidRun[] = L"dr";
std::wstring GetAppClientStateKey(const std::string& id) {
return base::ASCIIToWide(base::StrCat({CLIENT_STATE_KEY, id}));
}
bool GetActiveBitUnderKey(HKEY rootkey, const std::wstring& key_name) {
base::win::RegKey key;
if (key.Open(rootkey, key_name.c_str(), KEY_READ | KEY_WOW64_32KEY) ==
ERROR_SUCCESS) {
std::wstring value;
if (key.ReadValue(kDidRun, &value) == ERROR_SUCCESS && value == L"1")
return true;
}
return false;
}
bool GetMachineActiveBit(const std::string& id) {
// Read the active bit under each user in HKU\<sid>.
for (base::win::RegistryKeyIterator it(HKEY_USERS, L"", KEY_WOW64_32KEY);
it.Valid(); ++it) {
std::wstring user_state_key_name =
std::wstring(it.Name()).append(L"\\").append(GetAppClientStateKey(id));
if (GetActiveBitUnderKey(HKEY_USERS, user_state_key_name))
return true;
}
return false;
}
void ClearActiveBitUnderKey(HKEY rootkey, const std::wstring& key_name) {
base::win::RegKey key;
if (key.Open(rootkey, key_name.c_str(), KEY_WRITE | KEY_WOW64_32KEY) !=
ERROR_SUCCESS) {
VLOG(2) << "Failed to open activity key with write for " << key_name;
return;
}
const LONG result = key.WriteValue(kDidRun, L"0");
VLOG_IF(2, result) << "Failed to clear activity key for " << key_name << ": "
<< result;
}
void ClearMachineActiveBit(const std::string& id) {
// Clear the active bit under each user in HKU\<sid>.
for (base::win::RegistryKeyIterator it(HKEY_USERS, L"", KEY_WOW64_32KEY);
it.Valid(); ++it) {
std::wstring user_state_key_name =
std::wstring(it.Name()).append(L"\\").append(GetAppClientStateKey(id));
ClearActiveBitUnderKey(HKEY_USERS, user_state_key_name);
}
}
} // namespace
bool GetActiveBit(UpdaterScope scope, const std::string& id) {
switch (scope) {
case UpdaterScope::kUser:
// TODO(crbug/1159498): Standardize registry access.
return GetActiveBitUnderKey(HKEY_CURRENT_USER,
GetAppClientStateKey(id).c_str());
case UpdaterScope::kSystem:
return GetMachineActiveBit(id);
}
}
void ClearActiveBit(UpdaterScope scope, const std::string& id) {
switch (scope) {
case UpdaterScope::kUser:
// TODO(crbug/1159498): Standardize registry access.
ClearActiveBitUnderKey(HKEY_CURRENT_USER,
GetAppClientStateKey(id).c_str());
break;
case UpdaterScope::kSystem:
ClearMachineActiveBit(id);
break;
}
}
} // namespace updater