Module: wine
Branch: master
Commit: df4359b117acd7466ed7d9bed61e3bed713b5c45
URL: http://source.winehq.org/git/wine.git/?a=commit;h=df4359b117acd7466ed7d9bed…
Author: Andrew Nguyen <anguyen(a)codeweavers.com>
Date: Tue Sep 21 02:18:41 2010 -0500
taskkill: Implement graceful termination by process identifier.
---
programs/taskkill/En.rc | 2 +
programs/taskkill/taskkill.c | 87 +++++++++++++++++++++++++++++++++++++++++-
programs/taskkill/taskkill.h | 2 +
3 files changed, 89 insertions(+), 2 deletions(-)
diff --git a/programs/taskkill/En.rc b/programs/taskkill/En.rc
index 67b2dac..ccad885 100644
--- a/programs/taskkill/En.rc
+++ b/programs/taskkill/En.rc
@@ -31,4 +31,6 @@ STRINGTABLE
STRING_MISSING_OPTION, "Error: One of options /im or /pid must be specified.\n"
STRING_MISSING_PARAM, "Error: Option %s expects a command line parameter.\n"
STRING_MUTUAL_EXCLUSIVE, "Error: Options /im and /pid are mutually exclusive.\n"
+ STRING_CLOSE_PID_SEARCH, "Close message sent to top-level windows of process with PID %u.\n"
+ STRING_SEARCH_FAILED, "Error: Could not find process \"%s\".\n"
}
diff --git a/programs/taskkill/taskkill.c b/programs/taskkill/taskkill.c
index 0ff6385..4b9fb94 100644
--- a/programs/taskkill/taskkill.c
+++ b/programs/taskkill/taskkill.c
@@ -32,6 +32,12 @@ int force_termination;
WCHAR **task_list;
unsigned int task_count;
+struct pid_close_info
+{
+ DWORD pid;
+ BOOL found;
+};
+
static int taskkill_vprintfW(const WCHAR *msg, va_list va_args)
{
int wlen;
@@ -100,6 +106,78 @@ static int taskkill_message(int msg)
return taskkill_printfW(formatW, msg_buffer);
}
+/* Post WM_CLOSE to all top-level windows belonging to the process with specified PID. */
+static BOOL CALLBACK pid_enum_proc(HWND hwnd, LPARAM lParam)
+{
+ struct pid_close_info *info = (struct pid_close_info *)lParam;
+ DWORD hwnd_pid;
+
+ GetWindowThreadProcessId(hwnd, &hwnd_pid);
+
+ if (hwnd_pid == info->pid)
+ {
+ PostMessageW(hwnd, WM_CLOSE, 0, 0);
+ info->found = TRUE;
+ }
+
+ return TRUE;
+}
+
+/* The implemented task enumeration and termination behavior does not
+ * exactly match native behavior. On Windows:
+ *
+ * In the case of terminating by process name, specifying a particular
+ * process name more times than the number of running instances causes
+ * all instances to be terminated, but termination failure messages to
+ * be printed as many times as the difference between the specification
+ * quantity and the number of running instances.
+ *
+ * Successful terminations are all listed first in order, with failing
+ * terminations being listed at the end.
+ *
+ * A PID of zero causes taskkill to warn about the inability to terminate
+ * system processes. */
+static int send_close_messages(void)
+{
+ unsigned int i;
+ int status_code = 0;
+
+ for (i = 0; i < task_count; i++)
+ {
+ WCHAR *p = task_list[i];
+ BOOL is_numeric = TRUE;
+
+ /* Determine whether the string is not numeric. */
+ while (*p)
+ {
+ if (!isdigitW(*p++))
+ {
+ is_numeric = FALSE;
+ break;
+ }
+ }
+
+ if (is_numeric)
+ {
+ DWORD pid = atoiW(task_list[i]);
+ struct pid_close_info info = { pid };
+
+ EnumWindows(pid_enum_proc, (LPARAM)&info);
+ if (info.found)
+ taskkill_message_printfW(STRING_CLOSE_PID_SEARCH, pid);
+ else
+ {
+ taskkill_message_printfW(STRING_SEARCH_FAILED, task_list[i]);
+ status_code = 128;
+ }
+ }
+ else
+ WINE_FIXME("Termination by name is not implemented\n");
+ }
+
+ return status_code;
+}
+
static BOOL add_to_task_list(WCHAR *name)
{
static unsigned int list_size = 16;
@@ -202,14 +280,19 @@ static BOOL process_arguments(int argc, WCHAR *argv[])
int wmain(int argc, WCHAR *argv[])
{
+ int status_code = 0;
+
if (!process_arguments(argc, argv))
{
HeapFree(GetProcessHeap(), 0, task_list);
return 1;
}
- WINE_FIXME("taskkill.exe functionality is not implemented\n");
+ if (force_termination)
+ WINE_FIXME("Forced termination is not implemented\n");
+ else
+ status_code = send_close_messages();
HeapFree(GetProcessHeap(), 0, task_list);
- return 0;
+ return status_code;
}
diff --git a/programs/taskkill/taskkill.h b/programs/taskkill/taskkill.h
index 281690b..1cc09af 100644
--- a/programs/taskkill/taskkill.h
+++ b/programs/taskkill/taskkill.h
@@ -27,3 +27,5 @@
#define STRING_MISSING_OPTION 104
#define STRING_MISSING_PARAM 105
#define STRING_MUTUAL_EXCLUSIVE 106
+#define STRING_CLOSE_PID_SEARCH 107
+#define STRING_SEARCH_FAILED 108
Module: wine
Branch: master
Commit: 8e540ed26fb934999800c8d5e2c2afbeaef920a6
URL: http://source.winehq.org/git/wine.git/?a=commit;h=8e540ed26fb934999800c8d5e…
Author: Andrew Nguyen <anguyen(a)codeweavers.com>
Date: Tue Sep 21 02:17:09 2010 -0500
taskkill: Add stub implementation.
---
configure | 1 +
configure.ac | 1 +
programs/taskkill/Makefile.in | 7 +++++++
programs/taskkill/taskkill.c | 31 +++++++++++++++++++++++++++++++
4 files changed, 40 insertions(+), 0 deletions(-)
diff --git a/configure b/configure
index 58093b5..788a57a 100755
--- a/configure
+++ b/configure
@@ -15016,6 +15016,7 @@ wine_fn_config_program services enable_services install
wine_fn_config_program spoolsv enable_spoolsv install
wine_fn_config_program start enable_start install
wine_fn_config_program svchost enable_svchost install
+wine_fn_config_program taskkill enable_taskkill install
wine_fn_config_program taskmgr enable_taskmgr install
wine_fn_config_program termsv enable_termsv install
wine_fn_config_program uninstaller enable_uninstaller install
diff --git a/configure.ac b/configure.ac
index e3220ef..f279293 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2804,6 +2804,7 @@ WINE_CONFIG_PROGRAM(services,install)
WINE_CONFIG_PROGRAM(spoolsv,install)
WINE_CONFIG_PROGRAM(start,install)
WINE_CONFIG_PROGRAM(svchost,install)
+WINE_CONFIG_PROGRAM(taskkill,install)
WINE_CONFIG_PROGRAM(taskmgr,install)
WINE_CONFIG_PROGRAM(termsv,install)
WINE_CONFIG_PROGRAM(uninstaller,install)
diff --git a/programs/taskkill/Makefile.in b/programs/taskkill/Makefile.in
new file mode 100644
index 0000000..1f9c335
--- /dev/null
+++ b/programs/taskkill/Makefile.in
@@ -0,0 +1,7 @@
+EXTRADEFS = -DWINE_NO_UNICODE_MACROS
+MODULE = taskkill.exe
+APPMODE = -mconsole -municode
+
+C_SRCS = taskkill.c
+
+@MAKE_PROG_RULES@
diff --git a/programs/taskkill/taskkill.c b/programs/taskkill/taskkill.c
new file mode 100644
index 0000000..f38db0c
--- /dev/null
+++ b/programs/taskkill/taskkill.c
@@ -0,0 +1,31 @@
+/*
+ * Task termination utility
+ *
+ * Copyright 2010 Andrew Nguyen
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <windows.h>
+#include <wine/debug.h>
+#include <wine/unicode.h>
+
+WINE_DEFAULT_DEBUG_CHANNEL(taskkill);
+
+int wmain(int argc, WCHAR *argv[])
+{
+ WINE_FIXME("taskkill.exe is not implemented\n");
+ return 0;
+}