}
/* the FO_COPY operation */
-static HRESULT copy_files(FILE_OPERATION *op, const FILE_LIST *flFrom, const FILE_LIST *flTo)
+static HRESULT copy_files(FILE_OPERATION *op, const FILE_LIST *flFrom, FILE_LIST *flTo)
{
DWORD i;
const FILE_ENTRY *entryToCopy;
const FILE_ENTRY *fileDest = &flTo->feFiles[0];
- BOOL bCancelIfAnyDirectories = FALSE;
if (flFrom->bAnyDontExist)
return ERROR_SHELL_INTERNAL_FILE_NOT_FOUND;
- if (op->req->fFlags & FOF_MULTIDESTFILES && flFrom->bAnyFromWildcard)
- return ERROR_CANCELLED;
-
- if (!(op->req->fFlags & FOF_MULTIDESTFILES) &&
- flFrom->dwNumFiles != 1 && flTo->dwNumFiles != 1 &&
- !flFrom->bAnyFromWildcard)
+ if (op->req->fFlags & FOF_MULTIDESTFILES)
{
- return ERROR_CANCELLED;
- }
+ if (flFrom->bAnyFromWildcard)
+ return ERROR_CANCELLED;
- if (op->req->fFlags & FOF_MULTIDESTFILES && flFrom->dwNumFiles != 1 &&
- flFrom->dwNumFiles != flTo->dwNumFiles)
- {
- return ERROR_CANCELLED;
- }
+ if (flFrom->dwNumFiles != flTo->dwNumFiles)
+ {
+ if (flFrom->dwNumFiles != 1 && !IsAttribDir(fileDest->attributes))
+ return ERROR_CANCELLED;
- if (flFrom->dwNumFiles > 1 && flTo->dwNumFiles == 1 &&
- !PathFileExistsW(flTo->feFiles[0].szFullPath) &&
- IsAttribFile(fileDest->attributes))
- {
- bCancelIfAnyDirectories = TRUE;
+ flTo->dwNumFiles = 1;
+ }
+ else if (IsAttribDir(fileDest->attributes))
+ {
+ for (i = 1; i < flTo->dwNumFiles; i++)
+ if (!IsAttribDir(flTo->feFiles[i].attributes) ||
+ !IsAttribDir(flFrom->feFiles[i].attributes))
+ {
+ return ERROR_CANCELLED;
+ }
+ }
}
-
- if (flFrom->dwNumFiles > 1 && flTo->dwNumFiles == 1 && fileDest->bFromRelative &&
- !PathFileExistsW(fileDest->szFullPath))
+ else if (flFrom->dwNumFiles != 1)
{
- op->req->fAnyOperationsAborted = TRUE;
- return ERROR_CANCELLED;
- }
+ if (flTo->dwNumFiles != 1 && !IsAttribDir(fileDest->attributes))
+ return ERROR_CANCELLED;
- if (!(op->req->fFlags & FOF_MULTIDESTFILES) && flFrom->dwNumFiles != 1 &&
- PathFileExistsW(fileDest->szFullPath) &&
- IsAttribFile(fileDest->attributes))
- {
- return ERROR_CANCELLED;
+ if (PathFileExistsW(fileDest->szFullPath) &&
+ IsAttribFile(fileDest->attributes))
+ {
+ return ERROR_CANCELLED;
+ }
+
+ if (flTo->dwNumFiles == 1 && fileDest->bFromRelative &&
+ !PathFileExistsW(fileDest->szFullPath))
+ {
+ return ERROR_CANCELLED;
+ }
}
for (i = 0; i < flFrom->dwNumFiles; i++)
{
entryToCopy = &flFrom->feFiles[i];
- if (op->req->fFlags & FOF_MULTIDESTFILES)
+ if ((op->req->fFlags & FOF_MULTIDESTFILES) &&
+ flTo->dwNumFiles > 1)
+ {
fileDest = &flTo->feFiles[i];
+ }
if (IsAttribDir(entryToCopy->attributes) &&
!lstrcmpiW(entryToCopy->szFullPath, fileDest->szDirectory))
return ERROR_SUCCESS;
}
- if (IsAttribDir(entryToCopy->attributes) && bCancelIfAnyDirectories)
- return ERROR_CANCELLED;
-
create_dest_dirs(fileDest->szDirectory);
if (!lstrcmpiW(entryToCopy->szFullPath, fileDest->szFullPath))
}
if ((flFrom->dwNumFiles > 1 && flTo->dwNumFiles == 1) ||
- (IsAttribDir(fileDest->attributes) &&
- (flFrom->dwNumFiles == 1 || flFrom->bAnyFromWildcard)))
+ IsAttribDir(fileDest->attributes))
{
copy_to_dir(op, entryToCopy, fileDest);
}
CHAR to[5*MAX_PATH];
FILEOP_FLAGS tmp_flags;
DWORD retval;
+ LPSTR ptr;
shfo.hwnd = NULL;
shfo.wFunc = FO_COPY;
createTestFile("one.txt");
createTestFile("two.txt");
+ /* no double-NULL terminator for pTo,
+ * multiple source files,
+ * dest directory does not exist
+ */
+ memset(to, 'a', 2 * MAX_PATH);
+ lstrcpyA(to, "threedir");
+ shfo.pFrom = "one.txt\0two.txt\0";
+ shfo.pTo = to;
+ shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
+ retval = SHFileOperation(&shfo);
+ ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %d\n", retval);
+ ok(!DeleteFileA("threedir\\one.txt"), "Expected file to not exist\n");
+ ok(!DeleteFileA("threedir\\two.txt"), "Expected file to not exist\n");
+ ok(DeleteFileA("one.txt"), "Expected file to exist\n");
+ ok(DeleteFileA("two.txt"), "Expected file to exist\n");
+ ok(!DeleteFileA("threedir"), "Expected file to not exist\n");
+ ok(!RemoveDirectoryA("threedir"), "Expected dir to not exist\n");
+
+ createTestFile("one.txt");
+ createTestFile("two.txt");
+ CreateDirectoryA("threedir", NULL);
+
+ /* no double-NULL terminator for pTo,
+ * multiple source files,
+ * dest directory does exist
+ */
+ memset(to, 'a', 2 * MAX_PATH);
+ lstrcpyA(to, "threedir");
+ shfo.pFrom = "one.txt\0two.txt\0";
+ shfo.pTo = to;
+ shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
+ retval = SHFileOperation(&shfo);
+ ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
+ ok(DeleteFileA("threedir\\one.txt"), "Expected file to exist\n");
+ ok(DeleteFileA("threedir\\two.txt"), "Expected file to exist\n");
+ ok(DeleteFileA("one.txt"), "Expected file to exist\n");
+ ok(DeleteFileA("two.txt"), "Expected file to exist\n");
+ ok(RemoveDirectoryA("threedir"), "Expected dir to exist\n");
+
+ createTestFile("one.txt");
+ createTestFile("two.txt");
+
/* no double-NULL terminator for pTo,
* multiple source files, FOF_MULTIDESTFILES
+ * dest dir does not exist
*/
memset(to, 'a', 2 * MAX_PATH);
- lstrcpyA(to, "three.txt");
+ lstrcpyA(to, "threedir");
shfo.pFrom = "one.txt\0two.txt\0";
shfo.pTo = to;
shfo.fFlags = FOF_MULTIDESTFILES | FOF_NOCONFIRMATION |
FOF_SILENT | FOF_NOERRORUI;
retval = SHFileOperation(&shfo);
ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %d\n", retval);
+ ok(!DeleteFileA("threedir\\one.txt"), "Expected file to not exist\n");
+ ok(!DeleteFileA("threedir\\two.txt"), "Expected file to not exist\n");
ok(DeleteFileA("one.txt"), "Expected file to exist\n");
ok(DeleteFileA("two.txt"), "Expected file to exist\n");
+ ok(!RemoveDirectoryA("threedir"), "Expected dir to not exist\n");
todo_wine
{
- ok(!DeleteFileA("three.txt"), "Expected file to not exist\n");
+ ok(!DeleteFileA("threedir"), "Expected file to not exist\n");
}
+ createTestFile("one.txt");
+ createTestFile("two.txt");
+ CreateDirectoryA("threedir", NULL);
+
+ /* no double-NULL terminator for pTo,
+ * multiple source files, FOF_MULTIDESTFILES
+ * dest dir does exist
+ */
+ memset(to, 'a', 2 * MAX_PATH);
+ lstrcpyA(to, "threedir");
+ ptr = to + lstrlenA(to) + 1;
+ lstrcpyA(ptr, "fourdir");
+ shfo.pFrom = "one.txt\0two.txt\0";
+ shfo.pTo = to;
+ shfo.fFlags = FOF_MULTIDESTFILES | FOF_NOCONFIRMATION |
+ FOF_SILENT | FOF_NOERRORUI;
+ retval = SHFileOperation(&shfo);
+ ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
+ ok(DeleteFileA("threedir\\one.txt"), "Expected file to exist\n");
+ ok(DeleteFileA("threedir\\two.txt"), "Expected file to exist\n");
+ ok(DeleteFileA("one.txt"), "Expected file to exist\n");
+ ok(DeleteFileA("two.txt"), "Expected file to exist\n");
+ ok(RemoveDirectoryA("threedir"), "Expected dir to exist\n");
+ ok(!DeleteFileA("fourdir"), "Expected file to not exist\n");
+ ok(!RemoveDirectoryA("fourdir"), "Expected dir to not exist\n");
+
+ createTestFile("one.txt");
+ createTestFile("two.txt");
+ CreateDirectoryA("threedir", NULL);
+
+ /* multiple source files, FOF_MULTIDESTFILES
+ * multiple dest files, but first dest dir exists
+ * num files in lists is equal
+ */
+ shfo.pFrom = "one.txt\0two.txt\0";
+ shfo.pTo = "threedir\0fourdir\0";
+ shfo.fFlags = FOF_MULTIDESTFILES | FOF_NOCONFIRMATION |
+ FOF_SILENT | FOF_NOERRORUI;
+ retval = SHFileOperation(&shfo);
+ ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %d\n", retval);
+ ok(!DeleteFileA("threedir\\one.txt"), "Expected file to not exist\n");
+ ok(!DeleteFileA("threedir\\two.txt"), "Expected file to not exist\n");
+ ok(DeleteFileA("one.txt"), "Expected file to exist\n");
+ ok(DeleteFileA("two.txt"), "Expected file to exist\n");
+ ok(RemoveDirectoryA("threedir"), "Expected dir to exist\n");
+ ok(!DeleteFileA("fourdir"), "Expected file to not exist\n");
+ ok(!RemoveDirectoryA("fourdir"), "Expected dit to not exist\n");
+
+ createTestFile("one.txt");
+ createTestFile("two.txt");
+ CreateDirectoryA("threedir", NULL);
+
+ /* multiple source files, FOF_MULTIDESTFILES
+ * multiple dest files, but first dest dir exists
+ * num files in lists is not equal
+ */
+ shfo.pFrom = "one.txt\0two.txt\0";
+ shfo.pTo = "threedir\0fourdir\0five\0";
+ shfo.fFlags = FOF_MULTIDESTFILES | FOF_NOCONFIRMATION |
+ FOF_SILENT | FOF_NOERRORUI;
+ retval = SHFileOperation(&shfo);
+ ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
+ ok(DeleteFileA("threedir\\one.txt"), "Expected file to exist\n");
+ ok(DeleteFileA("threedir\\two.txt"), "Expected file to exist\n");
+ ok(DeleteFileA("one.txt"), "Expected file to exist\n");
+ ok(DeleteFileA("two.txt"), "Expected file to exist\n");
+ ok(RemoveDirectoryA("threedir"), "Expected dir to exist\n");
+ ok(!DeleteFileA("fourdir"), "Expected file to not exist\n");
+ ok(!RemoveDirectoryA("fourdir"), "Expected dit to not exist\n");
+ ok(!DeleteFileA("five"), "Expected file to not exist\n");
+ ok(!RemoveDirectoryA("five"), "Expected dit to not exist\n");
+
createTestFile("aa.txt");
createTestFile("ab.txt");
CreateDirectoryA("one", NULL);
ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
ok(DeleteFileA("one\\aa.txt"), "Expected file to exist\n");
ok(DeleteFileA("one\\ab.txt"), "Expected file to exist\n");
+ ok(!DeleteFileA("two\\aa.txt"), "Expected file to not exist\n");
+ ok(!DeleteFileA("two\\ab.txt"), "Expected file to not exist\n");
ok(DeleteFileA("aa.txt"), "Expected file to exist\n");
ok(DeleteFileA("ab.txt"), "Expected file to exist\n");
ok(RemoveDirectoryA("one"), "Expected dir to exist\n");