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;

Reply via email to