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 "remoting/host/usage_stats_consent.h"
6
7 #include <windows.h>
8 #include <string>
9
10 #include "base/logging.h"
11 #include "base/strings/stringprintf.h"
12 #include "base/win/registry.h"
13 #include "remoting/host/win/omaha.h"
14
15 namespace {
16
17 // The following strings are used to construct the registry key names where
18 // we record whether the user has consented to crash dump collection.
19 // the user's consent to collect crash dumps is recorded.
20 const wchar_t kOmahaClientStateKeyFormat[] =
21 L"Software\\Google\\Update\\%ls\\%ls";
22 const wchar_t kOmahaClientState[] = L"ClientState";
23 const wchar_t kOmahaClientStateMedium[] = L"ClientStateMedium";
24 const wchar_t kOmahaUsagestatsValue[] = L"usagestats";
25
ReadUsageStatsValue(const wchar_t * state_key,DWORD * usagestats_out)26 LONG ReadUsageStatsValue(const wchar_t* state_key, DWORD* usagestats_out) {
27 // presubmit: allow wstring
28 std::wstring client_state = base::StringPrintf(kOmahaClientStateKeyFormat,
29 state_key,
30 remoting::kHostOmahaAppid);
31 base::win::RegKey key;
32 LONG result = key.Open(HKEY_LOCAL_MACHINE, client_state.c_str(), KEY_READ);
33 if (result != ERROR_SUCCESS) {
34 return result;
35 }
36
37 return key.ReadValueDW(kOmahaUsagestatsValue, usagestats_out);
38 }
39
40 } // namespace
41
42 namespace remoting {
43
GetUsageStatsConsent(bool * allowed,bool * set_by_policy)44 bool GetUsageStatsConsent(bool* allowed, bool* set_by_policy) {
45 // TODO(alexeypa): report whether the consent is set by policy once
46 // supported.
47 *set_by_policy = false;
48
49 // The user's consent to collect crash dumps is recored as the "usagestats"
50 // value in the ClientState or ClientStateMedium key. Probe
51 // the ClientStateMedium key first.
52 DWORD value = 0;
53 if (ReadUsageStatsValue(kOmahaClientStateMedium, &value) == ERROR_SUCCESS) {
54 *allowed = value != 0;
55 return true;
56 }
57 if (ReadUsageStatsValue(kOmahaClientState, &value) == ERROR_SUCCESS) {
58 *allowed = value != 0;
59 return true;
60 }
61
62 // We do not log the error code here because the logging hasn't been
63 // initialized yet.
64 return false;
65 }
66
IsUsageStatsAllowed()67 bool IsUsageStatsAllowed() {
68 bool allowed;
69 bool set_by_policy;
70 return GetUsageStatsConsent(&allowed, &set_by_policy) && allowed;
71 }
72
SetUsageStatsConsent(bool allowed)73 bool SetUsageStatsConsent(bool allowed) {
74 DWORD value = allowed;
75 // presubmit: allow wstring
76 std::wstring client_state = base::StringPrintf(kOmahaClientStateKeyFormat,
77 kOmahaClientStateMedium,
78 kHostOmahaAppid);
79 base::win::RegKey key;
80 LONG result = key.Create(HKEY_LOCAL_MACHINE, client_state.c_str(),
81 KEY_SET_VALUE);
82 if (result == ERROR_SUCCESS) {
83 result = key.WriteValue(kOmahaUsagestatsValue, value);
84 if (result == ERROR_SUCCESS) {
85 return true;
86 }
87 }
88
89 LOG_GETLASTERROR(ERROR)
90 << "Failed to record the user's consent to crash dump reporting";
91 return false;
92 }
93
94 } // namespace remoting
95