summaryrefslogtreecommitdiffstats
path: root/chrome_frame/chrome_launcher_main.cc
blob: e6826756136dfaa7a1320ff3879cc5025384c5e0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
// Copyright (c) 2009 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 <windows.h>
#include <DbgHelp.h>
#include <string>

#include "chrome_frame/chrome_launcher.h"
#include "breakpad/src/client/windows/handler/exception_handler.h"

// TODO(robertshield): Much of the crash report init code is shared with CF and
// probably Chrome too. If this pans out, consider refactoring it into a
// common lib.

namespace {

// Possible names for Pipes:
// Headless (testing) mode: "NamedPipe\ChromeCrashServices"
// System-wide install: "NamedPipe\GoogleCrashServices\S-1-5-18"
// Per-user install: "NamedPipe\GoogleCrashServices\<user SID>"
const wchar_t kChromePipeName[] = L"\\\\.\\pipe\\ChromeCrashServices";
const wchar_t kGoogleUpdatePipeName[] = L"\\\\.\\pipe\\GoogleCrashServices\\";
const wchar_t kSystemPrincipalSid[] = L"S-1-5-18";

// Assume this implies headless mode and use kChromePipeName if it shows
// up in the command line.
const wchar_t kFullMemoryCrashReport[] = L"full-memory-crash-report";

const MINIDUMP_TYPE kLargerDumpType = static_cast<MINIDUMP_TYPE>(
    MiniDumpWithProcessThreadData |  // Get PEB and TEB.
    MiniDumpWithUnloadedModules |  // Get unloaded modules when available.
    MiniDumpWithIndirectlyReferencedMemory);  // Get memory referenced by stack.

}  // namespace

google_breakpad::CustomClientInfo* GetCustomInfo() {
  // TODO(robertshield): Populate this with actual data.
  std::wstring product(L"ChromeFrame");
  std::wstring version(L"0.1.0.0");
  static google_breakpad::CustomInfoEntry ver_entry(L"ver", version.c_str());
  static google_breakpad::CustomInfoEntry prod_entry(L"prod", product.c_str());
  static google_breakpad::CustomInfoEntry plat_entry(L"plat", L"Win32");
  static google_breakpad::CustomInfoEntry type_entry(L"ptype", L"chrome_frame");
  static google_breakpad::CustomInfoEntry entries[] = {
      ver_entry, prod_entry, plat_entry, type_entry };
  static google_breakpad::CustomClientInfo custom_info = {
      entries, arraysize(entries) };
  return &custom_info;
}

google_breakpad::ExceptionHandler* InitializeCrashReporting(
    const wchar_t* cmd_line) {
  if (cmd_line == NULL) {
    return NULL;
  }

  wchar_t temp_path[MAX_PATH + 1] = {0};
  DWORD path_len = ::GetTempPath(MAX_PATH, temp_path);

  std::wstring pipe_name;
  if (wcsstr(cmd_line, kFullMemoryCrashReport) != NULL) {
    pipe_name = kChromePipeName;
  } else {
    // TODO(robertshield): Figure out if we're a per-user install and connect
    // to the per-user named pipe instead.
    pipe_name = kGoogleUpdatePipeName;
    pipe_name += kSystemPrincipalSid;
  }

  google_breakpad::ExceptionHandler* breakpad =
      new google_breakpad::ExceptionHandler(
          temp_path, NULL, NULL, NULL,
          google_breakpad::ExceptionHandler::HANDLER_ALL, kLargerDumpType,
          pipe_name.c_str(), GetCustomInfo());

  return breakpad;
}

int APIENTRY wWinMain(HINSTANCE, HINSTANCE, wchar_t*, int) {
  const wchar_t* cmd_line = ::GetCommandLine();

  google_breakpad::scoped_ptr<google_breakpad::ExceptionHandler> breakpad(
      InitializeCrashReporting(cmd_line));

  UINT exit_code = ERROR_FILE_NOT_FOUND;
  if (chrome_launcher::SanitizeAndLaunchChrome(::GetCommandLine())) {
    exit_code = ERROR_SUCCESS;
  }

  return exit_code;
}