summaryrefslogtreecommitdiffstats
path: root/Source/kwsys/ProcessWin32Kill.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/kwsys/ProcessWin32Kill.cxx')
-rw-r--r--Source/kwsys/ProcessWin32Kill.cxx446
1 files changed, 0 insertions, 446 deletions
diff --git a/Source/kwsys/ProcessWin32Kill.cxx b/Source/kwsys/ProcessWin32Kill.cxx
deleted file mode 100644
index 3afe14a..0000000
--- a/Source/kwsys/ProcessWin32Kill.cxx
+++ /dev/null
@@ -1,446 +0,0 @@
-/*=========================================================================
-
- Program: KWSys - Kitware System Library
- Module: $RCSfile$
-
- Copyright (c) Kitware, Inc., Insight Consortium. All rights reserved.
- See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even
- the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- PURPOSE. See the above copyright notices for more information.
-
-=========================================================================*/
-#define KWSYS_IN_PROCESS_C
-#include "kwsysPrivate.h"
-#include KWSYS_HEADER(ProcessWin32Kill.h)
-
-/* The following process tree kill implementation is taken from
- http://www.alexfedotov.com/articles/killproc.asp
- It will work only on some versions of windows. Hopefully
- I will eventually get some time to do a real implementation of this
- for all windows versions. */
-
-#include <windows.h>
-#include <tchar.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <tlhelp32.h>
-
-//---------------------------------------------------------------------------
-// KillProcess
-//
-// Terminates the specified process.
-//
-// Parameters:
-// dwProcessId - identifier of the process to terminate
-//
-// Returns:
-// TRUE, if successful, FALSE - otherwise.
-//
-static BOOL
-WINAPI
-KillProcess(
- IN DWORD dwProcessId
- )
-{
- HANDLE hProcess;
- DWORD dwError;
-
- // first try to obtain handle to the process without the use of any
- // additional privileges
- hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, dwProcessId);
- if (hProcess == NULL)
- {
- if (GetLastError() != ERROR_ACCESS_DENIED)
- return FALSE;
-
- OSVERSIONINFO osvi;
-
- // determine operating system version
- osvi.dwOSVersionInfoSize = sizeof(osvi);
- GetVersionEx(&osvi);
-
- // we cannot do anything else if this is not Windows NT
- if (osvi.dwPlatformId != VER_PLATFORM_WIN32_NT)
- return SetLastError(ERROR_ACCESS_DENIED), FALSE;
-
- // enable SE_DEBUG_NAME privilege and try again
-
- TOKEN_PRIVILEGES Priv, PrivOld;
- DWORD cbPriv = sizeof(PrivOld);
- HANDLE hToken;
-
- // obtain the token of the current thread
- if (!OpenThreadToken(GetCurrentThread(),
- TOKEN_QUERY|TOKEN_ADJUST_PRIVILEGES,
- FALSE, &hToken))
- {
- if (GetLastError() != ERROR_NO_TOKEN)
- return FALSE;
-
- // revert to the process token
- if (!OpenProcessToken(GetCurrentProcess(),
- TOKEN_QUERY|TOKEN_ADJUST_PRIVILEGES,
- &hToken))
- return FALSE;
- }
-
- if(!(ANYSIZE_ARRAY > 0))
- {
- return 0;
- }
-
- Priv.PrivilegeCount = 1;
- Priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
- LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &Priv.Privileges[0].Luid);
-
- // try to enable the privilege
- if (!AdjustTokenPrivileges(hToken, FALSE, &Priv, sizeof(Priv),
- &PrivOld, &cbPriv))
- {
- dwError = GetLastError();
- CloseHandle(hToken);
- return SetLastError(dwError), FALSE;
- }
-
- if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
- {
- // the SE_DEBUG_NAME privilege is not present in the caller's
- // token
- CloseHandle(hToken);
- return SetLastError(ERROR_ACCESS_DENIED), FALSE;
- }
-
- // try to open process handle again
- hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, dwProcessId);
- dwError = GetLastError();
-
- // restore the original state of the privilege
- AdjustTokenPrivileges(hToken, FALSE, &PrivOld, sizeof(PrivOld),
- NULL, NULL);
- CloseHandle(hToken);
-
- if (hProcess == NULL)
- return SetLastError(FALSE), NULL;
- }
-
- // terminate the process
- if (!TerminateProcess(hProcess, (UINT)-1))
- {
- dwError = GetLastError();
- CloseHandle(hProcess);
- return SetLastError(dwError), FALSE;
- }
-
- CloseHandle(hProcess);
-
- // completed successfully
- return TRUE;
-}
-
-typedef LONG NTSTATUS;
-typedef LONG KPRIORITY;
-
-#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
-
-#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
-
-#define SystemProcessesAndThreadsInformation 5
-
-typedef struct _CLIENT_ID {
- DWORD UniqueProcess;
- DWORD UniqueThread;
-} CLIENT_ID;
-
-typedef struct _UNICODE_STRING {
- USHORT Length;
- USHORT MaximumLength;
- PWSTR Buffer;
-} UNICODE_STRING;
-
-typedef struct _VM_COUNTERS {
- SIZE_T PeakVirtualSize;
- SIZE_T VirtualSize;
- ULONG PageFaultCount;
- SIZE_T PeakWorkingSetSize;
- SIZE_T WorkingSetSize;
- SIZE_T QuotaPeakPagedPoolUsage;
- SIZE_T QuotaPagedPoolUsage;
- SIZE_T QuotaPeakNonPagedPoolUsage;
- SIZE_T QuotaNonPagedPoolUsage;
- SIZE_T PagefileUsage;
- SIZE_T PeakPagefileUsage;
-} VM_COUNTERS;
-
-typedef struct _SYSTEM_THREADS {
- LARGE_INTEGER KernelTime;
- LARGE_INTEGER UserTime;
- LARGE_INTEGER CreateTime;
- ULONG WaitTime;
- PVOID StartAddress;
- CLIENT_ID ClientId;
- KPRIORITY Priority;
- KPRIORITY BasePriority;
- ULONG ContextSwitchCount;
- LONG State;
- LONG WaitReason;
-} SYSTEM_THREADS, * PSYSTEM_THREADS;
-
-// Note that the size of the SYSTEM_PROCESSES structure is different on
-// NT 4 and Win2K, but we don't care about it, since we don't access neither
-// IoCounters member nor Threads array
-
-typedef struct _SYSTEM_PROCESSES {
- ULONG NextEntryDelta;
- ULONG ThreadCount;
- ULONG Reserved1[6];
- LARGE_INTEGER CreateTime;
- LARGE_INTEGER UserTime;
- LARGE_INTEGER KernelTime;
- UNICODE_STRING ProcessName;
- KPRIORITY BasePriority;
- ULONG ProcessId;
- ULONG InheritedFromProcessId;
- ULONG HandleCount;
- ULONG Reserved2[2];
- VM_COUNTERS VmCounters;
-#if _WIN32_WINNT >= 0x500
- IO_COUNTERS IoCounters;
-#endif
- SYSTEM_THREADS Threads[1];
-} SYSTEM_PROCESSES, * PSYSTEM_PROCESSES;
-
-//---------------------------------------------------------------------------
-// KillProcessTreeNtHelper
-//
-// This is a recursive helper function that terminates all the processes
-// started by the specified process and them terminates the process itself
-//
-// Parameters:
-// pInfo - processes information
-// dwProcessId - identifier of the process to terminate
-//
-// Returns:
-// Win32 error code.
-//
-static
-BOOL
-WINAPI
-KillProcessTreeNtHelper(
- IN PSYSTEM_PROCESSES pInfo,
- IN DWORD dwProcessId
- )
-{
- if(!pInfo)
- {
- return 0;
- }
-
- PSYSTEM_PROCESSES p = pInfo;
-
- // kill all children first
- for (;;)
- {
- if (p->InheritedFromProcessId == dwProcessId)
- KillProcessTreeNtHelper(pInfo, p->ProcessId);
-
- if (p->NextEntryDelta == 0)
- break;
-
- // find the address of the next process structure
- p = (PSYSTEM_PROCESSES)(((LPBYTE)p) + p->NextEntryDelta);
- }
-
- // kill the process itself
- if (!KillProcess(dwProcessId))
- return GetLastError();
-
- return ERROR_SUCCESS;
-}
-
-//---------------------------------------------------------------------------
-// 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"));
- if(!hKernel)
- {
- return 0;
- }
-
- // 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;
-}
-
-//---------------------------------------------------------------------------
-// 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.
-//
-static 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"));
- if(!hNtDll)
- {
- return 0;
- }
-
- // 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;
-}
-
-extern "C" {
-int kwsysProcessWin32Kill(int pid)
-{
- return KillProcessEx(pid, 1)? 1:0;
-}
-}