In native Windows, the COPY command will display the names of the files as they are copied. Wine should do the same. This change enables that.
-- v3: cmd: COPY should output file names as they are copied.
From: Joe Souza jsouza@yahoo.com
--- programs/cmd/builtins.c | 25 +++++++++++++++++++++++-- programs/cmd/cmd.rc | 1 + programs/cmd/wcmd.h | 1 + 3 files changed, 25 insertions(+), 2 deletions(-)
diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c index b78ae9d293b..17ba263a050 100644 --- a/programs/cmd/builtins.c +++ b/programs/cmd/builtins.c @@ -954,6 +954,9 @@ RETURN_CODE WCMD_copy(WCHAR * args) WCHAR *filenamepart; DWORD attributes; BOOL srcisdevice = FALSE; + BOOL havewildcards = FALSE; + BOOL displaynames = FALSE; + unsigned numcopied = 0;
/* If it was not explicit, we now know whether we are concatenating or not and hence whether to copy as binary or ascii */ @@ -965,6 +968,9 @@ RETURN_CODE WCMD_copy(WCHAR * args) return errorlevel = ERROR_INVALID_FUNCTION; WINE_TRACE("Full src name is '%s'\n", wine_dbgstr_w(srcpath));
+ havewildcards = wcspbrk(srcpath, L"*?") ? TRUE : FALSE; + displaynames = havewildcards; + /* If parameter is a directory, ensure it ends in * */ attributes = GetFileAttributesW(srcpath); if (ends_with_backslash( srcpath )) { @@ -972,17 +978,19 @@ RETURN_CODE WCMD_copy(WCHAR * args) /* We need to know where the filename part starts, so append * and recalculate the full resulting path */ lstrcatW(thiscopy->name, L"*"); + displaynames = TRUE; if (!WCMD_get_fullpath(thiscopy->name, ARRAY_SIZE(srcpath), srcpath, &filenamepart)) return errorlevel = ERROR_INVALID_FUNCTION; WINE_TRACE("Directory, so full name is now '%s'\n", wine_dbgstr_w(srcpath));
- } else if ((wcspbrk(srcpath, L"*?") == NULL) && + } else if (!havewildcards && (attributes != INVALID_FILE_ATTRIBUTES) && (attributes & FILE_ATTRIBUTE_DIRECTORY)) {
/* We need to know where the filename part starts, so append * and recalculate the full resulting path */ lstrcatW(thiscopy->name, L"\*"); + displaynames = TRUE; if (!WCMD_get_fullpath(thiscopy->name, ARRAY_SIZE(srcpath), srcpath, &filenamepart)) return errorlevel = ERROR_INVALID_FUNCTION; WINE_TRACE("Directory, so full name is now '%s'\n", wine_dbgstr_w(srcpath)); @@ -1097,6 +1105,11 @@ RETURN_CODE WCMD_copy(WCHAR * args) return_code = ERROR_INVALID_FUNCTION; } else { WINE_TRACE("Copied successfully\n"); + if (displaynames) { + WCMD_output_asis(srcpath); + WCMD_output_asis(L"\r\n"); + } + numcopied++; if (anyconcats) writtenoneconcat = TRUE;
/* Append EOF if ascii destination and we are not going to add more onto the end @@ -1114,7 +1127,15 @@ RETURN_CODE WCMD_copy(WCHAR * args) return_code = ERROR_INVALID_FUNCTION; } } while (!srcisdevice && FindNextFileW(hff, &fd) != 0); - if (!srcisdevice) FindClose (hff); + if (!srcisdevice) { + FindClose (hff); + if (numcopied) { + WCHAR* string; + string = WCMD_format_string(WCMD_LoadMessage(WCMD_NUMCOPIED), numcopied); + WCMD_output_asis(string); + LocalFree(string); + } + } } else { /* Error if the first file was not found */ if (!anyconcats || !writtenoneconcat) { diff --git a/programs/cmd/cmd.rc b/programs/cmd/cmd.rc index 90091090e11..29d105fa7a2 100644 --- a/programs/cmd/cmd.rc +++ b/programs/cmd/cmd.rc @@ -406,4 +406,5 @@ Enter HELP <command> for further information on any of the above commands.\n" WCMD_BADTOKEN, "Syntax error: unexpected %1\n" WCMD_ENDOFLINE, "End of line" WCMD_ENDOFFILE, "End of file" + WCMD_NUMCOPIED, "%t%1!u! file(s) copied\n" } diff --git a/programs/cmd/wcmd.h b/programs/cmd/wcmd.h index 4c85d7ad8cb..2731743c27a 100644 --- a/programs/cmd/wcmd.h +++ b/programs/cmd/wcmd.h @@ -454,3 +454,4 @@ extern WCHAR version_string[]; #define WCMD_BADTOKEN 1047 #define WCMD_ENDOFLINE 1048 #define WCMD_ENDOFFILE 1049 +#define WCMD_NUMCOPIED 1050
On Wed Jun 4 16:44:02 2025 +0000, eric pouech wrote:
quick testing on Win10 shows that printing of filenames doesn't always occur (eg 'copy a b' doesn't print 'a', while 'copy a* b' does) so some non regression tests could be useful (eg amend existing test to grab copy output to stdout and for example count number of lines, or check if a given filename is present in output)
Code has been updated and should work as expected now. I looked into updating the tests. Was intending to use find.exe to count lines but Wine's find.exe supports neither /c nor /v so I gave up.