blob: 273cf6c5ff6183aa6258109ae30c28d8d5632ddb [file] [log] [blame]
[email protected]e89298d2012-07-27 05:01:291// 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 <windows.h>
6#include <stdlib.h>
7
8#include "base/at_exit.h"
9#include "base/command_line.h"
[email protected]e89298d2012-07-27 05:01:2910#include "base/win/scoped_handle.h"
[email protected]bc825c0b2012-10-18 01:59:2911#include "remoting/host/logging.h"
[email protected]e89298d2012-07-27 05:01:2912
13namespace {
14
15// "--help" or "--?" prints the usage message.
16const char kHelpSwitchName[] = "help";
17const char kQuestionSwitchName[] = "?";
18
19const char kUsageMessage[] =
joedow900ad0c2017-04-20 21:31:1720 "\n"
21 "Usage: %s <pid>\n"
22 "\n"
23 " pid - PID of the process to be crashed.\n"
24 "\n\n"
25 "Note: You may need to run this tool as SYSTEM\n"
26 " to prevent access denied errors.\n";
[email protected]e89298d2012-07-27 05:01:2927
28// Exit codes:
29const int kSuccessExitCode = 0;
30const int kUsageExitCode = 1;
31const int kErrorExitCode = 2;
32
33void usage(const char* program_name) {
34 fprintf(stderr, kUsageMessage, program_name);
35}
36
37} // namespace
38
39int main(int argc, char** argv) {
[email protected]b982d512014-05-23 09:42:0240 base::CommandLine::Init(argc, argv);
[email protected]e89298d2012-07-27 05:01:2941
42 base::AtExitManager exit_manager;
43
[email protected]bc825c0b2012-10-18 01:59:2944 remoting::InitHostLogging();
[email protected]e89298d2012-07-27 05:01:2945
[email protected]b982d512014-05-23 09:42:0246 const base::CommandLine* command_line =
47 base::CommandLine::ForCurrentProcess();
[email protected]e89298d2012-07-27 05:01:2948 if (command_line->HasSwitch(kHelpSwitchName) ||
49 command_line->HasSwitch(kQuestionSwitchName)) {
50 usage(argv[0]);
51 return kSuccessExitCode;
52 }
53
[email protected]b982d512014-05-23 09:42:0254 base::CommandLine::StringVector args = command_line->GetArgs();
[email protected]e89298d2012-07-27 05:01:2955 if (args.size() != 1) {
56 usage(argv[0]);
57 return kUsageExitCode;
58 }
59
60 int pid = _wtoi(args[0].c_str());
61 if (pid == 0) {
62 LOG(ERROR) << "Invalid process PID: " << args[0];
63 return kErrorExitCode;
64 }
65
66 DWORD desired_access = PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION |
67 PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ;
68 base::win::ScopedHandle process;
69 process.Set(OpenProcess(desired_access, FALSE, pid));
70 if (!process.IsValid()) {
[email protected]ad8cfa92014-05-21 20:06:2371 PLOG(ERROR) << "Failed to open the process " << pid;
[email protected]e89298d2012-07-27 05:01:2972 return kErrorExitCode;
73 }
74
75 DWORD thread_id;
76 base::win::ScopedHandle thread;
77 thread.Set(CreateRemoteThread(process.Get(), NULL, 0, NULL, NULL, 0,
78 &thread_id));
79 if (!thread.IsValid()) {
[email protected]ad8cfa92014-05-21 20:06:2380 PLOG(ERROR) << "Failed to create a remote thread in " << pid;
[email protected]e89298d2012-07-27 05:01:2981 return kErrorExitCode;
82 }
83
84 return kSuccessExitCode;
85}