https://git.reactos.org/?p=reactos.git;a=commitdiff;h=520577a8ecccc6f2954d00...
commit 520577a8ecccc6f2954d00b662640011f2800fa7 Author: Katayama Hirofumi MZ katayama.hirofumi.mz@gmail.com AuthorDate: Sun Aug 6 20:56:45 2023 +0900 Commit: GitHub noreply@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;