// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <windows.h>
#include <stdlib.h>
#include "base/at_exit.h"
#include "base/command_line.h"
#include "base/win/scoped_handle.h"
#include "remoting/base/logging.h"
namespace {
// "--help" or "--?" prints the usage message.
const char kHelpSwitchName[] = "help";
const char kQuestionSwitchName[] = "?";
const char kUsageMessage[] =
"\n"
"Usage: %s <pid>\n"
"\n"
" pid - PID of the process to be crashed.\n"
"\n\n"
"Note: You may need to run this tool as SYSTEM\n"
" to prevent access denied errors.\n";
// Exit codes:
const int kSuccessExitCode = 0;
const int kUsageExitCode = 1;
const int kErrorExitCode = 2;
void usage(const char* program_name) {
fprintf(stderr, kUsageMessage, program_name);
}
} // namespace
int main(int argc, char** argv) {
base::CommandLine::Init(argc, argv);
base::AtExitManager exit_manager;
remoting::InitHostLogging();
const base::CommandLine* command_line =
base::CommandLine::ForCurrentProcess();
if (command_line->HasSwitch(kHelpSwitchName) ||
command_line->HasSwitch(kQuestionSwitchName)) {
usage(argv[0]);
return kSuccessExitCode;
}
base::CommandLine::StringVector args = command_line->GetArgs();
if (args.size() != 1) {
usage(argv[0]);
return kUsageExitCode;
}
int pid = _wtoi(args[0].c_str());
if (pid == 0) {
LOG(ERROR) << "Invalid process PID: " << args[0];
return kErrorExitCode;
}
DWORD desired_access = PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION |
PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ;
base::win::ScopedHandle process;
process.Set(OpenProcess(desired_access, FALSE, pid));
if (!process.IsValid()) {
PLOG(ERROR) << "Failed to open the process " << pid;
return kErrorExitCode;
}
DWORD thread_id;
base::win::ScopedHandle thread;
thread.Set(CreateRemoteThread(process.Get(), NULL, 0, NULL, NULL, 0,
&thread_id));
if (!thread.IsValid()) {
PLOG(ERROR) << "Failed to create a remote thread in " << pid;
return kErrorExitCode;
}
return kSuccessExitCode;
}