예제 #1
0
//---------------------------------------------------------------------------
// KillProcessTreeWinHelper
//
//  This is a recursive helper function that terminates all the processes
//  started by the specified process and them terminates the process itself
//
//  Parameters:
//	  dwProcessId - identifier of the process to terminate
//
//  Returns:
//	  Win32 error code.
//
BOOL WINAPI KillProcessTreeWinHelper(DWORD dwProcessId) {
	// create a snapshot
	auto_handle hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	if (!hSnapshot)
		return GetLastError();

	auto_localmem<PROCESSENTRY32*> pEntry = ::LocalAlloc(LMEM_FIXED|LMEM_ZEROINIT,sizeof(PROCESSENTRY32));

	pEntry->dwSize = sizeof(PROCESSENTRY32);
	if (!Process32First(hSnapshot, pEntry))
	{
		return GetLastError();
	}

	// kill all children first
	do
	{
		// there was a report of infinite recursion, so watching out for the obvious self-loop possibility
		DWORD pid = pEntry->th32ProcessID;
		if (pEntry->th32ParentProcessID == dwProcessId && dwProcessId!=pid)
			KillProcessTreeWinHelper(pid);
	}
	while (Process32Next(hSnapshot, pEntry));

	// kill the process itself
    if (!KillProcess(dwProcessId))
		return GetLastError();

	return ERROR_SUCCESS;
}
예제 #2
0
//---------------------------------------------------------------------------
// KillProcessEx
//
//  Terminates the specified process and, optionally, all processes started
//	from the specified process (the so-called process tree).
//
//  Parameters:
//	  dwProcessId - identifier of the process to terminate
//	  bTree		  - specifies whether the entire process tree should be
//					terminated
//
//  Returns:
//	  TRUE, if successful, FALSE - otherwise.
//
BOOL
WINAPI
KillProcessEx
(
 IN DWORD dwProcessId,
 IN BOOL bTree
)
{
  if (!bTree)
    return KillProcess(dwProcessId);

  OSVERSIONINFO osvi;
  DWORD dwError;

  // determine operating system version
  osvi.dwOSVersionInfoSize = sizeof(osvi);
  GetVersionEx(&osvi);

  if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT &&
      osvi.dwMajorVersion < 5)
    {
      HINSTANCE hNtDll;
      NTSTATUS (WINAPI * _ZwQuerySystemInformation)(UINT, PVOID, ULONG, PULONG);

      // get handle to NTDLL.DLL
      hNtDll = GetModuleHandle(_T("ntdll.dll"));
      // _ASSERTE(hNtDll != NULL);

      // find the address of ZwQuerySystemInformation
      *(FARPROC *)&_ZwQuerySystemInformation =
        GetProcAddress(hNtDll, "ZwQuerySystemInformation");
      if (_ZwQuerySystemInformation == NULL)
        return SetLastError(ERROR_PROC_NOT_FOUND), NULL;

      // obtain a handle to the default process heap
      HANDLE hHeap = GetProcessHeap();
    
      NTSTATUS Status;
      ULONG cbBuffer = 0x8000;
      PVOID pBuffer = NULL;

      // it is difficult to say a priory which size of the buffer 
      // will be enough to retrieve all information, so we start
      // with 32K buffer and increase its size until we get the
      // information successfully
      do
        {
          pBuffer = HeapAlloc(hHeap, 0, cbBuffer);
          if (pBuffer == NULL)
            return SetLastError(ERROR_NOT_ENOUGH_MEMORY), FALSE;

          Status = _ZwQuerySystemInformation(
                                             SystemProcessesAndThreadsInformation,
                                             pBuffer, cbBuffer, NULL);

          if (Status == STATUS_INFO_LENGTH_MISMATCH)
            {
              HeapFree(hHeap, 0, pBuffer);
              cbBuffer *= 2;
            }
          else if (!NT_SUCCESS(Status))
            {
              HeapFree(hHeap, 0, pBuffer);
              return SetLastError(Status), NULL;
            }
        }
      while (Status == STATUS_INFO_LENGTH_MISMATCH);

      // call the helper function
      dwError = KillProcessTreeNtHelper((PSYSTEM_PROCESSES)pBuffer, 
                                        dwProcessId);
		
      HeapFree(hHeap, 0, pBuffer);
    }
  else
    {
      // call the helper function
      dwError = KillProcessTreeWinHelper(dwProcessId);
    }

  SetLastError(dwError);
  return dwError == ERROR_SUCCESS;
}
예제 #3
0
//---------------------------------------------------------------------------
// KillProcessTreeWinHelper
//
//  This is a recursive helper function that terminates all the processes
//  started by the specified process and them terminates the process itself
//
//  Parameters:
//	  dwProcessId - identifier of the process to terminate
//
//  Returns:
//	  Win32 error code.
//
static
BOOL
WINAPI
KillProcessTreeWinHelper
(
 IN DWORD dwProcessId
)
{
  HINSTANCE hKernel;
  HANDLE (WINAPI * _CreateToolhelp32Snapshot)(DWORD, DWORD);
  BOOL (WINAPI * _Process32First)(HANDLE, PROCESSENTRY32 *);
  BOOL (WINAPI * _Process32Next)(HANDLE, PROCESSENTRY32 *);

  // get handle to KERNEL32.DLL
  hKernel = GetModuleHandle(_T("kernel32.dll"));
  //  _ASSERTE(hKernel != NULL);

  // locate necessary functions in KERNEL32.DLL
  *(FARPROC *)&_CreateToolhelp32Snapshot =
    GetProcAddress(hKernel, "CreateToolhelp32Snapshot");
  *(FARPROC *)&_Process32First =
    GetProcAddress(hKernel, "Process32First");
  *(FARPROC *)&_Process32Next =
    GetProcAddress(hKernel, "Process32Next");

  if (_CreateToolhelp32Snapshot == NULL ||
      _Process32First == NULL ||
      _Process32Next == NULL)
    return ERROR_PROC_NOT_FOUND;

  HANDLE hSnapshot;
  PROCESSENTRY32 Entry;

  // create a snapshot
  hSnapshot = _CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  if (hSnapshot == INVALID_HANDLE_VALUE)
    return GetLastError();

  Entry.dwSize = sizeof(Entry);
  if (!_Process32First(hSnapshot, &Entry))
    {
      DWORD dwError = GetLastError();
      CloseHandle(hSnapshot);
      return dwError;
    }

  // kill all children first
  do
    {
      if (Entry.th32ParentProcessID == dwProcessId)
        KillProcessTreeWinHelper(Entry.th32ProcessID);

      Entry.dwSize = sizeof(Entry);
    }
  while (_Process32Next(hSnapshot, &Entry));

  CloseHandle(hSnapshot);

  // kill the process itself
  if (!KillProcess(dwProcessId))
    return GetLastError();

  return ERROR_SUCCESS;
}
예제 #4
0
파일: winp.cpp 프로젝트: fabioz/winp
//---------------------------------------------------------------------------
// KillProcessEx
//
//  Terminates the specified process and, optionally, all processes started
//	from the specified process (the so-called process tree).
//
//  Parameters:
//	  dwProcessId - identifier of the process to terminate
//	  bTree		  - specifies whether the entire process tree should be
//					terminated
//
//  Returns:
//	  TRUE, if successful, FALSE - otherwise.
//
BOOL WINAPI KillProcessEx(DWORD dwProcessId, BOOL bTree) {
	if (!bTree) {
		return KillProcess(dwProcessId);
	}

	OSVERSIONINFO osvi;
	DWORD dwError;

	// determine operating system version
	osvi.dwOSVersionInfoSize = sizeof(osvi);
	GetVersionEx(&osvi);

	if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT &&
		osvi.dwMajorVersion < 5)
	{
		// obtain a handle to the default process heap
		HANDLE hHeap = GetProcessHeap();

		NTSTATUS Status;
		ULONG cbBuffer = 0x8000;
		PVOID pBuffer = NULL;

		// it is difficult to say a priory which size of the buffer
		// will be enough to retrieve all information, so we start
		// with 32K buffer and increase its size until we get the
		// information successfully
		do
		{
			pBuffer = HeapAlloc(hHeap, 0, cbBuffer);
			if (pBuffer == NULL) {
				return SetLastError(ERROR_NOT_ENOUGH_MEMORY), FALSE;
			}

			Status = ZwQuerySystemInformation(
							SystemProcessesAndThreadsInformation,
							pBuffer, cbBuffer, NULL);

			if (Status == STATUS_INFO_LENGTH_MISMATCH)
			{
				HeapFree(hHeap, 0, pBuffer);
				cbBuffer *= 2;
			}
			else if (!NT_SUCCESS(Status))
			{
				HeapFree(hHeap, 0, pBuffer);
				return SetLastError(Status), NULL;
			}
		}
		while (Status == STATUS_INFO_LENGTH_MISMATCH);

		// call the helper function
		dwError = KillProcessTreeNtHelper((PSYSTEM_PROCESSES)pBuffer,
										  dwProcessId);

		HeapFree(hHeap, 0, pBuffer);
	}
	else
	{
		// call the helper function
		dwError = KillProcessTreeWinHelper(dwProcessId);
	}

	SetLastError(dwError);
	return dwError == ERROR_SUCCESS;
}