// Copyright 2022 The Crashpad Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <string.h>

#include "base/check.h"
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/notreached.h"
#include "client/crashpad_client.h"
#include "util/misc/paths.h"

#include <Windows.h>

// We set up a program that crashes with a CFG exception so must be built and
// linked with /guard:cf. We register the crashpad runtime exception helper
// module to intercept and trigger the crashpad handler. Note that Windows only
// loads the module in WerFault after the crash for Windows 10 >= 20h1 (19041).
namespace crashpad {
namespace {

// This function should not be on our stack as CFG prevents the modified
// icall from happening.
int CallRffeManyTimes() {
  RaiseFailFastException(nullptr, nullptr, 0);
  RaiseFailFastException(nullptr, nullptr, 0);
  RaiseFailFastException(nullptr, nullptr, 0);
  RaiseFailFastException(nullptr, nullptr, 0);
  return 1;
}

using FuncType = decltype(&CallRffeManyTimes);
void IndirectCall(FuncType* func) {
  // This code always generates CFG guards.
  (*func)();
}

void CfgCrash() {
  // Call into the middle of the Crashy function.
  FuncType func = reinterpret_cast<FuncType>(
      (reinterpret_cast<uintptr_t>(CallRffeManyTimes)) + 16);
  __try {
    // Generates a STATUS_STACK_BUFFER_OVERRUN exception if CFG triggers.
    IndirectCall(&func);
  } __except (EXCEPTION_EXECUTE_HANDLER) {
    // CFG fast fail should never be caught.
    NOTREACHED();
  }
  // Should only reach here if CFG is disabled.
  abort();
}

void FastFailCrash() {
  __fastfail(77);
}

int CrashyMain(int argc, wchar_t* argv[]) {
  static CrashpadClient* client = new crashpad::CrashpadClient();

  std::wstring type;
  if (argc == 3) {
    type = argv[2];
    // We call this from end_to_end_test.py.
    if (!client->SetHandlerIPCPipe(argv[1])) {
      LOG(ERROR) << "SetHandler";
      return EXIT_FAILURE;
    }
  } else if (argc == 4) {
    type = argv[3];
    // This is helpful for debugging.
    if (!client->StartHandler(base::FilePath(argv[1]),
                              base::FilePath(argv[2]),
                              base::FilePath(),
                              std::string(),
                              std::map<std::string, std::string>(),
                              std::vector<std::string>(),
                              false,
                              true)) {
      LOG(ERROR) << "StartHandler";
      return EXIT_FAILURE;
    }
    // Got to have a handler & registration.
    if (!client->WaitForHandlerStart(10000)) {
      LOG(ERROR) << "Handler failed to start";
      return EXIT_FAILURE;
    }
  } else {
    fprintf(stderr, "Usage: %ls <server_pipe_name> [cf|ff]\n", argv[0]);
    fprintf(
        stderr, "       %ls <handler_path> <database_path> [cf|ff]\n", argv[0]);
    return EXIT_FAILURE;
  }

  base::FilePath exe_path;
  if (!Paths::Executable(&exe_path)) {
    LOG(ERROR) << "Failed getting path";
    return EXIT_FAILURE;
  }

  // Find the module.
  auto mod_path = exe_path.DirName().Append(L"crashpad_wer.dll");

  // Make sure it is registered in the registry.
  DWORD dwOne = 1;
  LSTATUS reg_res =
      RegSetKeyValueW(HKEY_CURRENT_USER,
                      L"Software\\Microsoft\\Windows\\Windows Error Reporting\\"
                      L"RuntimeExceptionHelperModules",
                      mod_path.value().c_str(),
                      REG_DWORD,
                      &dwOne,
                      sizeof(DWORD));
  if (reg_res != ERROR_SUCCESS) {
    LOG(ERROR) << "RegSetKeyValueW";
    return EXIT_FAILURE;
  }

  if (!client->RegisterWerModule(mod_path.value())) {
    LOG(ERROR) << "WerRegisterRuntimeExceptionModule";
    return EXIT_FAILURE;
  }

  // Some versions of python call SetErrorMode() which extends to children, and
  // prevents the WerFault infrastructure from running.
  SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);

  if (type == L"cf")
    CfgCrash();
  if (type == L"ff")
    FastFailCrash();

  LOG(ERROR) << "Invalid type or exception failed.";
  return EXIT_FAILURE;
}

}  // namespace
}  // namespace crashpad

int wmain(int argc, wchar_t* argv[]) {
  return crashpad::CrashyMain(argc, argv);
}
