Browse Source

ENH: Adding native windows process tree kill to ProcessWin32.c. This replaces the ProcessWin32Kill.c implementation.

Brad King 21 years ago
parent
commit
6c4ab7ec52

+ 0 - 2
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)

+ 403 - 5
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);
+    }
+}

+ 0 - 453
Source/kwsys/ProcessWin32Kill.c

@@ -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;
-}

+ 0 - 46
Source/kwsys/ProcessWin32Kill.h.in

@@ -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