Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ws2_32/socket.c | 106 +++++++++++++++++-------------------------- 1 file changed, 41 insertions(+), 65 deletions(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index 44c0690d535..71537e6a2d8 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -2118,75 +2118,51 @@ INT WINAPI WS_getsockopt(SOCKET s, INT level, return ret; case WS_SO_BSP_STATE: { - int req_size, addr_size; + CSADDR_INFO *csinfo = (CSADDR_INFO *)optval; WSAPROTOCOL_INFOW infow; - CSADDR_INFO *csinfo; + int addr_size;
- ret = ws_protocol_info(s, TRUE, &infow, &addr_size); - if (ret) + if (!ws_protocol_info( s, TRUE, &infow, &addr_size )) + return -1; + + if (infow.iAddressFamily == WS_AF_INET) + addr_size = sizeof(struct sockaddr_in); + else if (infow.iAddressFamily == WS_AF_INET6) + addr_size = sizeof(struct sockaddr_in6); + else { - if (infow.iAddressFamily == WS_AF_INET) - addr_size = sizeof(struct sockaddr_in); - else if (infow.iAddressFamily == WS_AF_INET6) - addr_size = sizeof(struct sockaddr_in6); - else - { - FIXME("Family %d is unsupported for SO_BSP_STATE\n", infow.iAddressFamily); - SetLastError(WSAEAFNOSUPPORT); - return SOCKET_ERROR; - } - - req_size = sizeof(CSADDR_INFO) + addr_size * 2; - if (*optlen < req_size) - { - ret = 0; - SetLastError(WSAEFAULT); - } - else - { - union generic_unix_sockaddr uaddr; - socklen_t uaddrlen; - - if ( (fd = get_sock_fd( s, 0, NULL )) == -1) - return SOCKET_ERROR; - - csinfo = (CSADDR_INFO*) optval; - - /* Check if the sock is bound */ - if (is_fd_bound(fd, &uaddr, &uaddrlen) == 1) - { - csinfo->LocalAddr.lpSockaddr = - (LPSOCKADDR) (optval + sizeof(CSADDR_INFO)); - ws_sockaddr_u2ws(&uaddr.addr, csinfo->LocalAddr.lpSockaddr, &addr_size); - csinfo->LocalAddr.iSockaddrLength = addr_size; - } - else - { - csinfo->LocalAddr.lpSockaddr = NULL; - csinfo->LocalAddr.iSockaddrLength = 0; - } - - /* Check if the sock is connected */ - if (!getpeername(fd, &uaddr.addr, &uaddrlen) && - is_sockaddr_bound(&uaddr.addr, uaddrlen)) - { - csinfo->RemoteAddr.lpSockaddr = - (LPSOCKADDR) (optval + sizeof(CSADDR_INFO) + addr_size); - ws_sockaddr_u2ws(&uaddr.addr, csinfo->RemoteAddr.lpSockaddr, &addr_size); - csinfo->RemoteAddr.iSockaddrLength = addr_size; - } - else - { - csinfo->RemoteAddr.lpSockaddr = NULL; - csinfo->RemoteAddr.iSockaddrLength = 0; - } - - csinfo->iSocketType = infow.iSocketType; - csinfo->iProtocol = infow.iProtocol; - release_sock_fd( s, fd ); - } + FIXME( "family %d is unsupported for SO_BSP_STATE\n", infow.iAddressFamily ); + SetLastError( WSAEAFNOSUPPORT ); + return -1; } - return ret ? 0 : SOCKET_ERROR; + + if (*optlen < sizeof(CSADDR_INFO) + addr_size * 2) + { + ret = 0; + SetLastError( WSAEFAULT ); + return -1; + } + + csinfo->LocalAddr.lpSockaddr = (struct WS_sockaddr *)(csinfo + 1); + csinfo->RemoteAddr.lpSockaddr = (struct WS_sockaddr *)((char *)(csinfo + 1) + addr_size); + + csinfo->LocalAddr.iSockaddrLength = addr_size; + if (WS_getsockname( s, csinfo->LocalAddr.lpSockaddr, &csinfo->LocalAddr.iSockaddrLength ) < 0) + { + csinfo->LocalAddr.lpSockaddr = NULL; + csinfo->LocalAddr.iSockaddrLength = 0; + } + + csinfo->RemoteAddr.iSockaddrLength = addr_size; + if (WS_getpeername( s, csinfo->RemoteAddr.lpSockaddr, &csinfo->RemoteAddr.iSockaddrLength ) < 0) + { + csinfo->RemoteAddr.lpSockaddr = NULL; + csinfo->RemoteAddr.iSockaddrLength = 0; + } + + csinfo->iSocketType = infow.iSocketType; + csinfo->iProtocol = infow.iProtocol; + return 0; } case WS_SO_DONTLINGER: {
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ws2_32/tests/sock.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+)
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index 01c14382e84..e7b91aab5bd 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -2856,6 +2856,18 @@ static void test_listen(void) ok (!ret, "getsockopt failed\n"); ok (acceptc == 0, "SO_ACCEPTCONN should be 0, received %d\n", acceptc);
+ acceptc = 1; + WSASetLastError(0xdeadbeef); + ret = setsockopt(fdA, SOL_SOCKET, SO_ACCEPTCONN, (char *)&acceptc, sizeof(acceptc)); + ok(ret == -1, "expected failure\n"); + ok(WSAGetLastError() == WSAENOPROTOOPT, "got error %u\n", WSAGetLastError()); + + acceptc = 0; + WSASetLastError(0xdeadbeef); + ret = setsockopt(fdA, SOL_SOCKET, SO_ACCEPTCONN, (char *)&acceptc, sizeof(acceptc)); + ok(ret == -1, "expected failure\n"); + ok(WSAGetLastError() == WSAENOPROTOOPT, "got error %u\n", WSAGetLastError()); + ok (!listen(fdA, 0), "listen failed\n"); ok (!listen(fdA, SOMAXCONN), "double listen failed\n");
@@ -2864,6 +2876,18 @@ static void test_listen(void) ok (!ret, "getsockopt failed\n"); ok (acceptc == 1, "SO_ACCEPTCONN should be 1, received %d\n", acceptc);
+ acceptc = 1; + WSASetLastError(0xdeadbeef); + ret = setsockopt(fdA, SOL_SOCKET, SO_ACCEPTCONN, (char *)&acceptc, sizeof(acceptc)); + ok(ret == -1, "expected failure\n"); + ok(WSAGetLastError() == WSAENOPROTOOPT, "got error %u\n", WSAGetLastError()); + + acceptc = 0; + WSASetLastError(0xdeadbeef); + ret = setsockopt(fdA, SOL_SOCKET, SO_ACCEPTCONN, (char *)&acceptc, sizeof(acceptc)); + ok(ret == -1, "expected failure\n"); + ok(WSAGetLastError() == WSAENOPROTOOPT, "got error %u\n", WSAGetLastError()); + SetLastError(0xdeadbeef); ok ((listen(fdB, SOMAXCONN) == SOCKET_ERROR), "listen did not fail\n"); ret = WSAGetLastError();
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ws2_32/socket.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index 71537e6a2d8..a0f704eba20 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -3617,7 +3617,6 @@ int WINAPI WS_setsockopt(SOCKET s, int level, int optname, /* The options listed here don't need any special handling. Thanks to * the conversion happening above, options from there will fall through * to this, too.*/ - case WS_SO_ACCEPTCONN: case WS_SO_BROADCAST: case WS_SO_ERROR: case WS_SO_KEEPALIVE: @@ -3714,6 +3713,9 @@ int WINAPI WS_setsockopt(SOCKET s, int level, int optname,
default: TRACE("Unknown SOL_SOCKET optname: 0x%08x\n", optname); + /* fall through */ + + case WS_SO_ACCEPTCONN: SetLastError(WSAENOPROTOOPT); return SOCKET_ERROR; }
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ws2_32/tests/sock.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+)
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index e7b91aab5bd..c12ff45b921 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -2294,23 +2294,51 @@ static void test_WSASocket(void) sock = WSASocketA(0, 0, 0, &pi[0], 0, 0); ok(sock != INVALID_SOCKET, "Failed to create socket: %d\n", WSAGetLastError()); + size = sizeof(socktype); socktype = 0xdead; err = getsockopt(sock, SOL_SOCKET, SO_TYPE, (char *) &socktype, &size); ok(!err,"getsockopt failed with %d\n", WSAGetLastError()); ok(socktype == SOCK_DGRAM, "Wrong socket type, expected %d received %d\n", SOCK_DGRAM, socktype); + + socktype = SOCK_STREAM; + WSASetLastError(0xdeadbeef); + err = setsockopt(sock, SOL_SOCKET, SO_TYPE, (char *)&socktype, sizeof(socktype)); + ok(err == -1, "expected failure\n"); + todo_wine ok(WSAGetLastError() == WSAEINVAL, "got error %u\n", WSAGetLastError()); + + socktype = SOCK_DGRAM; + WSASetLastError(0xdeadbeef); + err = setsockopt(sock, SOL_SOCKET, SO_TYPE, (char *)&socktype, sizeof(socktype)); + ok(err == -1, "expected failure\n"); + todo_wine ok(WSAGetLastError() == WSAEINVAL, "got error %u\n", WSAGetLastError()); + closesocket(sock);
sock = WSASocketA(AF_INET, SOCK_STREAM, IPPROTO_TCP, &pi[0], 0, 0); ok(sock != INVALID_SOCKET, "Failed to create socket: %d\n", WSAGetLastError()); + size = sizeof(socktype); socktype = 0xdead; err = getsockopt(sock, SOL_SOCKET, SO_TYPE, (char *) &socktype, &size); ok(!err,"getsockopt failed with %d\n", WSAGetLastError()); ok(socktype == SOCK_STREAM, "Wrong socket type, expected %d received %d\n", SOCK_STREAM, socktype); + + socktype = SOCK_STREAM; + WSASetLastError(0xdeadbeef); + err = setsockopt(sock, SOL_SOCKET, SO_TYPE, (char *)&socktype, sizeof(socktype)); + ok(err == -1, "expected failure\n"); + ok(WSAGetLastError() == WSAENOPROTOOPT, "got error %u\n", WSAGetLastError()); + + socktype = SOCK_DGRAM; + WSASetLastError(0xdeadbeef); + err = setsockopt(sock, SOL_SOCKET, SO_TYPE, (char *)&socktype, sizeof(socktype)); + ok(err == -1, "expected failure\n"); + ok(WSAGetLastError() == WSAENOPROTOOPT, "got error %u\n", WSAGetLastError()); + closesocket(sock);
HeapFree(GetProcessHeap(), 0, pi);
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ws2_32/socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index a0f704eba20..cb576bad5f2 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -3625,7 +3625,6 @@ int WINAPI WS_setsockopt(SOCKET s, int level, int optname, * however, using it the BSD way fixes bug 8513 and seems to be what * most programmers assume, anyway */ case WS_SO_REUSEADDR: - case WS_SO_TYPE: convert_sockopt(&level, &optname); break;
@@ -3716,6 +3715,7 @@ int WINAPI WS_setsockopt(SOCKET s, int level, int optname, /* fall through */
case WS_SO_ACCEPTCONN: + case WS_SO_TYPE: SetLastError(WSAENOPROTOOPT); return SOCKET_ERROR; }
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=92941
Your paranoid android.
=== debiant2 (32 bit report) ===
ws2_32: sock.c:4784: Test failed: expected timeout
=== debiant2 (32 bit Chinese:China report) ===
ws2_32: sock.c:5737: Test succeeded inside todo block: expected failure sock.c:5738: Test succeeded inside todo block: got error 64
=== debiant2 (64 bit WoW report) ===
Report validation errors: sock: Timeout
=== debiant2 (build log) ===
WineRunWineTest.pl:error: The task timed out