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