summaryrefslogtreecommitdiffstats
path: root/Source/kwsys
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2004-05-10 18:54:22 (GMT)
committerBrad King <brad.king@kitware.com>2004-05-10 18:54:22 (GMT)
commit6c4ab7ec52025971d8a038eb8485d6722cbe7011 (patch)
tree813215de7559ec4f99700a88e9889815cfbfa682 /Source/kwsys
parentdd70c8f82d5101fa4ec49c379fdbbdda14fe9a3b (diff)
downloadCMake-6c4ab7ec52025971d8a038eb8485d6722cbe7011.zip
CMake-6c4ab7ec52025971d8a038eb8485d6722cbe7011.tar.gz
CMake-6c4ab7ec52025971d8a038eb8485d6722cbe7011.tar.bz2
ENH: Adding native windows process tree kill to ProcessWin32.c. This replaces the ProcessWin32Kill.c implementation.
Diffstat (limited to 'Source/kwsys')
-rw-r--r--Source/kwsys/CMakeLists.txt2
-rw-r--r--Source/kwsys/ProcessWin32.c408
-rw-r--r--Source/kwsys/ProcessWin32Kill.c453
-rw-r--r--Source/kwsys/ProcessWin32Kill.h.in46
4 files changed, 403 insertions, 506 deletions
diff --git a/Source/kwsys/CMakeLists.txt b/Source/kwsys/CMakeLists.txt
index e253027..16c73d5 100644
--- a/Source/kwsys/CMakeLists.txt
+++ b/Source/kwsys/CMakeLists.txt
@@ -274,8 +274,6 @@ IF(KWSYS_USE_Process)
SET_SOURCE_FILES_PROPERTIES(
${PROJECT_BINARY_DIR}/${KWSYS_NAMESPACE}ProcessFwd9xEnc.c
PROPERTIES GENERATED 1)
- SET(KWSYS_H_FILES ${KWSYS_H_FILES} ProcessWin32Kill)
- SET(KWSYS_SRCS ${KWSYS_SRCS} ProcessWin32Kill.c)
ELSE(NOT UNIX)
# Use the UNIX implementation.
SET(KWSYS_SRCS ${KWSYS_SRCS} ProcessUNIX.c)
diff --git a/Source/kwsys/ProcessWin32.c b/Source/kwsys/ProcessWin32.c
index cdb4e96..a184367 100644
--- a/Source/kwsys/ProcessWin32.c
+++ b/Source/kwsys/ProcessWin32.c
@@ -14,7 +14,6 @@
#define KWSYS_IN_PROCESS_C
#include "kwsysPrivate.h"
#include KWSYS_HEADER(Process.h)
-#include KWSYS_HEADER(ProcessWin32Kill.h)
/*
@@ -102,6 +101,7 @@ static int kwsysProcessTimeLess(kwsysProcessTime in1, kwsysProcessTime in2);
static kwsysProcessTime kwsysProcessTimeAdd(kwsysProcessTime in1, kwsysProcessTime in2);
static kwsysProcessTime kwsysProcessTimeSubtract(kwsysProcessTime in1, kwsysProcessTime in2);
static void kwsysProcessSetExitException(kwsysProcess* cp, int code);
+static void kwsysProcessKillTree(int pid);
extern kwsysEXPORT int kwsysEncodedWriteArrayProcessFwd9x(const char* fname);
/*--------------------------------------------------------------------------*/
@@ -1405,10 +1405,7 @@ void kwsysProcess_Kill(kwsysProcess* cp)
/* Not Windows 9x. Just terminate the children. */
for(i=0; i < cp->NumberOfCommands; ++i)
{
- if(!kwsysProcessWin32Kill(cp->ProcessInformation[i].dwProcessId))
- {
- TerminateProcess(cp->ProcessInformation[i].hProcess, 255);
- }
+ kwsysProcessKillTree(cp->ProcessInformation[i].dwProcessId);
}
}
@@ -2141,3 +2138,404 @@ static void kwsysProcessSetExitException(kwsysProcess* cp, int code)
}
#undef KWSYSPE_CASE
+typedef struct kwsysProcess_List_s kwsysProcess_List;
+static kwsysProcess_List* kwsysProcess_List_New();
+static void kwsysProcess_List_Delete(kwsysProcess_List* self);
+static int kwsysProcess_List_Update(kwsysProcess_List* self);
+static int kwsysProcess_List_NextProcess(kwsysProcess_List* self);
+static int kwsysProcess_List_GetCurrentProcessId(kwsysProcess_List* self);
+static int kwsysProcess_List_GetCurrentParentId(kwsysProcess_List* self);
+
+/*--------------------------------------------------------------------------*/
+/* Windows NT 4 API definitions. */
+#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
+typedef LONG NTSTATUS;
+typedef LONG KPRIORITY;
+typedef struct _UNICODE_STRING UNICODE_STRING;
+struct _UNICODE_STRING
+{
+ USHORT Length;
+ USHORT MaximumLength;
+ PWSTR Buffer;
+};
+
+/* The process information structure. Declare only enough to get
+ process identifiers. The rest may be ignored because we use the
+ NextEntryDelta to move through an array of instances. */
+typedef struct _SYSTEM_PROCESS_INFORMATION SYSTEM_PROCESS_INFORMATION;
+typedef SYSTEM_PROCESS_INFORMATION* PSYSTEM_PROCESS_INFORMATION;
+struct _SYSTEM_PROCESS_INFORMATION
+{
+ 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;
+};
+
+/*--------------------------------------------------------------------------*/
+/* Toolhelp32 API definitions. */
+#define TH32CS_SNAPPROCESS 0x00000002
+typedef struct tagPROCESSENTRY32 PROCESSENTRY32;
+typedef PROCESSENTRY32* LPPROCESSENTRY32;
+struct tagPROCESSENTRY32
+{
+ DWORD dwSize;
+ DWORD cntUsage;
+ DWORD th32ProcessID;
+ DWORD th32DefaultHeapID;
+ DWORD th32ModuleID;
+ DWORD cntThreads;
+ DWORD th32ParentProcessID;
+ LONG pcPriClassBase;
+ DWORD dwFlags;
+ char szExeFile[MAX_PATH];
+};
+
+/*--------------------------------------------------------------------------*/
+/* Windows API function types. */
+typedef HANDLE (WINAPI* CreateToolhelp32SnapshotType)(DWORD, DWORD);
+typedef BOOL (WINAPI* Process32FirstType)(HANDLE, LPPROCESSENTRY32);
+typedef BOOL (WINAPI* Process32NextType)(HANDLE, LPPROCESSENTRY32);
+typedef NTSTATUS (WINAPI* ZwQuerySystemInformationType)(ULONG, PVOID,
+ ULONG, PULONG);
+
+
+/*--------------------------------------------------------------------------*/
+static int kwsysProcess_List__New_NT4(kwsysProcess_List* self);
+static int kwsysProcess_List__New_Snapshot(kwsysProcess_List* self);
+static void kwsysProcess_List__Delete_NT4(kwsysProcess_List* self);
+static void kwsysProcess_List__Delete_Snapshot(kwsysProcess_List* self);
+static int kwsysProcess_List__Update_NT4(kwsysProcess_List* self);
+static int kwsysProcess_List__Update_Snapshot(kwsysProcess_List* self);
+static int kwsysProcess_List__Next_NT4(kwsysProcess_List* self);
+static int kwsysProcess_List__Next_Snapshot(kwsysProcess_List* self);
+static int kwsysProcess_List__GetProcessId_NT4(kwsysProcess_List* self);
+static int kwsysProcess_List__GetProcessId_Snapshot(kwsysProcess_List* self);
+static int kwsysProcess_List__GetParentId_NT4(kwsysProcess_List* self);
+static int kwsysProcess_List__GetParentId_Snapshot(kwsysProcess_List* self);
+
+struct kwsysProcess_List_s
+{
+ /* Implementation switches at runtime based on version of Windows. */
+ int NT4;
+
+ /* Implementation functions and data for NT 4. */
+ ZwQuerySystemInformationType P_ZwQuerySystemInformation;
+ char* Buffer;
+ int BufferSize;
+ PSYSTEM_PROCESS_INFORMATION CurrentInfo;
+
+ /* Implementation functions and data for other Windows versions. */
+ CreateToolhelp32SnapshotType P_CreateToolhelp32Snapshot;
+ Process32FirstType P_Process32First;
+ Process32NextType P_Process32Next;
+ HANDLE Snapshot;
+ PROCESSENTRY32 CurrentEntry;
+};
+
+/*--------------------------------------------------------------------------*/
+static kwsysProcess_List* kwsysProcess_List_New()
+{
+ OSVERSIONINFO osv;
+ kwsysProcess_List* self;
+
+ /* Allocate and initialize the list object. */
+ if(!(self = (kwsysProcess_List*)malloc(sizeof(kwsysProcess_List))))
+ {
+ return 0;
+ }
+ memset(self, 0, sizeof(*self));
+
+ /* Select an implementation. */
+ ZeroMemory(&osv, sizeof(osv));
+ osv.dwOSVersionInfoSize = sizeof(osv);
+ GetVersionEx(&osv);
+ self->NT4 = (osv.dwPlatformId == VER_PLATFORM_WIN32_NT &&
+ osv.dwMajorVersion < 5)? 1:0;
+
+ /* Initialize the selected implementation. */
+ if(!(self->NT4?
+ kwsysProcess_List__New_NT4(self) :
+ kwsysProcess_List__New_Snapshot(self)))
+ {
+ kwsysProcess_List_Delete(self);
+ return 0;
+ }
+
+ /* Update to the current set of processes. */
+ if(!kwsysProcess_List_Update(self))
+ {
+ kwsysProcess_List_Delete(self);
+ return 0;
+ }
+ return self;
+}
+
+/*--------------------------------------------------------------------------*/
+static void kwsysProcess_List_Delete(kwsysProcess_List* self)
+{
+ if(self)
+ {
+ if(self->NT4)
+ {
+ kwsysProcess_List__Delete_NT4(self);
+ }
+ else
+ {
+ kwsysProcess_List__Delete_Snapshot(self);
+ }
+ free(self);
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+static int kwsysProcess_List_Update(kwsysProcess_List* self)
+{
+ return self? (self->NT4?
+ kwsysProcess_List__Update_NT4(self) :
+ kwsysProcess_List__Update_Snapshot(self)) : 0;
+}
+
+/*--------------------------------------------------------------------------*/
+static int kwsysProcess_List_GetCurrentProcessId(kwsysProcess_List* self)
+{
+ return self? (self->NT4?
+ kwsysProcess_List__GetProcessId_NT4(self) :
+ kwsysProcess_List__GetProcessId_Snapshot(self)) : -1;
+
+}
+
+/*--------------------------------------------------------------------------*/
+static int kwsysProcess_List_GetCurrentParentId(kwsysProcess_List* self)
+{
+ return self? (self->NT4?
+ kwsysProcess_List__GetParentId_NT4(self) :
+ kwsysProcess_List__GetParentId_Snapshot(self)) : -1;
+
+}
+
+/*--------------------------------------------------------------------------*/
+static int kwsysProcess_List_NextProcess(kwsysProcess_List* self)
+{
+ return (self? (self->NT4?
+ kwsysProcess_List__Next_NT4(self) :
+ kwsysProcess_List__Next_Snapshot(self)) : 0);
+}
+
+/*--------------------------------------------------------------------------*/
+static int kwsysProcess_List__New_NT4(kwsysProcess_List* self)
+{
+ HANDLE hNT = GetModuleHandle("ntdll.dll");
+ if(hNT)
+ {
+ /* Get pointers to the needed API functions. */
+ self->P_ZwQuerySystemInformation =
+ ((ZwQuerySystemInformationType)
+ GetProcAddress(hNT, "ZwQuerySystemInformation"));
+ CloseHandle(hNT);
+ }
+ if(!self->P_ZwQuerySystemInformation)
+ {
+ return 0;
+ }
+
+ /* Allocate an initial process information buffer. */
+ self->BufferSize = 32768;
+ self->Buffer = (char*)malloc(self->BufferSize);
+ return self->Buffer? 1:0;
+}
+
+/*--------------------------------------------------------------------------*/
+static void kwsysProcess_List__Delete_NT4(kwsysProcess_List* self)
+{
+ /* Free the process information buffer. */
+ if(self->Buffer)
+ {
+ free(self->Buffer);
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+static int kwsysProcess_List__Update_NT4(kwsysProcess_List* self)
+{
+ self->CurrentInfo = 0;
+ while(1)
+ {
+ /* Query number 5 is for system process list. */
+ NTSTATUS status =
+ self->P_ZwQuerySystemInformation(5, self->Buffer, self->BufferSize, 0);
+ if(status == STATUS_INFO_LENGTH_MISMATCH)
+ {
+ /* The query requires a bigger buffer. */
+ int newBufferSize = self->BufferSize * 2;
+ char* newBuffer = (char*)malloc(newBufferSize);
+ if(newBuffer)
+ {
+ free(self->Buffer);
+ self->Buffer = newBuffer;
+ self->BufferSize = newBufferSize;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+ else if(status >= 0)
+ {
+ /* The query succeeded. Initialize traversal of the process list. */
+ self->CurrentInfo = (PSYSTEM_PROCESS_INFORMATION)self->Buffer;
+ return 1;
+ }
+ else
+ {
+ /* The query failed. */
+ return 0;
+ }
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+static int kwsysProcess_List__Next_NT4(kwsysProcess_List* self)
+{
+ if(self->CurrentInfo)
+ {
+ if(self->CurrentInfo->NextEntryDelta > 0)
+ {
+ self->CurrentInfo = ((PSYSTEM_PROCESS_INFORMATION)
+ ((char*)self->CurrentInfo +
+ self->CurrentInfo->NextEntryDelta));
+ return 1;
+ }
+ self->CurrentInfo = 0;
+ }
+ return 0;
+}
+
+/*--------------------------------------------------------------------------*/
+static int kwsysProcess_List__GetProcessId_NT4(kwsysProcess_List* self)
+{
+ return self->CurrentInfo? self->CurrentInfo->ProcessId : -1;
+}
+
+/*--------------------------------------------------------------------------*/
+static int kwsysProcess_List__GetParentId_NT4(kwsysProcess_List* self)
+{
+ return self->CurrentInfo? self->CurrentInfo->InheritedFromProcessId : -1;
+}
+
+/*--------------------------------------------------------------------------*/
+static int kwsysProcess_List__New_Snapshot(kwsysProcess_List* self)
+{
+ HANDLE hKernel = GetModuleHandle("kernel32.dll");
+ if(hKernel)
+ {
+ self->P_CreateToolhelp32Snapshot =
+ ((CreateToolhelp32SnapshotType)
+ GetProcAddress(hKernel, "CreateToolhelp32Snapshot"));
+ self->P_Process32First =
+ ((Process32FirstType)
+ GetProcAddress(hKernel, "Process32First"));
+ self->P_Process32Next =
+ ((Process32NextType)
+ GetProcAddress(hKernel, "Process32Next"));
+ CloseHandle(hKernel);
+ }
+ return (self->P_CreateToolhelp32Snapshot &&
+ self->P_Process32First &&
+ self->P_Process32Next)? 1:0;
+}
+
+/*--------------------------------------------------------------------------*/
+static void kwsysProcess_List__Delete_Snapshot(kwsysProcess_List* self)
+{
+ if(self->Snapshot)
+ {
+ CloseHandle(self->Snapshot);
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+static int kwsysProcess_List__Update_Snapshot(kwsysProcess_List* self)
+{
+ if(self->Snapshot)
+ {
+ CloseHandle(self->Snapshot);
+ }
+ if(!(self->Snapshot =
+ self->P_CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)))
+ {
+ return 0;
+ }
+ ZeroMemory(&self->CurrentEntry, sizeof(self->CurrentEntry));
+ self->CurrentEntry.dwSize = sizeof(self->CurrentEntry);
+ if(!self->P_Process32First(self->Snapshot, &self->CurrentEntry))
+ {
+ CloseHandle(self->Snapshot);
+ self->Snapshot = 0;
+ return 0;
+ }
+ return 1;
+}
+
+/*--------------------------------------------------------------------------*/
+static int kwsysProcess_List__Next_Snapshot(kwsysProcess_List* self)
+{
+ if(self->Snapshot)
+ {
+ if(self->P_Process32Next(self->Snapshot, &self->CurrentEntry))
+ {
+ return 1;
+ }
+ CloseHandle(self->Snapshot);
+ self->Snapshot = 0;
+ }
+ return 0;
+}
+
+/*--------------------------------------------------------------------------*/
+static int kwsysProcess_List__GetProcessId_Snapshot(kwsysProcess_List* self)
+{
+ return self->Snapshot? self->CurrentEntry.th32ProcessID : -1;
+}
+
+/*--------------------------------------------------------------------------*/
+static int kwsysProcess_List__GetParentId_Snapshot(kwsysProcess_List* self)
+{
+ return self->Snapshot? self->CurrentEntry.th32ParentProcessID : -1;
+}
+
+/*--------------------------------------------------------------------------*/
+static void kwsysProcessKill(DWORD pid)
+{
+ HANDLE h = OpenProcess(PROCESS_TERMINATE, 0, pid);
+ if(h)
+ {
+ TerminateProcess(h, 255);
+ WaitForSingleObject(h, INFINITE);
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+static void kwsysProcessKillTree(int pid)
+{
+ kwsysProcess_List* plist = kwsysProcess_List_New();
+ kwsysProcessKill(pid);
+ if(plist)
+ {
+ do
+ {
+ if(kwsysProcess_List_GetCurrentParentId(plist) == pid)
+ {
+ int ppid = kwsysProcess_List_GetCurrentProcessId(plist);
+ kwsysProcessKillTree(ppid);
+ }
+ } while(kwsysProcess_List_NextProcess(plist));
+ kwsysProcess_List_Delete(plist);
+ }
+}
diff --git a/Source/kwsys/ProcessWin32Kill.c b/Source/kwsys/ProcessWin32Kill.c
deleted file mode 100644
index 21a1bb8..0000000
--- a/Source/kwsys/ProcessWin32Kill.c
+++ /dev/null
@@ -1,453 +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)
- {
- OSVERSIONINFO osvi;
- TOKEN_PRIVILEGES Priv, PrivOld;
- DWORD cbPriv;
- HANDLE hToken;
-
- if (GetLastError() != ERROR_ACCESS_DENIED)
- return FALSE;
-
- // 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
-
- cbPriv = sizeof(PrivOld);
-
- // 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), 0;
- }
-
- }
-
- // 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
- )
-{
- PSYSTEM_PROCESSES p;
- if(!pInfo)
- {
- return 0;
- }
-
- 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 hSnapshot;
- PROCESSENTRY32 Entry;
-
- 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;
-
-
- // 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
- )
-{
- OSVERSIONINFO osvi;
- DWORD dwError;
- HANDLE hHeap;
- NTSTATUS Status;
- ULONG cbBuffer;
- PVOID pBuffer = NULL;
-
- if (!bTree)
- return KillProcess(dwProcessId);
-
-
- // 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), 0;
-
- // obtain a handle to the default process heap
- hHeap = GetProcessHeap();
-
- cbBuffer = 0x8000;
-
- // 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), 0;
- }
- }
- 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;
-}
-
-int kwsysProcessWin32Kill(int pid)
-{
- return KillProcessEx(pid, 1)? 1:0;
-}
diff --git a/Source/kwsys/ProcessWin32Kill.h.in b/Source/kwsys/ProcessWin32Kill.h.in
deleted file mode 100644
index 2243600..0000000
--- a/Source/kwsys/ProcessWin32Kill.h.in
+++ /dev/null
@@ -1,46 +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.
-
-=========================================================================*/
-#ifndef @KWSYS_NAMESPACE@_ProcessWin32Kill_h
-#define @KWSYS_NAMESPACE@_ProcessWin32Kill_h
-
-#include <@KWSYS_NAMESPACE@/Configure.h>
-
-/* Redefine all public interface symbol names to be in the proper
- namespace. These macros are used internally to kwsys only, and are
- not visible to user code. Use kwsysHeaderDump.pl to reproduce
- these macros after making changes to the interface. */
-#define kwsys_ns(x) @KWSYS_NAMESPACE@##x
-#define kwsysEXPORT @KWSYS_NAMESPACE@_EXPORT
-#define kwsysProcessWin32Kill kwsys_ns(ProcessWin32Kill)
-
-#if defined(__cplusplus)
-extern "C"
-{
-#endif
-
-kwsysEXPORT int kwsysProcessWin32Kill(int pid);
-
-#if defined(__cplusplus)
-} /* extern "C" */
-#endif
-
-/* If we are building a kwsysProcess .c file, let it use these macros.
- Otherwise, undefine them to keep the namespace clean. */
-#if !defined(KWSYS_IN_PROCESS_C)
-# undef kwsys_ns
-# undef kwsysEXPORT
-# undef kwsysProcessWin32Kill
-#endif
-
-#endif