From: Florian Eder Subject: [PATCH 04/41] robocopy: add basic output Message-Id: <20210906145518.346132-4-others.meder@gmail.com> Date: Mon, 6 Sep 2021 14:54:41 +0000 In-Reply-To: <20210906145518.346132-1-others.meder@gmail.com> References: <20210906145518.346132-1-others.meder@gmail.com> Adds output method and prints a header and the source / destination / files to include back to the user Signed-off-by: Florian Eder --- programs/robocopy/main.c | 66 +++++++++++++++++++++++++++++++++++ programs/robocopy/robocopy.h | 9 ++++- programs/robocopy/robocopy.rc | 11 ++++++ 3 files changed, 85 insertions(+), 1 deletion(-) diff --git a/programs/robocopy/main.c b/programs/robocopy/main.c index 8f8974b3528..97b961a5d0d 100644 --- a/programs/robocopy/main.c +++ b/programs/robocopy/main.c @@ -27,6 +27,46 @@ WINE_DEFAULT_DEBUG_CHANNEL(robocopy); struct robocopy_options options; +static void output_message(UINT format_string_id, ...) +{ + WCHAR format_string[2048]; + __ms_va_list va_args; + WCHAR *string; + DWORD length, bytes_written; + + if (!LoadStringW(GetModuleHandleW(NULL), format_string_id, format_string, ARRAY_SIZE(format_string))) + { + WINE_ERR("invalid string loaded"); + return; + } + + __ms_va_start(va_args, format_string_id); + length = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER, + format_string, 0, 0, (LPWSTR)&string, 0, &va_args); + __ms_va_end(va_args); + if (!length) + { + WINE_ERR("string formation failed"); + return; + } + + /* If WriteConsole fails, the output is being redirected to a file */ + if (!WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), string, wcslen(string), &bytes_written, NULL)) + { + CHAR *string_multibyte; + DWORD length_multibyte; + + length_multibyte = WideCharToMultiByte(GetConsoleOutputCP(), 0, string, wcslen(string), NULL, 0, NULL, NULL); + string_multibyte = malloc(length_multibyte); + + WideCharToMultiByte(GetConsoleOutputCP(), 0, string, wcslen(string), string_multibyte, length_multibyte, NULL, NULL); + WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), string_multibyte, length_multibyte, &bytes_written, NULL); + free(string_multibyte); + } + + LocalFree(string); +} + static BOOL is_valid_robocopy_flag(WCHAR *string) { /* @@ -41,6 +81,13 @@ static BOOL is_valid_robocopy_flag(WCHAR *string) return TRUE; } +static WCHAR *strip_path_prefix(WCHAR* path) +{ + /* returns a path without the \\?\ prefix */ + if (wcslen(path) <= 4) return path; + return &(path[4]); +} + WCHAR *get_absolute_path_with_trailing_backslash(WCHAR *path) { DWORD size; @@ -100,10 +147,29 @@ static void parse_arguments(int argc, WCHAR *argv[]) } } +static void print_header(void) +{ + UINT i; + + output_message(STRING_HEADER); + + if (!options.source) output_message(STRING_SOURCE, L"-"); + else output_message(STRING_SOURCE, strip_path_prefix(options.source)); + + if (!options.destination) output_message(STRING_DESTINATION, L"-"); + else output_message(STRING_DESTINATION, strip_path_prefix(options.destination)); + + output_message(STRING_FILES, options.files->array[0]); + for (i = 1; i < options.files->size; i++) + output_message(STRING_ADDITIONAL_INFO, options.files->array[i]); +} + int __cdecl wmain(int argc, WCHAR *argv[]) { parse_arguments(argc, argv); + print_header(); + WINE_FIXME("robocopy stub"); return 0; } \ No newline at end of file diff --git a/programs/robocopy/robocopy.h b/programs/robocopy/robocopy.h index aa857cd8c35..3be51b460a7 100644 --- a/programs/robocopy/robocopy.h +++ b/programs/robocopy/robocopy.h @@ -28,4 +28,11 @@ struct robocopy_options { WCHAR *destination; WCHAR *source; struct path_array* files; -}; \ No newline at end of file +}; + +/* Resource strings */ +#define STRING_HEADER 1000 +#define STRING_SOURCE 1003 +#define STRING_DESTINATION 1004 +#define STRING_FILES 1005 +#define STRING_ADDITIONAL_INFO 1008 \ No newline at end of file diff --git a/programs/robocopy/robocopy.rc b/programs/robocopy/robocopy.rc index c7acd5ad161..e00d9fc0227 100644 --- a/programs/robocopy/robocopy.rc +++ b/programs/robocopy/robocopy.rc @@ -21,6 +21,17 @@ #pragma makedep po +LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT + +STRINGTABLE +{ + STRING_HEADER, "Robocopy for Wine\n\n" + STRING_SOURCE, " Source: %1\n" + STRING_DESTINATION, " Destination: %1\n\n" + STRING_FILES, " Files: %1\n" + STRING_ADDITIONAL_INFO, " %1\n" +} + LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL #define WINE_FILEDESCRIPTION_STR "Wine Robocopy" -- 2.32.0