From ffe90cf9f7ce824ad8ed7215cabd5ae7a350f315 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Sat, 9 May 2015 00:42:45 +0200 Subject: [PATCH] kernel32-CopyFileEx: Fix test failures in kernel32/file and add additional tests. --- debian/changelog | 2 + ...dd-tests-for-delete-behaviour-of-Cop.patch | 88 +++++++++++++++++++ ...ort-for-progress-callback-in-CopyFi.patch} | 61 ++++++++++--- patches/patchinstall.sh | 6 +- 4 files changed, 143 insertions(+), 14 deletions(-) create mode 100644 patches/kernel32-CopyFileEx/0001-kernel32-tests-Add-tests-for-delete-behaviour-of-Cop.patch rename patches/kernel32-CopyFileEx/{0001-kernel32-Add-support-for-progress-callback-in-CopyFi.patch => 0002-kernel32-Add-support-for-progress-callback-in-CopyFi.patch} (55%) diff --git a/debian/changelog b/debian/changelog index a1e55b68..17b3bed6 100644 --- a/debian/changelog +++ b/debian/changelog @@ -2,6 +2,8 @@ wine-staging (1.7.43) UNRELEASED; urgency=low * Disable patchset shell32-Default_Folder_ACLs (fixes Wine Staging Bug #265). * Updated patch to calculate msvcrt exponential math operations with higher precision (fixes Wine Staging Bug #268). + * Updated patchset for CopyFileEx improvements, fix testfailures in + kernel32/file and add additional tests. * Added patch to wait before reusing recently freed memory (fixes Wine Staging Bug #269 and #199). * Added patch to improve ReadDataAvailable handling in diff --git a/patches/kernel32-CopyFileEx/0001-kernel32-tests-Add-tests-for-delete-behaviour-of-Cop.patch b/patches/kernel32-CopyFileEx/0001-kernel32-tests-Add-tests-for-delete-behaviour-of-Cop.patch new file mode 100644 index 00000000..4e391f83 --- /dev/null +++ b/patches/kernel32-CopyFileEx/0001-kernel32-tests-Add-tests-for-delete-behaviour-of-Cop.patch @@ -0,0 +1,88 @@ +From 83deea381c8297ff55f69b04765b6f6f8a012120 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Sat, 9 May 2015 00:26:25 +0200 +Subject: kernel32/tests: Add tests for delete behaviour of CopyFileEx. + +--- + dlls/kernel32/tests/file.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 58 insertions(+) + +diff --git a/dlls/kernel32/tests/file.c b/dlls/kernel32/tests/file.c +index 9a6e972..0a8e0e2 100644 +--- a/dlls/kernel32/tests/file.c ++++ b/dlls/kernel32/tests/file.c +@@ -1099,6 +1099,63 @@ static void test_CopyFile2(void) + DeleteFileW(dest); + } + ++static DWORD WINAPI copy_progress_cb(LARGE_INTEGER total_size, LARGE_INTEGER total_transferred, ++ LARGE_INTEGER stream_size, LARGE_INTEGER stream_transferred, ++ DWORD stream, DWORD reason, HANDLE source, HANDLE dest, LPVOID userdata) ++{ ++ ok(reason == CALLBACK_STREAM_SWITCH, "expected CALLBACK_STREAM_SWITCH, got %u\n", reason); ++ CloseHandle(userdata); ++ return PROGRESS_CANCEL; ++} ++ ++static void test_CopyFileEx(void) ++{ ++ char temp_path[MAX_PATH]; ++ char source[MAX_PATH], dest[MAX_PATH]; ++ static const char prefix[] = "pfx"; ++ HANDLE hfile; ++ DWORD ret; ++ BOOL retok; ++ ++ ret = GetTempPathA(MAX_PATH, temp_path); ++ ok(ret != 0, "GetTempPathA error %d\n", GetLastError()); ++ ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n"); ++ ++ ret = GetTempFileNameA(temp_path, prefix, 0, source); ++ ok(ret != 0, "GetTempFileNameA error %d\n", GetLastError()); ++ ++ ret = GetTempFileNameA(temp_path, prefix, 0, dest); ++ ok(ret != 0, "GetTempFileNameA error %d\n", GetLastError()); ++ ++ hfile = CreateFileA(dest, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0); ++ ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file, error %d\n", GetLastError()); ++ SetLastError(0xdeadbeef); ++ retok = CopyFileExA(source, dest, copy_progress_cb, hfile, NULL, 0); ++ todo_wine ++ ok(!retok, "CopyFileExA unexpectedly succeeded\n"); ++ todo_wine ++ ok(GetLastError() == ERROR_REQUEST_ABORTED, "expected ERROR_REQUEST_ABORTED, got %d\n", GetLastError()); ++ ok(GetFileAttributesA( dest ) != INVALID_FILE_ATTRIBUTES, "file was deleted\n"); ++ ++ hfile = CreateFileA(dest, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE | FILE_SHARE_DELETE, ++ NULL, OPEN_EXISTING, 0, 0); ++ todo_wine ++ ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file, error %d\n", GetLastError()); ++ SetLastError(0xdeadbeef); ++ retok = CopyFileExA(source, dest, copy_progress_cb, hfile, NULL, 0); ++ todo_wine ++ ok(!retok, "CopyFileExA unexpectedly succeeded\n"); ++ todo_wine ++ ok(GetLastError() == ERROR_REQUEST_ABORTED, "expected ERROR_REQUEST_ABORTED, got %d\n", GetLastError()); ++ todo_wine ++ ok(GetFileAttributesA( dest ) == INVALID_FILE_ATTRIBUTES, "file was not deleted\n"); ++ ++ ret = DeleteFileA(source); ++ ok(ret, "DeleteFileA failed with error %d\n", GetLastError()); ++ ret = DeleteFileA(dest); ++ ok(!ret, "DeleteFileA unexpectedly succeeded\n"); ++} ++ + /* + * Debugging routine to dump a buffer in a hexdump-like fashion. + */ +@@ -4447,6 +4504,7 @@ START_TEST(file) + test_CopyFileA(); + test_CopyFileW(); + test_CopyFile2(); ++ test_CopyFileEx(); + test_CreateFile(); + test_CreateFileA(); + test_CreateFileW(); +-- +2.4.0 + diff --git a/patches/kernel32-CopyFileEx/0001-kernel32-Add-support-for-progress-callback-in-CopyFi.patch b/patches/kernel32-CopyFileEx/0002-kernel32-Add-support-for-progress-callback-in-CopyFi.patch similarity index 55% rename from patches/kernel32-CopyFileEx/0001-kernel32-Add-support-for-progress-callback-in-CopyFi.patch rename to patches/kernel32-CopyFileEx/0002-kernel32-Add-support-for-progress-callback-in-CopyFi.patch index 40248422..bb030bf9 100644 --- a/patches/kernel32-CopyFileEx/0001-kernel32-Add-support-for-progress-callback-in-CopyFi.patch +++ b/patches/kernel32-CopyFileEx/0002-kernel32-Add-support-for-progress-callback-in-CopyFi.patch @@ -1,17 +1,18 @@ -From a8dd7b9fd0ffbcba8a5e4e69c32c1fa1143d6965 Mon Sep 17 00:00:00 2001 +From 18a7daf004ad8d8d773dfbcaf390c9fad2ebfaed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20M=C3=BCller?= Date: Thu, 26 Feb 2015 06:41:26 +0100 Subject: kernel32: Add support for progress callback in CopyFileEx. --- - dlls/kernel32/path.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++-- - 1 file changed, 58 insertions(+), 2 deletions(-) + dlls/kernel32/path.c | 68 +++++++++++++++++++++++++++++++++++++++++++--- + dlls/kernel32/tests/file.c | 6 ---- + 2 files changed, 64 insertions(+), 10 deletions(-) diff --git a/dlls/kernel32/path.c b/dlls/kernel32/path.c -index 475b1f6..2e521a5 100644 +index 179c8e0..df98f26 100644 --- a/dlls/kernel32/path.c +++ b/dlls/kernel32/path.c -@@ -1092,6 +1092,9 @@ BOOL WINAPI CopyFileExW(LPCWSTR source, LPCWSTR dest, +@@ -1112,6 +1112,9 @@ BOOL WINAPI CopyFileExW(LPCWSTR source, LPCWSTR dest, DWORD count; BOOL ret = FALSE; char *buffer; @@ -21,7 +22,7 @@ index 475b1f6..2e521a5 100644 if (!source || !dest) { -@@ -1106,7 +1109,13 @@ BOOL WINAPI CopyFileExW(LPCWSTR source, LPCWSTR dest, +@@ -1126,7 +1129,13 @@ BOOL WINAPI CopyFileExW(LPCWSTR source, LPCWSTR dest, TRACE("%s -> %s, %x\n", debugstr_w(source), debugstr_w(dest), flags); @@ -36,16 +37,24 @@ index 475b1f6..2e521a5 100644 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, 0)) == INVALID_HANDLE_VALUE) { -@@ -1142,7 +1151,7 @@ BOOL WINAPI CopyFileExW(LPCWSTR source, LPCWSTR dest, +@@ -1162,9 +1171,13 @@ BOOL WINAPI CopyFileExW(LPCWSTR source, LPCWSTR dest, } } - if ((h2 = CreateFileW( dest, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, +- (flags & COPY_FILE_FAIL_IF_EXISTS) ? CREATE_NEW : CREATE_ALWAYS, +- info.dwFileAttributes, h1 )) == INVALID_HANDLE_VALUE) + if ((h2 = CreateFileW( dest, GENERIC_WRITE | DELETE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, - (flags & COPY_FILE_FAIL_IF_EXISTS) ? CREATE_NEW : CREATE_ALWAYS, - info.dwFileAttributes, h1 )) == INVALID_HANDLE_VALUE) ++ (flags & COPY_FILE_FAIL_IF_EXISTS) ? CREATE_NEW : CREATE_ALWAYS, ++ info.dwFileAttributes, h1 )) == INVALID_HANDLE_VALUE && ++ /* retry without DELETE if we got a sharing violation */ ++ (h2 = CreateFileW( dest, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, ++ (flags & COPY_FILE_FAIL_IF_EXISTS) ? CREATE_NEW : CREATE_ALWAYS, ++ info.dwFileAttributes, h1 )) == INVALID_HANDLE_VALUE) { -@@ -1152,6 +1161,31 @@ BOOL WINAPI CopyFileExW(LPCWSTR source, LPCWSTR dest, + WARN("Unable to open dest %s\n", debugstr_w(dest)); + HeapFree( GetProcessHeap(), 0, buffer ); +@@ -1172,6 +1185,31 @@ BOOL WINAPI CopyFileExW(LPCWSTR source, LPCWSTR dest, return FALSE; } @@ -77,7 +86,7 @@ index 475b1f6..2e521a5 100644 while (ReadFile( h1, buffer, buffer_size, &count, NULL ) && count) { char *p = buffer; -@@ -1161,6 +1195,28 @@ BOOL WINAPI CopyFileExW(LPCWSTR source, LPCWSTR dest, +@@ -1181,6 +1219,28 @@ BOOL WINAPI CopyFileExW(LPCWSTR source, LPCWSTR dest, if (!WriteFile( h2, p, count, &res, NULL ) || !res) goto done; p += res; count -= res; @@ -106,6 +115,34 @@ index 475b1f6..2e521a5 100644 } } ret = TRUE; +diff --git a/dlls/kernel32/tests/file.c b/dlls/kernel32/tests/file.c +index 0a8e0e2..ffebd8d 100644 +--- a/dlls/kernel32/tests/file.c ++++ b/dlls/kernel32/tests/file.c +@@ -1131,23 +1131,17 @@ static void test_CopyFileEx(void) + ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file, error %d\n", GetLastError()); + SetLastError(0xdeadbeef); + retok = CopyFileExA(source, dest, copy_progress_cb, hfile, NULL, 0); +- todo_wine + ok(!retok, "CopyFileExA unexpectedly succeeded\n"); +- todo_wine + ok(GetLastError() == ERROR_REQUEST_ABORTED, "expected ERROR_REQUEST_ABORTED, got %d\n", GetLastError()); + ok(GetFileAttributesA( dest ) != INVALID_FILE_ATTRIBUTES, "file was deleted\n"); + + hfile = CreateFileA(dest, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE | FILE_SHARE_DELETE, + NULL, OPEN_EXISTING, 0, 0); +- todo_wine + ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file, error %d\n", GetLastError()); + SetLastError(0xdeadbeef); + retok = CopyFileExA(source, dest, copy_progress_cb, hfile, NULL, 0); +- todo_wine + ok(!retok, "CopyFileExA unexpectedly succeeded\n"); +- todo_wine + ok(GetLastError() == ERROR_REQUEST_ABORTED, "expected ERROR_REQUEST_ABORTED, got %d\n", GetLastError()); +- todo_wine + ok(GetFileAttributesA( dest ) == INVALID_FILE_ATTRIBUTES, "file was not deleted\n"); + + ret = DeleteFileA(source); -- -2.1.0 +2.4.0 diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index 6512a283..ad04a92e 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -3191,11 +3191,13 @@ fi # | * [#22690] Allow to cancel a file operation via progress callback # | # | Modified files: -# | * dlls/kernel32/path.c +# | * dlls/kernel32/path.c, dlls/kernel32/tests/file.c # | if test "$enable_kernel32_CopyFileEx" -eq 1; then - patch_apply kernel32-CopyFileEx/0001-kernel32-Add-support-for-progress-callback-in-CopyFi.patch + patch_apply kernel32-CopyFileEx/0001-kernel32-tests-Add-tests-for-delete-behaviour-of-Cop.patch + patch_apply kernel32-CopyFileEx/0002-kernel32-Add-support-for-progress-callback-in-CopyFi.patch ( + echo '+ { "Sebastian Lackner", "kernel32/tests: Add tests for delete behaviour of CopyFileEx.", 1 },'; echo '+ { "Michael Müller", "kernel32: Add support for progress callback in CopyFileEx.", 1 },'; ) >> "$patchlist" fi