Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ws2_32/socket.c | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index ce71e25d63d..9f32e7eaf96 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -2259,27 +2259,22 @@ INT WINAPI WS_getsockopt(SOCKET s, INT level,
case WS_SO_TYPE: { - int sock_type; + WSAPROTOCOL_INFOW info; + int size; + if (!optlen || *optlen < sizeof(int) || !optval) { SetLastError(WSAEFAULT); return SOCKET_ERROR; } - if ( (fd = get_sock_fd( s, 0, NULL )) == -1) - return SOCKET_ERROR;
- sock_type = _get_fd_type(fd); - if (sock_type == -1) - { - SetLastError(wsaErrno()); - ret = SOCKET_ERROR; - } - else - (*(int *)optval) = convert_socktype_u2w(sock_type); + if (!ws_protocol_info( s, TRUE, &info, &size )) + return -1;
- release_sock_fd( s, fd ); - return ret; + *(int *)optval = info.iSocketType; + return 0; } + default: TRACE("Unknown SOL_SOCKET optname: 0x%08x\n", optname); SetLastError(WSAENOPROTOOPT);
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ws2_32/socket.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index 9f32e7eaf96..84f7f06036f 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -694,14 +694,6 @@ static inline void release_sock_fd( SOCKET s, int fd ) close( fd ); }
-static int _get_fd_type(int fd) -{ - int sock_type = -1; - socklen_t optlen = sizeof(sock_type); - getsockopt(fd, SOL_SOCKET, SO_TYPE, (char*) &sock_type, &optlen); - return sock_type; -} - static BOOL set_dont_fragment(SOCKET s, int level, BOOL value) { int fd, optname; @@ -2176,22 +2168,24 @@ INT WINAPI WS_getsockopt(SOCKET s, INT level,
case WS_SO_LINGER: { + WSAPROTOCOL_INFOW info; + int size; + /* struct linger and LINGER have different sizes */ if (!optlen || *optlen < sizeof(LINGER) || !optval) { SetLastError(WSAEFAULT); return SOCKET_ERROR; } - if ( (fd = get_sock_fd( s, 0, NULL )) == -1) - return SOCKET_ERROR;
- if (_get_fd_type(fd) == SOCK_DGRAM) + if (!ws_protocol_info( s, TRUE, &info, &size )) + return -1; + + if (info.iSocketType == SOCK_DGRAM) { - release_sock_fd( s, fd ); SetLastError( WSAENOPROTOOPT ); return -1; } - release_sock_fd( s, fd );
return server_getsockopt( s, IOCTL_AFD_WINE_GET_SO_LINGER, optval, optlen ); }
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ws2_32/tests/sock.c | 42 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+)
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index e579b72ecb5..8617a6fb7e3 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -11011,6 +11011,47 @@ static void test_so_debug(void) closesocket(s); }
+static void test_set_only_options(void) +{ + unsigned int i; + int ret, len; + int value; + SOCKET s; + + static const struct + { + int level; + int option; + } + tests[] = + { + {IPPROTO_IP, IP_ADD_MEMBERSHIP}, + {IPPROTO_IP, IP_DROP_MEMBERSHIP}, + {IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP}, + {IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP}, + }; + + for (i = 0; i < ARRAY_SIZE(tests); ++i) + { + if (tests[i].level == IPPROTO_IPV6) + { + s = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); + if (s == INVALID_SOCKET) continue; + } + else + { + s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + } + + len = sizeof(value); + ret = getsockopt(s, tests[i].level, tests[i].option, (char *)&value, &len); + ok(ret == -1, "expected failure\n"); + ok(WSAGetLastError() == WSAENOPROTOOPT, "got error %u\n", WSAGetLastError()); + + closesocket(s); + } +} + START_TEST( sock ) { int i; @@ -11027,6 +11068,7 @@ START_TEST( sock ) test_ip_pktinfo(); test_extendedSocketOptions(); test_so_debug(); + test_set_only_options();
for (i = 0; i < ARRAY_SIZE(tests); i++) do_test(&tests[i]);
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ws2_32/socket.c | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index 84f7f06036f..650885a101e 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -2433,8 +2433,6 @@ INT WINAPI WS_getsockopt(SOCKET s, INT level, case WS_IPPROTO_IP: switch(optname) { - case WS_IP_ADD_MEMBERSHIP: - case WS_IP_DROP_MEMBERSHIP: #ifdef IP_HDRINCL case WS_IP_HDRINCL: #endif @@ -2462,19 +2460,20 @@ INT WINAPI WS_getsockopt(SOCKET s, INT level, return ret; case WS_IP_DONTFRAGMENT: return get_dont_fragment(s, IPPROTO_IP, (BOOL *)optval) ? 0 : SOCKET_ERROR; + + default: + FIXME( "unrecognized IP option %u\n", optname ); + /* fall through */ + + case WS_IP_ADD_MEMBERSHIP: + case WS_IP_DROP_MEMBERSHIP: + SetLastError( WSAENOPROTOOPT ); + return -1; } - FIXME("Unknown IPPROTO_IP optname 0x%08x\n", optname); - return SOCKET_ERROR;
case WS_IPPROTO_IPV6: switch(optname) { -#ifdef IPV6_ADD_MEMBERSHIP - case WS_IPV6_ADD_MEMBERSHIP: -#endif -#ifdef IPV6_DROP_MEMBERSHIP - case WS_IPV6_DROP_MEMBERSHIP: -#endif case WS_IPV6_MULTICAST_IF: case WS_IPV6_MULTICAST_HOPS: case WS_IPV6_MULTICAST_LOOP: @@ -2495,9 +2494,16 @@ INT WINAPI WS_getsockopt(SOCKET s, INT level, return ret; case WS_IPV6_DONTFRAG: return get_dont_fragment(s, IPPROTO_IPV6, (BOOL *)optval) ? 0 : SOCKET_ERROR; + + default: + FIXME( "unrecognized IPv6 option %u\n", optname ); + /* fall through */ + + case WS_IPV6_ADD_MEMBERSHIP: + case WS_IPV6_DROP_MEMBERSHIP: + SetLastError( WSAENOPROTOOPT ); + return -1; } - FIXME("Unknown IPPROTO_IPV6 optname 0x%08x\n", optname); - return SOCKET_ERROR;
default: WARN("Unknown level: 0x%08x\n", level);
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ntdll/unix/socket.c | 3 +++ dlls/ws2_32/socket.c | 4 +++- include/wine/afd.h | 1 + 3 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/unix/socket.c b/dlls/ntdll/unix/socket.c index 38cb80997ff..f65feef763f 100644 --- a/dlls/ntdll/unix/socket.c +++ b/dlls/ntdll/unix/socket.c @@ -1675,6 +1675,9 @@ NTSTATUS sock_ioctl( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, void *apc return ret ? sock_errno_to_status( errno ) : STATUS_SUCCESS; }
+ case IOCTL_AFD_WINE_SET_IP_ADD_MEMBERSHIP: + return do_setsockopt( handle, io, IPPROTO_IP, IP_ADD_MEMBERSHIP, in_buffer, in_size ); + default: { if ((code >> 16) == FILE_DEVICE_NETWORK) diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index 650885a101e..87966545bb8 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -3624,6 +3624,9 @@ int WINAPI WS_setsockopt(SOCKET s, int level, int optname, case WS_IPPROTO_IP: switch(optname) { + case WS_IP_ADD_MEMBERSHIP: + return server_setsockopt( s, IOCTL_AFD_WINE_SET_IP_ADD_MEMBERSHIP, optval, optlen ); + case WS_IP_ADD_SOURCE_MEMBERSHIP: case WS_IP_DROP_SOURCE_MEMBERSHIP: case WS_IP_BLOCK_SOURCE: @@ -3640,7 +3643,6 @@ int WINAPI WS_setsockopt(SOCKET s, int level, int optname, convert_sockopt(&level, &optname); break; } - case WS_IP_ADD_MEMBERSHIP: case WS_IP_DROP_MEMBERSHIP: #ifdef IP_HDRINCL case WS_IP_HDRINCL: diff --git a/include/wine/afd.h b/include/wine/afd.h index 44a8b1a5ff9..c672168bc6a 100644 --- a/include/wine/afd.h +++ b/include/wine/afd.h @@ -179,6 +179,7 @@ struct afd_get_events_params #define IOCTL_AFD_WINE_GET_SO_SNDBUF CTL_CODE(FILE_DEVICE_NETWORK, 236, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_AFD_WINE_GET_SO_SNDTIMEO CTL_CODE(FILE_DEVICE_NETWORK, 237, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_AFD_WINE_SET_SO_SNDTIMEO CTL_CODE(FILE_DEVICE_NETWORK, 238, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_AFD_WINE_SET_IP_ADD_MEMBERSHIP CTL_CODE(FILE_DEVICE_NETWORK, 239, METHOD_BUFFERED, FILE_ANY_ACCESS)
struct afd_create_params {
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=93397
Your paranoid android.
=== debiant2 (32 bit report) ===
ws2_32: afd.c:336: Test failed: got flags 0x43 afd.c:342: Test failed: got flags 0x41
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=93398
Your paranoid android.
=== debiant2 (32 bit report) ===
ws2_32: afd.c:336: Test failed: got flags 0x43 afd.c:342: Test failed: got flags 0x41
=== debiant2 (64 bit WoW report) ===
ws2_32: sock.c:5787: Test succeeded inside todo block: expected failure sock.c:5788: Test succeeded inside todo block: got error 64