ReactOS 0.4.16-dev-981-g80eb313
taskkill.c
Go to the documentation of this file.
1/*
2 * Task termination utility
3 *
4 * Copyright 2008 Andrew Riedi
5 * Copyright 2010 Andrew Nguyen
6 * Copyright 2020 He Yang
7 * Copyright 2025 Hermès Bélusca-Maïto
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
24#include <stdlib.h>
25#include <windows.h>
26#include <tlhelp32.h>
27#include <wine/debug.h>
28
29#ifdef __REACTOS__
30#define wcsicmp _wcsicmp
31#endif
32
33#include "taskkill.h"
34
36
39
41static unsigned int task_count;
42
43static struct
44{
48}
50static unsigned int process_count;
51
53{
56};
57
58#ifdef __REACTOS__
59unsigned int* pkill_list;
60DWORD pkill_size;
61DWORD self_pid;
62#endif
63
64#ifdef __REACTOS__
65
66static PWCHAR opList[] = {L"f", L"im", L"pid", L"?", L"t"};
67
68#define OP_PARAM_INVALID -1
69
70#define OP_PARAM_FORCE_TERMINATE 0
71#define OP_PARAM_IMAGE 1
72#define OP_PARAM_PID 2
73#define OP_PARAM_HELP 3
74#define OP_PARAM_TERMINATE_CHILD 4
75
76#endif // __REACTOS__
77
78static int taskkill_vprintfW(const WCHAR *msg, va_list va_args)
79{
80 int wlen;
82 WCHAR msg_buffer[8192];
83
84 wlen = FormatMessageW(FORMAT_MESSAGE_FROM_STRING, msg, 0, 0, msg_buffer,
85 ARRAY_SIZE(msg_buffer), &va_args);
86
87 if (!WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), msg_buffer, wlen, &count, NULL))
88 {
89 DWORD len;
90 char *msgA;
91
92 /* On Windows WriteConsoleW() fails if the output is redirected. So fall
93 * back to WriteFile() using OEM code page.
94 */
95 len = WideCharToMultiByte(GetOEMCP(), 0, msg_buffer, wlen,
96 NULL, 0, NULL, NULL);
97 msgA = malloc(len);
98 if (!msgA)
99 return 0;
100
101 WideCharToMultiByte(GetOEMCP(), 0, msg_buffer, wlen, msgA, len, NULL, NULL);
103 free(msgA);
104 }
105
106 return count;
107}
108
109static int WINAPIV taskkill_printfW(const WCHAR *msg, ...)
110{
111 va_list va_args;
112 int len;
113
114 va_start(va_args, msg);
115 len = taskkill_vprintfW(msg, va_args);
116 va_end(va_args);
117
118 return len;
119}
120
122{
123 va_list va_args;
124 WCHAR msg_buffer[8192];
125 int len;
126
127 LoadStringW(GetModuleHandleW(NULL), msg, msg_buffer, ARRAY_SIZE(msg_buffer));
128
129 va_start(va_args, msg);
130 len = taskkill_vprintfW(msg_buffer, va_args);
131 va_end(va_args);
132
133 return len;
134}
135
136static int taskkill_message(int msg)
137{
138 WCHAR msg_buffer[8192];
139
140 LoadStringW(GetModuleHandleW(NULL), msg, msg_buffer, ARRAY_SIZE(msg_buffer));
141
142 return taskkill_printfW(L"%1", msg_buffer);
143}
144
145/* Post WM_CLOSE to all top-level windows belonging to the process with specified PID. */
147{
148 struct pid_close_info *info = (struct pid_close_info *)lParam;
149 DWORD hwnd_pid;
150
151 GetWindowThreadProcessId(hwnd, &hwnd_pid);
152
153 if (hwnd_pid == info->pid)
154 {
155 PostMessageW(hwnd, WM_CLOSE, 0, 0);
156 info->found = TRUE;
157 }
158
159 return TRUE;
160}
161
163{
164 unsigned int alloc_count = 128;
165 void *realloc_list;
167
170 return FALSE;
171
173 if (!process_list)
174 return FALSE;
175
176 process_list[0].p.dwSize = sizeof(process_list[0].p);
178 return FALSE;
179
180 do
181 {
182 process_list[process_count].is_numeric = FALSE;
183 process_list[process_count++].matched = FALSE;
185 {
186 alloc_count *= 2;
187 realloc_list = realloc(process_list, alloc_count * sizeof(*process_list));
188 if (!realloc_list)
189 return FALSE;
190 process_list = realloc_list;
191 }
195 return TRUE;
196}
197
198static void mark_task_process(const WCHAR *str, int *status_code)
199{
200#ifndef __REACTOS__
201 DWORD self_pid = GetCurrentProcessId();
202#endif
203 const WCHAR *p = str;
205 unsigned int i;
206 DWORD pid;
207
209 while (*p)
210 {
211 if (!iswdigit(*p++))
212 {
214 break;
215 }
216 }
217
218 if (is_numeric)
219 {
220 pid = wcstol(str, NULL, 10);
221 for (i = 0; i < process_count; ++i)
222 {
223 if (process_list[i].p.th32ProcessID == pid)
224 break;
225 }
227 goto not_found;
228 process_list[i].matched = TRUE;
229 process_list[i].is_numeric = TRUE;
230 if (pid == self_pid)
231 {
233 *status_code = 1;
234 }
235#ifdef __REACTOS__
236 else
237 {
238 pkill_list[pkill_size++] = i;
239 }
240#endif
241 return;
242 }
243
244 for (i = 0; i < process_count; ++i)
245 {
246 if (!wcsicmp(process_list[i].p.szExeFile, str) && !process_list[i].matched)
247 {
248 process_list[i].matched = TRUE;
249 if (process_list[i].p.th32ProcessID == self_pid)
250 {
252 *status_code = 1;
253 }
254#ifdef __REACTOS__
255 else
256 {
257 pkill_list[pkill_size++] = i;
258 continue;
259 }
260#endif
261 return;
262 }
263 }
264
265#ifdef __REACTOS__
266 // Cannot find any process matching the PID or name
267 if (pkill_size == 0)
268 {
269#endif
270not_found:
272 *status_code = 128;
273#ifdef __REACTOS__
274 }
275#endif
276}
277
278static void taskkill_message_print_process(int msg, unsigned int index)
279{
280 WCHAR pid_str[16];
281
283 {
285 return;
286 }
287 wsprintfW(pid_str, L"%lu", process_list[index].p.th32ProcessID);
289}
290
291#ifndef __REACTOS__
292/*
293 * Below is the Wine method of terminating child processes.
294 * Its problem is that it doesn't terminate them in either a parent-to-children
295 * or children-to-parent relationship, but instead in the order in which they
296 * appear in the process list. This differs from Windows' (or ReactOS) method.
297 * Wine's termination ordering can cause problems in scenarii where e.g. a
298 * parent process could re-spawn killed children processes, or, where it is
299 * of interest to kill the parent process first and then its children.
300 *
301 * NOTE: The following two functions implicitly assume that the process list
302 * obtained from the system, is such that any child process P[j] of a given
303 * parent process P[i] is enumerated *AFTER* its parent (i.e. i < j).
304 *
305 * Because of these facts, the ReactOS method is employed instead.
306 * Note however that the Wine method (below) has been adapted for
307 * ease of usage and comparison with that of ReactOS.
308 */
309
310static BOOL find_parent(unsigned int process_index, unsigned int *parent_index)
311{
312 DWORD parent_id = process_list[process_index].p.th32ParentProcessID;
313 unsigned int i;
314
315 if (!parent_id)
316 return FALSE;
317
318 for (i = 0; i < process_count; ++i)
319 {
320 if (process_list[i].p.th32ProcessID == parent_id)
321 {
322 *parent_index = i;
323 return TRUE;
324 }
325 }
326 return FALSE;
327}
328
329static void mark_child_processes(void)
330{
331 unsigned int i, parent;
332
333 for (i = 0; i < process_count; ++i)
334 {
336 continue;
337#ifdef __REACTOS__
338 // Prevent self-termination if we are in the process tree
339 if (process_list[i].p.th32ProcessID == self_pid)
340 continue;
341#endif
342 parent = i;
343 while (find_parent(parent, &parent))
344 {
346 {
347 WINE_TRACE("Adding child %04lx.\n", process_list[i].p.th32ProcessID);
348 process_list[i].matched = TRUE;
349#ifdef __REACTOS__
350 pkill_list[pkill_size++] = i;
351#endif
352 break;
353 }
354 }
355 }
356}
357
358#endif // !__REACTOS__
359
360/* The implemented task enumeration and termination behavior does not
361 * exactly match native behavior. On Windows:
362 *
363 * In the case of terminating by process name, specifying a particular
364 * process name more times than the number of running instances causes
365 * all instances to be terminated, but termination failure messages to
366 * be printed as many times as the difference between the specification
367 * quantity and the number of running instances.
368 *
369 * Successful terminations are all listed first in order, with failing
370 * terminations being listed at the end.
371 *
372 * A PID of zero causes taskkill to warn about the inability to terminate
373 * system processes. */
374
375#ifdef __REACTOS__
376
377static BOOL get_pid_creation_time(DWORD pid, FILETIME *time)
378{
380 FILETIME t1, t2, t3;
382
384 if (!process)
385 return FALSE;
386
387 success = GetProcessTimes(process, time, &t1, &t2, &t3);
389
390 return success;
391}
392
393static void queue_children(DWORD ppid)
394{
395 FILETIME parent_creation_time;
396 unsigned int i;
397
398 if (!get_pid_creation_time(ppid, &parent_creation_time))
399 return;
400
401 for (i = 0; i < process_count; ++i)
402 {
403 FILETIME child_creation_time;
404 DWORD pid;
405
406 // Ignore processes already marked for termination
408 continue;
409
410 // Prevent self-termination if we are in the process tree
411 pid = process_list[i].p.th32ProcessID;
412 if (pid == self_pid)
413 continue;
414
415 if (!get_pid_creation_time(pid, &child_creation_time))
416 continue;
417
418 // Compare creation time to avoid PID reuse cases
419 if (process_list[i].p.th32ParentProcessID == ppid &&
420 CompareFileTime(&parent_creation_time, &child_creation_time) < 0)
421 {
422 // Process marked for termination
423 WINE_TRACE("Adding child %04lx.\n", pid);
424 process_list[i].matched = TRUE;
425 pkill_list[pkill_size++] = i;
426 }
427 }
428}
429
430/*
431 * Based on the root processes to terminate, we perform a level order traversal
432 * (Breadth First Search) of the corresponding process trees, building the list
433 * of all processes and children to terminate,
434 * This allows terminating the processes, starting from parents down to their
435 * children. Note that this is in the reverse order than what Windows' taskkill
436 * does. The reason why we chose to do the reverse, is because there exist
437 * (parent) processes that detect whether their children are terminated, and
438 * if so, attempt to restart their terminated children. We want to avoid this
439 * scenario in order to ensure no extra processes get started, while the user
440 * wanted to terminate them.
441 */
442static void mark_child_processes(void)
443{
444 /*
445 * The temporary FIFO queue for BFS (starting empty), is embedded
446 * inside the result list. The queue resides between the [front, end)
447 * indices (if front == end, the queue is empty), and moves down
448 * through the result list, generating the sought values in order.
449 */
450 unsigned int front = 0; // end = 0; given by pkill_size
451
452 /* The root processes have already been
453 * enqueued in pkill_list[0..pkill_size] */
454
455 /* Now, find and enqueue the children processes */
456 while (pkill_size - front > 0)
457 {
458 /* Begin search at the next level */
459 unsigned int len = pkill_size - front;
460 unsigned int i;
461 for (i = 0; i < len; ++i)
462 {
463 /* Standard BFS would pop the element from the front of
464 * the queue and push it to the end of the result list.
465 * In our case, everything is already correctly positioned
466 * so that we can just simply emulate queue front popping. */
467 DWORD pid = process_list[pkill_list[front++]].p.th32ProcessID;
468
469 /* Enqueue the children processes */
470 queue_children(pid); // Updates pkill_size accordingly.
471 }
472 }
473}
474
475#endif // __REACTOS__
476
477static int send_close_messages(void)
478{
479 const WCHAR *process_name;
480 struct pid_close_info info;
481 unsigned int i;
482 int status_code = 0;
483
484#ifdef __REACTOS__
485 DWORD index;
486 for (index = 0; index < pkill_size; ++index)
487#else
488 for (i = 0; i < process_count; i++)
489#endif
490 {
491#ifdef __REACTOS__
492 i = pkill_list[index];
493#else
494 if (!process_list[i].matched)
495 continue;
496#endif
497
498 info.pid = process_list[i].p.th32ProcessID;
499 process_name = process_list[i].p.szExeFile;
500 info.found = FALSE;
501 WINE_TRACE("Terminating pid %04lx.\n", info.pid);
503 if (info.found)
504 {
506 taskkill_message_printfW(STRING_CLOSE_CHILD, info.pid, process_list[i].p.th32ParentProcessID);
507 else if (process_list[i].is_numeric)
509 else
511 continue;
512 }
514 status_code = 128;
515 }
516
517 return status_code;
518}
519
520static int terminate_processes(void)
521{
522 const WCHAR *process_name;
523 unsigned int i;
524 int status_code = 0;
526 DWORD pid;
527
528#ifdef __REACTOS__
529 DWORD index;
530 for (index = 0; index < pkill_size; ++index)
531#else
532 for (i = 0; i < process_count; i++)
533#endif
534 {
535#ifdef __REACTOS__
536 i = pkill_list[index];
537#else
538 if (!process_list[i].matched)
539 continue;
540#endif
541
542 pid = process_list[i].p.th32ProcessID;
543 process_name = process_list[i].p.szExeFile;
545 if (!process)
546 {
548 status_code = 128;
549 continue;
550 }
551 if (!TerminateProcess(process, 1))
552 {
553#ifdef __REACTOS__
556 else
557#endif
559 status_code = 1;
561 continue;
562 }
565 else if (process_list[i].is_numeric)
567 else
570 }
571 return status_code;
572}
573
575{
576 static unsigned int list_size = 16;
577
578 if (!task_list)
579 {
580 task_list = malloc(list_size * sizeof(*task_list));
581 if (!task_list)
582 return FALSE;
583 }
584 else if (task_count == list_size)
585 {
586 void *realloc_list;
587
588 list_size *= 2;
589 realloc_list = realloc(task_list, list_size * sizeof(*task_list));
590 if (!realloc_list)
591 return FALSE;
592
593 task_list = realloc_list;
594 }
595
597 return TRUE;
598}
599
600#ifdef __REACTOS__
601
602static int get_argument_type(WCHAR* argument)
603{
604 int i;
605
606 if (argument[0] != L'/' && argument[0] != L'-')
607 {
608 return OP_PARAM_INVALID;
609 }
610 argument++;
611
612 for (i = 0; i < _countof(opList); i++)
613 {
614 if (!wcsicmp(opList[i], argument))
615 {
616 return i;
617 }
618 }
619 return OP_PARAM_INVALID;
620}
621
622static BOOL process_arguments(int argc, WCHAR* argv[])
623{
624 BOOL has_im = FALSE, has_pid = FALSE, has_help = FALSE;
625
626 if (argc > 1)
627 {
628 int i;
629 for (i = 1; i < argc; i++)
630 {
631 int argument = get_argument_type(argv[i]);
632
633 switch (argument)
634 {
635 case OP_PARAM_FORCE_TERMINATE:
636 {
638 {
639 // -f already specified
642 return FALSE;
643 }
645 break;
646 }
647 case OP_PARAM_IMAGE:
648 case OP_PARAM_PID:
649 {
650 if (!argv[i + 1])
651 {
654 return FALSE;
655 }
656
657 if (argument == OP_PARAM_IMAGE)
658 has_im = TRUE;
659 if (argument == OP_PARAM_PID)
660 has_pid = TRUE;
661
662 if (has_im && has_pid)
663 {
666 return FALSE;
667 }
668
669 if (get_argument_type(argv[i + 1]) != OP_PARAM_INVALID)
670 {
673 return FALSE;
674 }
675
676 if (!add_to_task_list(argv[++i])) // add next parameters to task_list
677 return FALSE;
678
679 break;
680 }
681 case OP_PARAM_HELP:
682 {
683 if (has_help)
684 {
685 // -? already specified
688 return FALSE;
689 }
690 has_help = TRUE;
691 break;
692 }
693 case OP_PARAM_TERMINATE_CHILD:
694 {
696 {
697 // -t already specified
700 return FALSE;
701 }
703 break;
704 }
705 case OP_PARAM_INVALID:
706 default:
707 {
710 return FALSE;
711 }
712 }
713 }
714 }
715
716 if (has_help)
717 {
718 if (argc > 2) // any parameters other than -? is specified
719 {
722 return FALSE;
723 }
724 else
725 {
727 exit(0);
728 }
729 }
730 else if (!has_im && !has_pid) // has_help == FALSE
731 {
732 // both has_im and has_pid are missing (maybe -fi option is missing too, if implemented later)
735 return FALSE;
736 }
737
738 return TRUE;
739}
740
741#else
742
743/* FIXME Argument processing does not match behavior observed on Windows.
744 * Stringent argument counting and processing is performed, and unrecognized
745 * options are detected as parameters when placed after options that accept one. */
747{
748 if (argc > 1)
749 {
750 int i;
751 WCHAR *argdata;
752 BOOL has_im = FALSE, has_pid = FALSE;
753
754 /* Only the lone help option is recognized. */
755 if (argc == 2)
756 {
757 argdata = argv[1];
758 if ((*argdata == '/' || *argdata == '-') && !lstrcmpW(L"?", argdata + 1))
759 {
761 exit(0);
762 }
763 }
764
765 for (i = 1; i < argc; i++)
766 {
767 BOOL got_im = FALSE, got_pid = FALSE;
768
769 argdata = argv[i];
770 if (*argdata != '/' && *argdata != '-')
771 goto invalid;
772 argdata++;
773
774 if (!wcsicmp(L"t", argdata))
776 else if (!wcsicmp(L"f", argdata))
778 /* Options /IM and /PID appear to behave identically, except for
779 * the fact that they cannot be specified at the same time. */
780 else if ((got_im = !wcsicmp(L"im", argdata)) ||
781 (got_pid = !wcsicmp(L"pid", argdata)))
782 {
783 if (!argv[i + 1])
784 {
787 return FALSE;
788 }
789
790 if (got_im) has_im = TRUE;
791 if (got_pid) has_pid = TRUE;
792
793 if (has_im && has_pid)
794 {
797 return FALSE;
798 }
799
800 if (!add_to_task_list(argv[i + 1]))
801 return FALSE;
802 i++;
803 }
804 else
805 {
806 invalid:
809 return FALSE;
810 }
811 }
812 }
813 else
814 {
817 return FALSE;
818 }
819
820 return TRUE;
821}
822
823#endif // __REACTOS__
824
825int wmain(int argc, WCHAR *argv[])
826{
827 int search_status = 0, terminate_status;
828 unsigned int i;
829
831 return 1;
832
833 if (!enumerate_processes())
834 {
836 return 1;
837 }
838
839#ifdef __REACTOS__
840 pkill_list = malloc(process_count * sizeof(unsigned int*));
841 if (!pkill_list)
842 return 1;
843 memset(pkill_list, 0, process_count * sizeof(unsigned int*));
844 pkill_size = 0;
845
846 self_pid = GetCurrentProcessId();
847#endif
848
849 for (i = 0; i < task_count; ++i)
850 mark_task_process(task_list[i], &search_status);
854 terminate_status = terminate_processes();
855 else
856 terminate_status = send_close_messages();
857 return search_status ? search_status : terminate_status;
858}
static int argc
Definition: ServiceArgs.c:12
char * va_list
Definition: acmsvcex.h:78
#define va_end(ap)
Definition: acmsvcex.h:90
#define va_start(ap, A)
Definition: acmsvcex.h:91
#define msg(x)
Definition: auth_time.c:54
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define STRING_USAGE
Definition: resource.h:44
#define STRING_INVALID_SYNTAX
Definition: resource.h:33
#define STRING_INVALID_OPTION
Definition: resource.h:55
#define index(s, c)
Definition: various.h:29
#define ARRAY_SIZE(A)
Definition: main.h:20
HANDLE WINAPI GetStdHandle(IN DWORD nStdHandle)
Definition: console.c:203
LPARAM lParam
Definition: combotst.c:139
#define realloc
Definition: debug_ros.c:6
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define CloseHandle
Definition: compat.h:739
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define CALLBACK
Definition: compat.h:35
#define WideCharToMultiByte
Definition: compat.h:111
#define wcsicmp
Definition: compat.h:15
BOOL WINAPI DECLSPEC_HOTPATCH WriteConsoleW(IN HANDLE hConsoleOutput, IN CONST VOID *lpBuffer, IN DWORD nNumberOfCharsToWrite, OUT LPDWORD lpNumberOfCharsWritten, LPVOID lpReserved)
Definition: readwrite.c:1447
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:838
BOOL WINAPI TerminateProcess(IN HANDLE hProcess, IN UINT uExitCode)
Definition: proc.c:1532
HANDLE WINAPI OpenProcess(IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN DWORD dwProcessId)
Definition: proc.c:1227
BOOL WINAPI GetProcessTimes(IN HANDLE hProcess, IN LPFILETIME lpCreationTime, IN LPFILETIME lpExitTime, IN LPFILETIME lpKernelTime, IN LPFILETIME lpUserTime)
Definition: proc.c:1099
LONG WINAPI CompareFileTime(IN CONST FILETIME *lpFileTime1, IN CONST FILETIME *lpFileTime2)
Definition: time.c:106
BOOL WINAPI Process32NextW(HANDLE hSnapshot, LPPROCESSENTRY32W lppe)
Definition: toolhelp.c:1073
HANDLE WINAPI CreateToolhelp32Snapshot(DWORD dwFlags, DWORD th32ProcessID)
Definition: toolhelp.c:1255
BOOL WINAPI Process32FirstW(HANDLE hSnapshot, LPPROCESSENTRY32W lppe)
Definition: toolhelp.c:984
DWORD WINAPI FormatMessageW(DWORD dwFlags, LPCVOID lpSource, DWORD dwMessageId, DWORD dwLanguageId, LPWSTR lpBuffer, DWORD nSize, __ms_va_list *args)
Definition: format_msg.c:583
int WINAPI lstrcmpW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4243
UINT WINAPI GetOEMCP(void)
Definition: locale.c:2060
r parent
Definition: btrfs.c:3010
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint index
Definition: glext.h:6031
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define iswdigit(_c)
Definition: ctype.h:667
_Check_return_ long __cdecl wcstol(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
#define PROCESS_TERMINATE
Definition: pstypes.h:158
#define PROCESS_QUERY_INFORMATION
Definition: pstypes.h:167
__u16 time
Definition: mkdosfs.c:8
static const WCHAR invalid[]
Definition: assoc.c:39
static DWORD parent_id
Definition: cursoricon.c:2270
#define argv
Definition: mplay32.c:18
long alloc_count
Definition: nc_alloc.cpp:36
#define L(x)
Definition: ntvdm.h:50
int wmain()
const WCHAR * str
static struct address_cache * front
Definition: rpcb_clnt.c:83
#define WINAPIV
Definition: sdbpapi.h:64
#define WINE_TRACE
Definition: debug.h:354
#define exit(n)
Definition: config.h:202
#define memset(x, y, z)
Definition: compat.h:39
#define _countof(array)
Definition: sndvol32.h:70
Definition: name.c:39
static int terminate_processes(void)
Definition: taskkill.c:520
static BOOL find_parent(unsigned int process_index, unsigned int *parent_index)
Definition: taskkill.c:310
static BOOL force_termination
Definition: taskkill.c:37
static void taskkill_message_print_process(int msg, unsigned int index)
Definition: taskkill.c:278
static int taskkill_message(int msg)
Definition: taskkill.c:136
static BOOL CALLBACK pid_enum_proc(HWND hwnd, LPARAM lParam)
Definition: taskkill.c:146
static unsigned int process_count
Definition: taskkill.c:50
static BOOL kill_child_processes
Definition: taskkill.c:38
static WCHAR ** task_list
Definition: taskkill.c:40
static void mark_task_process(const WCHAR *str, int *status_code)
Definition: taskkill.c:198
static int WINAPIV taskkill_printfW(const WCHAR *msg,...)
Definition: taskkill.c:109
static BOOL process_arguments(int argc, WCHAR *argv[])
Definition: taskkill.c:746
static struct @6 * process_list
static int taskkill_vprintfW(const WCHAR *msg, va_list va_args)
Definition: taskkill.c:78
static BOOL add_to_task_list(WCHAR *name)
Definition: taskkill.c:574
static int WINAPIV taskkill_message_printfW(int msg,...)
Definition: taskkill.c:121
static void mark_child_processes(void)
Definition: taskkill.c:329
BOOL is_numeric
Definition: taskkill.c:47
BOOL matched
Definition: taskkill.c:46
static int send_close_messages(void)
Definition: taskkill.c:477
static unsigned int task_count
Definition: taskkill.c:41
PROCESSENTRY32W p
Definition: taskkill.c:45
static BOOL enumerate_processes(void)
Definition: taskkill.c:162
#define STRING_TERM_CHILD_FAILED
Definition: taskkill.h:40
#define STRING_ENUM_FAILED
Definition: taskkill.h:35
#define STRING_SEARCH_FAILED
Definition: taskkill.h:34
#define STRING_TERM_CHILD
Definition: taskkill.h:39
#define STRING_MISSING_PARAM
Definition: taskkill.h:28
#define STRING_CLOSE_CHILD
Definition: taskkill.h:38
#define STRING_MISSING_OPTION
Definition: taskkill.h:27
#define STRING_TERMINATE_FAILED
Definition: taskkill.h:36
#define STRING_CLOSE_PROC_SRCH
Definition: taskkill.h:31
#define STRING_TERM_PROC_SEARCH
Definition: taskkill.h:33
#define STRING_PARAM_TOO_MUCH
Definition: taskkill.h:41
#define STRING_SELF_TERMINATION
Definition: taskkill.h:37
#define STRING_MUTUAL_EXCLUSIVE
Definition: taskkill.h:29
#define STRING_CLOSE_PID_SEARCH
Definition: taskkill.h:30
#define STRING_TERM_PID_SEARCH
Definition: taskkill.h:32
#define TH32CS_SNAPPROCESS
Definition: tlhelp32.h:26
uint16_t * PWCHAR
Definition: typedefs.h:56
#define success(from, fromstr, to, tostr)
#define STD_OUTPUT_HANDLE
Definition: winbase.h:294
#define FORMAT_MESSAGE_FROM_STRING
Definition: winbase.h:447
DWORD WINAPI GetCurrentProcessId(void)
Definition: proc.c:1158
DWORD WINAPI GetWindowThreadProcessId(HWND hWnd, PDWORD lpdwProcessId)
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
_In_ ULONG_PTR _In_ ULONG _Out_ ULONG_PTR * pid
Definition: winddi.h:3837
LONG_PTR LPARAM
Definition: windef.h:208
#define WM_CLOSE
Definition: winuser.h:1632
BOOL WINAPI PostMessageW(_In_opt_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
int WINAPIV wsprintfW(_Out_ LPWSTR, _In_ _Printf_format_string_ LPCWSTR,...)
BOOL WINAPI EnumWindows(_In_ WNDENUMPROC lpEnumFunc, _In_ LPARAM lParam)
__wchar_t WCHAR
Definition: xmlstorage.h:180