示例#1
0
static void kill_process_tree( DWORD const pid, HANDLE const process )
{
    HANDLE const process_snapshot_h = CreateToolhelp32Snapshot(
        TH32CS_SNAPPROCESS, 0 );
    if ( INVALID_HANDLE_VALUE != process_snapshot_h )
    {
        BOOL ok = TRUE;
        PROCESSENTRY32 pinfo;
        pinfo.dwSize = sizeof( PROCESSENTRY32 );
        for (
            ok = Process32First( process_snapshot_h, &pinfo );
            ok == TRUE;
            ok = Process32Next( process_snapshot_h, &pinfo ) )
        {
            if ( pinfo.th32ParentProcessID == pid )
            {
                /* Found a child, recurse to kill it and anything else below it.
                 */
                HANDLE const ph = OpenProcess( PROCESS_ALL_ACCESS, FALSE,
                    pinfo.th32ProcessID );
                if ( ph )
                {
                    kill_process_tree( pinfo.th32ProcessID, ph );
                    CloseHandle( ph );
                }
            }
        }
        CloseHandle( process_snapshot_h );
    }
    /* Now that the children are all dead, kill the root. */
    TerminateProcess( process, -2 );
}
示例#2
0
static int try_kill_one()
{
    /* Only need to check if a timeout was specified with the -l option. */
    if ( globs.timeout > 0 )
    {
        int i;
        for ( i = 0; i < globs.jobs; ++i )
            if ( cmdtab[ i ].pi.hProcess )
            {
                double const t = running_time( cmdtab[ i ].pi.hProcess );
                if ( t > (double)globs.timeout )
                {
                    /* The job may have left an alert dialog around, try and get
                     * rid of it before killing the job itself.
                     */
                    close_alert( &cmdtab[ i ].pi );
                    /* We have a "runaway" job, kill it. */
                    kill_process_tree( cmdtab[ i ].pi.dwProcessId,
                        cmdtab[ i ].pi.hProcess );
                    /* And return its running commands table slot. */
                    return i;
                }
            }
    }
    return -1;
}
示例#3
0
文件: execnt.c 项目: 4ukuta/core
static int try_kill_one()
{
    /* Only need to check if a timeout was specified with the -l option. */
    if ( globs.timeout > 0 )
    {
        int i;
        for ( i = 0; i < globs.jobs; ++i )
        {
            double t = running_time( cmdtab[ i ].pi.hProcess );
            if ( t > (double)globs.timeout )
            {
                /* The job may have left an alert dialog around, try and get rid
                 * of it before killing
                 */
                close_alert( cmdtab[ i ].pi.hProcess );
                /* We have a "runaway" job, kill it. */
                kill_process_tree( 0, cmdtab[ i ].pi.hProcess );
                /* And return it marked as a timeout. */
                cmdtab[ i ].exit_reason = EXIT_TIMEOUT;
                return i;
            }
        }
    }
    return -1;
}
void cprocess_tree::kill_process_tree(_In_ process& root)
{
	process_map::iterator its = _proc_map.begin();
	process_map::iterator ite = _proc_map.end();
	for (; its != ite; ++its)
	{
		if (its->second.pid() != 0 &&
			its->second.ppid() == root.pid() &&
			its->second.creation_time() >= root.creation_time())
		{
			kill_process_tree(its->second);
		}
	}

	root.kill(0);
}
bool cprocess_tree::kill_process_tree(_In_ DWORD root_pid)
{
	if (root_pid == 0 || root_pid == 4) return false;

	process_map::iterator it = _proc_map.find(root_pid);
	if (it == _proc_map.end()) return true;
	process root = it->second;

	
	if (true == root.killed())
	{
		printf("already killed. pid = %u, %ws\n", root.pid(), root.process_name().c_str());
			return true;
	}


	kill_process_tree(root);

	return true;
}
示例#6
0
文件: hook.cpp 项目: Heather/nssm
static unsigned long WINAPI await_hook(void *arg) {
  hook_t *hook = (hook_t *) arg;
  if (! hook) return NSSM_HOOK_STATUS_ERROR;

  int ret = 0;
  if (WaitForSingleObject(hook->process_handle, hook->deadline) == WAIT_TIMEOUT) ret = NSSM_HOOK_STATUS_TIMEOUT;

  /* Tidy up hook process tree. */
  if (hook->name) hook->k.name = hook->name;
  else hook->k.name = _T("hook");
  hook->k.process_handle = hook->process_handle;
  hook->k.pid = hook->pid;
  hook->k.stop_method = ~0;
  hook->k.kill_console_delay = NSSM_KILL_CONSOLE_GRACE_PERIOD;
  hook->k.kill_window_delay = NSSM_KILL_WINDOW_GRACE_PERIOD;
  hook->k.kill_threads_delay = NSSM_KILL_THREADS_GRACE_PERIOD;
  hook->k.creation_time = hook->creation_time;
  GetSystemTimeAsFileTime(&hook->k.exit_time);
  kill_process_tree(&hook->k, hook->pid);

  if (ret) {
    CloseHandle(hook->process_handle);
    if (hook->name) HeapFree(GetProcessHeap(), 0, hook->name);
    HeapFree(GetProcessHeap(), 0, hook);
    return ret;
  }

  unsigned long exitcode;
  GetExitCodeProcess(hook->process_handle, &exitcode);
  CloseHandle(hook->process_handle);

  if (hook->name) HeapFree(GetProcessHeap(), 0, hook->name);
  HeapFree(GetProcessHeap(), 0, hook);

  if (exitcode == NSSM_HOOK_STATUS_ABORT) return NSSM_HOOK_STATUS_ABORT;
  if (exitcode) return NSSM_HOOK_STATUS_FAILED;

  return NSSM_HOOK_STATUS_SUCCESS;
}
示例#7
0
/* Callback function triggered when the server exits */
void CALLBACK end_service(void *arg, unsigned char why) {
  if (stopping) return;

  stopping = true;

  pid = (unsigned long) arg;

  /* Check exit code */
  unsigned long exitcode = 0;
  char code[16];
  FILETIME exit_time;
  GetExitCodeProcess(process_handle, &exitcode);
  if (exitcode == STILL_ACTIVE || get_process_exit_time(process_handle, &exit_time)) GetSystemTimeAsFileTime(&exit_time);
  CloseHandle(process_handle);

  /*
    Log that the service ended BEFORE logging about killing the process
    tree.  See below for the possible values of the why argument.
  */
  if (! why) {
    _snprintf(code, sizeof(code), "%d", exitcode);
    log_event(EVENTLOG_INFORMATION_TYPE, NSSM_EVENT_ENDED_SERVICE, exe, service_name, code, 0);
  }

  /* Clean up. */
  kill_process_tree(service_name, pid, exitcode, pid, &creation_time, &exit_time);

  /*
    The why argument is true if our wait timed out or false otherwise.
    Our wait is infinite so why will never be true when called by the system.
    If it is indeed true, assume we were called from stop_service() because
    this is a controlled shutdown, and don't take any restart action.
  */
  if (why) return;

  /* What action should we take? */
  int action = NSSM_EXIT_RESTART;
  unsigned char action_string[ACTION_LEN];
  bool default_action;
  if (! get_exit_action(service_name, &exitcode, action_string, &default_action)) {
    for (int i = 0; exit_action_strings[i]; i++) {
      if (! _strnicmp((const char *) action_string, exit_action_strings[i], ACTION_LEN)) {
        action = i;
        break;
      }
    }
  }

  process_handle = 0;
  pid = 0;
  switch (action) {
    /* Try to restart the service or return failure code to service manager */
    case NSSM_EXIT_RESTART:
      log_event(EVENTLOG_INFORMATION_TYPE, NSSM_EVENT_EXIT_RESTART, service_name, code, exit_action_strings[action], exe, 0);
      while (monitor_service()) {
        log_event(EVENTLOG_WARNING_TYPE, NSSM_EVENT_RESTART_SERVICE_FAILED, exe, service_name, 0);
        Sleep(30000);
      }
    break;

    /* Do nothing, just like srvany would */
    case NSSM_EXIT_IGNORE:
      log_event(EVENTLOG_INFORMATION_TYPE, NSSM_EVENT_EXIT_IGNORE, service_name, code, exit_action_strings[action], exe, 0);
      Sleep(INFINITE);
    break;

    /* Tell the service manager we are finished */
    case NSSM_EXIT_REALLY:
      log_event(EVENTLOG_INFORMATION_TYPE, NSSM_EVENT_EXIT_REALLY, service_name, code, exit_action_strings[action], 0);
      stop_service(exitcode, true, default_action);
    break;

    /* Fake a crash so pre-Vista service managers will run recovery actions. */
    case NSSM_EXIT_UNCLEAN:
      log_event(EVENTLOG_INFORMATION_TYPE, NSSM_EVENT_EXIT_UNCLEAN, service_name, code, exit_action_strings[action], 0);
      exit(stop_service(exitcode, false, default_action));
    break;
  }
}