Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ws2_32/socket.c | 5 +++-- server/sock.c | 12 ++++++++---- 2 files changed, 11 insertions(+), 6 deletions(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index 1136ec87b95..f43c57bf9ab 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -7716,7 +7716,8 @@ SOCKET WINAPI WSASocketW(int af, int type, int protocol,
RtlInitUnicodeString(&string, afdW); InitializeObjectAttributes(&attr, &string, (flags & WSA_FLAG_NO_HANDLE_INHERIT) ? 0 : OBJ_INHERIT, NULL, NULL); - if ((status = NtOpenFile(&handle, GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, &attr, &io, 0, 0))) + if ((status = NtOpenFile(&handle, GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, &attr, + &io, 0, (flags & WSA_FLAG_OVERLAPPED) ? 0 : FILE_SYNCHRONOUS_IO_NONALERT))) { WARN("Failed to create socket, status %#x.\n", status); WSASetLastError(NtStatusToWSAError(status)); @@ -7726,7 +7727,7 @@ SOCKET WINAPI WSASocketW(int af, int type, int protocol, create_params.family = unixaf; create_params.type = unixtype; create_params.protocol = protocol; - create_params.flags = flags & ~WSA_FLAG_NO_HANDLE_INHERIT; + create_params.flags = flags & ~(WSA_FLAG_NO_HANDLE_INHERIT | WSA_FLAG_OVERLAPPED); if ((status = NtDeviceIoControlFile(handle, NULL, NULL, NULL, &io, IOCTL_AFD_CREATE, &create_params, sizeof(create_params), NULL, 0))) { diff --git a/server/sock.c b/server/sock.c index 3f19c77964a..43a17d46ee0 100644 --- a/server/sock.c +++ b/server/sock.c @@ -315,7 +315,7 @@ static inline int sock_error( struct fd *fd )
static int sock_dispatch_asyncs( struct sock *sock, int event, int error ) { - if ( sock->flags & WSA_FLAG_OVERLAPPED ) + if (is_fd_overlapped( sock->fd )) { if (event & (POLLIN|POLLPRI) && async_waiting( &sock->read_q )) { @@ -680,6 +680,7 @@ static struct sock *create_socket(void)
static int init_socket( struct sock *sock, int family, int type, int protocol, unsigned int flags ) { + unsigned int options = 0; int sockfd;
sockfd = socket( family, type, protocol ); @@ -696,10 +697,13 @@ static int init_socket( struct sock *sock, int family, int type, int protocol, u sock->type = type; sock->family = family;
- if (sock->fd) release_object( sock->fd ); + if (sock->fd) + { + options = get_fd_options( sock->fd ); + release_object( sock->fd ); + }
- if (!(sock->fd = create_anonymous_fd( &sock_fd_ops, sockfd, &sock->obj, - (flags & WSA_FLAG_OVERLAPPED) ? 0 : FILE_SYNCHRONOUS_IO_NONALERT ))) + if (!(sock->fd = create_anonymous_fd( &sock_fd_ops, sockfd, &sock->obj, options ))) { return -1; }
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ws2_32/socket.c | 4 ++++ include/wine/afd.h | 2 ++ server/sock.c | 3 ++- 3 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index f43c57bf9ab..1ac1f77d6e6 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -5164,6 +5164,10 @@ INT WINAPI WSAIoctl(SOCKET s, DWORD code, LPVOID in_buff, DWORD in_size, LPVOID case 0x667e: /* Netscape tries hard to use bogus ioctl 0x667e */ SetLastError(WSAEOPNOTSUPP); return SOCKET_ERROR; + case WS_SIO_ADDRESS_LIST_CHANGE: + code = IOCTL_AFD_ADDRESS_LIST_CHANGE; + status = WSAEOPNOTSUPP; + break; default: status = WSAEOPNOTSUPP; break; diff --git a/include/wine/afd.h b/include/wine/afd.h index 41caaa7b4f3..24e6c31f228 100644 --- a/include/wine/afd.h +++ b/include/wine/afd.h @@ -25,6 +25,8 @@
#define IOCTL_AFD_CREATE CTL_CODE(FILE_DEVICE_NETWORK, 200, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+#define IOCTL_AFD_ADDRESS_LIST_CHANGE CTL_CODE(FILE_DEVICE_NETWORK, 323, METHOD_BUFFERED, 0) + struct afd_create_params { int family, type, protocol; diff --git a/server/sock.c b/server/sock.c index 43a17d46ee0..a0191d15e5d 100644 --- a/server/sock.c +++ b/server/sock.c @@ -562,7 +562,7 @@ static int sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async ) return 0; }
- case WS_SIO_ADDRESS_LIST_CHANGE: + case IOCTL_AFD_ADDRESS_LIST_CHANGE: if ((sock->state & FD_WINE_NONBLOCKING) && async_is_blocking( async )) { set_win32_error( WSAEWOULDBLOCK ); @@ -572,6 +572,7 @@ static int sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async ) queue_async( &sock->ifchange_q, async ); set_error( STATUS_PENDING ); return 1; + default: set_error( STATUS_NOT_SUPPORTED ); return 0;
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- server/sock.c | 81 +++++++++++++++++++++++++-------------------------- 1 file changed, 40 insertions(+), 41 deletions(-)
diff --git a/server/sock.c b/server/sock.c index a0191d15e5d..3bc4780f943 100644 --- a/server/sock.c +++ b/server/sock.c @@ -134,7 +134,6 @@ static int sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async ); static void sock_queue_async( struct fd *fd, struct async *async, int type, int count ); static void sock_reselect_async( struct fd *fd, struct async_queue *queue );
-static int init_socket( struct sock *sock, int family, int type, int protocol, unsigned int flags ); static int sock_get_ntstatus( int err ); static unsigned int sock_get_error( int err );
@@ -539,46 +538,6 @@ static enum server_fd_type sock_get_fd_type( struct fd *fd ) return FD_TYPE_SOCKET; }
-static int sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async ) -{ - struct sock *sock = get_fd_user( fd ); - - assert( sock->obj.ops == &sock_ops ); - - if (get_unix_fd( fd ) == -1 && code != IOCTL_AFD_CREATE) return 0; - - switch(code) - { - case IOCTL_AFD_CREATE: - { - const struct afd_create_params *params = get_req_data(); - - if (get_req_data_size() != sizeof(*params)) - { - set_error( STATUS_INVALID_PARAMETER ); - return 0; - } - init_socket( sock, params->family, params->type, params->protocol, params->flags ); - return 0; - } - - case IOCTL_AFD_ADDRESS_LIST_CHANGE: - if ((sock->state & FD_WINE_NONBLOCKING) && async_is_blocking( async )) - { - set_win32_error( WSAEWOULDBLOCK ); - return 0; - } - if (!sock_get_ifchange( sock )) return 0; - queue_async( &sock->ifchange_q, async ); - set_error( STATUS_PENDING ); - return 1; - - default: - set_error( STATUS_NOT_SUPPORTED ); - return 0; - } -} - static void sock_queue_async( struct fd *fd, struct async *async, int type, int count ) { struct sock *sock = get_fd_user( fd ); @@ -958,6 +917,46 @@ static int sock_get_ntstatus( int err ) } }
+static int sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async ) +{ + struct sock *sock = get_fd_user( fd ); + + assert( sock->obj.ops == &sock_ops ); + + if (get_unix_fd( fd ) == -1 && code != IOCTL_AFD_CREATE) return 0; + + switch(code) + { + case IOCTL_AFD_CREATE: + { + const struct afd_create_params *params = get_req_data(); + + if (get_req_data_size() != sizeof(*params)) + { + set_error( STATUS_INVALID_PARAMETER ); + return 0; + } + init_socket( sock, params->family, params->type, params->protocol, params->flags ); + return 0; + } + + case IOCTL_AFD_ADDRESS_LIST_CHANGE: + if ((sock->state & FD_WINE_NONBLOCKING) && async_is_blocking( async )) + { + set_win32_error( WSAEWOULDBLOCK ); + return 0; + } + if (!sock_get_ifchange( sock )) return 0; + queue_async( &sock->ifchange_q, async ); + set_error( STATUS_PENDING ); + return 1; + + default: + set_error( STATUS_NOT_SUPPORTED ); + return 0; + } +} + #ifdef HAVE_LINUX_RTNETLINK_H
/* only keep one ifchange object around, all sockets waiting for wakeups will look to it */
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=79331
Your paranoid android.
=== debiant (32 bit report) ===
ws2_32: sock.c:3058: Test succeeded inside todo block: Test[2]: expected 0, got 0
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ws2_32/tests/sock.c | 165 ++++++++++++++++----------------------- 1 file changed, 68 insertions(+), 97 deletions(-)
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index 7835246397d..cbbc1db1ee0 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -2471,107 +2471,78 @@ static void test_WSASocket(void) int items, err, size, socktype, i, j; UINT pi_size;
- SetLastError(0xdeadbeef); - ok(WSASocketA(0, 0, 0, NULL, 0, 0) == INVALID_SOCKET, - "WSASocketA should have failed\n"); - err = WSAGetLastError(); - ok(err == WSAEINVAL, "Expected 10022, received %d\n", err); - - sock = WSASocketA(AF_INET, 0, 0, NULL, 0, 0); - ok(sock != INVALID_SOCKET, "WSASocketA should have succeeded\n"); - closesocket(sock); - - sock = WSASocketA(AF_INET, SOCK_STREAM, 0, NULL, 0, 0); - ok(sock != INVALID_SOCKET, "WSASocketA should have succeeded\n"); - closesocket(sock); - - SetLastError(0xdeadbeef); - ok(WSASocketA(0, SOCK_STREAM, -1, NULL, 0, 0) == INVALID_SOCKET, - "WSASocketA should have failed\n"); - err = WSAGetLastError(); - ok(err == WSAEPROTONOSUPPORT, "Expected 10043, received %d\n", err); - - SetLastError(0xdeadbeef); - ok(WSASocketA(0, -1, IPPROTO_UDP, NULL, 0, 0) == INVALID_SOCKET, - "WSASocketA should have failed\n"); - err = WSAGetLastError(); - ok(err == WSAESOCKTNOSUPPORT, "Expected 10044, received %d\n", err); - - SetLastError(0xdeadbeef); - ok(WSASocketA(0, -1, 0, NULL, 0, 0) == INVALID_SOCKET, - "WSASocketA should have failed\n"); - err = WSAGetLastError(); - ok(err == WSAEINVAL, "Expected 10022, received %d\n", err); - - SetLastError(0xdeadbeef); - ok(WSASocketA(AF_INET, -1, 0, NULL, 0, 0) == INVALID_SOCKET, - "WSASocketA should have failed\n"); - err = WSAGetLastError(); - ok(err == WSAESOCKTNOSUPPORT, "Expected 10044, received %d\n", err); - - SetLastError(0xdeadbeef); - ok(WSASocketA(AF_INET, 0, -1, NULL, 0, 0) == INVALID_SOCKET, - "WSASocketA should have failed\n"); - err = WSAGetLastError(); - ok(err == WSAEPROTONOSUPPORT, "Expected 10043, received %d\n", err); - - SetLastError(0xdeadbeef); - ok(WSASocketA(0, -1, -1, NULL, 0, 0) == INVALID_SOCKET, - "WSASocketA should have failed\n"); - err = WSAGetLastError(); - ok(err == WSAESOCKTNOSUPPORT, "Expected 10044, received %d\n", err); - - SetLastError(0xdeadbeef); - ok(WSASocketA(-1, SOCK_STREAM, IPPROTO_UDP, NULL, 0, 0) == INVALID_SOCKET, - "WSASocketA should have failed\n"); - err = WSAGetLastError(); - ok(err == WSAEAFNOSUPPORT, "Expected 10047, received %d\n", err); - - sock = WSASocketA(AF_INET, 0, IPPROTO_TCP, NULL, 0, 0); - ok(sock != INVALID_SOCKET, "WSASocketA should have succeeded\n"); - closesocket(sock); - - SetLastError(0xdeadbeef); - ok(WSASocketA(0, SOCK_STREAM, 0, NULL, 0, 0) == INVALID_SOCKET, - "WSASocketA should have failed\n"); - err = WSAGetLastError(); - ok(err == WSAEINVAL, "Expected 10022, received %d\n", err); - - SetLastError(0xdeadbeef); - ok(WSASocketA(0, 0, 0xdead, NULL, 0, 0) == INVALID_SOCKET, - "WSASocketA should have failed\n"); - err = WSAGetLastError(); - ok(err == WSAEPROTONOSUPPORT, "Expected 10043, received %d\n", err); - - SetLastError(0xdeadbeef); - ok(WSASocketA(AF_INET, 0xdead, 0, NULL, 0, 0) == INVALID_SOCKET, - "WSASocketA should have failed\n"); - err = WSAGetLastError(); - ok(err == WSAESOCKTNOSUPPORT, "Expected 10044, received %d\n", err); + static const struct + { + int family, type, protocol; + DWORD error; + int ret_family, ret_type, ret_protocol; + } + tests[] = + { + /* 0 */ + {0xdead, SOCK_STREAM, IPPROTO_TCP, WSAEAFNOSUPPORT}, + {-1, SOCK_STREAM, IPPROTO_TCP, WSAEAFNOSUPPORT}, + {AF_INET, 0xdead, IPPROTO_TCP, WSAESOCKTNOSUPPORT}, + {AF_INET, -1, IPPROTO_TCP, WSAESOCKTNOSUPPORT}, + {AF_INET, SOCK_STREAM, 0xdead, WSAEPROTONOSUPPORT}, + {AF_INET, SOCK_STREAM, -1, WSAEPROTONOSUPPORT}, + {0xdead, 0xdead, IPPROTO_TCP, WSAESOCKTNOSUPPORT}, + {0xdead, SOCK_STREAM, 0xdead, WSAEAFNOSUPPORT}, + {AF_INET, 0xdead, 0xdead, WSAESOCKTNOSUPPORT}, + {0xdead, SOCK_STREAM, IPPROTO_UDP, WSAEAFNOSUPPORT}, + + /* 10 */ + {AF_INET, SOCK_STREAM, 0, 0, AF_INET, SOCK_STREAM, IPPROTO_TCP}, + {AF_INET, SOCK_DGRAM, 0, 0, AF_INET, SOCK_DGRAM, IPPROTO_UDP}, + {AF_INET, 0xdead, 0, WSAESOCKTNOSUPPORT}, + {AF_INET, 0, IPPROTO_TCP, 0, AF_INET, SOCK_STREAM, IPPROTO_TCP}, + {AF_INET, 0, IPPROTO_UDP, 0, AF_INET, SOCK_DGRAM, IPPROTO_UDP}, + {AF_INET, 0, 0xdead, WSAEPROTONOSUPPORT}, + {AF_INET, 0, 0, 0, AF_INET, SOCK_STREAM, IPPROTO_TCP}, + {AF_INET, SOCK_STREAM, IPPROTO_UDP, WSAEPROTONOSUPPORT}, + {AF_INET, SOCK_DGRAM, IPPROTO_TCP, WSAEPROTONOSUPPORT}, + + /* 19 */ + {AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP, 0, AF_INET, SOCK_STREAM, IPPROTO_TCP}, + {AF_UNSPEC, SOCK_STREAM, 0xdead, WSAEPROTONOSUPPORT}, + {AF_UNSPEC, 0xdead, IPPROTO_UDP, WSAESOCKTNOSUPPORT}, + {AF_UNSPEC, SOCK_STREAM, 0, WSAEINVAL}, + {AF_UNSPEC, SOCK_DGRAM, 0, WSAEINVAL}, + {AF_UNSPEC, 0xdead, 0, WSAEINVAL}, + {AF_UNSPEC, 0, IPPROTO_TCP, 0, AF_INET, SOCK_STREAM, IPPROTO_TCP}, + {AF_UNSPEC, 0, IPPROTO_UDP, 0, AF_INET, SOCK_DGRAM, IPPROTO_UDP}, + {AF_UNSPEC, 0, 0xdead, WSAEPROTONOSUPPORT}, + {AF_UNSPEC, 0, 0, WSAEINVAL}, + };
- SetLastError(0xdeadbeef); - ok(WSASocketA(0, 0xdead, 0, NULL, 0, 0) == INVALID_SOCKET, - "WSASocketA should have failed\n"); - err = WSAGetLastError(); - ok(err == WSAEINVAL, "Expected 10022, received %d\n", err); + for (i = 0; i < ARRAY_SIZE(tests); ++i) + { + SetLastError( 0xdeadbeef ); + sock = WSASocketA( tests[i].family, tests[i].type, tests[i].protocol, NULL, 0, 0 ); + todo_wine_if (!tests[i].error || i == 7) + ok(WSAGetLastError() == tests[i].error, "Test %u: got wrong error %u\n", i, WSAGetLastError()); + if (tests[i].error) + { + ok(sock == INVALID_SOCKET, "Test %u: expected failure\n", i); + } + else + { + WSAPROTOCOL_INFOA info;
- sock = WSASocketA(0, 0, IPPROTO_TCP, NULL, 0, 0); - ok(sock != INVALID_SOCKET, "WSASocketA should have succeeded\n"); - closesocket(sock); + todo_wine_if (i == 19) ok(sock != INVALID_SOCKET, "Text %u: expected success\n", i); + if (sock == INVALID_SOCKET) continue;
- /* SOCK_STREAM does not support IPPROTO_UDP */ - SetLastError(0xdeadbeef); - ok(WSASocketA(AF_INET, SOCK_STREAM, IPPROTO_UDP, NULL, 0, 0) == INVALID_SOCKET, - "WSASocketA should have failed\n"); - err = WSAGetLastError(); - ok(err == WSAEPROTONOSUPPORT, "Expected 10043, received %d\n", err); + size = sizeof(info); + err = getsockopt( sock, SOL_SOCKET, SO_PROTOCOL_INFOA, (char *)&info, &size ); + ok(!err, "Test %u: getsockopt failed, error %u\n", i, WSAGetLastError()); + ok(info.iAddressFamily == tests[i].ret_family, "Test %u: got wrong family %d\n", i, info.iAddressFamily); + ok(info.iSocketType == tests[i].ret_type, "Test %u: got wrong type %d\n", i, info.iSocketType); + todo_wine_if (i == 10 || i == 11 || i == 16) + ok(info.iProtocol == tests[i].ret_protocol, "Test %u: got wrong protocol %d\n", i, info.iProtocol);
- /* SOCK_DGRAM does not support IPPROTO_TCP */ - SetLastError(0xdeadbeef); - ok(WSASocketA(AF_INET, SOCK_DGRAM, IPPROTO_TCP, NULL, 0, 0) == INVALID_SOCKET, - "WSASocketA should have failed\n"); - err = WSAGetLastError(); - ok(err == WSAEPROTONOSUPPORT, "Expected 10043, received %d\n", err); + closesocket( sock ); + } + }
/* Set pi_size explicitly to a value below 2*sizeof(WSAPROTOCOL_INFOA) * to avoid a crash on win98.
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=79332
Your paranoid android.
=== w10pro64_2scr (32 bit report) ===
ws2_32: sock.c:8375: Test failed: Waiting for accept event failed with 258 + errno 0 sock.c:8385: Test failed: The wrong first client was accepted by acceptex: 2 != 1
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ws2_32/socket.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index 1ac1f77d6e6..5089029f4b4 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -7648,7 +7648,13 @@ SOCKET WINAPI WSASocketW(int af, int type, int protocol, protocol = lpProtocolInfo->iProtocol; }
- if (!type && (af || protocol)) + if (!af && !protocol) + { + WSASetLastError(WSAEINVAL); + return INVALID_SOCKET; + } + + if (!type) { int autoproto = protocol; WSAPROTOCOL_INFOW infow;