diff --git a/base/applications/cmdutils/taskkill/lang/de-DE.rc b/base/applications/cmdutils/taskkill/lang/de-DE.rc index ea43a9bae17..54a408fcc8a 100644 --- a/base/applications/cmdutils/taskkill/lang/de-DE.rc +++ b/base/applications/cmdutils/taskkill/lang/de-DE.rc @@ -16,4 +16,6 @@ STRINGTABLE STRING_ENUM_FAILED, "Fehler: Prozessliste kann nicht aufgebaut werden.\n" STRING_TERMINATE_FAILED, "Fehler: Prozess ""%1"" kann nicht beendet werden.\n" STRING_SELF_TERMINATION, "Fehler: Der Prozess kann sich nicht selbst beenden.\n" + STRING_PARAM_TOO_MUCH, "Error: Invalid syntax. '%1' option is not allowed more than '%2!d!' time(s).\n" + STRING_INVALID_SYNTAX, "Error: Invalid syntax.\n" } diff --git a/base/applications/cmdutils/taskkill/lang/en-US.rc b/base/applications/cmdutils/taskkill/lang/en-US.rc index 1e87249cb11..e34b34bad25 100644 --- a/base/applications/cmdutils/taskkill/lang/en-US.rc +++ b/base/applications/cmdutils/taskkill/lang/en-US.rc @@ -16,4 +16,6 @@ STRINGTABLE STRING_ENUM_FAILED, "Error: Unable to enumerate the process list.\n" STRING_TERMINATE_FAILED, "Error: Unable to terminate process ""%1"".\n" STRING_SELF_TERMINATION, "Error: Process self-termination is not permitted.\n" + STRING_PARAM_TOO_MUCH, "Error: Invalid syntax. '%1' option is not allowed more than '%2!d!' time(s).\n" + STRING_INVALID_SYNTAX, "Error: Invalid syntax.\n" } diff --git a/base/applications/cmdutils/taskkill/lang/it-IT.rc b/base/applications/cmdutils/taskkill/lang/it-IT.rc index 0a2cb322ae7..886c4a9a3c1 100644 --- a/base/applications/cmdutils/taskkill/lang/it-IT.rc +++ b/base/applications/cmdutils/taskkill/lang/it-IT.rc @@ -23,4 +23,6 @@ STRINGTABLE STRING_ENUM_FAILED, "Errore: Impossibile enumerare la lista dei processi.\n" STRING_TERMINATE_FAILED, "Errore: Impossibile terminare il processo ""%1"".\n" STRING_SELF_TERMINATION, "Errore: L'auto-terminazione non è consentita.\n" + STRING_PARAM_TOO_MUCH, "Error: Invalid syntax. '%1' option is not allowed more than '%2!d!' time(s).\n" + STRING_INVALID_SYNTAX, "Error: Invalid syntax.\n" } diff --git a/base/applications/cmdutils/taskkill/lang/pl-PL.rc b/base/applications/cmdutils/taskkill/lang/pl-PL.rc index c907dc72b62..d66da03ec6e 100644 --- a/base/applications/cmdutils/taskkill/lang/pl-PL.rc +++ b/base/applications/cmdutils/taskkill/lang/pl-PL.rc @@ -16,4 +16,6 @@ STRINGTABLE STRING_ENUM_FAILED, "Błąd: Nie można wyliczyć listy procesów.\n" STRING_TERMINATE_FAILED, "Błąd: Nie można zakończyć procesu ""%1"".\n" STRING_SELF_TERMINATION, "Błąd: Proces nie może zakończyć sam siebie.\n" + STRING_PARAM_TOO_MUCH, "Error: Invalid syntax. '%1' option is not allowed more than '%2!d!' time(s).\n" + STRING_INVALID_SYNTAX, "Error: Invalid syntax.\n" } diff --git a/base/applications/cmdutils/taskkill/lang/ro-RO.rc b/base/applications/cmdutils/taskkill/lang/ro-RO.rc index d050c6b4b80..649dfc47ed2 100644 --- a/base/applications/cmdutils/taskkill/lang/ro-RO.rc +++ b/base/applications/cmdutils/taskkill/lang/ro-RO.rc @@ -18,4 +18,6 @@ STRINGTABLE STRING_ENUM_FAILED, "Eroare: Procesele nu au putut fi enumerate.\n" STRING_TERMINATE_FAILED, "Eroare: Procesul «%1» nu poate fi oprit.\n" STRING_SELF_TERMINATION, "Eroare: Auto-terminarea nu este permisă.\n" + STRING_PARAM_TOO_MUCH, "Error: Invalid syntax. '%1' option is not allowed more than '%2!d!' time(s).\n" + STRING_INVALID_SYNTAX, "Error: Invalid syntax.\n" } diff --git a/base/applications/cmdutils/taskkill/lang/ru-RU.rc b/base/applications/cmdutils/taskkill/lang/ru-RU.rc index 5002db0732f..9a671e98b45 100644 --- a/base/applications/cmdutils/taskkill/lang/ru-RU.rc +++ b/base/applications/cmdutils/taskkill/lang/ru-RU.rc @@ -18,4 +18,6 @@ STRINGTABLE STRING_ENUM_FAILED, "Ошибка: Не удается получить список процессов.\n" STRING_TERMINATE_FAILED, "Ошибка: Не удается завершить процесс ""%1"".\n" STRING_SELF_TERMINATION, "Ошибка: Процесс не может завершить сам себя.\n" + STRING_PARAM_TOO_MUCH, "Error: Invalid syntax. '%1' option is not allowed more than '%2!d!' time(s).\n" + STRING_INVALID_SYNTAX, "Error: Invalid syntax.\n" } diff --git a/base/applications/cmdutils/taskkill/lang/sq-AL.rc b/base/applications/cmdutils/taskkill/lang/sq-AL.rc index c4ee3dd1bc3..85878177488 100644 --- a/base/applications/cmdutils/taskkill/lang/sq-AL.rc +++ b/base/applications/cmdutils/taskkill/lang/sq-AL.rc @@ -20,4 +20,6 @@ STRINGTABLE STRING_ENUM_FAILED, "Gabim: Në pamundësi për të numëruar listën proceseve.\n" STRING_TERMINATE_FAILED, "Gabim: Pamundur mbyllja e proceseve ""%1"".\n" STRING_SELF_TERMINATION, "Gabim: Procesi vetë-përfundimi nuk është i lejuar.\n" + STRING_PARAM_TOO_MUCH, "Error: Invalid syntax. '%1' option is not allowed more than '%2!d!' time(s).\n" + STRING_INVALID_SYNTAX, "Error: Invalid syntax.\n" } diff --git a/base/applications/cmdutils/taskkill/lang/tr-TR.rc b/base/applications/cmdutils/taskkill/lang/tr-TR.rc index 97ebbc186a8..fec4c4a07de 100644 --- a/base/applications/cmdutils/taskkill/lang/tr-TR.rc +++ b/base/applications/cmdutils/taskkill/lang/tr-TR.rc @@ -18,4 +18,6 @@ STRINGTABLE STRING_ENUM_FAILED, "Yanlışlık: İşlem dizelgesi numaralandırılamaz.\n" STRING_TERMINATE_FAILED, "Yanlışlık: ""%1"" işlemi sonlandırılamaz.\n" STRING_SELF_TERMINATION, "Yanlışlık: İşlemi kendi kendine sonlandırmaya izin verilmedi.\n" + STRING_PARAM_TOO_MUCH, "Error: Invalid syntax. '%1' option is not allowed more than '%2!d!' time(s).\n" + STRING_INVALID_SYNTAX, "Error: Invalid syntax.\n" } diff --git a/base/applications/cmdutils/taskkill/lang/zh-CN.rc b/base/applications/cmdutils/taskkill/lang/zh-CN.rc index f6980a6932d..e6b2c272d1d 100644 --- a/base/applications/cmdutils/taskkill/lang/zh-CN.rc +++ b/base/applications/cmdutils/taskkill/lang/zh-CN.rc @@ -1,4 +1,7 @@ -/* Simplified Chinese translation by Henry Tang Ih 2016 (henrytang2@hotmail.com) */ +/* Simplified Chinese translation by +Henry Tang Ih 2016 (henrytang2@hotmail.com) +He Yang 2020 (1160386205@qq.com) + */ LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED @@ -18,4 +21,6 @@ STRINGTABLE STRING_ENUM_FAILED, "错误: 无法枚举进程列表。\n" STRING_TERMINATE_FAILED, "错误: 无法终止进程 ""%1""。\n" STRING_SELF_TERMINATION, "错误: 不允许终止自身。\n" + STRING_PARAM_TOO_MUCH, "错误:无效语法。选项 '%1' 不允许超过 '%2!d!' 次。\n" + STRING_INVALID_SYNTAX, "错误:无效语法。\n" } diff --git a/base/applications/cmdutils/taskkill/lang/zh-TW.rc b/base/applications/cmdutils/taskkill/lang/zh-TW.rc index afc52383bab..16b37cae210 100644 --- a/base/applications/cmdutils/taskkill/lang/zh-TW.rc +++ b/base/applications/cmdutils/taskkill/lang/zh-TW.rc @@ -18,4 +18,6 @@ STRINGTABLE STRING_ENUM_FAILED, "錯誤: 無法枚舉處理序清單。\n" STRING_TERMINATE_FAILED, "錯誤: 無法終止處理序 ""%1""。\n" STRING_SELF_TERMINATION, "錯誤: 不允許自我終止的處理序。\n" + STRING_PARAM_TOO_MUCH, "Error: Invalid syntax. '%1' option is not allowed more than '%2!d!' time(s).\n" + STRING_INVALID_SYNTAX, "Error: Invalid syntax.\n" } diff --git a/base/applications/cmdutils/taskkill/taskkill.c b/base/applications/cmdutils/taskkill/taskkill.c index 59ce98dc6dc..b78d461a6fa 100644 --- a/base/applications/cmdutils/taskkill/taskkill.c +++ b/base/applications/cmdutils/taskkill/taskkill.c @@ -34,6 +34,26 @@ static BOOL force_termination = FALSE; static WCHAR **task_list; static unsigned int task_count; +#ifdef __REACTOS__ + +static WCHAR opForceTerminate[] = L"f"; +static WCHAR opImage[] = L"im"; +static WCHAR opPID[] = L"pid"; +static WCHAR opHelp[] = L"?"; +static WCHAR opTerminateChildren[] = L"t"; + +static PWCHAR opList[] = {opForceTerminate, opImage, opPID, opHelp, opTerminateChildren}; + +#define OP_PARAM_INVALID -1 + +#define OP_PARAM_FORCE_TERMINATE 0 +#define OP_PARAM_IMAGE 1 +#define OP_PARAM_PID 2 +#define OP_PARAM_HELP 3 +#define OP_PARAM_TERMINATE_CHILD 4 + +#endif + struct pid_close_info { DWORD pid; @@ -208,6 +228,153 @@ static BOOL get_process_name_from_pid(DWORD pid, WCHAR *buf, DWORD chars) * * A PID of zero causes taskkill to warn about the inability to terminate * system processes. */ + + +#ifdef __REACTOS__ + +static int terminate_processes(BOOL force_termination) +{ + DWORD *pid_list, pid_list_size; + DWORD self_pid = GetCurrentProcessId(); + unsigned int i; + int status_code = 0; + + pid_list = enumerate_processes(&pid_list_size); + if (!pid_list) + { + taskkill_message(STRING_ENUM_FAILED); + return 1; + } + + 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]); + + if (pid == self_pid) + { + taskkill_message(STRING_SELF_TERMINATION); + status_code = 1; + continue; + } + + if (force_termination) + { + HANDLE process; + process = OpenProcess(PROCESS_TERMINATE, FALSE, pid); + if (!process) + { + taskkill_message_printfW(STRING_SEARCH_FAILED, task_list[i]); + status_code = 128; + continue; + } + + if (!TerminateProcess(process, 0)) + { + taskkill_message_printfW(STRING_TERMINATE_FAILED, task_list[i]); + status_code = 1; + CloseHandle(process); + continue; + } + + taskkill_message_printfW(STRING_TERM_PID_SEARCH, pid); + CloseHandle(process); + } + else + { + 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 + { + DWORD index; + BOOL found_process = FALSE; + + for (index = 0; index < pid_list_size; index++) + { + WCHAR process_name[MAX_PATH]; + + if (get_process_name_from_pid(pid_list[index], process_name, MAX_PATH) && + !strcmpiW(process_name, task_list[i])) + { + found_process = TRUE; + + if (pid_list[index] == self_pid) + { + taskkill_message(STRING_SELF_TERMINATION); + status_code = 1; + continue; + } + + if (force_termination) + { + HANDLE process; + + process = OpenProcess(PROCESS_TERMINATE, FALSE, pid_list[index]); + if (!process) + { + taskkill_message_printfW(STRING_SEARCH_FAILED, task_list[i]); + status_code = 128; + continue; + } + + if (!TerminateProcess(process, 0)) + { + taskkill_message_printfW(STRING_TERMINATE_FAILED, task_list[i]); + status_code = 1; + CloseHandle(process); + continue; + } + + taskkill_message_printfW(STRING_TERM_PROC_SEARCH, task_list[i], pid_list[index]); + CloseHandle(process); + } + else + { + struct pid_close_info info = {pid_list[index]}; + EnumWindows(pid_enum_proc, (LPARAM)&info); + taskkill_message_printfW(STRING_CLOSE_PROC_SRCH, process_name, pid_list[index]); + } + } + } + + if (!found_process) + { + taskkill_message_printfW(STRING_SEARCH_FAILED, task_list[i]); + status_code = 128; + } + } + } + + HeapFree(GetProcessHeap(), 0, pid_list); + return status_code; +} + +#else + static int send_close_messages(void) { DWORD *pid_list, pid_list_size; @@ -412,6 +579,9 @@ static int terminate_processes(void) return status_code; } +#endif // __REACTOS__ + + static BOOL add_to_task_list(WCHAR *name) { static unsigned int list_size = 16; @@ -440,6 +610,146 @@ static BOOL add_to_task_list(WCHAR *name) return TRUE; } +#ifdef __REACTOS__ + +static int get_argument_type(WCHAR* argument) +{ + int i; + + if (argument[0] != L'/' && argument[0] != L'-') + { + return OP_PARAM_INVALID; + } + argument++; + + for (i = 0; i < _countof(opList); i++) + { + if (!strcmpiW(opList[i], argument)) + { + return i; + } + } + return OP_PARAM_INVALID; +} + +/* FIXME +argument T not supported +*/ + +static BOOL process_arguments(int argc, WCHAR* argv[]) +{ + BOOL has_im = FALSE, has_pid = FALSE, has_help = FALSE; + + if (argc > 1) + { + int i; + for (i = 1; i < argc; i++) + { + int argument = get_argument_type(argv[i]); + + switch (argument) + { + case OP_PARAM_FORCE_TERMINATE: + { + if (force_termination == TRUE) + { + // -f already specified + taskkill_message_printfW(STRING_PARAM_TOO_MUCH, argv[i], 1); + taskkill_message(STRING_USAGE); + return FALSE; + } + force_termination = TRUE; + break; + } + case OP_PARAM_IMAGE: + case OP_PARAM_PID: + { + if (!argv[i + 1]) + { + taskkill_message_printfW(STRING_MISSING_PARAM, argv[i]); + taskkill_message(STRING_USAGE); + return FALSE; + } + + if (argument == OP_PARAM_IMAGE) + has_im = TRUE; + if (argument == OP_PARAM_PID) + has_pid = TRUE; + + if (has_im && has_pid) + { + taskkill_message(STRING_MUTUAL_EXCLUSIVE); + taskkill_message(STRING_USAGE); + return FALSE; + } + + if (get_argument_type(argv[i + 1]) != OP_PARAM_INVALID) + { + taskkill_message_printfW(STRING_MISSING_PARAM, argv[i]); + taskkill_message(STRING_USAGE); + return FALSE; + } + + if (!add_to_task_list(argv[++i])) // add next parameters to task_list + return FALSE; + + break; + } + case OP_PARAM_HELP: + { + if (has_help == TRUE) + { + // -? already specified + taskkill_message_printfW(STRING_PARAM_TOO_MUCH, argv[i], 1); + taskkill_message(STRING_USAGE); + return FALSE; + } + has_help = TRUE; + break; + } + case OP_PARAM_TERMINATE_CHILD: + { + WINE_FIXME("argument T not supported\n"); + break; + } + case OP_PARAM_INVALID: + default: + { + taskkill_message(STRING_INVALID_OPTION); + taskkill_message(STRING_USAGE); + return FALSE; + } + } + } + } + + if (has_help) + { + if (argc > 2) // any parameters other than -? is specified + { + taskkill_message(STRING_INVALID_SYNTAX); + taskkill_message(STRING_USAGE); + return FALSE; + } + else + { + taskkill_message(STRING_USAGE); + exit(0); + } + } + else if ((!has_im) && (!has_pid)) // has_help == FALSE + { + // both has_im and has_pid are missing (maybe -fi option is missing too, if implemented later) + taskkill_message(STRING_MISSING_OPTION); + taskkill_message(STRING_USAGE); + return FALSE; + } + + return TRUE; +} + +#else + /* FIXME Argument processing does not match behavior observed on Windows. * Stringent argument counting and processing is performed, and unrecognized * options are detected as parameters when placed after options that accept one. */ @@ -526,6 +836,8 @@ static BOOL process_arguments(int argc, WCHAR *argv[]) return TRUE; } +#endif // __REACTOS__ + int wmain(int argc, WCHAR *argv[]) { int status_code = 0; @@ -536,11 +848,19 @@ int wmain(int argc, WCHAR *argv[]) return 1; } +#ifdef __REACTOS__ + + status_code = terminate_processes(force_termination); + +#else + if (force_termination) status_code = terminate_processes(); else status_code = send_close_messages(); +#endif + HeapFree(GetProcessHeap(), 0, task_list); return status_code; } diff --git a/base/applications/cmdutils/taskkill/taskkill.h b/base/applications/cmdutils/taskkill/taskkill.h index 7972a156f3c..03312fa8c9c 100644 --- a/base/applications/cmdutils/taskkill/taskkill.h +++ b/base/applications/cmdutils/taskkill/taskkill.h @@ -35,3 +35,6 @@ #define STRING_ENUM_FAILED 112 #define STRING_TERMINATE_FAILED 113 #define STRING_SELF_TERMINATION 114 +#define STRING_PARAM_TOO_MUCH 115 +#define STRING_INVALID_SYNTAX 116 +