Signed-off-by: Robin Ebert ebertrobin2002@gmail.com --- dlls/ws2_32/tests/sock.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index b523c326..1450038f 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -1750,6 +1750,21 @@ todo_wine closesocket(s); }
+ /* when no protocol is specified + * and the socket creation doesn't fail + * the socket should have a valid WSAPROTOCOL_INFOW struct */ + s = WSASocketW(AF_INET, SOCK_STREAM, 0, NULL, 0, 0); + ok(s != INVALID_SOCKET, "Failed to create socket: %d\n", + WSAGetLastError()); + + size = sizeof(WSAPROTOCOL_INFOW); + err = getsockopt(s, SOL_SOCKET, SO_PROTOCOL_INFOW, (char *)&infoW, &size); + + ok(!err, "getsockopt failed with %d\n", WSAGetLastError()); + if(!err) + ok(infoW.iProtocol != 0, "getsockopt returned zero protocol\n"); + closesocket(s); + /* Test SO_BSP_STATE - Present only in >= Win 2008 */ s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); ok(s != INVALID_SOCKET, "Failed to create socket\n");
The kernel selects a protocol if zero is given but the corresponding sock struct is not set accordingly. This causes problems in WS_getsockopt when trying to get socket's WSAPROTOCOL_INFOW struct.
Signed-off-by: Robin Ebert ebertrobin2002@gmail.com --- server/sock.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/server/sock.c b/server/sock.c index 1a53ce4b..c37624b0 100644 --- a/server/sock.c +++ b/server/sock.c @@ -38,6 +38,9 @@ #ifdef HAVE_SYS_SOCKET_H # include <sys/socket.h> #endif +#ifdef HAVE_NETINET_IN_H +# include <netinet/in.h> +#endif #ifdef HAVE_SYS_IOCTL_H #include <sys/ioctl.h> #endif @@ -659,6 +662,7 @@ static struct object *create_socket( int family, int type, int protocol, unsigne { struct sock *sock; int sockfd; + int proto, protolen;
sockfd = socket( family, type, protocol ); if (sockfd == -1) @@ -676,7 +680,19 @@ static struct object *create_socket( int family, int type, int protocol, unsigne init_sock( sock ); sock->state = (type != SOCK_STREAM) ? (FD_READ|FD_WRITE) : 0; sock->flags = flags; - sock->proto = protocol; + if(!protocol) + { + /* if protocol is 0 get it from the kernel */ + protolen = sizeof(int); + if(getsockopt(sockfd, SOL_SOCKET, SO_PROTOCOL, &proto, &protolen)) + { + release_object( sock ); + return NULL; + } + sock->proto = proto; + } + else + sock->proto = protocol; sock->type = type; sock->family = family;
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=77475
Your paranoid android.
=== debiant (32 bit report) ===
ws2_32: sock.c:1765: Test failed: getsockopt returned zero protocol
=== debiant (32 bit French report) ===
ws2_32: sock.c:1765: Test failed: getsockopt returned zero protocol
=== debiant (32 bit Japanese:Japan report) ===
ws2_32: sock.c:1765: Test failed: getsockopt returned zero protocol sock.c:3068: Test failed: Test[1]: expected 2, got 0 sock.c:3068: Test failed: Test[2]: expected 2, got 0 sock.c:3068: Test failed: Test[1]: expected 2, got 0 sock.c:3068: Test failed: Test[2]: expected 2, got 0
=== debiant (32 bit Chinese:China report) ===
ws2_32: sock.c:1765: Test failed: getsockopt returned zero protocol
=== debiant (32 bit WoW report) ===
ws2_32: sock.c:1765: Test failed: getsockopt returned zero protocol
=== debiant (64 bit WoW report) ===
ws2_32: sock.c:1765: Test failed: getsockopt returned zero protocol