]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/utils.cpp
wxUniversal fix.
[wxWidgets.git] / src / msw / utils.cpp
index 736a8c90af397e0879e2b74f6567fed0bb5e1d16..901aa039ed6942778303a2c7742ec53bb8995524 100644 (file)
@@ -94,6 +94,9 @@
     #endif
 #endif
 
+// For wxKillAllChildren
+#include <tlhelp32.h>
+
 // ----------------------------------------------------------------------------
 // constants
 // ----------------------------------------------------------------------------
@@ -649,8 +652,13 @@ BOOL CALLBACK wxEnumFindByPidProc(HWND hwnd, LPARAM lParam)
     return TRUE;
 }
 
-int wxKill(long pid, wxSignal sig, wxKillError *krc)
+int wxKillAllChildren(long pid, wxSignal sig, wxKillError *krc);
+
+int wxKill(long pid, wxSignal sig, wxKillError *krc, int flags)
 {
+    if (flags & wxKILL_CHILDREN)
+        wxKillAllChildren(pid, sig, krc);
+    
     // get the process handle to operate on
     HANDLE hProcess = ::OpenProcess(SYNCHRONIZE |
                                     PROCESS_TERMINATE |
@@ -805,6 +813,111 @@ int wxKill(long pid, wxSignal sig, wxKillError *krc)
     return -1;
 }
 
+HANDLE (WINAPI *lpfCreateToolhelp32Snapshot)(DWORD,DWORD) ;
+BOOL (WINAPI *lpfProcess32First)(HANDLE,LPPROCESSENTRY32) ;
+BOOL (WINAPI *lpfProcess32Next)(HANDLE,LPPROCESSENTRY32) ;
+  
+static void InitToolHelp32()
+{
+    static bool s_initToolHelpDone = false;
+    
+    if (s_initToolHelpDone)
+        return;
+    
+    s_initToolHelpDone = true;
+
+    lpfCreateToolhelp32Snapshot = NULL;
+    lpfProcess32First = NULL;
+    lpfProcess32Next = NULL;
+    
+    HINSTANCE hInstLib = LoadLibrary( wxT("Kernel32.DLL") ) ;
+    if( hInstLib == NULL )
+        return ;
+    
+    // Get procedure addresses.
+    // We are linking to these functions of Kernel32
+    // explicitly, because otherwise a module using
+    // this code would fail to load under Windows NT,
+    // which does not have the Toolhelp32
+    // functions in the Kernel 32.
+    lpfCreateToolhelp32Snapshot=
+        (HANDLE(WINAPI *)(DWORD,DWORD))
+        GetProcAddress( hInstLib,
+#ifdef __WXWINCE__
+        wxT("CreateToolhelp32Snapshot")
+#else
+        "CreateToolhelp32Snapshot"
+#endif
+        ) ;
+    
+    lpfProcess32First=
+        (BOOL(WINAPI *)(HANDLE,LPPROCESSENTRY32))
+        GetProcAddress( hInstLib,
+#ifdef __WXWINCE__
+        wxT("Process32First")
+#else
+        "Process32First"
+#endif
+        ) ;
+
+    lpfProcess32Next=
+        (BOOL(WINAPI *)(HANDLE,LPPROCESSENTRY32))
+        GetProcAddress( hInstLib,
+#ifdef __WXWINCE__
+        wxT("Process32Next")
+#else
+        "Process32Next"
+#endif
+        ) ;
+
+    FreeLibrary( hInstLib ) ;
+}
+
+// By John Skiff
+int wxKillAllChildren(long pid, wxSignal sig, wxKillError *krc)
+{
+    InitToolHelp32();
+    
+    if (krc)
+        *krc = wxKILL_OK;
+    
+    // If not implemented for this platform (e.g. NT 4.0), silently ignore
+    if (!lpfCreateToolhelp32Snapshot || !lpfProcess32First || !lpfProcess32Next)
+        return 0;
+    
+    // Take a snapshot of all processes in the system.
+    HANDLE hProcessSnap = lpfCreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
+    if (hProcessSnap == INVALID_HANDLE_VALUE) {
+        if (krc)
+            *krc = wxKILL_ERROR;
+        return -1;
+    }
+    
+    //Fill in the size of the structure before using it.
+    PROCESSENTRY32 pe = {0};
+    pe.dwSize = sizeof(PROCESSENTRY32);
+    
+    // Walk the snapshot of the processes, and for each process,
+    // kill it if its parent is pid.
+    if (!lpfProcess32First(hProcessSnap, &pe)) {
+        // Can't get first process.
+        if (krc)
+            *krc = wxKILL_ERROR;
+        CloseHandle (hProcessSnap);
+        return -1;
+    }
+    
+    do {
+        if (pe.th32ParentProcessID == (DWORD) pid) {
+            if (wxKill(pe.th32ProcessID, sig, krc))
+                return -1;
+        }
+    } while (lpfProcess32Next (hProcessSnap, &pe));
+    
+    
+    return 0;
+}
+
 // Execute a program in an Interactive Shell
 bool wxShell(const wxString& command)
 {