// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/credential_provider/gaiacp/gcp_crash_reporting_utils.h"
#include <winerror.h>
#include <string>
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/win/registry.h"
#include "build/branding_buildflags.h"
#include "chrome/credential_provider/common/gcp_strings.h"
#include "chrome/credential_provider/gaiacp/gcp_crash_reporter_client.h"
#include "chrome/credential_provider/gaiacp/logging.h"
#include "components/crash/core/common/crash_key.h"
#include "components/crash/core/common/crash_keys.h"
namespace {
constexpr wchar_t kCrashpadDumpsFolder[] = L"GCPW Crashpad";
#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
void SetCurrentVersionCrashKey() {
static crash_reporter::CrashKeyString<32> version_key("current-version");
version_key.Clear();
base::win::RegKey key(HKEY_LOCAL_MACHINE,
credential_provider::kRegUpdaterClientsAppPath,
KEY_QUERY_VALUE | KEY_WOW64_32KEY);
// Read from the Clients key.
std::wstring version_str;
if (key.ReadValue(L"pv", &version_str) == ERROR_SUCCESS) {
version_key.Set(base::WideToUTF8(version_str));
}
}
#endif // BUILDFLAG(GOOGLE_CHROME_BRANDING)
// Returns the SYSTEM version of TEMP. We do this instead of GetTempPath so
// that both elevated and SYSTEM runs share the same directory.
base::FilePath GetSystemTempFolder() {
base::win::RegKey reg_key(
HKEY_LOCAL_MACHINE,
L"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment",
KEY_QUERY_VALUE);
std::wstring temp_string;
if (reg_key.ReadValue(L"TEMP", &temp_string) != ERROR_SUCCESS)
return base::FilePath();
return base::FilePath(temp_string);
}
} // namespace
namespace credential_provider {
void InitializeGcpwCrashReporting(GcpCrashReporterClient* crash_client) {
crash_reporter::SetCrashReporterClient(crash_client);
base::FilePath crash_dir = GetFolderForCrashDumps();
if (crash_dir.empty() ||
(!base::PathExists(crash_dir) && !base::CreateDirectory(crash_dir))) {
HRESULT hr = HRESULT_FROM_WIN32(::GetLastError());
if (hr != HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS)) {
LOGFN(ERROR) << "Failed to create directory for crash dumps: "
<< crash_dir << " hr=" << putHR(hr);
}
}
}
base::FilePath GetFolderForCrashDumps() {
base::FilePath system_temp_dir = GetSystemTempFolder();
if (system_temp_dir.empty())
// Failed to get a temp dir, something's gone wrong.
return system_temp_dir;
return system_temp_dir.Append(kCrashpadDumpsFolder);
}
void SetCommonCrashKeys(const base::CommandLine& command_line) {
#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
SetCurrentVersionCrashKey();
crash_keys::SetSwitchesFromCommandLine(command_line, nullptr);
#endif
}
bool GetGCPWCollectStatsConsent() {
#if !BUILDFLAG(GOOGLE_CHROME_BRANDING)
return false;
#else
// This value is provided by Omaha during install based on how the installer
// is tagged. The installer is tagged based on the consent checkbox found
// on the download page.
//
// This value can also be changed after install by running the setup
// program with --enable-stats or --disable-stats.
//
// This consent is different from chrome's consent in that each products
// stores the consent in its own part of the registry.
DWORD collect_stats = 0;
base::win::RegKey key(HKEY_LOCAL_MACHINE,
credential_provider::kRegUpdaterClientStateAppPath,
KEY_QUERY_VALUE | KEY_WOW64_32KEY);
key.ReadValueDW(kRegUsageStatsName, &collect_stats);
return collect_stats == 1;
#endif // BUILDFLAG(GOOGLE_CHROME_BRANDING)
}
} // namespace credential_provider