[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
This commit is contained in:
Katayama Hirofumi MZ 2023-08-06 20:56:45 +09:00 committed by GitHub
parent b4684e9809
commit 520577a8ec
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 17 additions and 2 deletions

View file

@ -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))

View file

@ -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;