mirror of
https://github.com/reactos/reactos.git
synced 2025-08-06 20:13:04 +00:00
Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers into modules, and delete rossubsys.
This commit is contained in:
parent
b94e2d8ca0
commit
c2c66aff7d
24198 changed files with 0 additions and 37285 deletions
6
base/applications/cmdutils/taskkill/CMakeLists.txt
Normal file
6
base/applications/cmdutils/taskkill/CMakeLists.txt
Normal file
|
@ -0,0 +1,6 @@
|
|||
|
||||
add_executable(taskkill taskkill.c taskkill.rc)
|
||||
target_link_libraries(taskkill wine)
|
||||
set_module_type(taskkill win32cui UNICODE)
|
||||
add_importlibs(taskkill psapi user32 msvcrt kernel32 ntdll)
|
||||
add_cd_file(TARGET taskkill DESTINATION reactos/system32 FOR all)
|
19
base/applications/cmdutils/taskkill/lang/de-DE.rc
Normal file
19
base/applications/cmdutils/taskkill/lang/de-DE.rc
Normal file
|
@ -0,0 +1,19 @@
|
|||
LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL
|
||||
|
||||
STRINGTABLE
|
||||
{
|
||||
STRING_USAGE, "Usage: taskkill [/?] [/f] [/im Prozess Name | /pid Prozess ID]\n"
|
||||
STRING_INVALID_OPTION, "Fehler: Unbekannte oder ungülige Kommandozeilenoption angegeben.\n"
|
||||
STRING_INVALID_PARAM, "Fehler: Ungültiger Kommandozeilenparameter angegeben.\n"
|
||||
STRING_MISSING_OPTION, "Fehler: Eine der Optionen /im oder /pid muss angegeben werden.\n"
|
||||
STRING_MISSING_PARAM, "Fehler: Option %1 erwartet einen Kommandozeilenparameter.\n"
|
||||
STRING_MUTUAL_EXCLUSIVE, "Fehler: Optionen /im und /pid schließen sich gegenseitig aus.\n"
|
||||
STRING_CLOSE_PID_SEARCH, "Schließen-Befehl an oberstes Fenster des Prozesses mit PID %1!u! gesendet.\n"
|
||||
STRING_CLOSE_PROC_SRCH, "Schließen-Befehl an oberstes Fenster des Prozesses ""%1"" mit PID %2!u! gesendet.\n"
|
||||
STRING_TERM_PID_SEARCH, "Prozess mit PID %1!u! wurde erzwungenermaßen beendet.\n"
|
||||
STRING_TERM_PROC_SEARCH, "Prozess ""%1"" mit PID %2!u! wurde erzwungenermaßen beendet.\n"
|
||||
STRING_SEARCH_FAILED, "Fehler: Konnte Prozess ""%1"" nicht finden.\n"
|
||||
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"
|
||||
}
|
19
base/applications/cmdutils/taskkill/lang/en-US.rc
Normal file
19
base/applications/cmdutils/taskkill/lang/en-US.rc
Normal file
|
@ -0,0 +1,19 @@
|
|||
LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT
|
||||
|
||||
STRINGTABLE
|
||||
{
|
||||
STRING_USAGE, "Usage: taskkill [/?] [/f] [/im ProcessName | /pid ProcessID]\n"
|
||||
STRING_INVALID_OPTION, "Error: Unknown or invalid command line option specified.\n"
|
||||
STRING_INVALID_PARAM, "Error: Invalid command line parameter specified.\n"
|
||||
STRING_MISSING_OPTION, "Error: One of options /im or /pid must be specified.\n"
|
||||
STRING_MISSING_PARAM, "Error: Option %1 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 %1!u!.\n"
|
||||
STRING_CLOSE_PROC_SRCH, "Close message sent to top-level windows of process ""%1"" with PID %2!u!.\n"
|
||||
STRING_TERM_PID_SEARCH, "Process with PID %1!u! was forcibly terminated.\n"
|
||||
STRING_TERM_PROC_SEARCH, "Process ""%1"" with PID %2!u! was forcibly terminated.\n"
|
||||
STRING_SEARCH_FAILED, "Error: Could not find process ""%1"".\n"
|
||||
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"
|
||||
}
|
21
base/applications/cmdutils/taskkill/lang/ro-RO.rc
Normal file
21
base/applications/cmdutils/taskkill/lang/ro-RO.rc
Normal file
|
@ -0,0 +1,21 @@
|
|||
/* Translator: Ștefan Fulea (stefan dot fulea at mail dot md) */
|
||||
|
||||
LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL
|
||||
|
||||
STRINGTABLE
|
||||
{
|
||||
STRING_USAGE, "Utilizare: taskkill [/?] [/f] [/im NumeProces | /pid IdProces]\n"
|
||||
STRING_INVALID_OPTION, "Eroare: Opțiune specificată nevalidă sau necunoscută.\n"
|
||||
STRING_INVALID_PARAM, "Eroare: Parametrul de comandă specificat este nevalid.\n"
|
||||
STRING_MISSING_OPTION, "Eroare: Trebuie specificată una dintre opțiunile /im sau /pid.\n"
|
||||
STRING_MISSING_PARAM, "Eroare: Opțiunea %1 necesită un parametru.\n"
|
||||
STRING_MUTUAL_EXCLUSIVE, "Eroare: Opțiunile /im și /pid sunt reciproc exclusive.\n"
|
||||
STRING_CLOSE_PID_SEARCH, "Către fereastra procesului cu PID %1!u! a fost emis un mesaj de închidere.\n"
|
||||
STRING_CLOSE_PROC_SRCH, "Către fereastra procesului «%1» cu PID %2!u! a fost emis un mesaj de închidere.\n"
|
||||
STRING_TERM_PID_SEARCH, "Procesul cu PID %1!u! a fost oprit în mod forțat.\n"
|
||||
STRING_TERM_PROC_SEARCH, "Procesul «%1» cu PID %2!u! a fost oprit în mod forțat.\n"
|
||||
STRING_SEARCH_FAILED, "Eroare: Procesul «%1» nu poate fi găsit.\n"
|
||||
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"
|
||||
}
|
21
base/applications/cmdutils/taskkill/lang/ru-RU.rc
Normal file
21
base/applications/cmdutils/taskkill/lang/ru-RU.rc
Normal file
|
@ -0,0 +1,21 @@
|
|||
/* Russian language resource file by Kudratov Olimjon (olim98@bk.ru) */
|
||||
|
||||
LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
|
||||
|
||||
STRINGTABLE
|
||||
{
|
||||
STRING_USAGE, "Использование: TASKKILL [/F] [/IM <образ> | /PID <процесс>]\n"
|
||||
STRING_INVALID_OPTION, "Ошибка: Указаны неверные параметры командной строки.\n"
|
||||
STRING_INVALID_PARAM, "Ошибка: Указаны неверные параметры командной строки.\n"
|
||||
STRING_MISSING_OPTION, "Ошибка: Должен быть указан параметр /im или /pid.\n"
|
||||
STRING_MISSING_PARAM, "Ошибка: Потерян обязательный параметр %1.\n"
|
||||
STRING_MUTUAL_EXCLUSIVE, "Ошибка: Одновременное использование параметров '/pid' и '/im' запрещено.\n"
|
||||
STRING_CLOSE_PID_SEARCH, "Отправлен сигнал завершения процессу с идентификатором %1!u!.\n"
|
||||
STRING_CLOSE_PROC_SRCH, "Отправлен сигнал завершения процессу ""%1"" с идентификатором %2!u!.\n"
|
||||
STRING_TERM_PID_SEARCH, "Процесс, с идентификатором %1!u! принудительно завершен.\n"
|
||||
STRING_TERM_PROC_SEARCH, "Процесс ""%1"" с идентификатором %2!u! принудительно завершен.\n"
|
||||
STRING_SEARCH_FAILED, "Ошибка: Не удается найти процесс ""%1"".\n"
|
||||
STRING_ENUM_FAILED, "Ошибка: Не удается получить список процессов.\n"
|
||||
STRING_TERMINATE_FAILED, "Ошибка: Не удается завершить процесс ""%1"".\n"
|
||||
STRING_SELF_TERMINATION, "Ошибка: Процесс не может завершить сам себя.\n"
|
||||
}
|
23
base/applications/cmdutils/taskkill/lang/sq-AL.rc
Normal file
23
base/applications/cmdutils/taskkill/lang/sq-AL.rc
Normal file
|
@ -0,0 +1,23 @@
|
|||
/* TRANSLATOR : Ardit Dani (Ard1t) (ardit.dani@gmail.com)
|
||||
* DATE OF TR: 29-11-2013
|
||||
*/
|
||||
|
||||
LANGUAGE LANG_ALBANIAN, SUBLANG_NEUTRAL
|
||||
|
||||
STRINGTABLE
|
||||
{
|
||||
STRING_USAGE, "Usage: taskkill [/?] [/f] [/im ProcessName | /pid ProcessID]\n"
|
||||
STRING_INVALID_OPTION, "Gabim: Panjohur ose i pavlefshëm opsioni linjes komandes i specifikuar.\n"
|
||||
STRING_INVALID_PARAM, "Gabim: Pavlefshëm parametri i specifikuar ne linjen e komandes.\n"
|
||||
STRING_MISSING_OPTION, "Gabim: Njera nga opsionet /im ose /pid duhet te specifikohet.\n"
|
||||
STRING_MISSING_PARAM, "Gabim: Opsioni %1 kalon parametrin i linjes se komandes.\n"
|
||||
STRING_MUTUAL_EXCLUSIVE, "Gabim: Opsioni /im dhe /pid janë exclusiv reciprokisht.\n"
|
||||
STRING_CLOSE_PID_SEARCH, "Mbyll mesazhin e derguar ne dritaren e nivelin-lart te proceseve me PID %1!u!.\n"
|
||||
STRING_CLOSE_PROC_SRCH, "Mbyll mesazhin e derguar ne dritaren e nivelin-lart te proceseve ""%1"" me PID %2!u!.\n"
|
||||
STRING_TERM_PID_SEARCH, "Proceso me PID %1!u! u mbyll me force.\n"
|
||||
STRING_TERM_PROC_SEARCH, "Proces ""%1"" me PID %2!u! u mbyll me force.\n"
|
||||
STRING_SEARCH_FAILED, "Gabim: Nuk u gjend procesi ""%1"".\n"
|
||||
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"
|
||||
}
|
21
base/applications/cmdutils/taskkill/lang/tr-TR.rc
Normal file
21
base/applications/cmdutils/taskkill/lang/tr-TR.rc
Normal file
|
@ -0,0 +1,21 @@
|
|||
/* TRANSLATOR: 2015 Erdem Ersoy (eersoy93) (erdemersoy@live.com) */
|
||||
|
||||
LANGUAGE LANG_TURKISH, SUBLANG_NEUTRAL
|
||||
|
||||
STRINGTABLE
|
||||
{
|
||||
STRING_USAGE, "Kullanım: taskkill [/?] [/f] [/im işlem adı | /pid işlem kimliği]\n"
|
||||
STRING_INVALID_OPTION, "Yanlışlık: Bilinmeyen veyâ geçersiz komut yatacı seçeneği belirtildi.\n"
|
||||
STRING_INVALID_PARAM, "Yanlışlık: Geçersiz komut yatacı değişkeni belirtildi.\n"
|
||||
STRING_MISSING_OPTION, "Yanlışlık: /im ve /pid seçeneklerinden biri belirtilmeli.\n"
|
||||
STRING_MISSING_PARAM, "Yanlışlık: %1 seçeneği bir komut yatacı değişkeni bekler.\n"
|
||||
STRING_MUTUAL_EXCLUSIVE, "Yanlışlık: /im ve /pid seçenekleri birbirini dışlayandır.\n"
|
||||
STRING_CLOSE_PID_SEARCH, "PID'i %1!u! olan işlemin üst düzey penceresine kapatma iletisi gönderildi.\n"
|
||||
STRING_CLOSE_PROC_SRCH, "PID'i %2!u! olan ""%1"" işleminin üst düzey penceresine kapatma iletisi gönderildi.\n"
|
||||
STRING_TERM_PID_SEARCH, "PID'i %1!u! olan işlem zorla sonlandırıldı.\n"
|
||||
STRING_TERM_PROC_SEARCH, "PID'i %2!u! olan ""%1"" işlemi zorla sonlandırıldı.\n"
|
||||
STRING_SEARCH_FAILED, "Yanlışlık: ""%1"" işlemi bulunamadı.\n"
|
||||
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"
|
||||
}
|
21
base/applications/cmdutils/taskkill/lang/zh-CN.rc
Normal file
21
base/applications/cmdutils/taskkill/lang/zh-CN.rc
Normal file
|
@ -0,0 +1,21 @@
|
|||
/* Simplified Chinese translation by Henry Tang Ih 2016 (henrytang2@hotmail.com) */
|
||||
|
||||
LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
|
||||
|
||||
STRINGTABLE
|
||||
{
|
||||
STRING_USAGE, "用法: taskkill [/?] [/f] [/im 进程名称 | /pid 进程 ID]\n"
|
||||
STRING_INVALID_OPTION, "错误: 未知或无效的命令行选项指定。\n"
|
||||
STRING_INVALID_PARAM, "错误: 无效的命令行参数指定。\n"
|
||||
STRING_MISSING_OPTION, "错误: 选项 /im 或 /pid 之一必须指定。\n"
|
||||
STRING_MISSING_PARAM, "错误: %1 选项需要命令行参数。\n"
|
||||
STRING_MUTUAL_EXCLUSIVE, "错误: 选项 /im 和 /pid 是互斥的。\n"
|
||||
STRING_CLOSE_PID_SEARCH, "关闭消息发送到顶级窗口过程的 PID %1!u!。\n"
|
||||
STRING_CLOSE_PROC_SRCH, "关闭消息发送到顶级窗口的过程 ""%1"" 与 PID %2!u!.\n"
|
||||
STRING_TERM_PID_SEARCH, "过程与 PID %1!u! 被强行终止。\n"
|
||||
STRING_TERM_PROC_SEARCH, " ""%1"" 过程与 PID %2!u! 被强行终止。\n"
|
||||
STRING_SEARCH_FAILED, "错误: 找不到进程 ""%1""。\n"
|
||||
STRING_ENUM_FAILED, "错误: 无法枚举进程列表。\n"
|
||||
STRING_TERMINATE_FAILED, "错误: 无法终止进程 ""%1""。\n"
|
||||
STRING_SELF_TERMINATION, "错误: 不允许自我终止的进程。\n"
|
||||
}
|
21
base/applications/cmdutils/taskkill/lang/zh-TW.rc
Normal file
21
base/applications/cmdutils/taskkill/lang/zh-TW.rc
Normal file
|
@ -0,0 +1,21 @@
|
|||
/* Traditional Chinese translation by Henry Tang Ih 2016 (henrytang2@hotmail.com) */
|
||||
|
||||
LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL
|
||||
|
||||
STRINGTABLE
|
||||
{
|
||||
STRING_USAGE, "用法: taskkill [/?] [/f] [/im 進程名稱 | /pid 進程 ID]\n"
|
||||
STRING_INVALID_OPTION, "錯誤: 未知或不正確命令列選項指定。\n"
|
||||
STRING_INVALID_PARAM, "錯誤: 不正確命令列參數指定。\n"
|
||||
STRING_MISSING_OPTION, "錯誤: 選項 /im 或 /pid 之一必須指定。\n"
|
||||
STRING_MISSING_PARAM, "錯誤: %1 選項需要命令列參數。\n"
|
||||
STRING_MUTUAL_EXCLUSIVE, "錯誤: 選項 /im 和 /pid 是互斥的。\n"
|
||||
STRING_CLOSE_PID_SEARCH, "關閉消息發送到頂級視窗過程的 PID %1!u!。\n"
|
||||
STRING_CLOSE_PROC_SRCH, "關閉消息發送到頂級視窗的過程 ""%1"" 與 PID %2!u!.\n"
|
||||
STRING_TERM_PID_SEARCH, "過程與 PID %1!u! 被強行終止。\n"
|
||||
STRING_TERM_PROC_SEARCH, " ""%1"" 過程與 PID %2!u! 被強行終止。\n"
|
||||
STRING_SEARCH_FAILED, "錯誤: 找不到進程 ""%1""。\n"
|
||||
STRING_ENUM_FAILED, "錯誤: 無法枚舉進程清單。\n"
|
||||
STRING_TERMINATE_FAILED, "錯誤: 無法終止進程 ""%1""。\n"
|
||||
STRING_SELF_TERMINATION, "錯誤: 不允許自我終止的進程。\n"
|
||||
}
|
551
base/applications/cmdutils/taskkill/taskkill.c
Normal file
551
base/applications/cmdutils/taskkill/taskkill.c
Normal file
|
@ -0,0 +1,551 @@
|
|||
/*
|
||||
* Task termination utility
|
||||
*
|
||||
* Copyright 2008 Andrew Riedi
|
||||
* 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 <stdarg.h>
|
||||
#include <windef.h>
|
||||
#include <winbase.h>
|
||||
#include <wincon.h>
|
||||
#include <winuser.h>
|
||||
#include <psapi.h>
|
||||
#include <wine/debug.h>
|
||||
#include <wine/unicode.h>
|
||||
|
||||
#include "taskkill.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(taskkill);
|
||||
|
||||
static BOOL force_termination = FALSE;
|
||||
|
||||
static WCHAR **task_list;
|
||||
static unsigned int task_count;
|
||||
|
||||
struct pid_close_info
|
||||
{
|
||||
DWORD pid;
|
||||
BOOL found;
|
||||
};
|
||||
|
||||
static int taskkill_vprintfW(const WCHAR *msg, __ms_va_list va_args)
|
||||
{
|
||||
int wlen;
|
||||
DWORD count, ret;
|
||||
WCHAR msg_buffer[8192];
|
||||
|
||||
wlen = FormatMessageW(FORMAT_MESSAGE_FROM_STRING, msg, 0, 0, msg_buffer,
|
||||
sizeof(msg_buffer)/sizeof(*msg_buffer), &va_args);
|
||||
|
||||
ret = WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), msg_buffer, wlen, &count, NULL);
|
||||
if (!ret)
|
||||
{
|
||||
DWORD len;
|
||||
char *msgA;
|
||||
|
||||
/* On Windows WriteConsoleW() fails if the output is redirected. So fall
|
||||
* back to WriteFile(), assuming the console encoding is still the right
|
||||
* one in that case.
|
||||
*/
|
||||
len = WideCharToMultiByte(GetConsoleOutputCP(), 0, msg_buffer, wlen,
|
||||
NULL, 0, NULL, NULL);
|
||||
msgA = HeapAlloc(GetProcessHeap(), 0, len);
|
||||
if (!msgA)
|
||||
return 0;
|
||||
|
||||
WideCharToMultiByte(GetConsoleOutputCP(), 0, msg_buffer, wlen, msgA, len,
|
||||
NULL, NULL);
|
||||
WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), msgA, len, &count, FALSE);
|
||||
HeapFree(GetProcessHeap(), 0, msgA);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static int CDECL taskkill_printfW(const WCHAR *msg, ...)
|
||||
{
|
||||
__ms_va_list va_args;
|
||||
int len;
|
||||
|
||||
__ms_va_start(va_args, msg);
|
||||
len = taskkill_vprintfW(msg, va_args);
|
||||
__ms_va_end(va_args);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static int CDECL taskkill_message_printfW(int msg, ...)
|
||||
{
|
||||
__ms_va_list va_args;
|
||||
WCHAR msg_buffer[8192];
|
||||
int len;
|
||||
|
||||
LoadStringW(GetModuleHandleW(NULL), msg, msg_buffer,
|
||||
sizeof(msg_buffer)/sizeof(WCHAR));
|
||||
|
||||
__ms_va_start(va_args, msg);
|
||||
len = taskkill_vprintfW(msg_buffer, va_args);
|
||||
__ms_va_end(va_args);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static int taskkill_message(int msg)
|
||||
{
|
||||
static const WCHAR formatW[] = {'%','1',0};
|
||||
WCHAR msg_buffer[8192];
|
||||
|
||||
LoadStringW(GetModuleHandleW(NULL), msg, msg_buffer,
|
||||
sizeof(msg_buffer)/sizeof(WCHAR));
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
static DWORD *enumerate_processes(DWORD *list_count)
|
||||
{
|
||||
DWORD *pid_list, alloc_bytes = 1024 * sizeof(*pid_list), needed_bytes;
|
||||
|
||||
pid_list = HeapAlloc(GetProcessHeap(), 0, alloc_bytes);
|
||||
if (!pid_list)
|
||||
return NULL;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
DWORD *realloc_list;
|
||||
|
||||
if (!EnumProcesses(pid_list, alloc_bytes, &needed_bytes))
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, pid_list);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* EnumProcesses can't signal an insufficient buffer condition, so the
|
||||
* only way to possibly determine whether a larger buffer is required
|
||||
* is to see whether the written number of bytes is the same as the
|
||||
* buffer size. If so, the buffer will be reallocated to twice the
|
||||
* size. */
|
||||
if (alloc_bytes != needed_bytes)
|
||||
break;
|
||||
|
||||
alloc_bytes *= 2;
|
||||
realloc_list = HeapReAlloc(GetProcessHeap(), 0, pid_list, alloc_bytes);
|
||||
if (!realloc_list)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, pid_list);
|
||||
return NULL;
|
||||
}
|
||||
pid_list = realloc_list;
|
||||
}
|
||||
|
||||
*list_count = needed_bytes / sizeof(*pid_list);
|
||||
return pid_list;
|
||||
}
|
||||
|
||||
static BOOL get_process_name_from_pid(DWORD pid, WCHAR *buf, DWORD chars)
|
||||
{
|
||||
HANDLE process;
|
||||
HMODULE module;
|
||||
DWORD required_size;
|
||||
|
||||
process = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
|
||||
if (!process)
|
||||
return FALSE;
|
||||
|
||||
if (!EnumProcessModules(process, &module, sizeof(module), &required_size))
|
||||
{
|
||||
CloseHandle(process);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!GetModuleBaseNameW(process, module, buf, chars))
|
||||
{
|
||||
CloseHandle(process);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
CloseHandle(process);
|
||||
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)
|
||||
{
|
||||
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]);
|
||||
struct pid_close_info info = { pid };
|
||||
|
||||
if (pid == self_pid)
|
||||
{
|
||||
taskkill_message(STRING_SELF_TERMINATION);
|
||||
status_code = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
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]))
|
||||
{
|
||||
struct pid_close_info info = { pid_list[index] };
|
||||
|
||||
found_process = TRUE;
|
||||
if (pid_list[index] == self_pid)
|
||||
{
|
||||
taskkill_message(STRING_SELF_TERMINATION);
|
||||
status_code = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
static int terminate_processes(void)
|
||||
{
|
||||
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]);
|
||||
HANDLE process;
|
||||
|
||||
if (pid == self_pid)
|
||||
{
|
||||
taskkill_message(STRING_SELF_TERMINATION);
|
||||
status_code = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
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]))
|
||||
{
|
||||
HANDLE process;
|
||||
|
||||
if (pid_list[index] == self_pid)
|
||||
{
|
||||
taskkill_message(STRING_SELF_TERMINATION);
|
||||
status_code = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
found_process = TRUE;
|
||||
taskkill_message_printfW(STRING_TERM_PROC_SEARCH, task_list[i], pid_list[index]);
|
||||
CloseHandle(process);
|
||||
}
|
||||
}
|
||||
|
||||
if (!found_process)
|
||||
{
|
||||
taskkill_message_printfW(STRING_SEARCH_FAILED, task_list[i]);
|
||||
status_code = 128;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, pid_list);
|
||||
return status_code;
|
||||
}
|
||||
|
||||
static BOOL add_to_task_list(WCHAR *name)
|
||||
{
|
||||
static unsigned int list_size = 16;
|
||||
|
||||
if (!task_list)
|
||||
{
|
||||
task_list = HeapAlloc(GetProcessHeap(), 0,
|
||||
list_size * sizeof(*task_list));
|
||||
if (!task_list)
|
||||
return FALSE;
|
||||
}
|
||||
else if (task_count == list_size)
|
||||
{
|
||||
void *realloc_list;
|
||||
|
||||
list_size *= 2;
|
||||
realloc_list = HeapReAlloc(GetProcessHeap(), 0, task_list,
|
||||
list_size * sizeof(*task_list));
|
||||
if (!realloc_list)
|
||||
return FALSE;
|
||||
|
||||
task_list = realloc_list;
|
||||
}
|
||||
|
||||
task_list[task_count++] = name;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* 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. */
|
||||
static BOOL process_arguments(int argc, WCHAR *argv[])
|
||||
{
|
||||
static const WCHAR opForceTerminate[] = {'f',0};
|
||||
static const WCHAR opImage[] = {'i','m',0};
|
||||
static const WCHAR opPID[] = {'p','i','d',0};
|
||||
static const WCHAR opHelp[] = {'?',0};
|
||||
static const WCHAR opTerminateChildren[] = {'t',0};
|
||||
|
||||
if (argc > 1)
|
||||
{
|
||||
int i;
|
||||
WCHAR *argdata;
|
||||
BOOL has_im = FALSE, has_pid = FALSE;
|
||||
|
||||
/* Only the lone help option is recognized. */
|
||||
if (argc == 2)
|
||||
{
|
||||
argdata = argv[1];
|
||||
if ((*argdata == '/' || *argdata == '-') && !strcmpW(opHelp, argdata + 1))
|
||||
{
|
||||
taskkill_message(STRING_USAGE);
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 1; i < argc; i++)
|
||||
{
|
||||
BOOL got_im = FALSE, got_pid = FALSE;
|
||||
|
||||
argdata = argv[i];
|
||||
if (*argdata != '/' && *argdata != '-')
|
||||
goto invalid;
|
||||
argdata++;
|
||||
|
||||
if (!strcmpiW(opTerminateChildren, argdata))
|
||||
WINE_FIXME("argument T not supported\n");
|
||||
if (!strcmpiW(opForceTerminate, argdata))
|
||||
force_termination = TRUE;
|
||||
/* Options /IM and /PID appear to behave identically, except for
|
||||
* the fact that they cannot be specified at the same time. */
|
||||
else if ((got_im = !strcmpiW(opImage, argdata)) ||
|
||||
(got_pid = !strcmpiW(opPID, argdata)))
|
||||
{
|
||||
if (!argv[i + 1])
|
||||
{
|
||||
taskkill_message_printfW(STRING_MISSING_PARAM, argv[i]);
|
||||
taskkill_message(STRING_USAGE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (got_im) has_im = TRUE;
|
||||
if (got_pid) has_pid = TRUE;
|
||||
|
||||
if (has_im && has_pid)
|
||||
{
|
||||
taskkill_message(STRING_MUTUAL_EXCLUSIVE);
|
||||
taskkill_message(STRING_USAGE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!add_to_task_list(argv[i + 1]))
|
||||
return FALSE;
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
invalid:
|
||||
taskkill_message(STRING_INVALID_OPTION);
|
||||
taskkill_message(STRING_USAGE);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
taskkill_message(STRING_MISSING_OPTION);
|
||||
taskkill_message(STRING_USAGE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int wmain(int argc, WCHAR *argv[])
|
||||
{
|
||||
int status_code = 0;
|
||||
|
||||
if (!process_arguments(argc, argv))
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, task_list);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (force_termination)
|
||||
status_code = terminate_processes();
|
||||
else
|
||||
status_code = send_close_messages();
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, task_list);
|
||||
return status_code;
|
||||
}
|
37
base/applications/cmdutils/taskkill/taskkill.h
Normal file
37
base/applications/cmdutils/taskkill/taskkill.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Task termination utility private definitions
|
||||
*
|
||||
* 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 <windef.h>
|
||||
|
||||
/* Translation IDs. */
|
||||
#define STRING_USAGE 101
|
||||
#define STRING_INVALID_OPTION 102
|
||||
#define STRING_INVALID_PARAM 103
|
||||
#define STRING_MISSING_OPTION 104
|
||||
#define STRING_MISSING_PARAM 105
|
||||
#define STRING_MUTUAL_EXCLUSIVE 106
|
||||
#define STRING_CLOSE_PID_SEARCH 107
|
||||
#define STRING_CLOSE_PROC_SRCH 108
|
||||
#define STRING_TERM_PID_SEARCH 109
|
||||
#define STRING_TERM_PROC_SEARCH 110
|
||||
#define STRING_SEARCH_FAILED 111
|
||||
#define STRING_ENUM_FAILED 112
|
||||
#define STRING_TERMINATE_FAILED 113
|
||||
#define STRING_SELF_TERMINATION 114
|
56
base/applications/cmdutils/taskkill/taskkill.rc
Normal file
56
base/applications/cmdutils/taskkill/taskkill.rc
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* 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 "taskkill.h"
|
||||
|
||||
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
|
||||
|
||||
#define REACTOS_STR_FILE_DESCRIPTION "ReactOS Task Killer"
|
||||
#define REACTOS_STR_INTERNAL_NAME "taskkill"
|
||||
#define REACTOS_STR_ORIGINAL_FILENAME "taskkill.exe"
|
||||
#include <reactos/version.rc>
|
||||
|
||||
/* UTF-8 */
|
||||
#pragma code_page(65001)
|
||||
|
||||
#ifdef LANGUAGE_DE_DE
|
||||
#include "lang/de-DE.rc"
|
||||
#endif
|
||||
#ifdef LANGUAGE_EN_US
|
||||
#include "lang/en-US.rc"
|
||||
#endif
|
||||
#ifdef LANGUAGE_RO_RO
|
||||
#include "lang/ro-RO.rc"
|
||||
#endif
|
||||
#ifdef LANGUAGE_RU_RU
|
||||
#include "lang/ru-RU.rc"
|
||||
#endif
|
||||
#ifdef LANGAUGE_SQ_AL
|
||||
#include "lang/sq-AL.rc"
|
||||
#endif
|
||||
#ifdef LANGAUGE_TR_TR
|
||||
#include "lang/tr-TR.rc"
|
||||
#endif
|
||||
#ifdef LANGUAGE_ZH_CN
|
||||
#include "lang/zh-CN.rc"
|
||||
#endif
|
||||
#ifdef LANGUAGE_ZH_TW
|
||||
#include "lang/zh-TW.rc"
|
||||
#endif
|
Loading…
Add table
Add a link
Reference in a new issue