// Copyright 2014 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_elf/chrome_elf_util.h"

#include <assert.h>
#include <windows.h>
#include <stddef.h>

#include "base/macros.h"
#include "base/strings/string16.h"

ProcessType g_process_type = ProcessType::UNINITIALIZED;

namespace {

const wchar_t kRegPathClientState[] = L"Software\\Google\\Update\\ClientState";
const wchar_t kRegPathClientStateMedium[] =
    L"Software\\Google\\Update\\ClientStateMedium";
#if defined(GOOGLE_CHROME_BUILD)
const wchar_t kRegPathChromePolicy[] = L"SOFTWARE\\Policies\\Google\\Chrome";
#else
const wchar_t kRegPathChromePolicy[] = L"SOFTWARE\\Policies\\Chromium";
#endif  // defined(GOOGLE_CHROME_BUILD)

const wchar_t kRegValueUsageStats[] = L"usagestats";
const wchar_t kUninstallArgumentsField[] = L"UninstallArguments";
const wchar_t kMetricsReportingEnabled[] =L"MetricsReportingEnabled";

const wchar_t kAppGuidCanary[] =
    L"{4ea16ac7-fd5a-47c3-875b-dbf4a2008c20}";
const wchar_t kAppGuidGoogleChrome[] =
    L"{8A69D345-D564-463c-AFF1-A69D9E530F96}";
const wchar_t kAppGuidGoogleBinaries[] =
    L"{4DC8B4CA-1BDA-483e-B5FA-D3C12E15B62D}";

bool ReadKeyValueString(bool system_install, const wchar_t* key_path,
                        const wchar_t* guid, const wchar_t* value_to_read,
                        base::string16* value_out) {
  HKEY key = NULL;
  value_out->clear();

  base::string16 full_key_path(key_path);
  full_key_path.append(1, L'\\');
  full_key_path.append(guid);

  if (::RegOpenKeyEx(system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER,
                     full_key_path.c_str(), 0,
                     KEY_QUERY_VALUE | KEY_WOW64_32KEY, &key) !=
                     ERROR_SUCCESS) {
    return false;
  }

  const size_t kMaxStringLength = 1024;
  wchar_t raw_value[kMaxStringLength] = {};
  DWORD size = sizeof(raw_value);
  DWORD type = REG_SZ;
  LONG result = ::RegQueryValueEx(key, value_to_read, 0, &type,
                                  reinterpret_cast<LPBYTE>(raw_value), &size);

  if (result == ERROR_SUCCESS) {
    if (type != REG_SZ || (size & 1) != 0) {
      result = ERROR_NOT_SUPPORTED;
    } else if (size == 0) {
      *raw_value = L'\0';
    } else if (raw_value[size / sizeof(wchar_t) - 1] != L'\0') {
      if ((size / sizeof(wchar_t)) < kMaxStringLength)
        raw_value[size / sizeof(wchar_t)] = L'\0';
      else
        result = ERROR_MORE_DATA;
    }
  }

  if (result == ERROR_SUCCESS)
    *value_out = raw_value;

  ::RegCloseKey(key);

  return result == ERROR_SUCCESS;
}

bool ReadKeyValueDW(bool system_install, const wchar_t* key_path,
                    base::string16 guid, const wchar_t* value_to_read,
                    DWORD* value_out) {
  HKEY key = NULL;
  *value_out = 0;

  base::string16 full_key_path(key_path);
  full_key_path.append(1, L'\\');
  full_key_path.append(guid);

  if (::RegOpenKeyEx(system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER,
                     full_key_path.c_str(), 0,
                     KEY_QUERY_VALUE | KEY_WOW64_32KEY, &key) !=
                     ERROR_SUCCESS) {
    return false;
  }

  DWORD size = sizeof(*value_out);
  DWORD type = REG_DWORD;
  LONG result = ::RegQueryValueEx(key, value_to_read, 0, &type,
                                  reinterpret_cast<BYTE*>(value_out), &size);

  ::RegCloseKey(key);

  return result == ERROR_SUCCESS && size == sizeof(*value_out);
}

}  // namespace

bool IsCanary(const wchar_t* exe_path) {
  return wcsstr(exe_path, L"Chrome SxS\\Application") != NULL;
}

