[PATCH v8 3/3] robocopy: Add basic output
Florian Eder
others.meder at gmail.com
Sun Oct 31 15:34:36 CDT 2021
Adds output methods to output copied files and errors
Signed-off-by: Florian Eder <others.meder at gmail.com>
---
v8: Identical to v7
---
programs/robocopy/main.c | 86 +++++++++++++++++++++++++++++++++--
programs/robocopy/robocopy.h | 24 ++++++++++
programs/robocopy/robocopy.rc | 13 ++++++
3 files changed, 119 insertions(+), 4 deletions(-)
create mode 100644 programs/robocopy/robocopy.h
diff --git a/programs/robocopy/main.c b/programs/robocopy/main.c
index b58111c7bff..6aa5f102da7 100644
--- a/programs/robocopy/main.c
+++ b/programs/robocopy/main.c
@@ -27,6 +27,7 @@
WINE_DEFAULT_DEBUG_CHANNEL(robocopy);
#include <wine/list.h>
+#include "robocopy.h"
struct path_array
{
@@ -52,6 +53,62 @@ struct robocopy_options
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, (WCHAR *)&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 void output_error(UINT format_string_id, HRESULT error_code, WCHAR* path)
+{
+ WCHAR *error_string;
+
+ FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_ALLOCATE_BUFFER,
+ NULL, error_code, 0, (WCHAR *)&error_string, 0, NULL);
+
+ output_message(format_string(format_string_id), path, error_string);
+
+ LocalFree(error_string);
+}
+
static WCHAR *get_absolute_path(const WCHAR *path)
{
DWORD size;
@@ -82,7 +139,16 @@ static BOOL create_directory_path(const WCHAR *path)
while (pointer != NULL)
{
if (!lstrcpynW(current_folder, path, pointer - path + 2)) return FALSE;
- if (!CreateDirectoryW(current_folder, NULL) && GetLastError() != ERROR_ALREADY_EXISTS) return FALSE;
+ if (!CreateDirectoryW(current_folder, NULL))
+ {
+ if (GetLastError() != ERROR_ALREADY_EXISTS)
+ {
+ output_error(STRING_ERROR_WRITE_DIRECTORY, GetLastError(), current_folder);
+ return FALSE;
+ }
+ }
+ else
+ output_message(format_string(STRING_CREATE_DIRECTORY), current_folder);
pointer = wcschr(pointer + 1, L'\\');
}
return TRUE;
@@ -142,7 +208,11 @@ static BOOL perform_copy(void)
list_init(&paths_source);
- if (!PathIsDirectoryW(options.source)) return FALSE;
+ if (!PathIsDirectoryW(options.source))
+ {
+ output_error(STRING_ERROR_READ_DIRECTORY, ERROR_FILE_NOT_FOUND, options.source);
+ return FALSE;
+ }
create_directory_path(options.destination);
@@ -155,10 +225,18 @@ static BOOL perform_copy(void)
combine_path(options.source, current_path->name, ¤t_absolute_path);
combine_path(options.destination, current_path->name, &target_path);
- if (!PathIsDirectoryW(current_absolute_path))
+ if (PathIsDirectoryW(current_absolute_path))
+ {
+ if (!create_directory_path(target_path))
+ output_error(STRING_ERROR_WRITE_DIRECTORY, GetLastError(), target_path);
+ }
+ else
{
create_directory_path(target_path);
- CopyFileW(current_absolute_path, target_path, FALSE);
+ if (!CopyFileW(current_absolute_path, target_path, FALSE))
+ output_error(STRING_ERROR_WRITE_FILE, GetLastError(), target_path);
+ else
+ output_message(format_string(STRING_CREATE_FILE), target_path);
}
}
return TRUE;
diff --git a/programs/robocopy/robocopy.h b/programs/robocopy/robocopy.h
new file mode 100644
index 00000000000..4add81dd208
--- /dev/null
+++ b/programs/robocopy/robocopy.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2021 Florian Eder
+ *
+ * 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
+ */
+
+#define STRING_MISSING_DESTINATION_OR_SOURCE 1010
+#define STRING_ERROR_READ_DIRECTORY 1011
+#define STRING_ERROR_WRITE_DIRECTORY 1012
+#define STRING_ERROR_WRITE_FILE 1014
+#define STRING_CREATE_DIRECTORY 1019
+#define STRING_CREATE_FILE 1022
diff --git a/programs/robocopy/robocopy.rc b/programs/robocopy/robocopy.rc
index ffd5f770b1b..70dc11aab34 100644
--- a/programs/robocopy/robocopy.rc
+++ b/programs/robocopy/robocopy.rc
@@ -17,9 +17,22 @@
*/
#include <windef.h>
+#include "robocopy.h"
#pragma makedep po
+LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT
+
+STRINGTABLE
+{
+ STRING_MISSING_DESTINATION_OR_SOURCE, "No destination or source specified, can't copy anything\n"
+ STRING_ERROR_READ_DIRECTORY, "Error occurred reading directory \"%1\":\n%2\n"
+ STRING_ERROR_WRITE_DIRECTORY, "Error occurred writing directory \"%1\":\n%2\n"
+ STRING_ERROR_WRITE_FILE, "Error occurred writing file \"%1\":\n%2\n"
+ STRING_CREATE_DIRECTORY, " Created Dir: %1\n"
+ STRING_CREATE_FILE, " Copied File: %1\n"
+}
+
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
#define WINE_FILEDESCRIPTION_STR "Wine Robocopy"
--
2.32.0
More information about the wine-devel
mailing list