Add simple KillProc function
authorAndre Heinecke <aheinecke@intevation.de>
Mon, 29 Feb 2016 14:50:21 +0000 (15:50 +0100)
committerAndre Heinecke <aheinecke@intevation.de>
Mon, 29 Feb 2016 14:50:21 +0000 (15:50 +0100)
* src/desktopshellrun.cpp, src/exdll.h (ERRORPRINTF),
 (acp_to_wchar): Move from destkopshellrun to exdll.h
* src/g4wihelp.c (KillProc): New. Kill processes.

src/desktopshellrun.cpp
src/exdll.h
src/g4wihelp.c

index 76c4992..4ef8a9e 100644 (file)
@@ -47,13 +47,6 @@ __CRT_UUID_DECL(IShellFolderViewDual,  0xe7a1af80, 0x4d96,
 #endif
 
 #define UNUSED(x) (void)(x)
-#define ERRORPRINTF(fmt, ...) \
-  { \
-    char buf[512]; \
-    snprintf(buf, 511, "ERROR: " fmt, ##__VA_ARGS__); \
-    buf[511] = '\0'; \
-    OutputDebugStringA(buf); \
-  }
 
 /** @brief the actual execuation call on the shell dispatcher
  *
@@ -115,37 +108,6 @@ shellexecute(IShellDispatch2 *disp, wchar_t *fName, wchar_t *param)
   return true;
 }
 
-wchar_t
-*acp_to_wchar (const char *string, size_t len)
-{
-  int n, ilen;
-  wchar_t *result;
-
-  ilen = (int) len;
-  if (ilen < 0)
-    return NULL;
-
-  n = MultiByteToWideChar (CP_ACP, 0, string, ilen, NULL, 0);
-  if (n < 0 || n + 1 < 0)
-    return NULL;
-
-  result = (wchar_t *) malloc ((size_t)(n+1) * sizeof *result);
-  if (!result)
-    {
-      ERRORPRINTF("Out of core");
-      exit(1);
-    }
-  n = MultiByteToWideChar (CP_ACP, 0, string, ilen, result, n);
-  if (n < 0)
-    {
-      if (result)
-        free (result);
-      return NULL;
-    }
-  result[n] = 0;
-  return result;
-}
-
 #ifdef __cplusplus
 extern "C" {
 #endif
index a32ed20..0c36f28 100644 (file)
@@ -146,6 +146,44 @@ setuservariable(const int varnum, const char *var)
     lstrcpy(g_variables + varnum*g_stringsize, var);
 }
 
+#define ERRORPRINTF(fmt, ...) \
+  { \
+    char buf[512]; \
+    snprintf(buf, 511, "ERROR: " fmt, ##__VA_ARGS__); \
+    buf[511] = '\0'; \
+    OutputDebugStringA(buf); \
+  }
+
+static wchar_t
+*acp_to_wchar (const char *string, size_t len)
+{
+  int n, ilen;
+  wchar_t *result;
+
+  ilen = (int) len;
+  if (ilen < 0)
+    return NULL;
+
+  n = MultiByteToWideChar (CP_ACP, 0, string, ilen, NULL, 0);
+  if (n < 0 || n + 1 < 0)
+    return NULL;
+
+  result = (wchar_t *) malloc ((size_t)(n+1) * sizeof *result);
+  if (!result)
+    {
+      ERRORPRINTF("Out of core");
+      exit(1);
+    }
+  n = MultiByteToWideChar (CP_ACP, 0, string, ilen, result, n);
+  if (n < 0)
+    {
+      if (result)
+        free (result);
+      return NULL;
+    }
+  result[n] = 0;
+  return result;
+}
 
 
 #endif//_EXDLL_H_
index 7cb0679..dd2bc83 100644 (file)
@@ -1,6 +1,7 @@
 /* g4wihelp.c - NSIS Helper DLL used with gpg4win. -*- coding: latin-1; -*-
  * Copyright (C) 2005 g10 Code GmbH
  * Copyright (C) 2001 Justin Frankel
+ * Copyright (C) 2016 Intevation GmbH
  *
  * This software is provided 'as-is', without any express or implied
  * warranty. In no event will the authors be held liable for any
@@ -30,6 +31,8 @@
 
 #include <windows.h>
 #include <stdio.h>
+#include <tlhelp32.h>
+#include <psapi.h>
 #include "exdll.h"
 
 static HINSTANCE g_hInstance; /* Our Instance. */
@@ -1133,3 +1136,65 @@ path_remove (HWND hwndParent, int string_size, char *variables,
 
   setuservariable (INST_R0, "1");
 }
+
+/** @brief Kill processes with the name name.
+ *
+ * This function tries to kill a process using ExitProcess.
+ *
+ * If it does not work it does not work. No return values.
+ * The intention is to make an effort to kill something during
+ * installation / uninstallation.
+ *
+ * The function signature is explained by NSIS.
+ */
+void __declspec(dllexport) __cdecl KillProc(HWND hwndParent,
+                                            int string_size,
+                                            char *variables,
+                                            stack_t **stacktop)
+{
+  HANDLE h;
+  PROCESSENTRY32 pe32;
+
+  if (!stacktop || !*stacktop || !(*stacktop)->text)
+    {
+      ERRORPRINTF ("Invalid call to KillProc.");
+      return;
+    }
+
+
+  h = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0);
+  if (h == INVALID_HANDLE_VALUE)
+    {
+      ERRORPRINTF ("Failed to create Toolhelp snapshot");
+      return;
+    }
+  pe32.dwSize = sizeof (PROCESSENTRY32);
+
+  if (!Process32First (h, &pe32))
+    {
+      ERRORPRINTF ("Failed to get first process");
+      CloseHandle (h);
+      return;
+    }
+
+  do
+    {
+      if (!strcmp ((*stacktop)->text, pe32.szExeFile))
+        {
+          HANDLE hProc = OpenProcess (PROCESS_ALL_ACCESS, FALSE,
+                                      pe32.th32ProcessID);
+          if (!hProc)
+            {
+              ERRORPRINTF ("Failed to open process handle.");
+              continue;
+            }
+          if (!TerminateProcess (hProc, 1))
+            {
+              ERRORPRINTF ("Failed to terminate process.");
+            }
+          CloseHandle (hProc);
+        }
+    }
+  while (Process32Next (h, &pe32));
+  CloseHandle (h);
+}