ReactOS 0.4.15-dev-7674-gc0b4db1
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 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 */
22
23#include <stdlib.h>
24#include <windows.h>
25#include <psapi.h>
26#include <wine/debug.h>
27#include <wine/unicode.h>
28
29#include "taskkill.h"
30
32
34
36static unsigned int task_count;
37
38#ifdef __REACTOS__
39
40static WCHAR opForceTerminate[] = L"f";
41static WCHAR opImage[] = L"im";
42static WCHAR opPID[] = L"pid";
43static WCHAR opHelp[] = L"?";
44static WCHAR opTerminateChildren[] = L"t";
45
46static PWCHAR opList[] = {opForceTerminate, opImage, opPID, opHelp, opTerminateChildren};
47
48#define OP_PARAM_INVALID -1
49
50#define OP_PARAM_FORCE_TERMINATE 0
51#define OP_PARAM_IMAGE 1
52#define OP_PARAM_PID 2
53#define OP_PARAM_HELP 3
54#define OP_PARAM_TERMINATE_CHILD 4
55
56#endif // __REACTOS__
57
59{
62};
63
64static int taskkill_vprintfW(const WCHAR *msg, __ms_va_list va_args)
65{
66 int wlen;
68 WCHAR msg_buffer[8192];
69
70 wlen = FormatMessageW(FORMAT_MESSAGE_FROM_STRING, msg, 0, 0, msg_buffer,
71 ARRAY_SIZE(msg_buffer), &va_args);
72
74 if (!ret)
75 {
76 DWORD len;
77 char *msgA;
78
79 /* On Windows WriteConsoleW() fails if the output is redirected. So fall
80 * back to WriteFile(), assuming the console encoding is still the right
81 * one in that case.
82 */
83 len = WideCharToMultiByte(GetConsoleOutputCP(), 0, msg_buffer, wlen,
84 NULL, 0, NULL, NULL);
85 msgA = HeapAlloc(GetProcessHeap(), 0, len);
86 if (!msgA)
87 return 0;
88
89 WideCharToMultiByte(GetConsoleOutputCP(), 0, msg_buffer, wlen, msgA, len,
90 NULL, NULL);
92 HeapFree(GetProcessHeap(), 0, msgA);
93 }
94
95 return count;
96}
97
98static int WINAPIV taskkill_printfW(const WCHAR *msg, ...)
99{
100 __ms_va_list va_args;
101 int len;
102
103 __ms_va_start(va_args, msg);
104 len = taskkill_vprintfW(msg, va_args);
105 __ms_va_end(va_args);
106
107 return len;
108}
109
111{
112 __ms_va_list va_args;
113 WCHAR msg_buffer[8192];
114 int len;
115
116 LoadStringW(GetModuleHandleW(NULL), msg, msg_buffer, ARRAY_SIZE(msg_buffer));
117
118 __ms_va_start(va_args, msg);
119 len = taskkill_vprintfW(msg_buffer, va_args);
120 __ms_va_end(va_args);
121
122 return len;
123}
124
125static int taskkill_message(int msg)
126{
127 static const WCHAR formatW[] = {'%','1',0};
128 WCHAR msg_buffer[8192];
129
130 LoadStringW(GetModuleHandleW(NULL), msg, msg_buffer, ARRAY_SIZE(msg_buffer));
131
132 return taskkill_printfW(formatW, msg_buffer);
133}
134
135/* Post WM_CLOSE to all top-level windows belonging to the process with specified PID. */
137{
138 struct pid_close_info *info = (struct pid_close_info *)lParam;
139 DWORD hwnd_pid;
140
141 GetWindowThreadProcessId(hwnd, &hwnd_pid);
142
143 if (hwnd_pid == info->pid)
144 {
145 PostMessageW(hwnd, WM_CLOSE, 0, 0);
146 info->found = TRUE;
147 }
148
149 return TRUE;
150}
151
153{
154 DWORD *pid_list, alloc_bytes = 1024 * sizeof(*pid_list), needed_bytes;
155
156 pid_list = HeapAlloc(GetProcessHeap(), 0, alloc_bytes);
157 if (!pid_list)
158 return NULL;
159
160 for (;;)
161 {
162 DWORD *realloc_list;
163
164 if (!EnumProcesses(pid_list, alloc_bytes, &needed_bytes))
165 {
166 HeapFree(GetProcessHeap(), 0, pid_list);
167 return NULL;
168 }
169
170 /* EnumProcesses can't signal an insufficient buffer condition, so the
171 * only way to possibly determine whether a larger buffer is required
172 * is to see whether the written number of bytes is the same as the
173 * buffer size. If so, the buffer will be reallocated to twice the
174 * size. */
175 if (alloc_bytes != needed_bytes)
176 break;
177
178 alloc_bytes *= 2;
179 realloc_list = HeapReAlloc(GetProcessHeap(), 0, pid_list, alloc_bytes);
180 if (!realloc_list)
181 {
182 HeapFree(GetProcessHeap(), 0, pid_list);
183 return NULL;
184 }
185 pid_list = realloc_list;
186 }
187
188 *list_count = needed_bytes / sizeof(*pid_list);
189 return pid_list;
190}
191
193{
196 DWORD required_size;
197
199 if (!process)
200 return FALSE;
201
202 if (!EnumProcessModules(process, &module, sizeof(module), &required_size))
203 {
205 return FALSE;
206 }
207
208 if (!GetModuleBaseNameW(process, module, buf, chars))
209 {
211 return FALSE;
212 }
213
215 return TRUE;
216}
217
218/* The implemented task enumeration and termination behavior does not
219 * exactly match native behavior. On Windows:
220 *
221 * In the case of terminating by process name, specifying a particular
222 * process name more times than the number of running instances causes
223 * all instances to be terminated, but termination failure messages to
224 * be printed as many times as the difference between the specification
225 * quantity and the number of running instances.
226 *
227 * Successful terminations are all listed first in order, with failing
228 * terminations being listed at the end.
229 *
230 * A PID of zero causes taskkill to warn about the inability to terminate
231 * system processes. */
232
233#ifndef __REACTOS__
234
235static int send_close_messages(void)
236{
237 DWORD *pid_list, pid_list_size;
238 DWORD self_pid = GetCurrentProcessId();
239 unsigned int i;
240 int status_code = 0;
241
242 pid_list = enumerate_processes(&pid_list_size);
243 if (!pid_list)
244 {
246 return 1;
247 }
248
249 for (i = 0; i < task_count; i++)
250 {
251 WCHAR *p = task_list[i];
252 BOOL is_numeric = TRUE;
253
254 /* Determine whether the string is not numeric. */
255 while (*p)
256 {
257 if (!isdigitW(*p++))
258 {
259 is_numeric = FALSE;
260 break;
261 }
262 }
263
264 if (is_numeric)
265 {
267 struct pid_close_info info = { pid };
268
269 if (pid == self_pid)
270 {
272 status_code = 1;
273 continue;
274 }
275
277 if (info.found)
279 else
280 {
282 status_code = 128;
283 }
284 }
285 else
286 {
287 DWORD index;
288 BOOL found_process = FALSE;
289
290 for (index = 0; index < pid_list_size; index++)
291 {
292 WCHAR process_name[MAX_PATH];
293
294 if (get_process_name_from_pid(pid_list[index], process_name, MAX_PATH) &&
295 !strcmpiW(process_name, task_list[i]))
296 {
297 struct pid_close_info info = { pid_list[index] };
298
299 found_process = TRUE;
300 if (pid_list[index] == self_pid)
301 {
303 status_code = 1;
304 continue;
305 }
306
308 taskkill_message_printfW(STRING_CLOSE_PROC_SRCH, process_name, pid_list[index]);
309 }
310 }
311
312 if (!found_process)
313 {
315 status_code = 128;
316 }
317 }
318 }
319
320 HeapFree(GetProcessHeap(), 0, pid_list);
321 return status_code;
322}
323
324#endif // __REACTOS__
325
326#ifdef __REACTOS__
328#else
329static int terminate_processes(void)
330#endif
331{
332 DWORD *pid_list, pid_list_size;
333 DWORD self_pid = GetCurrentProcessId();
334 unsigned int i;
335 int status_code = 0;
336
337 pid_list = enumerate_processes(&pid_list_size);
338 if (!pid_list)
339 {
341 return 1;
342 }
343
344 for (i = 0; i < task_count; i++)
345 {
346 WCHAR *p = task_list[i];
347 BOOL is_numeric = TRUE;
348
349 /* Determine whether the string is not numeric. */
350 while (*p)
351 {
352 if (!isdigitW(*p++))
353 {
354 is_numeric = FALSE;
355 break;
356 }
357 }
358
359 if (is_numeric)
360 {
362#ifndef __REACTOS__
364#endif
365
366 if (pid == self_pid)
367 {
369 status_code = 1;
370 continue;
371 }
372
373#ifdef __REACTOS__
375 {
377#endif
379 if (!process)
380 {
382 status_code = 128;
383 continue;
384 }
385
386 if (!TerminateProcess(process, 0))
387 {
389 status_code = 1;
391 continue;
392 }
393
396#ifdef __REACTOS__
397 }
398 else
399 {
400 struct pid_close_info info = { pid };
401
403 if (info.found)
405 else
406 {
408 status_code = 128;
409 }
410 }
411#endif
412 }
413 else
414 {
415 DWORD index;
416 BOOL found_process = FALSE;
417
418 for (index = 0; index < pid_list_size; index++)
419 {
420 WCHAR process_name[MAX_PATH];
421
422 if (get_process_name_from_pid(pid_list[index], process_name, MAX_PATH) &&
423 !strcmpiW(process_name, task_list[i]))
424 {
425#ifdef __REACTOS__
426 found_process = TRUE;
427#else
429#endif
430
431 if (pid_list[index] == self_pid)
432 {
434 status_code = 1;
435 continue;
436 }
437
438#ifdef __REACTOS__
440 {
442#endif
444 if (!process)
445 {
447 status_code = 128;
448 continue;
449 }
450
451 if (!TerminateProcess(process, 0))
452 {
454 status_code = 1;
456 continue;
457 }
458
459#ifndef __REACTOS__
460 found_process = TRUE;
461#endif
464#ifdef __REACTOS__
465 }
466 else
467 {
468 struct pid_close_info info = { pid_list[index] };
470 taskkill_message_printfW(STRING_CLOSE_PROC_SRCH, process_name, pid_list[index]);
471 }
472#endif
473 }
474 }
475
476 if (!found_process)
477 {
479 status_code = 128;
480 }
481 }
482 }
483
484 HeapFree(GetProcessHeap(), 0, pid_list);
485 return status_code;
486}
487
489{
490 static unsigned int list_size = 16;
491
492 if (!task_list)
493 {
495 list_size * sizeof(*task_list));
496 if (!task_list)
497 return FALSE;
498 }
499 else if (task_count == list_size)
500 {
501 void *realloc_list;
502
503 list_size *= 2;
504 realloc_list = HeapReAlloc(GetProcessHeap(), 0, task_list,
505 list_size * sizeof(*task_list));
506 if (!realloc_list)
507 return FALSE;
508
509 task_list = realloc_list;
510 }
511
513 return TRUE;
514}
515
516#ifdef __REACTOS__
517
518static int get_argument_type(WCHAR* argument)
519{
520 int i;
521
522 if (argument[0] != L'/' && argument[0] != L'-')
523 {
524 return OP_PARAM_INVALID;
525 }
526 argument++;
527
528 for (i = 0; i < _countof(opList); i++)
529 {
530 if (!strcmpiW(opList[i], argument))
531 {
532 return i;
533 }
534 }
535 return OP_PARAM_INVALID;
536}
537
538/* FIXME
539argument T not supported
540*/
541
542static BOOL process_arguments(int argc, WCHAR* argv[])
543{
544 BOOL has_im = FALSE, has_pid = FALSE, has_help = FALSE;
545
546 if (argc > 1)
547 {
548 int i;
549 for (i = 1; i < argc; i++)
550 {
551 int argument = get_argument_type(argv[i]);
552
553 switch (argument)
554 {
555 case OP_PARAM_FORCE_TERMINATE:
556 {
557 if (force_termination == TRUE)
558 {
559 // -f already specified
562 return FALSE;
563 }
565 break;
566 }
567 case OP_PARAM_IMAGE:
568 case OP_PARAM_PID:
569 {
570 if (!argv[i + 1])
571 {
574 return FALSE;
575 }
576
577 if (argument == OP_PARAM_IMAGE)
578 has_im = TRUE;
579 if (argument == OP_PARAM_PID)
580 has_pid = TRUE;
581
582 if (has_im && has_pid)
583 {
586 return FALSE;
587 }
588
589 if (get_argument_type(argv[i + 1]) != OP_PARAM_INVALID)
590 {
593 return FALSE;
594 }
595
596 if (!add_to_task_list(argv[++i])) // add next parameters to task_list
597 return FALSE;
598
599 break;
600 }
601 case OP_PARAM_HELP:
602 {
603 if (has_help == TRUE)
604 {
605 // -? already specified
608 return FALSE;
609 }
610 has_help = TRUE;
611 break;
612 }
613 case OP_PARAM_TERMINATE_CHILD:
614 {
615 WINE_FIXME("argument T not supported\n");
616 break;
617 }
618 case OP_PARAM_INVALID:
619 default:
620 {
623 return FALSE;
624 }
625 }
626 }
627 }
628
629 if (has_help)
630 {
631 if (argc > 2) // any parameters other than -? is specified
632 {
635 return FALSE;
636 }
637 else
638 {
640 exit(0);
641 }
642 }
643 else if ((!has_im) && (!has_pid)) // has_help == FALSE
644 {
645 // both has_im and has_pid are missing (maybe -fi option is missing too, if implemented later)
648 return FALSE;
649 }
650
651 return TRUE;
652}
653
654#else
655
656/* FIXME Argument processing does not match behavior observed on Windows.
657 * Stringent argument counting and processing is performed, and unrecognized
658 * options are detected as parameters when placed after options that accept one. */
660{
661 static const WCHAR opForceTerminate[] = {'f',0};
662 static const WCHAR opImage[] = {'i','m',0};
663 static const WCHAR opPID[] = {'p','i','d',0};
664 static const WCHAR opHelp[] = {'?',0};
665 static const WCHAR opTerminateChildren[] = {'t',0};
666
667 if (argc > 1)
668 {
669 int i;
670 WCHAR *argdata;
671 BOOL has_im = FALSE, has_pid = FALSE;
672
673 /* Only the lone help option is recognized. */
674 if (argc == 2)
675 {
676 argdata = argv[1];
677 if ((*argdata == '/' || *argdata == '-') && !strcmpW(opHelp, argdata + 1))
678 {
680 exit(0);
681 }
682 }
683
684 for (i = 1; i < argc; i++)
685 {
686 BOOL got_im = FALSE, got_pid = FALSE;
687
688 argdata = argv[i];
689 if (*argdata != '/' && *argdata != '-')
690 goto invalid;
691 argdata++;
692
693 if (!strcmpiW(opTerminateChildren, argdata))
694 WINE_FIXME("argument T not supported\n");
695 if (!strcmpiW(opForceTerminate, argdata))
697 /* Options /IM and /PID appear to behave identically, except for
698 * the fact that they cannot be specified at the same time. */
699 else if ((got_im = !strcmpiW(opImage, argdata)) ||
700 (got_pid = !strcmpiW(opPID, argdata)))
701 {
702 if (!argv[i + 1])
703 {
706 return FALSE;
707 }
708
709 if (got_im) has_im = TRUE;
710 if (got_pid) has_pid = TRUE;
711
712 if (has_im && has_pid)
713 {
716 return FALSE;
717 }
718
719 if (!add_to_task_list(argv[i + 1]))
720 return FALSE;
721 i++;
722 }
723 else
724 {
725 invalid:
728 return FALSE;
729 }
730 }
731 }
732 else
733 {
736 return FALSE;
737 }
738
739 return TRUE;
740}
741
742#endif // __REACTOS__
743
744int wmain(int argc, WCHAR *argv[])
745{
746 int status_code = 0;
747
749 {
751 return 1;
752 }
753
754#ifdef __REACTOS__
756#else
759 else
761#endif
762
764 return status_code;
765}
static int argc
Definition: ServiceArgs.c:12
#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:33
HANDLE WINAPI GetStdHandle(IN DWORD nStdHandle)
Definition: console.c:203
LPARAM lParam
Definition: combotst.c:139
#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 GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define HeapReAlloc
Definition: compat.h:734
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define CALLBACK
Definition: compat.h:35
#define WideCharToMultiByte
Definition: compat.h:111
UINT WINAPI DECLSPEC_HOTPATCH GetConsoleOutputCP(VOID)
Definition: console.c:2451
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
DWORD WINAPI FormatMessageW(DWORD dwFlags, LPCVOID lpSource, DWORD dwMessageId, DWORD dwLanguageId, LPWSTR lpBuffer, DWORD nSize, __ms_va_list *args)
Definition: format_msg.c:583
BOOL WINAPI EnumProcessModules(HANDLE hProcess, HMODULE *lphModule, DWORD cb, LPDWORD lpcbNeeded)
Definition: psapi.c:526
BOOL WINAPI EnumProcesses(DWORD *lpidProcess, DWORD cb, LPDWORD lpcbNeeded)
Definition: psapi.c:442
DWORD WINAPI GetModuleBaseNameW(HANDLE hProcess, HMODULE hModule, LPWSTR lpBaseName, DWORD nSize)
Definition: psapi.c:914
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
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
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 PROCESS_TERMINATE
Definition: pstypes.h:157
#define PROCESS_VM_READ
Definition: pstypes.h:161
#define PROCESS_QUERY_INFORMATION
Definition: pstypes.h:166
static const WCHAR invalid[]
Definition: assoc.c:39
#define argv
Definition: mplay32.c:18
#define L(x)
Definition: ntvdm.h:50
int wmain()
#define atoiW(s)
Definition: unicode.h:54
#define isdigitW(n)
Definition: unicode.h:50
#define strcmpW(s1, s2)
Definition: unicode.h:38
#define strcmpiW(s1, s2)
Definition: unicode.h:39
#define WINAPIV
Definition: sdbpapi.h:64
#define WINE_FIXME
Definition: debug.h:366
__WINE_SERVER_LIST_INLINE unsigned int list_count(const struct list *list)
Definition: list.h:155
#define exit(n)
Definition: config.h:202
#define _countof(array)
Definition: sndvol32.h:68
Definition: name.c:39
static int terminate_processes(void)
Definition: taskkill.c:329
static BOOL force_termination
Definition: taskkill.c:33
static int taskkill_message(int msg)
Definition: taskkill.c:125
static BOOL CALLBACK pid_enum_proc(HWND hwnd, LPARAM lParam)
Definition: taskkill.c:136
static WCHAR ** task_list
Definition: taskkill.c:35
static DWORD * enumerate_processes(DWORD *list_count)
Definition: taskkill.c:152
static int WINAPIV taskkill_printfW(const WCHAR *msg,...)
Definition: taskkill.c:98
static BOOL process_arguments(int argc, WCHAR *argv[])
Definition: taskkill.c:659
static BOOL add_to_task_list(WCHAR *name)
Definition: taskkill.c:488
static int WINAPIV taskkill_message_printfW(int msg,...)
Definition: taskkill.c:110
static BOOL get_process_name_from_pid(DWORD pid, WCHAR *buf, DWORD chars)
Definition: taskkill.c:192
static int taskkill_vprintfW(const WCHAR *msg, __ms_va_list va_args)
Definition: taskkill.c:64
static int send_close_messages(void)
Definition: taskkill.c:235
static unsigned int task_count
Definition: taskkill.c:36
#define STRING_ENUM_FAILED
Definition: taskkill.h:35
#define STRING_SEARCH_FAILED
Definition: taskkill.h:34
#define STRING_MISSING_PARAM
Definition: taskkill.h:28
#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:38
#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
uint16_t * PWCHAR
Definition: typedefs.h:56
int ret
#define STD_OUTPUT_HANDLE
Definition: winbase.h:268
#define FORMAT_MESSAGE_FROM_STRING
Definition: winbase.h:421
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 __ms_va_list
Definition: windef.h:456
#define __ms_va_end(list)
Definition: windef.h:458
#define __ms_va_start(list, arg)
Definition: windef.h:457
#define WM_CLOSE
Definition: winuser.h:1620
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)
BOOL WINAPI EnumWindows(_In_ WNDENUMPROC lpEnumFunc, _In_ LPARAM lParam)
__wchar_t WCHAR
Definition: xmlstorage.h:180