From 3f85f1763b0f46a70b3e6465cbe09dc277df6653 Mon Sep 17 00:00:00 2001 From: "Erich E. Hoover" Date: Wed, 7 Jan 2015 11:17:26 -0700 Subject: [PATCH] Actually add patch for previous commit... --- ...-SetLastError-for-successful-WSARecv.patch | 173 ++++++++++++++++++ patches/ws2_32-WSARecv_Last_Error/definition | 1 + 2 files changed, 174 insertions(+) create mode 100644 patches/ws2_32-WSARecv_Last_Error/0001-ws2_32-Call-SetLastError-for-successful-WSARecv.patch create mode 100644 patches/ws2_32-WSARecv_Last_Error/definition diff --git a/patches/ws2_32-WSARecv_Last_Error/0001-ws2_32-Call-SetLastError-for-successful-WSARecv.patch b/patches/ws2_32-WSARecv_Last_Error/0001-ws2_32-Call-SetLastError-for-successful-WSARecv.patch new file mode 100644 index 00000000..c10f2c51 --- /dev/null +++ b/patches/ws2_32-WSARecv_Last_Error/0001-ws2_32-Call-SetLastError-for-successful-WSARecv.patch @@ -0,0 +1,173 @@ +From b95464321386d1255dc803d4a7b02a47564177fc Mon Sep 17 00:00:00 2001 +From: Heiko Przybyl +Date: Tue, 6 Jan 2015 14:03:14 -0700 +Subject: ws2_32: Call SetLastError for successful WSARecv. + +--- + dlls/ws2_32/socket.c | 2 +- + dlls/ws2_32/tests/sock.c | 129 +++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 130 insertions(+), 1 deletion(-) + +diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c +index 4edc38f..9b25e23 100644 +--- a/dlls/ws2_32/socket.c ++++ b/dlls/ws2_32/socket.c +@@ -6776,7 +6776,7 @@ static int WS2_recv_base( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, + if (wsa != &localwsa) HeapFree( GetProcessHeap(), 0, wsa ); + release_sock_fd( s, fd ); + _enable_event(SOCKET2HANDLE(s), FD_READ, 0, 0); +- ++ WSASetLastError(0); + return 0; + + error: +diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c +index d87f326..490be4c 100644 +--- a/dlls/ws2_32/tests/sock.c ++++ b/dlls/ws2_32/tests/sock.c +@@ -5806,6 +5806,134 @@ end: + WSACloseEvent(ov.hEvent); + } + ++static DWORD WINAPI recv_thread_non_overlapped(LPVOID arg) ++{ ++ SOCKET sock = *(SOCKET *)arg; ++ char buffer[32]; ++ WSABUF wsa; ++ DWORD flags = 0; ++ int c = 0, ret; ++ ++ wsa.buf = buffer; ++ wsa.len = sizeof(buffer); ++ ++ /* For non-blocking sockets this can cause WSAEWOULDBLOCK */ ++ do { ++ ret = WSARecv(sock, &wsa, 1, NULL, &flags, NULL, NULL); ++ Sleep(1); ++ } ++ while (ret == SOCKET_ERROR && c++ < NUM_QUERIES); ++ ++ /* Some applications do check error code even on success and choke if ++ there's still an error value set */ ++ if (c < NUM_QUERIES) ++ ok(!WSAGetLastError(), "WSAGetLastError() should return zero after " ++ "a successful call to WSARecv()\n"); ++ else ++ ok(0, "WSARecv() failed\n"); ++ ++ return 0; ++} ++ ++static void test_WSARecv_non_overlapped(void) ++{ ++ SOCKET src, dest, server = INVALID_SOCKET; ++ char buf[20]; ++ WSABUF bufs; ++ DWORD bytesReturned, flags, id; ++ struct linger ling; ++ struct sockaddr_in addr; ++ int iret, len; ++ DWORD dwret; ++ BOOL bret; ++ HANDLE thread; ++ ++ tcp_socketpair(&src, &dest); ++ if (src == INVALID_SOCKET || dest == INVALID_SOCKET) ++ { ++ skip("failed to create sockets\n"); ++ goto end; ++ } ++ ++ bufs.len = sizeof(buf); ++ bufs.buf = buf; ++ flags = 0; ++ ++ ling.l_onoff = 1; ++ ling.l_linger = 0; ++ iret = setsockopt (src, SOL_SOCKET, SO_LINGER, (char *) &ling, sizeof(ling)); ++ ok(!iret, "Failed to set linger %d\n", GetLastError()); ++ ++ if (set_blocking(dest, FALSE)) { ++ skip("couldn't make socket non-blocking, error %d\n", WSAGetLastError()); ++ goto end; ++ } ++ iret = WSARecv(dest, &bufs, 1, NULL, &flags, NULL, NULL); ++ ok(iret == SOCKET_ERROR && GetLastError() == WSAEWOULDBLOCK, "WSARecv failed - %d error %d\n", iret, GetLastError()); ++ ++ iret = WSARecv(dest, &bufs, 1, &bytesReturned, &flags, NULL, NULL); ++ ok(iret == SOCKET_ERROR && GetLastError() == WSAEWOULDBLOCK, "WSARecv failed - %d error %d\n", iret, GetLastError()); ++ ++ closesocket(src); ++ src = INVALID_SOCKET; ++ ++ ok(bytesReturned == 0, "non-overlapped Bytes received is %d\n", bytesReturned); ++ closesocket(dest); ++ dest = INVALID_SOCKET; ++ ++ src = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0); ++ ok(src != INVALID_SOCKET, "failed to create socket %d\n", WSAGetLastError()); ++ if (src == INVALID_SOCKET) goto end; ++ if (set_blocking(src, FALSE)) { ++ skip("couldn't make socket non-blocking, error %d\n", WSAGetLastError()); ++ goto end; ++ } ++ ++ server = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0); ++ ok(server != INVALID_SOCKET, "failed to create socket %d\n", WSAGetLastError()); ++ if (server == INVALID_SOCKET) goto end; ++ ++ memset(&addr, 0, sizeof(addr)); ++ addr.sin_family = AF_INET; ++ addr.sin_addr.s_addr = inet_addr("127.0.0.1"); ++ iret = bind(server, (struct sockaddr *)&addr, sizeof(addr)); ++ if (iret) goto end; ++ ++ len = sizeof(addr); ++ iret = getsockname(server, (struct sockaddr *)&addr, &len); ++ if (iret) goto end; ++ ++ iret = listen(server, 1); ++ if (iret) goto end; ++ ++ iret = connect(src, (struct sockaddr *)&addr, sizeof(addr)); ++ ok(iret == SOCKET_ERROR && GetLastError() == WSAEWOULDBLOCK, "failed to connect socket %d\n", WSAGetLastError()); ++ if (iret && GetLastError() != WSAEWOULDBLOCK) goto end; ++ ++ len = sizeof(addr); ++ dest = accept(server, (struct sockaddr *)&addr, &len); ++ ok(dest != INVALID_SOCKET, "failed to create socket %d\n", WSAGetLastError()); ++ if (dest == INVALID_SOCKET) goto end; ++ if (set_blocking(dest, FALSE)) { ++ skip("couldn't make socket non-blocking, error %d\n", WSAGetLastError()); ++ goto end; ++ } ++ ++ thread = CreateThread(NULL, 0, recv_thread_non_overlapped, &dest, 0, &id); ++ Sleep(10); /* enforce some WSAEWOULDBLOCK to happen */ ++ send(src, "test message", sizeof("test message"), 0); ++ WaitForSingleObject(thread, 3000); ++ CloseHandle(thread); ++ ++end: ++ if (server != INVALID_SOCKET) ++ closesocket(server); ++ if (dest != INVALID_SOCKET) ++ closesocket(dest); ++ if (src != INVALID_SOCKET) ++ closesocket(src); ++} ++ + static void test_GetAddrInfoW(void) + { + static const WCHAR port[] = {'8','0',0}; +@@ -8117,6 +8245,7 @@ START_TEST( sock ) + test_WSASendMsg(); + test_WSASendTo(); + test_WSARecv(); ++ test_WSARecv_non_overlapped(); + + test_events(0); + test_events(1); +-- +1.9.1 + diff --git a/patches/ws2_32-WSARecv_Last_Error/definition b/patches/ws2_32-WSARecv_Last_Error/definition new file mode 100644 index 00000000..3bd99c02 --- /dev/null +++ b/patches/ws2_32-WSARecv_Last_Error/definition @@ -0,0 +1 @@ +Fixes: [31438] WSARecv should call SetLastError on success