diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index fd6ea25c751..30f233fa78f 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -1424,6 +1424,14 @@ int WINAPI getsockopt( SOCKET s, int level, int optname, char *optval, int *optl return 0; } + case SO_CONNECT_TIME: + if (!optlen || !optval) + { + SetLastError( WSAEFAULT ); + return -1; + } + return server_getsockopt( s, IOCTL_AFD_WINE_GET_SO_CONNECT_TIME, optval, optlen ); + case SO_DEBUG: WARN( "returning 0 for SO_DEBUG\n" ); *(DWORD *)optval = 0; @@ -1450,27 +1458,6 @@ int WINAPI getsockopt( SOCKET s, int level, int optname, char *optval, int *optl return ret; } - case SO_CONNECT_TIME: - { - static int pretendtime = 0; - struct sockaddr addr; - int len = sizeof(addr); - - if (!optlen || *optlen < sizeof(DWORD) || !optval) - { - SetLastError(WSAEFAULT); - return SOCKET_ERROR; - } - if (getpeername(s, &addr, &len) == SOCKET_ERROR) - *(DWORD *)optval = ~0u; - else - { - if (!pretendtime) FIXME("SO_CONNECT_TIME - faking results\n"); - *(DWORD *)optval = pretendtime++; - } - *optlen = sizeof(DWORD); - return ret; - } /* As mentioned in setsockopt, Windows ignores this, so we * always return true here */ case SO_DONTROUTE: diff --git a/include/wine/afd.h b/include/wine/afd.h index 49bbcccd3af..e67ecae25a9 100644 --- a/include/wine/afd.h +++ b/include/wine/afd.h @@ -233,6 +233,7 @@ struct afd_get_events_params #define IOCTL_AFD_WINE_SET_IPV6_RECVPKTINFO WINE_AFD_IOC(289) #define IOCTL_AFD_WINE_GET_IPV6_RECVTCLASS WINE_AFD_IOC(290) #define IOCTL_AFD_WINE_SET_IPV6_RECVTCLASS WINE_AFD_IOC(291) +#define IOCTL_AFD_WINE_GET_SO_CONNECT_TIME WINE_AFD_IOC(292) struct afd_create_params { diff --git a/server/sock.c b/server/sock.c index 27477200ed0..50bfc08e145 100644 --- a/server/sock.c +++ b/server/sock.c @@ -2807,6 +2807,23 @@ static int sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async ) return 0; } + case IOCTL_AFD_WINE_GET_SO_CONNECT_TIME: + { + DWORD time = ~0u; + + if (get_reply_max_size() < sizeof(time)) + { + set_error( STATUS_BUFFER_TOO_SMALL ); + return 0; + } + + if (sock->state == SOCK_CONNECTED) + time = (current_time - sock->connect_time) / 10000000; + + set_reply_data( &time, sizeof(time) ); + return 1; + } + default: set_error( STATUS_NOT_SUPPORTED ); return 0;