https://git.reactos.org/?p=reactos.git;a=commitdiff;h=7916d0ae3e63f9fe4febf…
commit 7916d0ae3e63f9fe4febf2597f4e66e63fcabc38
Author: Denis Malikov <filedem(a)gmail.com>
AuthorDate: Wed Jun 6 00:13:51 2018 +0700
Commit: Mark Jansen <mark.jansen(a)reactos.org>
CommitDate: Wed Jun 13 20:13:44 2018 +0200
[SHELL32] Copy-paste files/folders into current place.
Files are copied with trying to find new path by adding (%d) suffix before asking for
overwrite existing item
CORE-13788
---
dll/win32/shell32/shlfileop.cpp | 54 +++++++++++++++++++++++++++++++++++++----
1 file changed, 49 insertions(+), 5 deletions(-)
diff --git a/dll/win32/shell32/shlfileop.cpp b/dll/win32/shell32/shlfileop.cpp
index 4dfd44f781..e07d32d8d7 100644
--- a/dll/win32/shell32/shlfileop.cpp
+++ b/dll/win32/shell32/shlfileop.cpp
@@ -32,6 +32,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(shell);
#define FO_MASK 0xF
+#define NEW_FILENAME_ON_COPY_TRIES 100
+
static const WCHAR wWildcardFile[] = {'*',0};
static const WCHAR wWildcardChars[] = {'*','?',0};
@@ -1219,6 +1221,34 @@ static void destroy_file_list(FILE_LIST *flList)
HeapFree(GetProcessHeap(), 0, flList->feFiles);
}
+static CStringW try_find_new_name(LPCWSTR szDestPath)
+{
+ CStringW mask(szDestPath);
+ CStringW ext(PathFindExtensionW(szDestPath));
+
+ // cut off extension before inserting a "new file" mask
+ if (!ext.IsEmpty())
+ {
+ mask = mask.Left(mask.GetLength() - ext.GetLength());
+ }
+ mask += L" (%d)" + ext;
+
+ CStringW newName;
+
+ // trying to find new file name
+ for (int i = 1; i < NEW_FILENAME_ON_COPY_TRIES; i++)
+ {
+ newName.Format(mask, i);
+
+ if (!PathFileExistsW(newName))
+ {
+ return newName;
+ }
+ }
+
+ return CStringW();
+}
+
static void copy_dir_to_dir(FILE_OPERATION *op, const FILE_ENTRY *feFrom, LPCWSTR
szDestPath)
{
WCHAR szFrom[MAX_PATH], szTo[MAX_PATH];
@@ -1236,12 +1266,20 @@ static void copy_dir_to_dir(FILE_OPERATION *op, const FILE_ENTRY
*feFrom, LPCWST
if (!(op->req->fFlags & FOF_NOCONFIRMATION) &&
PathFileExistsW(szTo))
{
- if (!SHELL_ConfirmDialogW(op->req->hwnd, ASK_OVERWRITE_FOLDER,
feFrom->szFilename, op))
+ CStringW newPath;
+ if (lstrcmp(feFrom->szDirectory, szDestPath) == 0 && !(newPath =
try_find_new_name(szTo)).IsEmpty())
{
- /* Vista returns an ERROR_CANCELLED even if user pressed "No" */
- if (!op->bManyItems)
- op->bCancelled = TRUE;
- return;
+ StringCchCopyW(szTo, _countof(szTo), newPath);
+ }
+ else
+ {
+ if (!SHELL_ConfirmDialogW(op->req->hwnd, ASK_OVERWRITE_FOLDER,
feFrom->szFilename, op))
+ {
+ /* Vista returns an ERROR_CANCELLED even if user pressed "No"
*/
+ if (!op->bManyItems)
+ op->bCancelled = TRUE;
+ return;
+ }
}
}
@@ -1266,6 +1304,12 @@ static BOOL copy_file_to_file(FILE_OPERATION *op, const WCHAR
*szFrom, const WCH
{
if (!(op->req->fFlags & FOF_NOCONFIRMATION) &&
PathFileExistsW(szTo))
{
+ CStringW newPath;
+ if (lstrcmp(szFrom, szTo) == 0 && !(newPath =
try_find_new_name(szTo)).IsEmpty())
+ {
+ return SHNotifyCopyFileW(op, szFrom, newPath, FALSE) == 0;
+ }
+
if (!SHELL_ConfirmDialogW(op->req->hwnd, ASK_OVERWRITE_FILE,
PathFindFileNameW(szTo), op))
return FALSE;
}