diff --git a/README.md b/README.md index 8d3b3990..5bdc9b03 100644 --- a/README.md +++ b/README.md @@ -39,12 +39,13 @@ Wine. All those differences are also documented on the Included bug fixes and improvements ----------------------------------- -**Bug fixes and features included in the next upcoming release [13]:** +**Bug fixes and features included in the next upcoming release [14]:** * Add IDragSourceHelper stub interface ([Wine Bug #24699](https://bugs.winehq.org/show_bug.cgi?id=24699)) * Catch invalid memory accesses in imagehlp.CheckSumMappedFile * Do not allow to deallocate thread stack for current thread * Fix detection of case-insensitive systems in MSYS2 +* Fix implementation of msvcrt.close when stdout == stderr * Implement enumeration of sound devices and basic properties to dxdiagn ([Wine Bug #32613](https://bugs.winehq.org/show_bug.cgi?id=32613)) * Implement shell32 NewMenu class with new folder item ([Wine Bug #24812](https://bugs.winehq.org/show_bug.cgi?id=24812)) * Implement special handling for calling GetChildContainer with an empty string ([Wine Bug #38014](https://bugs.winehq.org/show_bug.cgi?id=38014)) diff --git a/debian/changelog b/debian/changelog index 5c162722..28f300d0 100644 --- a/debian/changelog +++ b/debian/changelog @@ -24,6 +24,8 @@ wine-staging (1.7.50) UNRELEASED; urgency=low Wine Staging Bug #241). * Added patch to reject setting EOF on memory mapped files (fixes Wine Staging Bug #471). + * Added patch to fix implementation of msvcrt.close when stdout == stderr + (fixes Wine Staging Bug #485). * Removed patch to move security cookie initialization from memory management to loader (accepted upstream). * Removed patches for stub of D3DCompileFromFile and D3DCompile2 (accepted diff --git a/patches/msvcrt-StdHandle_RefCount/0001-msvcrt-tests-Add-tests-for-stdout-and-stderr-refcoun.patch b/patches/msvcrt-StdHandle_RefCount/0001-msvcrt-tests-Add-tests-for-stdout-and-stderr-refcoun.patch new file mode 100644 index 00000000..deba0e01 --- /dev/null +++ b/patches/msvcrt-StdHandle_RefCount/0001-msvcrt-tests-Add-tests-for-stdout-and-stderr-refcoun.patch @@ -0,0 +1,137 @@ +From 0b664b21287329f8c2828b3dc248fd460eece299 Mon Sep 17 00:00:00 2001 +From: Qian Hong +Date: Sat, 22 Aug 2015 11:20:31 +0800 +Subject: msvcrt/tests: Add tests for stdout and stderr refcount. + +--- + dlls/msvcrt/tests/file.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 93 insertions(+) + +diff --git a/dlls/msvcrt/tests/file.c b/dlls/msvcrt/tests/file.c +index ba8c3e3..7a79cb7 100644 +--- a/dlls/msvcrt/tests/file.c ++++ b/dlls/msvcrt/tests/file.c +@@ -1350,6 +1350,60 @@ static void test_file_inherit_child_no(const char* fd_s) + "Wrong write result in child process on %d (%s)\n", fd, strerror(errno)); + } + ++static void test_file_refcount_child(void) ++{ ++ static const char buffer1[] = "test1"; ++ static const char buffer2[] = "test2"; ++ static const char buffer3[] = "test3"; ++ static const char buffer4[] = "test4"; ++ HANDLE f0, f1, f2, h0, h1, h2; ++ DWORD written, flags, ret; ++ ++ f0 = (HANDLE)_get_osfhandle(STDIN_FILENO); ++ f1 = (HANDLE)_get_osfhandle(STDOUT_FILENO); ++ f2 = (HANDLE)_get_osfhandle(STDERR_FILENO); ++ ok(f0 == f1, "expected same handles, got %p, %p\n", f0, f1); ++ ok(f1 == f2, "expected same handles, got %p, %p\n", f1, f2); ++ ++ h0 = GetStdHandle(STD_INPUT_HANDLE); ++ h1 = GetStdHandle(STD_OUTPUT_HANDLE); ++ h2 = GetStdHandle(STD_ERROR_HANDLE); ++ ok(h0 == h1, "expected same handles, got %p, %p\n", h0, h1); ++ ok(h1 == h2, "expected same handles, got %p, %p\n", h1, h2); ++ ok(f0 == h0, "expected same handles, got %p, %p\n", f0, h0); ++ ++ ret = GetHandleInformation(h1, &flags); ++ ok(ret, "GetHandleInformation failed\n"); ++ ret = WriteFile(h1, buffer1, strlen(buffer1), &written, 0); ++ ok(ret, "WriteFile failed\n"); ++ ++ ret = fclose(stdout); ++ ok(ret == 0, "fclose failed\n"); ++ ret = GetHandleInformation(h1, &flags); ++todo_wine ++ ok(ret, "GetHandleInformation failed\n"); ++ ret = WriteFile(h1, buffer2, strlen(buffer2), &written, 0); ++todo_wine ++ ok(ret, "WriteFile failed\n"); ++ ++ ret = fclose(stdout); ++ ok(ret != 0, "fclose should fail\n"); ++ ret = GetHandleInformation(h1, &flags); ++todo_wine ++ ok(ret, "GetHandleInformation failed\n"); ++ ret = WriteFile(h1, buffer3, strlen(buffer3), &written, 0); ++todo_wine ++ ok(ret, "WriteFile failed\n"); ++ ++ ret = fclose(stderr); ++todo_wine ++ ok(ret == 0, "fclose failed\n"); ++ ret = GetHandleInformation(h1, &flags); ++ ok(!ret, "GetHandleInformation should fail\n"); ++ ret = WriteFile(h1, buffer4, strlen(buffer4), &written, 0); ++ ok(!ret, "WriteFile should fail\n"); ++} ++ + static void create_io_inherit_block( STARTUPINFOA *startup, unsigned int count, const HANDLE *handles ) + { + static BYTE block[1024]; +@@ -1423,6 +1477,37 @@ static void test_stdout_handle( STARTUPINFOA *startup, char *cmdline, HANDLE hst + DeleteFileA( "fdopen.err" ); + } + ++static void test_file_refcount( STARTUPINFOA *startup, char *cmdline, const char *descr ) ++{ ++ const char *data; ++ HANDLE hMixFile; ++ SECURITY_ATTRIBUTES sa; ++ PROCESS_INFORMATION proc; ++ ++ /* make file handle inheritable */ ++ sa.nLength = sizeof(sa); ++ sa.lpSecurityDescriptor = NULL; ++ sa.bInheritHandle = TRUE; ++ ++ hMixFile = CreateFileA( "fdopen.mix", GENERIC_READ|GENERIC_WRITE, ++ FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL ); ++ startup->dwFlags = STARTF_USESTDHANDLES; ++ startup->hStdInput = hMixFile; ++ startup->hStdOutput = hMixFile; ++ startup->hStdError = hMixFile; ++ ++ CreateProcessA( NULL, cmdline, NULL, NULL, TRUE, ++ CREATE_DEFAULT_ERROR_MODE | NORMAL_PRIORITY_CLASS, NULL, NULL, startup, &proc ); ++ winetest_wait_child_process( proc.hProcess ); ++ ++ data = read_file( hMixFile ); ++todo_wine ++ ok( !strcmp( data, "test1test2test3" ), "%s: Wrong error data (%s)\n", descr, data ); ++ ++ CloseHandle( hMixFile ); ++ DeleteFileA( "fdopen.mix" ); ++} ++ + static void test_file_inherit( const char* selfname ) + { + int fd; +@@ -1516,6 +1601,12 @@ static void test_file_inherit( const char* selfname ) + test_stdout_handle( &startup, cmdline, handles[1], TRUE, "large size block" ); + CloseHandle( handles[1] ); + DeleteFileA("fdopen.tst"); ++ ++ /* test refcount of handles */ ++ create_io_inherit_block( &startup, 0, NULL ); ++ sprintf(cmdline, "%s file refcount", selfname); ++ test_file_refcount( &startup, cmdline, "file refcount" ); ++ DeleteFileA("fdopen.tst"); + } + + static void test_tmpnam( void ) +@@ -2345,6 +2436,8 @@ START_TEST(file) + test_file_inherit_child_no(arg_v[3]); + else if (strcmp(arg_v[2], "pipes") == 0) + test_pipes_child(arg_c, arg_v); ++ else if (strcmp(arg_v[2], "refcount") == 0) ++ test_file_refcount_child(); + else + ok(0, "invalid argument '%s'\n", arg_v[2]); + return; +-- +2.5.0 + diff --git a/patches/msvcrt-StdHandle_RefCount/0002-msvcrt-Implemenent-refcount-check-for-stdout-and-std.patch b/patches/msvcrt-StdHandle_RefCount/0002-msvcrt-Implemenent-refcount-check-for-stdout-and-std.patch new file mode 100644 index 00000000..b538e989 --- /dev/null +++ b/patches/msvcrt-StdHandle_RefCount/0002-msvcrt-Implemenent-refcount-check-for-stdout-and-std.patch @@ -0,0 +1,81 @@ +From d55190c65e4cbdd8f81992ae842581a253b5ece6 Mon Sep 17 00:00:00 2001 +From: Qian Hong +Date: Sat, 22 Aug 2015 11:21:32 +0800 +Subject: msvcrt: Implemenent refcount check for stdout and stderr. + +--- + dlls/msvcrt/file.c | 15 +++++++++------ + dlls/msvcrt/tests/file.c | 6 ------ + 2 files changed, 9 insertions(+), 12 deletions(-) + +diff --git a/dlls/msvcrt/file.c b/dlls/msvcrt/file.c +index f304ec4..49cd4f0 100644 +--- a/dlls/msvcrt/file.c ++++ b/dlls/msvcrt/file.c +@@ -1007,18 +1007,21 @@ int CDECL MSVCRT__fflush_nolock(MSVCRT_FILE* file) + int CDECL MSVCRT__close(int fd) + { + ioinfo *info = get_ioinfo(fd); +- int ret; ++ int ret = 0; + + TRACE(":fd (%d) handle (%p)\n", fd, info->handle); + if (!(info->wxflag & WX_OPEN)) { + ret = -1; + } else { +- ret = CloseHandle(info->handle) ? 0 : -1; +- msvcrt_free_fd(fd); +- if (ret) { +- WARN(":failed-last error (%d)\n",GetLastError()); +- msvcrt_set_errno(GetLastError()); ++ if ((fd != MSVCRT_STDOUT_FILENO && fd != MSVCRT_STDERR_FILENO) || ++ get_ioinfo_nolock(MSVCRT_STDOUT_FILENO)->handle != get_ioinfo_nolock(MSVCRT_STDERR_FILENO)->handle) { ++ ret = CloseHandle(info->handle) ? 0 : -1; ++ if (ret) { ++ WARN(":failed-last error (%d)\n",GetLastError()); ++ msvcrt_set_errno(GetLastError()); ++ } + } ++ msvcrt_free_fd(fd); + } + release_ioinfo(info); + return ret; +diff --git a/dlls/msvcrt/tests/file.c b/dlls/msvcrt/tests/file.c +index 7a79cb7..ea7d307 100644 +--- a/dlls/msvcrt/tests/file.c ++++ b/dlls/msvcrt/tests/file.c +@@ -1380,23 +1380,18 @@ static void test_file_refcount_child(void) + ret = fclose(stdout); + ok(ret == 0, "fclose failed\n"); + ret = GetHandleInformation(h1, &flags); +-todo_wine + ok(ret, "GetHandleInformation failed\n"); + ret = WriteFile(h1, buffer2, strlen(buffer2), &written, 0); +-todo_wine + ok(ret, "WriteFile failed\n"); + + ret = fclose(stdout); + ok(ret != 0, "fclose should fail\n"); + ret = GetHandleInformation(h1, &flags); +-todo_wine + ok(ret, "GetHandleInformation failed\n"); + ret = WriteFile(h1, buffer3, strlen(buffer3), &written, 0); +-todo_wine + ok(ret, "WriteFile failed\n"); + + ret = fclose(stderr); +-todo_wine + ok(ret == 0, "fclose failed\n"); + ret = GetHandleInformation(h1, &flags); + ok(!ret, "GetHandleInformation should fail\n"); +@@ -1501,7 +1496,6 @@ static void test_file_refcount( STARTUPINFOA *startup, char *cmdline, const char + winetest_wait_child_process( proc.hProcess ); + + data = read_file( hMixFile ); +-todo_wine + ok( !strcmp( data, "test1test2test3" ), "%s: Wrong error data (%s)\n", descr, data ); + + CloseHandle( hMixFile ); +-- +2.5.0 + diff --git a/patches/msvcrt-StdHandle_RefCount/0003-msvcrt-Use-constants-instead-of-hardcoded-values.patch b/patches/msvcrt-StdHandle_RefCount/0003-msvcrt-Use-constants-instead-of-hardcoded-values.patch new file mode 100644 index 00000000..ae0bfca8 --- /dev/null +++ b/patches/msvcrt-StdHandle_RefCount/0003-msvcrt-Use-constants-instead-of-hardcoded-values.patch @@ -0,0 +1,33 @@ +From a491ae0671f0bf8e482ede7ad5b0538bd10ed87d Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Sat, 22 Aug 2015 07:22:56 +0200 +Subject: msvcrt: Use constants instead of hardcoded values. + +--- + dlls/msvcrt/file.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/dlls/msvcrt/file.c b/dlls/msvcrt/file.c +index 49cd4f0..a62f73d 100644 +--- a/dlls/msvcrt/file.c ++++ b/dlls/msvcrt/file.c +@@ -393,13 +393,13 @@ static void msvcrt_free_fd(int fd) + { + switch (fd) + { +- case 0: ++ case MSVCRT_STDIN_FILENO: + SetStdHandle(STD_INPUT_HANDLE, 0); + break; +- case 1: ++ case MSVCRT_STDOUT_FILENO: + SetStdHandle(STD_OUTPUT_HANDLE, 0); + break; +- case 2: ++ case MSVCRT_STDERR_FILENO: + SetStdHandle(STD_ERROR_HANDLE, 0); + break; + } +-- +2.5.0 + diff --git a/patches/msvcrt-StdHandle_RefCount/definition b/patches/msvcrt-StdHandle_RefCount/definition new file mode 100644 index 00000000..96394db3 --- /dev/null +++ b/patches/msvcrt-StdHandle_RefCount/definition @@ -0,0 +1,3 @@ +Fixes: Fix implementation of msvcrt.close when stdout == stderr + +# FIXME: Should msvcrt implement refcounting for all handles? diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index faa552b8..922c31d6 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -157,6 +157,7 @@ patch_enable_all () enable_mscoree_CorValidateImage="$1" enable_msvcp90_basic_string_dtor="$1" enable_msvcrt_Math_Precision="$1" + enable_msvcrt_StdHandle_RefCount="$1" enable_msvfw32_Image_Size="$1" enable_ntdll_APC_Performance="$1" enable_ntdll_APC_Start_Process="$1" @@ -559,6 +560,9 @@ patch_enable () msvcrt-Math_Precision) enable_msvcrt_Math_Precision="$2" ;; + msvcrt-StdHandle_RefCount) + enable_msvcrt_StdHandle_RefCount="$2" + ;; msvfw32-Image_Size) enable_msvfw32_Image_Size="$2" ;; @@ -3529,6 +3533,22 @@ if test "$enable_msvcrt_Math_Precision" -eq 1; then ) >> "$patchlist" fi +# Patchset msvcrt-StdHandle_RefCount +# | +# | Modified files: +# | * dlls/msvcrt/file.c, dlls/msvcrt/tests/file.c +# | +if test "$enable_msvcrt_StdHandle_RefCount" -eq 1; then + patch_apply msvcrt-StdHandle_RefCount/0001-msvcrt-tests-Add-tests-for-stdout-and-stderr-refcoun.patch + patch_apply msvcrt-StdHandle_RefCount/0002-msvcrt-Implemenent-refcount-check-for-stdout-and-std.patch + patch_apply msvcrt-StdHandle_RefCount/0003-msvcrt-Use-constants-instead-of-hardcoded-values.patch + ( + echo '+ { "Qian Hong", "msvcrt/tests: Add tests for stdout and stderr refcount.", 1 },'; + echo '+ { "Qian Hong", "msvcrt: Implemenent refcount check for stdout and stderr.", 1 },'; + echo '+ { "Sebastian Lackner", "msvcrt: Use constants instead of hardcoded values.", 1 },'; + ) >> "$patchlist" +fi + # Patchset msvfw32-Image_Size # | # | This patchset fixes the following Wine bugs: