diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index 60aaff4f..b685077a 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -214,6 +214,7 @@ patch_enable_all () enable_opencl_version_1_2="$1" enable_packager_DllMain="$1" enable_pdh_PdhLookupPerfNameByIndex_processor="$1" + enable_programs_findstr="$1" enable_quartz_MediaSeeking_Positions="$1" enable_riched20_Class_Tests="$1" enable_riched20_IText_Interface="$1" @@ -732,6 +733,9 @@ patch_enable () pdh-PdhLookupPerfNameByIndex-processor) enable_pdh_PdhLookupPerfNameByIndex_processor="$2" ;; + programs-findstr) + enable_programs_findstr="$2" + ;; quartz-MediaSeeking_Positions) enable_quartz_MediaSeeking_Positions="$2" ;; @@ -4245,6 +4249,21 @@ if test "$enable_pdh_PdhLookupPerfNameByIndex_processor" -eq 1; then ) >> "$patchlist" fi +# Patchset programs-findstr +# | +# | This patchset fixes the following Wine bugs: +# | * [#35254] findstr: Add minimal implementation +# | +# | Modified files: +# | * programs/findstr/Makefile.in, programs/findstr/findstr.rc, programs/findstr/main.c, programs/findstr/resources.h +# | +if test "$enable_programs_findstr" -eq 1; then + patch_apply programs-findstr/0001-findstr.exe-add-minimal-implementation.patch + ( + printf '%s\n' '+ { "Louis Lenders", "findstr.exe: Add minimal implementation.", 1 },'; + ) >> "$patchlist" +fi + # Patchset quartz-MediaSeeking_Positions # | # | Modified files: diff --git a/patches/programs-findstr/0001-findstr.exe-add-minimal-implementation.patch b/patches/programs-findstr/0001-findstr.exe-add-minimal-implementation.patch new file mode 100644 index 00000000..e5d7a5bf --- /dev/null +++ b/patches/programs-findstr/0001-findstr.exe-add-minimal-implementation.patch @@ -0,0 +1,354 @@ +From d8d1cce3600cfc6edc0908da462bf0760c01b16e Mon Sep 17 00:00:00 2001 +From: Louis Lenders +Date: Thu, 30 Jul 2020 19:29:43 +0200 +Subject: [PATCH] findstr.exe: add minimal implementation + +Signed-off-by: Louis Lenders +--- + programs/findstr/Makefile.in | 3 + + programs/findstr/findstr.rc | 27 +++++ + programs/findstr/main.c | 229 ++++++++++++++++++++++++++++++++++- + programs/findstr/resources.h | 29 +++++ + 4 files changed, 284 insertions(+), 4 deletions(-) + create mode 100644 programs/findstr/findstr.rc + create mode 100644 programs/findstr/resources.h + +diff --git a/programs/findstr/Makefile.in b/programs/findstr/Makefile.in +index 0f29794591b..454caadfc1b 100644 +--- a/programs/findstr/Makefile.in ++++ b/programs/findstr/Makefile.in +@@ -1,6 +1,9 @@ + MODULE = findstr.exe ++IMPORTS = user32 + + EXTRADLLFLAGS = -mconsole -municode -mno-cygwin + + C_SRCS = \ + main.c ++ ++RC_SRCS = findstr.rc +diff --git a/programs/findstr/findstr.rc b/programs/findstr/findstr.rc +new file mode 100644 +index 00000000000..3a6fad7eb1a +--- /dev/null ++++ b/programs/findstr/findstr.rc +@@ -0,0 +1,27 @@ ++/* ++ * Copyright 2019 Fabian Maurer ++ * ++ * 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 "resources.h" ++ ++STRINGTABLE ++{ ++ IDS_INVALID_PARAMETER "FINDSTR: Parameter format not correct\r\n" ++ IDS_INVALID_SWITCH "FINDSTR: Invalid switch\r\n" ++ IDS_FILE_NOT_FOUND "File not found - %s\r\n" ++ IDS_USAGE "Usage: findstr /options string filename\r\n" ++} +diff --git a/programs/findstr/main.c b/programs/findstr/main.c +index d25e1965f6e..590f39af225 100644 +--- a/programs/findstr/main.c ++++ b/programs/findstr/main.c +@@ -1,5 +1,6 @@ + /* + * Copyright 2012 Qian Hong ++ * Copyright 2018 Fabian Maurer + * + * 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,238 @@ + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + ++#include ++#include ++#include ++ ++#include "wine/heap.h" + #include "wine/debug.h" ++#include "resources.h" + + WINE_DEFAULT_DEBUG_CHANNEL(findstr); + ++static BOOL read_char_from_handle(HANDLE handle, char *char_out) ++{ ++ static char buffer[4096]; ++ static UINT buffer_max = 0; ++ static UINT buffer_pos = 0; ++ ++ /* Read next content into buffer */ ++ if (buffer_pos >= buffer_max) ++ { ++ BOOL success = ReadFile(handle, buffer, 4096, &buffer_max, NULL); ++ if (!success || !buffer_max) ++ return FALSE; ++ buffer_pos = 0; ++ } ++ ++ *char_out = buffer[buffer_pos++]; ++ return TRUE; ++} ++ ++/* Read a line from a handle, returns NULL if the end is reached */ ++static WCHAR* read_line_from_handle(HANDLE handle) ++{ ++ int line_max = 4096; ++ int length = 0; ++ WCHAR *line_converted; ++ int line_converted_length; ++ BOOL success; ++ char *line = heap_alloc(line_max); ++ ++ for (;;) ++ { ++ char c; ++ success = read_char_from_handle(handle, &c); ++ ++ /* Check for EOF */ ++ if (!success) ++ { ++ if (length == 0) ++ return NULL; ++ else ++ break; ++ } ++ ++ if (c == '\n') ++ break; ++ ++ /* Make sure buffer is large enough */ ++ if (length + 1 >= line_max) ++ { ++ line_max *= 2; ++ line = heap_realloc(line, line_max); ++ } ++ ++ line[length++] = c; ++ } ++ ++ line[length] = 0; ++ if (length - 1 >= 0 && line[length - 1] == '\r') /* Strip \r of windows line endings */ ++ line[length - 1] = 0; ++ ++ line_converted_length = MultiByteToWideChar(CP_ACP, 0, line, -1, 0, 0); ++ line_converted = heap_alloc(line_converted_length * sizeof(WCHAR)); ++ MultiByteToWideChar(CP_ACP, 0, line, -1, line_converted, line_converted_length); ++ ++ heap_free(line); ++ ++ return line_converted; ++} ++ ++static void write_to_stdout(const WCHAR *str) ++{ ++ char *str_converted; ++ UINT str_converted_length; ++ DWORD bytes_written; ++ UINT str_length = lstrlenW(str); ++ int codepage = CP_ACP; ++ ++ str_converted_length = WideCharToMultiByte(codepage, 0, str, str_length, NULL, 0, NULL, NULL); ++ str_converted = heap_alloc(str_converted_length); ++ WideCharToMultiByte(codepage, 0, str, str_length, str_converted, str_converted_length, NULL, NULL); ++ ++ WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), str_converted, str_converted_length, &bytes_written, NULL); ++ if (bytes_written < str_converted_length) ++ ERR("Failed to write output\n"); ++ ++ heap_free(str_converted); ++} ++ ++static BOOL run_find_for_line(const WCHAR *line, const WCHAR *tofind) ++{ ++ void *found; ++ WCHAR lineending[] = {'\r', '\n', 0}; ++ ++ if (lstrlenW(line) == 0 || lstrlenW(tofind) == 0) ++ return FALSE; ++ ++ found = wcsstr(line, tofind); ++ ++ if (found) ++ { ++ write_to_stdout(line); ++ write_to_stdout(lineending); ++ return TRUE; ++ } ++ ++ return FALSE; ++} ++ ++static void output_resource_message(int id) ++{ ++ WCHAR buffer[64]; ++ LoadStringW(GetModuleHandleW(NULL), id, buffer, ARRAY_SIZE(buffer)); ++ write_to_stdout(buffer); ++} ++ + int __cdecl wmain(int argc, WCHAR *argv[]) + { ++ WCHAR *line; ++ WCHAR *tofind_pattern = NULL; WCHAR *tofind = NULL; + int i; ++ int exitcode; ++ int file_paths_len = 0; ++ int file_paths_max = 0; ++ WCHAR** file_paths = NULL; + +- WINE_FIXME("stub:"); ++ TRACE("running find:"); + for (i = 0; i < argc; i++) +- WINE_FIXME(" %s", wine_dbgstr_w(argv[i])); +- WINE_FIXME("\n"); ++ { ++ TRACE(" %s", wine_dbgstr_w(argv[i])); ++ } ++ TRACE("\n"); ++ ++ for (i = 1; i < argc; i++) ++ { ++ if (argv[i][0] == '/') ++ { ++ switch(argv[i][1]) ++ { ++ case '?': ++ output_resource_message(IDS_USAGE); ++ return 0; ++ default: ++ WINE_FIXME("options not supported\n"); ++ } ++ } ++ else if (tofind_pattern == NULL) ++ { ++ tofind_pattern = argv[i]; ++ } ++ else ++ { ++ if (file_paths_len >= file_paths_max) ++ { ++ file_paths_max = file_paths_max ? file_paths_max * 2 : 2; ++ file_paths = heap_realloc(file_paths, sizeof(WCHAR*) * file_paths_max); ++ } ++ file_paths[file_paths_len++] = argv[i]; ++ } ++ } ++ ++ if (tofind_pattern == NULL) ++ { ++ output_resource_message(IDS_INVALID_PARAMETER); ++ return 2; ++ } ++ ++ exitcode = 1; ++ ++ if (file_paths_len > 0) ++ { ++ for (i = 0; i < file_paths_len; i++) ++ { ++ HANDLE input; ++ WCHAR file_path_upper[MAX_PATH]; ++ ++ wcscpy(file_path_upper, file_paths[i]); ++ wcsupr(file_path_upper); ++ ++ input = CreateFileW(file_paths[i], GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); ++ ++ if (input == INVALID_HANDLE_VALUE) ++ { ++ WCHAR buffer_message[64]; ++ WCHAR message[300]; ++ ++ LoadStringW(GetModuleHandleW(NULL), IDS_FILE_NOT_FOUND, buffer_message, ARRAY_SIZE(buffer_message)); ++ ++ wsprintfW(message, buffer_message, file_path_upper); ++ write_to_stdout(message); ++ continue; ++ } ++ ++ while ((line = read_line_from_handle(input)) != NULL) ++ { ++ tofind = _wcstok (tofind_pattern, L" |"); /* break up search pattern like "foo bar" or "foo | bar" into "foo" and "bar" */ ++ while (tofind != NULL && exitcode != 0) ++ { ++ if (run_find_for_line(line, tofind)) ++ exitcode = 0; ++ tofind = _wcstok (NULL, L" |"); ++ } ++ heap_free(line); ++ } ++ CloseHandle(input); ++ } ++ } ++ else ++ { ++ HANDLE input = GetStdHandle(STD_INPUT_HANDLE); ++ while ((line = read_line_from_handle(input)) != NULL) ++ { ++ tofind = _wcstok (tofind_pattern, L" |"); /* break up search pattern like "foo bar" or "foo | bar" into "foo" and "bar" */ ++ while (tofind != NULL && exitcode != 0) ++ { ++ if (run_find_for_line(line, tofind)) ++ exitcode = 0; ++ tofind = _wcstok (NULL, L" |"); ++ } ++ heap_free(line); ++ } ++ } + +- return 0; ++ heap_free(file_paths); ++ return exitcode; + } +diff --git a/programs/findstr/resources.h b/programs/findstr/resources.h +new file mode 100644 +index 00000000000..e868c7efa4a +--- /dev/null ++++ b/programs/findstr/resources.h +@@ -0,0 +1,29 @@ ++/* ++ * Resource IDs ++ * ++ * Copyright 2019 Fabian Maurer ++ * ++ * 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 ++ */ ++ ++#ifndef __WINE_FINDSTR_RESOURCES_H ++#define __WINE_FINDSTR_RESOURCES_H ++ ++#define IDS_INVALID_PARAMETER 1000 ++#define IDS_INVALID_SWITCH 1001 ++#define IDS_FILE_NOT_FOUND 1002 ++#define IDS_USAGE 1003 ++ ++#endif /* __WINE_FINDSTR_RESOURCES_H */ +-- +2.27.0 + diff --git a/patches/programs-findstr/definition b/patches/programs-findstr/definition new file mode 100644 index 00000000..f91cd281 --- /dev/null +++ b/patches/programs-findstr/definition @@ -0,0 +1 @@ +Fixes: [35254] findstr: Add minimal implementation