diff options
Diffstat (limited to 'Source/kwsys/ProcessWin32Kill.cxx')
-rw-r--r-- | Source/kwsys/ProcessWin32Kill.cxx | 446 |
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; -} -} |