bool IsSystemInstall(const wchar_t* exe_path) {
  wchar_t program_dir[MAX_PATH] = {};
  DWORD ret = ::GetEnvironmentVariable(L"PROGRAMFILES", program_dir,
                                       arraysize(program_dir));
  if (ret && ret < MAX_PATH && !wcsncmp(exe_path, program_dir, ret))
    return true;

  ret = ::GetEnvironmentVariable(L"PROGRAMFILES(X86)", program_dir,
                                 arraysize(program_dir));
  if (ret && ret < MAX_PATH && !wcsncmp(exe_path, program_dir, ret))
    return true;

  return false;
}

bool IsMultiInstall(bool is_system_install) {
  base::string16 args;
  if (!ReadKeyValueString(is_system_install, kRegPathClientState,
                          kAppGuidGoogleChrome, kUninstallArgumentsField,
                          &args)) {
    return false;
  }
  return args.find(L"--multi-install") != base::string16::npos;
}

bool AreUsageStatsEnabled(const wchar_t* exe_path) {
  bool enabled = true;
  bool controlled_by_policy = ReportingIsEnforcedByPolicy(&enabled);

  if (controlled_by_policy && !enabled)
    return false;

  bool system_install = IsSystemInstall(exe_path);
  base::string16 app_guid;

  if (IsCanary(exe_path)) {
    app_guid = kAppGuidCanary;
  } else {
    app_guid = IsMultiInstall(system_install) ? kAppGuidGoogleBinaries :
                                                kAppGuidGoogleChrome;
  }

  DWORD out_value = 0;
  if (system_install &&
      ReadKeyValueDW(system_install, kRegPathClientStateMedium, app_guid,
                     kRegValueUsageStats, &out_value)) {
    return out_value == 1;
  }

  return ReadKeyValueDW(system_install, kRegPathClientState, app_guid,
                        kRegValueUsageStats, &out_value) && out_value == 1;
}

bool ReportingIsEnforcedByPolicy(bool* breakpad_enabled) {
  HKEY key = NULL;
  DWORD value = 0;
  BYTE* value_bytes = reinterpret_cast<BYTE*>(&value);
  DWORD size = sizeof(value);
  DWORD type = REG_DWORD;

  if (::RegOpenKeyEx(HKEY_LOCAL_MACHINE, kRegPathChromePolicy, 0,
                     KEY_QUERY_VALUE, &key) == ERROR_SUCCESS) {
    if (::RegQueryValueEx(key, kMetricsReportingEnabled, 0, &type,
                          value_bytes, &size) == ERROR_SUCCESS) {
      *breakpad_enabled = value != 0;
    }
    ::RegCloseKey(key);
    return size == sizeof(value);
  }

  if (::RegOpenKeyEx(HKEY_CURRENT_USER, kRegPathChromePolicy, 0,
                     KEY_QUERY_VALUE, &key) == ERROR_SUCCESS) {
    if (::RegQueryValueEx(key, kMetricsReportingEnabled, 0, &type,
                          value_bytes, &size) == ERROR_SUCCESS) {
      *breakpad_enabled = value != 0;
    }
    ::RegCloseKey(key);
    return size == sizeof(value);
  }

  return false;
}

void InitializeProcessType() {
  assert(g_process_type == ProcessType::UNINITIALIZED);
  typedef bool (*IsSandboxedProcessFunc)();
  IsSandboxedProcessFunc is_sandboxed_process_func =
      reinterpret_cast<IsSandboxedProcessFunc>(
          GetProcAddress(GetModuleHandle(NULL), "IsSandboxedProcess"));
  if (is_sandboxed_process_func && is_sandboxed_process_func()) {
    g_process_type = ProcessType::NON_BROWSER_PROCESS;
    return;
  }

  // TODO(robertshield): Drop the command line check when we drop support for
  // enabling chrome_elf in unsandboxed processes.
  const wchar_t* command_line = GetCommandLine();
  if (command_line && wcsstr(command_line, L"--type")) {
    g_process_type = ProcessType::NON_BROWSER_PROCESS;
    return;
  }

  g_process_type = ProcessType::BROWSER_PROCESS;
}

bool IsNonBrowserProcess() {
  assert(g_process_type != ProcessType::UNINITIALIZED);
  return g_process_type == ProcessType::NON_BROWSER_PROCESS;
}
