File: activity_impl_win.cc

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (158 lines) | stat: -rw-r--r-- 5,061 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <string>

#include "base/functional/function_ref.h"
#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/activity.h"
#include "chrome/updater/updater_scope.h"
#include "chrome/updater/util/win_util.h"
#include "chrome/updater/win/user_info.h"
#include "chrome/updater/win/win_constants.h"

namespace updater {
namespace {

using ProcessActiveBitUnderKeyCallback =
    base::FunctionRef<bool(HKEY, const std::wstring&)>;

constexpr wchar_t kDidRun[] = L"dr";

bool GetActiveBitUnderKey(HKEY rootkey, const std::wstring& key_name) {
  base::win::RegKey key;
  if (key.Open(rootkey, key_name.c_str(), Wow6432(KEY_QUERY_VALUE)) ==
      ERROR_SUCCESS) {
    // We support both string and DWORD formats for backward compatibility.
    std::wstring value;
    if ((key.ReadValue(kDidRun, &value) == ERROR_SUCCESS) && (value == L"1")) {
      return true;
    }

    DWORD value_dw = 0;
    if ((key.ReadValueDW(kDidRun, &value_dw) == ERROR_SUCCESS) &&
        (value_dw == 1)) {
      return true;
    }
  }
  return false;
}

// Always returns false to avoid the short circuit in ProcessActiveBit and
// the early return in ProcessSystemActiveBit.
bool ClearActiveBitUnderKey(HKEY rootkey, const std::wstring& key_name) {
  base::win::RegKey key;
  if (key.Open(rootkey, key_name.c_str(),
               Wow6432(KEY_QUERY_VALUE | KEY_SET_VALUE)) != ERROR_SUCCESS) {
    VLOG(3) << "Failed to open activity key with write for " << key_name;
    return false;
  }

  if (!key.HasValue(kDidRun)) {
    return false;
  }

  // We always clear the value as a string "0".
  const LONG result = key.WriteValue(kDidRun, L"0");
  VLOG_IF(2, result) << "Failed to clear activity key for " << key_name << ": "
                     << result;
  return false;
}

bool ProcessActiveBit(ProcessActiveBitUnderKeyCallback callback,
                      HKEY rootkey,
                      const std::wstring& sid,
                      const std::string& id) {
  const std::wstring rootkey_suffix =
      (rootkey == HKEY_USERS) ? base::StrCat({sid, L"\\"}) : L"";
  const bool process_success = callback(
      rootkey, base::StrCat({rootkey_suffix, GetAppClientStateKey(id)}));

  // For Google Toolbar and similar apps that run at low integrity, we need to
  // also look at the low integrity IE key. Note that we cannot use the
  // IEGetWriteableHKCU function since this function assumes that we are
  // running with the user's credentials. The path is as follows:
  // USER_REG_VISTA_LOW_INTEGRITY_HKCU\\SID
  // \\GOOPDATE_REG_RELATIVE_CLIENT_STATE\\app_guid
  const std::wstring low_integrity_key_name =
      base::StrCat({rootkey_suffix, USER_REG_VISTA_LOW_INTEGRITY_HKCU, L"\\",
                    sid, L"\\", GetAppClientStateKey(id)});

  return callback(rootkey, low_integrity_key_name) || process_success;
}

bool ProcessUserActiveBit(ProcessActiveBitUnderKeyCallback callback,
                          const std::string& id) {
  // Clear the active bit under HKCU.
  std::wstring sid;
  const HRESULT hr = GetProcessUser(nullptr, nullptr, &sid);
  if (FAILED(hr)) {
    VLOG(2) << "Failed to GetProcessUser " << hr;
    return false;
  }

  return ProcessActiveBit(callback, HKEY_CURRENT_USER, sid, id);
}

bool ProcessSystemActiveBit(ProcessActiveBitUnderKeyCallback callback,
                            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) {
    const std::wstring sid = it.Name();
    if (ProcessActiveBit(callback, HKEY_USERS, sid, id)) {
      return true;
    }
  }

  return false;
}

bool GetUserActiveBit(const std::string& id) {
  // Read the active bit under HKCU.
  return ProcessUserActiveBit(&GetActiveBitUnderKey, id);
}

void ClearUserActiveBit(const std::string& id) {
  // Clear the active bit under HKCU.
  ProcessUserActiveBit(&ClearActiveBitUnderKey, id);
}

bool GetSystemActiveBit(const std::string& id) {
  // Read the active bit under each user in HKU\<sid>.
  return ProcessSystemActiveBit(&GetActiveBitUnderKey, id);
}

void ClearSystemActiveBit(const std::string& id) {
  // Clear the active bit under each user in HKU\<sid>.
  ProcessSystemActiveBit(&ClearActiveBitUnderKey, id);
}

}  // namespace

bool GetActiveBit(UpdaterScope scope, const std::string& id) {
  switch (scope) {
    case UpdaterScope::kUser:
      return GetUserActiveBit(id);
    case UpdaterScope::kSystem:
      return GetSystemActiveBit(id);
  }
}

void ClearActiveBit(UpdaterScope scope, const std::string& id) {
  switch (scope) {
    case UpdaterScope::kUser:
      ClearUserActiveBit(id);
      break;
    case UpdaterScope::kSystem:
      ClearSystemActiveBit(id);
      break;
  }
}

}  // namespace updater