diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index 5e904d82..610ac343 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -374,6 +374,7 @@ patch_enable_all () enable_ws2_32_WSACleanup="$1" enable_ws2_32_WriteWatches="$1" enable_ws2_32_getaddrinfo="$1" + enable_ws2_32_getsockopt="$1" enable_wtsapi32_EnumerateProcesses="$1" enable_wusa_MSU_Package_Installer="$1" } @@ -1270,6 +1271,9 @@ patch_enable () ws2_32-getaddrinfo) enable_ws2_32_getaddrinfo="$2" ;; + ws2_32-getsockopt) + enable_ws2_32_getsockopt="$2" + ;; wtsapi32-EnumerateProcesses) enable_wtsapi32_EnumerateProcesses="$2" ;; @@ -7599,6 +7603,21 @@ if test "$enable_ws2_32_getaddrinfo" -eq 1; then ) >> "$patchlist" fi +# Patchset ws2_32-getsockopt +# | +# | This patchset fixes the following Wine bugs: +# | * [#8606] Divide values returned by SO_RCVBUF and SO_SNDBUF getsockopt options by two +# | +# | Modified files: +# | * dlls/ws2_32/socket.c, dlls/ws2_32/tests/sock.c +# | +if test "$enable_ws2_32_getsockopt" -eq 1; then + patch_apply ws2_32-getsockopt/0001-ws2_32-Divide-values-returned-by-SO_RCVBUF-and-SO_SN.patch + ( + echo '+ { "Sebastian Lackner", "ws2_32: Divide values returned by SO_RCVBUF and SO_SNDBUF getsockopt options by two.", 1 },'; + ) >> "$patchlist" +fi + # Patchset wtsapi32-EnumerateProcesses # | # | This patchset fixes the following Wine bugs: diff --git a/patches/ws2_32-getsockopt/0001-ws2_32-Divide-values-returned-by-SO_RCVBUF-and-SO_SN.patch b/patches/ws2_32-getsockopt/0001-ws2_32-Divide-values-returned-by-SO_RCVBUF-and-SO_SN.patch new file mode 100644 index 00000000..52a6f3d3 --- /dev/null +++ b/patches/ws2_32-getsockopt/0001-ws2_32-Divide-values-returned-by-SO_RCVBUF-and-SO_SN.patch @@ -0,0 +1,73 @@ +From 881b4446e9f6abc97ff6bead1bfba18b49a5acca Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Mon, 8 Feb 2016 02:31:00 +0100 +Subject: ws2_32: Divide values returned by SO_RCVBUF and SO_SNDBUF getsockopt + options by two. + +--- + dlls/ws2_32/socket.c | 8 ++++++++ + dlls/ws2_32/tests/sock.c | 22 ++++++++++++++++++++++ + 2 files changed, 30 insertions(+) + +diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c +index f62c9cd..e17b163 100644 +--- a/dlls/ws2_32/socket.c ++++ b/dlls/ws2_32/socket.c +@@ -3736,6 +3736,14 @@ INT WINAPI WS_getsockopt(SOCKET s, INT level, + SetLastError(wsaErrno()); + ret = SOCKET_ERROR; + } ++ #ifdef __linux__ ++ else if (optname == SO_RCVBUF || optname == SO_SNDBUF) ++ { ++ /* For SO_RCVBUF / SO_SNDBUF, the Linux kernel always sets twice the value. ++ * Divide by two to ensure applications do not get confused by the result. */ ++ *(int *)optval /= 2; ++ } ++ #endif + release_sock_fd( s, fd ); + return ret; + case WS_SO_ACCEPTCONN: +diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c +index aeb7a62..2e7ab20 100644 +--- a/dlls/ws2_32/tests/sock.c ++++ b/dlls/ws2_32/tests/sock.c +@@ -1328,6 +1328,7 @@ static void test_set_getsockopt(void) + WSAPROTOCOL_INFOA infoA; + WSAPROTOCOL_INFOW infoW; + char providername[WSAPROTOCOL_LEN + 1]; ++ DWORD value; + struct _prottest + { + int family, type, proto; +@@ -1371,6 +1372,27 @@ static void test_set_getsockopt(void) + err = getsockopt(s, SOL_SOCKET, SO_SNDTIMEO, (char *) &timeout, &size); + ok( !err, "get/setsockopt(SO_SNDTIMEO) failed error: %d\n", WSAGetLastError()); + ok( timeout == SOCKTIMEOUT2, "getsockopt(SO_SNDTIMEO) returned wrong value %d\n", timeout); ++ ++ /* SO_SNDBUF */ ++ value = 4096; ++ size = sizeof(DWORD); ++ err = setsockopt(s, SOL_SOCKET, SO_SNDBUF, (char *)&value, size); ++ ok( !err, "setsockopt(SO_SNDBUF) failed error: %u\n", WSAGetLastError()); ++ value = 0xdeadbeef; ++ err = getsockopt(s, SOL_SOCKET, SO_SNDBUF, (char *)&value, &size); ++ ok( !err, "getsockopt(SO_SNDBUF) failed error: %u\n", WSAGetLastError()); ++ ok( value == 4096, "expected 4096, got %u\n", value ); ++ ++ /* SO_RCVBUF */ ++ value = 4096; ++ size = sizeof(DWORD); ++ err = setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&value, size); ++ ok( !err, "setsockopt(SO_RCVBUF) failed error: %u\n", WSAGetLastError()); ++ value = 0xdeadbeef; ++ err = getsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&value, &size); ++ ok( !err, "getsockopt(SO_RCVBUF) failed error: %u\n", WSAGetLastError()); ++ ok( value == 4096, "expected 4096, got %u\n", value ); ++ + /* SO_LINGER */ + for( i = 0; i < sizeof(linger_testvals)/sizeof(LINGER);i++) { + size = sizeof(lingval); +-- +2.7.0 + diff --git a/patches/ws2_32-getsockopt/definition b/patches/ws2_32-getsockopt/definition new file mode 100644 index 00000000..b0782086 --- /dev/null +++ b/patches/ws2_32-getsockopt/definition @@ -0,0 +1 @@ +Fixes: [8606] Divide values returned by SO_RCVBUF and SO_SNDBUF getsockopt options by two