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