https://git.reactos.org/?p=reactos.git;a=commitdiff;h=520577a8ecccc6f2954d00b662640011f2800fa7
commit 520577a8ecccc6f2954d00b662640011f2800fa7 Author: Katayama Hirofumi MZ <[email protected]> AuthorDate: Sun Aug 6 20:56:45 2023 +0900 Commit: GitHub <[email protected]> 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;
