15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/host/usage_stats_consent.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <windows.h>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
115e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/stringprintf.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/registry.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/host/win/omaha.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The following strings are used to construct the registry key names where
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// we record whether the user has consented to crash dump collection.
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the user's consent to collect crash dumps is recorded.
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t kOmahaClientStateKeyFormat[] =
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    L"Software\\Google\\Update\\%ls\\%ls";
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t kOmahaClientState[] = L"ClientState";
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t kOmahaClientStateMedium[] = L"ClientStateMedium";
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t kOmahaUsagestatsValue[] = L"usagestats";
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LONG ReadUsageStatsValue(const wchar_t* state_key, DWORD* usagestats_out) {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // presubmit: allow wstring
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::wstring client_state = base::StringPrintf(kOmahaClientStateKeyFormat,
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                 state_key,
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                 remoting::kHostOmahaAppid);
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::win::RegKey key;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LONG result = key.Open(HKEY_LOCAL_MACHINE, client_state.c_str(), KEY_READ);
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result != ERROR_SUCCESS) {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return result;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return key.ReadValueDW(kOmahaUsagestatsValue, usagestats_out);
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace remoting {
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GetUsageStatsConsent(bool* allowed, bool* set_by_policy) {
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(alexeypa): report whether the consent is set by policy once
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // supported.
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *set_by_policy = false;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The user's consent to collect crash dumps is recored as the "usagestats"
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // value in the ClientState or ClientStateMedium key. Probe
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the ClientStateMedium key first.
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DWORD value = 0;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (ReadUsageStatsValue(kOmahaClientStateMedium, &value) == ERROR_SUCCESS) {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *allowed = value != 0;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (ReadUsageStatsValue(kOmahaClientState, &value) == ERROR_SUCCESS) {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *allowed = value != 0;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We do not log the error code here because the logging hasn't been
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // initialized yet.
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsUsageStatsAllowed() {
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool allowed;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool set_by_policy;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetUsageStatsConsent(&allowed, &set_by_policy) && allowed;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SetUsageStatsConsent(bool allowed) {
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DWORD value = allowed;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // presubmit: allow wstring
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::wstring client_state = base::StringPrintf(kOmahaClientStateKeyFormat,
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                 kOmahaClientStateMedium,
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                 kHostOmahaAppid);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::win::RegKey key;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LONG result = key.Create(HKEY_LOCAL_MACHINE, client_state.c_str(),
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           KEY_SET_VALUE);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result == ERROR_SUCCESS) {
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result = key.WriteValue(kOmahaUsagestatsValue, value);
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (result == ERROR_SUCCESS) {
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  PLOG(ERROR) << "Failed to record the user's consent to crash dump reporting";
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace remoting
94