1// Copyright (c) 2010 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// Implementation of wrapper around common crash reporting.
6
7#include "chrome_frame/chrome_frame_reporting.h"
8
9#include "base/basictypes.h"
10#include "base/file_util.h"
11#include "base/file_version_info.h"
12#include "base/win/win_util.h"
13#include "chrome/installer/util/google_update_settings.h"
14#include "chrome/installer/util/install_util.h"
15#include "chrome_frame/crash_reporting/crash_report.h"
16#include "chrome_frame/exception_barrier.h"
17#include "chrome_frame/utils.h"
18
19extern "C" IMAGE_DOS_HEADER __ImageBase;
20
21namespace {
22
23// Well known SID for the system principal.
24const wchar_t kSystemPrincipalSid[] = L"S-1-5-18";
25const wchar_t kChromePipeName[] = L"\\\\.\\pipe\\ChromeCrashServices";
26
27// Returns the custom info structure based on the dll in parameter
28google_breakpad::CustomClientInfo* GetCustomInfo(const wchar_t* dll_path) {
29  std::wstring product;
30  std::wstring version;
31  scoped_ptr<FileVersionInfo> version_info(
32      FileVersionInfo::CreateFileVersionInfo(base::FilePath(dll_path)));
33  if (version_info.get()) {
34    version = version_info->product_version();
35    product = version_info->product_short_name();
36  }
37
38  if (version.empty())
39    version = L"0.1.0.0";
40
41  if (product.empty())
42    product = L"ChromeFrame";
43
44  static google_breakpad::CustomInfoEntry ver_entry(L"ver", version.c_str());
45  static google_breakpad::CustomInfoEntry prod_entry(L"prod", product.c_str());
46  static google_breakpad::CustomInfoEntry plat_entry(L"plat", L"Win32");
47  static google_breakpad::CustomInfoEntry type_entry(L"ptype", L"chrome_frame");
48  static google_breakpad::CustomInfoEntry entries[] = {
49      ver_entry, prod_entry, plat_entry, type_entry };
50  static google_breakpad::CustomClientInfo custom_info = {
51      entries, arraysize(entries) };
52  return &custom_info;
53}
54
55bool InitializeCrashReporting() {
56  // In headless mode we want crashes to be reported back.
57  bool always_take_dump = IsHeadlessMode();
58  // We want to use the Google Update crash reporting. We need to check if the
59  // user allows it first.
60  if (!always_take_dump && !GoogleUpdateSettings::GetCollectStatsConsent())
61    return true;
62
63  // If we got here, we want to report crashes, so make sure all
64  // ExceptionBarrierBase instances do so.
65  ExceptionBarrierConfig::set_enabled(true);
66
67  // Get the alternate dump directory. We use the temp path.
68  base::FilePath temp_directory;
69  if (!base::GetTempDir(&temp_directory) || temp_directory.empty())
70    return false;
71
72  wchar_t dll_path[MAX_PATH * 2] = {0};
73  GetModuleFileName(reinterpret_cast<HMODULE>(&__ImageBase), dll_path,
74                    arraysize(dll_path));
75
76  if (always_take_dump) {
77    return InitializeVectoredCrashReportingWithPipeName(
78        true, kChromePipeName, temp_directory.value(), GetCustomInfo(dll_path));
79  }
80
81  // Build the pipe name. It can be either:
82  // System-wide install: "NamedPipe\GoogleCrashServices\S-1-5-18"
83  // Per-user install: "NamedPipe\GoogleCrashServices\<user SID>"
84  std::wstring user_sid;
85  if (InstallUtil::IsPerUserInstall(dll_path)) {
86    if (!base::win::GetUserSidString(&user_sid))
87      return false;
88  } else {
89    user_sid = kSystemPrincipalSid;
90  }
91
92  return InitializeVectoredCrashReporting(
93      false, user_sid.c_str(), temp_directory.value(), GetCustomInfo(dll_path));
94}
95
96bool ShutdownCrashReporting() {
97  ExceptionBarrierConfig::set_enabled(false);
98  return ShutdownVectoredCrashReporting();
99}
100
101}  // namespace
102
103namespace chrome_frame {
104
105void CrashReportingTraits::Initialize() {
106  InitializeCrashReporting();
107}
108
109void CrashReportingTraits::Shutdown() {
110  ShutdownCrashReporting();
111}
112
113}  // namespace chrome_frame
114