1// 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" 10#include "base/win/scoped_handle.h" 11#include "remoting/host/logging.h" 12 13namespace { 14 15// "--help" or "--?" prints the usage message. 16const char kHelpSwitchName[] = "help"; 17const char kQuestionSwitchName[] = "?"; 18 19const char kUsageMessage[] = 20 "\n" 21 "Usage: %s <pid>\n" 22 "\n" 23 " pid - PID of the process to be crashed.\n"; 24 25// Exit codes: 26const int kSuccessExitCode = 0; 27const int kUsageExitCode = 1; 28const int kErrorExitCode = 2; 29 30void usage(const char* program_name) { 31 fprintf(stderr, kUsageMessage, program_name); 32} 33 34} // namespace 35 36int main(int argc, char** argv) { 37 base::CommandLine::Init(argc, argv); 38 39 base::AtExitManager exit_manager; 40 41 remoting::InitHostLogging(); 42 43 const base::CommandLine* command_line = 44 base::CommandLine::ForCurrentProcess(); 45 if (command_line->HasSwitch(kHelpSwitchName) || 46 command_line->HasSwitch(kQuestionSwitchName)) { 47 usage(argv[0]); 48 return kSuccessExitCode; 49 } 50 51 base::CommandLine::StringVector args = command_line->GetArgs(); 52 if (args.size() != 1) { 53 usage(argv[0]); 54 return kUsageExitCode; 55 } 56 57 int pid = _wtoi(args[0].c_str()); 58 if (pid == 0) { 59 LOG(ERROR) << "Invalid process PID: " << args[0]; 60 return kErrorExitCode; 61 } 62 63 DWORD desired_access = PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | 64 PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ; 65 base::win::ScopedHandle process; 66 process.Set(OpenProcess(desired_access, FALSE, pid)); 67 if (!process.IsValid()) { 68 PLOG(ERROR) << "Failed to open the process " << pid; 69 return kErrorExitCode; 70 } 71 72 DWORD thread_id; 73 base::win::ScopedHandle thread; 74 thread.Set(CreateRemoteThread(process.Get(), NULL, 0, NULL, NULL, 0, 75 &thread_id)); 76 if (!thread.IsValid()) { 77 PLOG(ERROR) << "Failed to create a remote thread in " << pid; 78 return kErrorExitCode; 79 } 80 81 return kSuccessExitCode; 82} 83