Signed-off-by: Zebediah Figura z.figura12@gmail.com --- include/wine/afd.h | 1 + server/sock.c | 14 ++++++++++++++ 2 files changed, 15 insertions(+)
diff --git a/include/wine/afd.h b/include/wine/afd.h index e497eece0be..4c501872dde 100644 --- a/include/wine/afd.h +++ b/include/wine/afd.h @@ -159,6 +159,7 @@ struct afd_get_events_params #define IOCTL_AFD_WINE_GETPEERNAME CTL_CODE(FILE_DEVICE_NETWORK, 216, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_AFD_WINE_DEFER CTL_CODE(FILE_DEVICE_NETWORK, 217, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_AFD_WINE_GET_INFO CTL_CODE(FILE_DEVICE_NETWORK, 218, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_AFD_WINE_GET_SO_ACCEPTCONN CTL_CODE(FILE_DEVICE_NETWORK, 219, METHOD_BUFFERED, FILE_ANY_ACCESS)
struct afd_create_params { diff --git a/server/sock.c b/server/sock.c index b73fbb98388..71f22845827 100644 --- a/server/sock.c +++ b/server/sock.c @@ -2532,6 +2532,20 @@ static int sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async ) return 0; }
+ case IOCTL_AFD_WINE_GET_SO_ACCEPTCONN: + { + int listening = (sock->state == SOCK_LISTENING); + + if (get_reply_max_size() < sizeof(listening)) + { + set_error( STATUS_BUFFER_TOO_SMALL ); + return 0; + } + + set_reply_data( &listening, sizeof(listening) ); + return 1; + } + default: set_error( STATUS_NOT_SUPPORTED ); return 0;
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ws2_32/socket.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index cb576bad5f2..3dac76fd3f0 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -2063,6 +2063,19 @@ int WINAPI WS_getsockname( SOCKET s, struct WS_sockaddr *addr, int *len ) return status ? -1 : 0; }
+ +static int server_getsockopt( SOCKET s, ULONG code, char *optval, int *optlen ) +{ + IO_STATUS_BLOCK io; + NTSTATUS status; + + status = NtDeviceIoControlFile( (HANDLE)s, NULL, NULL, NULL, &io, code, NULL, 0, optval, *optlen ); + if (!status) *optlen = io.Information; + SetLastError( NtStatusToWSAError( status ) ); + return status ? -1 : 0; +} + + /*********************************************************************** * getsockopt (WS2_32.7) */ @@ -2082,6 +2095,9 @@ INT WINAPI WS_getsockopt(SOCKET s, INT level, { switch(optname) { + case WS_SO_ACCEPTCONN: + return server_getsockopt( s, IOCTL_AFD_WINE_GET_SO_ACCEPTCONN, optval, optlen ); + /* Handle common cases. The special cases are below, sorted * alphabetically */ case WS_SO_BROADCAST: @@ -2101,21 +2117,7 @@ INT WINAPI WS_getsockopt(SOCKET s, INT level, } release_sock_fd( s, fd ); return ret; - case WS_SO_ACCEPTCONN: - if ( (fd = get_sock_fd( s, 0, NULL )) == -1) - return SOCKET_ERROR; - if (getsockopt(fd, SOL_SOCKET, SO_ACCEPTCONN, optval, (socklen_t *)optlen) != 0 ) - { - SetLastError(wsaErrno()); - ret = SOCKET_ERROR; - } - else - { - /* BSD returns != 0 while Windows return exact == 1 */ - if (*(int *)optval) *(int *)optval = 1; - } - release_sock_fd( s, fd ); - return ret; + case WS_SO_BSP_STATE: { CSADDR_INFO *csinfo = (CSADDR_INFO *)optval;
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ntdll/unix/socket.c | 22 ++++++++++++++++++++++ dlls/ws2_32/socket.c | 4 +++- include/wine/afd.h | 1 + 3 files changed, 26 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/unix/socket.c b/dlls/ntdll/unix/socket.c index 04db120dcbd..c3392f94b54 100644 --- a/dlls/ntdll/unix/socket.c +++ b/dlls/ntdll/unix/socket.c @@ -1146,6 +1146,25 @@ static void complete_async( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, vo }
+static NTSTATUS do_getsockopt( HANDLE handle, IO_STATUS_BLOCK *io, void *out_buffer, + ULONG out_size, int level, int option ) +{ + int fd, needs_close = FALSE; + socklen_t len = out_size; + NTSTATUS status; + int ret; + + if ((status = server_get_unix_fd( handle, 0, &fd, &needs_close, NULL, NULL ))) + return status; + + ret = getsockopt( fd, level, option, out_buffer, &len ); + if (needs_close) close( fd ); + if (ret) return sock_errno_to_status( errno ); + io->Information = len; + return STATUS_SUCCESS; +} + + NTSTATUS sock_ioctl( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, void *apc_user, IO_STATUS_BLOCK *io, ULONG code, void *in_buffer, ULONG in_size, void *out_buffer, ULONG out_size ) { @@ -1566,6 +1585,9 @@ NTSTATUS sock_ioctl( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, void *apc break; }
+ case IOCTL_AFD_WINE_GET_SO_BROADCAST: + return do_getsockopt( handle, io, out_buffer, out_size, SOL_SOCKET, SO_BROADCAST ); + default: { if ((code >> 16) == FILE_DEVICE_NETWORK) diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index 3dac76fd3f0..3b00e65fe3d 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -2098,9 +2098,11 @@ INT WINAPI WS_getsockopt(SOCKET s, INT level, case WS_SO_ACCEPTCONN: return server_getsockopt( s, IOCTL_AFD_WINE_GET_SO_ACCEPTCONN, optval, optlen );
+ case WS_SO_BROADCAST: + return server_getsockopt( s, IOCTL_AFD_WINE_GET_SO_BROADCAST, optval, optlen ); + /* Handle common cases. The special cases are below, sorted * alphabetically */ - case WS_SO_BROADCAST: case WS_SO_DEBUG: case WS_SO_KEEPALIVE: case WS_SO_OOBINLINE: diff --git a/include/wine/afd.h b/include/wine/afd.h index 4c501872dde..8916fafae53 100644 --- a/include/wine/afd.h +++ b/include/wine/afd.h @@ -160,6 +160,7 @@ struct afd_get_events_params #define IOCTL_AFD_WINE_DEFER CTL_CODE(FILE_DEVICE_NETWORK, 217, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_AFD_WINE_GET_INFO CTL_CODE(FILE_DEVICE_NETWORK, 218, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_AFD_WINE_GET_SO_ACCEPTCONN CTL_CODE(FILE_DEVICE_NETWORK, 219, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_AFD_WINE_GET_SO_BROADCAST CTL_CODE(FILE_DEVICE_NETWORK, 220, METHOD_BUFFERED, FILE_ANY_ACCESS)
struct afd_create_params {
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ntdll/unix/socket.c | 25 ++++++++++++++++++++++--- dlls/ws2_32/socket.c | 16 +++++++++++++++- include/wine/afd.h | 1 + 3 files changed, 38 insertions(+), 4 deletions(-)
diff --git a/dlls/ntdll/unix/socket.c b/dlls/ntdll/unix/socket.c index c3392f94b54..959f0e7bc00 100644 --- a/dlls/ntdll/unix/socket.c +++ b/dlls/ntdll/unix/socket.c @@ -1146,8 +1146,8 @@ static void complete_async( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, vo }
-static NTSTATUS do_getsockopt( HANDLE handle, IO_STATUS_BLOCK *io, void *out_buffer, - ULONG out_size, int level, int option ) +static NTSTATUS do_getsockopt( HANDLE handle, IO_STATUS_BLOCK *io, int level, + int option, void *out_buffer, ULONG out_size ) { int fd, needs_close = FALSE; socklen_t len = out_size; @@ -1165,6 +1165,22 @@ static NTSTATUS do_getsockopt( HANDLE handle, IO_STATUS_BLOCK *io, void *out_buf }
+static NTSTATUS do_setsockopt( HANDLE handle, IO_STATUS_BLOCK *io, int level, + int option, const void *optval, socklen_t optlen ) +{ + int fd, needs_close = FALSE; + NTSTATUS status; + int ret; + + if ((status = server_get_unix_fd( handle, 0, &fd, &needs_close, NULL, NULL ))) + return status; + + ret = setsockopt( fd, level, option, optval, optlen ); + if (needs_close) close( fd ); + return ret ? sock_errno_to_status( errno ) : STATUS_SUCCESS; +} + + NTSTATUS sock_ioctl( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, void *apc_user, IO_STATUS_BLOCK *io, ULONG code, void *in_buffer, ULONG in_size, void *out_buffer, ULONG out_size ) { @@ -1586,7 +1602,10 @@ NTSTATUS sock_ioctl( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, void *apc }
case IOCTL_AFD_WINE_GET_SO_BROADCAST: - return do_getsockopt( handle, io, out_buffer, out_size, SOL_SOCKET, SO_BROADCAST ); + return do_getsockopt( handle, io, SOL_SOCKET, SO_BROADCAST, out_buffer, out_size ); + + case IOCTL_AFD_WINE_SET_SO_BROADCAST: + return do_setsockopt( handle, io, SOL_SOCKET, SO_BROADCAST, in_buffer, in_size );
default: { diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index 3b00e65fe3d..320e4b3af2a 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -3538,6 +3538,18 @@ int WINAPI WS_sendto(SOCKET s, const char *buf, int len, int flags, return n; }
+ +static int server_setsockopt( SOCKET s, ULONG code, const char *optval, int optlen ) +{ + IO_STATUS_BLOCK io; + NTSTATUS status; + + status = NtDeviceIoControlFile( (HANDLE)s, NULL, NULL, NULL, &io, code, (void *)optval, optlen, NULL, 0 ); + SetLastError( NtStatusToWSAError( status ) ); + return status ? -1 : 0; +} + + /*********************************************************************** * setsockopt (WS2_32.21) */ @@ -3566,6 +3578,9 @@ int WINAPI WS_setsockopt(SOCKET s, int level, int optname, case WS_SOL_SOCKET: switch(optname) { + case WS_SO_BROADCAST: + return server_setsockopt( s, IOCTL_AFD_WINE_SET_SO_BROADCAST, optval, optlen ); + /* Some options need some conversion before they can be sent to * setsockopt. The conversions are done here, then they will fall through * to the general case. Special options that are not passed to @@ -3621,7 +3636,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_BROADCAST: case WS_SO_ERROR: case WS_SO_KEEPALIVE: case WS_SO_OOBINLINE: diff --git a/include/wine/afd.h b/include/wine/afd.h index 8916fafae53..6370e00539f 100644 --- a/include/wine/afd.h +++ b/include/wine/afd.h @@ -161,6 +161,7 @@ struct afd_get_events_params #define IOCTL_AFD_WINE_GET_INFO CTL_CODE(FILE_DEVICE_NETWORK, 218, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_AFD_WINE_GET_SO_ACCEPTCONN CTL_CODE(FILE_DEVICE_NETWORK, 219, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_AFD_WINE_GET_SO_BROADCAST CTL_CODE(FILE_DEVICE_NETWORK, 220, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_AFD_WINE_SET_SO_BROADCAST CTL_CODE(FILE_DEVICE_NETWORK, 221, 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=92991
Your paranoid android.
=== debiant2 (32 bit WoW report) ===
ws2_32: sock.c:4836: Test failed: expected timeout
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ws2_32/tests/sock.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+)
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index c12ff45b921..c4a3f953175 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -10978,6 +10978,41 @@ static void test_timeout(void) CloseHandle(overlapped.hEvent); }
+static void test_so_debug(void) +{ + int ret, len; + DWORD debug; + SOCKET s; + + s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + + len = sizeof(debug); + WSASetLastError(0xdeadbeef); + debug = 0xdeadbeef; + ret = getsockopt(s, SOL_SOCKET, SO_DEBUG, (char *)&debug, &len); + ok(!ret, "got %d\n", ret); + todo_wine ok(!WSAGetLastError(), "got error %u\n", WSAGetLastError()); + ok(len == sizeof(debug), "got len %u\n", len); + ok(!debug, "got debug %u\n", debug); + + WSASetLastError(0xdeadbeef); + debug = 2; + ret = setsockopt(s, SOL_SOCKET, SO_DEBUG, (char *)&debug, sizeof(debug)); + ok(!ret, "got %d\n", ret); + todo_wine ok(!WSAGetLastError(), "got error %u\n", WSAGetLastError()); + + len = sizeof(debug); + WSASetLastError(0xdeadbeef); + debug = 0xdeadbeef; + ret = getsockopt(s, SOL_SOCKET, SO_DEBUG, (char *)&debug, &len); + ok(!ret, "got %d\n", ret); + todo_wine ok(!WSAGetLastError(), "got error %u\n", WSAGetLastError()); + ok(len == sizeof(debug), "got len %u\n", len); + todo_wine ok(debug == 1, "got debug %u\n", debug); + + closesocket(s); +} + START_TEST( sock ) { int i; @@ -10993,6 +11028,7 @@ START_TEST( sock ) test_so_reuseaddr(); test_ip_pktinfo(); test_extendedSocketOptions(); + test_so_debug();
for (i = 0; i < ARRAY_SIZE(tests); i++) do_test(&tests[i]);
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=92992
Your paranoid android.
=== debiant2 (32 bit Hebrew:Israel report) ===
ws2_32: sock.c:4836: Test failed: expected timeout
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ws2_32/socket.c | 8 +++++++- dlls/ws2_32/tests/sock.c | 4 ++-- 2 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index 320e4b3af2a..ab111f726a9 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -2103,7 +2103,6 @@ INT WINAPI WS_getsockopt(SOCKET s, INT level,
/* Handle common cases. The special cases are below, sorted * alphabetically */ - case WS_SO_DEBUG: case WS_SO_KEEPALIVE: case WS_SO_OOBINLINE: case WS_SO_RCVBUF: @@ -2168,6 +2167,13 @@ INT WINAPI WS_getsockopt(SOCKET s, INT level, csinfo->iProtocol = infow.iProtocol; return 0; } + + case WS_SO_DEBUG: + WARN( "returning 0 for SO_DEBUG\n" ); + *(DWORD *)optval = 0; + SetLastError( 0 ); + return 0; + case WS_SO_DONTLINGER: { struct linger lingval; diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index c4a3f953175..7534e75edb3 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -10991,7 +10991,7 @@ static void test_so_debug(void) debug = 0xdeadbeef; ret = getsockopt(s, SOL_SOCKET, SO_DEBUG, (char *)&debug, &len); ok(!ret, "got %d\n", ret); - todo_wine ok(!WSAGetLastError(), "got error %u\n", WSAGetLastError()); + ok(!WSAGetLastError(), "got error %u\n", WSAGetLastError()); ok(len == sizeof(debug), "got len %u\n", len); ok(!debug, "got debug %u\n", debug);
@@ -11006,7 +11006,7 @@ static void test_so_debug(void) debug = 0xdeadbeef; ret = getsockopt(s, SOL_SOCKET, SO_DEBUG, (char *)&debug, &len); ok(!ret, "got %d\n", ret); - todo_wine ok(!WSAGetLastError(), "got error %u\n", WSAGetLastError()); + ok(!WSAGetLastError(), "got error %u\n", WSAGetLastError()); ok(len == sizeof(debug), "got len %u\n", len); todo_wine ok(debug == 1, "got debug %u\n", debug);
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=92993
Your paranoid android.
=== debiant2 (32 bit German report) ===
ws2_32: sock.c:4836: Test failed: expected timeout