// 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 "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;
}
