Company of Heroes: Battle of Crete needs a functioning tasklist.exe to exit properly.
From: Zhiyi Zhang zzhang@codeweavers.com
Company of Heroes: Battle of Crete needs a functioning tasklist.exe to exit properly. --- configure | 1 + configure.ac | 1 + programs/tasklist/Makefile.in | 3 +- programs/tasklist/tasklist.c | 234 +++++++++++++++++- programs/tasklist/tasklist.h | 38 +++ programs/tasklist/{version.rc => tasklist.rc} | 18 ++ programs/tasklist/tests/Makefile.in | 4 + programs/tasklist/tests/tasklist.c | 120 +++++++++ 8 files changed, 415 insertions(+), 4 deletions(-) create mode 100644 programs/tasklist/tasklist.h rename programs/tasklist/{version.rc => tasklist.rc} (69%) create mode 100644 programs/tasklist/tests/Makefile.in create mode 100644 programs/tasklist/tests/tasklist.c
diff --git a/configure b/configure index 836437fb89a..b2a5021e033 100755 --- a/configure +++ b/configure @@ -22100,6 +22100,7 @@ wine_fn_config_makefile programs/svchost enable_svchost wine_fn_config_makefile programs/systeminfo enable_systeminfo wine_fn_config_makefile programs/taskkill enable_taskkill wine_fn_config_makefile programs/tasklist enable_tasklist +wine_fn_config_makefile programs/tasklist/tests enable_tests wine_fn_config_makefile programs/taskmgr enable_taskmgr wine_fn_config_makefile programs/termsv enable_termsv wine_fn_config_makefile programs/uninstaller enable_uninstaller diff --git a/configure.ac b/configure.ac index fde3f29c770..e7fcf4c0479 100644 --- a/configure.ac +++ b/configure.ac @@ -3385,6 +3385,7 @@ WINE_CONFIG_MAKEFILE(programs/svchost) WINE_CONFIG_MAKEFILE(programs/systeminfo) WINE_CONFIG_MAKEFILE(programs/taskkill) WINE_CONFIG_MAKEFILE(programs/tasklist) +WINE_CONFIG_MAKEFILE(programs/tasklist/tests) WINE_CONFIG_MAKEFILE(programs/taskmgr) WINE_CONFIG_MAKEFILE(programs/termsv) WINE_CONFIG_MAKEFILE(programs/uninstaller) diff --git a/programs/tasklist/Makefile.in b/programs/tasklist/Makefile.in index 2163ca5ce76..8b1c206fe0e 100644 --- a/programs/tasklist/Makefile.in +++ b/programs/tasklist/Makefile.in @@ -1,7 +1,8 @@ MODULE = tasklist.exe +IMPORTS = user32
EXTRADLLFLAGS = -mconsole -municode
C_SRCS = tasklist.c
-RC_SRCS = version.rc +RC_SRCS = tasklist.rc diff --git a/programs/tasklist/tasklist.c b/programs/tasklist/tasklist.c index fd03f50dae6..23e32992184 100644 --- a/programs/tasklist/tasklist.c +++ b/programs/tasklist/tasklist.c @@ -1,5 +1,6 @@ /* * Copyright 2013 Austin English + * Copyright 2023 Zhiyi Zhang for CodeWeavers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -16,18 +17,245 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
+#include <windows.h> +#include <psapi.h> +#include "tasklist.h" #include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(tasklist);
+static int tasklist_vprintfW(HANDLE handle, const WCHAR *msg, va_list va_args) +{ + WCHAR msg_buffer[MAXSTRING]; + DWORD count; + int len_w; + + len_w = vswprintf(msg_buffer, ARRAY_SIZE(msg_buffer), msg, va_args); + + if (!WriteConsoleW(handle, msg_buffer, len_w, &count, NULL)) + { + char *msg_a; + DWORD len_a; + + /* On Windows WriteConsoleW() fails if the output is redirected. So fall back to WriteFile() + * with OEM code page. */ + len_a = WideCharToMultiByte(GetOEMCP(), 0, msg_buffer, len_w, NULL, 0, NULL, NULL); + msg_a = malloc(len_a); + if (!msg_a) + return 0; + + WideCharToMultiByte(GetOEMCP(), 0, msg_buffer, len_w, msg_a, len_a, NULL, NULL); + WriteFile(handle, msg_a, len_a, &count, FALSE); + free(msg_a); + } + + return count; +} + +static int WINAPIV tasklist_printfW(HANDLE handle, const WCHAR *msg, ...) +{ + va_list va_args; + int len; + + va_start(va_args, msg); + len = tasklist_vprintfW(handle, msg, va_args); + va_end(va_args); + + return len; +} + +static int tasklist_message(int msg) +{ + WCHAR msg_buffer[MAXSTRING]; + + LoadStringW(GetModuleHandleW(NULL), msg, msg_buffer, ARRAY_SIZE(msg_buffer)); + return tasklist_printfW(GetStdHandle(STD_OUTPUT_HANDLE), msg_buffer); +} + +static DWORD *enumerate_processes(DWORD *list_count) +{ + DWORD *pid_list, *realloc_list, alloc_bytes, needed_bytes; + + *list_count = 0; + + alloc_bytes = 1024 * sizeof(*pid_list); + pid_list = malloc(alloc_bytes); + if (!pid_list) + return NULL; + + for (;;) + { + if (!EnumProcesses(pid_list, alloc_bytes, &needed_bytes)) + { + free(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 (needed_bytes != alloc_bytes) + break; + + alloc_bytes *= 2; + realloc_list = realloc(pid_list, alloc_bytes); + if (!realloc_list) + { + free(pid_list); + return NULL; + } + pid_list = realloc_list; + } + + *list_count = needed_bytes / sizeof(*pid_list); + return pid_list; +} + +static NUMBERFMTW *tasklist_get_memory_format(void) +{ + static NUMBERFMTW format = {0, 0, 0, NULL, NULL, 1}; + static WCHAR grouping[3], decimal[2], thousand[2]; + static BOOL initialized; + + if (initialized) + return &format; + + if (!GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_ILZERO | LOCALE_RETURN_NUMBER, + (WCHAR *)&format.LeadingZero, 2)) + format.LeadingZero = 0; + + if (!GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SGROUPING, grouping, ARRAY_SIZE(grouping))) + format.Grouping = 3; + else + format.Grouping = (grouping[2] == '2' ? 32 : grouping[0] - '0'); + + if (!GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, decimal, ARRAY_SIZE(decimal))) + wcscpy(decimal, L"."); + + if (!GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, thousand, ARRAY_SIZE(thousand))) + wcscpy(thousand, L","); + + format.lpDecimalSep = decimal; + format.lpThousandSep = thousand; + initialized = TRUE; + return &format; +} + +static void tasklist_get_header(struct tasklist_process_info *header) +{ + HMODULE module; + + module = GetModuleHandleW(NULL); + LoadStringW(module, STRING_IMAGE_NAME, header->image_name, ARRAY_SIZE(header->image_name)); + LoadStringW(module, STRING_PID, header->pid, ARRAY_SIZE(header->pid)); + LoadStringW(module, STRING_SESSION_NAME, header->session_name, ARRAY_SIZE(header->session_name)); + LoadStringW(module, STRING_SESSION_NUMBER, header->session_number, ARRAY_SIZE(header->session_number)); + LoadStringW(module, STRING_MEM_USAGE, header->memory_usage, ARRAY_SIZE(header->memory_usage)); +} + +static BOOL tasklist_get_process_info(DWORD pid, struct tasklist_process_info *info) +{ + PROCESS_MEMORY_COUNTERS memory_counters; + BOOL ret = FALSE; + DWORD session_id; + WCHAR buffer[16]; + HANDLE process; + + memset(info, 0, sizeof(*info)); + process = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid); + if (!process) + { + WINE_FIXME("Failed to open process, %lu.\n", GetLastError()); + return FALSE; + } + + if (!GetModuleBaseNameW(process, NULL, info->image_name, ARRAY_SIZE(info->image_name) - 1)) + { + WINE_FIXME("Failed to get process module base name, %lu.\n", GetLastError()); + goto done; + } + + if (!ProcessIdToSessionId(pid, &session_id)) + { + WINE_FIXME("Failed to get process session id, %lu.\n", GetLastError()); + goto done; + } + + if (GetProcessMemoryInfo(process, &memory_counters, sizeof(memory_counters))) + { + swprintf(buffer, ARRAY_SIZE(buffer), L"%u", memory_counters.WorkingSetSize / 1024); + if (!GetNumberFormatW(LOCALE_USER_DEFAULT, 0, buffer, tasklist_get_memory_format(), + info->memory_usage, ARRAY_SIZE(info->memory_usage))) + { + WINE_FIXME("Failed to format memory usage number, %lu.\n", GetLastError()); + goto done; + } + + LoadStringW(GetModuleHandleW(NULL), STRING_K, buffer, ARRAY_SIZE(buffer)); + wcscat(info->memory_usage, L" "); + wcscat(info->memory_usage, buffer); + } + else + { + wcscpy(info->memory_usage, L"N/A"); + } + + swprintf(info->pid, ARRAY_SIZE(info->pid), L"%u", pid); + wcscpy(info->session_name, session_id == 0 ? L"Services" : L"Console"); + swprintf(info->session_number, ARRAY_SIZE(info->session_number), L"%u", session_id); + ret = TRUE; + +done: + CloseHandle(process); + return ret; +} + +static void tasklist_print(void) +{ + struct tasklist_process_info header, info; + DWORD *pid_list, list_count, i; + + tasklist_printfW(GetStdHandle(STD_OUTPUT_HANDLE), L"\r\n"); + tasklist_get_header(&header); + tasklist_printfW(GetStdHandle(STD_OUTPUT_HANDLE), + L"%-25.25s %8.8s %-16.16s %11.11s %12.12s\r\n" + L"========================= ======== ================ =========== ============\r\n", + header.image_name, header.pid, header.session_name, header.session_number, header.memory_usage); + + pid_list = enumerate_processes(&list_count); + for (i = 0; i < list_count; ++i) + { + if (!tasklist_get_process_info(pid_list[i], &info)) + continue; + + tasklist_printfW(GetStdHandle(STD_OUTPUT_HANDLE), + L"%-25.25s %8.8s %-16.16s %11.11s %12s\r\n", + info.image_name, info.pid, info.session_name, info.session_number, info.memory_usage); + } + free(pid_list); +} + int __cdecl wmain(int argc, WCHAR *argv[]) { int i;
- WINE_FIXME("stub:"); for (i = 0; i < argc; i++) - WINE_FIXME(" %s", wine_dbgstr_w(argv[i])); - WINE_FIXME("\n"); + WINE_TRACE("%s ", wine_dbgstr_w(argv[i])); + WINE_TRACE("\n"); + + for (i = 1; i < argc; i++) + { + if (!wcscmp(argv[i], L"/?")) + { + tasklist_message(STRING_USAGE); + return 0; + } + else + { + WINE_WARN("Ignoring option %s\n", wine_dbgstr_w(argv[i])); + } + }
+ tasklist_print(); return 0; } diff --git a/programs/tasklist/tasklist.h b/programs/tasklist/tasklist.h new file mode 100644 index 00000000000..707121680ec --- /dev/null +++ b/programs/tasklist/tasklist.h @@ -0,0 +1,38 @@ +/* + * Copyright 2023 Zhiyi Zhang for CodeWeavers + * + * 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> + +#define MAXSTRING 8192 + +#define STRING_USAGE 101 +#define STRING_IMAGE_NAME 102 +#define STRING_PID 103 +#define STRING_SESSION_NAME 104 +#define STRING_SESSION_NUMBER 105 +#define STRING_MEM_USAGE 106 +#define STRING_K 107 + +struct tasklist_process_info +{ + WCHAR image_name[32]; + WCHAR pid[32]; + WCHAR session_name[32]; + WCHAR session_number[32]; + WCHAR memory_usage[32]; +}; diff --git a/programs/tasklist/version.rc b/programs/tasklist/tasklist.rc similarity index 69% rename from programs/tasklist/version.rc rename to programs/tasklist/tasklist.rc index d6eecb55df2..d0776f1f6d9 100644 --- a/programs/tasklist/version.rc +++ b/programs/tasklist/tasklist.rc @@ -1,5 +1,6 @@ /* * Copyright 2013 Austin English + * Copyright 2023 Zhiyi Zhang for CodeWeavers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -16,6 +17,23 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
+#include "tasklist.h" + +#pragma makedep po + +LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT + +STRINGTABLE +{ + STRING_USAGE, "Usage: tasklist [/?]\r\n" + STRING_IMAGE_NAME, "Image Name" + STRING_PID, "PID" + STRING_SESSION_NAME, "Session Name" + STRING_SESSION_NUMBER, "Session#" + STRING_MEM_USAGE, "Mem Usage" + STRING_K, "K" +} + #define WINE_FILEDESCRIPTION_STR "Wine tasklist" #define WINE_FILENAME_STR "tasklist.exe" #define WINE_FILEVERSION 6,1,7601,16385 diff --git a/programs/tasklist/tests/Makefile.in b/programs/tasklist/tests/Makefile.in new file mode 100644 index 00000000000..ac6a97d0853 --- /dev/null +++ b/programs/tasklist/tests/Makefile.in @@ -0,0 +1,4 @@ +TESTDLL = tasklist.exe + +C_SRCS = \ + tasklist.c diff --git a/programs/tasklist/tests/tasklist.c b/programs/tasklist/tests/tasklist.c new file mode 100644 index 00000000000..cd4a2be0178 --- /dev/null +++ b/programs/tasklist/tests/tasklist.c @@ -0,0 +1,120 @@ +/* + * Copyright 2023 Zhiyi Zhang for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include <windows.h> +#include "wine/test.h" + +#define MAX_BUFFER 65536 + +static char stdout_buffer[MAX_BUFFER], stderr_buffer[MAX_BUFFER]; +static DWORD stdout_size, stderr_size; + +static void read_all_from_handle(HANDLE handle, char *buffer, DWORD *size) +{ + char bytes[4096]; + DWORD bytes_read; + + memset(buffer, 0, MAX_BUFFER); + *size = 0; + for (;;) + { + BOOL success = ReadFile(handle, bytes, sizeof(bytes), &bytes_read, NULL); + if (!success || !bytes_read) + break; + if (*size + bytes_read > MAX_BUFFER) + { + ok(FALSE, "Insufficient buffer.\n"); + break; + } + memcpy(buffer + *size, bytes, bytes_read); + *size += bytes_read; + } +} + +#define run_tasklist(a, b) _run_tasklist(__FILE__, __LINE__, a, b) +static void _run_tasklist(const char *file, int line, const char *commandline, int exitcode_expected) +{ + HANDLE child_stdout_write, child_stderr_write, parent_stdout_read, parent_stderr_read; + SECURITY_ATTRIBUTES security_attributes = {0}; + PROCESS_INFORMATION process_info = {0}; + STARTUPINFOA startup_info = {0}; + DWORD exitcode; + char cmd[256]; + + security_attributes.nLength = sizeof(SECURITY_ATTRIBUTES); + security_attributes.bInheritHandle = TRUE; + + CreatePipe(&parent_stdout_read, &child_stdout_write, &security_attributes, 0); + CreatePipe(&parent_stderr_read, &child_stderr_write, &security_attributes, 0); + SetHandleInformation(parent_stdout_read, HANDLE_FLAG_INHERIT, 0); + SetHandleInformation(parent_stderr_read, HANDLE_FLAG_INHERIT, 0); + + startup_info.cb = sizeof(STARTUPINFOA); + startup_info.hStdOutput = child_stdout_write; + startup_info.hStdError = child_stderr_write; + startup_info.dwFlags |= STARTF_USESTDHANDLES; + + sprintf(cmd, "tasklist.exe %s", commandline); + CreateProcessA(NULL, cmd, NULL, NULL, TRUE, 0, NULL, NULL, &startup_info, &process_info); + CloseHandle(child_stdout_write); + CloseHandle(child_stderr_write); + + read_all_from_handle(parent_stdout_read, stdout_buffer, &stdout_size); + read_all_from_handle(parent_stderr_read, stderr_buffer, &stderr_size); + CloseHandle(parent_stdout_read); + CloseHandle(parent_stderr_read); + + WaitForSingleObject(process_info.hProcess, INFINITE); + GetExitCodeProcess(process_info.hProcess, &exitcode); + CloseHandle(process_info.hProcess); + CloseHandle(process_info.hThread); + ok_(file, line)(exitcode == exitcode_expected, "Expected exitcode %d, got %ld\n", + exitcode_expected, exitcode); +} + +static void test_basic(void) +{ + char *pos; + + /* No options */ + run_tasklist("", 0); + ok(stdout_size > 0, "Unexpected stdout buffer size %ld.\n", stdout_size); + ok(stderr_size == 0, "Unexpected stderr buffer size %ld.\n", stderr_size); + pos = strstr(stdout_buffer, "\r\n" + "Image Name PID Session Name Session# Mem Usage\r\n" + "========================= ======== ================ =========== ============\r\n"); + ok(pos == stdout_buffer, "Got the wrong first line.\n"); + pos = strstr(stdout_buffer, "tasklist.exe"); + ok(!!pos, "Failed to list tasklist.exe.\n"); + + /* /? */ + run_tasklist("/?", 0); + ok(stdout_size > 0, "Unexpected stdout buffer size %ld.\n", stdout_size); + ok(stderr_size == 0, "Unexpected stderr buffer size %ld.\n", stderr_size); +} + +START_TEST(tasklist) +{ + if (PRIMARYLANGID(GetUserDefaultUILanguage()) != LANG_ENGLISH) + { + skip("Tests only work with English locale.\n"); + return; + } + + test_basic(); +}
From: Zhiyi Zhang zzhang@codeweavers.com
--- programs/tasklist/tasklist.c | 23 ++++++++++++++++------- programs/tasklist/tasklist.h | 5 +++++ programs/tasklist/tests/tasklist.c | 15 +++++++++++++++ 3 files changed, 36 insertions(+), 7 deletions(-)
diff --git a/programs/tasklist/tasklist.c b/programs/tasklist/tasklist.c index 23e32992184..d845cfea8e7 100644 --- a/programs/tasklist/tasklist.c +++ b/programs/tasklist/tasklist.c @@ -210,17 +210,21 @@ done: return ret; }
-static void tasklist_print(void) +static void tasklist_print(const struct tasklist_options *options) { struct tasklist_process_info header, info; DWORD *pid_list, list_count, i;
tasklist_printfW(GetStdHandle(STD_OUTPUT_HANDLE), L"\r\n"); - tasklist_get_header(&header); - tasklist_printfW(GetStdHandle(STD_OUTPUT_HANDLE), - L"%-25.25s %8.8s %-16.16s %11.11s %12.12s\r\n" - L"========================= ======== ================ =========== ============\r\n", - header.image_name, header.pid, header.session_name, header.session_number, header.memory_usage); + + if (!options->no_header) + { + tasklist_get_header(&header); + tasklist_printfW(GetStdHandle(STD_OUTPUT_HANDLE), + L"%-25.25s %8.8s %-16.16s %11.11s %12.12s\r\n" + L"========================= ======== ================ =========== ============\r\n", + header.image_name, header.pid, header.session_name, header.session_number, header.memory_usage); + }
pid_list = enumerate_processes(&list_count); for (i = 0; i < list_count; ++i) @@ -237,6 +241,7 @@ static void tasklist_print(void)
int __cdecl wmain(int argc, WCHAR *argv[]) { + struct tasklist_options options = {0}; int i;
for (i = 0; i < argc; i++) @@ -250,12 +255,16 @@ int __cdecl wmain(int argc, WCHAR *argv[]) tasklist_message(STRING_USAGE); return 0; } + else if (!wcsicmp(argv[i], L"/nh")) + { + options.no_header = TRUE; + } else { WINE_WARN("Ignoring option %s\n", wine_dbgstr_w(argv[i])); } }
- tasklist_print(); + tasklist_print(&options); return 0; } diff --git a/programs/tasklist/tasklist.h b/programs/tasklist/tasklist.h index 707121680ec..6add1f30277 100644 --- a/programs/tasklist/tasklist.h +++ b/programs/tasklist/tasklist.h @@ -36,3 +36,8 @@ struct tasklist_process_info WCHAR session_number[32]; WCHAR memory_usage[32]; }; + +struct tasklist_options +{ + BOOL no_header; +}; diff --git a/programs/tasklist/tests/tasklist.c b/programs/tasklist/tests/tasklist.c index cd4a2be0178..2c4d77855b0 100644 --- a/programs/tasklist/tests/tasklist.c +++ b/programs/tasklist/tests/tasklist.c @@ -108,6 +108,20 @@ static void test_basic(void) ok(stderr_size == 0, "Unexpected stderr buffer size %ld.\n", stderr_size); }
+static void test_no_header(void) +{ + char *pos; + + /* /nh */ + run_tasklist("/nh", 0); + ok(stdout_size > 0, "Unexpected stdout buffer size %ld.\n", stdout_size); + ok(stderr_size == 0, "Unexpected stderr buffer size %ld.\n", stderr_size); + pos = strstr(stdout_buffer, "Image Name"); + ok(!pos, "Got header.\n"); + pos = strstr(stdout_buffer, "="); + ok(!pos, "Got header.\n"); +} + START_TEST(tasklist) { if (PRIMARYLANGID(GetUserDefaultUILanguage()) != LANG_ENGLISH) @@ -117,4 +131,5 @@ START_TEST(tasklist) }
test_basic(); + test_no_header(); }
From: Zhiyi Zhang zzhang@codeweavers.com
--- programs/tasklist/tasklist.c | 85 ++++++++++++++++++++++++++---- programs/tasklist/tasklist.h | 9 ++++ programs/tasklist/tasklist.rc | 1 + programs/tasklist/tests/tasklist.c | 43 +++++++++++++++ 4 files changed, 128 insertions(+), 10 deletions(-)
diff --git a/programs/tasklist/tasklist.c b/programs/tasklist/tasklist.c index d845cfea8e7..ce2028726c9 100644 --- a/programs/tasklist/tasklist.c +++ b/programs/tasklist/tasklist.c @@ -72,6 +72,14 @@ static int tasklist_message(int msg) return tasklist_printfW(GetStdHandle(STD_OUTPUT_HANDLE), msg_buffer); }
+static int tasklist_error(int msg) +{ + WCHAR msg_buffer[MAXSTRING]; + + LoadStringW(GetModuleHandleW(NULL), msg, msg_buffer, ARRAY_SIZE(msg_buffer)); + return tasklist_printfW(GetStdHandle(STD_ERROR_HANDLE), msg_buffer); +} + static DWORD *enumerate_processes(DWORD *list_count) { DWORD *pid_list, *realloc_list, alloc_bytes, needed_bytes; @@ -141,7 +149,8 @@ static NUMBERFMTW *tasklist_get_memory_format(void) return &format; }
-static void tasklist_get_header(struct tasklist_process_info *header) +static void tasklist_get_header(const struct tasklist_options *options, + struct tasklist_process_info *header) { HMODULE module;
@@ -151,6 +160,14 @@ static void tasklist_get_header(struct tasklist_process_info *header) LoadStringW(module, STRING_SESSION_NAME, header->session_name, ARRAY_SIZE(header->session_name)); LoadStringW(module, STRING_SESSION_NUMBER, header->session_number, ARRAY_SIZE(header->session_number)); LoadStringW(module, STRING_MEM_USAGE, header->memory_usage, ARRAY_SIZE(header->memory_usage)); + if (options->format == LIST) + { + wcscat(header->image_name, L":"); + wcscat(header->pid, L":"); + wcscat(header->session_name, L":"); + wcscat(header->session_number, L":"); + wcscat(header->memory_usage, L":"); + } }
static BOOL tasklist_get_process_info(DWORD pid, struct tasklist_process_info *info) @@ -215,15 +232,20 @@ static void tasklist_print(const struct tasklist_options *options) struct tasklist_process_info header, info; DWORD *pid_list, list_count, i;
- tasklist_printfW(GetStdHandle(STD_OUTPUT_HANDLE), L"\r\n"); + if (options->format == TABLE) + tasklist_printfW(GetStdHandle(STD_OUTPUT_HANDLE), L"\r\n");
+ tasklist_get_header(options, &header); if (!options->no_header) { - tasklist_get_header(&header); - tasklist_printfW(GetStdHandle(STD_OUTPUT_HANDLE), - L"%-25.25s %8.8s %-16.16s %11.11s %12.12s\r\n" - L"========================= ======== ================ =========== ============\r\n", - header.image_name, header.pid, header.session_name, header.session_number, header.memory_usage); + if (options->format == TABLE) + tasklist_printfW(GetStdHandle(STD_OUTPUT_HANDLE), + L"%-25.25s %8.8s %-16.16s %11.11s %12.12s\r\n" + L"========================= ======== ================ =========== ============\r\n", + header.image_name, header.pid, header.session_name, header.session_number, header.memory_usage); + else if (options->format == CSV) + tasklist_printfW(GetStdHandle(STD_OUTPUT_HANDLE), L""%s","%s","%s","%s","%s"\r\n", + header.image_name, header.pid, header.session_name, header.session_number, header.memory_usage); }
pid_list = enumerate_processes(&list_count); @@ -232,9 +254,27 @@ static void tasklist_print(const struct tasklist_options *options) if (!tasklist_get_process_info(pid_list[i], &info)) continue;
- tasklist_printfW(GetStdHandle(STD_OUTPUT_HANDLE), - L"%-25.25s %8.8s %-16.16s %11.11s %12s\r\n", - info.image_name, info.pid, info.session_name, info.session_number, info.memory_usage); + if (options->format == TABLE) + tasklist_printfW(GetStdHandle(STD_OUTPUT_HANDLE), + L"%-25.25s %8.8s %-16.16s %11.11s %12s\r\n", + info.image_name, info.pid, info.session_name, info.session_number, info.memory_usage); + else if (options->format == CSV) + tasklist_printfW(GetStdHandle(STD_OUTPUT_HANDLE), + L""%s","%s","%s","%s","%s"\r\n", + info.image_name, info.pid, info.session_name, info.session_number, info.memory_usage); + else if (options->format == LIST) + tasklist_printfW(GetStdHandle(STD_OUTPUT_HANDLE), + L"\r\n" + L"%-13.13s %s\r\n" + L"%-13.13s %s\r\n" + L"%-13.13s %s\r\n" + L"%-13.13s %s\r\n" + L"%-13.13s %s\r\n", + header.image_name, info.image_name, + header.pid, info.pid, + header.session_name, info.session_name, + header.session_number, info.session_number, + header.memory_usage, info.memory_usage); } free(pid_list); } @@ -259,6 +299,31 @@ int __cdecl wmain(int argc, WCHAR *argv[]) { options.no_header = TRUE; } + else if (!wcsicmp(argv[i], L"/fo")) + { + if (i + 1 >= argc) + { + tasklist_error(STRING_INVALID_SYNTAX); + return 1; + } + else if (!wcsicmp(argv[i + 1], L"TABLE")) + { + options.format = TABLE; + } + else if (!wcsicmp(argv[i + 1], L"CSV")) + { + options.format = CSV; + } + else if (!wcsicmp(argv[i + 1], L"LIST")) + { + options.format = LIST; + } + else + { + tasklist_error(STRING_INVALID_SYNTAX); + return 1; + } + } else { WINE_WARN("Ignoring option %s\n", wine_dbgstr_w(argv[i])); diff --git a/programs/tasklist/tasklist.h b/programs/tasklist/tasklist.h index 6add1f30277..5e4e90960ea 100644 --- a/programs/tasklist/tasklist.h +++ b/programs/tasklist/tasklist.h @@ -27,6 +27,14 @@ #define STRING_SESSION_NUMBER 105 #define STRING_MEM_USAGE 106 #define STRING_K 107 +#define STRING_INVALID_SYNTAX 108 + +enum tasklist_format +{ + TABLE = 0, + CSV = 1, + LIST = 2, +};
struct tasklist_process_info { @@ -40,4 +48,5 @@ struct tasklist_process_info struct tasklist_options { BOOL no_header; + enum tasklist_format format; }; diff --git a/programs/tasklist/tasklist.rc b/programs/tasklist/tasklist.rc index d0776f1f6d9..10bb965318c 100644 --- a/programs/tasklist/tasklist.rc +++ b/programs/tasklist/tasklist.rc @@ -32,6 +32,7 @@ STRINGTABLE STRING_SESSION_NUMBER, "Session#" STRING_MEM_USAGE, "Mem Usage" STRING_K, "K" + STRING_INVALID_SYNTAX, "ERROR: Invalid syntax\r\n" }
#define WINE_FILEDESCRIPTION_STR "Wine tasklist" diff --git a/programs/tasklist/tests/tasklist.c b/programs/tasklist/tests/tasklist.c index 2c4d77855b0..011bfdeb382 100644 --- a/programs/tasklist/tests/tasklist.c +++ b/programs/tasklist/tests/tasklist.c @@ -122,6 +122,48 @@ static void test_no_header(void) ok(!pos, "Got header.\n"); }
+static void test_format(void) +{ + char *pos; + + /* /fo */ + run_tasklist("/fo", 1); + ok(stdout_size == 0, "Unexpected stdout buffer size %ld.\n", stdout_size); + ok(stderr_size > 0, "Unexpected stderr buffer size %ld.\n", stderr_size); + + /* /fo invalid */ + run_tasklist("/fo invalid", 1); + ok(stdout_size == 0, "Unexpected stdout buffer size %ld.\n", stdout_size); + ok(stderr_size > 0, "Unexpected stderr buffer size %ld.\n", stderr_size); + + /* /fo TABLE */ + run_tasklist("/fo TABLE", 0); + ok(stdout_size > 0, "Unexpected stdout buffer size %ld.\n", stdout_size); + ok(stderr_size == 0, "Unexpected stderr buffer size %ld.\n", stderr_size); + pos = strstr(stdout_buffer, "\r\n" + "Image Name PID Session Name Session# Mem Usage\r\n" + "========================= ======== ================ =========== ============\r\n"); + ok(pos == stdout_buffer, "Got the wrong first line.\n"); + pos = strstr(stdout_buffer, "tasklist.exe"); + ok(!!pos, "Failed to list tasklist.exe.\n"); + + /* /fo CSV */ + run_tasklist("/fo CSV", 0); + ok(stdout_size > 0, "Unexpected stdout buffer size %ld.\n", stdout_size); + ok(stderr_size == 0, "Unexpected stderr buffer size %ld.\n", stderr_size); + pos = strstr(stdout_buffer, ""Image Name","PID","Session Name","Session#","Mem Usage""); + ok(pos == stdout_buffer, "Got the wrong first line.\n"); + pos = strstr(stdout_buffer, ""tasklist.exe","); + ok(!!pos, "Failed to list tasklist.exe.\n"); + + /* /fo LIST */ + run_tasklist("/fo LIST", 0); + ok(stdout_size > 0, "Unexpected stdout buffer size %ld.\n", stdout_size); + ok(stderr_size == 0, "Unexpected stderr buffer size %ld.\n", stderr_size); + pos = strstr(stdout_buffer, "Image Name: tasklist.exe"); + ok(!!pos, "Failed to list tasklist.exe.\n"); +} + START_TEST(tasklist) { if (PRIMARYLANGID(GetUserDefaultUILanguage()) != LANG_ENGLISH) @@ -132,4 +174,5 @@ START_TEST(tasklist)
test_basic(); test_no_header(); + test_format(); }
From: Zhiyi Zhang zzhang@codeweavers.com
Some filters such as STATUS and CPUTIME are not implemented.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=48596 --- programs/tasklist/tasklist.c | 173 ++++++++++++++++++++++++++++- programs/tasklist/tasklist.h | 32 ++++++ programs/tasklist/tasklist.rc | 1 + programs/tasklist/tests/tasklist.c | 97 ++++++++++++++++ 4 files changed, 298 insertions(+), 5 deletions(-)
diff --git a/programs/tasklist/tasklist.c b/programs/tasklist/tasklist.c index ce2028726c9..7c477806142 100644 --- a/programs/tasklist/tasklist.c +++ b/programs/tasklist/tasklist.c @@ -217,6 +217,9 @@ static BOOL tasklist_get_process_info(DWORD pid, struct tasklist_process_info *i wcscpy(info->memory_usage, L"N/A"); }
+ info->pid_value = pid; + info->memory_usage_value = memory_counters.WorkingSetSize / 1024; + info->session_id_value = session_id; swprintf(info->pid, ARRAY_SIZE(info->pid), L"%u", pid); wcscpy(info->session_name, session_id == 0 ? L"Services" : L"Console"); swprintf(info->session_number, ARRAY_SIZE(info->session_number), L"%u", session_id); @@ -227,6 +230,67 @@ done: return ret; }
+static BOOL tasklist_check_filters(const struct tasklist_filter *filter, + const struct tasklist_process_info *info) +{ + DWORD left_dword_operand, right_dword_operand; + const WCHAR *left_string_operand = NULL; + BOOL eval; + + while (filter) + { + left_string_operand = NULL; + left_dword_operand = 0; + eval = FALSE; + + if (filter->name == IMAGENAME) + left_string_operand = info->image_name; + else if (filter->name == SESSIONNAME) + left_string_operand = info->session_name; + else if (filter->name == PID) + left_dword_operand = info->pid_value; + else if (filter->name == SESSION) + left_dword_operand = info->session_id_value; + else if (filter->name == MEMUSAGE) + left_dword_operand = info->memory_usage_value; + + if (left_string_operand) + { + eval = wcsicmp(left_string_operand, filter->value); + if (filter->op == EQ) + eval = !eval; + } + else + { + if (swscanf(filter->value, L"%lu", &right_dword_operand) != 1) + { + WINE_ERR("Invalid filter operand %s.\n", wine_dbgstr_w(filter->value)); + return FALSE; + } + + if (filter->op == EQ) + eval = left_dword_operand == right_dword_operand; + else if (filter->op == NE) + eval = left_dword_operand != right_dword_operand; + else if (filter->op == GT) + eval = left_dword_operand > right_dword_operand; + else if (filter->op == LT) + eval = left_dword_operand < right_dword_operand; + else if (filter->op == GE) + eval = left_dword_operand >= right_dword_operand; + else if (filter->op == LE) + eval = left_dword_operand <= right_dword_operand; + } + + if (!eval) + return FALSE; + + filter = filter->next; + } + + return TRUE; +} + static void tasklist_print(const struct tasklist_options *options) { struct tasklist_process_info header, info; @@ -254,6 +318,9 @@ static void tasklist_print(const struct tasklist_options *options) if (!tasklist_get_process_info(pid_list[i], &info)) continue;
+ if (!tasklist_check_filters(options->filters, &info)) + continue; + if (options->format == TABLE) tasklist_printfW(GetStdHandle(STD_OUTPUT_HANDLE), L"%-25.25s %8.8s %-16.16s %11.11s %12s\r\n", @@ -282,7 +349,9 @@ static void tasklist_print(const struct tasklist_options *options) int __cdecl wmain(int argc, WCHAR *argv[]) { struct tasklist_options options = {0}; - int i; + struct tasklist_filter *filter, *next, **filter_ptr = &options.filters; + WCHAR *filter_name, *filter_op, *buffer; + int i, ret = 0;
for (i = 0; i < argc; i++) WINE_TRACE("%s ", wine_dbgstr_w(argv[i])); @@ -293,7 +362,7 @@ int __cdecl wmain(int argc, WCHAR *argv[]) if (!wcscmp(argv[i], L"/?")) { tasklist_message(STRING_USAGE); - return 0; + goto done; } else if (!wcsicmp(argv[i], L"/nh")) { @@ -304,7 +373,8 @@ int __cdecl wmain(int argc, WCHAR *argv[]) if (i + 1 >= argc) { tasklist_error(STRING_INVALID_SYNTAX); - return 1; + ret = 1; + goto done; } else if (!wcsicmp(argv[i + 1], L"TABLE")) { @@ -321,8 +391,92 @@ int __cdecl wmain(int argc, WCHAR *argv[]) else { tasklist_error(STRING_INVALID_SYNTAX); - return 1; + ret = 1; + goto done; + } + } + else if (!wcsicmp(argv[i], L"/fi")) + { + if (i + 1 >= argc || !(filter_name = wcstok(argv[i + 1], L" ", &buffer))) + { + tasklist_error(STRING_INVALID_SYNTAX); + ret = 1; + goto done; } + + filter = calloc(1, sizeof(*filter)); + if (!filter) + { + WINE_ERR("Out of memory.\n"); + ret = 1; + goto done; + } + + if (!wcsicmp(filter_name, L"IMAGENAME")) + filter->name = IMAGENAME; + else if (!wcsicmp(filter_name, L"PID")) + filter->name = PID; + else if (!wcsicmp(filter_name, L"SESSION")) + filter->name = SESSION; + else if (!wcsicmp(filter_name, L"SESSIONNAME")) + filter->name = SESSIONNAME; + else if (!wcsicmp(filter_name, L"MEMUSAGE")) + filter->name = MEMUSAGE; + else + { + WINE_WARN("Ignoring filter %s.\n", wine_dbgstr_w(filter_name)); + free(filter); + continue; + } + + filter_op = wcstok(NULL, L" ", &buffer); + if (!filter_op) + { + tasklist_error(STRING_FILTER_NOT_RECOGNIZED); + free(filter); + ret = 1; + goto done; + } + + if (!wcsicmp(filter_op, L"EQ")) + filter->op = EQ; + else if (!wcsicmp(filter_op, L"NE")) + filter->op = NE; + else if (!wcsicmp(filter_op, L"GT")) + filter->op = GT; + else if (!wcsicmp(filter_op, L"LT")) + filter->op = LT; + else if (!wcsicmp(filter_op, L"GE")) + filter->op = GE; + else if (!wcsicmp(filter_op, L"LE")) + filter->op = LE; + else + { + tasklist_error(STRING_FILTER_NOT_RECOGNIZED); + free(filter); + ret = 1; + goto done; + } + + if (filter->op >= GT && filter->name != PID && filter->name != SESSION && filter->name != MEMUSAGE) + { + tasklist_error(STRING_FILTER_NOT_RECOGNIZED); + free(filter); + ret = 1; + goto done; + } + + filter->value = wcstok(NULL, L" ", &buffer); + if (!filter->value) + { + tasklist_error(STRING_FILTER_NOT_RECOGNIZED); + free(filter); + ret = 1; + goto done; + } + + *filter_ptr = filter; + filter_ptr = &filter->next; } else { @@ -331,5 +485,14 @@ int __cdecl wmain(int argc, WCHAR *argv[]) }
tasklist_print(&options); - return 0; + +done: + next = options.filters; + while (next) + { + filter = next->next; + free(next); + next = filter; + } + return ret; } diff --git a/programs/tasklist/tasklist.h b/programs/tasklist/tasklist.h index 5e4e90960ea..7b05224757f 100644 --- a/programs/tasklist/tasklist.h +++ b/programs/tasklist/tasklist.h @@ -28,6 +28,7 @@ #define STRING_MEM_USAGE 106 #define STRING_K 107 #define STRING_INVALID_SYNTAX 108 +#define STRING_FILTER_NOT_RECOGNIZED 109
enum tasklist_format { @@ -36,8 +37,38 @@ enum tasklist_format LIST = 2, };
+enum tasklist_filter_name +{ + IMAGENAME = 1, + PID = 2, + SESSION = 3, + SESSIONNAME = 4, + MEMUSAGE = 5, +}; + +enum tasklist_filter_operator +{ + EQ = 0, + NE = 1, + GT = 2, + LT = 3, + GE = 4, + LE = 5, +}; + +struct tasklist_filter +{ + enum tasklist_filter_name name; + enum tasklist_filter_operator op; + WCHAR *value; + struct tasklist_filter *next; +}; + struct tasklist_process_info { + DWORD pid_value; + DWORD memory_usage_value; + DWORD session_id_value; WCHAR image_name[32]; WCHAR pid[32]; WCHAR session_name[32]; @@ -49,4 +80,5 @@ struct tasklist_options { BOOL no_header; enum tasklist_format format; + struct tasklist_filter *filters; }; diff --git a/programs/tasklist/tasklist.rc b/programs/tasklist/tasklist.rc index 10bb965318c..a9ca3f15e91 100644 --- a/programs/tasklist/tasklist.rc +++ b/programs/tasklist/tasklist.rc @@ -33,6 +33,7 @@ STRINGTABLE STRING_MEM_USAGE, "Mem Usage" STRING_K, "K" STRING_INVALID_SYNTAX, "ERROR: Invalid syntax\r\n" + STRING_FILTER_NOT_RECOGNIZED, "ERROR: The search filter cannot be recognized.\r\n" }
#define WINE_FILEDESCRIPTION_STR "Wine tasklist" diff --git a/programs/tasklist/tests/tasklist.c b/programs/tasklist/tests/tasklist.c index 011bfdeb382..d75f361748d 100644 --- a/programs/tasklist/tests/tasklist.c +++ b/programs/tasklist/tests/tasklist.c @@ -164,6 +164,102 @@ static void test_format(void) ok(!!pos, "Failed to list tasklist.exe.\n"); }
+static void test_filter(void) +{ + char options[256], *pos; + DWORD current_pid; + + current_pid = GetCurrentProcessId(); + + /* /fi */ + /* no value for fi */ + run_tasklist("/fi", 1); + ok(stdout_size == 0, "Unexpected stdout buffer size %ld.\n", stdout_size); + ok(stderr_size > 0, "Unexpected stderr buffer size %ld.\n", stderr_size); + + /* IMAGENAME eq */ + run_tasklist("/fi "IMAGENAME eq tasklist.exe"", 0); + ok(stdout_size > 0, "Unexpected stdout buffer size %ld.\n", stdout_size); + ok(stderr_size == 0, "Unexpected stderr buffer size %ld.\n", stderr_size); + pos = strstr(stdout_buffer, "tasklist.exe"); + ok(!!pos, "Failed to list tasklist.exe.\n"); + + /* IMAGENAME ne */ + run_tasklist("/fi "IMAGENAME ne explorer.exe"", 0); + ok(stdout_size > 0, "Unexpected stdout buffer size %ld.\n", stdout_size); + ok(stderr_size == 0, "Unexpected stderr buffer size %ld.\n", stderr_size); + pos = strstr(stdout_buffer, "explorer.exe"); + ok(!pos, "Got explorer.exe.\n"); + pos = strstr(stdout_buffer, "tasklist.exe"); + ok(!!pos, "Failed to list tasklist.exe.\n"); + + /* PID eq */ + sprintf(options, "/fi "PID eq %ld"", current_pid); + run_tasklist(options, 0); + ok(stdout_size > 0, "Unexpected stdout buffer size %ld.\n", stdout_size); + ok(stderr_size == 0, "Unexpected stderr buffer size %ld.\n", stderr_size); + pos = strstr(stdout_buffer, "tasklist.exe_test.exe"); + ok(!!pos, "Failed to list tasklist.exe_test.exe.\n"); + + /* PID ne */ + sprintf(options, "/fi "PID ne %ld"", current_pid); + run_tasklist(options, 0); + ok(stdout_size > 0, "Unexpected stdout buffer size %ld.\n", stdout_size); + ok(stderr_size == 0, "Unexpected stderr buffer size %ld.\n", stderr_size); + pos = strstr(stdout_buffer, "tasklist.exe_test.exe"); + ok(!pos, "Got tasklist.exe_test.exe.\n"); + pos = strstr(stdout_buffer, "explorer.exe"); + ok(!!pos, "Failed to list explorer.exe.\n"); + + /* PID gt */ + sprintf(options, "/fi "PID gt %ld"", current_pid - 1); + run_tasklist(options, 0); + ok(stdout_size > 0, "Unexpected stdout buffer size %ld.\n", stdout_size); + ok(stderr_size == 0, "Unexpected stderr buffer size %ld.\n", stderr_size); + pos = strstr(stdout_buffer, "tasklist.exe_test.exe"); + ok(!!pos, "Failed to list tasklist.exe_test.exe.\n"); + + /* PID lt */ + sprintf(options, "/fi "PID lt %ld"", current_pid + 1); + run_tasklist(options, 0); + ok(stdout_size > 0, "Unexpected stdout buffer size %ld.\n", stdout_size); + ok(stderr_size == 0, "Unexpected stderr buffer size %ld.\n", stderr_size); + pos = strstr(stdout_buffer, "tasklist.exe_test.exe"); + ok(!!pos, "Failed to list tasklist.exe_test.exe.\n"); + + /* PID ge */ + sprintf(options, "/fi "PID ge %ld"", current_pid); + run_tasklist(options, 0); + ok(stdout_size > 0, "Unexpected stdout buffer size %ld.\n", stdout_size); + ok(stderr_size == 0, "Unexpected stderr buffer size %ld.\n", stderr_size); + pos = strstr(stdout_buffer, "tasklist.exe_test.exe"); + ok(!!pos, "Failed to list tasklist.exe_test.exe.\n"); + + /* PID le */ + sprintf(options, "/fi "PID le %ld"", current_pid); + run_tasklist(options, 0); + ok(stdout_size > 0, "Unexpected stdout buffer size %ld.\n", stdout_size); + ok(stderr_size == 0, "Unexpected stderr buffer size %ld.\n", stderr_size); + pos = strstr(stdout_buffer, "tasklist.exe_test.exe"); + ok(!!pos, "Failed to list tasklist.exe_test.exe.\n"); + + /* IMAGENAME eq + PID eq */ + sprintf(options, "/fi "IMAGENAME eq tasklist.exe_test.exe" /fi "PID eq %ld"", current_pid); + run_tasklist(options, 0); + ok(stdout_size > 0, "Unexpected stdout buffer size %ld.\n", stdout_size); + ok(stderr_size == 0, "Unexpected stderr buffer size %ld.\n", stderr_size); + pos = strstr(stdout_buffer, "tasklist.exe_test.exe"); + ok(!!pos, "Failed to list tasklist.exe_test.exe.\n"); + + /* IMAGENAME eq + PID eq with wrong PID */ + sprintf(options, "/fi "IMAGENAME eq tasklist.exe_test.exe" /fi "PID eq %ld"", current_pid + 1); + run_tasklist(options, 0); + ok(stdout_size > 0, "Unexpected stdout buffer size %ld.\n", stdout_size); + ok(stderr_size == 0, "Unexpected stderr buffer size %ld.\n", stderr_size); + pos = strstr(stdout_buffer, "tasklist.exe_test.exe"); + ok(!pos, "Got tasklist.exe_test.exe.\n"); +} + START_TEST(tasklist) { if (PRIMARYLANGID(GetUserDefaultUILanguage()) != LANG_ENGLISH) @@ -175,4 +271,5 @@ START_TEST(tasklist) test_basic(); test_no_header(); test_format(); + test_filter(); }
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=132092
Your paranoid android.
=== w7pro64 (64 bit report) ===
tasklist.exe: tasklist.c:202: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:220: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:228: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:236: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:244: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:252: Test failed: Failed to list tasklist.exe_test.exe.
=== w864 (64 bit report) ===
tasklist.exe: tasklist.c:202: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:220: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:228: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:236: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:244: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:252: Test failed: Failed to list tasklist.exe_test.exe.
=== w1064v1507 (64 bit report) ===
tasklist.exe: tasklist.c:202: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:220: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:228: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:236: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:244: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:252: Test failed: Failed to list tasklist.exe_test.exe.
=== w1064v1809 (64 bit report) ===
tasklist.exe: tasklist.c:202: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:220: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:228: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:236: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:244: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:252: Test failed: Failed to list tasklist.exe_test.exe.
=== w1064_2qxl (64 bit report) ===
tasklist.exe: tasklist.c:202: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:220: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:228: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:236: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:244: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:252: Test failed: Failed to list tasklist.exe_test.exe.
=== w1064_adm (64 bit report) ===
tasklist.exe: tasklist.c:202: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:220: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:228: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:236: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:244: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:252: Test failed: Failed to list tasklist.exe_test.exe.
=== w1064_tsign (64 bit report) ===
tasklist.exe: tasklist.c:202: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:220: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:228: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:236: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:244: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:252: Test failed: Failed to list tasklist.exe_test.exe.
=== w10pro64 (64 bit report) ===
tasklist.exe: tasklist.c:202: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:220: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:228: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:236: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:244: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:252: Test failed: Failed to list tasklist.exe_test.exe.
=== w10pro64_en_AE_u8 (64 bit report) ===
tasklist.exe: tasklist.c:202: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:220: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:228: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:236: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:244: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:252: Test failed: Failed to list tasklist.exe_test.exe.
=== w11pro64_amd (64 bit report) ===
tasklist.exe: tasklist.c:202: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:220: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:228: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:236: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:244: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:252: Test failed: Failed to list tasklist.exe_test.exe.
=== debian11b (32 bit WoW report) ===
tasklist.exe: tasklist.c:212: Test failed: Failed to list explorer.exe.
On Fri Apr 21 03:46:43 2023 +0000, **** wrote:
Marvin replied on the mailing list:
Hi, It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated. The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details: The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=132092 Your paranoid android. === w7pro64 (64 bit report) === tasklist.exe: tasklist.c:202: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:220: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:228: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:236: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:244: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:252: Test failed: Failed to list tasklist.exe_test.exe. === w864 (64 bit report) === tasklist.exe: tasklist.c:202: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:220: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:228: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:236: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:244: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:252: Test failed: Failed to list tasklist.exe_test.exe. === w1064v1507 (64 bit report) === tasklist.exe: tasklist.c:202: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:220: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:228: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:236: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:244: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:252: Test failed: Failed to list tasklist.exe_test.exe. === w1064v1809 (64 bit report) === tasklist.exe: tasklist.c:202: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:220: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:228: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:236: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:244: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:252: Test failed: Failed to list tasklist.exe_test.exe. === w1064_2qxl (64 bit report) === tasklist.exe: tasklist.c:202: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:220: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:228: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:236: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:244: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:252: Test failed: Failed to list tasklist.exe_test.exe. === w1064_adm (64 bit report) === tasklist.exe: tasklist.c:202: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:220: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:228: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:236: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:244: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:252: Test failed: Failed to list tasklist.exe_test.exe. === w1064_tsign (64 bit report) === tasklist.exe: tasklist.c:202: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:220: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:228: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:236: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:244: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:252: Test failed: Failed to list tasklist.exe_test.exe. === w10pro64 (64 bit report) === tasklist.exe: tasklist.c:202: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:220: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:228: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:236: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:244: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:252: Test failed: Failed to list tasklist.exe_test.exe. === w10pro64_en_AE_u8 (64 bit report) === tasklist.exe: tasklist.c:202: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:220: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:228: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:236: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:244: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:252: Test failed: Failed to list tasklist.exe_test.exe. === w11pro64_amd (64 bit report) === tasklist.exe: tasklist.c:202: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:220: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:228: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:236: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:244: Test failed: Failed to list tasklist.exe_test.exe. tasklist.c:252: Test failed: Failed to list tasklist.exe_test.exe. === debian11b (32 bit WoW report) === tasklist.exe: tasklist.c:212: Test failed: Failed to list explorer.exe.
Looking into this.