[PATCH] shell32: Allow copy operation to overwrite an existing write protected file + tests

Christian Costa titan.costa at wanadoo.fr
Fri Feb 19 08:34:41 CST 2010


---

 dlls/shell32/shlfileop.c       |   10 +++++++++-
 dlls/shell32/tests/shlfileop.c |   20 ++++++++++++++++++++
 2 files changed, 29 insertions(+), 1 deletions(-)
-------------- next part --------------
diff --git a/dlls/shell32/shlfileop.c b/dlls/shell32/shlfileop.c
index 0b08f52..27e3c34 100644
--- a/dlls/shell32/shlfileop.c
+++ b/dlls/shell32/shlfileop.c
@@ -627,6 +627,14 @@ static DWORD SHNotifyCopyFileW(LPCWSTR src, LPCWSTR dest, BOOL bFailIfExists)
 
 	TRACE("(%s %s %s)\n", debugstr_w(src), debugstr_w(dest), bFailIfExists ? "failIfExists" : "");
 
+        if (PathFileExistsW(dest))
+        {
+          /* Destination file may already exist with read only attribute */
+          DWORD attribs = GetFileAttributesW(dest);
+          if (IsAttrib(attribs, FILE_ATTRIBUTE_READONLY))
+            SetFileAttributesW(dest, attribs &= ~ FILE_ATTRIBUTE_READONLY);
+        }
+
 	ret = CopyFileW(src, dest, bFailIfExists);
 	if (ret)
 	{
@@ -1132,7 +1140,7 @@ static BOOL copy_file_to_file(FILE_OPERATION *op, const WCHAR *szFrom, const WCH
         if (!SHELL_ConfirmDialogW(op->req->hwnd, ASK_OVERWRITE_FILE, PathFindFileNameW(szTo), op))
             return 0;
     }
-    
+
     return SHNotifyCopyFileW(szFrom, szTo, FALSE) == 0;
 }
 
diff --git a/dlls/shell32/tests/shlfileop.c b/dlls/shell32/tests/shlfileop.c
index 777801e..08867c8 100644
--- a/dlls/shell32/tests/shlfileop.c
+++ b/dlls/shell32/tests/shlfileop.c
@@ -965,6 +965,26 @@ static void test_copy(void)
     ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
     ok(file_exists("testdir2\\test1.txt"), "Expected testdir2\\test1 to exist\n");
 
+    /* try to overwrite an existing write protected file */
+    clean_after_shfo_tests();
+    init_shfo_tests();
+    tmp_flags = shfo.fFlags;
+    shfo.pFrom = "test1.txt\0";
+    shfo.pTo = "test2.txt\0";
+    /* suppress the error-dialog in win9x here */
+    shfo.fFlags = FOF_NOERRORUI | FOF_NOCONFIRMATION | FOF_SILENT;
+    ok(SetFileAttributesA(shfo.pTo, FILE_ATTRIBUTE_READONLY),
+        "Failure to set file attributes (error %x)\n", GetLastError());
+    retval = CopyFileA(shfo.pFrom, shfo.pTo, FALSE);
+    ok(!retval && GetLastError() == ERROR_ACCESS_DENIED, "CopyFileA should have fail with ERROR_ACCESS_DENIED\n");
+    retval = SHFileOperationA(&shfo);
+    /* Does not work on Win95, Win95B, NT4WS and NT4SRV */
+    ok(!retval || broken(retval == DE_OPCANCELLED), "SHFileOperationA failed to copy (error %x)\n", retval);
+    /* Set back normal attributes to make the file deletion succeed */
+    ok(SetFileAttributesA(shfo.pTo, FILE_ATTRIBUTE_NORMAL),
+        "Failure to set file attributes (error %x)\n", GetLastError());
+    shfo.fFlags = tmp_flags;
+
     /* try to copy files to a file */
     clean_after_shfo_tests();
     init_shfo_tests();


More information about the wine-patches mailing list