[PATCH v4 0/2] MR8200: cmd: COPY should output file names as they are copied.
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. -- v4: cmd/tests: Add tests for unexpected COPY filename output. https://gitlab.winehq.org/wine/wine/-/merge_requests/8200
From: Joe Souza <jsouza(a)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 -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/8200
From: Joe Souza <jsouza(a)yahoo.com> --- programs/cmd/tests/test_builtins.bat | 6 ++++-- programs/cmd/tests/test_builtins.bat.exp | 2 ++ programs/cmd/tests/test_builtins.cmd | 6 ++++-- programs/cmd/tests/test_builtins.cmd.exp | 2 ++ 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/programs/cmd/tests/test_builtins.bat b/programs/cmd/tests/test_builtins.bat index 728a0e4eafc..0aa79f17a9c 100644 --- a/programs/cmd/tests/test_builtins.bat +++ b/programs/cmd/tests/test_builtins.bat @@ -108,12 +108,14 @@ echo --- success/failure for COPY command mkdir foo & cd foo echo a > fileA echo b > fileB -call :setError 666 & (copy fileA >NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) -call :setError 666 & (copy fileA fileZ >NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) +call :setError 666 & (copy fileA >test1.txt &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) +call :setError 666 & (copy fileA fileZ >test2.txt &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) call :setError 666 & (copy fileA fileZ /-Y >NUL <NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) call :setError 666 & (copy fileA+fileD fileZ /-Y >NUL <NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) call :setError 666 & (copy fileD+fileA fileZ /-Y >NUL <NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) if exist fileD echo Unexpected fileD +call :setError 666 & (find /i "fileA" test1.txt >NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) +call :setError 666 & (find /i "fileA" test2.txt >NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) cd .. && rd /q /s foo echo --- success/failure for MOVE command diff --git a/programs/cmd/tests/test_builtins.bat.exp b/programs/cmd/tests/test_builtins.bat.exp index a6b583f78c1..31a4d6e73c2 100644 --- a/programs/cmd/tests/test_builtins.bat.exp +++ b/programs/cmd/tests/test_builtins.bat.exp @@ -77,6 +77,8 @@ SUCCESS 0 FAILURE 1 FAILURE 1 FAILURE 1 +FAILURE 1 +FAILURE 1 --- success/failure for MOVE command FAILURE 1 SUCCESS 0 diff --git a/programs/cmd/tests/test_builtins.cmd b/programs/cmd/tests/test_builtins.cmd index 58d78194380..e8a70f06962 100644 --- a/programs/cmd/tests/test_builtins.cmd +++ b/programs/cmd/tests/test_builtins.cmd @@ -625,12 +625,14 @@ echo --- success/failure for COPY command mkdir foo & cd foo echo a > fileA echo b > fileB -call :setError 666 & (copy fileA >NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) -call :setError 666 & (copy fileA fileZ >NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) +call :setError 666 & (copy fileA >test1.txt &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) +call :setError 666 & (copy fileA fileZ >test2.txt &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) call :setError 666 & (copy fileA fileZ /-Y >NUL <NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) call :setError 666 & (copy fileA+fileD fileZ /-Y >NUL <NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) call :setError 666 & (copy fileD+fileA fileZ /-Y >NUL <NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) if exist fileD echo Unexpected fileD +call :setError 666 & (find /i "fileA" test1.txt >NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) +call :setError 666 & (find /i "fileA" test2.txt >NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) cd .. && rd /q /s foo echo --- success/failure for MOVE command diff --git a/programs/cmd/tests/test_builtins.cmd.exp b/programs/cmd/tests/test_builtins.cmd.exp index ff6f944cffb..edcebbffb31 100644 --- a/programs/cmd/tests/test_builtins.cmd.exp +++ b/programs/cmd/tests/test_builtins.cmd.exp @@ -538,6 +538,8 @@ SUCCESS 0 FAILURE 1 FAILURE 1 FAILURE 1 +FAILURE 1 +FAILURE 1 --- success/failure for MOVE command FAILURE 1 SUCCESS 0 -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/8200
On Wed Jun 4 16:44:52 2025 +0000, Joe Souza wrote:
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. OK, managed to update the tests using find.exe to search for the filename in the output. Test output is confusing but seems to work.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/8200#note_105369
participants (2)
-
Joe Souza -
Joe Souza (@JoeS209)