1// Copyright (c) 2012 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#include "win8/delegate_execute/crash_server_init.h"
6
7#include <shlobj.h>
8#include <windows.h>
9
10#include <cwchar>
11
12#include "base/file_version_info.h"
13#include "base/memory/scoped_ptr.h"
14#include "base/win/win_util.h"
15#include "breakpad/src/client/windows/handler/exception_handler.h"
16
17const wchar_t kGoogleUpdatePipeName[] = L"\\\\.\\pipe\\GoogleCrashServices\\";
18const wchar_t kSystemPrincipalSid[] = L"S-1-5-18";
19
20const MINIDUMP_TYPE kLargerDumpType = static_cast<MINIDUMP_TYPE>(
21    MiniDumpWithProcessThreadData |  // Get PEB and TEB.
22    MiniDumpWithUnloadedModules |  // Get unloaded modules when available.
23    MiniDumpWithIndirectlyReferencedMemory);  // Get memory referenced by stack.
24
25extern "C" IMAGE_DOS_HEADER __ImageBase;
26
27namespace {
28
29bool IsRunningSystemInstall() {
30  wchar_t exe_path[MAX_PATH * 2] = {0};
31  GetModuleFileName(reinterpret_cast<HMODULE>(&__ImageBase),
32                    exe_path,
33                    _countof(exe_path));
34
35  bool is_system = false;
36
37  wchar_t program_files_path[MAX_PATH] = {0};
38  if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PROGRAM_FILES, NULL,
39                                SHGFP_TYPE_CURRENT, program_files_path))) {
40    if (wcsstr(exe_path, program_files_path) == exe_path) {
41      is_system = true;
42    }
43  }
44
45  return is_system;
46}
47
48google_breakpad::CustomClientInfo* GetCustomInfo() {
49  scoped_ptr<FileVersionInfo> version_info(
50      FileVersionInfo::CreateFileVersionInfoForCurrentModule());
51
52  static google_breakpad::CustomInfoEntry ver_entry(
53      L"ver", version_info->file_version().c_str());
54  static google_breakpad::CustomInfoEntry prod_entry(L"prod", L"Chrome");
55  static google_breakpad::CustomInfoEntry plat_entry(L"plat", L"Win32");
56  static google_breakpad::CustomInfoEntry type_entry(L"ptype",
57                                                     L"delegate_execute");
58  static google_breakpad::CustomInfoEntry entries[] = {
59      ver_entry, prod_entry, plat_entry, type_entry };
60  static google_breakpad::CustomClientInfo custom_info = {
61      entries, ARRAYSIZE(entries) };
62  return &custom_info;
63}
64
65}  // namespace
66
67namespace delegate_execute {
68
69scoped_ptr<google_breakpad::ExceptionHandler> InitializeCrashReporting() {
70  wchar_t temp_path[MAX_PATH + 1] = {0};
71  DWORD path_len = ::GetTempPath(MAX_PATH, temp_path);
72
73  base::string16 pipe_name;
74  pipe_name = kGoogleUpdatePipeName;
75  if (IsRunningSystemInstall()) {
76    pipe_name += kSystemPrincipalSid;
77  } else {
78    base::string16 user_sid;
79    if (base::win::GetUserSidString(&user_sid)) {
80      pipe_name += user_sid;
81    } else {
82      // We don't think we're a system install, but we couldn't get the
83      // user SID. Try connecting to the system-level crash service as a
84      // last ditch effort.
85      pipe_name += kSystemPrincipalSid;
86    }
87  }
88
89  return scoped_ptr<google_breakpad::ExceptionHandler>(
90      new google_breakpad::ExceptionHandler(
91          temp_path, NULL, NULL, NULL,
92          google_breakpad::ExceptionHandler::HANDLER_ALL, kLargerDumpType,
93          pipe_name.c_str(), GetCustomInfo()));
94}
95
96}  // namespace delegate_execute
97