From 240afab36275d72c10f6dc4bcc52419562ef240f Mon Sep 17 00:00:00 2001 From: Christian Costa Date: Tue, 23 Feb 2010 09:53:23 +0100 Subject: [PATCH] shell32: Allow copy operation to overwrite an existing write protected file + tests. --- dlls/shell32/shlfileop.c | 8 +++++++- dlls/shell32/tests/shlfileop.c | 20 ++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/dlls/shell32/shlfileop.c b/dlls/shell32/shlfileop.c index 0b08f52a820..702a6c099d5 100644 --- a/dlls/shell32/shlfileop.c +++ b/dlls/shell32/shlfileop.c @@ -624,9 +624,15 @@ static DWORD SHNotifyMoveFileW(LPCWSTR src, LPCWSTR dest) static DWORD SHNotifyCopyFileW(LPCWSTR src, LPCWSTR dest, BOOL bFailIfExists) { BOOL ret; + DWORD attribs; TRACE("(%s %s %s)\n", debugstr_w(src), debugstr_w(dest), bFailIfExists ? "failIfExists" : ""); + /* Destination file may already exist with read only attribute */ + attribs = GetFileAttributesW(dest); + if (IsAttrib(attribs, FILE_ATTRIBUTE_READONLY)) + SetFileAttributesW(dest, attribs & ~FILE_ATTRIBUTE_READONLY); + ret = CopyFileW(src, dest, bFailIfExists); if (ret) { @@ -1132,7 +1138,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 777801e7786..08867c87d6c 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();