[PATCH v2 4/6] robocopy: Add basic output

Florian Eder others.meder at gmail.com
Wed Sep 15 16:56:58 CDT 2021


Adds output method and prints a header and the source / destination / files to include
back to the user

Signed-off-by: Florian Eder <others.meder at gmail.com>
---
Removed STRING_ADDITIONAL_INFO, as it isn't necessary to translate it,
changed output_message to accept a string pointer to a format string, instead
of a string table entry, and added an additional function to get a format string
from a string table id
---
 programs/robocopy/main.c      | 70 +++++++++++++++++++++++++++++++++++
 programs/robocopy/robocopy.h  |  6 +++
 programs/robocopy/robocopy.rc | 11 ++++++
 3 files changed, 87 insertions(+)

diff --git a/programs/robocopy/main.c b/programs/robocopy/main.c
index e5400952ec5..fc16fa1c2a2 100644
--- a/programs/robocopy/main.c
+++ b/programs/robocopy/main.c
@@ -27,6 +27,57 @@ WINE_DEFAULT_DEBUG_CHANNEL(robocopy);
 
 struct robocopy_options options;
 
+static const WCHAR *format_string(UINT format_string_id)
+{
+    WCHAR format_string[2048];
+    if (!LoadStringW(GetModuleHandleW(NULL), format_string_id, format_string, ARRAY_SIZE(format_string)))
+    {
+        WINE_ERR("invalid string loaded");
+        return L"";
+    }
+    return wcsdup(format_string);
+}
+
+static void output_message(const WCHAR *format_string, ...)
+{
+    __ms_va_list va_args;
+    WCHAR *string;
+    DWORD length, bytes_written;
+
+    __ms_va_start(va_args, format_string);
+    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 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(WCHAR *path)
 {
     DWORD size;
@@ -94,10 +145,29 @@ static void parse_arguments(int argc, WCHAR *argv[])
     }
 }
 
+static void print_header(void)
+{
+    UINT i;
+
+    output_message(format_string(STRING_HEADER));
+
+    if (!options.source) output_message(format_string(STRING_SOURCE), L"-");
+    else output_message(format_string(STRING_SOURCE), strip_path_prefix(options.source));
+
+    if (!options.destination) output_message(format_string(STRING_DESTINATION), L"-");
+    else output_message(format_string(STRING_DESTINATION), strip_path_prefix(options.destination));
+
+    output_message(format_string(STRING_FILES), options.files->array[0]);
+    for (i = 1; i < options.files->size; i++)
+        output_message(L"                 %1\n", options.files->array[i]);
+}
+
 int __cdecl wmain(int argc, WCHAR *argv[])
 {
     parse_arguments(argc, argv);
 
+    print_header();
+
     WINE_FIXME("robocopy stub");
     return 0;
 }
diff --git a/programs/robocopy/robocopy.h b/programs/robocopy/robocopy.h
index f62eb92c663..f5c2ac56fcf 100644
--- a/programs/robocopy/robocopy.h
+++ b/programs/robocopy/robocopy.h
@@ -31,3 +31,9 @@ struct robocopy_options
     WCHAR *source;
     struct path_array *files;
 };
+
+/* Resource strings */
+#define STRING_HEADER                         1000
+#define STRING_SOURCE                         1003
+#define STRING_DESTINATION                    1004
+#define STRING_FILES                          1005
diff --git a/programs/robocopy/robocopy.rc b/programs/robocopy/robocopy.rc
index edae5b71d86..3a2ddc9474f 100644
--- a/programs/robocopy/robocopy.rc
+++ b/programs/robocopy/robocopy.rc
@@ -17,9 +17,20 @@
  */
 
 #include <windef.h>
+#include "robocopy.h"
 
 #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"
+}
+
 LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
 
 #define WINE_FILEDESCRIPTION_STR "Wine Robocopy"
-- 
2.32.0




More information about the wine-devel mailing list