cmd: Fix copying when the dest is one of the sources.
"COPY a+b a" appends b to a. "COPY a+b b" skips b from the sources. Signed-off-by: Lauri Kenttä <lauri.kentta@gmail.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
6cc673477d
commit
064508c0dd
@ -459,6 +459,36 @@ static BOOL WCMD_AppendEOF(WCHAR *filename)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* WCMD_IsSameFile
|
||||||
|
*
|
||||||
|
* Checks if the two paths reference to the same file
|
||||||
|
*/
|
||||||
|
static BOOL WCMD_IsSameFile(const WCHAR *name1, const WCHAR *name2)
|
||||||
|
{
|
||||||
|
BOOL ret = FALSE;
|
||||||
|
HANDLE file1 = INVALID_HANDLE_VALUE, file2 = INVALID_HANDLE_VALUE;
|
||||||
|
BY_HANDLE_FILE_INFORMATION info1, info2;
|
||||||
|
|
||||||
|
file1 = CreateFileW(name1, 0, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
|
||||||
|
if (file1 == INVALID_HANDLE_VALUE || !GetFileInformationByHandle(file1, &info1))
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
file2 = CreateFileW(name2, 0, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
|
||||||
|
if (file2 == INVALID_HANDLE_VALUE || !GetFileInformationByHandle(file2, &info2))
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
ret = info1.dwVolumeSerialNumber == info2.dwVolumeSerialNumber
|
||||||
|
&& info1.nFileIndexHigh == info2.nFileIndexHigh
|
||||||
|
&& info1.nFileIndexLow == info2.nFileIndexLow;
|
||||||
|
end:
|
||||||
|
if (file1 != INVALID_HANDLE_VALUE)
|
||||||
|
CloseHandle(file1);
|
||||||
|
if (file2 != INVALID_HANDLE_VALUE)
|
||||||
|
CloseHandle(file2);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* WCMD_ManualCopy
|
* WCMD_ManualCopy
|
||||||
*
|
*
|
||||||
@ -922,6 +952,7 @@ void WCMD_copy(WCHAR * args) {
|
|||||||
do {
|
do {
|
||||||
WCHAR outname[MAX_PATH];
|
WCHAR outname[MAX_PATH];
|
||||||
BOOL overwrite;
|
BOOL overwrite;
|
||||||
|
BOOL appendtofirstfile = FALSE;
|
||||||
|
|
||||||
/* Skip . and .., and directories */
|
/* Skip . and .., and directories */
|
||||||
if (!srcisdevice && fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
if (!srcisdevice && fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
||||||
@ -946,8 +977,14 @@ void WCMD_copy(WCHAR * args) {
|
|||||||
WINE_TRACE("Flags: srcbinary(%d), dstbinary(%d), over(%d), prompt(%d)\n",
|
WINE_TRACE("Flags: srcbinary(%d), dstbinary(%d), over(%d), prompt(%d)\n",
|
||||||
thiscopy->binarycopy, destination->binarycopy, overwrite, prompt);
|
thiscopy->binarycopy, destination->binarycopy, overwrite, prompt);
|
||||||
|
|
||||||
|
if (!writtenoneconcat) {
|
||||||
|
appendtofirstfile = anyconcats && WCMD_IsSameFile(srcpath, outname);
|
||||||
|
}
|
||||||
|
|
||||||
/* Prompt before overwriting */
|
/* Prompt before overwriting */
|
||||||
if (!overwrite) {
|
if (appendtofirstfile) {
|
||||||
|
overwrite = TRUE;
|
||||||
|
} else if (!overwrite) {
|
||||||
DWORD attributes = GetFileAttributesW(outname);
|
DWORD attributes = GetFileAttributesW(outname);
|
||||||
if (attributes != INVALID_FILE_ATTRIBUTES) {
|
if (attributes != INVALID_FILE_ATTRIBUTES) {
|
||||||
WCHAR* question;
|
WCHAR* question;
|
||||||
@ -969,7 +1006,10 @@ void WCMD_copy(WCHAR * args) {
|
|||||||
|
|
||||||
/* Do the copy as appropriate */
|
/* Do the copy as appropriate */
|
||||||
if (overwrite) {
|
if (overwrite) {
|
||||||
if (anyconcats && writtenoneconcat) {
|
if (anyconcats && WCMD_IsSameFile(srcpath, outname)) {
|
||||||
|
/* Silently skip if the destination file is also a source file */
|
||||||
|
status = TRUE;
|
||||||
|
} else if (anyconcats && writtenoneconcat) {
|
||||||
if (thiscopy->binarycopy) {
|
if (thiscopy->binarycopy) {
|
||||||
status = WCMD_ManualCopy(srcpath, outname, FALSE, TRUE);
|
status = WCMD_ManualCopy(srcpath, outname, FALSE, TRUE);
|
||||||
} else {
|
} else {
|
||||||
|
@ -2584,6 +2584,22 @@ rem Concat 2 files, default mode - (one EOF on the end 5+8+1)
|
|||||||
copy ..\file1+..\file2 file12_eof2 >nul 2>&1
|
copy ..\file1+..\file2 file12_eof2 >nul 2>&1
|
||||||
call :CheckFileSize file12_eof2 14
|
call :CheckFileSize file12_eof2 14
|
||||||
|
|
||||||
|
rem Test copying when destination is one of the sources.
|
||||||
|
rem Concat file1+file2+file3 into file1, should produce file1+file2+file3 = 24
|
||||||
|
copy /y ..\file? .\ >nul 2>&1
|
||||||
|
copy /y /b file1+file2+file3 file1 >nul 2>&1
|
||||||
|
call :CheckFileSize file1 24
|
||||||
|
|
||||||
|
rem Concat file1+file2+file3 into file2, should produce file1+file3 = 16
|
||||||
|
copy /y ..\file? .\ >nul 2>&1
|
||||||
|
copy /y /b file1+file2+file3 file2 >nul 2>&1
|
||||||
|
call :CheckFileSize file2 16
|
||||||
|
|
||||||
|
rem Concat file1+file2+file3 into file3, should produce file1+file2 = 13
|
||||||
|
copy /y ..\file? .\ >nul 2>&1
|
||||||
|
copy /y /b file1+file2+file3 file3 >nul 2>&1
|
||||||
|
call :CheckFileSize file3 13
|
||||||
|
|
||||||
rem --------------------------------------------------------------
|
rem --------------------------------------------------------------
|
||||||
rem Show ascii source copy stops at first EOF, binary does the lot
|
rem Show ascii source copy stops at first EOF, binary does the lot
|
||||||
rem --------------------------------------------------------------
|
rem --------------------------------------------------------------
|
||||||
|
@ -1462,6 +1462,9 @@ Passed: file size check on file3_plus_eof [12]@or_broken@Skipping file size chec
|
|||||||
Passed: file size check on file12_plus_eof [14]@or_broken@Skipping file size check on NT4
|
Passed: file size check on file12_plus_eof [14]@or_broken@Skipping file size check on NT4
|
||||||
Passed: file size check on file12_no_eof [13]@or_broken@Skipping file size check on NT4
|
Passed: file size check on file12_no_eof [13]@or_broken@Skipping file size check on NT4
|
||||||
Passed: file size check on file12_eof2 [14]@or_broken@Skipping file size check on NT4
|
Passed: file size check on file12_eof2 [14]@or_broken@Skipping file size check on NT4
|
||||||
|
Passed: file size check on file1 [24]@or_broken@Skipping file size check on NT4
|
||||||
|
Passed: file size check on file2 [16]@or_broken@Skipping file size check on NT4
|
||||||
|
Passed: file size check on file3 [13]@or_broken@Skipping file size check on NT4
|
||||||
Passed: file size check on file1_binary_srccopy [6]@or_broken@Skipping file size check on NT4
|
Passed: file size check on file1_binary_srccopy [6]@or_broken@Skipping file size check on NT4
|
||||||
Passed: file size check on file1_ascii_srccopy [5]@or_broken@Skipping file size check on NT4
|
Passed: file size check on file1_ascii_srccopy [5]@or_broken@Skipping file size check on NT4
|
||||||
Passed: file size check on file123_default_copy [25]@or_broken@Skipping file size check on NT4
|
Passed: file size check on file123_default_copy [25]@or_broken@Skipping file size check on NT4
|
||||||
|
Loading…
x
Reference in New Issue
Block a user