James Hawkins : shell32: Handle a few cases in FO_COPY that arise from not double-NULL terminating the input .
Alexandre Julliard
julliard at winehq.org
Wed Apr 2 06:55:37 CDT 2008
Module: wine
Branch: master
Commit: 6ecccdb790fad9dd24acdbc12fbc361ebe148fac
URL: http://source.winehq.org/git/wine.git/?a=commit;h=6ecccdb790fad9dd24acdbc12fbc361ebe148fac
Author: James Hawkins <jhawkins at codeweavers.com>
Date: Wed Apr 2 03:28:29 2008 -0500
shell32: Handle a few cases in FO_COPY that arise from not double-NULL terminating the input.
---
dlls/shell32/shlfileop.c | 11 +++-
dlls/shell32/tests/shlfileop.c | 111 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 119 insertions(+), 3 deletions(-)
diff --git a/dlls/shell32/shlfileop.c b/dlls/shell32/shlfileop.c
index 61d7ab0..cb7f995 100644
--- a/dlls/shell32/shlfileop.c
+++ b/dlls/shell32/shlfileop.c
@@ -1186,8 +1186,12 @@ static HRESULT copy_files(FILE_OPERATION *op, const FILE_LIST *flFrom, const FIL
if (op->req->fFlags & FOF_MULTIDESTFILES && flFrom->bAnyFromWildcard)
return ERROR_CANCELLED;
- if (!(op->req->fFlags & FOF_MULTIDESTFILES) && flTo->dwNumFiles != 1)
+ if (!(op->req->fFlags & FOF_MULTIDESTFILES) &&
+ flFrom->dwNumFiles != 1 && flTo->dwNumFiles != 1 &&
+ !flFrom->bAnyFromWildcard)
+ {
return ERROR_CANCELLED;
+ }
if (op->req->fFlags & FOF_MULTIDESTFILES && flFrom->dwNumFiles != 1 &&
flFrom->dwNumFiles != flTo->dwNumFiles)
@@ -1243,7 +1247,8 @@ static HRESULT copy_files(FILE_OPERATION *op, const FILE_LIST *flFrom, const FIL
}
if ((flFrom->dwNumFiles > 1 && flTo->dwNumFiles == 1) ||
- (flFrom->dwNumFiles == 1 && IsAttribDir(fileDest->attributes)))
+ (IsAttribDir(fileDest->attributes) &&
+ (flFrom->dwNumFiles == 1 || flFrom->bAnyFromWildcard)))
{
copy_to_dir(op, entryToCopy, fileDest);
}
@@ -1537,7 +1542,7 @@ int WINAPI SHFileOperationW(LPSHFILEOPSTRUCTW lpFileOp)
if (ret == ERROR_CANCELLED)
lpFileOp->fAnyOperationsAborted = TRUE;
-
+
return ret;
}
diff --git a/dlls/shell32/tests/shlfileop.c b/dlls/shell32/tests/shlfileop.c
index 247ab76..bc82fc1 100644
--- a/dlls/shell32/tests/shlfileop.c
+++ b/dlls/shell32/tests/shlfileop.c
@@ -839,6 +839,117 @@ static void test_copy(void)
retval = SHFileOperation(&shfo);
ok(retval == 0, "Expected 0, got %d\n", retval);
ok(file_has_content("testdir2\\test4.txt\\test1.txt", "test4.txt\\.\\test1.txt\n"), "The file was not copied\n");
+
+ createTestFile("one.txt");
+
+ /* no double-NULL terminator for pFrom */
+ memset(from, 'a', MAX_PATH);
+ lstrcpyA(from, "one.txt");
+ shfo.pFrom = from;
+ shfo.pTo = "two.txt\0";
+ shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
+ retval = SHFileOperation(&shfo);
+ todo_wine
+ {
+ ok(retval == 1148, "Expected 1148, got %d\n", retval);
+ }
+ ok(DeleteFileA("one.txt"), "Expected file to exist\n");
+ ok(!DeleteFileA("two.txt"), "Expected file to not exist\n");
+
+ createTestFile("one.txt");
+
+ /* no double-NULL terminator for pTo */
+ memset(to, 'a', MAX_PATH);
+ lstrcpyA(to, "two.txt");
+ shfo.pFrom = "one.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("one.txt"), "Expected file to exist\n");
+ ok(DeleteFileA("two.txt"), "Expected file to exist\n");
+
+ createTestFile("one.txt");
+
+ /* no FOF_MULTIDESTFILES, two files in pTo */
+ shfo.pFrom = "one.txt\0";
+ shfo.pTo = "two.txt\0three.txt\0";
+ shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
+ retval = SHFileOperation(&shfo);
+ ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
+ ok(DeleteFileA("one.txt"), "Expected file to exist\n");
+ ok(DeleteFileA("two.txt"), "Expected file to exist\n");
+
+ createTestFile("one.txt");
+
+ /* no double-NULL terminator for pFrom and pTo */
+ memset(from, 'a', MAX_PATH);
+ memset(to, 'a', MAX_PATH);
+ lstrcpyA(from, "one.txt");
+ lstrcpyA(to, "two.txt");
+ shfo.pFrom = from;
+ shfo.pTo = to;
+ shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
+ retval = SHFileOperation(&shfo);
+ todo_wine
+ {
+ ok(retval == 1148, "Expected 1148, got %d\n", retval);
+ }
+ ok(DeleteFileA("one.txt"), "Expected file to exist\n");
+ ok(!DeleteFileA("two.txt"), "Expected file to not exist\n");
+
+ createTestFile("one.txt");
+
+ /* no double-NULL terminator for pTo, FOF_MULTIDESTFILES */
+ memset(to, 'a', MAX_PATH);
+ lstrcpyA(to, "two.txt");
+ shfo.pFrom = "one.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("one.txt"), "Expected file to exist\n");
+ ok(DeleteFileA("two.txt"), "Expected file to exist\n");
+
+ createTestFile("one.txt");
+ createTestFile("two.txt");
+
+ /* no double-NULL terminator for pTo,
+ * multiple source files, FOF_MULTIDESTFILES
+ */
+ memset(to, 'a', 2 * MAX_PATH);
+ lstrcpyA(to, "three.txt");
+ 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("one.txt"), "Expected file to exist\n");
+ ok(DeleteFileA("two.txt"), "Expected file to exist\n");
+ todo_wine
+ {
+ ok(!DeleteFileA("three.txt"), "Expected file to not exist\n");
+ }
+
+ createTestFile("aa.txt");
+ createTestFile("ab.txt");
+ CreateDirectoryA("one", NULL);
+ CreateDirectoryA("two", NULL);
+
+ /* pFrom has a glob, pTo has more than one dest */
+ shfo.pFrom = "a*.txt\0";
+ shfo.pTo = "one\0two\0";
+ shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
+ retval = SHFileOperation(&shfo);
+ 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("aa.txt"), "Expected file to exist\n");
+ ok(DeleteFileA("ab.txt"), "Expected file to exist\n");
+ ok(RemoveDirectoryA("one"), "Expected dir to exist\n");
+ ok(RemoveDirectoryA("two"), "Expected dir to exist\n");
}
/* tests the FO_MOVE action */
More information about the wine-cvs
mailing list