Home | History | Annotate | Download | only in tools
      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