12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "win8/delegate_execute/crash_server_init.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <shlobj.h>
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <windows.h>
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <cwchar>
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/file_version_info.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/scoped_ptr.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/win/win_util.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "breakpad/src/client/windows/handler/exception_handler.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const wchar_t kGoogleUpdatePipeName[] = L"\\\\.\\pipe\\GoogleCrashServices\\";
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const wchar_t kSystemPrincipalSid[] = L"S-1-5-18";
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const MINIDUMP_TYPE kLargerDumpType = static_cast<MINIDUMP_TYPE>(
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MiniDumpWithProcessThreadData |  // Get PEB and TEB.
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MiniDumpWithUnloadedModules |  // Get unloaded modules when available.
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MiniDumpWithIndirectlyReferencedMemory);  // Get memory referenced by stack.
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)extern "C" IMAGE_DOS_HEADER __ImageBase;
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool IsRunningSystemInstall() {
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  wchar_t exe_path[MAX_PATH * 2] = {0};
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GetModuleFileName(reinterpret_cast<HMODULE>(&__ImageBase),
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    exe_path,
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    _countof(exe_path));
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool is_system = false;
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  wchar_t program_files_path[MAX_PATH] = {0};
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PROGRAM_FILES, NULL,
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                SHGFP_TYPE_CURRENT, program_files_path))) {
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (wcsstr(exe_path, program_files_path) == exe_path) {
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      is_system = true;
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return is_system;
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)google_breakpad::CustomClientInfo* GetCustomInfo() {
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FileVersionInfo> version_info(
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FileVersionInfo::CreateFileVersionInfoForCurrentModule());
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static google_breakpad::CustomInfoEntry ver_entry(
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      L"ver", version_info->file_version().c_str());
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static google_breakpad::CustomInfoEntry prod_entry(L"prod", L"Chrome");
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static google_breakpad::CustomInfoEntry plat_entry(L"plat", L"Win32");
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static google_breakpad::CustomInfoEntry type_entry(L"ptype",
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                     L"delegate_execute");
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static google_breakpad::CustomInfoEntry entries[] = {
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ver_entry, prod_entry, plat_entry, type_entry };
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static google_breakpad::CustomClientInfo custom_info = {
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      entries, ARRAYSIZE(entries) };
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return &custom_info;
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace delegate_execute {
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<google_breakpad::ExceptionHandler> InitializeCrashReporting() {
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  wchar_t temp_path[MAX_PATH + 1] = {0};
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DWORD path_len = ::GetTempPath(MAX_PATH, temp_path);
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::string16 pipe_name;
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  pipe_name = kGoogleUpdatePipeName;
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (IsRunningSystemInstall()) {
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    pipe_name += kSystemPrincipalSid;
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::string16 user_sid;
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (base::win::GetUserSidString(&user_sid)) {
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      pipe_name += user_sid;
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // We don't think we're a system install, but we couldn't get the
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // user SID. Try connecting to the system-level crash service as a
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // last ditch effort.
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      pipe_name += kSystemPrincipalSid;
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return scoped_ptr<google_breakpad::ExceptionHandler>(
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new google_breakpad::ExceptionHandler(
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          temp_path, NULL, NULL, NULL,
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          google_breakpad::ExceptionHandler::HANDLER_ALL, kLargerDumpType,
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          pipe_name.c_str(), GetCustomInfo()));
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace delegate_execute
97