https://git.reactos.org/?p=reactos.git;a=commitdiff;h=7916d0ae3e63f9fe4febf2...
commit 7916d0ae3e63f9fe4febf2597f4e66e63fcabc38 Author: Denis Malikov filedem@gmail.com AuthorDate: Wed Jun 6 00:13:51 2018 +0700 Commit: Mark Jansen mark.jansen@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; }