https://git.reactos.org/?p=reactos.git;a=commitdiff;h=520577a8ecccc6f2954d0…
commit 520577a8ecccc6f2954d00b662640011f2800fa7
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Sun Aug 6 20:56:45 2023 +0900
Commit: GitHub <noreply(a)github.com>
CommitDate: Sun Aug 6 20:56:45 2023 +0900
[SHELL32] Rename file on copy-paste path collision (#5462)
- If the source and destination of copying file are on the same directory,
then enable FOF_RENAMEONCOLLISION flag. End if.
- Don't show error message IDS_COPYERRORSUBFOLDER or
IDS_MOVEERRORSUBFOLDER if the source and the destination are the same.
CORE-18599
---
dll/win32/shell32/droptargets/CFSDropTarget.cpp | 17 ++++++++++++++++-
dll/win32/shell32/shlfileop.cpp | 2 +-
2 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/dll/win32/shell32/droptargets/CFSDropTarget.cpp
b/dll/win32/shell32/droptargets/CFSDropTarget.cpp
index 10aee5e3532..f480ffa9808 100644
--- a/dll/win32/shell32/droptargets/CFSDropTarget.cpp
+++ b/dll/win32/shell32/droptargets/CFSDropTarget.cpp
@@ -42,6 +42,7 @@ HRESULT CFSDropTarget::_CopyItems(IShellFolder * pSFFrom, UINT cidl,
PWCHAR pwszListPos = pwszSrcPathsList;
STRRET strretFrom;
SHFILEOPSTRUCTW fop;
+ BOOL bRenameOnCollision = FALSE;
/* Build a double null terminated list of C strings from source paths */
for (UINT i = 0; i < cidl; i++)
@@ -64,7 +65,18 @@ HRESULT CFSDropTarget::_CopyItems(IShellFolder * pSFFrom, UINT cidl,
if (FAILED(ret))
goto cleanup;
- wszDstPath[lstrlenW(wszDstPath) + 1] = L'\0';
+ wszDstPath[lstrlenW(wszDstPath) + 1] = UNICODE_NULL;
+
+ /* Set bRenameOnCollision to TRUE if necesssary */
+ if (bCopy)
+ {
+ WCHAR szPath1[MAX_PATH], szPath2[MAX_PATH];
+ GetFullPathNameW(pwszSrcPathsList, _countof(szPath1), szPath1, NULL);
+ GetFullPathNameW(wszDstPath, _countof(szPath2), szPath2, NULL);
+ PathRemoveFileSpecW(szPath1);
+ if (_wcsicmp(szPath1, szPath2) == 0)
+ bRenameOnCollision = TRUE;
+ }
ZeroMemory(&fop, sizeof(fop));
fop.hwnd = m_hwndSite;
@@ -72,6 +84,9 @@ HRESULT CFSDropTarget::_CopyItems(IShellFolder * pSFFrom, UINT cidl,
fop.pFrom = pwszSrcPathsList;
fop.pTo = wszDstPath;
fop.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMMKDIR;
+ if (bRenameOnCollision)
+ fop.fFlags |= FOF_RENAMEONCOLLISION;
+
ret = S_OK;
if (SHFileOperationW(&fop))
diff --git a/dll/win32/shell32/shlfileop.cpp b/dll/win32/shell32/shlfileop.cpp
index 351ee1e4c5c..18956867143 100644
--- a/dll/win32/shell32/shlfileop.cpp
+++ b/dll/win32/shell32/shlfileop.cpp
@@ -1940,7 +1940,7 @@ validate_operation(LPSHFILEOPSTRUCTW lpFileOp, FILE_LIST *flFrom,
FILE_LIST *flT
{
size_t cchFrom = PathAddBackslashW(szFrom) - szFrom;
size_t cchTo = PathAddBackslashW(szTo) - szTo;
- if (cchFrom <= cchTo)
+ if (cchFrom < cchTo)
{
WCHAR ch = szTo[cchFrom];
szTo[cchFrom] = 0;