ws2_32: Make wait in WS2_recv_base() alertable.
[wine.git] / dlls / ws2_32 / tests / sock.c
blobaf4226e62585b2d4cffe2e0a3259624630a0819a
1 /*
2 * Unit test suite for winsock functions
4 * Copyright 2002 Martin Wilck
5 * Copyright 2005 Thomas Kho
6 * Copyright 2008 Jeff Zaroyko
7 * Copyright 2017 Dmitry Timoshkov
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #include <ntstatus.h>
25 #define WIN32_NO_STATUS
26 #include <winsock2.h>
27 #include <windows.h>
28 #include <winternl.h>
29 #include <iphlpapi.h>
30 #include <ws2tcpip.h>
31 #include <wsipx.h>
32 #include <wsnwlink.h>
33 #include <mswsock.h>
34 #include <mstcpip.h>
35 #include <stdio.h>
36 #include "wine/test.h"
38 #define MAX_CLIENTS 4 /* Max number of clients */
39 #define FIRST_CHAR 'A' /* First character in transferred pattern */
40 #define BIND_SLEEP 10 /* seconds to wait between attempts to bind() */
41 #define BIND_TRIES 6 /* Number of bind() attempts */
42 #define TEST_TIMEOUT 30 /* seconds to wait before killing child threads
43 after server initialization, if something hangs */
45 #define NUM_UDP_PEERS 3 /* Number of UDP sockets to create and test > 1 */
47 #define SERVERIP "127.0.0.1" /* IP to bind to */
48 #define SERVERPORT 9374 /* Port number to bind to */
50 #define wsa_ok(op, cond, msg) \
51 do { \
52 int tmp, err = 0; \
53 tmp = op; \
54 if ( !(cond tmp) ) err = WSAGetLastError(); \
55 ok ( cond tmp, msg, GetCurrentThreadId(), err); \
56 } while (0);
58 #define make_keepalive(k, enable, time, interval) \
59 k.onoff = enable; \
60 k.keepalivetime = time; \
61 k.keepaliveinterval = interval;
63 /* Function pointers */
64 static int (WINAPI *pWSAPoll)(WSAPOLLFD *,ULONG,INT);
66 /* Function pointers from ntdll */
67 static DWORD (WINAPI *pNtClose)(HANDLE);
69 /**************** Structs and typedefs ***************/
71 typedef struct thread_info
73 HANDLE thread;
74 DWORD id;
75 } thread_info;
77 /* Information in the server about open client connections */
78 typedef struct sock_info
80 SOCKET s;
81 struct sockaddr_in addr;
82 struct sockaddr_in peer;
83 char *buf;
84 int n_recvd;
85 int n_sent;
86 } sock_info;
88 /* Test parameters for both server & client */
89 typedef struct test_params
91 int sock_type;
92 int sock_prot;
93 const char *inet_addr;
94 short inet_port;
95 int chunk_size;
96 int n_chunks;
97 int n_clients;
98 } test_params;
100 /* server-specific test parameters */
101 typedef struct server_params
103 test_params *general;
104 DWORD sock_flags;
105 int buflen;
106 } server_params;
108 /* client-specific test parameters */
109 typedef struct client_params
111 test_params *general;
112 DWORD sock_flags;
113 int buflen;
114 } client_params;
116 /* This type combines all information for setting up a test scenario */
117 typedef struct test_setup
119 test_params general;
120 LPVOID srv;
121 server_params srv_params;
122 LPVOID clt;
123 client_params clt_params;
124 } test_setup;
126 /* Thread local storage for server */
127 typedef struct server_memory
129 SOCKET s;
130 struct sockaddr_in addr;
131 sock_info sock[MAX_CLIENTS];
132 } server_memory;
134 /* Thread local storage for client */
135 typedef struct client_memory
137 SOCKET s;
138 struct sockaddr_in addr;
139 char *send_buf;
140 char *recv_buf;
141 } client_memory;
143 /* SelectReadThread thread parameters */
144 typedef struct select_thread_params
146 SOCKET s;
147 BOOL ReadKilled;
148 } select_thread_params;
150 /**************** Static variables ***************/
152 static DWORD tls; /* Thread local storage index */
153 static HANDLE thread[1+MAX_CLIENTS];
154 static DWORD thread_id[1+MAX_CLIENTS];
155 static HANDLE server_ready;
156 static HANDLE client_ready[MAX_CLIENTS];
157 static int client_id;
158 static GUID WSARecvMsg_GUID = WSAID_WSARECVMSG;
160 /**************** General utility functions ***************/
162 static SOCKET setup_server_socket(struct sockaddr_in *addr, int *len);
163 static SOCKET setup_connector_socket(const struct sockaddr_in *addr, int len, BOOL nonblock);
165 static void tcp_socketpair_flags(SOCKET *src, SOCKET *dst, DWORD flags)
167 SOCKET server = INVALID_SOCKET;
168 struct sockaddr_in addr;
169 int len, ret;
171 *src = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, flags);
172 ok(*src != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
174 server = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, flags);
175 ok(server != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
177 memset(&addr, 0, sizeof(addr));
178 addr.sin_family = AF_INET;
179 addr.sin_addr.s_addr = inet_addr("127.0.0.1");
180 ret = bind(server, (struct sockaddr *)&addr, sizeof(addr));
181 ok(!ret, "failed to bind socket, error %u\n", WSAGetLastError());
183 len = sizeof(addr);
184 ret = getsockname(server, (struct sockaddr *)&addr, &len);
185 ok(!ret, "failed to get address, error %u\n", WSAGetLastError());
187 ret = listen(server, 1);
188 ok(!ret, "failed to listen, error %u\n", WSAGetLastError());
190 ret = connect(*src, (struct sockaddr *)&addr, sizeof(addr));
191 ok(!ret, "failed to connect, error %u\n", WSAGetLastError());
193 len = sizeof(addr);
194 *dst = accept(server, (struct sockaddr *)&addr, &len);
195 ok(*dst != INVALID_SOCKET, "failed to accept socket, error %u\n", WSAGetLastError());
197 closesocket(server);
200 static void tcp_socketpair(SOCKET *src, SOCKET *dst)
202 tcp_socketpair_flags(src, dst, WSA_FLAG_OVERLAPPED);
205 static void WINAPI apc_func(ULONG_PTR apc_count)
207 ++*(unsigned int *)apc_count;
210 /* Set the linger timeout to zero and close the socket. This will trigger an
211 * RST on the connection on Windows as well as on Unix systems. */
212 static void close_with_rst(SOCKET s)
214 static const struct linger linger = {.l_onoff = 1};
215 int ret;
217 SetLastError(0xdeadbeef);
218 ret = setsockopt(s, SOL_SOCKET, SO_LINGER, (const char *)&linger, sizeof(linger));
219 ok(!ret, "got %d\n", ret);
220 ok(!GetLastError(), "got error %lu\n", GetLastError());
222 closesocket(s);
225 #define check_poll(a, b) check_poll_(__LINE__, a, POLLRDNORM | POLLRDBAND | POLLWRNORM, b, FALSE)
226 #define check_poll_todo(a, b) check_poll_(__LINE__, a, POLLRDNORM | POLLRDBAND | POLLWRNORM, b, TRUE)
227 #define check_poll_mask(a, b, c) check_poll_(__LINE__, a, b, c, FALSE)
228 #define check_poll_mask_todo(a, b, c) check_poll_(__LINE__, a, b, c, TRUE)
229 static void check_poll_(int line, SOCKET s, short mask, short expect, BOOL todo)
231 WSAPOLLFD pollfd;
232 int ret;
234 pollfd.fd = s;
235 pollfd.events = mask;
236 pollfd.revents = 0xdead;
237 ret = pWSAPoll(&pollfd, 1, 1000);
238 ok_(__FILE__, line)(ret == (pollfd.revents ? 1 : 0), "WSAPoll() returned %d\n", ret);
239 todo_wine_if (todo) ok_(__FILE__, line)(pollfd.revents == expect, "got wrong events %#x\n", pollfd.revents);
242 static DWORD WINAPI poll_async_thread(void *arg)
244 WSAPOLLFD *pollfd = arg;
245 int ret;
247 ret = pWSAPoll(pollfd, 1, 500);
248 ok(ret == (pollfd->revents ? 1 : 0), "WSAPoll() returned %d\n", ret);
250 return 0;
253 static void set_so_opentype ( BOOL overlapped )
255 int optval = !overlapped, newval, len = sizeof (int);
257 ok ( setsockopt ( INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE,
258 (LPVOID) &optval, sizeof (optval) ) == 0,
259 "setting SO_OPENTYPE failed\n" );
260 ok ( getsockopt ( INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE,
261 (LPVOID) &newval, &len ) == 0,
262 "getting SO_OPENTYPE failed\n" );
263 ok ( optval == newval, "failed to set SO_OPENTYPE\n" );
266 static int set_blocking ( SOCKET s, BOOL blocking )
268 u_long val = !blocking;
269 return ioctlsocket ( s, FIONBIO, &val );
272 static void fill_buffer ( char *buf, int chunk_size, int n_chunks )
274 char c, *p;
275 for ( c = FIRST_CHAR, p = buf; c < FIRST_CHAR + n_chunks; c++, p += chunk_size )
276 memset ( p, c, chunk_size );
279 static int test_buffer ( char *buf, int chunk_size, int n_chunks )
281 char c, *p;
282 int i;
283 for ( c = FIRST_CHAR, p = buf; c < FIRST_CHAR + n_chunks; c++, p += chunk_size )
285 for ( i = 0; i < chunk_size; i++ )
286 if ( p[i] != c ) return i;
288 return -1;
292 * This routine is called when a client / server does not expect any more data,
293 * but needs to acknowledge the closing of the connection (by reading 0 bytes).
295 static void read_zero_bytes ( SOCKET s )
297 char buf[256];
298 int tmp, n = 0;
299 while ( ( tmp = recv ( s, buf, 256, 0 ) ) > 0 )
300 n += tmp;
301 ok ( n <= 0, "garbage data received: %d bytes\n", n );
304 static int do_synchronous_send ( SOCKET s, char *buf, int buflen, int flags, int sendlen )
306 char* last = buf + buflen, *p;
307 int n = 1;
308 for ( p = buf; n > 0 && p < last; )
310 n = send ( s, p, min ( sendlen, last - p ), flags );
311 if (n > 0) p += n;
313 wsa_ok ( n, 0 <=, "do_synchronous_send (%lx): error %d\n" );
314 return p - buf;
317 static int do_synchronous_recv ( SOCKET s, char *buf, int buflen, int flags, int recvlen )
319 char* last = buf + buflen, *p;
320 int n = 1;
321 for ( p = buf; n > 0 && p < last; )
323 n = recv ( s, p, min ( recvlen, last - p ), flags );
324 if (n > 0) p += n;
326 wsa_ok ( n, 0 <=, "do_synchronous_recv (%lx): error %d:\n" );
327 return p - buf;
330 static int do_synchronous_recvfrom ( SOCKET s, char *buf, int buflen, int flags, struct sockaddr *from, int *fromlen, int recvlen )
332 char* last = buf + buflen, *p;
333 int n = 1;
334 for ( p = buf; n > 0 && p < last; )
336 n = recvfrom ( s, p, min ( recvlen, last - p ), flags, from, fromlen );
337 if (n > 0) p += n;
339 wsa_ok ( n, 0 <=, "do_synchronous_recv (%lx): error %d:\n" );
340 return p - buf;
344 * Call this routine right after thread startup.
345 * SO_OPENTYPE must by 0, regardless what the server did.
347 static void check_so_opentype (void)
349 int tmp = 1, len;
350 len = sizeof (tmp);
351 getsockopt ( INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE, (LPVOID) &tmp, &len );
352 ok ( tmp == 0, "check_so_opentype: wrong startup value of SO_OPENTYPE: %d\n", tmp );
355 /**************** Server utility functions ***************/
358 * Even if we have closed our server socket cleanly,
359 * the OS may mark the address "in use" for some time -
360 * this happens with native Linux apps, too.
362 static void do_bind ( SOCKET s, struct sockaddr* addr, int addrlen )
364 int err, wsaerr = 0, n_try = BIND_TRIES;
366 while ( ( err = bind ( s, addr, addrlen ) ) != 0 &&
367 ( wsaerr = WSAGetLastError () ) == WSAEADDRINUSE &&
368 n_try-- >= 0)
370 trace ( "address in use, waiting ...\n" );
371 Sleep ( 1000 * BIND_SLEEP );
373 ok ( err == 0, "failed to bind: %d\n", wsaerr );
376 static void server_start ( server_params *par )
378 int i;
379 test_params *gen = par->general;
380 server_memory *mem = LocalAlloc ( LPTR, sizeof ( server_memory ) );
382 TlsSetValue ( tls, mem );
383 mem->s = WSASocketA ( AF_INET, gen->sock_type, gen->sock_prot,
384 NULL, 0, par->sock_flags );
385 ok ( mem->s != INVALID_SOCKET, "Server: WSASocket failed\n" );
387 mem->addr.sin_family = AF_INET;
388 mem->addr.sin_addr.s_addr = inet_addr ( gen->inet_addr );
389 mem->addr.sin_port = htons ( gen->inet_port );
391 for (i = 0; i < MAX_CLIENTS; i++)
393 mem->sock[i].s = INVALID_SOCKET;
394 mem->sock[i].buf = LocalAlloc ( LPTR, gen->n_chunks * gen->chunk_size );
395 mem->sock[i].n_recvd = 0;
396 mem->sock[i].n_sent = 0;
399 if ( gen->sock_type == SOCK_STREAM )
400 do_bind ( mem->s, (struct sockaddr*) &mem->addr, sizeof (mem->addr) );
403 static void server_stop (void)
405 int i;
406 server_memory *mem = TlsGetValue ( tls );
408 for (i = 0; i < MAX_CLIENTS; i++ )
410 LocalFree ( mem->sock[i].buf );
411 if ( mem->sock[i].s != INVALID_SOCKET )
412 closesocket ( mem->sock[i].s );
414 ok ( closesocket ( mem->s ) == 0, "closesocket failed\n" );
415 LocalFree ( mem );
416 ExitThread ( GetCurrentThreadId () );
419 /**************** Client utilitiy functions ***************/
421 static void client_start ( client_params *par )
423 test_params *gen = par->general;
424 client_memory *mem = LocalAlloc (LPTR, sizeof (client_memory));
426 TlsSetValue ( tls, mem );
428 WaitForSingleObject ( server_ready, INFINITE );
430 mem->s = WSASocketA ( AF_INET, gen->sock_type, gen->sock_prot,
431 NULL, 0, par->sock_flags );
433 mem->addr.sin_family = AF_INET;
434 mem->addr.sin_addr.s_addr = inet_addr ( gen->inet_addr );
435 mem->addr.sin_port = htons ( gen->inet_port );
437 ok ( mem->s != INVALID_SOCKET, "Client: WSASocket failed\n" );
439 mem->send_buf = LocalAlloc ( LPTR, 2 * gen->n_chunks * gen->chunk_size );
440 mem->recv_buf = mem->send_buf + gen->n_chunks * gen->chunk_size;
441 fill_buffer ( mem->send_buf, gen->chunk_size, gen->n_chunks );
443 SetEvent ( client_ready[client_id] );
444 /* Wait for the other clients to come up */
445 WaitForMultipleObjects ( min ( gen->n_clients, MAX_CLIENTS ), client_ready, TRUE, INFINITE );
448 static void client_stop (void)
450 client_memory *mem = TlsGetValue ( tls );
451 wsa_ok ( closesocket ( mem->s ), 0 ==, "closesocket error (%lx): %d\n" );
452 LocalFree ( mem->send_buf );
453 LocalFree ( mem );
454 ExitThread(0);
457 /**************** Servers ***************/
460 * simple_server: A very basic server doing synchronous IO.
462 static VOID WINAPI simple_server ( server_params *par )
464 test_params *gen = par->general;
465 server_memory *mem;
466 int pos, n_recvd, n_sent, n_expected = gen->n_chunks * gen->chunk_size, tmp, i,
467 id = GetCurrentThreadId();
469 set_so_opentype ( FALSE ); /* non-overlapped */
470 server_start ( par );
471 mem = TlsGetValue ( tls );
473 wsa_ok ( set_blocking ( mem->s, TRUE ), 0 ==, "simple_server (%lx): failed to set blocking mode: %d\n");
474 wsa_ok ( listen ( mem->s, SOMAXCONN ), 0 ==, "simple_server (%lx): listen failed: %d\n");
476 SetEvent ( server_ready ); /* notify clients */
478 for ( i = 0; i < min ( gen->n_clients, MAX_CLIENTS ); i++ )
480 /* accept a single connection */
481 tmp = sizeof ( mem->sock[0].peer );
482 mem->sock[0].s = accept ( mem->s, (struct sockaddr*) &mem->sock[0].peer, &tmp );
483 wsa_ok ( mem->sock[0].s, INVALID_SOCKET !=, "simple_server (%lx): accept failed: %d\n" );
485 ok ( mem->sock[0].peer.sin_addr.s_addr == inet_addr ( gen->inet_addr ),
486 "simple_server (%x): strange peer address\n", id );
488 /* Receive data & check it */
489 n_recvd = do_synchronous_recv ( mem->sock[0].s, mem->sock[0].buf, n_expected, 0, par->buflen );
490 ok ( n_recvd == n_expected,
491 "simple_server (%x): received less data than expected: %d of %d\n", id, n_recvd, n_expected );
492 pos = test_buffer ( mem->sock[0].buf, gen->chunk_size, gen->n_chunks );
493 ok ( pos == -1, "simple_server (%x): test pattern error: %d\n", id, pos);
495 /* Echo data back */
496 n_sent = do_synchronous_send ( mem->sock[0].s, mem->sock[0].buf, n_expected, 0, par->buflen );
497 ok ( n_sent == n_expected,
498 "simple_server (%x): sent less data than expected: %d of %d\n", id, n_sent, n_expected );
500 /* cleanup */
501 read_zero_bytes ( mem->sock[0].s );
502 wsa_ok ( closesocket ( mem->sock[0].s ), 0 ==, "simple_server (%lx): closesocket error: %d\n" );
503 mem->sock[0].s = INVALID_SOCKET;
506 server_stop ();
510 * oob_server: A very basic server receiving out-of-band data.
512 static VOID WINAPI oob_server ( server_params *par )
514 test_params *gen = par->general;
515 server_memory *mem;
516 u_long atmark = 0;
517 int pos, n_sent, n_recvd, n_expected = gen->n_chunks * gen->chunk_size, tmp,
518 id = GetCurrentThreadId();
520 set_so_opentype ( FALSE ); /* non-overlapped */
521 server_start ( par );
522 mem = TlsGetValue ( tls );
524 wsa_ok ( set_blocking ( mem->s, TRUE ), 0 ==, "oob_server (%lx): failed to set blocking mode: %d\n");
525 wsa_ok ( listen ( mem->s, SOMAXCONN ), 0 ==, "oob_server (%lx): listen failed: %d\n");
527 SetEvent ( server_ready ); /* notify clients */
529 /* accept a single connection */
530 tmp = sizeof ( mem->sock[0].peer );
531 mem->sock[0].s = accept ( mem->s, (struct sockaddr*) &mem->sock[0].peer, &tmp );
532 wsa_ok ( mem->sock[0].s, INVALID_SOCKET !=, "oob_server (%lx): accept failed: %d\n" );
534 ok ( mem->sock[0].peer.sin_addr.s_addr == inet_addr ( gen->inet_addr ),
535 "oob_server (%x): strange peer address\n", id );
537 /* check initial atmark state */
538 ioctlsocket ( mem->sock[0].s, SIOCATMARK, &atmark );
539 ok ( atmark == 1, "oob_server (%x): unexpectedly at the OOB mark: %li\n", id, atmark );
541 /* Receive normal data */
542 n_recvd = do_synchronous_recv ( mem->sock[0].s, mem->sock[0].buf, n_expected, 0, par->buflen );
543 ok ( n_recvd == n_expected,
544 "oob_server (%x): received less data than expected: %d of %d\n", id, n_recvd, n_expected );
545 pos = test_buffer ( mem->sock[0].buf, gen->chunk_size, gen->n_chunks );
546 ok ( pos == -1, "oob_server (%x): test pattern error: %d\n", id, pos);
548 /* check atmark state */
549 ioctlsocket ( mem->sock[0].s, SIOCATMARK, &atmark );
550 ok ( atmark == 1, "oob_server (%x): unexpectedly at the OOB mark: %li\n", id, atmark );
552 /* Echo data back */
553 n_sent = do_synchronous_send ( mem->sock[0].s, mem->sock[0].buf, n_expected, 0, par->buflen );
554 ok ( n_sent == n_expected,
555 "oob_server (%x): sent less data than expected: %d of %d\n", id, n_sent, n_expected );
557 /* Receive a part of the out-of-band data and print atmark state */
558 n_recvd = do_synchronous_recv ( mem->sock[0].s, mem->sock[0].buf, 8, 0, par->buflen );
559 ok ( n_recvd == 8,
560 "oob_server (%x): received less data than expected: %d of %d\n", id, n_recvd, 8 );
561 n_expected -= 8;
563 ioctlsocket ( mem->sock[0].s, SIOCATMARK, &atmark );
565 /* Receive the rest of the out-of-band data and check atmark state */
566 do_synchronous_recv ( mem->sock[0].s, mem->sock[0].buf, n_expected, 0, par->buflen );
568 ioctlsocket ( mem->sock[0].s, SIOCATMARK, &atmark );
569 todo_wine ok ( atmark == 0, "oob_server (%x): not at the OOB mark: %li\n", id, atmark );
571 /* cleanup */
572 wsa_ok ( closesocket ( mem->sock[0].s ), 0 ==, "oob_server (%lx): closesocket error: %d\n" );
573 mem->sock[0].s = INVALID_SOCKET;
575 server_stop ();
579 * select_server: A non-blocking server.
581 static VOID WINAPI select_server ( server_params *par )
583 test_params *gen = par->general;
584 server_memory *mem;
585 int n_expected = gen->n_chunks * gen->chunk_size, tmp, i,
586 id = GetCurrentThreadId(), n_connections = 0, n_sent, n_recvd,
587 n_set, delta, n_ready;
588 struct timeval timeout = {0,10}; /* wait for 10 milliseconds */
589 fd_set fds_recv, fds_send, fds_openrecv, fds_opensend;
591 set_so_opentype ( FALSE ); /* non-overlapped */
592 server_start ( par );
593 mem = TlsGetValue ( tls );
595 wsa_ok ( set_blocking ( mem->s, FALSE ), 0 ==, "select_server (%lx): failed to set blocking mode: %d\n");
596 wsa_ok ( listen ( mem->s, SOMAXCONN ), 0 ==, "select_server (%lx): listen failed: %d\n");
598 SetEvent ( server_ready ); /* notify clients */
600 FD_ZERO ( &fds_openrecv );
601 FD_ZERO ( &fds_recv );
602 FD_ZERO ( &fds_send );
603 FD_ZERO ( &fds_opensend );
605 FD_SET ( mem->s, &fds_openrecv );
607 while(1)
609 fds_recv = fds_openrecv;
610 fds_send = fds_opensend;
612 n_set = 0;
614 wsa_ok ( ( n_ready = select ( 0, &fds_recv, &fds_send, NULL, &timeout ) ), SOCKET_ERROR !=,
615 "select_server (%lx): select() failed: %d\n" );
617 /* check for incoming requests */
618 if ( FD_ISSET ( mem->s, &fds_recv ) ) {
619 n_set += 1;
621 /* accept a single connection */
622 tmp = sizeof ( mem->sock[n_connections].peer );
623 mem->sock[n_connections].s = accept ( mem->s, (struct sockaddr*) &mem->sock[n_connections].peer, &tmp );
624 wsa_ok ( mem->sock[n_connections].s, INVALID_SOCKET !=, "select_server (%lx): accept() failed: %d\n" );
626 ok ( mem->sock[n_connections].peer.sin_addr.s_addr == inet_addr ( gen->inet_addr ),
627 "select_server (%x): strange peer address\n", id );
629 /* add to list of open connections */
630 FD_SET ( mem->sock[n_connections].s, &fds_openrecv );
631 FD_SET ( mem->sock[n_connections].s, &fds_opensend );
633 n_connections++;
636 /* handle open requests */
638 for ( i = 0; i < n_connections; i++ )
640 if ( FD_ISSET( mem->sock[i].s, &fds_recv ) ) {
641 n_set += 1;
643 if ( mem->sock[i].n_recvd < n_expected ) {
644 /* Receive data & check it */
645 n_recvd = recv ( mem->sock[i].s, mem->sock[i].buf + mem->sock[i].n_recvd, min ( n_expected - mem->sock[i].n_recvd, par->buflen ), 0 );
646 ok ( n_recvd != SOCKET_ERROR, "select_server (%x): error in recv(): %d\n", id, WSAGetLastError() );
647 mem->sock[i].n_recvd += n_recvd;
649 if ( mem->sock[i].n_recvd == n_expected ) {
650 int pos = test_buffer ( mem->sock[i].buf, gen->chunk_size, gen->n_chunks );
651 ok ( pos == -1, "select_server (%x): test pattern error: %d\n", id, pos );
652 FD_CLR ( mem->sock[i].s, &fds_openrecv );
655 ok ( mem->sock[i].n_recvd <= n_expected, "select_server (%x): received too many bytes: %d\n", id, mem->sock[i].n_recvd );
659 /* only echo back what we've received */
660 delta = mem->sock[i].n_recvd - mem->sock[i].n_sent;
662 if ( FD_ISSET ( mem->sock[i].s, &fds_send ) ) {
663 n_set += 1;
665 if ( ( delta > 0 ) && ( mem->sock[i].n_sent < n_expected ) ) {
666 /* Echo data back */
667 n_sent = send ( mem->sock[i].s, mem->sock[i].buf + mem->sock[i].n_sent, min ( delta, par->buflen ), 0 );
668 ok ( n_sent != SOCKET_ERROR, "select_server (%x): error in send(): %d\n", id, WSAGetLastError() );
669 mem->sock[i].n_sent += n_sent;
671 if ( mem->sock[i].n_sent == n_expected ) {
672 FD_CLR ( mem->sock[i].s, &fds_opensend );
675 ok ( mem->sock[i].n_sent <= n_expected, "select_server (%x): sent too many bytes: %d\n", id, mem->sock[i].n_sent );
680 /* check that select returned the correct number of ready sockets */
681 ok ( ( n_set == n_ready ), "select_server (%x): select() returns wrong number of ready sockets\n", id );
683 /* check if all clients are done */
684 if ( ( fds_opensend.fd_count == 0 )
685 && ( fds_openrecv.fd_count == 1 ) /* initial socket that accepts clients */
686 && ( n_connections == min ( gen->n_clients, MAX_CLIENTS ) ) ) {
687 break;
691 for ( i = 0; i < min ( gen->n_clients, MAX_CLIENTS ); i++ )
693 /* cleanup */
694 read_zero_bytes ( mem->sock[i].s );
695 wsa_ok ( closesocket ( mem->sock[i].s ), 0 ==, "select_server (%lx): closesocket error: %d\n" );
696 mem->sock[i].s = INVALID_SOCKET;
699 server_stop ();
702 /**************** Clients ***************/
705 * simple_client: A very basic client doing synchronous IO.
707 static VOID WINAPI simple_client ( client_params *par )
709 test_params *gen = par->general;
710 client_memory *mem;
711 int pos, n_sent, n_recvd, n_expected = gen->n_chunks * gen->chunk_size, id;
713 id = GetCurrentThreadId();
714 /* wait here because we want to call set_so_opentype before creating a socket */
715 WaitForSingleObject ( server_ready, INFINITE );
717 check_so_opentype ();
718 set_so_opentype ( FALSE ); /* non-overlapped */
719 client_start ( par );
720 mem = TlsGetValue ( tls );
722 /* Connect */
723 wsa_ok ( connect ( mem->s, (struct sockaddr*) &mem->addr, sizeof ( mem->addr ) ),
724 0 ==, "simple_client (%lx): connect error: %d\n" );
725 ok ( set_blocking ( mem->s, TRUE ) == 0,
726 "simple_client (%x): failed to set blocking mode\n", id );
728 /* send data to server */
729 n_sent = do_synchronous_send ( mem->s, mem->send_buf, n_expected, 0, par->buflen );
730 ok ( n_sent == n_expected,
731 "simple_client (%x): sent less data than expected: %d of %d\n", id, n_sent, n_expected );
733 /* shutdown send direction */
734 wsa_ok ( shutdown ( mem->s, SD_SEND ), 0 ==, "simple_client (%lx): shutdown failed: %d\n" );
736 /* Receive data echoed back & check it */
737 n_recvd = do_synchronous_recv ( mem->s, mem->recv_buf, n_expected, 0, par->buflen );
738 ok ( n_recvd == n_expected,
739 "simple_client (%x): received less data than expected: %d of %d\n", id, n_recvd, n_expected );
741 /* check data */
742 pos = test_buffer ( mem->recv_buf, gen->chunk_size, gen->n_chunks );
743 ok ( pos == -1, "simple_client (%x): test pattern error: %d\n", id, pos);
745 /* cleanup */
746 read_zero_bytes ( mem->s );
747 client_stop ();
751 * oob_client: A very basic client sending out-of-band data.
753 static VOID WINAPI oob_client ( client_params *par )
755 test_params *gen = par->general;
756 client_memory *mem;
757 int pos, n_sent, n_recvd, n_expected = gen->n_chunks * gen->chunk_size, id;
759 id = GetCurrentThreadId();
760 /* wait here because we want to call set_so_opentype before creating a socket */
761 WaitForSingleObject ( server_ready, INFINITE );
763 check_so_opentype ();
764 set_so_opentype ( FALSE ); /* non-overlapped */
765 client_start ( par );
766 mem = TlsGetValue ( tls );
768 /* Connect */
769 wsa_ok ( connect ( mem->s, (struct sockaddr*) &mem->addr, sizeof ( mem->addr ) ),
770 0 ==, "oob_client (%lx): connect error: %d\n" );
771 ok ( set_blocking ( mem->s, TRUE ) == 0,
772 "oob_client (%x): failed to set blocking mode\n", id );
774 /* send data to server */
775 n_sent = do_synchronous_send ( mem->s, mem->send_buf, n_expected, 0, par->buflen );
776 ok ( n_sent == n_expected,
777 "oob_client (%x): sent less data than expected: %d of %d\n", id, n_sent, n_expected );
779 /* Receive data echoed back & check it */
780 n_recvd = do_synchronous_recv ( mem->s, mem->recv_buf, n_expected, 0, par->buflen );
781 ok ( n_recvd == n_expected,
782 "simple_client (%x): received less data than expected: %d of %d\n", id, n_recvd, n_expected );
783 pos = test_buffer ( mem->recv_buf, gen->chunk_size, gen->n_chunks );
784 ok ( pos == -1, "simple_client (%x): test pattern error: %d\n", id, pos);
786 /* send out-of-band data to server */
787 n_sent = do_synchronous_send ( mem->s, mem->send_buf, n_expected, MSG_OOB, par->buflen );
788 ok ( n_sent == n_expected,
789 "oob_client (%x): sent less data than expected: %d of %d\n", id, n_sent, n_expected );
791 /* shutdown send direction */
792 wsa_ok ( shutdown ( mem->s, SD_SEND ), 0 ==, "simple_client (%lx): shutdown failed: %d\n" );
794 /* cleanup */
795 read_zero_bytes ( mem->s );
796 client_stop ();
800 * simple_mixed_client: mixing send and recvfrom
802 static VOID WINAPI simple_mixed_client ( client_params *par )
804 test_params *gen = par->general;
805 client_memory *mem;
806 int pos, n_sent, n_recvd, n_expected = gen->n_chunks * gen->chunk_size, id;
807 int fromLen = sizeof(mem->addr);
808 struct sockaddr test;
810 id = GetCurrentThreadId();
811 /* wait here because we want to call set_so_opentype before creating a socket */
812 WaitForSingleObject ( server_ready, INFINITE );
814 check_so_opentype ();
815 set_so_opentype ( FALSE ); /* non-overlapped */
816 client_start ( par );
817 mem = TlsGetValue ( tls );
819 /* Connect */
820 wsa_ok ( connect ( mem->s, (struct sockaddr*) &mem->addr, sizeof ( mem->addr ) ),
821 0 ==, "simple_client (%lx): connect error: %d\n" );
822 ok ( set_blocking ( mem->s, TRUE ) == 0,
823 "simple_client (%x): failed to set blocking mode\n", id );
825 /* send data to server */
826 n_sent = do_synchronous_send ( mem->s, mem->send_buf, n_expected, 0, par->buflen );
827 ok ( n_sent == n_expected,
828 "simple_client (%x): sent less data than expected: %d of %d\n", id, n_sent, n_expected );
830 /* shutdown send direction */
831 wsa_ok ( shutdown ( mem->s, SD_SEND ), 0 ==, "simple_client (%lx): shutdown failed: %d\n" );
833 /* this shouldn't change, since lpFrom, is not updated on
834 connection oriented sockets - exposed by bug 11640
836 ((struct sockaddr_in*)&test)->sin_addr.s_addr = inet_addr("0.0.0.0");
838 /* Receive data echoed back & check it */
839 n_recvd = do_synchronous_recvfrom ( mem->s,
840 mem->recv_buf,
841 n_expected,
843 (struct sockaddr *)&test,
844 &fromLen,
845 par->buflen );
846 ok ( n_recvd == n_expected,
847 "simple_client (%x): received less data than expected: %d of %d\n", id, n_recvd, n_expected );
849 /* check that lpFrom was not updated */
850 ok(0 ==
851 strcmp(
852 inet_ntoa(((struct sockaddr_in*)&test)->sin_addr),
853 "0.0.0.0"), "lpFrom shouldn't be updated on connection oriented sockets\n");
855 /* check data */
856 pos = test_buffer ( mem->recv_buf, gen->chunk_size, gen->n_chunks );
857 ok ( pos == -1, "simple_client (%x): test pattern error: %d\n", id, pos);
859 /* cleanup */
860 read_zero_bytes ( mem->s );
861 client_stop ();
865 * event_client: An event-driven client
867 static void WINAPI event_client ( client_params *par )
869 test_params *gen = par->general;
870 client_memory *mem;
871 int id = GetCurrentThreadId(), n_expected = gen->n_chunks * gen->chunk_size,
872 tmp, err, n;
873 HANDLE event;
874 WSANETWORKEVENTS wsa_events;
875 char *send_last, *recv_last, *send_p, *recv_p;
876 LONG mask = FD_READ | FD_WRITE | FD_CLOSE;
878 client_start ( par );
880 mem = TlsGetValue ( tls );
882 /* Prepare event notification for connect, makes socket nonblocking */
883 event = WSACreateEvent ();
884 WSAEventSelect ( mem->s, event, FD_CONNECT );
885 tmp = connect ( mem->s, (struct sockaddr*) &mem->addr, sizeof ( mem->addr ) );
886 if ( tmp != 0 ) {
887 err = WSAGetLastError ();
888 ok ( err == WSAEWOULDBLOCK, "event_client (%x): connect error: %d\n", id, err );
889 tmp = WaitForSingleObject ( event, INFINITE );
890 ok ( tmp == WAIT_OBJECT_0, "event_client (%x): wait for connect event failed: %d\n", id, tmp );
891 err = WSAEnumNetworkEvents ( mem->s, event, &wsa_events );
892 ok ( err == 0, "event_client (%x): WSAEnumNetworkEvents error: %d\n", id, err );
893 err = wsa_events.iErrorCode[ FD_CONNECT_BIT ];
894 ok ( err == 0, "event_client (%x): connect error: %d\n", id, err );
895 if ( err ) goto out;
898 WSAEventSelect ( mem->s, event, mask );
900 recv_p = mem->recv_buf;
901 recv_last = mem->recv_buf + n_expected;
902 send_p = mem->send_buf;
903 send_last = mem->send_buf + n_expected;
905 while ( TRUE )
907 err = WaitForSingleObject ( event, INFINITE );
908 ok ( err == WAIT_OBJECT_0, "event_client (%x): wait failed\n", id );
910 err = WSAEnumNetworkEvents ( mem->s, event, &wsa_events );
911 ok( err == 0, "event_client (%x): WSAEnumNetworkEvents error: %d\n", id, err );
913 if ( wsa_events.lNetworkEvents & FD_WRITE )
915 err = wsa_events.iErrorCode[ FD_WRITE_BIT ];
916 ok ( err == 0, "event_client (%x): FD_WRITE error code: %d\n", id, err );
918 if ( err== 0 )
921 n = send ( mem->s, send_p, min ( send_last - send_p, par->buflen ), 0 );
922 if ( n < 0 )
924 err = WSAGetLastError ();
925 ok ( err == WSAEWOULDBLOCK, "event_client (%x): send error: %d\n", id, err );
927 else
928 send_p += n;
930 while ( n >= 0 && send_p < send_last );
932 if ( send_p == send_last )
934 shutdown ( mem->s, SD_SEND );
935 mask &= ~FD_WRITE;
936 WSAEventSelect ( mem->s, event, mask );
939 if ( wsa_events.lNetworkEvents & FD_READ )
941 err = wsa_events.iErrorCode[ FD_READ_BIT ];
942 ok ( err == 0, "event_client (%x): FD_READ error code: %d\n", id, err );
943 if ( err != 0 ) break;
945 /* First read must succeed */
946 n = recv ( mem->s, recv_p, min ( recv_last - recv_p, par->buflen ), 0 );
947 wsa_ok ( n, 0 <=, "event_client (%lx): recv error: %d\n" );
949 while ( n >= 0 ) {
950 recv_p += n;
951 if ( recv_p == recv_last )
953 mask &= ~FD_READ;
954 WSAEventSelect ( mem->s, event, mask );
955 break;
957 n = recv ( mem->s, recv_p, min ( recv_last - recv_p, par->buflen ), 0 );
958 ok(n >= 0 || WSAGetLastError() == WSAEWOULDBLOCK,
959 "event_client (%x): got error %u\n", id, WSAGetLastError());
963 if ( wsa_events.lNetworkEvents & FD_CLOSE )
965 err = wsa_events.iErrorCode[ FD_CLOSE_BIT ];
966 ok ( err == 0, "event_client (%x): FD_CLOSE error code: %d\n", id, err );
967 break;
971 n = send_p - mem->send_buf;
972 ok ( send_p == send_last,
973 "simple_client (%x): sent less data than expected: %d of %d\n", id, n, n_expected );
974 n = recv_p - mem->recv_buf;
975 ok ( recv_p == recv_last,
976 "simple_client (%x): received less data than expected: %d of %d\n", id, n, n_expected );
977 n = test_buffer ( mem->recv_buf, gen->chunk_size, gen->n_chunks );
978 ok ( n == -1, "event_client (%x): test pattern error: %d\n", id, n);
980 out:
981 WSACloseEvent ( event );
982 client_stop ();
985 /* Tests for WSAStartup */
986 static void test_WithoutWSAStartup(void)
988 DWORD err;
990 WSASetLastError(0xdeadbeef);
991 ok(WSASocketA(0, 0, 0, NULL, 0, 0) == INVALID_SOCKET, "WSASocketA should have failed\n");
992 err = WSAGetLastError();
993 ok(err == WSANOTINITIALISED, "Expected 10093, received %ld\n", err);
995 WSASetLastError(0xdeadbeef);
996 ok(gethostbyname("localhost") == NULL, "gethostbyname() succeeded unexpectedly\n");
997 err = WSAGetLastError();
998 ok(err == WSANOTINITIALISED, "Expected 10093, received %ld\n", err);
1001 static void test_WithWSAStartup(void)
1003 WSADATA data;
1004 WORD version = MAKEWORD( 2, 2 );
1005 INT res, socks, i, j;
1006 SOCKET sock;
1007 LPVOID ptr;
1008 struct
1010 SOCKET src, dst, dup_src, dup_dst;
1011 } pairs[32];
1012 DWORD error;
1014 res = WSAStartup( version, &data );
1015 ok(res == 0, "WSAStartup() failed unexpectedly: %d\n", res);
1017 ptr = gethostbyname("localhost");
1018 ok(ptr != NULL, "gethostbyname() failed unexpectedly: %d\n", WSAGetLastError());
1020 /* Alloc some sockets to check if they are destroyed on WSACleanup */
1021 for (socks = 0; socks < ARRAY_SIZE(pairs); socks++)
1023 WSAPROTOCOL_INFOA info;
1024 tcp_socketpair(&pairs[socks].src, &pairs[socks].dst);
1026 memset(&info, 0, sizeof(info));
1027 ok(!WSADuplicateSocketA(pairs[socks].src, GetCurrentProcessId(), &info),
1028 "WSADuplicateSocketA should have worked\n");
1029 pairs[socks].dup_src = WSASocketA(0, 0, 0, &info, 0, 0);
1030 ok(pairs[socks].dup_src != SOCKET_ERROR, "expected != -1\n");
1032 memset(&info, 0, sizeof(info));
1033 ok(!WSADuplicateSocketA(pairs[socks].dst, GetCurrentProcessId(), &info),
1034 "WSADuplicateSocketA should have worked\n");
1035 pairs[socks].dup_dst = WSASocketA(0, 0, 0, &info, 0, 0);
1036 ok(pairs[socks].dup_dst != SOCKET_ERROR, "expected != -1\n");
1039 res = send(pairs[0].src, "TEST", 4, 0);
1040 ok(res == 4, "send failed with error %d\n", WSAGetLastError());
1042 WSACleanup();
1044 res = WSAStartup( version, &data );
1045 ok(res == 0, "WSAStartup() failed unexpectedly: %d\n", res);
1047 /* show that sockets are destroyed automatically after WSACleanup */
1048 SetLastError(0xdeadbeef);
1049 res = send(pairs[0].src, "TEST", 4, 0);
1050 error = WSAGetLastError();
1051 ok(res == SOCKET_ERROR, "send should have failed\n");
1052 ok(error == WSAENOTSOCK, "expected 10038, got %ld\n", error);
1054 SetLastError(0xdeadbeef);
1055 res = send(pairs[0].dst, "TEST", 4, 0);
1056 error = WSAGetLastError();
1057 ok(res == SOCKET_ERROR, "send should have failed\n");
1058 ok(error == WSAENOTSOCK, "expected 10038, got %ld\n", error);
1060 /* Check that all sockets were destroyed */
1061 for (i = 0; i < socks; i++)
1063 for (j = 0; j < 4; j++)
1065 struct sockaddr_in saddr;
1066 int size = sizeof(saddr);
1067 switch(j)
1069 case 0: sock = pairs[i].src; break;
1070 case 1: sock = pairs[i].dup_src; break;
1071 case 2: sock = pairs[i].dst; break;
1072 case 3: sock = pairs[i].dup_dst; break;
1075 SetLastError(0xdeadbeef);
1076 res = getsockname(sock, (struct sockaddr *)&saddr, &size);
1077 error = WSAGetLastError();
1078 ok(res == SOCKET_ERROR, "Test[%d]: getsockname should have failed\n", i);
1079 if (res == SOCKET_ERROR)
1080 ok(error == WSAENOTSOCK, "Test[%d]: expected 10038, got %ld\n", i, error);
1084 /* While wine is not fixed, close all sockets manually */
1085 for (i = 0; i < socks; i++)
1087 closesocket(pairs[i].src);
1088 closesocket(pairs[i].dst);
1089 closesocket(pairs[i].dup_src);
1090 closesocket(pairs[i].dup_dst);
1093 res = WSACleanup();
1094 ok(res == 0, "expected 0, got %d\n", res);
1095 WSASetLastError(0xdeadbeef);
1096 res = WSACleanup();
1097 error = WSAGetLastError();
1098 ok ( res == SOCKET_ERROR && error == WSANOTINITIALISED,
1099 "WSACleanup returned %d WSAGetLastError is %ld\n", res, error);
1102 /**************** Main program utility functions ***************/
1104 static void Init (void)
1106 WORD ver = MAKEWORD (2, 2);
1107 WSADATA data;
1108 HMODULE hws2_32 = GetModuleHandleA("ws2_32.dll"), ntdll;
1110 pWSAPoll = (void *)GetProcAddress(hws2_32, "WSAPoll");
1112 ntdll = LoadLibraryA("ntdll.dll");
1113 if (ntdll)
1114 pNtClose = (void *)GetProcAddress(ntdll, "NtClose");
1116 ok ( WSAStartup ( ver, &data ) == 0, "WSAStartup failed\n" );
1117 tls = TlsAlloc();
1120 static void Exit (void)
1122 INT ret, err;
1123 TlsFree ( tls );
1124 ret = WSACleanup();
1125 err = WSAGetLastError();
1126 ok ( ret == 0, "WSACleanup failed ret = %d GetLastError is %d\n", ret, err);
1129 static void StartServer (LPTHREAD_START_ROUTINE routine,
1130 test_params *general, server_params *par)
1132 par->general = general;
1133 thread[0] = CreateThread ( NULL, 0, routine, par, 0, &thread_id[0] );
1134 ok ( thread[0] != NULL, "Failed to create server thread\n" );
1137 static void StartClients (LPTHREAD_START_ROUTINE routine,
1138 test_params *general, client_params *par)
1140 int i;
1141 par->general = general;
1142 for ( i = 1; i <= min ( general->n_clients, MAX_CLIENTS ); i++ )
1144 client_id = i - 1;
1145 thread[i] = CreateThread ( NULL, 0, routine, par, 0, &thread_id[i] );
1146 ok ( thread[i] != NULL, "Failed to create client thread\n" );
1147 /* Make sure the client is up and running */
1148 WaitForSingleObject ( client_ready[client_id], INFINITE );
1152 static void do_test( test_setup *test )
1154 DWORD i, n = min (test->general.n_clients, MAX_CLIENTS);
1155 DWORD wait;
1157 server_ready = CreateEventA ( NULL, TRUE, FALSE, NULL );
1158 for (i = 0; i <= n; i++)
1159 client_ready[i] = CreateEventA ( NULL, TRUE, FALSE, NULL );
1161 StartServer ( test->srv, &test->general, &test->srv_params );
1162 StartClients ( test->clt, &test->general, &test->clt_params );
1163 WaitForSingleObject ( server_ready, INFINITE );
1165 wait = WaitForMultipleObjects ( 1 + n, thread, TRUE, 1000 * TEST_TIMEOUT );
1166 ok(!wait, "wait failed, error %lu\n", wait);
1168 CloseHandle ( server_ready );
1169 for (i = 0; i <= n; i++)
1170 CloseHandle ( client_ready[i] );
1173 /********* some tests for getsockopt(setsockopt(X)) == X ***********/
1174 /* optname = SO_LINGER */
1175 static const LINGER linger_testvals[] = {
1176 {0,0},
1177 {0,73},
1178 {1,0},
1179 {5,189}
1182 /* optname = SO_RCVTIMEO, SOSNDTIMEO */
1183 #define SOCKTIMEOUT1 63000 /* 63 seconds. Do not test fractional part because of a
1184 bug in the linux kernel (fixed in 2.6.8) */
1185 #define SOCKTIMEOUT2 997000 /* 997 seconds */
1187 static void test_set_getsockopt(void)
1189 static struct
1191 int af;
1192 int type;
1193 int level;
1194 int optname;
1195 BOOL accepts_short_len;
1196 unsigned int sizes[3];
1197 DWORD values[3];
1198 BOOL accepts_large_value;
1199 BOOL bool_value;
1201 test_optsize[] =
1203 {AF_INET, SOCK_DGRAM, SOL_SOCKET, SO_BROADCAST, TRUE, {1, 1, 4}, {0, 0xdead0001, 0}, TRUE, TRUE},
1204 {AF_INET, SOCK_STREAM, SOL_SOCKET, SO_DONTLINGER, TRUE, {1, 1, 4}, {0, 0xdead0001, 0}, TRUE, TRUE},
1205 {AF_INET, SOCK_STREAM, SOL_SOCKET, SO_LINGER, FALSE, {1, 2, 4}, {0xdeadbe00, 0xdead0000}, TRUE},
1206 {AF_INET, SOCK_STREAM, SOL_SOCKET, SO_OOBINLINE, TRUE, {1, 1, 4}, {0, 0xdead0001, 0}, TRUE, TRUE},
1207 {AF_INET, SOCK_STREAM, SOL_SOCKET, SO_RCVBUF, FALSE, {1, 2, 4}, {0xdeadbe00, 0xdead0000}, TRUE},
1208 {AF_INET, SOCK_STREAM, SOL_SOCKET, SO_KEEPALIVE, TRUE, {1, 1, 1}, {0}, TRUE},
1209 {AF_INET, SOCK_STREAM, SOL_SOCKET, SO_DONTROUTE, TRUE, {1, 1, 1}, {0}, TRUE},
1210 {AF_INET, SOCK_STREAM, SOL_SOCKET, SO_RCVTIMEO, FALSE, {1, 2, 4}, {0}, TRUE},
1211 {AF_INET, SOCK_STREAM, SOL_SOCKET, SO_REUSEADDR, TRUE, {1, 1, 4}, {0, 0xdead0001, 0}, TRUE, TRUE},
1212 {AF_INET, SOCK_STREAM, SOL_SOCKET, SO_SNDBUF, FALSE, {1, 2, 4}, {0xdeadbe00, 0xdead0000}, TRUE},
1213 {AF_INET, SOCK_STREAM, SOL_SOCKET, SO_SNDTIMEO, FALSE, {1, 2, 4}, {0}, TRUE},
1214 {AF_INET, SOCK_STREAM, SOL_SOCKET, SO_OPENTYPE, FALSE, {1, 2, 4}, {0}, TRUE},
1215 {AF_INET, SOCK_STREAM, IPPROTO_TCP, TCP_NODELAY, TRUE, {1, 1, 1}, {0}, TRUE},
1216 {AF_INET, SOCK_DGRAM, IPPROTO_IP, IP_MULTICAST_LOOP, TRUE, {1, 1, 4}, {0}, TRUE, TRUE},
1217 {AF_INET, SOCK_DGRAM, IPPROTO_IP, IP_MULTICAST_TTL, TRUE, {1, 1, 4}, {0}, FALSE},
1218 {AF_INET, SOCK_DGRAM, IPPROTO_IP, IP_PKTINFO, FALSE, {0, 0, 4}, {0}, TRUE, TRUE},
1219 {AF_INET, SOCK_DGRAM, IPPROTO_IP, IP_RECVTOS, FALSE, {0, 0, 4}, {0}, TRUE, TRUE},
1220 {AF_INET, SOCK_DGRAM, IPPROTO_IP, IP_RECVTTL, FALSE, {0, 0, 4}, {0}, TRUE, TRUE},
1221 {AF_INET, SOCK_DGRAM, IPPROTO_IP, IP_TOS, TRUE, {1, 1, 4}, {0}, FALSE},
1222 {AF_INET, SOCK_DGRAM, IPPROTO_IP, IP_TTL, TRUE, {1, 1, 4}, {0}, FALSE},
1223 {AF_INET6, SOCK_STREAM, IPPROTO_IPV6, IPV6_DONTFRAG, TRUE, {1, 1, 4}, {0}, TRUE, TRUE},
1224 {AF_INET6, SOCK_DGRAM, IPPROTO_IPV6, IPV6_HOPLIMIT, FALSE, {0, 0, 4}, {0}, TRUE, TRUE},
1225 {AF_INET6, SOCK_DGRAM, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, TRUE, {1, 1, 4}, {0}, FALSE},
1226 {AF_INET6, SOCK_DGRAM, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, TRUE, {1, 1, 4}, {0}, TRUE, TRUE},
1227 {AF_INET6, SOCK_DGRAM, IPPROTO_IPV6, IPV6_PKTINFO, FALSE, {0, 0, 4}, {0}, TRUE, TRUE},
1228 {AF_INET6, SOCK_DGRAM, IPPROTO_IPV6, IPV6_RECVTCLASS, FALSE, {0, 0, 4}, {0}, TRUE, TRUE},
1229 {AF_INET6, SOCK_DGRAM, IPPROTO_IPV6, IPV6_UNICAST_HOPS, TRUE, {1, 1, 4}, {0}, FALSE},
1230 {AF_INET6, SOCK_DGRAM, IPPROTO_IPV6, IPV6_V6ONLY, TRUE, {1, 1, 1}, {0}, TRUE},
1232 SOCKET s, s2;
1233 int i, j, err, lasterr;
1234 int timeout;
1235 LINGER lingval;
1236 int size;
1237 WSAPROTOCOL_INFOA infoA;
1238 WSAPROTOCOL_INFOW infoW;
1239 char providername[WSAPROTOCOL_LEN + 1];
1240 DWORD expected_last_error, expected_value;
1241 int expected_err, expected_size;
1242 DWORD value, save_value;
1243 UINT64 value64;
1245 struct _prottest
1247 int family, type, proto;
1248 } prottest[] = {
1249 {AF_INET, SOCK_STREAM, IPPROTO_TCP},
1250 {AF_INET, SOCK_DGRAM, IPPROTO_UDP},
1251 {AF_INET6, SOCK_STREAM, IPPROTO_TCP},
1252 {AF_INET6, SOCK_DGRAM, IPPROTO_UDP}
1254 union _csspace
1256 CSADDR_INFO cs;
1257 char space[128];
1258 } csinfoA, csinfoB;
1260 s = socket(AF_INET, SOCK_STREAM, 0);
1261 ok(s!=INVALID_SOCKET, "socket() failed error: %d\n", WSAGetLastError());
1262 if( s == INVALID_SOCKET) return;
1263 /* SO_RCVTIMEO */
1264 timeout = SOCKTIMEOUT1;
1265 size = sizeof(timeout);
1266 err = setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char *) &timeout, size);
1267 if( !err)
1268 err = getsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char *) &timeout, &size);
1269 ok( !err, "get/setsockopt(SO_RCVTIMEO) failed error: %d\n", WSAGetLastError());
1270 ok( timeout == SOCKTIMEOUT1, "getsockopt(SO_RCVTIMEO) returned wrong value %d\n", timeout);
1272 timeout = 0;
1273 size = sizeof(timeout);
1274 err = setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char *) &timeout, size);
1275 if( !err)
1276 err = getsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char *) &timeout, &size);
1277 ok( !err, "get/setsockopt(SO_RCVTIMEO) failed error: %d\n", WSAGetLastError());
1278 ok( timeout == 0, "getsockopt(SO_RCVTIMEO) returned wrong value %d\n", timeout);
1280 /* SO_SNDTIMEO */
1281 timeout = SOCKTIMEOUT2; /* 997 seconds. See remark above */
1282 size = sizeof(timeout);
1283 err = setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, (char *) &timeout, size);
1284 if( !err)
1285 err = getsockopt(s, SOL_SOCKET, SO_SNDTIMEO, (char *) &timeout, &size);
1286 ok( !err, "get/setsockopt(SO_SNDTIMEO) failed error: %d\n", WSAGetLastError());
1287 ok( timeout == SOCKTIMEOUT2, "getsockopt(SO_SNDTIMEO) returned wrong value %d\n", timeout);
1289 /* SO_SNDBUF */
1290 value = 4096;
1291 size = sizeof(value);
1292 err = setsockopt(s, SOL_SOCKET, SO_SNDBUF, (char *)&value, size);
1293 ok( !err, "setsockopt(SO_SNDBUF) failed error: %u\n", WSAGetLastError() );
1294 value = 0xdeadbeef;
1295 err = getsockopt(s, SOL_SOCKET, SO_SNDBUF, (char *)&value, &size);
1296 ok( !err, "getsockopt(SO_SNDBUF) failed error: %u\n", WSAGetLastError() );
1297 ok( value == 4096, "expected 4096, got %lu\n", value );
1299 /* SO_RCVBUF */
1300 value = 4096;
1301 size = sizeof(value);
1302 err = setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&value, size);
1303 ok( !err, "setsockopt(SO_RCVBUF) failed error: %u\n", WSAGetLastError() );
1304 value = 0xdeadbeef;
1305 err = getsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&value, &size);
1306 ok( !err, "getsockopt(SO_RCVBUF) failed error: %u\n", WSAGetLastError() );
1307 ok( value == 4096, "expected 4096, got %lu\n", value );
1309 /* SO_LINGER */
1310 for( i = 0; i < ARRAY_SIZE(linger_testvals);i++) {
1311 size = sizeof(lingval);
1312 lingval = linger_testvals[i];
1313 err = setsockopt(s, SOL_SOCKET, SO_LINGER, (char *)&lingval, size);
1314 ok(!err, "Test %u: failed to set SO_LINGER, error %u\n", i, WSAGetLastError());
1315 err = getsockopt(s, SOL_SOCKET, SO_LINGER, (char *)&lingval, &size);
1316 ok(!err, "Test %u: failed to get SO_LINGER, error %u\n", i, WSAGetLastError());
1317 ok(!lingval.l_onoff == !linger_testvals[i].l_onoff, "Test %u: expected %d, got %d\n",
1318 i, linger_testvals[i].l_onoff, lingval.l_onoff);
1319 if (lingval.l_onoff)
1320 ok(lingval.l_linger == linger_testvals[i].l_linger, "Test %u: expected %d, got %d\n",
1321 i, linger_testvals[i].l_linger, lingval.l_linger);
1324 size = sizeof(lingval);
1325 err = setsockopt(s, SOL_SOCKET, SO_LINGER, NULL, size);
1326 ok(err == SOCKET_ERROR && WSAGetLastError() == WSAEFAULT,
1327 "got %d with %d (expected SOCKET_ERROR with WSAEFAULT)\n", err, WSAGetLastError());
1328 err = setsockopt(s, SOL_SOCKET, SO_LINGER, NULL, 0);
1329 ok(err == SOCKET_ERROR && WSAGetLastError() == WSAEFAULT,
1330 "got %d with %d (expected SOCKET_ERROR with WSAEFAULT)\n", err, WSAGetLastError());
1332 size = sizeof(BOOL);
1333 err = setsockopt(s, SOL_SOCKET, SO_DONTLINGER, NULL, size);
1334 ok(err == SOCKET_ERROR && WSAGetLastError() == WSAEFAULT,
1335 "got %d with %d (expected SOCKET_ERROR with WSAEFAULT)\n", err, WSAGetLastError());
1336 err = setsockopt(s, SOL_SOCKET, SO_DONTLINGER, NULL, 0);
1337 ok(err == SOCKET_ERROR && WSAGetLastError() == WSAEFAULT,
1338 "got %d with %d (expected SOCKET_ERROR with WSAEFAULT)\n", err, WSAGetLastError());
1340 /* TCP_NODELAY: optlen doesn't matter on windows, it should work with any positive value */
1341 size = sizeof(value);
1343 value = 1;
1344 err = setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char*)&value, 1);
1345 ok (!err, "setsockopt TCP_NODELAY failed with optlen == 1\n");
1346 value = 0xff;
1347 err = getsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char*)&value, &size);
1348 ok(!err, "getsockopt TCP_NODELAY failed\n");
1349 ok(value == 1, "TCP_NODELAY should be 1\n");
1350 value = 0;
1351 err = setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char*)&value, sizeof(value));
1352 ok(!err, "Failed to reset TCP_NODELAY to 0\n");
1354 value = 1;
1355 err = setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char*)&value, 4);
1356 ok (!err, "setsockopt TCP_NODELAY failed with optlen == 4\n");
1357 value = 0xff;
1358 err = getsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char*)&value, &size);
1359 ok(!err, "getsockopt TCP_NODELAY failed\n");
1360 ok(value == 1, "TCP_NODELAY should be 1\n");
1361 value = 0;
1362 err = setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char*)&value, sizeof(value));
1363 ok(!err, "Failed to reset TCP_NODELAY to 0\n");
1365 value = 1;
1366 err = setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char*)&value, 42);
1367 ok (!err, "setsockopt TCP_NODELAY failed with optlen == 42\n");
1368 value = 0xff;
1369 err = getsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char*)&value, &size);
1370 ok(!err, "getsockopt TCP_NODELAY failed\n");
1371 ok(value == 1, "TCP_NODELAY should be 1\n");
1372 value = 0;
1373 err = setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char*)&value, sizeof(value));
1374 ok(!err, "Failed to reset TCP_NODELAY to 0\n");
1376 value = 1;
1377 err = setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char*)&value, 0);
1378 ok(err == SOCKET_ERROR && WSAGetLastError() == WSAEFAULT,
1379 "got %d with %d (expected SOCKET_ERROR with WSAEFAULT)\n", err, WSAGetLastError());
1380 value = 0xff;
1381 err = getsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char*)&value, &size);
1382 ok(!err, "getsockopt TCP_NODELAY failed\n");
1383 ok(!value, "TCP_NODELAY should be 0\n");
1385 value = 1;
1386 err = setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char*)&value, -1);
1387 /* On win 10 pro, this sets the error to WSAENOBUFS instead of WSAEFAULT */
1388 ok(err == SOCKET_ERROR && (WSAGetLastError() == WSAEFAULT || WSAGetLastError() == WSAENOBUFS),
1389 "got %d with %d (expected SOCKET_ERROR with either WSAEFAULT or WSAENOBUFS)\n", err, WSAGetLastError());
1390 value = 0xff;
1391 err = getsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char*)&value, &size);
1392 ok(!err, "getsockopt TCP_NODELAY failed\n");
1393 ok(!value, "TCP_NODELAY should be 0\n");
1395 value = 0x100;
1396 err = setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char*)&value, 4);
1397 ok (!err, "setsockopt TCP_NODELAY failed with optlen == 4 and optvalue = 0x100\n");
1398 value = 0xff;
1399 err = getsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char*)&value, &size);
1400 ok(!err, "getsockopt TCP_NODELAY failed\n");
1401 ok(!value, "TCP_NODELAY should be 0\n");
1403 /* Test for erroneously passing a value instead of a pointer as optval */
1404 size = sizeof(char);
1405 err = setsockopt(s, SOL_SOCKET, SO_DONTROUTE, (char *)1, size);
1406 ok(err == SOCKET_ERROR, "setsockopt with optval being a value passed "
1407 "instead of failing.\n");
1408 lasterr = WSAGetLastError();
1409 ok(lasterr == WSAEFAULT, "setsockopt with optval being a value "
1410 "returned 0x%08x, not WSAEFAULT(0x%08x)\n",
1411 lasterr, WSAEFAULT);
1413 /* SO_RCVTIMEO with invalid values for level */
1414 size = sizeof(timeout);
1415 timeout = SOCKTIMEOUT1;
1416 SetLastError(0xdeadbeef);
1417 err = setsockopt(s, 0xffffffff, SO_RCVTIMEO, (char *) &timeout, size);
1418 ok( (err == SOCKET_ERROR) && (WSAGetLastError() == WSAEINVAL),
1419 "got %d with %d (expected SOCKET_ERROR with WSAEINVAL)\n",
1420 err, WSAGetLastError());
1422 timeout = SOCKTIMEOUT1;
1423 SetLastError(0xdeadbeef);
1424 err = setsockopt(s, 0x00008000, SO_RCVTIMEO, (char *) &timeout, size);
1425 ok( (err == SOCKET_ERROR) && (WSAGetLastError() == WSAEINVAL),
1426 "got %d with %d (expected SOCKET_ERROR with WSAEINVAL)\n",
1427 err, WSAGetLastError());
1429 /* Test SO_ERROR set/get */
1430 SetLastError(0xdeadbeef);
1431 i = 1234;
1432 err = setsockopt(s, SOL_SOCKET, SO_ERROR, (char *) &i, size);
1433 todo_wine
1434 ok( !err && !WSAGetLastError(),
1435 "got %d with %d (expected 0 with 0)\n",
1436 err, WSAGetLastError());
1438 SetLastError(0xdeadbeef);
1439 i = 4321;
1440 err = getsockopt(s, SOL_SOCKET, SO_ERROR, (char *) &i, &size);
1441 ok( !err && !WSAGetLastError(),
1442 "got %d with %d (expected 0 with 0)\n",
1443 err, WSAGetLastError());
1444 todo_wine
1445 ok (i == 1234, "got %d (expected 1234)\n", i);
1447 /* Test invalid optlen */
1448 SetLastError(0xdeadbeef);
1449 size = 1;
1450 err = getsockopt(s, SOL_SOCKET, SO_ERROR, (char *) &i, &size);
1451 ok( (err == SOCKET_ERROR) && (WSAGetLastError() == WSAEFAULT),
1452 "got %d with %d (expected SOCKET_ERROR with WSAEFAULT)\n",
1453 err, WSAGetLastError());
1455 closesocket(s);
1457 /* Test option length. */
1458 for (i = 0; i < ARRAY_SIZE(test_optsize); ++i)
1460 winetest_push_context("i %u, level %d, optname %d",
1461 i, test_optsize[i].level, test_optsize[i].optname);
1463 s2 = socket( test_optsize[i].af, test_optsize[i].type, 0 );
1464 ok(s2 != INVALID_SOCKET, "socket() failed error %d\n", WSAGetLastError());
1466 size = sizeof(save_value);
1467 err = getsockopt(s2, test_optsize[i].level, test_optsize[i].optname, (char*)&save_value, &size);
1468 ok(!err, "Unexpected getsockopt result %d.\n", err);
1470 value64 = 0xffffffff00000001;
1471 err = setsockopt(s2, test_optsize[i].level, test_optsize[i].optname, (char *)&value64, sizeof(value64));
1472 ok(!err, "Unexpected setsockopt result %d.\n", err);
1473 ok(!WSAGetLastError(), "Unexpected WSAGetLastError() %u.\n", WSAGetLastError());
1475 size = sizeof(value64);
1476 err = getsockopt(s2, test_optsize[i].level, test_optsize[i].optname, (char*)&value64, &size);
1477 ok(!err, "Unexpected getsockopt result %d.\n", err);
1478 ok(size == test_optsize[i].sizes[2], "Got unexpected size %d.\n", size);
1479 /* The behaviour regarding filling the high dword is different between options without the obvious
1480 * pattern, it is either left untouched (more often) or zeroed. Wine doesn't touch the high dword. */
1482 if (test_optsize[i].sizes[2] == 1 || test_optsize[i].level != SOL_SOCKET)
1484 expected_err = -1;
1485 expected_last_error = WSAENOBUFS;
1487 else
1489 expected_err = 0;
1490 expected_last_error = 0;
1493 value = 1;
1494 err = setsockopt(s2, test_optsize[i].level, test_optsize[i].optname, (char *)&value, -1);
1495 ok(err == expected_err, "Unexpected setsockopt result %d.\n", err);
1496 /* Broken between Win7 and Win10 21H1. */
1497 ok(WSAGetLastError() == expected_last_error || broken(expected_last_error && WSAGetLastError() == WSAEFAULT),
1498 "Unexpected WSAGetLastError() %u.\n", WSAGetLastError());
1500 size = -1;
1501 value = 0xdeadbeef;
1502 err = getsockopt(s2, test_optsize[i].level, test_optsize[i].optname, (char*)&value, &size);
1503 if (test_optsize[i].optname == SO_OPENTYPE)
1505 ok(!err, "Unexpected getsockopt result %d.\n", err);
1506 ok(!WSAGetLastError(), "Unexpected WSAGetLastError() %u.\n", WSAGetLastError());
1508 else
1510 ok(err == -1, "Unexpected getsockopt result %d.\n", err);
1511 ok(WSAGetLastError() == WSAEFAULT, "Unexpected WSAGetLastError() %u.\n", WSAGetLastError());
1513 ok(size == (test_optsize[i].optname == SO_OPENTYPE ? 4 : -1), "Got unexpected size %d.\n", size);
1515 if (test_optsize[i].level == SOL_SOCKET && test_optsize[i].bool_value)
1517 expected_err = 0;
1518 expected_last_error = 0;
1520 else
1522 expected_err = -1;
1523 expected_last_error = WSAEFAULT;
1525 value = 1;
1526 SetLastError(0xdeadbeef);
1527 err = setsockopt(s2, test_optsize[i].level, test_optsize[i].optname, (char*)&value, 0);
1528 ok(err == expected_err, "Unexpected setsockopt result %d.\n", err);
1529 ok(WSAGetLastError() == expected_last_error, "Unexpected WSAGetLastError() %u.\n", WSAGetLastError());
1531 size = 0;
1532 err = getsockopt(s2, test_optsize[i].level, test_optsize[i].optname, (char*)&value, &size);
1533 ok(err == -1, "Unexpected getsockopt result %d.\n", err);
1534 ok(WSAGetLastError() == WSAEFAULT, "Unexpected WSAGetLastError() %u.\n", WSAGetLastError());
1536 expected_size = test_optsize[i].sizes[2];
1537 if (expected_size == 1)
1538 expected_value = 0xdeadbe00;
1539 else
1540 expected_value = test_optsize[i].bool_value ? 0x1 : 0x100;
1541 if (test_optsize[i].accepts_large_value)
1543 expected_err = 0;
1544 expected_last_error = 0;
1546 else
1548 expected_err = -1;
1549 expected_last_error = WSAEINVAL;
1552 value = 0x100;
1553 SetLastError(0xdeadbeef);
1554 err = setsockopt(s2, test_optsize[i].level, test_optsize[i].optname, (char*)&value, 4);
1555 ok(err == expected_err, "Unexpected setsockopt result %d.\n", err);
1556 ok(WSAGetLastError() == expected_last_error, "Unexpected WSAGetLastError() %u.\n", WSAGetLastError());
1558 if (test_optsize[i].accepts_large_value)
1560 value = 0xdeadbeef;
1561 SetLastError(0xdeadbeef);
1562 size = 4;
1563 err = getsockopt(s2, test_optsize[i].level, test_optsize[i].optname, (char*)&value, &size);
1564 ok(err == expected_err, "Unexpected getsockopt result %d.\n", err);
1565 ok(WSAGetLastError() == expected_last_error, "Unexpected WSAGetLastError() %u.\n", WSAGetLastError());
1566 todo_wine_if(test_optsize[i].optname == SO_DONTROUTE || test_optsize[i].optname == SO_LINGER)
1567 ok(value == expected_value, "Got unexpected value %#lx, expected %#lx.\n", value, expected_value);
1568 ok(size == expected_size, "Got unexpected size %u, expected %u.\n", size, expected_size);
1571 winetest_pop_context();
1573 for (j = 0; j < ARRAY_SIZE(test_optsize[i].sizes); ++j)
1575 size = 1 << j;
1576 winetest_push_context("i %u, level %d, optname %d, len %u",
1577 i, test_optsize[i].level, test_optsize[i].optname, size);
1579 value = 1;
1580 if (test_optsize[i].values[j])
1581 expected_value = test_optsize[i].values[j];
1582 else
1583 expected_value = 0xdeadbeef;
1585 if (test_optsize[i].accepts_short_len || size == 4)
1587 expected_err = 0;
1588 expected_last_error = 0;
1589 expected_size = test_optsize[i].sizes[j];
1591 if (!test_optsize[i].values[j])
1592 memcpy(&expected_value, &value, expected_size);
1594 else
1596 expected_err = -1;
1597 expected_last_error = WSAEFAULT;
1598 expected_size = test_optsize[i].sizes[j];
1601 SetLastError(0xdeadbeef);
1602 err = setsockopt(s2, test_optsize[i].level, test_optsize[i].optname, (char*)&value, size);
1603 ok(err == expected_err, "Unexpected setsockopt result %d.\n", err);
1604 ok(WSAGetLastError() == expected_last_error, "Unexpected WSAGetLastError() %u.\n", WSAGetLastError());
1606 value = 0xdeadbeef;
1607 SetLastError(0xdeadbeef);
1608 err = getsockopt(s2, test_optsize[i].level, test_optsize[i].optname, (char*)&value, &size);
1609 ok(err == expected_err, "Unexpected getsockopt result %d.\n", err);
1610 ok(WSAGetLastError() == expected_last_error, "Unexpected WSAGetLastError() %u.\n", WSAGetLastError());
1611 ok(value == expected_value, "Got unexpected value %#lx, expected %#lx.\n", value, expected_value);
1612 ok(size == expected_size, "Got unexpected size %d, expected %d.\n", size, expected_size);
1614 winetest_pop_context();
1617 err = setsockopt(s2, test_optsize[i].level, test_optsize[i].optname,
1618 (char*)&save_value, sizeof(save_value));
1619 ok(!err, "Unexpected getsockopt result %d.\n", err);
1620 closesocket(s2);
1623 /* Test with the closed socket */
1624 SetLastError(0xdeadbeef);
1625 size = sizeof(i);
1626 i = 1234;
1627 err = getsockopt(s, SOL_SOCKET, SO_ERROR, (char *) &i, &size);
1628 ok( (err == SOCKET_ERROR) && (WSAGetLastError() == WSAENOTSOCK),
1629 "got %d with %d (expected SOCKET_ERROR with WSAENOTSOCK)\n",
1630 err, WSAGetLastError());
1631 ok (i == 1234, "expected 1234, got %d\n", i);
1633 /* Test WS_IP_MULTICAST_TTL with 8, 16, 24 and 32 bits values */
1634 s = socket(AF_INET, SOCK_DGRAM, 0);
1635 ok(s != INVALID_SOCKET, "Failed to create socket\n");
1636 size = sizeof(i);
1637 i = 0x0000000a;
1638 err = setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, (char *) &i, size);
1639 if (!err)
1641 for (i = 0; i < 4; i++)
1643 int k, j;
1644 const int tests[] = {0xffffff0a, 0xffff000b, 0xff00000c, 0x0000000d};
1645 err = setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, (char *) &tests[i], i + 1);
1646 ok(!err, "Test [%d] Expected 0, got %d\n", i, err);
1647 err = getsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, (char *) &k, &size);
1648 ok(!err, "Test [%d] Expected 0, got %d\n", i, err);
1649 j = i != 3 ? tests[i] & ((1 << (i + 1) * 8) - 1) : tests[i];
1650 ok(k == j, "Test [%d] Expected 0x%x, got 0x%x\n", i, j, k);
1653 else
1654 win_skip("IP_MULTICAST_TTL is unsupported\n");
1655 closesocket(s);
1657 /* test SO_PROTOCOL_INFOA invalid parameters */
1658 ok(getsockopt(INVALID_SOCKET, SOL_SOCKET, SO_PROTOCOL_INFOA, NULL, NULL),
1659 "getsockopt should have failed\n");
1660 err = WSAGetLastError();
1661 ok(err == WSAENOTSOCK, "expected 10038, got %d instead\n", err);
1662 size = sizeof(WSAPROTOCOL_INFOA);
1663 ok(getsockopt(INVALID_SOCKET, SOL_SOCKET, SO_PROTOCOL_INFOA, (char *) &infoA, &size),
1664 "getsockopt should have failed\n");
1665 ok(size == sizeof(WSAPROTOCOL_INFOA), "got size %d\n", size);
1666 err = WSAGetLastError();
1667 ok(err == WSAENOTSOCK, "expected 10038, got %d instead\n", err);
1668 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1669 ok(getsockopt(s, SOL_SOCKET, SO_PROTOCOL_INFOA, NULL, NULL),
1670 "getsockopt should have failed\n");
1671 err = WSAGetLastError();
1672 ok(err == WSAEFAULT, "expected 10014, got %d instead\n", err);
1673 ok(getsockopt(s, SOL_SOCKET, SO_PROTOCOL_INFOA, (char *) &infoA, NULL),
1674 "getsockopt should have failed\n");
1675 err = WSAGetLastError();
1676 ok(err == WSAEFAULT, "expected 10014, got %d instead\n", err);
1677 ok(getsockopt(s, SOL_SOCKET, SO_PROTOCOL_INFOA, NULL, &size),
1678 "getsockopt should have failed\n");
1679 err = WSAGetLastError();
1680 ok(err == WSAEFAULT, "expected 10014, got %d instead\n", err);
1681 size = sizeof(WSAPROTOCOL_INFOA) / 2;
1682 ok(getsockopt(s, SOL_SOCKET, SO_PROTOCOL_INFOA, (char *) &infoA, &size),
1683 "getsockopt should have failed\n");
1684 err = WSAGetLastError();
1685 ok(err == WSAEFAULT, "expected 10014, got %d instead\n", err);
1686 ok(size == sizeof(WSAPROTOCOL_INFOA), "got size %d\n", size);
1687 size = sizeof(WSAPROTOCOL_INFOA) * 2;
1688 err = getsockopt(s, SOL_SOCKET, SO_PROTOCOL_INFOA, (char *) &infoA, &size);
1689 ok(!err,"getsockopt failed with %d\n", WSAGetLastError());
1690 ok(size == sizeof(WSAPROTOCOL_INFOA) * 2, "got size %d\n", size);
1692 closesocket(s);
1694 /* test SO_PROTOCOL_INFO structure returned for different protocols */
1695 for (i = 0; i < ARRAY_SIZE(prottest); i++)
1697 int k;
1699 s = socket(prottest[i].family, prottest[i].type, prottest[i].proto);
1700 if (s == INVALID_SOCKET && prottest[i].family == AF_INET6) continue;
1702 ok(s != INVALID_SOCKET, "Failed to create socket: %d\n",
1703 WSAGetLastError());
1705 /* compare both A and W version */
1706 infoA.szProtocol[0] = 0;
1707 size = sizeof(WSAPROTOCOL_INFOA);
1708 err = getsockopt(s, SOL_SOCKET, SO_PROTOCOL_INFOA, (char *) &infoA, &size);
1709 ok(!err,"getsockopt failed with %d\n", WSAGetLastError());
1710 ok(size == sizeof(WSAPROTOCOL_INFOA), "got size %d\n", size);
1712 infoW.szProtocol[0] = 0;
1713 size = sizeof(WSAPROTOCOL_INFOW);
1714 err = getsockopt(s, SOL_SOCKET, SO_PROTOCOL_INFOW, (char *) &infoW, &size);
1715 ok(!err,"getsockopt failed with %d\n", WSAGetLastError());
1716 ok(size == sizeof(WSAPROTOCOL_INFOW), "got size %d\n", size);
1718 ok(infoA.szProtocol[0], "WSAPROTOCOL_INFOA was not filled\n");
1719 ok(infoW.szProtocol[0], "WSAPROTOCOL_INFOW was not filled\n");
1721 WideCharToMultiByte(CP_ACP, 0, infoW.szProtocol, -1,
1722 providername, sizeof(providername), NULL, NULL);
1723 ok(!strcmp(infoA.szProtocol,providername),
1724 "different provider names '%s' != '%s'\n", infoA.szProtocol, providername);
1726 ok(!memcmp(&infoA, &infoW, FIELD_OFFSET(WSAPROTOCOL_INFOA, szProtocol)),
1727 "SO_PROTOCOL_INFO[A/W] comparison failed\n");
1729 /* Remove IF when WSAEnumProtocols support IPV6 data */
1730 ok(infoA.iAddressFamily == prottest[i].family, "socket family invalid, expected %d received %d\n",
1731 prottest[i].family, infoA.iAddressFamily);
1732 ok(infoA.iSocketType == prottest[i].type, "socket type invalid, expected %d received %d\n",
1733 prottest[i].type, infoA.iSocketType);
1734 ok(infoA.iProtocol == prottest[i].proto, "socket protocol invalid, expected %d received %d\n",
1735 prottest[i].proto, infoA.iProtocol);
1737 /* IP_HDRINCL is supported only on SOCK_RAW but passed to SOCK_DGRAM by Impossible Creatures */
1738 size = sizeof(i);
1739 k = 1;
1740 SetLastError(0xdeadbeef);
1741 err = setsockopt(s, IPPROTO_IP, IP_HDRINCL, (char *) &k, size);
1742 if (err == -1) /* >= Vista */
1744 ok(GetLastError() == WSAEINVAL, "Expected 10022, got %ld\n", GetLastError());
1745 k = 99;
1746 SetLastError(0xdeadbeef);
1747 err = getsockopt(s, IPPROTO_IP, IP_HDRINCL, (char *) &k, &size);
1748 ok(err == -1, "Expected -1, got %d\n", err);
1749 ok(GetLastError() == WSAEINVAL, "Expected 10022, got %ld\n", GetLastError());
1750 ok(k == 99, "Expected 99, got %d\n", k);
1752 size = sizeof(k);
1753 k = 0;
1754 SetLastError(0xdeadbeef);
1755 err = setsockopt(s, IPPROTO_IP, IP_HDRINCL, (char *) &k, size);
1756 ok(err == -1, "Expected -1, got %d\n", err);
1757 ok(GetLastError() == WSAEINVAL, "Expected 10022, got %ld\n", GetLastError());
1758 k = 99;
1759 SetLastError(0xdeadbeef);
1760 err = getsockopt(s, IPPROTO_IP, IP_HDRINCL, (char *) &k, &size);
1761 ok(err == -1, "Expected -1, got %d\n", err);
1762 ok(GetLastError() == WSAEINVAL, "Expected 10022, got %ld\n", GetLastError());
1763 ok(k == 99, "Expected 99, got %d\n", k);
1765 else /* <= 2003 the tests differ between TCP and UDP, UDP silently accepts */
1767 SetLastError(0xdeadbeef);
1768 k = 99;
1769 err = getsockopt(s, IPPROTO_IP, IP_HDRINCL, (char *) &k, &size);
1770 if (prottest[i].type == SOCK_DGRAM)
1772 ok(err == 0, "Expected 0, got %d\n", err);
1773 ok(k == 1, "Expected 1, got %d\n", k);
1775 else
1777 /* contratry to what we could expect the function returns error but k is changed */
1778 ok(err == -1, "Expected -1, got %d\n", err);
1779 ok(GetLastError() == WSAENOPROTOOPT, "Expected 10042, got %ld\n", GetLastError());
1780 ok(k == 0, "Expected 0, got %d\n", k);
1783 k = 0;
1784 err = setsockopt(s, IPPROTO_IP, IP_HDRINCL, (char *) &k, size);
1785 ok(err == 0, "Expected 0, got %d\n", err);
1787 k = 99;
1788 err = getsockopt(s, IPPROTO_IP, IP_HDRINCL, (char *) &k, &size);
1789 if (prottest[i].type == SOCK_DGRAM)
1791 ok(err == 0, "Expected 0, got %d\n", err);
1792 ok(k == 0, "Expected 0, got %d\n", k);
1794 else
1796 /* contratry to what we could expect the function returns error but k is changed */
1797 ok(err == -1, "Expected -1, got %d\n", err);
1798 ok(GetLastError() == WSAENOPROTOOPT, "Expected 10042, got %ld\n", GetLastError());
1799 ok(k == 0, "Expected 0, got %d\n", k);
1803 closesocket(s);
1806 /* Test SO_BSP_STATE - Present only in >= Win 2008 */
1807 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1808 ok(s != INVALID_SOCKET, "Failed to create socket\n");
1809 s2 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1810 ok(s2 != INVALID_SOCKET, "Failed to create socket\n");
1812 SetLastError(0xdeadbeef);
1813 size = sizeof(csinfoA);
1814 err = getsockopt(s, SOL_SOCKET, SO_BSP_STATE, (char *) &csinfoA, &size);
1815 if (!err)
1817 struct sockaddr_in saddr;
1818 memset(&saddr, 0, sizeof(saddr));
1819 saddr.sin_family = AF_INET;
1820 saddr.sin_addr.s_addr = inet_addr("127.0.0.1");
1822 /* Socket is not bound, no information provided */
1823 ok(!csinfoA.cs.LocalAddr.iSockaddrLength, "Expected 0, got %d\n", csinfoA.cs.LocalAddr.iSockaddrLength);
1824 ok(csinfoA.cs.LocalAddr.lpSockaddr == NULL, "Expected NULL, got %p\n", csinfoA.cs.LocalAddr.lpSockaddr);
1825 /* Socket is not connected, no information provided */
1826 ok(!csinfoA.cs.RemoteAddr.iSockaddrLength, "Expected 0, got %d\n", csinfoA.cs.RemoteAddr.iSockaddrLength);
1827 ok(csinfoA.cs.RemoteAddr.lpSockaddr == NULL, "Expected NULL, got %p\n", csinfoA.cs.RemoteAddr.lpSockaddr);
1829 err = bind(s, (struct sockaddr*)&saddr, sizeof(saddr));
1830 ok(!err, "Expected 0, got %d\n", err);
1831 size = sizeof(csinfoA);
1832 err = getsockopt(s, SOL_SOCKET, SO_BSP_STATE, (char *) &csinfoA, &size);
1833 ok(!err, "Expected 0, got %d\n", err);
1835 /* Socket is bound */
1836 ok(csinfoA.cs.LocalAddr.iSockaddrLength, "Expected non-zero\n");
1837 ok(csinfoA.cs.LocalAddr.lpSockaddr != NULL, "Expected non-null\n");
1838 /* Socket is not connected, no information provided */
1839 ok(!csinfoA.cs.RemoteAddr.iSockaddrLength, "Expected 0, got %d\n", csinfoA.cs.RemoteAddr.iSockaddrLength);
1840 ok(csinfoA.cs.RemoteAddr.lpSockaddr == NULL, "Expected NULL, got %p\n", csinfoA.cs.RemoteAddr.lpSockaddr);
1842 err = bind(s2, (struct sockaddr*)&saddr, sizeof(saddr));
1843 ok(!err, "Expected 0, got %d\n", err);
1844 err = getsockname(s2, (struct sockaddr *)&saddr, &size);
1845 ok(!err, "Expected 0, got %d\n", err);
1846 err = listen(s2, 1);
1847 ok(!err, "Expected 0, got %d\n", err);
1848 err = connect(s, (struct sockaddr*)&saddr, sizeof(saddr));
1849 ok(!err, "Expected 0, got %d\n", err);
1850 size = sizeof(saddr);
1851 err = accept(s2, (struct sockaddr*)&saddr, &size);
1852 ok(err != INVALID_SOCKET, "Failed to accept socket\n");
1853 closesocket(s2);
1854 s2 = err;
1856 size = sizeof(csinfoA);
1857 err = getsockopt(s, SOL_SOCKET, SO_BSP_STATE, (char *) &csinfoA, &size);
1858 ok(!err, "Expected 0, got %d\n", err);
1859 err = getsockopt(s2, SOL_SOCKET, SO_BSP_STATE, (char *) &csinfoB, &size);
1860 ok(!err, "Expected 0, got %d\n", err);
1861 ok(size == sizeof(csinfoA), "Got %d\n", size);
1862 size = sizeof(saddr);
1863 ok(size == csinfoA.cs.LocalAddr.iSockaddrLength, "Expected %d, got %d\n", size,
1864 csinfoA.cs.LocalAddr.iSockaddrLength);
1865 ok(size == csinfoA.cs.RemoteAddr.iSockaddrLength, "Expected %d, got %d\n", size,
1866 csinfoA.cs.RemoteAddr.iSockaddrLength);
1867 ok(!memcmp(csinfoA.cs.LocalAddr.lpSockaddr, csinfoB.cs.RemoteAddr.lpSockaddr, size),
1868 "Expected matching addresses\n");
1869 ok(!memcmp(csinfoB.cs.LocalAddr.lpSockaddr, csinfoA.cs.RemoteAddr.lpSockaddr, size),
1870 "Expected matching addresses\n");
1871 ok(csinfoA.cs.iSocketType == SOCK_STREAM, "Wrong socket type\n");
1872 ok(csinfoB.cs.iSocketType == SOCK_STREAM, "Wrong socket type\n");
1873 ok(csinfoA.cs.iProtocol == IPPROTO_TCP, "Wrong socket protocol\n");
1874 ok(csinfoB.cs.iProtocol == IPPROTO_TCP, "Wrong socket protocol\n");
1876 err = getpeername(s, (struct sockaddr *)&saddr, &size);
1877 ok(!err, "Expected 0, got %d\n", err);
1878 ok(!memcmp(&saddr, csinfoA.cs.RemoteAddr.lpSockaddr, size), "Expected matching addresses\n");
1879 ok(!memcmp(&saddr, csinfoB.cs.LocalAddr.lpSockaddr, size), "Expected matching addresses\n");
1880 err = getpeername(s2, (struct sockaddr *)&saddr, &size);
1881 ok(!err, "Expected 0, got %d\n", err);
1882 ok(!memcmp(&saddr, csinfoB.cs.RemoteAddr.lpSockaddr, size), "Expected matching addresses\n");
1883 ok(!memcmp(&saddr, csinfoA.cs.LocalAddr.lpSockaddr, size), "Expected matching addresses\n");
1884 err = getsockname(s, (struct sockaddr *)&saddr, &size);
1885 ok(!err, "Expected 0, got %d\n", err);
1886 ok(!memcmp(&saddr, csinfoA.cs.LocalAddr.lpSockaddr, size), "Expected matching addresses\n");
1887 ok(!memcmp(&saddr, csinfoB.cs.RemoteAddr.lpSockaddr, size), "Expected matching addresses\n");
1888 err = getsockname(s2, (struct sockaddr *)&saddr, &size);
1889 ok(!err, "Expected 0, got %d\n", err);
1890 ok(!memcmp(&saddr, csinfoB.cs.LocalAddr.lpSockaddr, size), "Expected matching addresses\n");
1891 ok(!memcmp(&saddr, csinfoA.cs.RemoteAddr.lpSockaddr, size), "Expected matching addresses\n");
1893 SetLastError(0xdeadbeef);
1894 size = sizeof(CSADDR_INFO);
1895 err = getsockopt(s, SOL_SOCKET, SO_BSP_STATE, (char *) &csinfoA, &size);
1896 ok(err, "Expected non-zero\n");
1897 ok(size == sizeof(CSADDR_INFO), "Got %d\n", size);
1898 ok(GetLastError() == WSAEFAULT, "Expected 10014, got %ld\n", GetLastError());
1900 /* At least for IPv4 the size is exactly 56 bytes */
1901 size = sizeof(*csinfoA.cs.LocalAddr.lpSockaddr) * 2 + sizeof(csinfoA.cs);
1902 err = getsockopt(s, SOL_SOCKET, SO_BSP_STATE, (char *) &csinfoA, &size);
1903 ok(!err, "Expected 0, got %d\n", err);
1904 size--;
1905 SetLastError(0xdeadbeef);
1906 err = getsockopt(s, SOL_SOCKET, SO_BSP_STATE, (char *) &csinfoA, &size);
1907 ok(err, "Expected non-zero\n");
1908 ok(GetLastError() == WSAEFAULT, "Expected 10014, got %ld\n", GetLastError());
1910 else
1911 ok(GetLastError() == WSAENOPROTOOPT, "Expected 10042, got %ld\n", GetLastError());
1913 closesocket(s);
1914 closesocket(s2);
1916 for (i = 0; i < 2; i++)
1918 int family, level;
1920 if (i)
1922 family = AF_INET6;
1923 level = IPPROTO_IPV6;
1925 else
1927 family = AF_INET;
1928 level = IPPROTO_IP;
1931 s = socket(family, SOCK_DGRAM, 0);
1932 if (s == INVALID_SOCKET && i)
1934 skip("IPv6 is not supported\n");
1935 break;
1937 ok(s != INVALID_SOCKET, "socket failed with error %ld\n", GetLastError());
1939 size = sizeof(value);
1940 value = 0xdead;
1941 err = getsockopt(s, level, IP_DONTFRAGMENT, (char *) &value, &size);
1942 ok(!err, "Expected 0, got %d with error %ld\n", err, GetLastError());
1943 ok(value == 0, "Expected 0, got %ld\n", value);
1945 size = sizeof(value);
1946 value = 1;
1947 err = setsockopt(s, level, IP_DONTFRAGMENT, (char *) &value, size);
1948 ok(!err, "Expected 0, got %d with error %ld\n", err, GetLastError());
1950 value = 0xdead;
1951 err = getsockopt(s, level, IP_DONTFRAGMENT, (char *) &value, &size);
1952 ok(!err, "Expected 0, got %d with error %ld\n", err, GetLastError());
1953 ok(value == 1, "Expected 1, got %ld\n", value);
1955 size = sizeof(value);
1956 value = 0xdead;
1957 err = setsockopt(s, level, IP_DONTFRAGMENT, (char *) &value, size);
1958 ok(!err, "Expected 0, got %d with error %ld\n", err, GetLastError());
1960 err = getsockopt(s, level, IP_DONTFRAGMENT, (char *) &value, &size);
1961 ok(!err, "Expected 0, got %d with error %ld\n", err, GetLastError());
1962 ok(value == 1, "Expected 1, got %ld\n", value);
1964 closesocket(s);
1966 s = socket(family, SOCK_STREAM, 0);
1967 ok(s != INVALID_SOCKET, "socket failed with error %ld\n", GetLastError());
1969 size = sizeof(value);
1970 value = 0xdead;
1971 err = getsockopt(s, level, IP_DONTFRAGMENT, (char *) &value, &size);
1972 ok(!err, "Expected 0, got %d with error %ld\n", err, GetLastError());
1973 ok(value == 1 || broken(value == 0) /* < vista */, "Expected 1, got %ld\n", value);
1975 size = sizeof(value);
1976 value = 0;
1977 err = setsockopt(s, level, IP_DONTFRAGMENT, (char *) &value, size);
1978 ok(!err, "Expected 0, got %d with error %ld\n", err, GetLastError());
1980 value = 0xdead;
1981 err = getsockopt(s, level, IP_DONTFRAGMENT, (char *) &value, &size);
1982 ok(!err, "Expected 0, got %d with error %ld\n", err, GetLastError());
1983 ok(value == 0, "Expected 0, got %ld\n", value);
1985 closesocket(s);
1987 s = socket(family, SOCK_RAW, 0);
1988 if (s == INVALID_SOCKET)
1990 if (WSAGetLastError() == WSAEACCES) skip("SOCK_RAW is not available\n");
1991 else if (i) skip("IPv6 is not supported\n");
1992 break;
1994 ok(s != INVALID_SOCKET, "socket failed with error %ld\n", GetLastError());
1996 size = sizeof(value);
1997 value = 0xdead;
1998 err = getsockopt(s, level, IP_DONTFRAGMENT, (char *) &value, &size);
1999 ok(!err, "Expected 0, got %d with error %ld\n", err, GetLastError());
2000 ok(value == 0, "Expected 0, got %ld\n", value);
2002 size = sizeof(value);
2003 value = 1;
2004 err = setsockopt(s, level, IP_DONTFRAGMENT, (char *) &value, size);
2005 ok(!err, "Expected 0, got %d with error %ld\n", err, GetLastError());
2007 value = 0xdead;
2008 err = getsockopt(s, level, IP_DONTFRAGMENT, (char *) &value, &size);
2009 ok(!err, "Expected 0, got %d with error %ld\n", err, GetLastError());
2010 ok(value == 1, "Expected 1, got %ld\n", value);
2012 closesocket(s);
2016 static void test_so_reuseaddr(void)
2018 struct sockaddr_in saddr;
2019 SOCKET s1,s2;
2020 unsigned int rc,reuse;
2021 int size;
2022 DWORD err;
2024 saddr.sin_family = AF_INET;
2025 saddr.sin_port = htons(SERVERPORT+1);
2026 saddr.sin_addr.s_addr = inet_addr("127.0.0.1");
2028 s1=socket(AF_INET, SOCK_STREAM, 0);
2029 ok(s1!=INVALID_SOCKET, "socket() failed error: %d\n", WSAGetLastError());
2030 rc = bind(s1, (struct sockaddr*)&saddr, sizeof(saddr));
2031 ok(rc!=SOCKET_ERROR, "bind(s1) failed error: %d\n", WSAGetLastError());
2033 s2=socket(AF_INET, SOCK_STREAM, 0);
2034 ok(s2!=INVALID_SOCKET, "socket() failed error: %d\n", WSAGetLastError());
2036 reuse=0x1234;
2037 size=sizeof(reuse);
2038 rc=getsockopt(s2, SOL_SOCKET, SO_REUSEADDR, (char*)&reuse, &size );
2039 ok(rc==0 && reuse==0,"wrong result in getsockopt(SO_REUSEADDR): rc=%d reuse=%d\n",rc,reuse);
2041 rc = bind(s2, (struct sockaddr*)&saddr, sizeof(saddr));
2042 ok(rc==SOCKET_ERROR, "bind() succeeded\n");
2044 reuse = 1;
2045 rc = setsockopt(s2, SOL_SOCKET, SO_REUSEADDR, (char*)&reuse, sizeof(reuse));
2046 ok(rc==0, "setsockopt() failed error: %d\n", WSAGetLastError());
2048 /* On Win2k3 and above, all SO_REUSEADDR seems to do is to allow binding to
2049 * a port immediately after closing another socket on that port, so
2050 * basically following the BSD socket semantics here. */
2051 rc = bind(s2, (struct sockaddr*)&saddr, sizeof(saddr));
2052 if(rc==0)
2054 int s3=socket(AF_INET, SOCK_STREAM, 0), s4;
2056 /* If we could bind again in the same port this is Windows version <= XP.
2057 * Lets test if we can really connect to one of them. */
2058 set_blocking(s1, FALSE);
2059 set_blocking(s2, FALSE);
2060 rc = listen(s1, 1);
2061 ok(!rc, "listen() failed with error: %d\n", WSAGetLastError());
2062 rc = listen(s2, 1);
2063 ok(!rc, "listen() failed with error: %d\n", WSAGetLastError());
2064 rc = connect(s3, (struct sockaddr*)&saddr, sizeof(saddr));
2065 ok(!rc, "connecting to accepting socket failed %d\n", WSAGetLastError());
2067 /* the delivery of the connection is random so we need to try on both sockets */
2068 size = sizeof(saddr);
2069 s4 = accept(s1, (struct sockaddr*)&saddr, &size);
2070 if(s4 == INVALID_SOCKET)
2071 s4 = accept(s2, (struct sockaddr*)&saddr, &size);
2072 ok(s4 != INVALID_SOCKET, "none of the listening sockets could get the connection\n");
2074 closesocket(s1);
2075 closesocket(s3);
2076 closesocket(s4);
2078 else
2080 err = WSAGetLastError();
2081 ok(err==WSAEACCES, "expected 10013, got %ld\n", err);
2083 closesocket(s1);
2084 rc = bind(s2, (struct sockaddr*)&saddr, sizeof(saddr));
2085 ok(rc==0, "bind() failed error: %d\n", WSAGetLastError());
2088 closesocket(s2);
2091 #define IP_PKTINFO_LEN (sizeof(WSACMSGHDR) + WSA_CMSG_ALIGN(sizeof(struct in_pktinfo)))
2093 static unsigned int got_ip_pktinfo_apc;
2095 static void WINAPI ip_pktinfo_apc(DWORD error, DWORD size, OVERLAPPED *overlapped, DWORD flags)
2097 ok(error == WSAEMSGSIZE, "got error %lu\n", error);
2098 ok(size == 6, "got size %lu\n", size);
2099 ok(!flags, "got flags %#lx\n", flags);
2100 ++got_ip_pktinfo_apc;
2103 static void test_ip_pktinfo(void)
2105 ULONG addresses[2] = {inet_addr("127.0.0.1"), htonl(INADDR_ANY)};
2106 char recvbuf[10], pktbuf[512], msg[] = "HELLO";
2107 struct sockaddr_in s1addr, s2addr, s3addr;
2108 LPFN_WSARECVMSG pWSARecvMsg = NULL;
2109 unsigned int rc, yes = 1;
2110 BOOL foundhdr;
2111 DWORD dwBytes, dwSize, dwFlags;
2112 socklen_t addrlen;
2113 WSACMSGHDR *cmsg;
2114 WSAOVERLAPPED ov;
2115 WSABUF iovec[1];
2116 SOCKET s1, s2;
2117 WSAMSG hdr;
2118 int i, err;
2120 memset(&ov, 0, sizeof(ov));
2121 ov.hEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
2123 memset(&hdr, 0x00, sizeof(hdr));
2124 s1addr.sin_family = AF_INET;
2125 s1addr.sin_port = htons(0);
2126 /* Note: s1addr.sin_addr is set below */
2127 iovec[0].buf = recvbuf;
2128 iovec[0].len = sizeof(recvbuf);
2129 hdr.name = (struct sockaddr*)&s3addr;
2130 hdr.namelen = sizeof(s3addr);
2131 hdr.lpBuffers = &iovec[0];
2132 hdr.dwBufferCount = 1;
2133 hdr.Control.buf = pktbuf;
2134 /* Note: hdr.Control.len is set below */
2135 hdr.dwFlags = 0;
2137 for (i=0;i<ARRAY_SIZE(addresses);i++)
2139 s1addr.sin_addr.s_addr = addresses[i];
2141 /* Build "server" side socket */
2142 s1=socket(AF_INET, SOCK_DGRAM, 0);
2143 ok(s1 != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
2145 /* Obtain the WSARecvMsg function */
2146 rc = WSAIoctl(s1, SIO_GET_EXTENSION_FUNCTION_POINTER, &WSARecvMsg_GUID, sizeof(WSARecvMsg_GUID),
2147 &pWSARecvMsg, sizeof(pWSARecvMsg), &dwBytes, NULL, NULL);
2148 ok(!rc, "failed to get WSARecvMsg, error %u\n", WSAGetLastError());
2150 /* Setup the server side socket */
2151 rc=bind(s1, (struct sockaddr*)&s1addr, sizeof(s1addr));
2152 ok(rc != SOCKET_ERROR, "bind() failed error: %d\n", WSAGetLastError());
2154 /* Build "client" side socket */
2155 addrlen = sizeof(s2addr);
2156 rc = getsockname(s1, (struct sockaddr *) &s2addr, &addrlen);
2157 ok(!rc, "failed to get address, error %u\n", WSAGetLastError());
2158 s2addr.sin_addr.s_addr = addresses[0]; /* Always target the local adapter address */
2159 s2=socket(AF_INET, SOCK_DGRAM, 0);
2160 ok(s2 != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
2162 /* Test an empty message header */
2163 rc=pWSARecvMsg(s1, NULL, NULL, NULL, NULL);
2164 err=WSAGetLastError();
2165 ok(rc == SOCKET_ERROR && err == WSAEFAULT, "WSARecvMsg() failed error: %d (ret = %d)\n", err, rc);
2167 /* Test that when no control data arrives, a 0-length NULL-valued control buffer should succeed */
2168 SetLastError(0xdeadbeef);
2169 rc=sendto(s2, msg, sizeof(msg), 0, (struct sockaddr*)&s2addr, sizeof(s2addr));
2170 ok(rc == sizeof(msg), "sendto() failed error: %d\n", WSAGetLastError());
2171 ok(GetLastError() == ERROR_SUCCESS, "Expected 0, got %ld\n", GetLastError());
2172 hdr.Control.buf = NULL;
2173 hdr.Control.len = 0;
2174 rc=pWSARecvMsg(s1, &hdr, &dwSize, NULL, NULL);
2175 ok(rc == 0, "WSARecvMsg() failed error: %d\n", WSAGetLastError());
2176 hdr.Control.buf = pktbuf;
2178 /* Now start IP_PKTINFO for future tests */
2179 rc=setsockopt(s1, IPPROTO_IP, IP_PKTINFO, (const char*)&yes, sizeof(yes));
2180 ok(rc == 0, "failed to set IPPROTO_IP flag IP_PKTINFO!\n");
2183 * Send a packet from the client to the server and test for specifying
2184 * a short control header.
2186 SetLastError(0xdeadbeef);
2187 rc=sendto(s2, msg, sizeof(msg), 0, (struct sockaddr*)&s2addr, sizeof(s2addr));
2188 ok(rc == sizeof(msg), "sendto() failed error: %d\n", WSAGetLastError());
2189 ok(GetLastError() == ERROR_SUCCESS, "Expected 0, got %ld\n", GetLastError());
2190 hdr.Control.len = 1;
2191 dwSize = 0xdeadbeef;
2192 rc = pWSARecvMsg(s1, &hdr, &dwSize, NULL, NULL);
2193 ok(rc == -1, "expected failure\n");
2194 ok(WSAGetLastError() == WSAEMSGSIZE, "got error %u\n", WSAGetLastError());
2195 todo_wine ok(dwSize == sizeof(msg), "got size %lu\n", dwSize);
2196 ok(hdr.dwFlags == MSG_CTRUNC, "got flags %#lx\n", hdr.dwFlags);
2197 hdr.dwFlags = 0; /* Reset flags */
2199 /* Perform another short control header test, this time with an overlapped receive */
2200 hdr.Control.len = 1;
2201 ov.Internal = 0xdead1;
2202 ov.InternalHigh = 0xdead2;
2203 ov.Offset = 0xdead3;
2204 ov.OffsetHigh = 0xdead4;
2205 rc=pWSARecvMsg(s1, &hdr, NULL, &ov, NULL);
2206 err=WSAGetLastError();
2207 ok(rc != 0 && err == WSA_IO_PENDING, "WSARecvMsg() failed error: %d\n", err);
2208 SetLastError(0xdeadbeef);
2209 rc=sendto(s2, msg, sizeof(msg), 0, (struct sockaddr*)&s2addr, sizeof(s2addr));
2210 ok(rc == sizeof(msg), "sendto() failed error: %d\n", WSAGetLastError());
2211 ok(GetLastError() == ERROR_SUCCESS, "Expected 0, got %ld\n", GetLastError());
2212 ok(!WaitForSingleObject(ov.hEvent, 100), "wait failed\n");
2213 ok((NTSTATUS)ov.Internal == STATUS_BUFFER_OVERFLOW, "got status %#lx\n", (NTSTATUS)ov.Internal);
2214 ok(ov.InternalHigh == sizeof(msg), "got size %Iu\n", ov.InternalHigh);
2215 ok(ov.Offset == 0xdead3, "got Offset %lu\n", ov.Offset);
2216 ok(ov.OffsetHigh == 0xdead4, "got OffsetHigh %lu\n", ov.OffsetHigh);
2217 dwFlags = 0xdeadbeef;
2218 rc = WSAGetOverlappedResult(s1, &ov, &dwSize, FALSE, &dwFlags);
2219 ok(!rc, "expected failure\n");
2220 ok(WSAGetLastError() == WSAEMSGSIZE, "got error %u\n", WSAGetLastError());
2221 ok(dwSize == sizeof(msg), "got size %lu\n", dwSize);
2222 todo_wine ok(dwFlags == 0xdeadbeef, "got flags %#lx\n", dwFlags);
2223 ok(hdr.dwFlags == MSG_CTRUNC,
2224 "WSARecvMsg() overlapped operation set unexpected flags %ld.\n", hdr.dwFlags);
2225 hdr.dwFlags = 0; /* Reset flags */
2227 /* And with an APC. */
2229 SetLastError(0xdeadbeef);
2230 rc = sendto(s2, msg, sizeof(msg), 0, (struct sockaddr *)&s2addr, sizeof(s2addr));
2231 ok(rc == sizeof(msg), "sendto() failed error: %d\n", WSAGetLastError());
2232 ok(GetLastError() == ERROR_SUCCESS, "Expected 0, got %ld\n", GetLastError());
2233 hdr.Control.len = 1;
2235 ov.Internal = 0xdead1;
2236 ov.InternalHigh = 0xdead2;
2237 ov.Offset = 0xdead3;
2238 ov.OffsetHigh = 0xdead4;
2239 dwSize = 0xdeadbeef;
2240 rc = pWSARecvMsg(s1, &hdr, NULL, &ov, ip_pktinfo_apc);
2241 ok(rc == -1, "expected failure\n");
2242 todo_wine ok(WSAGetLastError() == ERROR_IO_PENDING, "got error %u\n", WSAGetLastError());
2244 rc = SleepEx(1000, TRUE);
2245 ok(rc == WAIT_IO_COMPLETION, "got %d\n", rc);
2246 ok(got_ip_pktinfo_apc == 1, "apc was called %u times\n", got_ip_pktinfo_apc);
2247 ok(hdr.dwFlags == MSG_CTRUNC, "got flags %#lx\n", hdr.dwFlags);
2248 got_ip_pktinfo_apc = 0;
2250 hdr.dwFlags = 0; /* Reset flags */
2253 * Setup an overlapped receive, send a packet, then wait for the packet to be retrieved
2254 * on the server end and check that the returned packet matches what was sent.
2256 hdr.Control.len = sizeof(pktbuf);
2257 rc=pWSARecvMsg(s1, &hdr, NULL, &ov, NULL);
2258 err=WSAGetLastError();
2259 ok(rc != 0 && err == WSA_IO_PENDING, "WSARecvMsg() failed error: %d\n", err);
2260 ok(hdr.Control.len == sizeof(pktbuf),
2261 "WSARecvMsg() control length mismatch (%ld != sizeof pktbuf).\n", hdr.Control.len);
2262 rc=sendto(s2, msg, sizeof(msg), 0, (struct sockaddr*)&s2addr, sizeof(s2addr));
2263 ok(rc == sizeof(msg), "sendto() failed error: %d\n", WSAGetLastError());
2264 ok(!WaitForSingleObject(ov.hEvent, 100), "wait failed\n");
2265 dwSize = 0;
2266 WSAGetOverlappedResult(s1, &ov, &dwSize, FALSE, NULL);
2267 ok(dwSize == sizeof(msg),
2268 "WSARecvMsg() buffer length does not match transmitted data!\n");
2269 ok(strncmp(iovec[0].buf, msg, sizeof(msg)) == 0,
2270 "WSARecvMsg() buffer does not match transmitted data!\n");
2271 ok(hdr.Control.len == IP_PKTINFO_LEN,
2272 "WSARecvMsg() control length mismatch (%ld).\n", hdr.Control.len);
2274 /* Test for the expected IP_PKTINFO return information. */
2275 foundhdr = FALSE;
2276 for (cmsg = WSA_CMSG_FIRSTHDR(&hdr); cmsg != NULL; cmsg = WSA_CMSG_NXTHDR(&hdr, cmsg))
2278 if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO)
2280 struct in_pktinfo *pi = (struct in_pktinfo *)WSA_CMSG_DATA(cmsg);
2282 ok(pi->ipi_addr.s_addr == s2addr.sin_addr.s_addr, "destination ip mismatch!\n");
2283 foundhdr = TRUE;
2286 ok(foundhdr, "IP_PKTINFO header information was not returned!\n");
2288 closesocket(s2);
2289 closesocket(s1);
2292 CloseHandle(ov.hEvent);
2295 static void test_ipv4_cmsg(void)
2297 static const DWORD off = 0;
2298 static const DWORD on = 1;
2299 SOCKADDR_IN localhost = {0};
2300 SOCKET client, server;
2301 char payload[] = "HELLO";
2302 char control[100];
2303 WSABUF payload_buf = {sizeof(payload), payload};
2304 WSAMSG msg = {NULL, 0, &payload_buf, 1, {sizeof(control), control}, 0};
2305 WSACMSGHDR *header = (WSACMSGHDR *)control;
2306 LPFN_WSARECVMSG pWSARecvMsg;
2307 INT *int_data = (INT *)WSA_CMSG_DATA(header);
2308 IN_PKTINFO *pkt_info = (IN_PKTINFO *)WSA_CMSG_DATA(header);
2309 DWORD count, state;
2310 int rc;
2312 localhost.sin_family = AF_INET;
2313 localhost.sin_port = htons(SERVERPORT);
2314 inet_pton(AF_INET, "127.0.0.1", &localhost.sin_addr);
2316 client = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
2317 ok(client != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
2318 server = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
2319 ok(server != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
2321 rc = bind(server, (SOCKADDR *)&localhost, sizeof(localhost));
2322 ok(rc != SOCKET_ERROR, "bind failed, error %u\n", WSAGetLastError());
2323 rc = connect(client, (SOCKADDR *)&localhost, sizeof(localhost));
2324 ok(rc != SOCKET_ERROR, "connect failed, error %u\n", WSAGetLastError());
2326 rc = WSAIoctl(server, SIO_GET_EXTENSION_FUNCTION_POINTER, &WSARecvMsg_GUID, sizeof(WSARecvMsg_GUID),
2327 &pWSARecvMsg, sizeof(pWSARecvMsg), &count, NULL, NULL);
2328 ok(!rc, "failed to get WSARecvMsg, error %u\n", WSAGetLastError());
2330 memset(control, 0, sizeof(control));
2331 msg.Control.len = sizeof(control);
2332 rc = setsockopt(server, IPPROTO_IP, IP_RECVTTL, (const char *)&on, sizeof(on));
2333 ok(!rc, "failed to set IP_RECVTTL, error %u\n", WSAGetLastError());
2334 state = 0;
2335 count = sizeof(state);
2336 rc = getsockopt(server, IPPROTO_IP, IP_RECVTTL, (char *)&state, (INT *)&count);
2337 ok(!rc, "failed to get IP_RECVTTL, error %u\n", WSAGetLastError());
2338 ok(state == 1, "expected 1, got %lu\n", state);
2339 rc = send(client, payload, sizeof(payload), 0);
2340 ok(rc == sizeof(payload), "send failed, error %u\n", WSAGetLastError());
2341 rc = pWSARecvMsg(server, &msg, &count, NULL, NULL);
2342 ok(!rc, "WSARecvMsg failed, error %u\n", WSAGetLastError());
2343 ok(count == sizeof(payload), "expected length %Iu, got %lu\n", sizeof(payload), count);
2344 ok(header->cmsg_level == IPPROTO_IP, "expected IPPROTO_IP, got %i\n", header->cmsg_level);
2345 ok(header->cmsg_type == IP_TTL || broken(header->cmsg_type == IP_HOPLIMIT) /* <= win10 v1607 */,
2346 "expected IP_TTL, got %i\n", header->cmsg_type);
2347 ok(header->cmsg_len == sizeof(*header) + sizeof(INT),
2348 "expected length %Iu, got %Iu\n", sizeof(*header) + sizeof(INT), header->cmsg_len);
2349 ok(*int_data >= 32, "expected at least 32, got %i\n", *int_data);
2350 setsockopt(server, IPPROTO_IP, IP_RECVTTL, (const char *)&off, sizeof(off));
2351 ok(!rc, "failed to clear IP_RECVTTL, error %u\n", WSAGetLastError());
2353 memset(control, 0, sizeof(control));
2354 msg.Control.len = sizeof(control);
2355 rc = setsockopt(server, IPPROTO_IP, IP_PKTINFO, (const char *)&on, sizeof(on));
2356 ok(!rc, "failed to set IP_PKTINFO, error %u\n", WSAGetLastError());
2357 state = 0;
2358 count = sizeof(state);
2359 rc = getsockopt(server, IPPROTO_IP, IP_PKTINFO, (char *)&state, (INT *)&count);
2360 ok(!rc, "failed to get IP_PKTINFO, error %u\n", WSAGetLastError());
2361 ok(state == 1, "expected 1, got %lu\n", state);
2362 rc = send(client, payload, sizeof(payload), 0);
2363 ok(rc == sizeof(payload), "send failed, error %u\n", WSAGetLastError());
2364 rc = pWSARecvMsg(server, &msg, &count, NULL, NULL);
2365 ok(!rc, "WSARecvMsg failed, error %u\n", WSAGetLastError());
2366 ok(count == sizeof(payload), "expected length %Iu, got %lu\n", sizeof(payload), count);
2367 ok(header->cmsg_level == IPPROTO_IP, "expected IPPROTO_IP, got %i\n", header->cmsg_level);
2368 ok(header->cmsg_type == IP_PKTINFO, "expected IP_PKTINFO, got %i\n", header->cmsg_type);
2369 ok(header->cmsg_len == sizeof(*header) + sizeof(IN_PKTINFO),
2370 "expected length %Iu, got %Iu\n", sizeof(*header) + sizeof(IN_PKTINFO), header->cmsg_len);
2371 ok(!memcmp(&pkt_info->ipi_addr, &localhost.sin_addr, sizeof(IN_ADDR)), "expected 127.0.0.1\n");
2372 rc = setsockopt(server, IPPROTO_IP, IP_PKTINFO, (const char *)&off, sizeof(off));
2373 ok(!rc, "failed to clear IP_PKTINFO, error %u\n", WSAGetLastError());
2375 memset(control, 0, sizeof(control));
2376 msg.Control.len = sizeof(control);
2377 rc = setsockopt(server, IPPROTO_IP, IP_RECVTOS, (const char *)&on, sizeof(on));
2378 ok(!rc, "failed to set IP_RECVTOS, error %u\n", WSAGetLastError());
2379 state = 0;
2380 count = sizeof(state);
2381 rc = getsockopt(server, IPPROTO_IP, IP_RECVTOS, (char *)&state, (INT *)&count);
2382 ok(!rc, "failed to get IP_RECVTOS, error %u\n", WSAGetLastError());
2383 ok(state == 1, "expected 1, got %lu\n", state);
2384 rc = send(client, payload, sizeof(payload), 0);
2385 ok(rc == sizeof(payload), "send failed, error %u\n", WSAGetLastError());
2386 rc = pWSARecvMsg(server, &msg, &count, NULL, NULL);
2387 ok(!rc, "WSARecvMsg failed, error %u\n", WSAGetLastError());
2388 ok(count == sizeof(payload), "expected length %Iu, got %lu\n", sizeof(payload), count);
2389 ok(header->cmsg_level == IPPROTO_IP, "expected IPPROTO_IP, got %i\n", header->cmsg_level);
2390 ok(header->cmsg_type == IP_TOS || broken(header->cmsg_type == IP_TCLASS) /* <= win10 v1607 */,
2391 "expected IP_TOS, got %i\n", header->cmsg_type);
2392 ok(header->cmsg_len == sizeof(*header) + sizeof(INT),
2393 "expected length %Iu, got %Iu\n", sizeof(*header) + sizeof(INT), header->cmsg_len);
2394 ok(*int_data == 0, "expected 0, got %i\n", *int_data);
2395 rc = setsockopt(server, IPPROTO_IP, IP_RECVTOS, (const char *)&off, sizeof(off));
2396 ok(!rc, "failed to clear IP_RECVTOS, error %u\n", WSAGetLastError());
2398 closesocket(server);
2399 closesocket(client);
2402 static void test_ipv6_cmsg(void)
2404 static const DWORD off = 0;
2405 static const DWORD on = 1;
2406 SOCKADDR_IN6 localhost = {0};
2407 SOCKET client, server;
2408 char payload[] = "HELLO";
2409 char control[100];
2410 WSABUF payload_buf = {sizeof(payload), payload};
2411 WSAMSG msg = {NULL, 0, &payload_buf, 1, {sizeof(control), control}, 0};
2412 WSACMSGHDR *header = (WSACMSGHDR *)control;
2413 LPFN_WSARECVMSG pWSARecvMsg;
2414 INT *int_data = (INT *)WSA_CMSG_DATA(header);
2415 IN6_PKTINFO *pkt_info = (IN6_PKTINFO *)WSA_CMSG_DATA(header);
2416 DWORD count, state;
2417 int rc;
2419 localhost.sin6_family = AF_INET6;
2420 localhost.sin6_port = htons(SERVERPORT);
2421 inet_pton(AF_INET6, "::1", &localhost.sin6_addr);
2423 client = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
2424 ok(client != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
2425 server = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
2426 ok(server != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
2428 rc = bind(server, (SOCKADDR *)&localhost, sizeof(localhost));
2429 ok(rc != SOCKET_ERROR, "bind failed, error %u\n", WSAGetLastError());
2430 rc = connect(client, (SOCKADDR *)&localhost, sizeof(localhost));
2431 ok(rc != SOCKET_ERROR, "connect failed, error %u\n", WSAGetLastError());
2433 rc = WSAIoctl(server, SIO_GET_EXTENSION_FUNCTION_POINTER, &WSARecvMsg_GUID, sizeof(WSARecvMsg_GUID),
2434 &pWSARecvMsg, sizeof(pWSARecvMsg), &count, NULL, NULL);
2435 ok(!rc, "failed to get WSARecvMsg, error %u\n", WSAGetLastError());
2437 memset(control, 0, sizeof(control));
2438 msg.Control.len = sizeof(control);
2439 rc = setsockopt(server, IPPROTO_IPV6, IPV6_HOPLIMIT, (const char *)&on, sizeof(on));
2440 ok(!rc, "failed to set IPV6_HOPLIMIT, error %u\n", WSAGetLastError());
2441 state = 0;
2442 count = sizeof(state);
2443 rc = getsockopt(server, IPPROTO_IPV6, IPV6_HOPLIMIT, (char *)&state, (INT *)&count);
2444 ok(!rc, "failed to get IPV6_HOPLIMIT, error %u\n", WSAGetLastError());
2445 ok(state == 1, "expected 1, got %lu\n", state);
2446 rc = send(client, payload, sizeof(payload), 0);
2447 ok(rc == sizeof(payload), "send failed, error %u\n", WSAGetLastError());
2448 rc = pWSARecvMsg(server, &msg, &count, NULL, NULL);
2449 ok(!rc, "WSARecvMsg failed, error %u\n", WSAGetLastError());
2450 ok(count == sizeof(payload), "expected length %Iu, got %lu\n", sizeof(payload), count);
2451 ok(header->cmsg_level == IPPROTO_IPV6, "expected IPPROTO_IPV6, got %i\n", header->cmsg_level);
2452 ok(header->cmsg_type == IPV6_HOPLIMIT, "expected IPV6_HOPLIMIT, got %i\n", header->cmsg_type);
2453 ok(header->cmsg_len == sizeof(*header) + sizeof(INT),
2454 "expected length %Iu, got %Iu\n", sizeof(*header) + sizeof(INT), header->cmsg_len);
2455 ok(*int_data >= 32, "expected at least 32, got %i\n", *int_data);
2456 setsockopt(server, IPPROTO_IPV6, IPV6_HOPLIMIT, (const char *)&off, sizeof(off));
2457 ok(!rc, "failed to clear IPV6_HOPLIMIT, error %u\n", WSAGetLastError());
2459 memset(control, 0, sizeof(control));
2460 msg.Control.len = sizeof(control);
2461 rc = setsockopt(server, IPPROTO_IPV6, IPV6_PKTINFO, (const char *)&on, sizeof(on));
2462 ok(!rc, "failed to set IPV6_PKTINFO, error %u\n", WSAGetLastError());
2463 state = 0;
2464 count = sizeof(state);
2465 rc = getsockopt(server, IPPROTO_IPV6, IPV6_PKTINFO, (char *)&state, (INT *)&count);
2466 ok(!rc, "failed to get IPV6_PKTINFO, error %u\n", WSAGetLastError());
2467 ok(state == 1, "expected 1, got %lu\n", state);
2468 rc = send(client, payload, sizeof(payload), 0);
2469 ok(rc == sizeof(payload), "send failed, error %u\n", WSAGetLastError());
2470 rc = pWSARecvMsg(server, &msg, &count, NULL, NULL);
2471 ok(!rc, "WSARecvMsg failed, error %u\n", WSAGetLastError());
2472 ok(count == sizeof(payload), "expected length %Iu, got %lu\n", sizeof(payload), count);
2473 ok(header->cmsg_level == IPPROTO_IPV6, "expected IPPROTO_IPV6, got %i\n", header->cmsg_level);
2474 ok(header->cmsg_type == IPV6_PKTINFO, "expected IPV6_PKTINFO, got %i\n", header->cmsg_type);
2475 ok(header->cmsg_len == sizeof(*header) + sizeof(IN6_PKTINFO),
2476 "expected length %Iu, got %Iu\n", sizeof(*header) + sizeof(IN6_PKTINFO), header->cmsg_len);
2477 ok(!memcmp(&pkt_info->ipi6_addr, &localhost.sin6_addr, sizeof(IN6_ADDR)), "expected ::1\n");
2478 rc = setsockopt(server, IPPROTO_IPV6, IPV6_PKTINFO, (const char *)&off, sizeof(off));
2479 ok(!rc, "failed to clear IPV6_PKTINFO, error %u\n", WSAGetLastError());
2481 memset(control, 0, sizeof(control));
2482 msg.Control.len = sizeof(control);
2483 rc = setsockopt(server, IPPROTO_IPV6, IPV6_RECVTCLASS, (const char *)&on, sizeof(on));
2484 ok(!rc, "failed to set IPV6_RECVTCLASS, error %u\n", WSAGetLastError());
2485 state = 0;
2486 count = sizeof(state);
2487 rc = getsockopt(server, IPPROTO_IPV6, IPV6_RECVTCLASS, (char *)&state, (INT *)&count);
2488 ok(!rc, "failed to get IPV6_RECVTCLASS, error %u\n", WSAGetLastError());
2489 ok(state == 1, "expected 1, got %lu\n", state);
2490 rc = send(client, payload, sizeof(payload), 0);
2491 ok(rc == sizeof(payload), "send failed, error %u\n", WSAGetLastError());
2492 rc = pWSARecvMsg(server, &msg, &count, NULL, NULL);
2493 ok(!rc, "WSARecvMsg failed, error %u\n", WSAGetLastError());
2494 ok(count == sizeof(payload), "expected length %Iu, got %lu\n", sizeof(payload), count);
2495 ok(header->cmsg_level == IPPROTO_IPV6, "expected IPPROTO_IPV6, got %i\n", header->cmsg_level);
2496 ok(header->cmsg_type == IPV6_TCLASS, "expected IPV6_TCLASS, got %i\n", header->cmsg_type);
2497 ok(header->cmsg_len == sizeof(*header) + sizeof(INT),
2498 "expected length %Iu, got %Iu\n", sizeof(*header) + sizeof(INT), header->cmsg_len);
2499 ok(*int_data == 0, "expected 0, got %i\n", *int_data);
2500 rc = setsockopt(server, IPPROTO_IPV6, IPV6_RECVTCLASS, (const char *)&off, sizeof(off));
2501 ok(!rc, "failed to clear IPV6_RECVTCLASS, error %u\n", WSAGetLastError());
2503 closesocket(server);
2504 closesocket(client);
2507 /************* Array containing the tests to run **********/
2509 #define STD_STREAM_SOCKET \
2510 SOCK_STREAM, \
2511 0, \
2512 SERVERIP, \
2513 SERVERPORT
2515 static test_setup tests [] =
2517 /* Test 0: synchronous client and server */
2520 STD_STREAM_SOCKET,
2521 2048,
2525 simple_server,
2527 NULL,
2531 simple_client,
2533 NULL,
2538 /* Test 1: event-driven client, synchronous server */
2541 STD_STREAM_SOCKET,
2542 2048,
2546 simple_server,
2548 NULL,
2552 event_client,
2554 NULL,
2555 WSA_FLAG_OVERLAPPED,
2559 /* Test 2: synchronous client, non-blocking server via select() */
2562 STD_STREAM_SOCKET,
2563 2048,
2567 select_server,
2569 NULL,
2573 simple_client,
2575 NULL,
2580 /* Test 3: OOB client, OOB server */
2583 STD_STREAM_SOCKET,
2584 128,
2588 oob_server,
2590 NULL,
2594 oob_client,
2596 NULL,
2601 /* Test 4: synchronous mixed client and server */
2604 STD_STREAM_SOCKET,
2605 2048,
2609 simple_server,
2611 NULL,
2615 simple_mixed_client,
2617 NULL,
2624 static void test_UDP(void)
2626 /* This function tests UDP sendto() and recvfrom(). UDP is unreliable, so it is
2627 possible that this test fails due to dropped packets. */
2629 /* peer 0 receives data from all other peers */
2630 struct sock_info peer[NUM_UDP_PEERS];
2631 char buf[16];
2632 int ss, i, n_recv, n_sent;
2634 memset (buf,0,sizeof(buf));
2635 for ( i = NUM_UDP_PEERS - 1; i >= 0; i-- ) {
2636 ok ( ( peer[i].s = socket ( AF_INET, SOCK_DGRAM, 0 ) ) != INVALID_SOCKET, "UDP: socket failed\n" );
2638 peer[i].addr.sin_family = AF_INET;
2639 peer[i].addr.sin_addr.s_addr = inet_addr ( SERVERIP );
2641 if ( i == 0 ) {
2642 peer[i].addr.sin_port = htons ( SERVERPORT );
2643 } else {
2644 peer[i].addr.sin_port = htons ( 0 );
2647 do_bind ( peer[i].s, (struct sockaddr *) &peer[i].addr, sizeof( peer[i].addr ) );
2649 /* test getsockname() to get peer's port */
2650 ss = sizeof ( peer[i].addr );
2651 ok ( getsockname ( peer[i].s, (struct sockaddr *) &peer[i].addr, &ss ) != SOCKET_ERROR, "UDP: could not getsockname()\n" );
2652 ok ( peer[i].addr.sin_port != htons ( 0 ), "UDP: bind() did not associate port\n" );
2655 /* test getsockname() */
2656 ok ( peer[0].addr.sin_port == htons ( SERVERPORT ), "UDP: getsockname returned incorrect peer port\n" );
2658 for ( i = 1; i < NUM_UDP_PEERS; i++ ) {
2659 /* send client's ip */
2660 memcpy( buf, &peer[i].addr.sin_port, sizeof(peer[i].addr.sin_port) );
2661 n_sent = sendto ( peer[i].s, buf, sizeof(buf), 0, (struct sockaddr*) &peer[0].addr, sizeof(peer[0].addr) );
2662 ok ( n_sent == sizeof(buf), "UDP: sendto() sent wrong amount of data or socket error: %d\n", n_sent );
2665 for ( i = 1; i < NUM_UDP_PEERS; i++ ) {
2666 n_recv = recvfrom ( peer[0].s, buf, sizeof(buf), 0,(struct sockaddr *) &peer[0].peer, &ss );
2667 ok ( n_recv == sizeof(buf), "UDP: recvfrom() received wrong amount of data or socket error: %d\n", n_recv );
2668 ok ( memcmp ( &peer[0].peer.sin_port, buf, sizeof(peer[0].addr.sin_port) ) == 0, "UDP: port numbers do not match\n" );
2672 static void test_WSASocket(void)
2674 SOCKET sock = INVALID_SOCKET;
2675 WSAPROTOCOL_INFOA *pi;
2676 int wsaproviders[] = {IPPROTO_TCP, IPPROTO_IP};
2677 int autoprotocols[] = {IPPROTO_TCP, IPPROTO_UDP};
2678 int items, err, size, socktype, i, j;
2679 DWORD pi_size;
2681 static const struct
2683 int family, type, protocol;
2684 DWORD error;
2685 int ret_family, ret_type, ret_protocol;
2687 tests[] =
2689 /* 0 */
2690 {0xdead, SOCK_STREAM, IPPROTO_TCP, WSAEAFNOSUPPORT},
2691 {-1, SOCK_STREAM, IPPROTO_TCP, WSAEAFNOSUPPORT},
2692 {AF_INET, 0xdead, IPPROTO_TCP, WSAESOCKTNOSUPPORT},
2693 {AF_INET, -1, IPPROTO_TCP, WSAESOCKTNOSUPPORT},
2694 {AF_INET, SOCK_STREAM, 0xdead, WSAEPROTONOSUPPORT},
2695 {AF_INET, SOCK_STREAM, -1, WSAEPROTONOSUPPORT},
2696 {0xdead, 0xdead, IPPROTO_TCP, WSAESOCKTNOSUPPORT},
2697 {0xdead, SOCK_STREAM, 0xdead, WSAEAFNOSUPPORT},
2698 {AF_INET, 0xdead, 0xdead, WSAESOCKTNOSUPPORT},
2699 {0xdead, SOCK_STREAM, IPPROTO_UDP, WSAEAFNOSUPPORT},
2701 /* 10 */
2702 {AF_INET, SOCK_STREAM, 0, 0, AF_INET, SOCK_STREAM, IPPROTO_TCP},
2703 {AF_INET, SOCK_DGRAM, 0, 0, AF_INET, SOCK_DGRAM, IPPROTO_UDP},
2704 {AF_INET, 0xdead, 0, WSAESOCKTNOSUPPORT},
2705 {AF_INET, 0, IPPROTO_TCP, 0, AF_INET, SOCK_STREAM, IPPROTO_TCP},
2706 {AF_INET, 0, IPPROTO_UDP, 0, AF_INET, SOCK_DGRAM, IPPROTO_UDP},
2707 {AF_INET, 0, 0xdead, WSAEPROTONOSUPPORT},
2708 {AF_INET, 0, 0, 0, AF_INET, SOCK_STREAM, IPPROTO_TCP},
2709 {AF_INET, SOCK_STREAM, IPPROTO_UDP, WSAEPROTONOSUPPORT},
2710 {AF_INET, SOCK_DGRAM, IPPROTO_TCP, WSAEPROTONOSUPPORT},
2712 /* 19 */
2713 {AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP, 0, AF_INET, SOCK_STREAM, IPPROTO_TCP},
2714 {AF_UNSPEC, SOCK_STREAM, 0xdead, WSAEPROTONOSUPPORT},
2715 {AF_UNSPEC, 0xdead, IPPROTO_UDP, WSAESOCKTNOSUPPORT},
2716 {AF_UNSPEC, SOCK_STREAM, 0, WSAEINVAL},
2717 {AF_UNSPEC, SOCK_DGRAM, 0, WSAEINVAL},
2718 {AF_UNSPEC, 0xdead, 0, WSAEINVAL},
2719 {AF_UNSPEC, 0, IPPROTO_TCP, 0, AF_INET, SOCK_STREAM, IPPROTO_TCP},
2720 {AF_UNSPEC, 0, IPPROTO_UDP, 0, AF_INET, SOCK_DGRAM, IPPROTO_UDP},
2721 {AF_UNSPEC, 0, 0xdead, WSAEPROTONOSUPPORT},
2722 {AF_UNSPEC, 0, 0, WSAEINVAL},
2725 for (i = 0; i < ARRAY_SIZE(tests); ++i)
2727 SetLastError( 0xdeadbeef );
2728 sock = WSASocketA( tests[i].family, tests[i].type, tests[i].protocol, NULL, 0, 0 );
2729 todo_wine_if (i == 7)
2730 ok(WSAGetLastError() == tests[i].error, "Test %u: got wrong error %u\n", i, WSAGetLastError());
2731 if (tests[i].error)
2733 ok(sock == INVALID_SOCKET, "Test %u: expected failure\n", i);
2735 else
2737 WSAPROTOCOL_INFOA info;
2739 ok(sock != INVALID_SOCKET, "Text %u: expected success\n", i);
2741 size = sizeof(info);
2742 err = getsockopt( sock, SOL_SOCKET, SO_PROTOCOL_INFOA, (char *)&info, &size );
2743 ok(!err, "Test %u: getsockopt failed, error %u\n", i, WSAGetLastError());
2744 ok(info.iAddressFamily == tests[i].ret_family, "Test %u: got wrong family %d\n", i, info.iAddressFamily);
2745 ok(info.iSocketType == tests[i].ret_type, "Test %u: got wrong type %d\n", i, info.iSocketType);
2746 ok(info.iProtocol == tests[i].ret_protocol, "Test %u: got wrong protocol %d\n", i, info.iProtocol);
2748 closesocket( sock );
2752 /* Set pi_size explicitly to a value below 2*sizeof(WSAPROTOCOL_INFOA)
2753 * to avoid a crash on win98.
2755 pi_size = 0;
2756 items = WSAEnumProtocolsA(wsaproviders, NULL, &pi_size);
2757 ok(items == SOCKET_ERROR, "WSAEnumProtocolsA({6,0}, NULL, 0) returned %d\n",
2758 items);
2759 err = WSAGetLastError();
2760 ok(err == WSAENOBUFS, "WSAEnumProtocolsA error is %d, not WSAENOBUFS(%d)\n",
2761 err, WSAENOBUFS);
2763 pi = HeapAlloc(GetProcessHeap(), 0, pi_size);
2764 ok(pi != NULL, "Failed to allocate memory\n");
2766 items = WSAEnumProtocolsA(wsaproviders, pi, &pi_size);
2767 ok(items != SOCKET_ERROR, "WSAEnumProtocolsA failed, last error is %d\n",
2768 WSAGetLastError());
2770 if (items == 0) {
2771 skip("No protocols enumerated.\n");
2772 HeapFree(GetProcessHeap(), 0, pi);
2773 return;
2776 sock = WSASocketA(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO,
2777 FROM_PROTOCOL_INFO, &pi[0], 0, 0);
2778 ok(sock != INVALID_SOCKET, "Failed to create socket: %d\n",
2779 WSAGetLastError());
2780 closesocket(sock);
2782 /* find what parameters are used first: plain parameters or protocol info struct */
2783 pi[0].iProtocol = -1;
2784 pi[0].iSocketType = -1;
2785 pi[0].iAddressFamily = -1;
2786 ok(WSASocketA(0, 0, IPPROTO_UDP, &pi[0], 0, 0) == INVALID_SOCKET,
2787 "WSASocketA should have failed\n");
2788 err = WSAGetLastError();
2789 ok(err == WSAEAFNOSUPPORT, "Expected 10047, received %d\n", err);
2791 pi[0].iProtocol = 0;
2792 pi[0].iSocketType = 0;
2793 pi[0].iAddressFamily = 0;
2794 sock = WSASocketA(0, 0, IPPROTO_UDP, &pi[0], 0, 0);
2795 if(sock != INVALID_SOCKET)
2797 win_skip("must work only in OS <= 2003\n");
2798 closesocket(sock);
2800 else
2802 err = WSAGetLastError();
2803 ok(err == WSAEAFNOSUPPORT, "Expected 10047, received %d\n", err);
2806 pi[0].iProtocol = IPPROTO_UDP;
2807 pi[0].iSocketType = SOCK_DGRAM;
2808 pi[0].iAddressFamily = AF_INET;
2809 sock = WSASocketA(0, 0, 0, &pi[0], 0, 0);
2810 ok(sock != INVALID_SOCKET, "Failed to create socket: %d\n",
2811 WSAGetLastError());
2813 size = sizeof(socktype);
2814 socktype = 0xdead;
2815 err = getsockopt(sock, SOL_SOCKET, SO_TYPE, (char *) &socktype, &size);
2816 ok(!err,"getsockopt failed with %d\n", WSAGetLastError());
2817 ok(socktype == SOCK_DGRAM, "Wrong socket type, expected %d received %d\n",
2818 SOCK_DGRAM, socktype);
2820 socktype = SOCK_STREAM;
2821 WSASetLastError(0xdeadbeef);
2822 err = setsockopt(sock, SOL_SOCKET, SO_TYPE, (char *)&socktype, sizeof(socktype));
2823 ok(err == -1, "expected failure\n");
2824 todo_wine ok(WSAGetLastError() == WSAEINVAL, "got error %u\n", WSAGetLastError());
2826 socktype = SOCK_DGRAM;
2827 WSASetLastError(0xdeadbeef);
2828 err = setsockopt(sock, SOL_SOCKET, SO_TYPE, (char *)&socktype, sizeof(socktype));
2829 ok(err == -1, "expected failure\n");
2830 todo_wine ok(WSAGetLastError() == WSAEINVAL, "got error %u\n", WSAGetLastError());
2832 closesocket(sock);
2834 sock = WSASocketA(AF_INET, SOCK_STREAM, IPPROTO_TCP, &pi[0], 0, 0);
2835 ok(sock != INVALID_SOCKET, "Failed to create socket: %d\n",
2836 WSAGetLastError());
2838 size = sizeof(socktype);
2839 socktype = 0xdead;
2840 err = getsockopt(sock, SOL_SOCKET, SO_TYPE, (char *) &socktype, &size);
2841 ok(!err,"getsockopt failed with %d\n", WSAGetLastError());
2842 ok(socktype == SOCK_STREAM, "Wrong socket type, expected %d received %d\n",
2843 SOCK_STREAM, socktype);
2845 socktype = SOCK_STREAM;
2846 WSASetLastError(0xdeadbeef);
2847 err = setsockopt(sock, SOL_SOCKET, SO_TYPE, (char *)&socktype, sizeof(socktype));
2848 ok(err == -1, "expected failure\n");
2849 ok(WSAGetLastError() == WSAENOPROTOOPT, "got error %u\n", WSAGetLastError());
2851 socktype = SOCK_DGRAM;
2852 WSASetLastError(0xdeadbeef);
2853 err = setsockopt(sock, SOL_SOCKET, SO_TYPE, (char *)&socktype, sizeof(socktype));
2854 ok(err == -1, "expected failure\n");
2855 ok(WSAGetLastError() == WSAENOPROTOOPT, "got error %u\n", WSAGetLastError());
2857 closesocket(sock);
2859 HeapFree(GetProcessHeap(), 0, pi);
2861 pi_size = 0;
2862 items = WSAEnumProtocolsA(NULL, NULL, &pi_size);
2863 ok(items == SOCKET_ERROR, "WSAEnumProtocolsA(NULL, NULL, 0) returned %d\n",
2864 items);
2865 err = WSAGetLastError();
2866 ok(err == WSAENOBUFS, "WSAEnumProtocolsA error is %d, not WSAENOBUFS(%d)\n",
2867 err, WSAENOBUFS);
2869 pi = HeapAlloc(GetProcessHeap(), 0, pi_size);
2870 ok(pi != NULL, "Failed to allocate memory\n");
2872 items = WSAEnumProtocolsA(NULL, pi, &pi_size);
2873 ok(items != SOCKET_ERROR, "WSAEnumProtocolsA failed, last error is %d\n",
2874 WSAGetLastError());
2876 /* when no protocol and socket type are specified the first entry
2877 * from WSAEnumProtocols that has the flag PFL_MATCHES_PROTOCOL_ZERO
2878 * is returned */
2879 sock = WSASocketA(AF_INET, 0, 0, NULL, 0, 0);
2880 ok(sock != INVALID_SOCKET, "Failed to create socket: %d\n",
2881 WSAGetLastError());
2883 size = sizeof(socktype);
2884 socktype = 0xdead;
2885 err = getsockopt(sock, SOL_SOCKET, SO_TYPE, (char *) &socktype, &size);
2886 ok(!err, "getsockopt failed with %d\n", WSAGetLastError());
2887 for(i = 0; i < items; i++)
2889 if(pi[i].dwProviderFlags & PFL_MATCHES_PROTOCOL_ZERO)
2891 ok(socktype == pi[i].iSocketType, "Wrong socket type, expected %d received %d\n",
2892 pi[i].iSocketType, socktype);
2893 break;
2896 ok(i != items, "Creating a socket without protocol and socket type didn't work\n");
2897 closesocket(sock);
2899 /* when no socket type is specified the first entry from WSAEnumProtocols
2900 * that matches the protocol is returned */
2901 for (i = 0; i < ARRAY_SIZE(autoprotocols); i++)
2903 sock = WSASocketA(0, 0, autoprotocols[i], NULL, 0, 0);
2904 ok(sock != INVALID_SOCKET, "Failed to create socket for protocol %d, received %d\n",
2905 autoprotocols[i], WSAGetLastError());
2907 size = sizeof(socktype);
2908 socktype = 0xdead;
2909 err = getsockopt(sock, SOL_SOCKET, SO_TYPE, (char *) &socktype, &size);
2910 ok(!err, "getsockopt failed with %d\n", WSAGetLastError());
2912 for (err = 1, j = 0; j < items; j++)
2914 if (pi[j].iProtocol == autoprotocols[i])
2916 ok(pi[j].iSocketType == socktype, "expected %d, got %d\n", socktype, pi[j].iSocketType);
2917 err = 0;
2918 break;
2921 ok(!err, "Protocol %d not found in WSAEnumProtocols\n", autoprotocols[i]);
2923 closesocket(sock);
2926 HeapFree(GetProcessHeap(), 0, pi);
2928 SetLastError(0xdeadbeef);
2929 /* starting on vista the socket function returns error during the socket
2930 creation and no longer in the socket operations (sendto, readfrom) */
2931 sock = WSASocketA(AF_INET, SOCK_RAW, IPPROTO_ICMP, NULL, 0, 0);
2932 if (sock == INVALID_SOCKET)
2934 err = WSAGetLastError();
2935 ok(err == WSAEACCES, "Expected 10013, received %d\n", err);
2936 skip("SOCK_RAW is not supported\n");
2938 else
2940 size = sizeof(socktype);
2941 socktype = 0xdead;
2942 err = getsockopt(sock, SOL_SOCKET, SO_TYPE, (char *) &socktype, &size);
2943 ok(!err, "getsockopt failed with %d\n", WSAGetLastError());
2944 ok(socktype == SOCK_RAW, "Wrong socket type, expected %d received %d\n",
2945 SOCK_RAW, socktype);
2946 closesocket(sock);
2948 sock = WSASocketA(0, 0, IPPROTO_RAW, NULL, 0, 0);
2949 if (sock != INVALID_SOCKET)
2951 todo_wine {
2952 size = sizeof(socktype);
2953 socktype = 0xdead;
2954 err = getsockopt(sock, SOL_SOCKET, SO_TYPE, (char *) &socktype, &size);
2955 ok(!err, "getsockopt failed with %d\n", WSAGetLastError());
2956 ok(socktype == SOCK_RAW, "Wrong socket type, expected %d received %d\n",
2957 SOCK_RAW, socktype);
2958 closesocket(sock);
2961 sock = WSASocketA(AF_INET, SOCK_RAW, IPPROTO_TCP, NULL, 0, 0);
2962 ok(sock != INVALID_SOCKET, "Failed to create socket: %d\n",
2963 WSAGetLastError());
2964 size = sizeof(socktype);
2965 socktype = 0xdead;
2966 err = getsockopt(sock, SOL_SOCKET, SO_TYPE, (char *) &socktype, &size);
2967 ok(!err, "getsockopt failed with %d\n", WSAGetLastError());
2968 ok(socktype == SOCK_RAW, "Wrong socket type, expected %d received %d\n",
2969 SOCK_RAW, socktype);
2970 closesocket(sock);
2972 else if (WSAGetLastError() == WSAEACCES)
2973 skip("SOCK_RAW is not available\n");
2974 else
2975 ok(0, "Failed to create socket: %d\n", WSAGetLastError());
2979 /* IPX socket tests */
2981 SetLastError(0xdeadbeef);
2982 sock = WSASocketA(AF_IPX, SOCK_DGRAM, NSPROTO_IPX, NULL, 0, 0);
2983 if (sock == INVALID_SOCKET)
2985 ok(WSAGetLastError() == WSAEAFNOSUPPORT, "got error %u\n", WSAGetLastError());
2986 skip("IPX is not supported\n");
2988 else
2990 WSAPROTOCOL_INFOA info;
2991 closesocket(sock);
2993 sock = WSASocketA(0, 0, NSPROTO_IPX, NULL, 0, 0);
2994 ok(sock != INVALID_SOCKET, "Failed to create socket: %d\n",
2995 WSAGetLastError());
2997 size = sizeof(socktype);
2998 socktype = 0xdead;
2999 err = getsockopt(sock, SOL_SOCKET, SO_TYPE, (char *) &socktype, &size);
3000 ok(!err,"getsockopt failed with %d\n", WSAGetLastError());
3001 ok(socktype == SOCK_DGRAM, "Wrong socket type, expected %d received %d\n",
3002 SOCK_DGRAM, socktype);
3004 /* check socket family, type and protocol */
3005 size = sizeof(WSAPROTOCOL_INFOA);
3006 err = getsockopt(sock, SOL_SOCKET, SO_PROTOCOL_INFOA, (char *) &info, &size);
3007 ok(!err,"getsockopt failed with %d\n", WSAGetLastError());
3008 ok(info.iProtocol == NSPROTO_IPX, "expected protocol %d, received %d\n",
3009 NSPROTO_IPX, info.iProtocol);
3010 ok(info.iAddressFamily == AF_IPX, "expected family %d, received %d\n",
3011 AF_IPX, info.iProtocol);
3012 ok(info.iSocketType == SOCK_DGRAM, "expected type %d, received %d\n",
3013 SOCK_DGRAM, info.iSocketType);
3014 closesocket(sock);
3016 /* SOCK_STREAM does not support NSPROTO_IPX */
3017 SetLastError(0xdeadbeef);
3018 ok(WSASocketA(AF_IPX, SOCK_STREAM, NSPROTO_IPX, NULL, 0, 0) == INVALID_SOCKET,
3019 "WSASocketA should have failed\n");
3020 err = WSAGetLastError();
3021 ok(err == WSAEPROTONOSUPPORT, "Expected 10043, received %d\n", err);
3023 /* test extended IPX support - that is adding any number between 0 and 255
3024 * to the IPX protocol value will make it be used as IPX packet type */
3025 for(i = 0;i <= 255;i += 17)
3027 SetLastError(0xdeadbeef);
3028 sock = WSASocketA(0, 0, NSPROTO_IPX + i, NULL, 0, 0);
3029 ok(sock != INVALID_SOCKET, "Failed to create socket: %d\n",
3030 WSAGetLastError());
3032 size = sizeof(int);
3033 socktype = -1;
3034 err = getsockopt(sock, NSPROTO_IPX, IPX_PTYPE, (char *) &socktype, &size);
3035 ok(!err, "getsockopt failed with %d\n", WSAGetLastError());
3036 ok(socktype == i, "Wrong IPX packet type, expected %d received %d\n",
3037 i, socktype);
3039 closesocket(sock);
3044 static void test_WSADuplicateSocket(void)
3046 SOCKET source, dupsock;
3047 WSAPROTOCOL_INFOA info;
3048 DWORD err;
3049 struct sockaddr_in addr;
3050 int socktype, size, addrsize, ret;
3051 char teststr[] = "TEST", buffer[16];
3053 source = WSASocketA(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0);
3054 ok(source != INVALID_SOCKET, "WSASocketA should have succeeded\n");
3056 /* test invalid parameters */
3057 SetLastError(0xdeadbeef);
3058 ok(WSADuplicateSocketA(0, 0, NULL), "WSADuplicateSocketA should have failed\n");
3059 err = WSAGetLastError();
3060 ok(err == WSAENOTSOCK, "expected 10038, received %ld\n", err);
3062 SetLastError(0xdeadbeef);
3063 ok(WSADuplicateSocketA(source, 0, NULL),
3064 "WSADuplicateSocketA should have failed\n");
3065 err = WSAGetLastError();
3066 ok(err == WSAEINVAL, "expected 10022, received %ld\n", err);
3068 SetLastError(0xdeadbeef);
3069 ok(WSADuplicateSocketA(source, ~0, &info),
3070 "WSADuplicateSocketA should have failed\n");
3071 err = WSAGetLastError();
3072 ok(err == WSAEINVAL, "expected 10022, received %ld\n", err);
3074 SetLastError(0xdeadbeef);
3075 ok(WSADuplicateSocketA(0, GetCurrentProcessId(), &info),
3076 "WSADuplicateSocketA should have failed\n");
3077 err = WSAGetLastError();
3078 ok(err == WSAENOTSOCK, "expected 10038, received %ld\n", err);
3080 SetLastError(0xdeadbeef);
3081 ok(WSADuplicateSocketA(source, GetCurrentProcessId(), NULL),
3082 "WSADuplicateSocketA should have failed\n");
3083 err = WSAGetLastError();
3084 ok(err == WSAEFAULT, "expected 10014, received %ld\n", err);
3086 /* test returned structure */
3087 memset(&info, 0, sizeof(info));
3088 ok(!WSADuplicateSocketA(source, GetCurrentProcessId(), &info),
3089 "WSADuplicateSocketA should have worked\n");
3091 ok(info.iProtocol == IPPROTO_TCP, "expected protocol %d, received %d\n",
3092 IPPROTO_TCP, info.iProtocol);
3093 ok(info.iAddressFamily == AF_INET, "expected family %d, received %d\n",
3094 AF_INET, info.iProtocol);
3095 ok(info.iSocketType == SOCK_STREAM, "expected type %d, received %d\n",
3096 SOCK_STREAM, info.iSocketType);
3098 dupsock = WSASocketA(0, 0, 0, &info, 0, 0);
3099 ok(dupsock != INVALID_SOCKET, "WSASocketA should have succeeded\n");
3101 closesocket(dupsock);
3102 closesocket(source);
3104 /* create a socket, bind it, duplicate it then send data on source and
3105 * receive in the duplicated socket */
3106 source = WSASocketA(AF_INET, SOCK_DGRAM, IPPROTO_UDP, NULL, 0, 0);
3107 ok(source != INVALID_SOCKET, "WSASocketA should have succeeded\n");
3109 memset(&info, 0, sizeof(info));
3110 ok(!WSADuplicateSocketA(source, GetCurrentProcessId(), &info),
3111 "WSADuplicateSocketA should have worked\n");
3113 ok(info.iProtocol == IPPROTO_UDP, "expected protocol %d, received %d\n",
3114 IPPROTO_UDP, info.iProtocol);
3115 ok(info.iAddressFamily == AF_INET, "expected family %d, received %d\n",
3116 AF_INET, info.iProtocol);
3117 ok(info.iSocketType == SOCK_DGRAM, "expected type %d, received %d\n",
3118 SOCK_DGRAM, info.iSocketType);
3120 memset(&addr, 0, sizeof(addr));
3121 addr.sin_family = AF_INET;
3122 addr.sin_addr.s_addr = inet_addr("127.0.0.1");
3123 ok(!bind(source, (struct sockaddr*)&addr, sizeof(addr)),
3124 "bind should have worked\n");
3126 /* read address to find out the port number to be used in sendto */
3127 memset(&addr, 0, sizeof(addr));
3128 addrsize = sizeof(addr);
3129 ok(!getsockname(source, (struct sockaddr *) &addr, &addrsize),
3130 "getsockname should have worked\n");
3131 ok(addr.sin_port, "socket port should be != 0\n");
3133 dupsock = WSASocketA(0, 0, 0, &info, 0, 0);
3134 ok(dupsock != INVALID_SOCKET, "WSASocketA should have succeeded\n");
3136 size = sizeof(int);
3137 ret = getsockopt(dupsock, SOL_SOCKET, SO_TYPE, (char *) &socktype, &size);
3138 ok(!ret, "getsockopt failed with %d\n", WSAGetLastError());
3139 ok(socktype == SOCK_DGRAM, "Wrong socket type, expected %d received %d\n",
3140 SOCK_DGRAM, socktype);
3142 set_blocking(source, TRUE);
3144 /* send data on source socket */
3145 addrsize = sizeof(addr);
3146 size = sendto(source, teststr, sizeof(teststr), 0, (struct sockaddr *) &addr, addrsize);
3147 ok(size == sizeof(teststr), "got %d (err %d)\n", size, WSAGetLastError());
3149 /* receive on duplicated socket */
3150 addrsize = sizeof(addr);
3151 memset(buffer, 0, sizeof(buffer));
3152 size = recvfrom(dupsock, buffer, sizeof(teststr), 0, (struct sockaddr *) &addr, &addrsize);
3153 ok(size == sizeof(teststr), "got %d (err %d)\n", size, WSAGetLastError());
3154 buffer[sizeof(teststr) - 1] = 0;
3155 ok(!strcmp(buffer, teststr), "expected '%s', received '%s'\n", teststr, buffer);
3157 closesocket(dupsock);
3158 closesocket(source);
3160 /* show that the source socket need to be bound before the duplicated
3161 * socket is created */
3162 source = WSASocketA(AF_INET, SOCK_DGRAM, IPPROTO_UDP, NULL, 0, 0);
3163 ok(source != INVALID_SOCKET, "WSASocketA should have succeeded\n");
3165 memset(&info, 0, sizeof(info));
3166 ok(!WSADuplicateSocketA(source, GetCurrentProcessId(), &info),
3167 "WSADuplicateSocketA should have worked\n");
3169 dupsock = WSASocketA(0, 0, 0, &info, 0, 0);
3170 ok(dupsock != INVALID_SOCKET, "WSASocketA should have succeeded\n");
3172 memset(&addr, 0, sizeof(addr));
3173 addr.sin_family = AF_INET;
3174 addr.sin_addr.s_addr = inet_addr("127.0.0.1");
3175 ok(!bind(source, (struct sockaddr*)&addr, sizeof(addr)),
3176 "bind should have worked\n");
3178 /* read address to find out the port number to be used in sendto */
3179 memset(&addr, 0, sizeof(addr));
3180 addrsize = sizeof(addr);
3181 ok(!getsockname(source, (struct sockaddr *) &addr, &addrsize),
3182 "getsockname should have worked\n");
3183 ok(addr.sin_port, "socket port should be != 0\n");
3185 set_blocking(source, TRUE);
3187 addrsize = sizeof(addr);
3188 size = sendto(source, teststr, sizeof(teststr), 0, (struct sockaddr *) &addr, addrsize);
3189 ok(size == sizeof(teststr), "got %d (err %d)\n", size, WSAGetLastError());
3191 SetLastError(0xdeadbeef);
3192 addrsize = sizeof(addr);
3193 memset(buffer, 0, sizeof(buffer));
3194 todo_wine {
3195 ok(recvfrom(dupsock, buffer, sizeof(teststr), 0, (struct sockaddr *) &addr, &addrsize) == -1,
3196 "recvfrom should have failed\n");
3197 err = WSAGetLastError();
3198 ok(err == WSAEINVAL, "expected 10022, received %ld\n", err);
3201 closesocket(dupsock);
3202 closesocket(source);
3205 static void test_WSAConnectByName(void)
3207 SOCKET s;
3208 SOCKADDR_IN local_addr = {0}, remote_addr = {0},
3209 sock_addr = {0}, peer_addr = {0};
3210 DWORD local_len, remote_len, conn_ctx;
3211 int ret, err, sock_len, peer_len;
3212 WSAOVERLAPPED overlap;
3213 struct addrinfo *first_addrinfo, first_hints;
3215 conn_ctx = TRUE;
3217 /* First call of getaddrinfo fails on w8adm */
3218 first_addrinfo = NULL;
3219 memset(&first_hints, 0, sizeof(struct addrinfo));
3220 first_hints.ai_socktype = SOCK_STREAM;
3221 first_hints.ai_family = AF_INET;
3222 first_hints.ai_protocol = IPPROTO_TCP;
3223 getaddrinfo("winehq.org", "http", &first_hints, &first_addrinfo);
3224 if (first_addrinfo)
3225 freeaddrinfo(first_addrinfo);
3226 SetLastError(0xdeadbeef);
3228 /* Fill all fields */
3229 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
3230 local_len = remote_len = sizeof(SOCKADDR_IN);
3231 ret = WSAConnectByNameA(s, "winehq.org", "http", &local_len, (struct sockaddr *)&local_addr,
3232 &remote_len, (struct sockaddr *)&remote_addr, NULL, NULL);
3233 ok(ret, "WSAConnectByNameA should have succeeded, error %u\n", WSAGetLastError());
3234 setsockopt(s, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, (char *)&conn_ctx, sizeof(DWORD));
3235 sock_len = peer_len = sizeof(SOCKADDR_IN);
3236 ret = getsockname(s, (struct sockaddr *)&sock_addr, &sock_len);
3237 ok(!ret, "getsockname should have succeeded, error %u\n", WSAGetLastError());
3238 ret = getpeername(s, (struct sockaddr *)&peer_addr, &peer_len);
3239 ok(!ret, "getpeername should have succeeded, error %u\n", WSAGetLastError());
3240 ok(sock_len == sizeof(SOCKADDR_IN), "got sockname size of %d\n", sock_len);
3241 ok(peer_len == sizeof(SOCKADDR_IN), "got peername size of %d\n", peer_len);
3242 ok(local_len == sizeof(SOCKADDR_IN), "got local size of %lu\n", local_len);
3243 ok(remote_len == sizeof(SOCKADDR_IN), "got remote size of %lu\n", remote_len);
3244 ok(!local_addr.sin_port, "local_addr has non-zero sin_port: %hu.\n", local_addr.sin_port);
3245 ok(!memcmp(&sock_addr.sin_addr, &local_addr.sin_addr, sizeof(struct in_addr)),
3246 "local_addr did not receive data.\n");
3247 ok(!memcmp(&peer_addr, &remote_addr, sizeof(SOCKADDR_IN)), "remote_addr did not receive data.\n");
3248 closesocket(s);
3250 /* Passing NULL length but a pointer to a sockaddr */
3251 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
3252 local_len = remote_len = sizeof(SOCKADDR_IN);
3253 memset(&local_addr, 0, sizeof(SOCKADDR_IN));
3254 memset(&remote_addr, 0, sizeof(SOCKADDR_IN));
3255 memset(&sock_addr, 0, sizeof(SOCKADDR_IN));
3256 memset(&peer_addr, 0, sizeof(SOCKADDR_IN));
3257 ret = WSAConnectByNameA(s, "winehq.org", "http", NULL, (struct sockaddr *)&local_addr,
3258 NULL, (struct sockaddr *)&remote_addr, NULL, NULL);
3259 ok(ret, "WSAConnectByNameA should have succeeded, error %u\n", WSAGetLastError());
3260 setsockopt(s, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, (char *)&conn_ctx, sizeof(DWORD));
3261 sock_len = peer_len = sizeof(SOCKADDR_IN);
3262 ret = getsockname(s, (struct sockaddr *)&sock_addr, &sock_len);
3263 ok(!ret, "getsockname should have succeeded, error %u\n", WSAGetLastError());
3264 ret = getpeername(s, (struct sockaddr *)&peer_addr, &peer_len);
3265 ok(!ret, "getpeername should have succeeded, error %u\n", WSAGetLastError());
3266 ok(sock_len == sizeof(SOCKADDR_IN), "got sockname size of %d\n", sock_len);
3267 ok(peer_len == sizeof(SOCKADDR_IN), "got peername size of %d\n", peer_len);
3268 ok(!local_addr.sin_family, "local_addr received data.\n");
3269 ok(!remote_addr.sin_family, "remote_addr received data.\n");
3270 closesocket(s);
3272 /* Passing NULLs for node or service */
3273 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
3274 ret = WSAConnectByNameA(s, NULL, "http", NULL, NULL, NULL, NULL, NULL, NULL);
3275 err = WSAGetLastError();
3276 ok(!ret, "WSAConnectByNameA should have failed\n");
3277 ok(err == WSAEINVAL, "expected error %u (WSAEINVAL), got %u\n", WSAEINVAL, err);
3278 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
3279 closesocket(s);
3280 ret = WSAConnectByNameA(s, "winehq.org", NULL, NULL, NULL, NULL, NULL, NULL, NULL);
3281 err = WSAGetLastError();
3282 ok(!ret, "WSAConnectByNameA should have failed\n");
3283 ok(err == WSAEINVAL, "expected error %u (WSAEINVAL), got %u\n", WSAEINVAL, err);
3284 closesocket(s);
3286 /* Passing NULL for the addresses and address lengths */
3287 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
3288 ret = WSAConnectByNameA(s, "winehq.org", "http", NULL, NULL, NULL, NULL, NULL, NULL);
3289 ok(ret, "WSAConnectByNameA should have succeeded, error %u\n", WSAGetLastError());
3290 closesocket(s);
3292 /* Passing NULL for the addresses and passing correct lengths */
3293 local_len = remote_len = sizeof(SOCKADDR_IN);
3294 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
3295 ret = WSAConnectByNameA(s, "winehq.org", "http", &local_len, NULL,
3296 &remote_len, NULL, NULL, NULL);
3297 ok(ret, "WSAConnectByNameA should have succeeded, error %u\n", WSAGetLastError());
3298 ok(local_len == sizeof(SOCKADDR_IN), "local_len should have been %Iu, got %ld\n", sizeof(SOCKADDR_IN),
3299 local_len);
3300 ok(remote_len == sizeof(SOCKADDR_IN), "remote_len should have been %Iu, got %ld\n", sizeof(SOCKADDR_IN),
3301 remote_len);
3302 closesocket(s);
3304 /* Passing addresses and passing short lengths */
3305 local_len = remote_len = 3;
3306 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
3307 ret = WSAConnectByNameA(s, "winehq.org", "http", &local_len, (struct sockaddr *)&local_addr,
3308 &remote_len, (struct sockaddr *)&remote_addr, NULL, NULL);
3309 err = WSAGetLastError();
3310 ok(!ret, "WSAConnectByNameA should have failed\n");
3311 ok(err == WSAEFAULT, "expected error %u (WSAEFAULT), got %u\n", WSAEFAULT, err);
3312 ok(local_len == 3, "local_len should have been 3, got %ld\n", local_len);
3313 ok(remote_len == 3, "remote_len should have been 3, got %ld\n", remote_len);
3314 closesocket(s);
3316 /* Passing addresses and passing long lengths */
3317 local_len = remote_len = 50;
3318 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
3319 ret = WSAConnectByNameA(s, "winehq.org", "http", &local_len, (struct sockaddr *)&local_addr,
3320 &remote_len, (struct sockaddr *)&remote_addr, NULL, NULL);
3321 ok(ret, "WSAConnectByNameA should have succeeded, error %u\n", WSAGetLastError());
3322 ok(local_len == sizeof(SOCKADDR_IN), "local_len should have been %Iu, got %ld\n", sizeof(SOCKADDR_IN),
3323 local_len);
3324 ok(remote_len == sizeof(SOCKADDR_IN), "remote_len should have been %Iu, got %ld\n", sizeof(SOCKADDR_IN),
3325 remote_len);
3326 closesocket(s);
3328 /* Unknown service */
3329 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
3330 ret = WSAConnectByNameA(s, "winehq.org", "nonexistentservice", NULL, NULL, NULL, NULL, NULL, NULL);
3331 err = WSAGetLastError();
3332 ok(!ret, "WSAConnectByNameA should have failed\n");
3333 ok(err == WSATYPE_NOT_FOUND, "expected error %u (WSATYPE_NOT_FOUND), got %u\n",
3334 WSATYPE_NOT_FOUND, err);
3335 closesocket(s);
3337 /* Connecting with a UDP socket */
3338 s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
3339 ret = WSAConnectByNameA(s, "winehq.org", "https", NULL, NULL, NULL, NULL, NULL, NULL);
3340 err = WSAGetLastError();
3341 ok(!ret, "WSAConnectByNameA should have failed\n");
3342 ok(err == WSAEINVAL || err == WSAEFAULT, "expected error %u (WSAEINVAL) or %u (WSAEFAULT), got %u\n",
3343 WSAEINVAL, WSAEFAULT, err); /* WSAEFAULT win10 >= 1809 */
3344 closesocket(s);
3346 /* Passing non-null as the reserved parameter */
3347 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
3348 ret = WSAConnectByNameA(s, "winehq.org", "http", NULL, NULL, NULL, NULL, NULL, &overlap);
3349 err = WSAGetLastError();
3350 ok(!ret, "WSAConnectByNameA should have failed\n");
3351 ok(err == WSAEINVAL, "expected error %u (WSAEINVAL), got %u\n", WSAEINVAL, err);
3352 closesocket(s);
3355 static void test_WSAEnumNetworkEvents(void)
3357 SOCKET s, s2;
3358 int sock_type[] = {SOCK_STREAM, SOCK_DGRAM, SOCK_STREAM}, i, j, k, l;
3359 struct sockaddr_in address;
3360 HANDLE event;
3361 WSANETWORKEVENTS net_events;
3363 memset(&address, 0, sizeof(address));
3364 address.sin_addr.s_addr = htonl(INADDR_ANY);
3365 address.sin_family = AF_INET;
3367 /* This test follows the steps from bugs 10204 and 24946 */
3368 for (l = 0; l < 2; l++)
3370 for (i = 0; i < ARRAY_SIZE(sock_type); i++)
3372 if (i == 2)
3373 tcp_socketpair(&s, &s2);
3374 else
3376 s = socket(AF_INET, sock_type[i], 0);
3377 ok (s != SOCKET_ERROR, "Test[%d]: failed to create socket\n", i);
3378 ok (!bind(s, (struct sockaddr*) &address, sizeof(address)), "Test[%d]: bind failed\n", i);
3380 event = WSACreateEvent();
3381 ok (event != NULL, "Test[%d]: failed to create event\n", i);
3382 for (j = 0; j < 5; j++) /* Repeat sometimes and the result must be the same */
3384 /* When the TCP socket is not connected NO events will be returned.
3385 * When connected and no data pending it will get the write event.
3386 * UDP sockets don't have connections so as soon as they are bound
3387 * they can read/write data. Since nobody is sendind us data only
3388 * the write event will be returned and ONLY once.
3390 ok (!WSAEventSelect(s, event, FD_READ | FD_WRITE), "Test[%d]: WSAEventSelect failed\n", i);
3391 memset(&net_events, 0xAB, sizeof(net_events));
3392 ok (!WSAEnumNetworkEvents(s, l == 0 ? event : NULL, &net_events),
3393 "Test[%d]: WSAEnumNetworkEvents failed\n", i);
3394 if (i >= 1 && j == 0) /* FD_WRITE is SET on first try for UDP and connected TCP */
3396 ok (net_events.lNetworkEvents == FD_WRITE, "Test[%d]: expected 2, got %ld\n",
3397 i, net_events.lNetworkEvents);
3399 else
3401 ok (net_events.lNetworkEvents == 0, "Test[%d]: expected 0, got %ld\n",
3402 i, net_events.lNetworkEvents);
3404 for (k = 0; k < FD_MAX_EVENTS; k++)
3406 if (net_events.lNetworkEvents & (1 << k))
3408 ok (net_events.iErrorCode[k] == 0x0, "Test[%d][%d]: expected 0x0, got 0x%x\n",
3409 i, k, net_events.iErrorCode[k]);
3411 else
3413 /* Bits that are not set in lNetworkEvents MUST not be changed */
3414 ok (net_events.iErrorCode[k] == 0xABABABAB, "Test[%d][%d]: expected 0xABABABAB, got 0x%x\n",
3415 i, k, net_events.iErrorCode[k]);
3419 closesocket(s);
3420 WSACloseEvent(event);
3421 if (i == 2) closesocket(s2);
3426 static DWORD WINAPI SelectReadThread(void *param)
3428 select_thread_params *par = param;
3429 fd_set readfds;
3430 int ret;
3431 struct sockaddr_in addr;
3432 struct timeval select_timeout;
3434 FD_ZERO(&readfds);
3435 FD_SET(par->s, &readfds);
3436 select_timeout.tv_sec=5;
3437 select_timeout.tv_usec=0;
3438 addr.sin_family = AF_INET;
3439 addr.sin_addr.s_addr = inet_addr(SERVERIP);
3440 addr.sin_port = htons(SERVERPORT);
3442 do_bind(par->s, (struct sockaddr *)&addr, sizeof(addr));
3443 wsa_ok(listen(par->s, SOMAXCONN ), 0 ==, "SelectReadThread (%lx): listen failed: %d\n");
3445 SetEvent(server_ready);
3446 ret = select(par->s+1, &readfds, NULL, NULL, &select_timeout);
3447 par->ReadKilled = (ret == 1);
3449 return 0;
3452 static DWORD WINAPI SelectCloseThread(void *param)
3454 SOCKET s = *(SOCKET*)param;
3455 Sleep(500);
3456 closesocket(s);
3457 return 0;
3460 static void test_errors(void)
3462 SOCKET sock;
3463 SOCKADDR_IN SockAddr;
3464 int ret, err;
3466 WSASetLastError(NO_ERROR);
3467 sock = socket(PF_INET, SOCK_STREAM, 0);
3468 ok( (sock != INVALID_SOCKET), "socket failed unexpectedly: %d\n", WSAGetLastError() );
3469 memset(&SockAddr, 0, sizeof(SockAddr));
3470 SockAddr.sin_family = AF_INET;
3471 SockAddr.sin_port = htons(6924);
3472 SockAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
3474 ret = connect(sock, (PSOCKADDR)&SockAddr, sizeof(SockAddr));
3475 ok( (ret == SOCKET_ERROR), "expected SOCKET_ERROR, got: %d\n", ret );
3476 if (ret == SOCKET_ERROR)
3478 err = WSAGetLastError();
3479 ok( (err == WSAECONNREFUSED), "expected WSAECONNREFUSED, got: %d\n", err );
3483 TIMEVAL timeval;
3484 fd_set set = {1, {sock}};
3486 timeval.tv_sec = 0;
3487 timeval.tv_usec = 50000;
3489 ret = select(1, NULL, &set, NULL, &timeval);
3490 ok( (ret == 0), "expected 0 (timeout), got: %d\n", ret );
3493 ret = closesocket(sock);
3494 ok ( (ret == 0), "closesocket failed unexpectedly: %d\n", WSAGetLastError());
3497 static void test_listen(void)
3499 SOCKET fdA, fdB;
3500 int ret, acceptc, olen = sizeof(acceptc);
3501 struct sockaddr_in address;
3503 memset(&address, 0, sizeof(address));
3504 address.sin_addr.s_addr = inet_addr("127.0.0.1");
3505 address.sin_family = AF_INET;
3506 address.sin_port = htons(SERVERPORT);
3508 /* invalid socket tests */
3509 SetLastError(0xdeadbeef);
3510 ok ((listen(0, 0) == SOCKET_ERROR), "listen did not fail\n");
3511 ret = WSAGetLastError();
3512 ok (ret == WSAENOTSOCK, "expected 10038, received %d\n", ret);
3514 SetLastError(0xdeadbeef);
3515 ok ((listen(0xdeadbeef, 0) == SOCKET_ERROR), "listen did not fail\n");
3516 ret = WSAGetLastError();
3517 ok (ret == WSAENOTSOCK, "expected 10038, received %d\n", ret);
3519 /* tcp tests */
3520 fdA = socket(AF_INET, SOCK_STREAM, 0);
3521 ok ((fdA != INVALID_SOCKET), "socket failed unexpectedly: %d\n", WSAGetLastError() );
3523 fdB = socket(AF_INET, SOCK_STREAM, 0);
3524 ok ((fdB != INVALID_SOCKET), "socket failed unexpectedly: %d\n", WSAGetLastError() );
3526 SetLastError(0xdeadbeef);
3527 ok ((listen(fdA, -2) == SOCKET_ERROR), "listen did not fail\n");
3528 ret = WSAGetLastError();
3529 ok (ret == WSAEINVAL, "expected 10022, received %d\n", ret);
3531 SetLastError(0xdeadbeef);
3532 ok ((listen(fdA, 1) == SOCKET_ERROR), "listen did not fail\n");
3533 ret = WSAGetLastError();
3534 ok (ret == WSAEINVAL, "expected 10022, received %d\n", ret);
3536 SetLastError(0xdeadbeef);
3537 ok ((listen(fdA, SOMAXCONN) == SOCKET_ERROR), "listen did not fail\n");
3538 ret = WSAGetLastError();
3539 ok (ret == WSAEINVAL, "expected 10022, received %d\n", ret);
3541 ok (!bind(fdA, (struct sockaddr*) &address, sizeof(address)), "bind failed\n");
3543 SetLastError(0xdeadbeef);
3544 ok (bind(fdB, (struct sockaddr*) &address, sizeof(address)), "bind should have failed\n");
3545 ok (ret == WSAEINVAL, "expected 10022, received %d\n", ret);
3547 acceptc = 0xdead;
3548 ret = getsockopt(fdA, SOL_SOCKET, SO_ACCEPTCONN, (char*)&acceptc, &olen);
3549 ok (!ret, "getsockopt failed\n");
3550 ok (acceptc == 0, "SO_ACCEPTCONN should be 0, received %d\n", acceptc);
3552 acceptc = 1;
3553 WSASetLastError(0xdeadbeef);
3554 ret = setsockopt(fdA, SOL_SOCKET, SO_ACCEPTCONN, (char *)&acceptc, sizeof(acceptc));
3555 ok(ret == -1, "expected failure\n");
3556 ok(WSAGetLastError() == WSAENOPROTOOPT, "got error %u\n", WSAGetLastError());
3558 acceptc = 0;
3559 WSASetLastError(0xdeadbeef);
3560 ret = setsockopt(fdA, SOL_SOCKET, SO_ACCEPTCONN, (char *)&acceptc, sizeof(acceptc));
3561 ok(ret == -1, "expected failure\n");
3562 ok(WSAGetLastError() == WSAENOPROTOOPT, "got error %u\n", WSAGetLastError());
3564 ok (!listen(fdA, 0), "listen failed\n");
3565 ok (!listen(fdA, SOMAXCONN), "double listen failed\n");
3567 acceptc = 0xdead;
3568 ret = getsockopt(fdA, SOL_SOCKET, SO_ACCEPTCONN, (char*)&acceptc, &olen);
3569 ok (!ret, "getsockopt failed\n");
3570 ok (acceptc == 1, "SO_ACCEPTCONN should be 1, received %d\n", acceptc);
3572 acceptc = 1;
3573 WSASetLastError(0xdeadbeef);
3574 ret = setsockopt(fdA, SOL_SOCKET, SO_ACCEPTCONN, (char *)&acceptc, sizeof(acceptc));
3575 ok(ret == -1, "expected failure\n");
3576 ok(WSAGetLastError() == WSAENOPROTOOPT, "got error %u\n", WSAGetLastError());
3578 acceptc = 0;
3579 WSASetLastError(0xdeadbeef);
3580 ret = setsockopt(fdA, SOL_SOCKET, SO_ACCEPTCONN, (char *)&acceptc, sizeof(acceptc));
3581 ok(ret == -1, "expected failure\n");
3582 ok(WSAGetLastError() == WSAENOPROTOOPT, "got error %u\n", WSAGetLastError());
3584 SetLastError(0xdeadbeef);
3585 ok ((listen(fdB, SOMAXCONN) == SOCKET_ERROR), "listen did not fail\n");
3586 ret = WSAGetLastError();
3587 ok (ret == WSAEINVAL, "expected 10022, received %d\n", ret);
3589 ret = closesocket(fdB);
3590 ok (ret == 0, "closesocket failed unexpectedly: %d\n", ret);
3592 fdB = socket(AF_INET, SOCK_STREAM, 0);
3593 ok ((fdB != INVALID_SOCKET), "socket failed unexpectedly: %d\n", WSAGetLastError() );
3595 SetLastError(0xdeadbeef);
3596 ok (bind(fdB, (struct sockaddr*) &address, sizeof(address)), "bind should have failed\n");
3597 ret = WSAGetLastError();
3598 ok (ret == WSAEADDRINUSE, "expected 10048, received %d\n", ret);
3600 ret = closesocket(fdA);
3601 ok (ret == 0, "closesocket failed unexpectedly: %d\n", ret);
3602 ret = closesocket(fdB);
3603 ok (ret == 0, "closesocket failed unexpectedly: %d\n", ret);
3606 #define FD_ZERO_ALL() { FD_ZERO(&readfds); FD_ZERO(&writefds); FD_ZERO(&exceptfds); }
3607 #define FD_SET_ALL(s) { FD_SET(s, &readfds); FD_SET(s, &writefds); FD_SET(s, &exceptfds); }
3608 static void test_select(void)
3610 static char tmp_buf[1024];
3612 fd_set readfds, writefds, exceptfds, *alloc_fds;
3613 SOCKET fdListen, fdRead, fdWrite, sockets[200];
3614 int ret, len;
3615 char buffer;
3616 struct timeval select_timeout;
3617 struct sockaddr_in address;
3618 select_thread_params thread_params;
3619 HANDLE thread_handle;
3620 DWORD ticks, id, old_protect;
3621 unsigned int apc_count;
3622 unsigned int maxfd, i;
3623 char *page_pair;
3625 fdRead = socket(AF_INET, SOCK_STREAM, 0);
3626 ok( (fdRead != INVALID_SOCKET), "socket failed unexpectedly: %d\n", WSAGetLastError() );
3627 fdWrite = socket(AF_INET, SOCK_STREAM, 0);
3628 ok( (fdWrite != INVALID_SOCKET), "socket failed unexpectedly: %d\n", WSAGetLastError() );
3630 maxfd = fdRead;
3631 if (fdWrite > maxfd)
3632 maxfd = fdWrite;
3634 FD_ZERO_ALL();
3635 FD_SET_ALL(fdRead);
3636 FD_SET_ALL(fdWrite);
3637 select_timeout.tv_sec=0;
3638 select_timeout.tv_usec=0;
3640 ticks = GetTickCount();
3641 ret = select(maxfd+1, &readfds, &writefds, &exceptfds, &select_timeout);
3642 ticks = GetTickCount() - ticks;
3643 ok(ret == 0, "select should not return any socket handles\n");
3644 ok(ticks < 100, "select was blocking for %lu ms\n", ticks);
3645 ok(!FD_ISSET(fdRead, &readfds), "FD should not be set\n");
3646 ok(!FD_ISSET(fdWrite, &writefds), "FD should not be set\n");
3647 ok(!FD_ISSET(fdRead, &exceptfds), "FD should not be set\n");
3648 ok(!FD_ISSET(fdWrite, &exceptfds), "FD should not be set\n");
3650 FD_ZERO_ALL();
3651 FD_SET_ALL(fdRead);
3652 FD_SET_ALL(fdWrite);
3653 select_timeout.tv_sec=0;
3654 select_timeout.tv_usec=500;
3656 ret = select(maxfd+1, &readfds, &writefds, &exceptfds, &select_timeout);
3657 ok(ret == 0, "select should not return any socket handles\n");
3658 ok(!FD_ISSET(fdRead, &readfds), "FD should not be set\n");
3659 ok(!FD_ISSET(fdWrite, &writefds), "FD should not be set\n");
3660 ok(!FD_ISSET(fdRead, &exceptfds), "FD should not be set\n");
3661 ok(!FD_ISSET(fdWrite, &exceptfds), "FD should not be set\n");
3663 ok ((listen(fdWrite, SOMAXCONN) == SOCKET_ERROR), "listen did not fail\n");
3664 ret = closesocket(fdWrite);
3665 ok ( (ret == 0), "closesocket failed unexpectedly: %d\n", ret);
3667 thread_params.s = fdRead;
3668 thread_params.ReadKilled = FALSE;
3669 server_ready = CreateEventA(NULL, TRUE, FALSE, NULL);
3670 thread_handle = CreateThread (NULL, 0, SelectReadThread, &thread_params, 0, &id );
3671 ok ( (thread_handle != NULL), "CreateThread failed unexpectedly: %ld\n", GetLastError());
3673 WaitForSingleObject (server_ready, INFINITE);
3674 Sleep(200);
3675 ret = closesocket(fdRead);
3676 ok ( (ret == 0), "closesocket failed unexpectedly: %d\n", ret);
3678 WaitForSingleObject (thread_handle, 1000);
3679 ok ( thread_params.ReadKilled, "closesocket did not wake up select\n");
3680 ret = recv(fdRead, &buffer, 1, MSG_PEEK);
3681 ok( (ret == -1), "peek at closed socket expected -1 got %d\n", ret);
3683 /* Test selecting invalid handles */
3684 FD_ZERO_ALL();
3686 SetLastError(0);
3687 ret = select(maxfd+1, 0, 0, 0, &select_timeout);
3688 ok ( (ret == SOCKET_ERROR), "expected SOCKET_ERROR, got %i\n", ret);
3689 ok ( WSAGetLastError() == WSAEINVAL, "expected WSAEINVAL, got %i\n", WSAGetLastError());
3691 SetLastError(0);
3692 ret = select(maxfd+1, &readfds, &writefds, &exceptfds, &select_timeout);
3693 ok ( (ret == SOCKET_ERROR), "expected SOCKET_ERROR, got %i\n", ret);
3694 ok ( WSAGetLastError() == WSAEINVAL, "expected WSAEINVAL, got %i\n", WSAGetLastError());
3696 FD_SET(INVALID_SOCKET, &readfds);
3697 SetLastError(0);
3698 ret = select(maxfd+1, &readfds, &writefds, &exceptfds, &select_timeout);
3699 ok ( (ret == SOCKET_ERROR), "expected SOCKET_ERROR, got %i\n", ret);
3700 ok ( WSAGetLastError() == WSAENOTSOCK, "expected WSAENOTSOCK, got %i\n", WSAGetLastError());
3701 ok ( !FD_ISSET(fdRead, &readfds), "FD should not be set\n");
3703 FD_ZERO(&readfds);
3704 FD_SET(INVALID_SOCKET, &writefds);
3705 SetLastError(0);
3706 ret = select(maxfd+1, &readfds, &writefds, &exceptfds, &select_timeout);
3707 ok ( (ret == SOCKET_ERROR), "expected SOCKET_ERROR, got %i\n", ret);
3708 ok ( WSAGetLastError() == WSAENOTSOCK, "expected WSAENOTSOCK, got %i\n", WSAGetLastError());
3709 ok ( !FD_ISSET(fdRead, &writefds), "FD should not be set\n");
3711 FD_ZERO(&writefds);
3712 FD_SET(INVALID_SOCKET, &exceptfds);
3713 SetLastError(0);
3714 ret = select(maxfd+1, &readfds, &writefds, &exceptfds, &select_timeout);
3715 ok ( (ret == SOCKET_ERROR), "expected SOCKET_ERROR, got %i\n", ret);
3716 ok ( WSAGetLastError() == WSAENOTSOCK, "expected WSAENOTSOCK, got %i\n", WSAGetLastError());
3717 ok ( !FD_ISSET(fdRead, &exceptfds), "FD should not be set\n");
3719 tcp_socketpair(&fdRead, &fdWrite);
3720 maxfd = fdRead;
3721 if(fdWrite > maxfd) maxfd = fdWrite;
3723 FD_ZERO(&readfds);
3724 FD_SET(fdRead, &readfds);
3725 apc_count = 0;
3726 ret = QueueUserAPC(apc_func, GetCurrentThread(), (ULONG_PTR)&apc_count);
3727 ok(ret, "QueueUserAPC returned %d\n", ret);
3728 ret = select(fdRead+1, &readfds, NULL, NULL, &select_timeout);
3729 ok(!ret, "select returned %d\n", ret);
3730 ok(apc_count == 1, "got apc_count %d.\n", apc_count);
3732 FD_ZERO(&writefds);
3733 FD_SET(fdWrite, &writefds);
3734 apc_count = 0;
3735 ret = QueueUserAPC(apc_func, GetCurrentThread(), (ULONG_PTR)&apc_count);
3736 ok(ret, "QueueUserAPC returned %d\n", ret);
3737 ret = select(fdWrite+1, NULL, &writefds, NULL, &select_timeout);
3738 ok(ret == 1, "select returned %d\n", ret);
3739 ok(FD_ISSET(fdWrite, &writefds), "fdWrite socket is not in the set\n");
3740 ok(!apc_count, "APC was called\n");
3741 SleepEx(0, TRUE);
3742 ok(apc_count == 1, "got apc_count %d.\n", apc_count);
3744 /* select the same socket twice */
3745 writefds.fd_count = 2;
3746 writefds.fd_array[0] = fdWrite;
3747 writefds.fd_array[1] = fdWrite;
3748 ret = select(0, NULL, &writefds, NULL, &select_timeout);
3749 ok(ret == 1, "select returned %d\n", ret);
3750 ok(writefds.fd_count == 1, "got count %u\n", writefds.fd_count);
3751 ok(writefds.fd_array[0] == fdWrite, "got fd %#Ix\n", writefds.fd_array[0]);
3752 ok(writefds.fd_array[1] == fdWrite, "got fd %#Ix\n", writefds.fd_array[1]);
3754 /* tests for overlapping fd_set pointers */
3755 FD_ZERO(&readfds);
3756 FD_SET(fdWrite, &readfds);
3757 ret = select(fdWrite+1, &readfds, &readfds, NULL, &select_timeout);
3758 ok(ret == 1, "select returned %d\n", ret);
3759 ok(FD_ISSET(fdWrite, &readfds), "fdWrite socket is not in the set\n");
3761 FD_ZERO(&readfds);
3762 FD_SET(fdWrite, &readfds);
3763 FD_SET(fdRead, &readfds);
3764 ret = select(maxfd+1, &readfds, &readfds, NULL, &select_timeout);
3765 ok(ret == 2, "select returned %d\n", ret);
3766 ok(FD_ISSET(fdWrite, &readfds), "fdWrite socket is not in the set\n");
3767 ok(FD_ISSET(fdRead, &readfds), "fdRead socket is not in the set\n");
3769 ok(send(fdWrite, "test", 4, 0) == 4, "failed to send data\n");
3770 FD_ZERO(&readfds);
3771 FD_SET(fdRead, &readfds);
3772 ret = select(fdRead+1, &readfds, NULL, NULL, &select_timeout);
3773 ok(ret == 1, "select returned %d\n", ret);
3774 ok(FD_ISSET(fdRead, &readfds), "fdRead socket is not in the set\n");
3776 FD_ZERO(&readfds);
3777 FD_SET(fdWrite, &readfds);
3778 FD_SET(fdRead, &readfds);
3779 ret = select(maxfd+1, &readfds, &readfds, NULL, &select_timeout);
3780 ok(ret == 2, "select returned %d\n", ret);
3781 ok(FD_ISSET(fdWrite, &readfds), "fdWrite socket is not in the set\n");
3782 ok(FD_ISSET(fdRead, &readfds), "fdRead socket is not in the set\n");
3784 while(1) {
3785 FD_ZERO(&writefds);
3786 FD_SET(fdWrite, &writefds);
3787 ret = select(fdWrite+1, NULL, &writefds, NULL, &select_timeout);
3788 if(!ret) break;
3789 ok(send(fdWrite, tmp_buf, sizeof(tmp_buf), 0) > 0, "failed to send data\n");
3791 FD_ZERO(&readfds);
3792 FD_SET(fdWrite, &readfds);
3793 FD_SET(fdRead, &readfds);
3794 ret = select(maxfd+1, &readfds, &readfds, NULL, &select_timeout);
3795 ok(ret == 1, "select returned %d\n", ret);
3796 ok(!FD_ISSET(fdWrite, &readfds), "fdWrite socket is in the set\n");
3797 ok(FD_ISSET(fdRead, &readfds), "fdRead socket is not in the set\n");
3799 ok(send(fdRead, "test", 4, 0) == 4, "failed to send data\n");
3800 Sleep(100);
3801 FD_ZERO(&readfds);
3802 FD_SET(fdWrite, &readfds);
3803 FD_SET(fdRead, &readfds);
3804 ret = select(maxfd+1, &readfds, &readfds, NULL, &select_timeout);
3805 ok(ret == 2, "select returned %d\n", ret);
3806 ok(FD_ISSET(fdWrite, &readfds), "fdWrite socket is not in the set\n");
3807 ok(FD_ISSET(fdRead, &readfds), "fdRead socket is not in the set\n");
3809 page_pair = VirtualAlloc(NULL, 0x1000 * 2, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
3810 VirtualProtect(page_pair + 0x1000, 0x1000, PAGE_NOACCESS, &old_protect);
3811 alloc_fds = (fd_set *)((page_pair + 0x1000) - offsetof(fd_set, fd_array[1]));
3812 alloc_fds->fd_count = 1;
3813 alloc_fds->fd_array[0] = fdRead;
3814 ret = select(fdRead+1, alloc_fds, NULL, NULL, &select_timeout);
3815 ok(ret == 1, "select returned %d\n", ret);
3816 VirtualFree(page_pair, 0, MEM_RELEASE);
3818 closesocket(fdRead);
3819 closesocket(fdWrite);
3821 alloc_fds = malloc(offsetof(fd_set, fd_array[ARRAY_SIZE(sockets)]));
3822 alloc_fds->fd_count = ARRAY_SIZE(sockets);
3823 for (i = 0; i < ARRAY_SIZE(sockets); i += 2)
3825 tcp_socketpair(&sockets[i], &sockets[i + 1]);
3826 alloc_fds->fd_array[i] = sockets[i];
3827 alloc_fds->fd_array[i + 1] = sockets[i + 1];
3829 ret = select(0, NULL, alloc_fds, NULL, &select_timeout);
3830 ok(ret == ARRAY_SIZE(sockets), "got %d\n", ret);
3831 for (i = 0; i < ARRAY_SIZE(sockets); ++i)
3833 ok(alloc_fds->fd_array[i] == sockets[i], "got socket %#Ix at index %u\n", alloc_fds->fd_array[i], i);
3834 closesocket(sockets[i]);
3836 free(alloc_fds);
3838 /* select() works in 3 distinct states:
3839 * - to check if a connection attempt ended with success or error;
3840 * - to check if a pending connection is waiting for acceptance;
3841 * - to check for data to read, availability for write and OOB data
3843 * The tests below ensure that all conditions are tested.
3845 memset(&address, 0, sizeof(address));
3846 address.sin_addr.s_addr = inet_addr("127.0.0.1");
3847 address.sin_family = AF_INET;
3848 len = sizeof(address);
3849 fdListen = setup_server_socket(&address, &len);
3850 select_timeout.tv_sec = 1;
3851 select_timeout.tv_usec = 250000;
3853 /* When no events are pending select returns 0 with no error */
3854 FD_ZERO_ALL();
3855 FD_SET_ALL(fdListen);
3856 ret = select(0, &readfds, &writefds, &exceptfds, &select_timeout);
3857 ok(ret == 0, "expected 0, got %d\n", ret);
3859 /* When a socket is attempting to connect the listening socket receives the read descriptor */
3860 fdWrite = setup_connector_socket(&address, len, TRUE);
3861 FD_ZERO_ALL();
3862 FD_SET_ALL(fdListen);
3863 ret = select(0, &readfds, &writefds, &exceptfds, &select_timeout);
3864 ok(ret == 1, "expected 1, got %d\n", ret);
3865 ok(FD_ISSET(fdListen, &readfds), "fdListen socket is not in the set\n");
3866 len = sizeof(address);
3867 fdRead = accept(fdListen, (struct sockaddr*) &address, &len);
3868 ok(fdRead != INVALID_SOCKET, "expected a valid socket\n");
3870 /* The connector is signaled through the write descriptor */
3871 FD_ZERO_ALL();
3872 FD_SET_ALL(fdListen);
3873 FD_SET_ALL(fdRead);
3874 FD_SET_ALL(fdWrite);
3875 ret = select(0, &readfds, &writefds, &exceptfds, &select_timeout);
3876 ok(ret == 2, "expected 2, got %d\n", ret);
3877 ok(FD_ISSET(fdWrite, &writefds), "fdWrite socket is not in the set\n");
3878 ok(FD_ISSET(fdRead, &writefds), "fdRead socket is not in the set\n");
3879 len = sizeof(id);
3880 id = 0xdeadbeef;
3881 ret = getsockopt(fdWrite, SOL_SOCKET, SO_ERROR, (char*)&id, &len);
3882 ok(!ret, "getsockopt failed with %d\n", WSAGetLastError());
3883 ok(id == 0, "expected 0, got %ld\n", id);
3885 /* When data is received the receiver gets the read descriptor */
3886 ret = send(fdWrite, "1234", 4, 0);
3887 ok(ret == 4, "expected 4, got %d\n", ret);
3888 FD_ZERO_ALL();
3889 FD_SET_ALL(fdListen);
3890 FD_SET(fdRead, &readfds);
3891 FD_SET(fdRead, &exceptfds);
3892 ret = select(0, &readfds, &writefds, &exceptfds, &select_timeout);
3893 ok(ret == 1, "expected 1, got %d\n", ret);
3894 ok(FD_ISSET(fdRead, &readfds), "fdRead socket is not in the set\n");
3895 ok(!FD_ISSET(fdRead, &exceptfds), "fdRead socket is in the set\n");
3896 FD_ZERO_ALL();
3897 FD_SET_ALL(fdRead);
3898 ret = select(0, &readfds, &writefds, &exceptfds, &select_timeout);
3899 ok(ret == 2, "expected 1, got %d\n", ret);
3900 ok(FD_ISSET(fdRead, &readfds), "fdRead socket is not in the set\n");
3901 ok(FD_ISSET(fdRead, &writefds), "fdRead socket is not in the set\n");
3902 ok(!FD_ISSET(fdRead, &exceptfds), "fdRead socket is in the set\n");
3903 ret = recv(fdRead, tmp_buf, sizeof(tmp_buf), 0);
3904 ok(ret == 4, "expected 4, got %d\n", ret);
3905 ok(!strcmp(tmp_buf, "1234"), "data received differs from sent\n");
3907 /* When OOB data is received the socket is set in the except descriptor */
3908 ret = send(fdWrite, "A", 1, MSG_OOB);
3909 ok(ret == 1, "expected 1, got %d\n", ret);
3910 FD_ZERO_ALL();
3911 FD_SET_ALL(fdListen);
3912 FD_SET(fdRead, &readfds);
3913 FD_SET(fdRead, &exceptfds);
3914 ret = select(0, &readfds, &writefds, &exceptfds, &select_timeout);
3915 ok(ret == 1, "expected 1, got %d\n", ret);
3916 ok(FD_ISSET(fdRead, &exceptfds), "fdRead socket is not in the set\n");
3917 tmp_buf[0] = 0xAF;
3918 ret = recv(fdRead, tmp_buf, sizeof(tmp_buf), MSG_OOB);
3919 ok(ret == 1, "expected 1, got %d\n", ret);
3920 ok(tmp_buf[0] == 'A', "expected 'A', got 0x%02X\n", tmp_buf[0]);
3922 /* If the socket is OOBINLINED it will not receive the OOB in except fds */
3923 ret = 1;
3924 ret = setsockopt(fdRead, SOL_SOCKET, SO_OOBINLINE, (char*) &ret, sizeof(ret));
3925 ok(ret == 0, "expected 0, got %d\n", ret);
3926 ret = send(fdWrite, "A", 1, MSG_OOB);
3927 ok(ret == 1, "expected 1, got %d\n", ret);
3928 FD_ZERO_ALL();
3929 FD_SET_ALL(fdListen);
3930 FD_SET(fdRead, &readfds);
3931 FD_SET(fdRead, &exceptfds);
3932 ret = select(0, &readfds, &writefds, &exceptfds, &select_timeout);
3933 ok(ret == 1, "expected 1, got %d\n", ret);
3934 ok(FD_ISSET(fdRead, &readfds), "fdRead socket is not in the set\n");
3935 tmp_buf[0] = 0xAF;
3936 SetLastError(0xdeadbeef);
3937 ret = recv(fdRead, tmp_buf, sizeof(tmp_buf), MSG_OOB);
3938 ok(ret == SOCKET_ERROR, "expected SOCKET_ERROR, got %d\n", ret);
3939 ok(GetLastError() == WSAEINVAL, "expected 10022, got %ld\n", GetLastError());
3940 ret = recv(fdRead, tmp_buf, sizeof(tmp_buf), 0);
3941 ok(ret == 1, "expected 1, got %d\n", ret);
3942 ok(tmp_buf[0] == 'A', "expected 'A', got 0x%02X\n", tmp_buf[0]);
3944 /* When the connection is closed the socket is set in the read descriptor */
3945 ret = closesocket(fdRead);
3946 ok(ret == 0, "expected 0, got %d\n", ret);
3947 FD_ZERO_ALL();
3948 FD_SET_ALL(fdListen);
3949 FD_SET(fdWrite, &readfds);
3950 ret = select(0, &readfds, &writefds, &exceptfds, &select_timeout);
3951 ok(ret == 1, "expected 1, got %d\n", ret);
3952 ok(FD_ISSET(fdWrite, &readfds), "fdWrite socket is not in the set\n");
3953 ret = recv(fdWrite, tmp_buf, sizeof(tmp_buf), 0);
3954 ok(ret == 0, "expected 0, got %d\n", ret);
3955 ret = closesocket(fdWrite);
3956 ok(ret == 0, "expected 0, got %d\n", ret);
3958 /* w10pro64 sometimes takes over 2 seconds for an error to be reported. */
3959 if (winetest_interactive)
3961 const struct sockaddr_in invalid_addr =
3963 .sin_family = AF_INET,
3964 .sin_addr.s_addr = htonl(INADDR_LOOPBACK),
3965 .sin_port = 255,
3968 fdWrite = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
3969 set_blocking(fdWrite, FALSE);
3971 ret = connect(fdWrite, (struct sockaddr *)&invalid_addr, sizeof(invalid_addr));
3972 ok(ret == -1, "got %d\n", ret);
3973 ok(WSAGetLastError() == WSAEWOULDBLOCK, "got error %u\n", WSAGetLastError());
3975 FD_ZERO_ALL();
3976 FD_SET(fdWrite, &readfds);
3977 FD_SET(fdWrite, &writefds);
3978 FD_SET(fdWrite, &exceptfds);
3979 select_timeout.tv_sec = 10;
3980 ret = select(0, &readfds, &writefds, &exceptfds, &select_timeout);
3981 ok(ret == 1, "expected 1, got %d\n", ret);
3982 ok(FD_ISSET(fdWrite, &exceptfds), "fdWrite socket is not in the set\n");
3983 ok(select_timeout.tv_usec == 250000, "select timeout should not have changed\n");
3985 len = sizeof(id);
3986 id = 0xdeadbeef;
3987 ret = getsockopt(fdWrite, SOL_SOCKET, SO_ERROR, (char *)&id, &len);
3988 ok(!ret, "getsockopt failed with %d\n", WSAGetLastError());
3989 ok(id == WSAECONNREFUSED, "got error %lu\n", id);
3991 len = sizeof(id);
3992 id = 0xdeadbeef;
3993 ret = getsockopt(fdWrite, SOL_SOCKET, SO_ERROR, (char *)&id, &len);
3994 ok(!ret, "getsockopt failed with %d\n", WSAGetLastError());
3995 ok(id == WSAECONNREFUSED, "got error %lu\n", id);
3997 FD_ZERO_ALL();
3998 FD_SET(fdWrite, &readfds);
3999 FD_SET(fdWrite, &writefds);
4000 FD_SET(fdWrite, &exceptfds);
4001 select_timeout.tv_sec = 10;
4002 ret = select(0, &readfds, &writefds, &exceptfds, &select_timeout);
4003 ok(ret == 1, "got %d\n", ret);
4004 ok(FD_ISSET(fdWrite, &exceptfds), "fdWrite socket is not in the set\n");
4006 /* Calling connect() doesn't reset the socket error, but a successful
4007 * connection does. This is kind of tricky to test, because while
4008 * Windows takes a couple seconds to actually fail the connection,
4009 * Linux will fail the connection almost immediately. */
4011 ret = connect(fdWrite, (const struct sockaddr *)&invalid_addr, sizeof(invalid_addr));
4012 ok(ret == -1, "got %d\n", ret);
4013 todo_wine ok(WSAGetLastError() == WSAEWOULDBLOCK, "got error %u\n", WSAGetLastError());
4014 if (WSAGetLastError() == WSAECONNABORTED)
4016 ret = connect(fdWrite, (const struct sockaddr *)&invalid_addr, sizeof(invalid_addr));
4017 ok(ret == -1, "got %d\n", ret);
4018 ok(WSAGetLastError() == WSAEWOULDBLOCK, "got error %u\n", WSAGetLastError());
4021 len = sizeof(id);
4022 id = 0xdeadbeef;
4023 ret = getsockopt(fdWrite, SOL_SOCKET, SO_ERROR, (char *)&id, &len);
4024 ok(!ret, "getsockopt failed with %d\n", WSAGetLastError());
4025 ok(id == WSAECONNREFUSED, "got error %lu\n", id);
4027 FD_ZERO_ALL();
4028 FD_SET(fdWrite, &readfds);
4029 FD_SET(fdWrite, &writefds);
4030 FD_SET(fdWrite, &exceptfds);
4031 select_timeout.tv_sec = 10;
4032 ret = select(0, &readfds, &writefds, &exceptfds, &select_timeout);
4033 ok(ret == 1, "got %d\n", ret);
4034 ok(FD_ISSET(fdWrite, &exceptfds), "fdWrite socket is not in the set\n");
4036 len = sizeof(address);
4037 ret = getsockname(fdListen, (struct sockaddr *)&address, &len);
4038 ok(!ret, "got error %u\n", WSAGetLastError());
4039 ret = connect(fdWrite, (const struct sockaddr *)&address, sizeof(address));
4040 ok(ret == -1, "got %d\n", ret);
4041 todo_wine ok(WSAGetLastError() == WSAEWOULDBLOCK, "got error %u\n", WSAGetLastError());
4042 if (WSAGetLastError() == WSAECONNABORTED)
4044 ret = connect(fdWrite, (const struct sockaddr *)&address, sizeof(address));
4045 ok(ret == -1, "got %d\n", ret);
4046 ok(WSAGetLastError() == WSAEWOULDBLOCK, "got error %u\n", WSAGetLastError());
4049 FD_ZERO_ALL();
4050 FD_SET(fdWrite, &readfds);
4051 FD_SET(fdWrite, &writefds);
4052 FD_SET(fdWrite, &exceptfds);
4053 select_timeout.tv_sec = 1;
4054 ret = select(0, &readfds, &writefds, &exceptfds, &select_timeout);
4055 ok(ret == 1, "expected 1, got %d\n", ret);
4056 ok(FD_ISSET(fdWrite, &writefds), "fdWrite socket is not in the set\n");
4058 len = sizeof(id);
4059 id = 0xdeadbeef;
4060 ret = getsockopt(fdWrite, SOL_SOCKET, SO_ERROR, (char *)&id, &len);
4061 ok(!ret, "getsockopt failed with %d\n", WSAGetLastError());
4062 ok(!id, "got error %lu\n", id);
4064 closesocket(fdWrite);
4066 /* test polling after a (synchronous) failure */
4068 fdWrite = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
4070 ret = connect(fdWrite, (const struct sockaddr *)&invalid_addr, sizeof(invalid_addr));
4071 ok(ret == -1, "got %d\n", ret);
4072 ok(WSAGetLastError() == WSAECONNREFUSED, "got error %u\n", WSAGetLastError());
4074 FD_ZERO_ALL();
4075 FD_SET(fdWrite, &readfds);
4076 FD_SET(fdWrite, &writefds);
4077 FD_SET(fdWrite, &exceptfds);
4078 select_timeout.tv_sec = 0;
4079 ret = select(0, &readfds, &writefds, &exceptfds, &select_timeout);
4080 ok(ret == 1, "expected 1, got %d\n", ret);
4081 ok(FD_ISSET(fdWrite, &exceptfds), "fdWrite socket is not in the set\n");
4083 len = sizeof(id);
4084 id = 0xdeadbeef;
4085 ret = getsockopt(fdWrite, SOL_SOCKET, SO_ERROR, (char *)&id, &len);
4086 ok(!ret, "getsockopt failed with %d\n", WSAGetLastError());
4087 todo_wine ok(!id, "got error %lu\n", id);
4089 closesocket(fdWrite);
4092 ret = closesocket(fdListen);
4093 ok(ret == 0, "expected 0, got %d\n", ret);
4095 select_timeout.tv_sec = 1;
4096 select_timeout.tv_usec = 250000;
4098 /* Try select() on a closed socket after connection */
4099 tcp_socketpair(&fdRead, &fdWrite);
4100 closesocket(fdRead);
4101 FD_ZERO_ALL();
4102 FD_SET_ALL(fdWrite);
4103 FD_SET_ALL(fdRead);
4104 SetLastError(0xdeadbeef);
4105 ret = select(0, &readfds, NULL, &exceptfds, &select_timeout);
4106 ok(ret == SOCKET_ERROR, "expected -1, got %d\n", ret);
4107 ok(GetLastError() == WSAENOTSOCK, "got %ld\n", GetLastError());
4108 /* descriptor sets are unchanged */
4109 ok(readfds.fd_count == 2, "expected 2, got %d\n", readfds.fd_count);
4110 ok(exceptfds.fd_count == 2, "expected 2, got %d\n", exceptfds.fd_count);
4111 closesocket(fdWrite);
4113 /* Close the socket currently being selected in a thread - bug 38399 */
4114 tcp_socketpair(&fdRead, &fdWrite);
4115 thread_handle = CreateThread(NULL, 0, SelectCloseThread, &fdWrite, 0, &id);
4116 ok(thread_handle != NULL, "CreateThread failed unexpectedly: %ld\n", GetLastError());
4117 FD_ZERO_ALL();
4118 FD_SET_ALL(fdWrite);
4119 ret = select(0, &readfds, NULL, &exceptfds, &select_timeout);
4120 ok(ret == 1, "expected 1, got %d\n", ret);
4121 ok(FD_ISSET(fdWrite, &readfds), "fdWrite socket is not in the set\n");
4122 WaitForSingleObject (thread_handle, 1000);
4123 closesocket(fdRead);
4124 /* test again with only the except descriptor */
4125 tcp_socketpair(&fdRead, &fdWrite);
4126 thread_handle = CreateThread(NULL, 0, SelectCloseThread, &fdWrite, 0, &id);
4127 ok(thread_handle != NULL, "CreateThread failed unexpectedly: %ld\n", GetLastError());
4128 FD_ZERO_ALL();
4129 FD_SET(fdWrite, &exceptfds);
4130 SetLastError(0xdeadbeef);
4131 ret = select(0, NULL, NULL, &exceptfds, &select_timeout);
4132 ok(ret == SOCKET_ERROR, "expected -1, got %d\n", ret);
4133 ok(GetLastError() == WSAENOTSOCK, "got %ld\n", GetLastError());
4134 ok(!FD_ISSET(fdWrite, &exceptfds), "fdWrite socket is in the set\n");
4135 WaitForSingleObject (thread_handle, 1000);
4136 closesocket(fdRead);
4138 /* test UDP behavior of unbound sockets */
4139 select_timeout.tv_sec = 0;
4140 select_timeout.tv_usec = 250000;
4141 fdWrite = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
4142 ok(fdWrite != INVALID_SOCKET, "socket call failed\n");
4143 FD_ZERO_ALL();
4144 FD_SET_ALL(fdWrite);
4145 ret = select(0, &readfds, &writefds, &exceptfds, &select_timeout);
4146 ok(ret == 1, "expected 1, got %d\n", ret);
4147 ok(FD_ISSET(fdWrite, &writefds), "fdWrite socket is not in the set\n");
4148 closesocket(fdWrite);
4150 #undef FD_SET_ALL
4151 #undef FD_ZERO_ALL
4153 static DWORD WINAPI AcceptKillThread(void *param)
4155 select_thread_params *par = param;
4156 struct sockaddr_in address;
4157 int len = sizeof(address);
4158 SOCKET client_socket;
4160 SetEvent(server_ready);
4161 client_socket = accept(par->s, (struct sockaddr*) &address, &len);
4162 if (client_socket != INVALID_SOCKET)
4163 closesocket(client_socket);
4164 par->ReadKilled = (client_socket == INVALID_SOCKET);
4165 return 0;
4169 static int CALLBACK AlwaysDeferConditionFunc(LPWSABUF lpCallerId, LPWSABUF lpCallerData, LPQOS pQos,
4170 LPQOS lpGQOS, LPWSABUF lpCalleeId, LPWSABUF lpCalleeData,
4171 GROUP *g, DWORD_PTR dwCallbackData)
4173 return CF_DEFER;
4176 static SOCKET setup_server_socket(struct sockaddr_in *addr, int *len)
4178 int ret, val;
4179 SOCKET server_socket;
4181 server_socket = socket(AF_INET, SOCK_STREAM, 0);
4182 ok(server_socket != INVALID_SOCKET, "failed to bind socket, error %u\n", WSAGetLastError());
4184 val = 1;
4185 ret = setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val));
4186 ok(!ret, "failed to set SO_REUSEADDR, error %u\n", WSAGetLastError());
4188 ret = bind(server_socket, (struct sockaddr *)addr, *len);
4189 ok(!ret, "failed to bind socket, error %u\n", WSAGetLastError());
4191 ret = getsockname(server_socket, (struct sockaddr *)addr, len);
4192 ok(!ret, "failed to get address, error %u\n", WSAGetLastError());
4194 ret = listen(server_socket, 5);
4195 ok(!ret, "failed to listen, error %u\n", WSAGetLastError());
4197 return server_socket;
4200 static SOCKET setup_connector_socket(const struct sockaddr_in *addr, int len, BOOL nonblock)
4202 int ret;
4203 SOCKET connector;
4205 connector = socket(AF_INET, SOCK_STREAM, 0);
4206 ok(connector != INVALID_SOCKET, "failed to create connector socket %d\n", WSAGetLastError());
4208 if (nonblock)
4209 set_blocking(connector, !nonblock);
4211 ret = connect(connector, (const struct sockaddr *)addr, len);
4212 if (!nonblock)
4213 ok(!ret, "connecting to accepting socket failed %d\n", WSAGetLastError());
4214 else if (ret == SOCKET_ERROR)
4215 ok(WSAGetLastError() == WSAEWOULDBLOCK, "got error %u\n", WSAGetLastError());
4217 return connector;
4220 static void test_accept(void)
4222 int ret;
4223 SOCKET server_socket, accepted = INVALID_SOCKET, connector;
4224 struct sockaddr_in address;
4225 SOCKADDR_STORAGE ss, ss_empty;
4226 int socklen;
4227 select_thread_params thread_params;
4228 HANDLE thread_handle = NULL;
4229 DWORD id;
4231 memset(&address, 0, sizeof(address));
4232 address.sin_addr.s_addr = inet_addr("127.0.0.1");
4233 address.sin_family = AF_INET;
4235 socklen = sizeof(address);
4236 server_socket = setup_server_socket(&address, &socklen);
4238 connector = setup_connector_socket(&address, socklen, FALSE);
4239 if (connector == INVALID_SOCKET) goto done;
4241 accepted = WSAAccept(server_socket, NULL, NULL, AlwaysDeferConditionFunc, 0);
4242 ok(accepted == INVALID_SOCKET && WSAGetLastError() == WSATRY_AGAIN, "Failed to defer connection, %d\n", WSAGetLastError());
4244 accepted = accept(server_socket, NULL, 0);
4245 ok(accepted != INVALID_SOCKET, "Failed to accept deferred connection, error %d\n", WSAGetLastError());
4247 server_ready = CreateEventA(NULL, TRUE, FALSE, NULL);
4249 thread_params.s = server_socket;
4250 thread_params.ReadKilled = FALSE;
4251 thread_handle = CreateThread(NULL, 0, AcceptKillThread, &thread_params, 0, &id);
4253 WaitForSingleObject(server_ready, INFINITE);
4254 Sleep(200);
4255 ret = closesocket(server_socket);
4256 ok(!ret, "failed to close socket, error %u\n", WSAGetLastError());
4258 WaitForSingleObject(thread_handle, 1000);
4259 ok(thread_params.ReadKilled, "closesocket did not wake up accept\n");
4261 closesocket(accepted);
4262 closesocket(connector);
4263 accepted = connector = INVALID_SOCKET;
4265 socklen = sizeof(address);
4266 server_socket = setup_server_socket(&address, &socklen);
4268 connector = setup_connector_socket(&address, socklen, FALSE);
4269 if (connector == INVALID_SOCKET) goto done;
4271 socklen = 0;
4272 accepted = WSAAccept(server_socket, (struct sockaddr *)&ss, &socklen, NULL, 0);
4273 ok(accepted == INVALID_SOCKET && WSAGetLastError() == WSAEFAULT, "got %d\n", WSAGetLastError());
4274 ok(!socklen, "got %d\n", socklen);
4275 closesocket(connector);
4276 connector = INVALID_SOCKET;
4278 socklen = sizeof(address);
4279 connector = setup_connector_socket(&address, socklen, FALSE);
4280 if (connector == INVALID_SOCKET) goto done;
4282 accepted = WSAAccept(server_socket, NULL, NULL, NULL, 0);
4283 ok(accepted != INVALID_SOCKET, "Failed to accept connection, %d\n", WSAGetLastError());
4284 closesocket(accepted);
4285 closesocket(connector);
4286 accepted = connector = INVALID_SOCKET;
4288 socklen = sizeof(address);
4289 connector = setup_connector_socket(&address, socklen, FALSE);
4290 if (connector == INVALID_SOCKET) goto done;
4292 socklen = sizeof(ss);
4293 memset(&ss, 0, sizeof(ss));
4294 accepted = WSAAccept(server_socket, (struct sockaddr *)&ss, &socklen, NULL, 0);
4295 ok(accepted != INVALID_SOCKET, "Failed to accept connection, %d\n", WSAGetLastError());
4296 ok(socklen != sizeof(ss), "unexpected length\n");
4297 ok(ss.ss_family, "family not set\n");
4298 closesocket(accepted);
4299 closesocket(connector);
4300 accepted = connector = INVALID_SOCKET;
4302 socklen = sizeof(address);
4303 connector = setup_connector_socket(&address, socklen, FALSE);
4304 if (connector == INVALID_SOCKET) goto done;
4306 socklen = 0;
4307 accepted = accept(server_socket, (struct sockaddr *)&ss, &socklen);
4308 ok(accepted == INVALID_SOCKET && WSAGetLastError() == WSAEFAULT, "got %d\n", WSAGetLastError());
4309 ok(!socklen, "got %d\n", socklen);
4310 closesocket(connector);
4311 accepted = connector = INVALID_SOCKET;
4313 socklen = sizeof(address);
4314 connector = setup_connector_socket(&address, socklen, FALSE);
4315 if (connector == INVALID_SOCKET) goto done;
4317 accepted = accept(server_socket, NULL, NULL);
4318 ok(accepted != INVALID_SOCKET, "Failed to accept connection, %d\n", WSAGetLastError());
4319 closesocket(accepted);
4320 closesocket(connector);
4321 accepted = connector = INVALID_SOCKET;
4323 socklen = sizeof(address);
4324 connector = setup_connector_socket(&address, socklen, FALSE);
4325 if (connector == INVALID_SOCKET) goto done;
4327 socklen = sizeof(ss);
4328 memset(&ss, 0, sizeof(ss));
4329 accepted = accept(server_socket, (struct sockaddr *)&ss, &socklen);
4330 ok(accepted != INVALID_SOCKET, "Failed to accept connection, %d\n", WSAGetLastError());
4331 ok(socklen != sizeof(ss), "unexpected length\n");
4332 ok(ss.ss_family, "family not set\n");
4333 closesocket(accepted);
4334 closesocket(connector);
4335 accepted = connector = INVALID_SOCKET;
4337 socklen = sizeof(address);
4338 connector = setup_connector_socket(&address, socklen, FALSE);
4339 if (connector == INVALID_SOCKET) goto done;
4341 memset(&ss, 0, sizeof(ss));
4342 memset(&ss_empty, 0, sizeof(ss_empty));
4343 accepted = accept(server_socket, (struct sockaddr *)&ss, NULL);
4344 ok(accepted != INVALID_SOCKET, "Failed to accept connection, %d\n", WSAGetLastError());
4345 ok(!memcmp(&ss, &ss_empty, sizeof(ss)), "structure is different\n");
4347 done:
4348 if (accepted != INVALID_SOCKET)
4349 closesocket(accepted);
4350 if (connector != INVALID_SOCKET)
4351 closesocket(connector);
4352 if (thread_handle != NULL)
4353 CloseHandle(thread_handle);
4354 if (server_ready != INVALID_HANDLE_VALUE)
4355 CloseHandle(server_ready);
4356 if (server_socket != INVALID_SOCKET)
4357 closesocket(server_socket);
4360 static void test_extendedSocketOptions(void)
4362 WSADATA wsa;
4363 SOCKET sock;
4364 struct sockaddr_in sa;
4365 int sa_len = sizeof(struct sockaddr_in);
4366 int optval, optlen = sizeof(int), ret;
4367 BOOL bool_opt_val;
4368 LINGER linger_val;
4370 ret = WSAStartup(MAKEWORD(2,0), &wsa);
4371 ok(!ret, "failed to startup, error %u\n", WSAGetLastError());
4373 memset(&sa, 0, sa_len);
4375 sa.sin_family = AF_INET;
4376 sa.sin_port = htons(0);
4377 sa.sin_addr.s_addr = htonl(INADDR_ANY);
4379 sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
4380 ok(sock != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
4382 ret = bind(sock, (struct sockaddr *) &sa, sa_len);
4383 ok(!ret, "failed to bind socket, error %u\n", WSAGetLastError());
4385 ret = getsockopt(sock, SOL_SOCKET, SO_MAX_MSG_SIZE, (char *)&optval, &optlen);
4387 ok(ret == 0, "getsockopt failed to query SO_MAX_MSG_SIZE, return value is 0x%08x\n", ret);
4388 ok((optval == 65507) || (optval == 65527),
4389 "SO_MAX_MSG_SIZE reported %d, expected 65507 or 65527\n", optval);
4391 /* IE 3 use 0xffffffff instead of SOL_SOCKET (0xffff) */
4392 SetLastError(0xdeadbeef);
4393 optval = 0xdeadbeef;
4394 optlen = sizeof(int);
4395 ret = getsockopt(sock, 0xffffffff, SO_MAX_MSG_SIZE, (char *)&optval, &optlen);
4396 ok( (ret == SOCKET_ERROR) && (WSAGetLastError() == WSAEINVAL),
4397 "got %d with %d and optval: 0x%x/%d (expected SOCKET_ERROR with WSAEINVAL)\n",
4398 ret, WSAGetLastError(), optval, optval);
4400 /* more invalid values for level */
4401 SetLastError(0xdeadbeef);
4402 optval = 0xdeadbeef;
4403 optlen = sizeof(int);
4404 ret = getsockopt(sock, 0x1234ffff, SO_MAX_MSG_SIZE, (char *)&optval, &optlen);
4405 ok( (ret == SOCKET_ERROR) && (WSAGetLastError() == WSAEINVAL),
4406 "got %d with %d and optval: 0x%x/%d (expected SOCKET_ERROR with WSAEINVAL)\n",
4407 ret, WSAGetLastError(), optval, optval);
4409 SetLastError(0xdeadbeef);
4410 optval = 0xdeadbeef;
4411 optlen = sizeof(int);
4412 ret = getsockopt(sock, 0x8000ffff, SO_MAX_MSG_SIZE, (char *)&optval, &optlen);
4413 ok( (ret == SOCKET_ERROR) && (WSAGetLastError() == WSAEINVAL),
4414 "got %d with %d and optval: 0x%x/%d (expected SOCKET_ERROR with WSAEINVAL)\n",
4415 ret, WSAGetLastError(), optval, optval);
4417 SetLastError(0xdeadbeef);
4418 optval = 0xdeadbeef;
4419 optlen = sizeof(int);
4420 ret = getsockopt(sock, 0x00008000, SO_MAX_MSG_SIZE, (char *)&optval, &optlen);
4421 ok( (ret == SOCKET_ERROR) && (WSAGetLastError() == WSAEINVAL),
4422 "got %d with %d and optval: 0x%x/%d (expected SOCKET_ERROR with WSAEINVAL)\n",
4423 ret, WSAGetLastError(), optval, optval);
4425 SetLastError(0xdeadbeef);
4426 optval = 0xdeadbeef;
4427 optlen = sizeof(int);
4428 ret = getsockopt(sock, 0x00000800, SO_MAX_MSG_SIZE, (char *)&optval, &optlen);
4429 ok( (ret == SOCKET_ERROR) && (WSAGetLastError() == WSAEINVAL),
4430 "got %d with %d and optval: 0x%x/%d (expected SOCKET_ERROR with WSAEINVAL)\n",
4431 ret, WSAGetLastError(), optval, optval);
4433 SetLastError(0xdeadbeef);
4434 optlen = sizeof(LINGER);
4435 ret = getsockopt(sock, SOL_SOCKET, SO_LINGER, (char *)&linger_val, &optlen);
4436 ok( (ret == SOCKET_ERROR) && (WSAGetLastError() == WSAENOPROTOOPT),
4437 "getsockopt should fail for UDP sockets setting last error to WSAENOPROTOOPT, got %d with %d\n",
4438 ret, WSAGetLastError());
4439 closesocket(sock);
4441 sock = socket(PF_INET, SOCK_STREAM, IPPROTO_IP);
4442 ok(sock != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
4444 ret = bind(sock, (struct sockaddr *) &sa, sa_len);
4445 ok(!ret, "failed to bind socket, error %u\n", WSAGetLastError());
4447 ret = getsockopt(sock, SOL_SOCKET, SO_LINGER, (char *)&linger_val, &optlen);
4448 ok(ret == 0, "getsockopt failed to query SO_LINGER, return value is 0x%08x\n", ret);
4450 optlen = sizeof(BOOL);
4451 ret = getsockopt(sock, SOL_SOCKET, SO_DONTLINGER, (char *)&bool_opt_val, &optlen);
4452 ok(ret == 0, "getsockopt failed to query SO_DONTLINGER, return value is 0x%08x\n", ret);
4453 ok((linger_val.l_onoff && !bool_opt_val) || (!linger_val.l_onoff && bool_opt_val),
4454 "Return value of SO_DONTLINGER is %d, but SO_LINGER returned l_onoff == %d.\n",
4455 bool_opt_val, linger_val.l_onoff);
4457 closesocket(sock);
4458 WSACleanup();
4461 static void test_getsockname(void)
4463 WSADATA wsa;
4464 SOCKET sock;
4465 struct sockaddr_in sa_set, sa_get;
4466 int sa_set_len = sizeof(struct sockaddr_in);
4467 int sa_get_len = sa_set_len;
4468 static const unsigned char null_padding[] = {0,0,0,0,0,0,0,0};
4469 int ret;
4470 struct hostent *h;
4472 ret = WSAStartup(MAKEWORD(2,0), &wsa);
4473 ok(!ret, "failed to startup, error %u\n", WSAGetLastError());
4475 memset(&sa_set, 0, sa_set_len);
4477 sa_set.sin_family = AF_INET;
4478 sa_set.sin_port = htons(0);
4479 sa_set.sin_addr.s_addr = htonl(INADDR_ANY);
4481 sock = socket(PF_INET, SOCK_STREAM, IPPROTO_IP);
4482 ok(sock != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
4484 sa_get = sa_set;
4485 WSASetLastError(0xdeadbeef);
4486 ret = getsockname(sock, (struct sockaddr *)&sa_get, &sa_get_len);
4487 ok(ret == SOCKET_ERROR, "expected failure\n");
4488 ok(WSAGetLastError() == WSAEINVAL, "got error %u\n", WSAGetLastError());
4489 ok(!memcmp(&sa_get, &sa_set, sizeof(sa_get)), "address should not be changed\n");
4491 ret = bind(sock, (struct sockaddr *) &sa_set, sa_set_len);
4492 ok(!ret, "failed to bind, error %u\n", WSAGetLastError());
4494 WSASetLastError(0xdeadbeef);
4495 memset(&sa_get, 0, sizeof(sa_get));
4496 ret = getsockname(sock, (struct sockaddr *) &sa_get, &sa_get_len);
4497 ok(!ret, "got %d\n", ret);
4498 ok(!WSAGetLastError() || WSAGetLastError() == 0xdeadbeef /* < 7 */, "got error %u\n", WSAGetLastError());
4499 ok(sa_get.sin_family == AF_INET, "got family %#x\n", sa_get.sin_family);
4500 ok(sa_get.sin_port != 0, "got zero port\n");
4501 ok(sa_get.sin_addr.s_addr == INADDR_ANY, "got addr %08lx\n", sa_get.sin_addr.s_addr);
4503 ret = memcmp(sa_get.sin_zero, null_padding, 8);
4504 ok(ret == 0, "getsockname did not zero the sockaddr_in structure\n");
4506 sa_get_len = sizeof(sa_get) - 1;
4507 WSASetLastError(0xdeadbeef);
4508 ret = getsockname(sock, (struct sockaddr *)&sa_get, &sa_get_len);
4509 ok(ret == -1, "expected failure\n");
4510 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
4511 ok(sa_get_len == sizeof(sa_get) - 1, "got size %d\n", sa_get_len);
4513 closesocket(sock);
4515 h = gethostbyname("");
4516 if (h && h->h_length == 4) /* this test is only meaningful in IPv4 */
4518 int i;
4519 for (i = 0; h->h_addr_list[i]; i++)
4521 char ipstr[32];
4522 struct in_addr ip;
4523 ip.s_addr = *(ULONG *) h->h_addr_list[i];
4525 sock = socket(AF_INET, SOCK_DGRAM, 0);
4526 ok(sock != INVALID_SOCKET, "socket failed with %ld\n", GetLastError());
4528 memset(&sa_set, 0, sizeof(sa_set));
4529 sa_set.sin_family = AF_INET;
4530 sa_set.sin_addr.s_addr = ip.s_addr;
4531 /* The same address we bind must be the same address we get */
4532 ret = bind(sock, (struct sockaddr*)&sa_set, sizeof(sa_set));
4533 ok(ret == 0, "bind failed with %ld\n", GetLastError());
4534 sa_get_len = sizeof(sa_get);
4535 ret = getsockname(sock, (struct sockaddr*)&sa_get, &sa_get_len);
4536 ok(ret == 0, "getsockname failed with %ld\n", GetLastError());
4537 strcpy(ipstr, inet_ntoa(sa_get.sin_addr));
4538 ok(sa_get.sin_addr.s_addr == sa_set.sin_addr.s_addr,
4539 "address does not match: %s != %s\n", ipstr, inet_ntoa(sa_set.sin_addr));
4541 closesocket(sock);
4545 WSACleanup();
4548 static DWORD apc_error, apc_size;
4549 static OVERLAPPED *apc_overlapped;
4550 static unsigned int apc_count;
4552 static void WINAPI socket_apc(DWORD error, DWORD size, OVERLAPPED *overlapped, DWORD flags)
4554 ok(!flags, "got flags %#lx\n", flags);
4555 ++apc_count;
4556 apc_error = error;
4557 apc_size = size;
4558 apc_overlapped = overlapped;
4561 #define check_fionread_siocatmark(a, b, c) check_fionread_siocatmark_(__LINE__, a, b, c, FALSE, FALSE)
4562 #define check_fionread_siocatmark_todo(a, b, c) check_fionread_siocatmark_(__LINE__, a, b, c, TRUE, TRUE)
4563 #define check_fionread_siocatmark_todo_oob(a, b, c) check_fionread_siocatmark_(__LINE__, a, b, c, FALSE, TRUE)
4564 static void check_fionread_siocatmark_(int line, SOCKET s, unsigned int normal, unsigned int oob,
4565 BOOL todo_normal, BOOL todo_oob)
4567 int ret, value;
4568 DWORD size;
4570 value = 0xdeadbeef;
4571 WSASetLastError(0xdeadbeef);
4572 ret = WSAIoctl(s, FIONREAD, NULL, 0, &value, sizeof(value), &size, NULL, NULL);
4573 ok_(__FILE__, line)(!ret, "expected success\n");
4574 ok_(__FILE__, line)(!WSAGetLastError(), "got error %u\n", WSAGetLastError());
4575 todo_wine_if (todo_normal) ok_(__FILE__, line)(value == normal, "FIONBIO returned %u\n", value);
4577 value = 0xdeadbeef;
4578 WSASetLastError(0xdeadbeef);
4579 ret = WSAIoctl(s, SIOCATMARK, NULL, 0, &value, sizeof(value), &size, NULL, NULL);
4580 ok_(__FILE__, line)(!ret, "expected success\n");
4581 ok_(__FILE__, line)(!WSAGetLastError(), "got error %u\n", WSAGetLastError());
4582 todo_wine_if (todo_oob) ok_(__FILE__, line)(value == oob, "SIOCATMARK returned %u\n", value);
4585 static void test_fionread_siocatmark(void)
4587 const struct sockaddr_in bind_addr = {.sin_family = AF_INET, .sin_addr.s_addr = htonl(INADDR_LOOPBACK)};
4588 OVERLAPPED overlapped = {0}, *overlapped_ptr;
4589 SOCKET client, server;
4590 char buffer[5];
4591 int ret, value;
4592 ULONG_PTR key;
4593 HANDLE port;
4594 DWORD size;
4596 tcp_socketpair(&client, &server);
4597 set_blocking(client, FALSE);
4598 overlapped.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
4600 WSASetLastError(0xdeadbeef);
4601 ret = ioctlsocket(client, FIONREAD, (u_long *)1);
4602 ok(ret == -1, "expected failure\n");
4603 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
4605 WSASetLastError(0xdeadbeef);
4606 ret = ioctlsocket(client, SIOCATMARK, (u_long *)1);
4607 ok(ret == -1, "expected failure\n");
4608 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
4610 WSASetLastError(0xdeadbeef);
4611 ret = WSAIoctl(client, FIONREAD, NULL, 0, &value, sizeof(value), NULL, NULL, NULL);
4612 ok(ret == -1, "expected failure\n");
4613 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
4615 WSASetLastError(0xdeadbeef);
4616 size = 0xdeadbeef;
4617 ret = WSAIoctl(client, FIONREAD, NULL, 0, &value, sizeof(value) - 1, &size, NULL, NULL);
4618 ok(ret == -1, "expected failure\n");
4619 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
4620 ok(size == 0xdeadbeef, "got size %lu\n", size);
4622 WSASetLastError(0xdeadbeef);
4623 ret = WSAIoctl(client, SIOCATMARK, NULL, 0, &value, sizeof(value), NULL, NULL, NULL);
4624 ok(ret == -1, "expected failure\n");
4625 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
4627 WSASetLastError(0xdeadbeef);
4628 size = 0xdeadbeef;
4629 ret = WSAIoctl(client, SIOCATMARK, NULL, 0, &value, sizeof(value) - 1, &size, NULL, NULL);
4630 ok(ret == -1, "expected failure\n");
4631 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
4632 ok(size == 0xdeadbeef, "got size %lu\n", size);
4634 check_fionread_siocatmark(client, 0, TRUE);
4636 port = CreateIoCompletionPort((HANDLE)client, NULL, 123, 0);
4638 ret = WSAIoctl(client, FIONREAD, NULL, 0, &value, sizeof(value), NULL, &overlapped, NULL);
4639 ok(ret == -1, "expected failure\n");
4640 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
4642 ret = WSAIoctl(client, SIOCATMARK, NULL, 0, &value, sizeof(value), NULL, &overlapped, NULL);
4643 ok(ret == -1, "expected failure\n");
4644 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
4646 WSASetLastError(0xdeadbeef);
4647 size = 0xdeadbeef;
4648 value = 0xdeadbeef;
4649 overlapped.Internal = 0xdeadbeef;
4650 overlapped.InternalHigh = 0xdeadbeef;
4651 ret = WSAIoctl(client, FIONREAD, NULL, 0, &value, sizeof(value), &size, &overlapped, NULL);
4652 ok(!ret, "expected success\n");
4653 ok(!WSAGetLastError(), "got error %u\n", WSAGetLastError());
4654 ok(!value, "got %u\n", value);
4655 ok(size == sizeof(value), "got size %lu\n", size);
4656 ok(!overlapped.Internal, "got status %#lx\n", (NTSTATUS)overlapped.Internal);
4657 ok(!overlapped.InternalHigh, "got size %Iu\n", overlapped.InternalHigh);
4659 ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 0);
4660 ok(ret, "got error %lu\n", GetLastError());
4661 ok(!size, "got size %lu\n", size);
4662 ok(key == 123, "got key %Iu\n", key);
4663 ok(overlapped_ptr == &overlapped, "got overlapped %p\n", overlapped_ptr);
4665 WSASetLastError(0xdeadbeef);
4666 size = 0xdeadbeef;
4667 value = 0xdeadbeef;
4668 overlapped.Internal = 0xdeadbeef;
4669 overlapped.InternalHigh = 0xdeadbeef;
4670 ret = WSAIoctl(client, SIOCATMARK, NULL, 0, &value, sizeof(value), &size, &overlapped, NULL);
4671 ok(!ret, "expected success\n");
4672 ok(!WSAGetLastError(), "got error %u\n", WSAGetLastError());
4673 ok(value == TRUE, "got %u\n", value);
4674 ok(size == sizeof(value), "got size %lu\n", size);
4675 ok(!overlapped.Internal, "got status %#lx\n", (NTSTATUS)overlapped.Internal);
4676 ok(!overlapped.InternalHigh, "got size %Iu\n", overlapped.InternalHigh);
4678 ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 0);
4679 ok(ret, "got error %lu\n", GetLastError());
4680 ok(!size, "got size %lu\n", size);
4681 ok(key == 123, "got key %Iu\n", key);
4682 ok(overlapped_ptr == &overlapped, "got overlapped %p\n", overlapped_ptr);
4684 ret = send(server, "data", 5, 0);
4685 ok(ret == 5, "got %d\n", ret);
4687 /* wait for the data to be available */
4688 check_poll_mask(client, POLLRDNORM, POLLRDNORM);
4690 check_fionread_siocatmark(client, 5, TRUE);
4692 ret = send(server, "a", 1, MSG_OOB);
4693 ok(ret == 1, "got %d\n", ret);
4695 /* wait for the data to be available */
4696 check_poll_mask(client, POLLRDBAND, POLLRDBAND);
4698 check_fionread_siocatmark_todo_oob(client, 5, FALSE);
4700 ret = send(server, "a", 1, MSG_OOB);
4701 ok(ret == 1, "got %d\n", ret);
4703 check_fionread_siocatmark_todo(client, 5, FALSE);
4705 ret = recv(client, buffer, 3, 0);
4706 ok(ret == 3, "got %d\n", ret);
4708 check_fionread_siocatmark_todo(client, 2, FALSE);
4710 ret = recv(client, buffer, 1, MSG_OOB);
4711 ok(ret == 1, "got %d\n", ret);
4713 /* wait for the data to be available */
4714 check_poll_mask_todo(client, POLLRDBAND, POLLRDBAND);
4716 check_fionread_siocatmark_todo(client, 2, FALSE);
4718 ret = recv(client, buffer, 5, 0);
4719 todo_wine ok(ret == 2, "got %d\n", ret);
4721 check_fionread_siocatmark(client, 0, FALSE);
4723 ret = recv(client, buffer, 1, MSG_OOB);
4724 todo_wine ok(ret == 1, "got %d\n", ret);
4726 check_fionread_siocatmark_todo_oob(client, 0, TRUE);
4728 ret = send(server, "a", 1, MSG_OOB);
4729 ok(ret == 1, "got %d\n", ret);
4731 /* wait for the data to be available */
4732 check_poll_mask(client, POLLRDBAND, POLLRDBAND);
4734 ret = 1;
4735 ret = setsockopt(client, SOL_SOCKET, SO_OOBINLINE, (char *)&ret, sizeof(ret));
4736 ok(!ret, "got error %u\n", WSAGetLastError());
4738 check_fionread_siocatmark_todo_oob(client, 1, FALSE);
4740 ret = recv(client, buffer, 1, 0);
4741 ok(ret == 1, "got %d\n", ret);
4743 check_fionread_siocatmark(client, 0, TRUE);
4745 ret = send(server, "a", 1, MSG_OOB);
4746 ok(ret == 1, "got %d\n", ret);
4748 /* wait for the data to be available */
4749 check_poll_mask(client, POLLRDNORM, POLLRDNORM);
4751 check_fionread_siocatmark(client, 1, TRUE);
4753 closesocket(client);
4754 closesocket(server);
4756 server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
4758 check_fionread_siocatmark(server, 0, TRUE);
4760 ret = bind(server, (const struct sockaddr *)&bind_addr, sizeof(bind_addr));
4761 ok(!ret, "got error %u\n", WSAGetLastError());
4763 check_fionread_siocatmark(server, 0, TRUE);
4765 closesocket(server);
4766 CloseHandle(overlapped.hEvent);
4768 /* test with APCs */
4770 server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
4772 ret = WSAIoctl(server, FIONREAD, NULL, 0, &value, sizeof(value), NULL, &overlapped, socket_apc);
4773 ok(ret == -1, "expected failure\n");
4774 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
4776 ret = WSAIoctl(server, SIOCATMARK, NULL, 0, &value, sizeof(value), NULL, &overlapped, socket_apc);
4777 ok(ret == -1, "expected failure\n");
4778 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
4780 apc_count = 0;
4781 size = 0xdeadbeef;
4782 ret = WSAIoctl(server, FIONREAD, NULL, 0, &value, sizeof(value), &size, &overlapped, socket_apc);
4783 ok(!ret, "expected success\n");
4784 ok(size == sizeof(value), "got size %lu\n", size);
4786 ret = SleepEx(0, TRUE);
4787 ok(ret == WAIT_IO_COMPLETION, "got %d\n", ret);
4788 ok(apc_count == 1, "APC was called %u times\n", apc_count);
4789 ok(!apc_error, "got APC error %lu\n", apc_error);
4790 ok(!apc_size, "got APC size %lu\n", apc_size);
4791 ok(apc_overlapped == &overlapped, "got APC overlapped %p\n", apc_overlapped);
4793 apc_count = 0;
4794 size = 0xdeadbeef;
4795 ret = WSAIoctl(server, SIOCATMARK, NULL, 0, &value, sizeof(value), &size, &overlapped, socket_apc);
4796 ok(!ret, "expected success\n");
4797 ok(size == sizeof(value), "got size %lu\n", size);
4799 ret = SleepEx(0, TRUE);
4800 ok(ret == WAIT_IO_COMPLETION, "got %d\n", ret);
4801 ok(apc_count == 1, "APC was called %u times\n", apc_count);
4802 ok(!apc_error, "got APC error %lu\n", apc_error);
4803 ok(!apc_size, "got APC size %lu\n", apc_size);
4804 ok(apc_overlapped == &overlapped, "got APC overlapped %p\n", apc_overlapped);
4806 closesocket(server);
4809 static void test_fionbio(void)
4811 OVERLAPPED overlapped = {0}, *overlapped_ptr;
4812 u_long one = 1, zero = 0;
4813 HANDLE port, event;
4814 ULONG_PTR key;
4815 void *output;
4816 DWORD size;
4817 SOCKET s;
4818 int ret;
4820 event = CreateEventW(NULL, TRUE, FALSE, NULL);
4821 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
4822 port = CreateIoCompletionPort((HANDLE)s, NULL, 123, 0);
4824 WSASetLastError(0xdeadbeef);
4825 ret = ioctlsocket(s, FIONBIO, (u_long *)1);
4826 ok(ret == -1, "expected failure\n");
4827 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
4829 WSASetLastError(0xdeadbeef);
4830 ret = WSAIoctl(s, FIONBIO, &one, sizeof(one), NULL, 0, NULL, NULL, NULL);
4831 ok(ret == -1, "expected failure\n");
4832 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
4834 ret = WSAIoctl(s, FIONBIO, &one, sizeof(one) - 1, NULL, 0, &size, &overlapped, NULL);
4835 ok(ret == -1, "expected failure\n");
4836 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
4838 size = 0xdeadbeef;
4839 WSASetLastError(0xdeadbeef);
4840 ret = WSAIoctl(s, FIONBIO, &one, sizeof(one), NULL, 0, &size, NULL, NULL);
4841 ok(!ret, "expected success\n");
4842 ok(!WSAGetLastError(), "got error %u\n", WSAGetLastError());
4843 ok(!size, "got size %lu\n", size);
4845 ret = WSAIoctl(s, FIONBIO, &one, sizeof(one) + 1, NULL, 0, &size, NULL, NULL);
4846 ok(!ret, "got error %u\n", WSAGetLastError());
4848 output = VirtualAlloc(NULL, 4, MEM_RESERVE | MEM_COMMIT, PAGE_NOACCESS);
4849 ret = WSAIoctl(s, FIONBIO, &one, sizeof(one) + 1, output, 4, &size, NULL, NULL);
4850 ok(!ret, "got error %u\n", WSAGetLastError());
4851 VirtualFree(output, 0, MEM_FREE);
4853 overlapped.Internal = 0xdeadbeef;
4854 overlapped.InternalHigh = 0xdeadbeef;
4855 size = 0xdeadbeef;
4856 ret = WSAIoctl(s, FIONBIO, &one, sizeof(one), NULL, 0, &size, &overlapped, NULL);
4857 ok(!ret, "expected success\n");
4858 ok(!size, "got size %lu\n", size);
4860 ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 0);
4861 ok(ret, "got error %lu\n", GetLastError());
4862 ok(!size, "got size %lu\n", size);
4863 ok(overlapped_ptr == &overlapped, "got overlapped %p\n", overlapped_ptr);
4864 ok(!overlapped.Internal, "got status %#lx\n", (NTSTATUS)overlapped.Internal);
4865 ok(!overlapped.InternalHigh, "got size %Iu\n", overlapped.InternalHigh);
4867 ret = WSAIoctl(s, FIONBIO, &one, sizeof(one), NULL, 0, NULL, &overlapped, NULL);
4868 ok(ret == -1, "expected failure\n");
4869 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
4871 ret = WSAEventSelect(s, event, FD_READ);
4872 ok(!ret, "got error %u\n", WSAGetLastError());
4874 ret = WSAIoctl(s, FIONBIO, &one, sizeof(one), NULL, 0, &size, NULL, NULL);
4875 ok(!ret, "got error %u\n", WSAGetLastError());
4877 size = 0xdeadbeef;
4878 ret = WSAIoctl(s, FIONBIO, &zero, sizeof(zero), NULL, 0, &size, NULL, NULL);
4879 ok(ret == -1, "expected failure\n");
4880 ok(WSAGetLastError() == WSAEINVAL, "got error %u\n", WSAGetLastError());
4881 todo_wine ok(!size, "got size %lu\n", size);
4883 CloseHandle(port);
4884 closesocket(s);
4885 CloseHandle(event);
4887 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
4889 ret = WSAIoctl(s, FIONBIO, &one, sizeof(one), NULL, 0, NULL, &overlapped, socket_apc);
4890 ok(ret == -1, "expected failure\n");
4891 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
4893 apc_count = 0;
4894 size = 0xdeadbeef;
4895 ret = WSAIoctl(s, FIONBIO, &one, sizeof(one), NULL, 0, &size, &overlapped, socket_apc);
4896 ok(!ret, "expected success\n");
4897 ok(!size, "got size %lu\n", size);
4899 ret = SleepEx(0, TRUE);
4900 ok(ret == WAIT_IO_COMPLETION, "got %d\n", ret);
4901 ok(apc_count == 1, "APC was called %u times\n", apc_count);
4902 ok(!apc_error, "got APC error %lu\n", apc_error);
4903 ok(!apc_size, "got APC size %lu\n", apc_size);
4904 ok(apc_overlapped == &overlapped, "got APC overlapped %p\n", apc_overlapped);
4906 closesocket(s);
4909 static void test_keepalive_vals(void)
4911 OVERLAPPED overlapped = {0}, *overlapped_ptr;
4912 struct tcp_keepalive kalive;
4913 ULONG_PTR key;
4914 HANDLE port;
4915 SOCKET sock;
4916 DWORD size;
4917 int ret;
4919 sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
4920 ok(sock != INVALID_SOCKET, "Creating the socket failed: %d\n", WSAGetLastError());
4921 port = CreateIoCompletionPort((HANDLE)sock, NULL, 123, 0);
4923 WSASetLastError(0xdeadbeef);
4924 size = 0xdeadbeef;
4925 ret = WSAIoctl(sock, SIO_KEEPALIVE_VALS, &kalive, 0, NULL, 0, &size, NULL, NULL);
4926 ok(ret == SOCKET_ERROR, "WSAIoctl succeeded unexpectedly\n");
4927 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
4928 ok(!size, "got size %lu\n", size);
4930 WSASetLastError(0xdeadbeef);
4931 size = 0xdeadbeef;
4932 ret = WSAIoctl(sock, SIO_KEEPALIVE_VALS, NULL, sizeof(kalive), NULL, 0, &size, NULL, NULL);
4933 ok(ret == SOCKET_ERROR, "WSAIoctl succeeded unexpectedly\n");
4934 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
4935 ok(!size, "got size %lu\n", size);
4937 WSASetLastError(0xdeadbeef);
4938 size = 0xdeadbeef;
4939 make_keepalive(kalive, 0, 0, 0);
4940 ret = WSAIoctl(sock, SIO_KEEPALIVE_VALS, &kalive, sizeof(kalive), NULL, 0, &size, NULL, NULL);
4941 ok(ret == 0, "WSAIoctl failed unexpectedly\n");
4942 ok(!WSAGetLastError(), "got error %u\n", WSAGetLastError());
4943 ok(!size, "got size %lu\n", size);
4945 ret = WSAIoctl(sock, SIO_KEEPALIVE_VALS, &kalive, sizeof(kalive), NULL, 0, NULL, NULL, NULL);
4946 ok(ret == SOCKET_ERROR, "WSAIoctl succeeded unexpectedly\n");
4947 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
4949 ret = WSAIoctl(sock, SIO_KEEPALIVE_VALS, &kalive, sizeof(kalive), NULL, 0, NULL, &overlapped, NULL);
4950 ok(ret == SOCKET_ERROR, "WSAIoctl succeeded unexpectedly\n");
4951 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
4953 WSASetLastError(0xdeadbeef);
4954 size = 0xdeadbeef;
4955 overlapped.Internal = 0xdeadbeef;
4956 overlapped.InternalHigh = 0xdeadbeef;
4957 ret = WSAIoctl(sock, SIO_KEEPALIVE_VALS, &kalive, sizeof(kalive) - 1, NULL, 0, &size, &overlapped, NULL);
4958 ok(ret == SOCKET_ERROR, "WSAIoctl succeeded unexpectedly\n");
4959 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
4960 ok(size == 0xdeadbeef, "got size %lu\n", size);
4961 todo_wine ok(overlapped.Internal == STATUS_PENDING, "got status %#lx\n", (NTSTATUS)overlapped.Internal);
4962 ok(overlapped.InternalHigh == 0xdeadbeef, "got size %Iu\n", overlapped.InternalHigh);
4964 WSASetLastError(0xdeadbeef);
4965 size = 0xdeadbeef;
4966 overlapped.Internal = 0xdeadbeef;
4967 overlapped.InternalHigh = 0xdeadbeef;
4968 ret = WSAIoctl(sock, SIO_KEEPALIVE_VALS, &kalive, sizeof(kalive), NULL, 0, &size, &overlapped, NULL);
4969 ok(ret == 0, "WSAIoctl failed unexpectedly\n");
4970 ok(!WSAGetLastError(), "got error %u\n", WSAGetLastError());
4971 todo_wine ok(size == 0xdeadbeef, "got size %lu\n", size);
4973 ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 0);
4974 ok(ret, "got error %lu\n", GetLastError());
4975 ok(!size, "got size %lu\n", size);
4976 ok(overlapped_ptr == &overlapped, "got overlapped %p\n", overlapped_ptr);
4977 ok(!overlapped.Internal, "got status %#lx\n", (NTSTATUS)overlapped.Internal);
4978 ok(!overlapped.InternalHigh, "got size %Iu\n", overlapped.InternalHigh);
4980 make_keepalive(kalive, 1, 0, 0);
4981 ret = WSAIoctl(sock, SIO_KEEPALIVE_VALS, &kalive, sizeof(kalive), NULL, 0, &size, NULL, NULL);
4982 ok(ret == 0, "WSAIoctl failed unexpectedly\n");
4984 make_keepalive(kalive, 1, 1000, 1000);
4985 ret = WSAIoctl(sock, SIO_KEEPALIVE_VALS, &kalive, sizeof(kalive), NULL, 0, &size, NULL, NULL);
4986 ok(ret == 0, "WSAIoctl failed unexpectedly\n");
4988 make_keepalive(kalive, 1, 10000, 10000);
4989 ret = WSAIoctl(sock, SIO_KEEPALIVE_VALS, &kalive, sizeof(kalive), NULL, 0, &size, NULL, NULL);
4990 ok(ret == 0, "WSAIoctl failed unexpectedly\n");
4992 make_keepalive(kalive, 1, 100, 100);
4993 ret = WSAIoctl(sock, SIO_KEEPALIVE_VALS, &kalive, sizeof(kalive), NULL, 0, &size, NULL, NULL);
4994 ok(ret == 0, "WSAIoctl failed unexpectedly\n");
4996 make_keepalive(kalive, 0, 100, 100);
4997 ret = WSAIoctl(sock, SIO_KEEPALIVE_VALS, &kalive, sizeof(kalive), NULL, 0, &size, NULL, NULL);
4998 ok(ret == 0, "WSAIoctl failed unexpectedly\n");
5000 CloseHandle(port);
5001 closesocket(sock);
5003 sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
5005 ret = WSAIoctl(sock, SIO_KEEPALIVE_VALS, &kalive, sizeof(kalive), NULL, 0, NULL, &overlapped, socket_apc);
5006 ok(ret == -1, "expected failure\n");
5007 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
5009 apc_count = 0;
5010 size = 0xdeadbeef;
5011 ret = WSAIoctl(sock, SIO_KEEPALIVE_VALS, &kalive, sizeof(kalive), NULL, 0, &size, &overlapped, socket_apc);
5012 ok(!ret, "expected success\n");
5013 ok(!size, "got size %lu\n", size);
5015 ret = SleepEx(0, TRUE);
5016 ok(ret == WAIT_IO_COMPLETION, "got %d\n", ret);
5017 ok(apc_count == 1, "APC was called %u times\n", apc_count);
5018 ok(!apc_error, "got APC error %lu\n", apc_error);
5019 ok(!apc_size, "got APC size %lu\n", apc_size);
5020 ok(apc_overlapped == &overlapped, "got APC overlapped %p\n", apc_overlapped);
5022 closesocket(sock);
5025 static void test_unsupported_ioctls(void)
5027 OVERLAPPED overlapped = {0}, *overlapped_ptr;
5028 unsigned int i;
5029 ULONG_PTR key;
5030 HANDLE port;
5031 DWORD size;
5032 SOCKET s;
5033 int ret;
5035 static const DWORD codes[] = {0xdeadbeef, FIOASYNC, 0x667e, SIO_FLUSH};
5037 for (i = 0; i < ARRAY_SIZE(codes); ++i)
5039 winetest_push_context("ioctl %#lx", codes[i]);
5040 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
5041 port = CreateIoCompletionPort((HANDLE)s, NULL, 123, 0);
5043 WSASetLastError(0xdeadbeef);
5044 ret = WSAIoctl(s, codes[i], NULL, 0, NULL, 0, NULL, &overlapped, NULL);
5045 ok(ret == -1, "expected failure\n");
5046 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
5048 WSASetLastError(0xdeadbeef);
5049 size = 0xdeadbeef;
5050 ret = WSAIoctl(s, codes[i], NULL, 0, NULL, 0, &size, NULL, NULL);
5051 ok(ret == -1, "expected failure\n");
5052 ok(WSAGetLastError() == WSAEOPNOTSUPP, "got error %u\n", WSAGetLastError());
5053 ok(!size, "got size %lu\n", size);
5055 WSASetLastError(0xdeadbeef);
5056 size = 0xdeadbeef;
5057 overlapped.Internal = 0xdeadbeef;
5058 overlapped.InternalHigh = 0xdeadbeef;
5059 ret = WSAIoctl(s, codes[i], NULL, 0, NULL, 0, &size, &overlapped, NULL);
5060 ok(ret == -1, "expected failure\n");
5061 ok(WSAGetLastError() == ERROR_IO_PENDING, "got error %u\n", WSAGetLastError());
5062 ok(size == 0xdeadbeef, "got size %lu\n", size);
5064 ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 0);
5065 ok(!ret, "expected failure\n");
5066 ok(GetLastError() == ERROR_NOT_SUPPORTED, "got error %lu\n", GetLastError());
5067 ok(!size, "got size %lu\n", size);
5068 ok(key == 123, "got key %Iu\n", key);
5069 ok(overlapped_ptr == &overlapped, "got overlapped %p\n", overlapped_ptr);
5070 ok((NTSTATUS)overlapped.Internal == STATUS_NOT_SUPPORTED,
5071 "got status %#lx\n", (NTSTATUS)overlapped.Internal);
5072 ok(!overlapped.InternalHigh, "got size %Iu\n", overlapped.InternalHigh);
5074 CloseHandle(port);
5075 closesocket(s);
5077 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
5079 ret = WSAIoctl(s, codes[i], NULL, 0, NULL, 0, NULL, &overlapped, socket_apc);
5080 ok(ret == -1, "expected failure\n");
5081 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
5083 apc_count = 0;
5084 size = 0xdeadbeef;
5085 ret = WSAIoctl(s, codes[i], NULL, 0, NULL, 0, &size, &overlapped, socket_apc);
5086 ok(ret == -1, "expected failure\n");
5087 ok(WSAGetLastError() == ERROR_IO_PENDING, "got error %u\n", WSAGetLastError());
5088 ok(size == 0xdeadbeef, "got size %lu\n", size);
5090 ret = SleepEx(0, TRUE);
5091 ok(ret == WAIT_IO_COMPLETION, "got %d\n", ret);
5092 ok(apc_count == 1, "APC was called %u times\n", apc_count);
5093 ok(apc_error == WSAEOPNOTSUPP, "got APC error %lu\n", apc_error);
5094 ok(!apc_size, "got APC size %lu\n", apc_size);
5095 ok(apc_overlapped == &overlapped, "got APC overlapped %p\n", apc_overlapped);
5097 closesocket(s);
5098 winetest_pop_context();
5102 static void test_get_extension_func(void)
5104 OVERLAPPED overlapped = {0}, *overlapped_ptr;
5105 GUID acceptex_guid = WSAID_ACCEPTEX;
5106 GUID bogus_guid = {0xdeadbeef};
5107 ULONG_PTR key;
5108 HANDLE port;
5109 DWORD size;
5110 void *func;
5111 SOCKET s;
5112 int ret;
5114 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
5115 port = CreateIoCompletionPort((HANDLE)s, NULL, 123, 0);
5117 WSASetLastError(0xdeadbeef);
5118 ret = WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &acceptex_guid, sizeof(GUID),
5119 &func, sizeof(func), NULL, &overlapped, NULL);
5120 ok(ret == -1, "expected failure\n");
5121 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
5123 WSASetLastError(0xdeadbeef);
5124 size = 0xdeadbeef;
5125 ret = WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &acceptex_guid, sizeof(GUID),
5126 &func, sizeof(func), &size, NULL, NULL);
5127 ok(!ret, "expected success\n");
5128 ok(!WSAGetLastError(), "got error %u\n", WSAGetLastError());
5129 ok(size == sizeof(func), "got size %lu\n", size);
5131 WSASetLastError(0xdeadbeef);
5132 size = 0xdeadbeef;
5133 overlapped.Internal = 0xdeadbeef;
5134 overlapped.InternalHigh = 0xdeadbeef;
5135 ret = WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &acceptex_guid, sizeof(GUID),
5136 &func, sizeof(func), &size, &overlapped, NULL);
5137 ok(!ret, "expected success\n");
5138 ok(!WSAGetLastError(), "got error %u\n", WSAGetLastError());
5139 ok(size == sizeof(func), "got size %lu\n", size);
5141 ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 0);
5142 ok(ret, "got error %lu\n", GetLastError());
5143 ok(!size, "got size %lu\n", size);
5144 ok(key == 123, "got key %Iu\n", key);
5145 ok(overlapped_ptr == &overlapped, "got overlapped %p\n", overlapped_ptr);
5146 ok(!overlapped.Internal, "got status %#lx\n", (NTSTATUS)overlapped.Internal);
5147 ok(!overlapped.InternalHigh, "got size %Iu\n", overlapped.InternalHigh);
5149 size = 0xdeadbeef;
5150 overlapped.Internal = 0xdeadbeef;
5151 overlapped.InternalHigh = 0xdeadbeef;
5152 ret = WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &bogus_guid, sizeof(GUID),
5153 &func, sizeof(func), &size, &overlapped, NULL);
5154 ok(ret == -1, "expected failure\n");
5155 ok(WSAGetLastError() == WSAEINVAL, "got error %u\n", WSAGetLastError());
5156 ok(size == 0xdeadbeef, "got size %lu\n", size);
5157 ok(overlapped.Internal == 0xdeadbeef, "got status %#lx\n", (NTSTATUS)overlapped.Internal);
5158 ok(overlapped.InternalHigh == 0xdeadbeef, "got size %Iu\n", overlapped.InternalHigh);
5160 ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 0);
5161 ok(!ret, "expected failure\n");
5162 ok(GetLastError() == WAIT_TIMEOUT, "got error %u\n", WSAGetLastError());
5164 CloseHandle(port);
5165 closesocket(s);
5167 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
5169 ret = WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &acceptex_guid, sizeof(GUID),
5170 &func, sizeof(func), NULL, &overlapped, socket_apc);
5171 ok(ret == -1, "expected failure\n");
5172 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
5174 apc_count = 0;
5175 size = 0xdeadbeef;
5176 ret = WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &acceptex_guid, sizeof(GUID),
5177 &func, sizeof(func), &size, &overlapped, socket_apc);
5178 ok(!ret, "got error %u\n", WSAGetLastError());
5179 ok(size == sizeof(func), "got size %lu\n", size);
5181 ret = SleepEx(0, TRUE);
5182 ok(ret == WAIT_IO_COMPLETION, "got %d\n", ret);
5183 ok(apc_count == 1, "APC was called %u times\n", apc_count);
5184 ok(!apc_error, "got APC error %lu\n", apc_error);
5185 ok(!apc_size, "got APC size %lu\n", apc_size);
5186 ok(apc_overlapped == &overlapped, "got APC overlapped %p\n", apc_overlapped);
5188 closesocket(s);
5191 static void test_base_handle(void)
5193 OVERLAPPED overlapped = {0}, *overlapped_ptr;
5194 unsigned int i;
5195 SOCKET s, base;
5196 ULONG_PTR key;
5197 HANDLE port;
5198 DWORD size;
5199 int ret;
5201 static const struct
5203 int family, type, protocol;
5205 tests[] =
5207 {AF_INET, SOCK_STREAM, IPPROTO_TCP},
5208 {AF_INET, SOCK_DGRAM, IPPROTO_UDP},
5209 {AF_INET6, SOCK_STREAM, IPPROTO_TCP},
5210 {AF_INET6, SOCK_DGRAM, IPPROTO_UDP},
5213 for (i = 0; i < ARRAY_SIZE(tests); ++i)
5215 s = socket(tests[i].family, tests[i].type, tests[i].protocol);
5216 if (s == INVALID_SOCKET) continue;
5217 port = CreateIoCompletionPort((HANDLE)s, NULL, 123, 0);
5219 WSASetLastError(0xdeadbeef);
5220 ret = WSAIoctl(s, SIO_BASE_HANDLE, NULL, 0, &base, sizeof(base), NULL, &overlapped, NULL);
5221 ok(ret == -1, "expected failure\n");
5222 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
5224 WSASetLastError(0xdeadbeef);
5225 size = 0xdeadbeef;
5226 base = 0xdeadbeef;
5227 ret = WSAIoctl(s, SIO_BASE_HANDLE, NULL, 0, &base, sizeof(base), &size, NULL, NULL);
5228 ok(!ret, "expected success\n");
5229 ok(!WSAGetLastError(), "got error %u\n", WSAGetLastError());
5230 ok(size == sizeof(base), "got size %lu\n", size);
5231 ok(base == s, "expected %#Ix, got %#Ix\n", s, base);
5233 WSASetLastError(0xdeadbeef);
5234 size = 0xdeadbeef;
5235 base = 0xdeadbeef;
5236 overlapped.Internal = 0xdeadbeef;
5237 overlapped.InternalHigh = 0xdeadbeef;
5238 ret = WSAIoctl(s, SIO_BASE_HANDLE, NULL, 0, &base, sizeof(base), &size, &overlapped, NULL);
5239 ok(ret == -1, "expected failure\n");
5240 ok(WSAGetLastError() == ERROR_IO_PENDING, "got error %u\n", WSAGetLastError());
5241 ok(size == 0xdeadbeef, "got size %lu\n", size);
5243 ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 0);
5244 ok(!ret, "expected failure\n");
5245 ok(GetLastError() == ERROR_NOT_SUPPORTED, "got error %lu\n", GetLastError());
5246 ok(!size, "got size %lu\n", size);
5247 ok(key == 123, "got key %Iu\n", key);
5248 ok(overlapped_ptr == &overlapped, "got overlapped %p\n", overlapped_ptr);
5249 ok((NTSTATUS)overlapped.Internal == STATUS_NOT_SUPPORTED, "got status %#lx\n", (NTSTATUS)overlapped.Internal);
5250 ok(!overlapped.InternalHigh, "got size %Iu\n", overlapped.InternalHigh);
5251 ok(base == 0xdeadbeef, "expected %#Ix, got %#Ix\n", s, base);
5253 CloseHandle(port);
5254 closesocket(s);
5256 s = socket(tests[i].family, tests[i].type, tests[i].protocol);
5258 ret = WSAIoctl(s, SIO_BASE_HANDLE, NULL, 0, &base, sizeof(base), NULL, &overlapped, socket_apc);
5259 ok(ret == -1, "expected failure\n");
5260 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
5262 apc_count = 0;
5263 size = 0xdeadbeef;
5264 base = 0xdeadbeef;
5265 ret = WSAIoctl(s, SIO_BASE_HANDLE, NULL, 0, &base, sizeof(base), &size, &overlapped, socket_apc);
5266 ok(ret == -1, "expected failure\n");
5267 ok(WSAGetLastError() == ERROR_IO_PENDING, "got error %u\n", WSAGetLastError());
5268 ok(size == 0xdeadbeef, "got size %lu\n", size);
5270 ret = SleepEx(0, TRUE);
5271 ok(ret == WAIT_IO_COMPLETION, "got %d\n", ret);
5272 ok(apc_count == 1, "APC was called %u times\n", apc_count);
5273 ok(apc_error == WSAEOPNOTSUPP, "got APC error %lu\n", apc_error);
5274 ok(!apc_size, "got APC size %lu\n", apc_size);
5275 ok(apc_overlapped == &overlapped, "got APC overlapped %p\n", apc_overlapped);
5276 ok(base == 0xdeadbeef, "expected %#Ix, got %#Ix\n", s, base);
5278 closesocket(s);
5282 static void test_circular_queueing(void)
5284 SOCKET s;
5285 DWORD size;
5286 int ret;
5288 s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
5289 ret = WSAIoctl(s, SIO_ENABLE_CIRCULAR_QUEUEING, NULL, 0, NULL, 0, &size, NULL, NULL);
5290 ok(!ret, "expected 0, got %d\n", ret);
5292 closesocket(s);
5295 static BOOL drain_pause = FALSE;
5296 static DWORD WINAPI drain_socket_thread(LPVOID arg)
5298 char buffer[1024];
5299 SOCKET sock = *(SOCKET*)arg;
5300 int ret;
5302 while ((ret = recv(sock, buffer, sizeof(buffer), 0)) != 0)
5304 if (ret < 0)
5306 if (WSAGetLastError() == WSAEWOULDBLOCK)
5308 fd_set readset;
5309 FD_ZERO(&readset);
5310 FD_SET(sock, &readset);
5311 select(sock+1, &readset, NULL, NULL, NULL);
5312 while (drain_pause)
5313 Sleep(100);
5315 else
5316 break;
5319 return 0;
5322 static void test_send(void)
5324 SOCKET src = INVALID_SOCKET;
5325 SOCKET dst = INVALID_SOCKET;
5326 HANDLE hThread = NULL;
5327 const int buflen = 1024*1024;
5328 char *buffer = NULL;
5329 int ret, i, zero = 0;
5330 WSABUF buf;
5331 OVERLAPPED ov;
5332 BOOL bret;
5333 DWORD id, bytes_sent, dwRet;
5335 memset(&ov, 0, sizeof(ov));
5337 tcp_socketpair(&src, &dst);
5339 set_blocking(dst, FALSE);
5340 /* force disable buffering so we can get a pending overlapped request */
5341 ret = setsockopt(dst, SOL_SOCKET, SO_SNDBUF, (char *) &zero, sizeof(zero));
5342 ok(!ret, "setsockopt SO_SNDBUF failed: %d - %ld\n", ret, GetLastError());
5344 hThread = CreateThread(NULL, 0, drain_socket_thread, &dst, 0, &id);
5346 buffer = HeapAlloc(GetProcessHeap(), 0, buflen);
5348 /* fill the buffer with some nonsense */
5349 for (i = 0; i < buflen; ++i)
5351 buffer[i] = (char) i;
5354 ret = send(src, buffer, buflen, 0);
5355 ok(ret == buflen, "send should have sent %d bytes, but it only sent %d\n", buflen, ret);
5357 buf.buf = buffer;
5358 buf.len = buflen;
5360 ov.hEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
5361 ok(ov.hEvent != NULL, "could not create event object, errno = %ld\n", GetLastError());
5362 if (!ov.hEvent)
5363 goto end;
5365 bytes_sent = 0;
5366 WSASetLastError(12345);
5367 ret = WSASend(dst, &buf, 1, &bytes_sent, 0, &ov, NULL);
5368 ok(ret == SOCKET_ERROR, "expected failure\n");
5369 ok(WSAGetLastError() == ERROR_IO_PENDING, "wrong error %u\n", WSAGetLastError());
5371 /* don't check for completion yet, we may need to drain the buffer while still sending */
5372 set_blocking(src, FALSE);
5373 for (i = 0; i < buflen; ++i)
5375 int j = 0;
5377 ret = recv(src, buffer, 1, 0);
5378 while (ret == SOCKET_ERROR && GetLastError() == WSAEWOULDBLOCK && j < 100)
5380 j++;
5381 Sleep(50);
5382 ret = recv(src, buffer, 1, 0);
5385 ok(ret == 1, "Failed to receive data %d - %ld (got %d/%d)\n", ret, GetLastError(), i, buflen);
5386 if (ret != 1)
5387 break;
5389 ok(buffer[0] == (char) i, "Received bad data at position %d\n", i);
5392 dwRet = WaitForSingleObject(ov.hEvent, 1000);
5393 ok(dwRet == WAIT_OBJECT_0, "Failed to wait for recv message: %ld - %ld\n", dwRet, GetLastError());
5394 if (dwRet == WAIT_OBJECT_0)
5396 bret = GetOverlappedResult((HANDLE)dst, &ov, &bytes_sent, FALSE);
5397 ok(bret && bytes_sent == buflen,
5398 "Got %ld instead of %d (%d - %ld)\n", bytes_sent, buflen, bret, GetLastError());
5401 WSASetLastError(12345);
5402 ret = WSASend(INVALID_SOCKET, &buf, 1, NULL, 0, &ov, NULL);
5403 ok(ret == SOCKET_ERROR && WSAGetLastError() == WSAENOTSOCK,
5404 "WSASend failed %d - %d\n", ret, WSAGetLastError());
5406 WSASetLastError(12345);
5407 ret = WSASend(dst, &buf, 1, NULL, 0, &ov, NULL);
5408 ok(ret == SOCKET_ERROR && WSAGetLastError() == ERROR_IO_PENDING,
5409 "Failed to start overlapped send %d - %d\n", ret, WSAGetLastError());
5411 end:
5412 if (src != INVALID_SOCKET)
5413 closesocket(src);
5414 if (dst != INVALID_SOCKET)
5415 closesocket(dst);
5416 if (hThread != NULL)
5418 dwRet = WaitForSingleObject(hThread, 500);
5419 ok(dwRet == WAIT_OBJECT_0, "failed to wait for thread termination: %ld\n", GetLastError());
5420 CloseHandle(hThread);
5422 if (ov.hEvent)
5423 CloseHandle(ov.hEvent);
5424 HeapFree(GetProcessHeap(), 0, buffer);
5427 #define WM_SOCKET (WM_USER+100)
5429 struct event_test_ctx
5431 int is_message;
5432 SOCKET socket;
5433 HANDLE event;
5434 HWND window;
5437 static void select_events(struct event_test_ctx *ctx, SOCKET socket, LONG events)
5439 int ret;
5441 if (ctx->is_message)
5442 ret = WSAAsyncSelect(socket, ctx->window, WM_USER, events);
5443 else
5444 ret = WSAEventSelect(socket, ctx->event, events);
5445 ok(!ret, "failed to select, error %u\n", WSAGetLastError());
5446 ctx->socket = socket;
5449 #define check_events(a, b, c, d) check_events_(__LINE__, a, b, c, d, FALSE, FALSE)
5450 #define check_events_todo(a, b, c, d) check_events_(__LINE__, a, b, c, d, TRUE, TRUE)
5451 #define check_events_todo_event(a, b, c, d) check_events_(__LINE__, a, b, c, d, TRUE, FALSE)
5452 #define check_events_todo_msg(a, b, c, d) check_events_(__LINE__, a, b, c, d, FALSE, TRUE)
5453 static void check_events_(int line, struct event_test_ctx *ctx,
5454 LONG flag1, LONG flag2, DWORD timeout, BOOL todo_event, BOOL todo_msg)
5456 int ret;
5458 if (ctx->is_message)
5460 BOOL any_fail = FALSE;
5461 MSG msg;
5463 if (flag1)
5465 ret = PeekMessageA(&msg, ctx->window, WM_USER, WM_USER, PM_REMOVE);
5466 while (!ret && !MsgWaitForMultipleObjects(0, NULL, FALSE, timeout, QS_POSTMESSAGE))
5467 ret = PeekMessageA(&msg, ctx->window, WM_USER, WM_USER, PM_REMOVE);
5468 todo_wine_if (todo_msg && !ret) ok_(__FILE__, line)(ret, "expected a message\n");
5469 if (ret)
5471 ok_(__FILE__, line)(msg.wParam == ctx->socket,
5472 "expected wparam %#Ix, got %#Ix\n", ctx->socket, msg.wParam);
5473 todo_wine_if (todo_msg && msg.lParam != flag1)
5474 ok_(__FILE__, line)(msg.lParam == flag1, "got first event %#Ix\n", msg.lParam);
5475 if (msg.lParam != flag1) any_fail = TRUE;
5477 else
5478 any_fail = TRUE;
5480 if (flag2)
5482 ret = PeekMessageA(&msg, ctx->window, WM_USER, WM_USER, PM_REMOVE);
5483 while (!ret && !MsgWaitForMultipleObjects(0, NULL, FALSE, timeout, QS_POSTMESSAGE))
5484 ret = PeekMessageA(&msg, ctx->window, WM_USER, WM_USER, PM_REMOVE);
5485 ok_(__FILE__, line)(ret, "expected a message\n");
5486 ok_(__FILE__, line)(msg.wParam == ctx->socket, "got wparam %#Ix\n", msg.wParam);
5487 todo_wine_if (todo_msg) ok_(__FILE__, line)(msg.lParam == flag2, "got second event %#Ix\n", msg.lParam);
5489 ret = PeekMessageA(&msg, ctx->window, WM_USER, WM_USER, PM_REMOVE);
5490 todo_wine_if (todo_msg && ret) ok_(__FILE__, line)(!ret, "got unexpected event %#Ix\n", msg.lParam);
5491 if (ret) any_fail = TRUE;
5493 /* catch tests which succeed */
5494 todo_wine_if (todo_msg) ok_(__FILE__, line)(!any_fail, "event series matches\n");
5496 else
5498 WSANETWORKEVENTS events;
5499 unsigned int i;
5501 memset(&events, 0xcc, sizeof(events));
5502 ret = WaitForSingleObject(ctx->event, timeout);
5503 if (flag1 | flag2)
5504 todo_wine_if (todo_event && ret) ok_(__FILE__, line)(!ret, "event wait timed out\n");
5505 else
5506 todo_wine_if (todo_event) ok_(__FILE__, line)(ret == WAIT_TIMEOUT, "expected timeout\n");
5507 ret = WSAEnumNetworkEvents(ctx->socket, ctx->event, &events);
5508 ok_(__FILE__, line)(!ret, "failed to get events, error %u\n", WSAGetLastError());
5509 todo_wine_if (todo_event)
5510 ok_(__FILE__, line)(events.lNetworkEvents == LOWORD(flag1 | flag2), "got events %#lx\n", events.lNetworkEvents);
5511 for (i = 0; i < ARRAY_SIZE(events.iErrorCode); ++i)
5513 if ((1u << i) == LOWORD(flag1) && (events.lNetworkEvents & LOWORD(flag1)))
5514 todo_wine_if (HIWORD(flag1)) ok_(__FILE__, line)(events.iErrorCode[i] == HIWORD(flag1),
5515 "got error code %d for event %#x\n", events.iErrorCode[i], 1u << i);
5516 if ((1u << i) == LOWORD(flag2) && (events.lNetworkEvents & LOWORD(flag2)))
5517 ok_(__FILE__, line)(events.iErrorCode[i] == HIWORD(flag2),
5518 "got error code %d for event %#x\n", events.iErrorCode[i], 1u << i);
5523 static void test_accept_events(struct event_test_ctx *ctx)
5525 const struct sockaddr_in addr = {.sin_family = AF_INET, .sin_addr.s_addr = htonl(INADDR_LOOPBACK)};
5526 SOCKET listener, server, client, client2;
5527 GUID acceptex_guid = WSAID_ACCEPTEX;
5528 struct sockaddr_in destaddr;
5529 OVERLAPPED overlapped = {0};
5530 LPFN_ACCEPTEX pAcceptEx;
5531 char buffer[32];
5532 int len, ret;
5533 DWORD size;
5535 overlapped.hEvent = CreateEventA(NULL, TRUE, FALSE, NULL);
5537 listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
5538 ok(listener != -1, "failed to create socket, error %u\n", WSAGetLastError());
5540 ret = WSAIoctl(listener, SIO_GET_EXTENSION_FUNCTION_POINTER, &acceptex_guid, sizeof(acceptex_guid),
5541 &pAcceptEx, sizeof(pAcceptEx), &size, NULL, NULL);
5542 ok(!ret, "failed to get AcceptEx, error %u\n", WSAGetLastError());
5544 select_events(ctx, listener, FD_CONNECT | FD_READ | FD_OOB | FD_ACCEPT);
5546 ret = bind(listener, (const struct sockaddr *)&addr, sizeof(addr));
5547 ok(!ret, "failed to bind, error %u\n", WSAGetLastError());
5548 len = sizeof(destaddr);
5549 ret = getsockname(listener, (struct sockaddr *)&destaddr, &len);
5550 ok(!ret, "failed to get address, error %u\n", WSAGetLastError());
5551 ret = listen(listener, 2);
5552 ok(!ret, "failed to listen, error %u\n", WSAGetLastError());
5554 check_events(ctx, 0, 0, 0);
5556 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
5557 ok(client != -1, "failed to create socket, error %u\n", WSAGetLastError());
5558 ret = connect(client, (struct sockaddr *)&destaddr, sizeof(destaddr));
5559 ok(!ret, "failed to connect, error %u\n", WSAGetLastError());
5561 check_events(ctx, FD_ACCEPT, 0, 200);
5562 check_events(ctx, 0, 0, 0);
5563 select_events(ctx, listener, FD_CONNECT | FD_READ | FD_OOB | FD_ACCEPT);
5564 if (ctx->is_message)
5565 check_events(ctx, FD_ACCEPT, 0, 200);
5566 check_events(ctx, 0, 0, 0);
5567 select_events(ctx, listener, 0);
5568 select_events(ctx, listener, FD_CONNECT | FD_READ | FD_OOB | FD_ACCEPT);
5569 if (ctx->is_message)
5570 check_events(ctx, FD_ACCEPT, 0, 200);
5571 check_events(ctx, 0, 0, 0);
5573 client2 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
5574 ok(client2 != -1, "failed to create socket, error %u\n", WSAGetLastError());
5575 ret = connect(client2, (struct sockaddr *)&destaddr, sizeof(destaddr));
5576 ok(!ret, "failed to connect, error %u\n", WSAGetLastError());
5578 if (!ctx->is_message)
5579 check_events_todo(ctx, FD_ACCEPT, 0, 200);
5580 check_events(ctx, 0, 0, 0);
5582 server = accept(listener, NULL, NULL);
5583 ok(server != -1, "failed to accept, error %u\n", WSAGetLastError());
5584 closesocket(server);
5586 check_events(ctx, FD_ACCEPT, 0, 200);
5587 check_events(ctx, 0, 0, 0);
5589 server = accept(listener, NULL, NULL);
5590 ok(server != -1, "failed to accept, error %u\n", WSAGetLastError());
5591 closesocket(server);
5593 check_events(ctx, 0, 0, 0);
5595 closesocket(client2);
5596 closesocket(client);
5598 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
5599 ok(client != -1, "failed to create socket, error %u\n", WSAGetLastError());
5600 ret = connect(client, (struct sockaddr *)&destaddr, sizeof(destaddr));
5601 ok(!ret, "failed to connect, error %u\n", WSAGetLastError());
5603 check_events(ctx, FD_ACCEPT, 0, 200);
5605 server = accept(listener, NULL, NULL);
5606 ok(server != -1, "failed to accept, error %u\n", WSAGetLastError());
5607 closesocket(server);
5608 closesocket(client);
5610 check_events(ctx, 0, 0, 200);
5612 closesocket(listener);
5614 /* Connect and then select. */
5616 listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
5617 ok(listener != -1, "failed to create socket, error %u\n", WSAGetLastError());
5618 ret = bind(listener, (const struct sockaddr *)&addr, sizeof(addr));
5619 ok(!ret, "failed to bind, error %u\n", WSAGetLastError());
5620 len = sizeof(destaddr);
5621 ret = getsockname(listener, (struct sockaddr *)&destaddr, &len);
5622 ok(!ret, "failed to get address, error %u\n", WSAGetLastError());
5623 ret = listen(listener, 2);
5624 ok(!ret, "failed to listen, error %u\n", WSAGetLastError());
5626 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
5627 ok(client != -1, "failed to create socket, error %u\n", WSAGetLastError());
5628 ret = connect(client, (struct sockaddr *)&destaddr, sizeof(destaddr));
5629 ok(!ret, "failed to connect, error %u\n", WSAGetLastError());
5631 select_events(ctx, listener, FD_CONNECT | FD_READ | FD_OOB | FD_ACCEPT);
5633 check_events(ctx, FD_ACCEPT, 0, 200);
5635 server = accept(listener, NULL, NULL);
5636 ok(server != -1, "failed to accept, error %u\n", WSAGetLastError());
5637 closesocket(server);
5638 closesocket(client);
5640 /* As above, but select on a subset containing FD_ACCEPT first. */
5642 if (!ctx->is_message)
5644 select_events(ctx, listener, FD_CONNECT | FD_READ | FD_OOB | FD_ACCEPT);
5646 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
5647 ok(client != -1, "failed to create socket, error %u\n", WSAGetLastError());
5648 ret = connect(client, (struct sockaddr *)&destaddr, sizeof(destaddr));
5649 ok(!ret, "failed to connect, error %u\n", WSAGetLastError());
5651 ret = WaitForSingleObject(ctx->event, 200);
5652 ok(!ret, "wait timed out\n");
5654 select_events(ctx, listener, FD_CONNECT | FD_READ | FD_OOB);
5655 ret = WaitForSingleObject(ctx->event, 0);
5656 ok(!ret, "wait timed out\n");
5658 ResetEvent(ctx->event);
5660 select_events(ctx, listener, FD_CONNECT | FD_READ | FD_OOB);
5661 ret = WaitForSingleObject(ctx->event, 0);
5662 ok(ret == WAIT_TIMEOUT, "expected timeout\n");
5664 select_events(ctx, listener, FD_CONNECT | FD_READ | FD_OOB | FD_ACCEPT);
5665 ret = WaitForSingleObject(ctx->event, 0);
5666 ok(!ret, "wait timed out\n");
5667 check_events(ctx, FD_ACCEPT, 0, 0);
5669 server = accept(listener, NULL, NULL);
5670 ok(server != -1, "failed to accept, error %u\n", WSAGetLastError());
5671 closesocket(server);
5672 closesocket(client);
5675 /* As above, but select on a subset not containing FD_ACCEPT first. */
5677 select_events(ctx, listener, FD_CONNECT | FD_READ | FD_OOB);
5679 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
5680 ok(client != -1, "failed to create socket, error %u\n", WSAGetLastError());
5681 ret = connect(client, (struct sockaddr *)&destaddr, sizeof(destaddr));
5682 ok(!ret, "failed to connect, error %u\n", WSAGetLastError());
5684 select_events(ctx, listener, FD_CONNECT | FD_READ | FD_OOB | FD_ACCEPT);
5685 check_events(ctx, FD_ACCEPT, 0, 200);
5687 server = accept(listener, NULL, NULL);
5688 ok(server != -1, "failed to accept, error %u\n", WSAGetLastError());
5689 closesocket(server);
5690 closesocket(client);
5692 /* As above, but call accept() before selecting. */
5694 select_events(ctx, listener, FD_CONNECT | FD_READ | FD_OOB);
5696 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
5697 ok(client != -1, "failed to create socket, error %u\n", WSAGetLastError());
5698 ret = connect(client, (struct sockaddr *)&destaddr, sizeof(destaddr));
5699 ok(!ret, "failed to connect, error %u\n", WSAGetLastError());
5700 Sleep(200);
5701 server = accept(listener, NULL, NULL);
5702 ok(server != -1, "failed to accept, error %u\n", WSAGetLastError());
5704 select_events(ctx, listener, FD_CONNECT | FD_READ | FD_OOB | FD_ACCEPT);
5705 check_events(ctx, 0, 0, 200);
5707 closesocket(server);
5708 closesocket(client);
5710 closesocket(listener);
5712 /* The socket returned from accept() inherits the same parameters. */
5714 listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
5715 ok(listener != -1, "failed to create socket, error %u\n", WSAGetLastError());
5716 ret = bind(listener, (const struct sockaddr *)&addr, sizeof(addr));
5717 ok(!ret, "failed to bind, error %u\n", WSAGetLastError());
5718 len = sizeof(destaddr);
5719 ret = getsockname(listener, (struct sockaddr *)&destaddr, &len);
5720 ok(!ret, "failed to get address, error %u\n", WSAGetLastError());
5721 ret = listen(listener, 2);
5722 ok(!ret, "failed to listen, error %u\n", WSAGetLastError());
5724 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
5725 ok(client != -1, "failed to create socket, error %u\n", WSAGetLastError());
5726 ret = connect(client, (struct sockaddr *)&destaddr, sizeof(destaddr));
5727 ok(!ret, "failed to connect, error %u\n", WSAGetLastError());
5729 select_events(ctx, listener, FD_CONNECT | FD_READ | FD_OOB | FD_ACCEPT | FD_WRITE);
5730 check_events(ctx, FD_ACCEPT, 0, 200);
5732 server = accept(listener, NULL, NULL);
5733 ok(server != -1, "failed to accept, error %u\n", WSAGetLastError());
5734 ctx->socket = server;
5735 check_events(ctx, FD_WRITE, 0, 200);
5736 check_events(ctx, 0, 0, 0);
5738 closesocket(server);
5739 closesocket(client);
5741 /* Connect while there is a pending AcceptEx(). */
5743 select_events(ctx, listener, FD_CONNECT | FD_READ | FD_OOB | FD_ACCEPT);
5745 server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
5746 ret = pAcceptEx(listener, server, buffer, 0, 0, sizeof(buffer), NULL, &overlapped);
5747 ok(!ret, "got %d\n", ret);
5748 ok(WSAGetLastError() == ERROR_IO_PENDING, "got error %u\n", WSAGetLastError());
5750 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
5751 ret = connect(client, (struct sockaddr *)&destaddr, sizeof(destaddr));
5752 ok(!ret, "got error %u\n", WSAGetLastError());
5754 ret = WaitForSingleObject(overlapped.hEvent, 200);
5755 ok(!ret, "got %d\n", ret);
5756 ret = GetOverlappedResult((HANDLE)listener, &overlapped, &size, FALSE);
5757 ok(ret, "got error %lu\n", GetLastError());
5758 ok(!size, "got size %lu\n", size);
5760 check_events(ctx, 0, 0, 0);
5762 closesocket(server);
5763 closesocket(client);
5765 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
5766 ret = connect(client, (struct sockaddr *)&destaddr, sizeof(destaddr));
5767 ok(!ret, "got error %u\n", WSAGetLastError());
5769 check_events(ctx, FD_ACCEPT, 0, 200);
5770 check_events(ctx, 0, 0, 0);
5772 server = accept(listener, NULL, NULL);
5773 ok(server != -1, "failed to accept, error %u\n", WSAGetLastError());
5774 closesocket(server);
5775 closesocket(client);
5777 closesocket(listener);
5778 CloseHandle(overlapped.hEvent);
5781 static void test_connect_events(struct event_test_ctx *ctx)
5783 const struct sockaddr_in addr = {.sin_family = AF_INET, .sin_addr.s_addr = htonl(INADDR_LOOPBACK)};
5784 SOCKET listener, server, client;
5785 struct sockaddr_in destaddr;
5786 int len, ret;
5788 listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
5789 ok(listener != -1, "failed to create socket, error %u\n", WSAGetLastError());
5790 ret = bind(listener, (const struct sockaddr *)&addr, sizeof(addr));
5791 ok(!ret, "failed to bind, error %u\n", WSAGetLastError());
5792 len = sizeof(destaddr);
5793 ret = getsockname(listener, (struct sockaddr *)&destaddr, &len);
5794 ok(!ret, "failed to get address, error %u\n", WSAGetLastError());
5795 ret = listen(listener, 2);
5796 ok(!ret, "failed to listen, error %u\n", WSAGetLastError());
5798 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
5799 ok(client != -1, "failed to create socket, error %u\n", WSAGetLastError());
5801 select_events(ctx, client, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ | FD_WRITE);
5802 check_events(ctx, 0, 0, 0);
5804 ret = connect(client, (struct sockaddr *)&destaddr, sizeof(destaddr));
5805 ok(!ret || WSAGetLastError() == WSAEWOULDBLOCK, "failed to connect, error %u\n", WSAGetLastError());
5807 check_events(ctx, FD_CONNECT, FD_WRITE, 200);
5808 check_events(ctx, 0, 0, 0);
5809 select_events(ctx, client, 0);
5810 select_events(ctx, client, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ | FD_WRITE);
5811 if (ctx->is_message)
5812 check_events(ctx, FD_WRITE, 0, 200);
5813 check_events(ctx, 0, 0, 0);
5815 server = accept(listener, NULL, NULL);
5816 ok(server != -1, "failed to accept, error %u\n", WSAGetLastError());
5818 select_events(ctx, server, FD_ACCEPT | FD_CONNECT | FD_OOB | FD_READ | FD_WRITE);
5819 check_events(ctx, FD_WRITE, 0, 200);
5821 closesocket(client);
5822 closesocket(server);
5824 /* Connect and then select. */
5826 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
5827 ok(client != -1, "failed to create socket, error %u\n", WSAGetLastError());
5829 ret = connect(client, (struct sockaddr *)&destaddr, sizeof(destaddr));
5830 ok(!ret, "failed to connect, error %u\n", WSAGetLastError());
5832 server = accept(listener, NULL, NULL);
5833 ok(server != -1, "failed to accept, error %u\n", WSAGetLastError());
5835 ret = send(client, "data", 5, 0);
5836 ok(ret == 5, "got %d\n", ret);
5838 select_events(ctx, client, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ | FD_WRITE);
5839 if (ctx->is_message)
5840 check_events(ctx, FD_WRITE, 0, 200);
5841 else
5842 check_events(ctx, FD_CONNECT, FD_WRITE, 200);
5844 closesocket(client);
5845 closesocket(server);
5847 /* As above, but select on a subset not containing FD_CONNECT first. */
5849 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
5850 ok(client != -1, "failed to create socket, error %u\n", WSAGetLastError());
5852 select_events(ctx, client, FD_ACCEPT | FD_CLOSE | FD_OOB | FD_READ | FD_WRITE);
5854 ret = connect(client, (struct sockaddr *)&destaddr, sizeof(destaddr));
5855 ok(!ret || WSAGetLastError() == WSAEWOULDBLOCK, "failed to connect, error %u\n", WSAGetLastError());
5857 server = accept(listener, NULL, NULL);
5858 ok(server != -1, "failed to accept, error %u\n", WSAGetLastError());
5860 check_events(ctx, FD_WRITE, 0, 200);
5862 select_events(ctx, client, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ | FD_WRITE);
5864 if (ctx->is_message)
5865 check_events(ctx, FD_WRITE, 0, 200);
5866 else
5867 check_events(ctx, FD_CONNECT, 0, 200);
5869 closesocket(client);
5870 closesocket(server);
5872 closesocket(listener);
5875 /* perform a blocking recv() even on a nonblocking socket */
5876 static int sync_recv(SOCKET s, void *buffer, int len, DWORD flags)
5878 OVERLAPPED overlapped = {0};
5879 WSABUF wsabuf;
5880 DWORD ret_len;
5881 int ret;
5883 overlapped.hEvent = CreateEventA(NULL, TRUE, FALSE, NULL);
5884 wsabuf.buf = buffer;
5885 wsabuf.len = len;
5886 ret = WSARecv(s, &wsabuf, 1, &ret_len, &flags, &overlapped, NULL);
5887 if (ret == -1 && WSAGetLastError() == ERROR_IO_PENDING)
5889 ret = WaitForSingleObject(overlapped.hEvent, 1000);
5890 ok(!ret, "wait timed out\n");
5891 ret = WSAGetOverlappedResult(s, &overlapped, &ret_len, FALSE, &flags);
5892 ret = (ret ? 0 : -1);
5894 CloseHandle(overlapped.hEvent);
5895 if (!ret) return ret_len;
5896 return -1;
5899 static void test_write_events(struct event_test_ctx *ctx)
5901 static const int buffer_size = 1024 * 1024;
5902 SOCKET server, client;
5903 char *buffer;
5904 int ret;
5906 buffer = malloc(buffer_size);
5908 tcp_socketpair(&client, &server);
5909 set_blocking(client, FALSE);
5911 select_events(ctx, server, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ | FD_WRITE);
5912 check_events(ctx, FD_WRITE, 0, 200);
5913 check_events(ctx, 0, 0, 0);
5914 select_events(ctx, server, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ | FD_WRITE);
5915 if (ctx->is_message)
5916 check_events(ctx, FD_WRITE, 0, 200);
5917 check_events(ctx, 0, 0, 0);
5918 select_events(ctx, server, 0);
5919 select_events(ctx, server, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ | FD_WRITE);
5920 if (ctx->is_message)
5921 check_events(ctx, FD_WRITE, 0, 200);
5922 check_events(ctx, 0, 0, 0);
5924 ret = send(server, "data", 5, 0);
5925 ok(ret == 5, "got %d\n", ret);
5927 check_events(ctx, 0, 0, 0);
5929 ret = sync_recv(client, buffer, buffer_size, 0);
5930 ok(ret == 5, "got %d\n", ret);
5932 check_events(ctx, 0, 0, 0);
5934 if (!broken(1))
5936 /* Windows will never send less than buffer_size bytes here, but Linux
5937 * may do a short write. */
5938 while ((ret = send(server, buffer, buffer_size, 0)) > 0);
5939 ok(ret == -1, "got %d\n", ret);
5940 ok(WSAGetLastError() == WSAEWOULDBLOCK, "got error %u\n", WSAGetLastError());
5942 while (recv(client, buffer, buffer_size, 0) > 0);
5943 ok(WSAGetLastError() == WSAEWOULDBLOCK, "got error %u\n", WSAGetLastError());
5945 /* Broken on Windows versions older than win10v1607 (though sometimes
5946 * works regardless, for unclear reasons. */
5947 check_events(ctx, FD_WRITE, 0, 200);
5948 check_events(ctx, 0, 0, 0);
5949 select_events(ctx, server, 0);
5950 select_events(ctx, server, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ | FD_WRITE);
5951 if (ctx->is_message)
5952 check_events(ctx, FD_WRITE, 0, 200);
5953 check_events(ctx, 0, 0, 0);
5956 closesocket(server);
5957 closesocket(client);
5959 /* Select on a subset not containing FD_WRITE first. */
5961 tcp_socketpair(&client, &server);
5962 set_blocking(client, FALSE);
5964 ret = send(client, "data", 5, 0);
5965 ok(ret == 5, "got %d\n", ret);
5967 select_events(ctx, client, FD_ACCEPT | FD_CONNECT | FD_OOB | FD_READ);
5968 if (!ctx->is_message)
5969 check_events(ctx, FD_CONNECT, 0, 200);
5970 check_events(ctx, 0, 0, 0);
5972 select_events(ctx, client, FD_ACCEPT | FD_CONNECT | FD_OOB | FD_READ | FD_WRITE);
5973 check_events(ctx, FD_WRITE, 0, 200);
5974 check_events(ctx, 0, 0, 0);
5976 closesocket(client);
5977 closesocket(server);
5979 /* Despite the documentation, and unlike FD_ACCEPT and FD_RECV, calling
5980 * send() doesn't clear the FD_WRITE bit. */
5982 tcp_socketpair(&client, &server);
5984 select_events(ctx, server, FD_ACCEPT | FD_CONNECT | FD_OOB | FD_READ | FD_WRITE);
5986 ret = send(server, "data", 5, 0);
5987 ok(ret == 5, "got %d\n", ret);
5989 check_events(ctx, FD_WRITE, 0, 200);
5991 closesocket(server);
5992 closesocket(client);
5994 free(buffer);
5997 static void test_read_events(struct event_test_ctx *ctx)
5999 OVERLAPPED overlapped = {0};
6000 SOCKET server, client;
6001 DWORD size, flags = 0;
6002 WSAPOLLFD pollfd;
6003 unsigned int i;
6004 char buffer[8];
6005 WSABUF wsabuf;
6006 HANDLE thread;
6007 int ret;
6009 overlapped.hEvent = CreateEventA(NULL, TRUE, FALSE, NULL);
6011 tcp_socketpair(&client, &server);
6012 set_blocking(client, FALSE);
6014 select_events(ctx, server, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ);
6015 check_events(ctx, 0, 0, 0);
6017 ret = send(client, "data", 5, 0);
6018 ok(ret == 5, "got %d\n", ret);
6020 check_events(ctx, FD_READ, 0, 200);
6021 check_events(ctx, 0, 0, 0);
6022 select_events(ctx, server, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ);
6023 if (ctx->is_message)
6024 check_events(ctx, FD_READ, 0, 200);
6025 check_events(ctx, 0, 0, 0);
6026 select_events(ctx, server, 0);
6027 select_events(ctx, server, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ);
6028 if (ctx->is_message)
6029 check_events(ctx, FD_READ, 0, 200);
6030 check_events(ctx, 0, 0, 0);
6032 ret = send(client, "data", 5, 0);
6033 ok(ret == 5, "got %d\n", ret);
6035 if (!ctx->is_message)
6036 check_events_todo(ctx, FD_READ, 0, 200);
6037 check_events(ctx, 0, 0, 0);
6039 ret = recv(server, buffer, 2, 0);
6040 ok(ret == 2, "got %d\n", ret);
6042 check_events(ctx, FD_READ, 0, 200);
6043 check_events(ctx, 0, 0, 0);
6045 ret = recv(server, buffer, -1, 0);
6046 ok(ret == -1, "got %d\n", ret);
6047 ok(WSAGetLastError() == WSAEFAULT || WSAGetLastError() == WSAENOBUFS /* < Windows 7 */,
6048 "got error %u\n", WSAGetLastError());
6050 if (ctx->is_message)
6051 check_events_todo_msg(ctx, FD_READ, 0, 200);
6052 check_events(ctx, 0, 0, 0);
6054 for (i = 0; i < 8; ++i)
6056 ret = sync_recv(server, buffer, 1, 0);
6057 ok(ret == 1, "got %d\n", ret);
6059 if (i < 7)
6060 check_events(ctx, FD_READ, 0, 200);
6061 check_events(ctx, 0, 0, 0);
6064 /* Send data while we're not selecting. */
6066 select_events(ctx, server, 0);
6067 ret = send(client, "data", 5, 0);
6068 ok(ret == 5, "got %d\n", ret);
6069 select_events(ctx, server, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ);
6071 check_events(ctx, FD_READ, 0, 200);
6073 ret = recv(server, buffer, 5, 0);
6074 ok(ret == 5, "got %d\n", ret);
6076 select_events(ctx, server, 0);
6077 ret = send(client, "data", 5, 0);
6078 ok(ret == 5, "got %d\n", ret);
6079 ret = sync_recv(server, buffer, 5, 0);
6080 ok(ret == 5, "got %d\n", ret);
6081 select_events(ctx, server, FD_ACCEPT | FD_CONNECT | FD_OOB | FD_READ);
6083 check_events(ctx, 0, 0, 200);
6085 /* Send data while we're polling for data but not selecting for FD_READ. */
6087 pollfd.fd = server;
6088 pollfd.events = POLLIN;
6089 thread = CreateThread(NULL, 0, poll_async_thread, &pollfd, 0, NULL);
6091 select_events(ctx, server, 0);
6092 ret = send(client, "data", 5, 0);
6093 ok(ret == 5, "got %d\n", ret);
6095 ret = WaitForSingleObject(thread, 1000);
6096 ok(!ret, "wait timed out\n");
6097 CloseHandle(thread);
6099 /* And check events, to show that WSAEnumNetworkEvents() should not clear
6100 * events we are not currently selecting for. */
6101 check_events(ctx, 0, 0, 0);
6103 select_events(ctx, server, FD_ACCEPT | FD_CONNECT | FD_OOB | FD_READ | FD_WRITE);
6104 check_events(ctx, FD_READ, FD_WRITE, 200);
6105 check_events(ctx, 0, 0, 0);
6107 ret = sync_recv(server, buffer, 5, 0);
6108 ok(ret == 5, "got %d\n", ret);
6110 /* Send data while there is a pending WSARecv(). */
6112 select_events(ctx, server, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ);
6114 wsabuf.buf = buffer;
6115 wsabuf.len = 1;
6116 ret = WSARecv(server, &wsabuf, 1, NULL, &flags, &overlapped, NULL);
6117 ok(ret == -1, "got %d\n", ret);
6118 ok(WSAGetLastError() == ERROR_IO_PENDING, "got error %u\n", WSAGetLastError());
6120 ret = send(client, "a", 1, 0);
6121 ok(ret == 1, "got %d\n", ret);
6123 ret = WaitForSingleObject(overlapped.hEvent, 200);
6124 ok(!ret, "got %d\n", ret);
6125 ret = GetOverlappedResult((HANDLE)server, &overlapped, &size, FALSE);
6126 ok(ret, "got error %lu\n", GetLastError());
6127 ok(size == 1, "got size %lu\n", size);
6129 check_events(ctx, 0, 0, 0);
6131 ret = send(client, "a", 1, 0);
6132 ok(ret == 1, "got %d\n", ret);
6134 check_events(ctx, FD_READ, 0, 200);
6135 check_events(ctx, 0, 0, 0);
6137 closesocket(server);
6138 closesocket(client);
6139 CloseHandle(overlapped.hEvent);
6142 static void test_oob_events(struct event_test_ctx *ctx)
6144 SOCKET server, client;
6145 char buffer[1];
6146 int ret;
6148 tcp_socketpair(&client, &server);
6149 set_blocking(client, FALSE);
6151 select_events(ctx, server, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ);
6152 check_events(ctx, 0, 0, 0);
6154 ret = send(client, "a", 1, MSG_OOB);
6155 ok(ret == 1, "got %d\n", ret);
6157 check_events(ctx, FD_OOB, 0, 200);
6158 check_events(ctx, 0, 0, 0);
6159 select_events(ctx, server, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ);
6160 if (ctx->is_message)
6161 check_events(ctx, FD_OOB, 0, 200);
6162 check_events(ctx, 0, 0, 0);
6163 select_events(ctx, server, 0);
6164 select_events(ctx, server, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ);
6165 if (ctx->is_message)
6166 check_events(ctx, FD_OOB, 0, 200);
6167 check_events(ctx, 0, 0, 0);
6169 ret = send(client, "b", 1, MSG_OOB);
6170 ok(ret == 1, "got %d\n", ret);
6172 if (!ctx->is_message)
6173 check_events_todo_event(ctx, FD_OOB, 0, 200);
6174 check_events(ctx, 0, 0, 0);
6176 ret = recv(server, buffer, 1, MSG_OOB);
6177 ok(ret == 1, "got %d\n", ret);
6179 check_events_todo(ctx, FD_OOB, 0, 200);
6180 check_events(ctx, 0, 0, 0);
6182 ret = recv(server, buffer, 1, MSG_OOB);
6183 todo_wine ok(ret == 1, "got %d\n", ret);
6185 check_events(ctx, 0, 0, 0);
6187 /* Send data while we're not selecting. */
6189 select_events(ctx, server, 0);
6190 ret = send(client, "a", 1, MSG_OOB);
6191 ok(ret == 1, "got %d\n", ret);
6192 select_events(ctx, server, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ);
6194 check_events(ctx, FD_OOB, 0, 200);
6196 ret = recv(server, buffer, 1, MSG_OOB);
6197 ok(ret == 1, "got %d\n", ret);
6199 closesocket(server);
6200 closesocket(client);
6203 static void test_close_events(struct event_test_ctx *ctx)
6205 SOCKET server, client;
6206 char buffer[5];
6207 int ret;
6209 /* Test closesocket(). */
6211 tcp_socketpair(&client, &server);
6213 select_events(ctx, server, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ);
6215 closesocket(client);
6217 check_events(ctx, FD_CLOSE, 0, 200);
6218 check_events(ctx, 0, 0, 0);
6219 select_events(ctx, server, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ);
6220 if (ctx->is_message)
6221 check_events(ctx, FD_CLOSE, 0, 200);
6222 check_events(ctx, 0, 0, 0);
6223 select_events(ctx, server, 0);
6224 select_events(ctx, server, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ);
6225 if (ctx->is_message)
6226 check_events(ctx, FD_CLOSE, 0, 200);
6227 check_events(ctx, 0, 0, 0);
6229 ret = recv(server, buffer, 5, 0);
6230 ok(!ret, "got %d\n", ret);
6232 check_events(ctx, 0, 0, 0);
6234 closesocket(server);
6236 /* Test shutdown(remote end, SD_SEND). */
6238 tcp_socketpair(&client, &server);
6240 select_events(ctx, server, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ);
6242 shutdown(client, SD_SEND);
6244 check_events(ctx, FD_CLOSE, 0, 200);
6245 check_events(ctx, 0, 0, 0);
6247 closesocket(client);
6249 check_events(ctx, 0, 0, 0);
6251 closesocket(server);
6253 /* No other shutdown() call generates an event. */
6255 tcp_socketpair(&client, &server);
6257 select_events(ctx, server, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ);
6259 shutdown(client, SD_RECEIVE);
6260 shutdown(server, SD_BOTH);
6262 check_events(ctx, 0, 0, 200);
6264 shutdown(client, SD_SEND);
6266 check_events_todo(ctx, FD_CLOSE, 0, 200);
6267 check_events(ctx, 0, 0, 0);
6269 closesocket(server);
6270 closesocket(client);
6272 /* Test sending data before calling closesocket(). */
6274 tcp_socketpair(&client, &server);
6276 select_events(ctx, server, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ);
6278 ret = send(client, "data", 5, 0);
6279 ok(ret == 5, "got %d\n", ret);
6281 check_events(ctx, FD_READ, 0, 200);
6283 closesocket(client);
6285 check_events_todo(ctx, FD_CLOSE, 0, 200);
6287 ret = recv(server, buffer, 3, 0);
6288 ok(ret == 3, "got %d\n", ret);
6290 check_events(ctx, FD_READ, 0, 200);
6292 ret = recv(server, buffer, 5, 0);
6293 ok(ret == 2, "got %d\n", ret);
6295 check_events_todo(ctx, 0, 0, 0);
6297 closesocket(server);
6299 /* Close and then select. */
6301 tcp_socketpair(&client, &server);
6302 closesocket(client);
6304 select_events(ctx, server, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ);
6305 check_events(ctx, FD_CLOSE, 0, 200);
6307 closesocket(server);
6309 /* As above, but select on a subset not containing FD_CLOSE first. */
6311 tcp_socketpair(&client, &server);
6313 select_events(ctx, server, FD_ACCEPT | FD_CONNECT | FD_OOB | FD_READ);
6315 closesocket(client);
6317 check_events(ctx, 0, 0, 200);
6318 select_events(ctx, server, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ);
6319 check_events(ctx, FD_CLOSE, 0, 200);
6321 closesocket(server);
6323 /* Trigger RST. */
6325 tcp_socketpair(&client, &server);
6327 select_events(ctx, server, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ);
6329 close_with_rst(client);
6331 check_events_todo_msg(ctx, MAKELONG(FD_CLOSE, WSAECONNABORTED), 0, 200);
6332 check_events(ctx, 0, 0, 0);
6333 select_events(ctx, server, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ);
6334 if (ctx->is_message)
6335 check_events_todo(ctx, MAKELONG(FD_CLOSE, WSAECONNABORTED), 0, 200);
6336 check_events(ctx, 0, 0, 0);
6337 select_events(ctx, server, 0);
6338 select_events(ctx, server, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ);
6339 if (ctx->is_message)
6340 check_events_todo(ctx, MAKELONG(FD_CLOSE, WSAECONNABORTED), 0, 200);
6341 check_events(ctx, 0, 0, 0);
6343 closesocket(server);
6346 static void test_events(void)
6348 struct event_test_ctx ctx;
6350 ctx.is_message = FALSE;
6351 ctx.event = CreateEventW(NULL, TRUE, FALSE, NULL);
6353 test_accept_events(&ctx);
6354 test_connect_events(&ctx);
6355 test_write_events(&ctx);
6356 test_read_events(&ctx);
6357 test_close_events(&ctx);
6358 test_oob_events(&ctx);
6360 CloseHandle(ctx.event);
6362 ctx.is_message = TRUE;
6363 ctx.window = CreateWindowA("Message", NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL);
6365 test_accept_events(&ctx);
6366 test_connect_events(&ctx);
6367 test_write_events(&ctx);
6368 test_read_events(&ctx);
6369 test_close_events(&ctx);
6370 test_oob_events(&ctx);
6372 DestroyWindow(ctx.window);
6375 static void test_ipv6only(void)
6377 SOCKET v4 = INVALID_SOCKET, v6;
6378 struct sockaddr_in sin4;
6379 struct sockaddr_in6 sin6;
6380 int ret, enabled, len = sizeof(enabled);
6382 memset(&sin4, 0, sizeof(sin4));
6383 sin4.sin_family = AF_INET;
6384 sin4.sin_port = htons(SERVERPORT);
6386 memset(&sin6, 0, sizeof(sin6));
6387 sin6.sin6_family = AF_INET6;
6388 sin6.sin6_port = htons(SERVERPORT);
6390 v6 = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
6391 if (v6 == INVALID_SOCKET)
6393 skip("Could not create IPv6 socket (LastError: %d)\n", WSAGetLastError());
6394 goto end;
6397 enabled = 2;
6398 ret = getsockopt(v6, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&enabled, &len);
6399 ok(!ret, "getsockopt(IPV6_V6ONLY) failed (LastError: %d)\n", WSAGetLastError());
6400 ok(enabled == 1, "expected 1, got %d\n", enabled);
6402 ret = bind(v6, (struct sockaddr*)&sin6, sizeof(sin6));
6403 ok(!ret, "failed to bind, error %u\n", WSAGetLastError());
6405 v4 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
6406 ok(v4 != INVALID_SOCKET, "Could not create IPv4 socket (LastError: %d)\n", WSAGetLastError());
6408 todo_wine {
6409 enabled = 2;
6410 ret = getsockopt(v4, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&enabled, &len);
6411 ok(!ret, "getsockopt(IPV6_V6ONLY) failed (LastError: %d)\n", WSAGetLastError());
6412 ok(enabled == 1, "expected 1, got %d\n", enabled);
6415 enabled = 0;
6416 len = sizeof(enabled);
6417 ret = setsockopt(v4, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&enabled, len);
6418 ok(!ret, "setsockopt(IPV6_V6ONLY) failed (LastError: %d)\n", WSAGetLastError());
6420 todo_wine {
6421 enabled = 2;
6422 ret = getsockopt(v4, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&enabled, &len);
6423 ok(!ret, "getsockopt(IPV6_V6ONLY) failed (LastError: %d)\n", WSAGetLastError());
6424 ok(!enabled, "expected 0, got %d\n", enabled);
6427 enabled = 1;
6428 len = sizeof(enabled);
6429 ret = setsockopt(v4, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&enabled, len);
6430 ok(!ret, "setsockopt(IPV6_V6ONLY) failed (LastError: %d)\n", WSAGetLastError());
6432 /* bind on IPv4 socket should succeed - IPV6_V6ONLY is enabled by default */
6433 ret = bind(v4, (struct sockaddr*)&sin4, sizeof(sin4));
6434 ok(!ret, "Could not bind IPv4 address (LastError: %d)\n", WSAGetLastError());
6436 todo_wine {
6437 enabled = 2;
6438 ret = getsockopt(v4, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&enabled, &len);
6439 ok(!ret, "getsockopt(IPV6_V6ONLY) failed (LastError: %d)\n", WSAGetLastError());
6440 ok(enabled == 1, "expected 1, got %d\n", enabled);
6443 enabled = 0;
6444 len = sizeof(enabled);
6445 ret = setsockopt(v4, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&enabled, len);
6446 ok(ret, "setsockopt(IPV6_V6ONLY) succeeded (LastError: %d)\n", WSAGetLastError());
6448 todo_wine {
6449 enabled = 0;
6450 ret = getsockopt(v4, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&enabled, &len);
6451 ok(!ret, "getsockopt(IPV6_V6ONLY) failed (LastError: %d)\n", WSAGetLastError());
6452 ok(enabled == 1, "expected 1, got %d\n", enabled);
6455 enabled = 1;
6456 len = sizeof(enabled);
6457 ret = setsockopt(v4, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&enabled, len);
6458 ok(ret, "setsockopt(IPV6_V6ONLY) succeeded (LastError: %d)\n", WSAGetLastError());
6460 closesocket(v4);
6461 closesocket(v6);
6463 /* Test again, this time disabling IPV6_V6ONLY. */
6464 sin4.sin_port = htons(SERVERPORT+2);
6465 sin6.sin6_port = htons(SERVERPORT+2);
6467 v6 = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
6468 ok(v6 != INVALID_SOCKET, "Could not create IPv6 socket (LastError: %d; %d expected if IPv6 not available).\n",
6469 WSAGetLastError(), WSAEAFNOSUPPORT);
6471 enabled = 0;
6472 ret = setsockopt(v6, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&enabled, len);
6473 ok(!ret, "Could not disable IPV6_V6ONLY (LastError: %d).\n", WSAGetLastError());
6475 enabled = 2;
6476 ret = getsockopt(v6, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&enabled, &len);
6477 ok(!ret, "getsockopt(IPV6_V6ONLY) failed (LastError: %d)\n", WSAGetLastError());
6478 ok(!enabled, "expected 0, got %d\n", enabled);
6481 Observaition:
6482 On Windows, bind on both IPv4 and IPv6 with IPV6_V6ONLY disabled succeeds by default.
6483 Application must set SO_EXCLUSIVEADDRUSE on first socket to disallow another successful bind.
6484 In general, a standard application should not use SO_REUSEADDR.
6485 Setting both SO_EXCLUSIVEADDRUSE and SO_REUSEADDR on the same socket is not possible in
6486 either order, the later setsockopt call always fails.
6488 enabled = 1;
6489 ret = setsockopt(v6, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (char*)&enabled, len);
6490 ok(!ret, "Could not set SO_EXCLUSIVEADDRUSE on IPv6 socket (LastError: %d)\n", WSAGetLastError());
6492 ret = bind(v6, (struct sockaddr*)&sin6, sizeof(sin6));
6493 ok(!ret, "Could not bind IPv6 address (LastError: %d)\n", WSAGetLastError());
6495 enabled = 2;
6496 len = sizeof(enabled);
6497 getsockopt(v6, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&enabled, &len);
6498 ok(!ret, "getsockopt(IPV6_V6ONLY) failed (LastError: %d)\n", WSAGetLastError());
6499 ok(!enabled, "IPV6_V6ONLY is enabled after bind\n");
6501 v4 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
6502 ok(v4 != INVALID_SOCKET, "Could not create IPv4 socket (LastError: %d)\n", WSAGetLastError());
6504 enabled = 1;
6505 ret = setsockopt(v4, SOL_SOCKET, SO_REUSEADDR, (char*)&enabled, len);
6506 ok(!ret, "Could not set SO_REUSEADDR on IPv4 socket (LastError: %d)\n", WSAGetLastError());
6508 WSASetLastError(0xdeadbeef);
6509 ret = bind(v4, (struct sockaddr*)&sin4, sizeof(sin4));
6510 ok(ret, "bind succeeded unexpectedly for the IPv4 socket\n");
6511 ok(WSAGetLastError() == WSAEACCES, "Expected 10013, got %d\n", WSAGetLastError());
6513 end:
6514 if (v4 != INVALID_SOCKET)
6515 closesocket(v4);
6516 if (v6 != INVALID_SOCKET)
6517 closesocket(v6);
6520 static void test_WSASendMsg(void)
6522 SOCKET sock, dst;
6523 struct sockaddr_in sendaddr, sockaddr;
6524 GUID WSASendMsg_GUID = WSAID_WSASENDMSG;
6525 LPFN_WSASENDMSG pWSASendMsg = NULL;
6526 char teststr[12] = "hello world", buffer[32];
6527 WSABUF iovec[2];
6528 WSAMSG msg;
6529 DWORD bytesSent, err;
6530 int ret, addrlen;
6532 /* FIXME: Missing OVERLAPPED and OVERLAPPED COMPLETION ROUTINE tests */
6534 sock = socket(AF_INET, SOCK_DGRAM, 0);
6535 ok(sock != INVALID_SOCKET, "socket() failed\n");
6537 /* Obtain the WSASendMsg function */
6538 WSAIoctl(sock, SIO_GET_EXTENSION_FUNCTION_POINTER, &WSASendMsg_GUID, sizeof(WSASendMsg_GUID),
6539 &pWSASendMsg, sizeof(pWSASendMsg), &err, NULL, NULL);
6540 if (!pWSASendMsg)
6542 closesocket(sock);
6543 win_skip("WSASendMsg is unsupported, some tests will be skipped.\n");
6544 return;
6547 /* fake address for now */
6548 sendaddr.sin_family = AF_INET;
6549 sendaddr.sin_port = htons(139);
6550 sendaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
6552 memset(&msg, 0, sizeof(msg));
6553 iovec[0].buf = teststr;
6554 iovec[0].len = sizeof(teststr);
6555 iovec[1].buf = teststr;
6556 iovec[1].len = sizeof(teststr) / 2;
6557 msg.name = (struct sockaddr *) &sendaddr;
6558 msg.namelen = sizeof(sendaddr);
6559 msg.lpBuffers = iovec;
6560 msg.dwBufferCount = 1; /* send only one buffer for now */
6562 WSASetLastError(0xdeadbeef);
6563 ret = pWSASendMsg(INVALID_SOCKET, &msg, 0, NULL, NULL, NULL);
6564 ok(ret == SOCKET_ERROR, "WSASendMsg should have failed\n");
6565 err = WSAGetLastError();
6566 ok(err == WSAENOTSOCK, "expected 10038, got %ld instead\n", err);
6568 WSASetLastError(0xdeadbeef);
6569 ret = pWSASendMsg(sock, NULL, 0, NULL, NULL, NULL);
6570 ok(ret == SOCKET_ERROR, "WSASendMsg should have failed\n");
6571 err = WSAGetLastError();
6572 ok(err == WSAEFAULT, "expected 10014, got %ld instead\n", err);
6574 WSASetLastError(0xdeadbeef);
6575 ret = pWSASendMsg(sock, NULL, 0, &bytesSent, NULL, NULL);
6576 ok(ret == SOCKET_ERROR, "WSASendMsg should have failed\n");
6577 err = WSAGetLastError();
6578 ok(err == WSAEFAULT, "expected 10014, got %ld instead\n", err);
6580 WSASetLastError(0xdeadbeef);
6581 ret = pWSASendMsg(sock, &msg, 0, NULL, NULL, NULL);
6582 ok(ret == SOCKET_ERROR, "WSASendMsg should have failed\n");
6583 err = WSAGetLastError();
6584 ok(err == WSAEFAULT, "expected 10014, got %ld instead\n", err);
6586 closesocket(sock);
6588 sock = socket(AF_INET, SOCK_DGRAM, 0);
6589 ok(sock != INVALID_SOCKET, "socket() failed\n");
6591 dst = socket(AF_INET, SOCK_DGRAM, 0);
6592 ok(dst != INVALID_SOCKET, "socket() failed\n");
6594 memset(&sockaddr, 0, sizeof(sockaddr));
6595 sockaddr.sin_family = AF_INET;
6596 sockaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
6597 ok(!bind(dst, (struct sockaddr*)&sockaddr, sizeof(sockaddr)),
6598 "bind should have worked\n");
6600 /* read address to find out the port number to be used in send */
6601 memset(&sendaddr, 0, sizeof(sendaddr));
6602 addrlen = sizeof(sendaddr);
6603 ok(!getsockname(dst, (struct sockaddr *) &sendaddr, &addrlen),
6604 "getsockname should have worked\n");
6605 ok(sendaddr.sin_port, "socket port should be != 0\n");
6607 /* ensure the sending socket is not bound */
6608 WSASetLastError(0xdeadbeef);
6609 addrlen = sizeof(sockaddr);
6610 ret = getsockname(sock, (struct sockaddr*)&sockaddr, &addrlen);
6611 ok(ret == SOCKET_ERROR, "getsockname should have failed\n");
6612 err = WSAGetLastError();
6613 ok(err == WSAEINVAL, "expected 10022, got %ld instead\n", err);
6615 set_blocking(sock, TRUE);
6617 bytesSent = 0;
6618 SetLastError(0xdeadbeef);
6619 ret = pWSASendMsg(sock, &msg, 0, &bytesSent, NULL, NULL);
6620 ok(!ret, "WSASendMsg should have worked\n");
6621 ok(GetLastError() == 0 || broken(GetLastError() == 0xdeadbeef) /* Win <= 2008 */,
6622 "Expected 0, got %ld\n", GetLastError());
6623 ok(bytesSent == iovec[0].len, "incorrect bytes sent, expected %ld, sent %ld\n",
6624 iovec[0].len, bytesSent);
6626 /* receive data */
6627 addrlen = sizeof(sockaddr);
6628 memset(buffer, 0, sizeof(buffer));
6629 SetLastError(0xdeadbeef);
6630 ret = recvfrom(dst, buffer, sizeof(buffer), 0, (struct sockaddr *) &sockaddr, &addrlen);
6631 ok(ret == bytesSent, "got %d, expected %ld\n",
6632 ret, bytesSent);
6633 ok(GetLastError() == ERROR_SUCCESS, "Expected 0, got %ld\n", GetLastError());
6635 /* A successful call to WSASendMsg must have bound the socket */
6636 addrlen = sizeof(sockaddr);
6637 sockaddr.sin_port = 0;
6638 sockaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
6639 ret = getsockname(sock, (struct sockaddr*)&sockaddr, &addrlen);
6640 ok(!ret, "getsockname should have worked\n");
6641 ok(sockaddr.sin_addr.s_addr == htonl(INADDR_ANY), "expected 0.0.0.0, got %s\n",
6642 inet_ntoa(sockaddr.sin_addr));
6643 ok(sockaddr.sin_port, "sin_port should be != 0\n");
6645 msg.dwBufferCount = 2; /* send both buffers */
6647 bytesSent = 0;
6648 SetLastError(0xdeadbeef);
6649 ret = pWSASendMsg(sock, &msg, 0, &bytesSent, NULL, NULL);
6650 ok(!ret, "WSASendMsg should have worked\n");
6651 ok(bytesSent == iovec[0].len + iovec[1].len, "incorrect bytes sent, expected %ld, sent %ld\n",
6652 iovec[0].len + iovec[1].len, bytesSent);
6653 ok(GetLastError() == 0 || broken(GetLastError() == 0xdeadbeef) /* Win <= 2008 */,
6654 "Expected 0, got %ld\n", GetLastError());
6656 /* receive data */
6657 addrlen = sizeof(sockaddr);
6658 memset(buffer, 0, sizeof(buffer));
6659 SetLastError(0xdeadbeef);
6660 ret = recvfrom(dst, buffer, sizeof(buffer), 0, (struct sockaddr *) &sockaddr, &addrlen);
6661 ok(ret == bytesSent, "got %d, expected %ld\n",
6662 ret, bytesSent);
6663 ok(GetLastError() == ERROR_SUCCESS, "Expected 0, got %ld\n", GetLastError());
6665 closesocket(sock);
6666 closesocket(dst);
6668 /* a bad call to WSASendMsg will also bind the socket */
6669 addrlen = sizeof(sockaddr);
6670 sockaddr.sin_port = 0;
6671 sockaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
6672 sock = socket(AF_INET, SOCK_DGRAM, 0);
6673 ok(sock != INVALID_SOCKET, "socket() failed\n");
6674 ok(pWSASendMsg(sock, &msg, 0, NULL, NULL, NULL) == SOCKET_ERROR, "WSASendMsg should have failed\n");
6675 todo_wine {
6676 ok(!getsockname(sock, (struct sockaddr*)&sockaddr, &addrlen), "getsockname should have worked\n");
6677 ok(sockaddr.sin_addr.s_addr == htonl(INADDR_ANY), "expected 0.0.0.0, got %s\n",
6678 inet_ntoa(sockaddr.sin_addr));
6679 ok(sockaddr.sin_port, "sin_port should be > 0\n");
6681 closesocket(sock);
6683 /* a bad call without msg parameter will not trigger the auto-bind */
6684 sock = socket(AF_INET, SOCK_DGRAM, 0);
6685 ok(sock != INVALID_SOCKET, "socket() failed\n");
6686 ok(pWSASendMsg(sock, NULL, 0, NULL, NULL, NULL) == SOCKET_ERROR, "WSASendMsg should have failed\n");
6687 ok(getsockname(sock, (struct sockaddr*)&sockaddr, &addrlen), "getsockname should have failed\n");
6688 err = WSAGetLastError();
6689 ok(err == WSAEINVAL, "expected 10022, got %ld instead\n", err);
6690 closesocket(sock);
6692 /* SOCK_STREAM sockets are not supported */
6693 bytesSent = 0;
6694 sock = socket(AF_INET, SOCK_STREAM, 0);
6695 ok(sock != INVALID_SOCKET, "socket() failed\n");
6696 SetLastError(0xdeadbeef);
6697 ret = pWSASendMsg(sock, &msg, 0, &bytesSent, NULL, NULL);
6698 ok(ret == SOCKET_ERROR, "WSASendMsg should have failed\n");
6699 err = WSAGetLastError();
6700 todo_wine
6701 ok(err == WSAEINVAL, "expected 10014, got %ld instead\n", err);
6702 closesocket(sock);
6705 static void test_WSASendTo(void)
6707 SOCKET s;
6708 struct sockaddr_in addr, ret_addr;
6709 char buf[12] = "hello world";
6710 WSABUF data_buf;
6711 DWORD bytesSent;
6712 int ret, len;
6714 addr.sin_family = AF_INET;
6715 addr.sin_port = htons(139);
6716 addr.sin_addr.s_addr = inet_addr("127.0.0.1");
6717 data_buf.len = sizeof(buf);
6718 data_buf.buf = buf;
6720 s = socket(AF_INET, SOCK_DGRAM, 0);
6721 ok(s != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
6723 WSASetLastError(12345);
6724 ret = WSASendTo(INVALID_SOCKET, &data_buf, 1, NULL, 0, (struct sockaddr*)&addr, sizeof(addr), NULL, NULL);
6725 ok(ret == SOCKET_ERROR && WSAGetLastError() == WSAENOTSOCK,
6726 "WSASendTo() failed: %d/%d\n", ret, WSAGetLastError());
6728 len = sizeof(ret_addr);
6729 ret = getsockname(s, (struct sockaddr *)&ret_addr, &len);
6730 ok(ret == -1, "expected failure\n");
6731 ok(WSAGetLastError() == WSAEINVAL, "got error %u\n", WSAGetLastError());
6733 WSASetLastError(12345);
6734 ret = WSASendTo(s, &data_buf, 1, NULL, 0, (struct sockaddr*)&addr, sizeof(addr), NULL, NULL);
6735 ok(ret == SOCKET_ERROR && WSAGetLastError() == WSAEFAULT,
6736 "WSASendTo() failed: %d/%d\n", ret, WSAGetLastError());
6738 WSASetLastError(12345);
6739 ret = WSASendTo(s, &data_buf, 1, &bytesSent, 0, (struct sockaddr *)&addr, sizeof(addr), NULL, NULL);
6740 ok(!ret, "expected success\n");
6741 ok(!WSAGetLastError(), "got error %u\n", WSAGetLastError());
6743 len = sizeof(ret_addr);
6744 ret = getsockname(s, (struct sockaddr *)&ret_addr, &len);
6745 ok(!ret, "got error %u\n", WSAGetLastError());
6746 ok(ret_addr.sin_family == AF_INET, "got family %u\n", ret_addr.sin_family);
6747 ok(ret_addr.sin_port, "expected nonzero port\n");
6750 struct recv_thread_apc_param
6752 SOCKET sock;
6753 unsigned int apc_count;
6756 static void WINAPI recv_thread_apc_func(ULONG_PTR param)
6758 struct recv_thread_apc_param *p = (struct recv_thread_apc_param *)param;
6759 int ret;
6761 ++p->apc_count;
6763 ret = send(p->sock, "test", 4, 0);
6764 ok(ret == 4, "got %d.\n", ret);
6767 struct recv_thread_param
6769 SOCKET sock;
6770 BOOL overlapped;
6773 static DWORD WINAPI recv_thread(LPVOID arg)
6775 struct recv_thread_param *p = arg;
6776 SOCKET sock = p->sock;
6777 char buffer[32];
6778 WSABUF wsa;
6779 WSAOVERLAPPED ov;
6780 DWORD flags = 0;
6781 DWORD len;
6782 int ret;
6784 wsa.buf = buffer;
6785 wsa.len = sizeof(buffer);
6786 if (p->overlapped)
6788 ov.hEvent = WSACreateEvent();
6789 WSARecv(sock, &wsa, 1, NULL, &flags, &ov, NULL);
6791 WaitForSingleObject(ov.hEvent, 1000);
6792 WSACloseEvent(ov.hEvent);
6794 else
6796 SetLastError(0xdeadbeef);
6797 ret = WSARecv(sock, &wsa, 1, &len, &flags, NULL, NULL);
6798 ok(!ret, "got ret %d.\n", ret);
6799 ok(WSAGetLastError() == 0, "got error %d.\n", WSAGetLastError());
6800 ok(len == 4, "got len %lu.\n", len);
6802 return 0;
6805 static int completion_called;
6807 static void WINAPI io_completion(DWORD error, DWORD transferred, WSAOVERLAPPED *overlapped, DWORD flags)
6809 completion_called++;
6812 static void test_WSARecv(void)
6814 SOCKET src, dest, server = INVALID_SOCKET;
6815 struct recv_thread_apc_param apc_param;
6816 struct recv_thread_param recv_param;
6817 char buf[20];
6818 WSABUF bufs[2];
6819 WSAOVERLAPPED ov;
6820 DWORD bytesReturned, flags, id;
6821 struct sockaddr_in addr;
6822 unsigned int apc_count;
6823 int iret, len;
6824 DWORD dwret;
6825 BOOL bret;
6826 HANDLE thread, event = NULL, io_port;
6828 tcp_socketpair(&src, &dest);
6830 memset(&ov, 0, sizeof(ov));
6831 flags = 0;
6832 bufs[0].len = 2;
6833 bufs[0].buf = buf;
6835 /* Send 4 bytes and receive in two calls of 2 */
6836 SetLastError(0xdeadbeef);
6837 iret = send(src, "test", 4, 0);
6838 ok(iret == 4, "Expected 4, got %d\n", iret);
6839 ok(GetLastError() == ERROR_SUCCESS, "Expected 0, got %ld\n", GetLastError());
6840 SetLastError(0xdeadbeef);
6841 bytesReturned = 0xdeadbeef;
6843 apc_count = 0;
6844 dwret = QueueUserAPC(apc_func, GetCurrentThread(), (ULONG_PTR)&apc_count);
6845 ok(dwret, "QueueUserAPC returned %lu\n", dwret);
6847 iret = WSARecv(dest, bufs, 1, &bytesReturned, &flags, NULL, NULL);
6848 ok(!iret, "Expected 0, got %d\n", iret);
6849 ok(bytesReturned == 2, "Expected 2, got %ld\n", bytesReturned);
6850 ok(GetLastError() == ERROR_SUCCESS, "Expected 0, got %ld\n", GetLastError());
6852 ok(!apc_count, "got apc_count %u.\n", apc_count);
6853 SleepEx(0, TRUE);
6854 ok(apc_count == 1, "got apc_count %u.\n", apc_count);
6856 SetLastError(0xdeadbeef);
6857 bytesReturned = 0xdeadbeef;
6858 iret = WSARecv(dest, bufs, 1, &bytesReturned, &flags, NULL, NULL);
6859 ok(!iret, "Expected 0, got %d\n", iret);
6860 ok(bytesReturned == 2, "Expected 2, got %ld\n", bytesReturned);
6861 ok(GetLastError() == ERROR_SUCCESS, "Expected 0, got %ld\n", GetLastError());
6863 bufs[0].len = 4;
6864 SetLastError(0xdeadbeef);
6865 iret = send(src, "test", 4, 0);
6866 ok(iret == 4, "Expected 4, got %d\n", iret);
6867 ok(GetLastError() == ERROR_SUCCESS, "Expected 0, got %ld\n", GetLastError());
6868 SetLastError(0xdeadbeef);
6869 bytesReturned = 0xdeadbeef;
6870 iret = WSARecv(dest, bufs, 1, &bytesReturned, &flags, NULL, NULL);
6871 ok(!iret, "Expected 0, got %d\n", iret);
6872 ok(bytesReturned == 4, "Expected 4, got %ld\n", bytesReturned);
6873 ok(GetLastError() == ERROR_SUCCESS, "Expected 0, got %ld\n", GetLastError());
6875 /* Test 2 buffers */
6876 bufs[0].len = 4;
6877 bufs[1].len = 5;
6878 bufs[1].buf = buf + 10;
6879 SetLastError(0xdeadbeef);
6880 iret = send(src, "deadbeefs", 9, 0);
6881 ok(iret == 9, "Expected 9, got %d\n", iret);
6882 ok(GetLastError() == ERROR_SUCCESS, "Expected 0, got %ld\n", GetLastError());
6883 SetLastError(0xdeadbeef);
6884 bytesReturned = 0xdeadbeef;
6885 iret = WSARecv(dest, bufs, 2, &bytesReturned, &flags, NULL, NULL);
6886 ok(!iret, "Expected 0, got %d\n", iret);
6887 ok(bytesReturned == 9, "Expected 9, got %ld\n", bytesReturned);
6888 bufs[0].buf[4] = '\0';
6889 bufs[1].buf[5] = '\0';
6890 ok(!strcmp(bufs[0].buf, "dead"), "buf[0] doesn't match: %s != dead\n", bufs[0].buf);
6891 ok(!strcmp(bufs[1].buf, "beefs"), "buf[1] doesn't match: %s != beefs\n", bufs[1].buf);
6892 ok(GetLastError() == ERROR_SUCCESS, "Expected 0, got %ld\n", GetLastError());
6894 bufs[0].len = sizeof(buf);
6895 ov.hEvent = event = CreateEventA(NULL, FALSE, FALSE, NULL);
6896 ok(ov.hEvent != NULL, "could not create event object, errno = %ld\n", GetLastError());
6897 if (!event)
6898 goto end;
6900 iret = WSARecv(dest, bufs, 1, NULL, &flags, &ov, NULL);
6901 ok(iret == SOCKET_ERROR && GetLastError() == ERROR_IO_PENDING, "WSARecv failed - %d error %ld\n", iret, GetLastError());
6903 iret = WSARecv(dest, bufs, 1, &bytesReturned, &flags, &ov, NULL);
6904 ok(iret == SOCKET_ERROR && GetLastError() == ERROR_IO_PENDING, "WSARecv failed - %d error %ld\n", iret, GetLastError());
6906 close_with_rst(src);
6908 dwret = WaitForSingleObject(ov.hEvent, 1000);
6909 ok(dwret == WAIT_OBJECT_0, "Waiting for disconnect event failed with %ld + errno %ld\n", dwret, GetLastError());
6911 bret = GetOverlappedResult((HANDLE)dest, &ov, &bytesReturned, FALSE);
6912 todo_wine ok(!bret, "expected failure\n");
6913 todo_wine ok(GetLastError() == ERROR_NETNAME_DELETED, "got error %lu\n", GetLastError());
6914 ok(bytesReturned == 0, "Bytes received is %ld\n", bytesReturned);
6915 closesocket(dest);
6916 dest = INVALID_SOCKET;
6918 src = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0);
6919 ok(src != INVALID_SOCKET, "failed to create socket %d\n", WSAGetLastError());
6920 if (src == INVALID_SOCKET) goto end;
6922 server = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
6923 ok(server != INVALID_SOCKET, "failed to create socket %d\n", WSAGetLastError());
6924 if (server == INVALID_SOCKET) goto end;
6926 memset(&addr, 0, sizeof(addr));
6927 addr.sin_family = AF_INET;
6928 addr.sin_addr.s_addr = inet_addr("127.0.0.1");
6929 iret = bind(server, (struct sockaddr *)&addr, sizeof(addr));
6930 ok(!iret, "failed to bind, error %u\n", WSAGetLastError());
6932 len = sizeof(addr);
6933 iret = getsockname(server, (struct sockaddr *)&addr, &len);
6934 ok(!iret, "failed to get address, error %u\n", WSAGetLastError());
6936 iret = listen(server, 1);
6937 ok(!iret, "failed to listen, error %u\n", WSAGetLastError());
6939 iret = connect(src, (struct sockaddr *)&addr, sizeof(addr));
6940 ok(!iret, "failed to connect, error %u\n", WSAGetLastError());
6942 len = sizeof(addr);
6943 dest = accept(server, (struct sockaddr *)&addr, &len);
6944 ok(dest != INVALID_SOCKET, "failed to create socket %d\n", WSAGetLastError());
6945 if (dest == INVALID_SOCKET) goto end;
6947 send(src, "test message", sizeof("test message"), 0);
6948 recv_param.sock = dest;
6949 recv_param.overlapped = TRUE;
6950 thread = CreateThread(NULL, 0, recv_thread, &recv_param, 0, &id);
6951 WaitForSingleObject(thread, 3000);
6952 CloseHandle(thread);
6954 recv_param.overlapped = FALSE;
6955 thread = CreateThread(NULL, 0, recv_thread, &recv_param, 0, &id);
6956 apc_param.apc_count = 0;
6957 apc_param.sock = src;
6958 dwret = QueueUserAPC(recv_thread_apc_func, thread, (ULONG_PTR)&apc_param);
6959 ok(dwret, "QueueUserAPC returned %lu\n", dwret);
6960 WaitForSingleObject(thread, 3000);
6961 ok(apc_param.apc_count == 1, "got apc_count %u.\n", apc_param.apc_count);
6963 CloseHandle(thread);
6965 memset(&ov, 0, sizeof(ov));
6966 ov.hEvent = event;
6967 ResetEvent(event);
6968 iret = WSARecv(dest, bufs, 1, NULL, &flags, &ov, io_completion);
6969 ok(iret == SOCKET_ERROR && GetLastError() == ERROR_IO_PENDING, "WSARecv failed - %d error %ld\n", iret, GetLastError());
6970 send(src, "test message", sizeof("test message"), 0);
6972 completion_called = 0;
6973 dwret = SleepEx(1000, TRUE);
6974 ok(dwret == WAIT_IO_COMPLETION, "got %lu\n", dwret);
6975 ok(completion_called == 1, "completion not called\n");
6977 dwret = WaitForSingleObject(event, 1);
6978 ok(dwret == WAIT_TIMEOUT, "got %lu\n", dwret);
6980 io_port = CreateIoCompletionPort( (HANDLE)dest, NULL, 0, 0 );
6981 ok(io_port != NULL, "failed to create completion port %lu\n", GetLastError());
6983 /* Using completion function on socket associated with completion port is not allowed. */
6984 memset(&ov, 0, sizeof(ov));
6985 completion_called = 0;
6986 iret = WSARecv(dest, bufs, 1, NULL, &flags, &ov, io_completion);
6987 ok(iret == SOCKET_ERROR && GetLastError() == WSAEINVAL, "WSARecv failed - %d error %ld\n", iret, GetLastError());
6988 ok(!completion_called, "completion called\n");
6990 CloseHandle(io_port);
6992 end:
6993 if (server != INVALID_SOCKET)
6994 closesocket(server);
6995 if (dest != INVALID_SOCKET)
6996 closesocket(dest);
6997 if (src != INVALID_SOCKET)
6998 closesocket(src);
6999 if (event)
7000 WSACloseEvent(event);
7003 struct write_watch_thread_args
7005 int func;
7006 SOCKET dest;
7007 void *base;
7008 DWORD size;
7009 const char *expect;
7012 static DWORD CALLBACK write_watch_thread( void *arg )
7014 struct write_watch_thread_args *args = arg;
7015 struct sockaddr addr;
7016 int addr_len = sizeof(addr), ret;
7017 DWORD bytes, flags = 0;
7018 WSABUF buf[1];
7020 switch (args->func)
7022 case 0:
7023 ret = recv( args->dest, args->base, args->size, 0 );
7024 ok( ret == strlen(args->expect) + 1, "wrong len %d\n", ret );
7025 ok( !strcmp( args->base, args->expect ), "wrong data\n" );
7026 break;
7027 case 1:
7028 ret = recvfrom( args->dest, args->base, args->size, 0, &addr, &addr_len );
7029 ok( ret == strlen(args->expect) + 1, "wrong len %d\n", ret );
7030 ok( !strcmp( args->base, args->expect ), "wrong data\n" );
7031 break;
7032 case 2:
7033 buf[0].len = args->size;
7034 buf[0].buf = args->base;
7035 ret = WSARecv( args->dest, buf, 1, &bytes, &flags, NULL, NULL );
7036 ok( !ret, "WSARecv failed %lu\n", GetLastError() );
7037 ok( bytes == strlen(args->expect) + 1, "wrong len %ld\n", bytes );
7038 ok( !strcmp( args->base, args->expect ), "wrong data\n" );
7039 break;
7040 case 3:
7041 buf[0].len = args->size;
7042 buf[0].buf = args->base;
7043 ret = WSARecvFrom( args->dest, buf, 1, &bytes, &flags, &addr, &addr_len, NULL, NULL );
7044 ok( !ret, "WSARecvFrom failed %lu\n", GetLastError() );
7045 ok( bytes == strlen(args->expect) + 1, "wrong len %ld\n", bytes );
7046 ok( !strcmp( args->base, args->expect ), "wrong data\n" );
7047 break;
7049 return 0;
7052 static void test_write_watch(void)
7054 SOCKET src, dest;
7055 WSABUF bufs[2];
7056 WSAOVERLAPPED ov;
7057 struct write_watch_thread_args args;
7058 DWORD bytesReturned, flags, size;
7059 struct sockaddr addr;
7060 int addr_len, ret;
7061 HANDLE thread, event;
7062 char *base;
7063 void *results[64];
7064 ULONG_PTR count;
7065 ULONG pagesize;
7066 UINT (WINAPI *pGetWriteWatch)(DWORD,LPVOID,SIZE_T,LPVOID*,ULONG_PTR*,ULONG*);
7068 pGetWriteWatch = (void *)GetProcAddress( GetModuleHandleA("kernel32.dll"), "GetWriteWatch" );
7069 if (!pGetWriteWatch)
7071 win_skip( "write watched not supported\n" );
7072 return;
7075 tcp_socketpair(&src, &dest);
7077 memset(&ov, 0, sizeof(ov));
7078 ov.hEvent = event = CreateEventA(NULL, FALSE, FALSE, NULL);
7079 ok(ov.hEvent != NULL, "could not create event object, errno = %ld\n", GetLastError());
7081 flags = 0;
7083 size = 0x10000;
7084 base = VirtualAlloc( 0, size, MEM_RESERVE | MEM_COMMIT | MEM_WRITE_WATCH, PAGE_READWRITE );
7085 ok( base != NULL, "VirtualAlloc failed %lu\n", GetLastError() );
7087 memset( base, 0, size );
7088 count = 64;
7089 ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize );
7090 ok( !ret, "GetWriteWatch failed %lu\n", GetLastError() );
7091 ok( count == 16, "wrong count %Iu\n", count );
7093 bufs[0].len = 5;
7094 bufs[0].buf = base;
7095 bufs[1].len = 0x8000;
7096 bufs[1].buf = base + 0x4000;
7098 ret = WSARecv( dest, bufs, 2, NULL, &flags, &ov, NULL);
7099 ok(ret == SOCKET_ERROR && GetLastError() == ERROR_IO_PENDING,
7100 "WSARecv failed - %d error %ld\n", ret, GetLastError());
7102 count = 64;
7103 ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize );
7104 ok( !ret, "GetWriteWatch failed %lu\n", GetLastError() );
7105 ok( count == 9, "wrong count %Iu\n", count );
7106 ok( !base[0], "data set\n" );
7108 send(src, "test message", sizeof("test message"), 0);
7110 ret = GetOverlappedResult( (HANDLE)dest, &ov, &bytesReturned, TRUE );
7111 ok( ret, "GetOverlappedResult failed %lu\n", GetLastError() );
7112 ok( bytesReturned == sizeof("test message"), "wrong size %lu\n", bytesReturned );
7113 ok( !memcmp( base, "test ", 5 ), "wrong data %s\n", base );
7114 ok( !memcmp( base + 0x4000, "message", 8 ), "wrong data %s\n", base + 0x4000 );
7116 count = 64;
7117 ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize );
7118 ok( !ret, "GetWriteWatch failed %lu\n", GetLastError() );
7119 ok( count == 0, "wrong count %Iu\n", count );
7121 memset( base, 0, size );
7122 count = 64;
7123 ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize );
7124 ok( !ret, "GetWriteWatch failed %lu\n", GetLastError() );
7125 ok( count == 16, "wrong count %Iu\n", count );
7127 bufs[1].len = 0x4000;
7128 bufs[1].buf = base + 0x2000;
7129 ret = WSARecvFrom( dest, bufs, 2, NULL, &flags, &addr, &addr_len, &ov, NULL);
7130 ok(ret == SOCKET_ERROR && GetLastError() == ERROR_IO_PENDING,
7131 "WSARecv failed - %d error %ld\n", ret, GetLastError());
7133 count = 64;
7134 ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize );
7135 ok( !ret, "GetWriteWatch failed %lu\n", GetLastError() );
7136 ok( count == 5, "wrong count %Iu\n", count );
7137 ok( !base[0], "data set\n" );
7139 send(src, "test message", sizeof("test message"), 0);
7141 ret = GetOverlappedResult( (HANDLE)dest, &ov, &bytesReturned, TRUE );
7142 ok( ret, "GetOverlappedResult failed %lu\n", GetLastError() );
7143 ok( bytesReturned == sizeof("test message"), "wrong size %lu\n", bytesReturned );
7144 ok( !memcmp( base, "test ", 5 ), "wrong data %s\n", base );
7145 ok( !memcmp( base + 0x2000, "message", 8 ), "wrong data %s\n", base + 0x2000 );
7147 count = 64;
7148 ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize );
7149 ok( !ret, "GetWriteWatch failed %lu\n", GetLastError() );
7150 ok( count == 0, "wrong count %Iu\n", count );
7152 memset( base, 0, size );
7153 count = 64;
7154 ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize );
7155 ok( !ret, "GetWriteWatch failed %lu\n", GetLastError() );
7156 ok( count == 16, "wrong count %Iu\n", count );
7158 args.dest = dest;
7159 args.base = base;
7160 args.size = 0x7002;
7161 args.expect = "test message";
7162 for (args.func = 0; args.func < 4; args.func++)
7164 thread = CreateThread( NULL, 0, write_watch_thread, &args, 0, NULL );
7165 Sleep( 200 );
7167 count = 64;
7168 ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize );
7169 ok( !ret, "GetWriteWatch failed %lu\n", GetLastError() );
7170 ok( count == 8, "wrong count %Iu\n", count );
7172 send(src, "test message", sizeof("test message"), 0);
7173 WaitForSingleObject( thread, 10000 );
7174 CloseHandle( thread );
7176 count = 64;
7177 ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize );
7178 ok( !ret, "GetWriteWatch failed %lu\n", GetLastError() );
7179 ok( count == 0, "wrong count %Iu\n", count );
7181 WSACloseEvent( event );
7182 closesocket( dest );
7183 closesocket( src );
7184 VirtualFree( base, 0, MEM_FREE );
7187 static void test_WSAPoll(void)
7189 const struct sockaddr_in bind_addr = {.sin_family = AF_INET, .sin_addr.s_addr = htonl(INADDR_LOOPBACK)};
7190 int ret, err, len;
7191 SOCKET listener, server, client;
7192 struct sockaddr_in address;
7193 WSAPOLLFD fds[16];
7194 HANDLE thread_handle;
7195 unsigned int i;
7196 char buffer[6];
7198 static const short invalid_flags[] =
7199 {POLLERR, POLLHUP, POLLNVAL, 0x8, POLLWRBAND, 0x40, 0x80, POLLPRI, 0x800, 0x1000, 0x2000, 0x4000, 0x8000};
7201 if (!pWSAPoll) /* >= Vista */
7203 win_skip("WSAPoll is unsupported, some tests will be skipped.\n");
7204 return;
7207 /* Invalid parameters test */
7208 SetLastError(0xdeadbeef);
7209 ret = pWSAPoll(NULL, 0, 0);
7210 err = GetLastError();
7211 ok(ret == SOCKET_ERROR, "expected -1, got %d\n", ret);
7212 ok(err == WSAEINVAL, "expected 10022, got %d\n", err);
7213 SetLastError(0xdeadbeef);
7214 ret = pWSAPoll(NULL, 1, 0);
7215 err = GetLastError();
7216 ok(ret == SOCKET_ERROR, "expected -1, got %d\n", ret);
7217 ok(err == WSAEFAULT, "expected 10014, got %d\n", err);
7218 SetLastError(0xdeadbeef);
7219 ret = pWSAPoll(NULL, 0, 1);
7220 err = GetLastError();
7221 ok(ret == SOCKET_ERROR, "expected -1, got %d\n", ret);
7222 ok(err == WSAEINVAL, "expected 10022, got %d\n", err);
7223 SetLastError(0xdeadbeef);
7224 ret = pWSAPoll(NULL, 1, 1);
7225 err = GetLastError();
7226 ok(ret == SOCKET_ERROR, "expected -1, got %d\n", ret);
7227 ok(err == WSAEFAULT, "expected 10014, got %d\n", err);
7229 memset(&address, 0, sizeof(address));
7230 address.sin_addr.s_addr = inet_addr("127.0.0.1");
7231 address.sin_family = AF_INET;
7232 len = sizeof(address);
7233 listener = setup_server_socket(&address, &len);
7235 for (i = 0; i < ARRAY_SIZE(invalid_flags); ++i)
7237 fds[0].fd = listener;
7238 fds[0].events = invalid_flags[i];
7239 fds[0].revents = 0xdead;
7240 WSASetLastError(0xdeadbeef);
7241 ret = pWSAPoll(fds, 1, 0);
7242 todo_wine ok(ret == -1, "got %d\n", ret);
7243 todo_wine ok(WSAGetLastError() == WSAEINVAL, "got error %u\n", WSAGetLastError());
7246 /* When no events are pending poll returns 0 with no error */
7247 fds[0].fd = listener;
7248 fds[0].events = POLLRDNORM | POLLRDBAND | POLLWRNORM;
7249 fds[0].revents = 0xdead;
7250 ret = pWSAPoll(fds, 1, 0);
7251 ok(ret == 0, "got %d\n", ret);
7252 ok(!fds[0].revents, "got events %#x\n", fds[0].revents);
7254 fds[0].fd = -1;
7255 fds[0].events = POLLERR;
7256 fds[0].revents = 0xdead;
7257 fds[1].fd = listener;
7258 fds[1].events = POLLIN;
7259 fds[1].revents = 0xdead;
7260 WSASetLastError(0xdeadbeef);
7261 ret = pWSAPoll(fds, 2, 0);
7262 ok(!ret, "got %d\n", ret);
7263 ok(!WSAGetLastError(), "got error %u\n", WSAGetLastError());
7264 ok(fds[0].revents == POLLNVAL, "got events %#x\n", fds[0].revents);
7265 ok(!fds[1].revents, "got events %#x\n", fds[1].revents);
7267 fds[0].fd = listener;
7268 fds[0].events = POLLIN;
7269 fds[0].revents = 0xdead;
7270 fds[1].fd = 0xabacab;
7271 fds[1].events = POLLIN;
7272 fds[1].revents = 0xdead;
7273 WSASetLastError(0xdeadbeef);
7274 ret = pWSAPoll(fds, 2, 0);
7275 ok(!ret, "got %d\n", ret);
7276 ok(!WSAGetLastError(), "got error %u\n", WSAGetLastError());
7277 ok(!fds[0].revents, "got events %#x\n", fds[0].revents);
7278 ok(fds[1].revents == POLLNVAL, "got events %#x\n", fds[1].revents);
7280 fds[0].fd = listener;
7281 fds[0].events = POLLIN;
7282 fds[0].revents = 0xdead;
7283 fds[1].fd = 0xabacab;
7284 fds[1].events = POLLERR;
7285 fds[1].revents = 0xdead;
7286 WSASetLastError(0xdeadbeef);
7287 ret = pWSAPoll(fds, 2, 0);
7288 todo_wine ok(ret == -1, "got %d\n", ret);
7289 todo_wine ok(WSAGetLastError() == WSAEINVAL, "got error %u\n", WSAGetLastError());
7290 ok(!fds[0].revents, "got events %#x\n", fds[0].revents);
7291 todo_wine ok(!fds[1].revents, "got events %#x\n", fds[1].revents);
7293 fds[0].fd = -1;
7294 fds[0].events = POLLERR;
7295 fds[0].revents = 0xdead;
7296 fds[1].fd = 0xabacab;
7297 fds[1].events = POLLERR;
7298 fds[1].revents = 0xdead;
7299 WSASetLastError(0xdeadbeef);
7300 ret = pWSAPoll(fds, 2, 0);
7301 ok(ret == -1, "got %d\n", ret);
7302 ok(WSAGetLastError() == WSAENOTSOCK, "got error %u\n", WSAGetLastError());
7303 ok(fds[0].revents == POLLNVAL, "got events %#x\n", fds[0].revents);
7304 ok(fds[1].revents == POLLNVAL, "got events %#x\n", fds[1].revents);
7306 /* Test listening socket connection attempt notifications */
7307 client = setup_connector_socket(&address, len, TRUE);
7309 fds[0].fd = listener;
7310 fds[0].events = POLLIN;
7311 fds[0].revents = 0xdead;
7312 ret = pWSAPoll(fds, 1, 100);
7313 ok(ret == 1, "got %d\n", ret);
7314 ok(fds[0].revents == POLLRDNORM, "got events %#x\n", fds[0].revents);
7316 fds[0].revents = 0xdead;
7317 ret = pWSAPoll(fds, 1, 0);
7318 ok(ret == 1, "got %d\n", ret);
7319 ok(fds[0].revents == POLLRDNORM, "got events %#x\n", fds[0].revents);
7321 fds[0].events = POLLRDBAND | POLLWRNORM;
7322 fds[0].revents = 0xdead;
7323 ret = pWSAPoll(fds, 1, 0);
7324 ok(ret == 0, "got %d\n", ret);
7325 ok(!fds[0].revents, "got events %#x\n", fds[0].revents);
7327 server = accept(listener, NULL, NULL);
7328 ok(server != INVALID_SOCKET, "failed to accept, error %u\n", WSAGetLastError());
7329 set_blocking(client, FALSE);
7330 set_blocking(server, FALSE);
7332 for (i = 0; i < ARRAY_SIZE(invalid_flags); ++i)
7334 fds[0].fd = server;
7335 fds[0].events = invalid_flags[i];
7336 fds[0].revents = 0xdead;
7337 WSASetLastError(0xdeadbeef);
7338 ret = pWSAPoll(fds, 1, 0);
7339 todo_wine ok(ret == -1, "got %d\n", ret);
7340 todo_wine ok(WSAGetLastError() == WSAEINVAL, "got error %u\n", WSAGetLastError());
7343 /* Test flags exposed by connected sockets. */
7345 fds[0].fd = listener;
7346 fds[0].events = POLLRDNORM | POLLRDBAND | POLLWRNORM;
7347 fds[0].revents = 0xdead;
7348 fds[1].fd = server;
7349 fds[1].events = POLLRDNORM | POLLRDBAND | POLLWRNORM;
7350 fds[1].revents = 0xdead;
7351 fds[2].fd = client;
7352 fds[2].events = POLLRDNORM | POLLRDBAND | POLLWRNORM;
7353 fds[2].revents = 0xdead;
7354 ret = pWSAPoll(fds, 3, 0);
7355 ok(ret == 2, "got %d\n", ret);
7356 ok(!fds[0].revents, "got events %#x\n", fds[0].revents);
7357 ok(fds[1].revents == POLLWRNORM, "got events %#x\n", fds[1].revents);
7358 ok(fds[2].revents == POLLWRNORM, "got events %#x\n", fds[2].revents);
7360 /* Test data receiving notifications */
7362 ret = send(server, "1234", 4, 0);
7363 ok(ret == 4, "got %d\n", ret);
7365 check_poll_mask(client, POLLRDNORM | POLLRDBAND, POLLRDNORM);
7366 check_poll(client, POLLRDNORM | POLLWRNORM);
7367 check_poll(server, POLLWRNORM);
7369 ret = sync_recv(client, buffer, sizeof(buffer), 0);
7370 ok(ret == 4, "got %d\n", ret);
7372 check_poll(client, POLLWRNORM);
7373 check_poll(server, POLLWRNORM);
7375 /* Because the kernel asynchronously buffers data, this test is not reliable. */
7377 if (0)
7379 static const int large_buffer_size = 1024 * 1024;
7380 char *large_buffer = malloc(large_buffer_size);
7382 while (send(server, large_buffer, large_buffer_size, 0) == large_buffer_size);
7384 check_poll(client, POLLWRNORM | POLLRDNORM);
7385 check_poll(server, 0);
7387 while (recv(client, large_buffer, large_buffer_size, 0) > 0);
7389 check_poll(client, POLLWRNORM);
7390 check_poll(server, POLLWRNORM);
7392 free(large_buffer);
7395 /* Test OOB data notifications */
7397 ret = send(client, "A", 1, MSG_OOB);
7398 ok(ret == 1, "got %d\n", ret);
7400 check_poll(client, POLLWRNORM);
7401 check_poll_mask(server, POLLRDNORM | POLLRDBAND, POLLRDBAND);
7402 check_poll(server, POLLWRNORM | POLLRDBAND);
7404 buffer[0] = 0xcc;
7405 ret = recv(server, buffer, 1, MSG_OOB);
7406 ok(ret == 1, "got %d\n", ret);
7407 ok(buffer[0] == 'A', "got %#x\n", buffer[0]);
7409 check_poll(client, POLLWRNORM);
7410 check_poll(server, POLLWRNORM);
7412 /* If the socket is OOBINLINED the notification is like normal data */
7414 ret = 1;
7415 ret = setsockopt(server, SOL_SOCKET, SO_OOBINLINE, (char *)&ret, sizeof(ret));
7416 ok(!ret, "got error %u\n", WSAGetLastError());
7417 ret = send(client, "A", 1, MSG_OOB);
7418 ok(ret == 1, "got %d\n", ret);
7420 check_poll(client, POLLWRNORM);
7421 check_poll_mask(server, POLLRDNORM | POLLRDBAND, POLLRDNORM);
7422 check_poll(server, POLLWRNORM | POLLRDNORM);
7424 buffer[0] = 0xcc;
7425 ret = recv(server, buffer, 1, 0);
7426 ok(ret == 1, "got %d\n", ret);
7427 ok(buffer[0] == 'A', "got %#x\n", buffer[0]);
7429 check_poll(client, POLLWRNORM);
7430 check_poll_todo(server, POLLWRNORM);
7432 /* Test shutdown. */
7434 ret = shutdown(client, SD_RECEIVE);
7435 ok(!ret, "got error %u\n", WSAGetLastError());
7437 check_poll(client, POLLWRNORM);
7438 check_poll_todo(server, POLLWRNORM);
7440 ret = shutdown(client, SD_SEND);
7441 ok(!ret, "got error %u\n", WSAGetLastError());
7443 check_poll(client, POLLWRNORM);
7444 check_poll_mask_todo(server, 0, POLLHUP);
7445 check_poll_todo(server, POLLWRNORM | POLLHUP);
7447 closesocket(client);
7448 closesocket(server);
7450 /* Test shutdown via closesocket(). */
7452 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
7453 ret = connect(client, (struct sockaddr *)&address, sizeof(address));
7454 ok(!ret, "got error %u\n", WSAGetLastError());
7455 server = accept(listener, NULL, NULL);
7456 ok(server != -1, "got error %u\n", WSAGetLastError());
7458 closesocket(client);
7460 check_poll_mask(server, 0, POLLHUP);
7461 check_poll(server, POLLWRNORM | POLLHUP);
7463 closesocket(server);
7465 /* Test shutdown with data in the pipe. */
7467 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
7468 ret = connect(client, (struct sockaddr *)&address, sizeof(address));
7469 ok(!ret, "got error %u\n", WSAGetLastError());
7470 server = accept(listener, NULL, NULL);
7471 ok(server != -1, "got error %u\n", WSAGetLastError());
7473 ret = send(client, "data", 5, 0);
7474 ok(ret == 5, "got %d\n", ret);
7476 check_poll(client, POLLWRNORM);
7477 check_poll_mask(server, POLLRDNORM | POLLRDBAND, POLLRDNORM);
7478 check_poll(server, POLLWRNORM | POLLRDNORM);
7480 ret = shutdown(client, SD_SEND);
7482 check_poll(client, POLLWRNORM);
7483 check_poll_mask_todo(server, 0, POLLHUP);
7484 check_poll_todo(server, POLLWRNORM | POLLRDNORM | POLLHUP);
7486 closesocket(client);
7487 closesocket(server);
7489 /* Test closing a socket while selecting on it. */
7491 tcp_socketpair(&client, &server);
7493 thread_handle = CreateThread(NULL, 0, SelectCloseThread, &client, 0, NULL);
7494 fds[0].fd = client;
7495 fds[0].events = POLLRDNORM | POLLRDBAND;
7496 fds[0].revents = 0xdead;
7497 ret = pWSAPoll(fds, 1, 2000);
7498 ok(ret == 1, "got %d\n", ret);
7499 ok(fds[0].revents == POLLNVAL, "got events %#x\n", fds[0].revents);
7500 ret = WaitForSingleObject(thread_handle, 1000);
7501 ok(!ret, "wait failed\n");
7502 CloseHandle(thread_handle);
7504 closesocket(server);
7506 /* Test a failed connection.
7508 * The following WSAPoll() call times out on versions older than w10pro64,
7509 * but even on w10pro64 it takes over 2 seconds for an error to be reported,
7510 * so make the test interactive-only. */
7511 if (winetest_interactive)
7513 const struct sockaddr_in invalid_addr =
7515 .sin_family = AF_INET,
7516 .sin_addr.s_addr = htonl(INADDR_LOOPBACK),
7517 .sin_port = 255,
7519 SOCKET client;
7521 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
7522 set_blocking(client, FALSE);
7524 ret = connect(client, (const struct sockaddr *)&invalid_addr, sizeof(invalid_addr));
7525 ok(ret == -1, "got %d\n", ret);
7526 ok(WSAGetLastError() == WSAEWOULDBLOCK, "got error %u\n", WSAGetLastError());
7528 fds[0].fd = client;
7529 fds[0].events = POLLRDNORM | POLLRDBAND | POLLWRNORM;
7530 fds[0].revents = 0xdead;
7531 ret = pWSAPoll(fds, 1, 10000);
7532 ok(ret == 1, "got %d\n", ret);
7533 todo_wine ok(fds[0].revents == (POLLWRNORM | POLLHUP | POLLERR), "got events %#x\n", fds[0].revents);
7535 len = sizeof(err);
7536 err = 0xdeadbeef;
7537 ret = getsockopt(client, SOL_SOCKET, SO_ERROR, (char *)&err, &len);
7538 ok(!ret, "getsockopt failed with %d\n", WSAGetLastError());
7539 ok(err == WSAECONNREFUSED, "got error %u\n", err);
7541 len = sizeof(err);
7542 err = 0xdeadbeef;
7543 ret = getsockopt(client, SOL_SOCKET, SO_ERROR, (char *)&err, &len);
7544 ok(!ret, "getsockopt failed with %d\n", WSAGetLastError());
7545 ok(err == WSAECONNREFUSED, "got error %u\n", err);
7547 check_poll_todo(client, POLLWRNORM | POLLHUP | POLLERR);
7549 closesocket(client);
7551 /* test polling after a (synchronous) failure */
7553 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
7555 ret = connect(client, (const struct sockaddr *)&invalid_addr, sizeof(invalid_addr));
7556 ok(ret == -1, "got %d\n", ret);
7557 ok(WSAGetLastError() == WSAECONNREFUSED, "got error %u\n", WSAGetLastError());
7559 check_poll_todo(client, POLLWRNORM | POLLHUP | POLLERR);
7561 len = sizeof(err);
7562 err = 0xdeadbeef;
7563 ret = getsockopt(client, SOL_SOCKET, SO_ERROR, (char *)&err, &len);
7564 ok(!ret, "getsockopt failed with %d\n", WSAGetLastError());
7565 todo_wine ok(!err, "got error %u\n", err);
7567 closesocket(client);
7570 closesocket(listener);
7572 /* Test UDP sockets. */
7574 client = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
7575 server = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
7577 check_poll(client, POLLWRNORM);
7578 check_poll(server, POLLWRNORM);
7580 ret = bind(client, (const struct sockaddr *)&bind_addr, sizeof(bind_addr));
7581 ok(!ret, "got error %u\n", WSAGetLastError());
7582 len = sizeof(address);
7583 ret = getsockname(client, (struct sockaddr *)&address, &len);
7584 ok(!ret, "got error %u\n", WSAGetLastError());
7586 check_poll(client, POLLWRNORM);
7587 check_poll(server, POLLWRNORM);
7589 ret = sendto(server, "data", 5, 0, (struct sockaddr *)&address, sizeof(address));
7590 ok(ret == 5, "got %d\n", ret);
7592 check_poll_mask(client, POLLRDNORM | POLLRDBAND, POLLRDNORM);
7593 check_poll(client, POLLWRNORM | POLLRDNORM);
7594 check_poll(server, POLLWRNORM);
7596 closesocket(client);
7597 closesocket(server);
7600 static void test_connect(void)
7602 SOCKET listener = INVALID_SOCKET;
7603 SOCKET acceptor = INVALID_SOCKET;
7604 SOCKET connector = INVALID_SOCKET;
7605 struct sockaddr_in address, conaddress;
7606 int addrlen;
7607 OVERLAPPED overlapped;
7608 LPFN_CONNECTEX pConnectEx;
7609 GUID connectExGuid = WSAID_CONNECTEX;
7610 DWORD bytesReturned;
7611 char buffer[1024];
7612 BOOL bret;
7613 DWORD dwret;
7614 int iret;
7616 memset(&overlapped, 0, sizeof(overlapped));
7618 listener = socket(AF_INET, SOCK_STREAM, 0);
7619 ok(listener != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
7621 connector = socket(AF_INET, SOCK_STREAM, 0);
7622 ok(connector != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
7624 memset(&address, 0, sizeof(address));
7625 address.sin_family = AF_INET;
7626 address.sin_addr.s_addr = inet_addr("127.0.0.1");
7627 iret = bind(listener, (struct sockaddr*)&address, sizeof(address));
7628 ok(!iret, "failed to bind, error %u\n", WSAGetLastError());
7630 addrlen = sizeof(address);
7631 iret = getsockname(listener, (struct sockaddr*)&address, &addrlen);
7632 ok(!iret, "failed to get address, error %u\n", WSAGetLastError());
7634 iret = listen(listener, 1);
7635 ok(!iret, "failed to listen, error %u\n", WSAGetLastError());
7637 iret = set_blocking(listener, TRUE);
7638 ok(!iret, "failed to set nonblocking, error %u\n", WSAGetLastError());
7640 bytesReturned = 0xdeadbeef;
7641 iret = WSAIoctl(connector, SIO_GET_EXTENSION_FUNCTION_POINTER, &connectExGuid, sizeof(connectExGuid),
7642 &pConnectEx, sizeof(pConnectEx), &bytesReturned, NULL, NULL);
7643 ok(!iret, "failed to get ConnectEx, error %u\n", WSAGetLastError());
7645 ok(bytesReturned == sizeof(pConnectEx), "expected sizeof(pConnectEx), got %lu\n", bytesReturned);
7647 WSASetLastError(0xdeadbeef);
7648 iret = connect(listener, (struct sockaddr *)&address, sizeof(address));
7649 ok(iret == -1, "got %d\n", iret);
7650 ok(WSAGetLastError() == WSAEINVAL, "got error %u\n", WSAGetLastError());
7652 WSASetLastError(0xdeadbeef);
7653 overlapped.Internal = 0xdeadbeef;
7654 overlapped.InternalHigh = 0xdeadbeef;
7655 iret = pConnectEx(listener, (struct sockaddr *)&address, sizeof(address), NULL, 0, &bytesReturned, &overlapped);
7656 ok(!iret, "got %d\n", iret);
7657 ok(WSAGetLastError() == WSAEINVAL, "got error %u\n", WSAGetLastError());
7658 ok(overlapped.Internal == STATUS_PENDING, "got status %#lx\n", (NTSTATUS)overlapped.Internal);
7659 todo_wine ok(overlapped.InternalHigh == 0xdeadbeef, "got size %Iu\n", overlapped.InternalHigh);
7661 bret = pConnectEx(INVALID_SOCKET, (struct sockaddr*)&address, addrlen, NULL, 0, &bytesReturned, &overlapped);
7662 ok(bret == FALSE && WSAGetLastError() == WSAENOTSOCK, "ConnectEx on invalid socket "
7663 "returned %d + errno %d\n", bret, WSAGetLastError());
7665 bret = pConnectEx(connector, (struct sockaddr*)&address, addrlen, NULL, 0, &bytesReturned, &overlapped);
7666 ok(bret == FALSE && WSAGetLastError() == WSAEINVAL, "ConnectEx on a unbound socket "
7667 "returned %d + errno %d\n", bret, WSAGetLastError());
7669 /* ConnectEx needs a bound socket */
7670 memset(&conaddress, 0, sizeof(conaddress));
7671 conaddress.sin_family = AF_INET;
7672 conaddress.sin_addr.s_addr = inet_addr("127.0.0.1");
7673 iret = bind(connector, (struct sockaddr*)&conaddress, sizeof(conaddress));
7674 ok(!iret, "failed to bind, error %u\n", WSAGetLastError());
7676 bret = pConnectEx(connector, (struct sockaddr*)&address, addrlen, NULL, 0, &bytesReturned, NULL);
7677 ok(bret == FALSE && WSAGetLastError() == ERROR_INVALID_PARAMETER, "ConnectEx on a NULL overlapped "
7678 "returned %d + errno %d\n", bret, WSAGetLastError());
7680 overlapped.hEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
7682 bret = pConnectEx(connector, (struct sockaddr*)&address, addrlen, NULL, 0, &bytesReturned, &overlapped);
7683 ok(bret == FALSE && WSAGetLastError() == ERROR_IO_PENDING, "ConnectEx failed: "
7684 "returned %d + errno %d\n", bret, WSAGetLastError());
7685 dwret = WaitForSingleObject(overlapped.hEvent, 15000);
7686 ok(dwret == WAIT_OBJECT_0, "Waiting for connect event failed with %ld + errno %ld\n", dwret, GetLastError());
7688 bret = GetOverlappedResult((HANDLE)connector, &overlapped, &bytesReturned, FALSE);
7689 ok(bret, "Connecting failed, error %ld\n", GetLastError());
7690 ok(bytesReturned == 0, "Bytes sent is %ld\n", bytesReturned);
7692 closesocket(connector);
7693 connector = socket(AF_INET, SOCK_STREAM, 0);
7694 ok(connector != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
7695 /* ConnectEx needs a bound socket */
7696 memset(&conaddress, 0, sizeof(conaddress));
7697 conaddress.sin_family = AF_INET;
7698 conaddress.sin_addr.s_addr = inet_addr("127.0.0.1");
7699 iret = bind(connector, (struct sockaddr*)&conaddress, sizeof(conaddress));
7700 ok(!iret, "failed to bind, error %u\n", WSAGetLastError());
7702 acceptor = accept(listener, NULL, NULL);
7703 ok(acceptor != INVALID_SOCKET, "failed to accept socket, error %u\n", WSAGetLastError());
7705 buffer[0] = '1';
7706 buffer[1] = '2';
7707 buffer[2] = '3';
7708 bret = pConnectEx(connector, (struct sockaddr*)&address, addrlen, buffer, 3, &bytesReturned, &overlapped);
7709 memset(buffer, 0, 3);
7710 ok(bret == FALSE && WSAGetLastError() == ERROR_IO_PENDING, "ConnectEx failed: "
7711 "returned %d + errno %d\n", bret, WSAGetLastError());
7712 dwret = WaitForSingleObject(overlapped.hEvent, 15000);
7713 ok(dwret == WAIT_OBJECT_0, "Waiting for connect event failed with %ld + errno %ld\n", dwret, GetLastError());
7715 bret = GetOverlappedResult((HANDLE)connector, &overlapped, &bytesReturned, FALSE);
7716 ok(bret, "Connecting failed, error %ld\n", GetLastError());
7717 ok(bytesReturned == 3, "Bytes sent is %ld\n", bytesReturned);
7719 acceptor = accept(listener, NULL, NULL);
7720 ok(acceptor != INVALID_SOCKET, "could not accept socket error %d\n", WSAGetLastError());
7722 bytesReturned = recv(acceptor, buffer, 3, 0);
7723 buffer[4] = 0;
7724 ok(bytesReturned == 3, "Didn't get all sent data, got only %ld\n", bytesReturned);
7725 ok(buffer[0] == '1' && buffer[1] == '2' && buffer[2] == '3',
7726 "Failed to get the right data, expected '123', got '%s'\n", buffer);
7728 WSASetLastError(0xdeadbeef);
7729 iret = connect(connector, (struct sockaddr *)&address, sizeof(address));
7730 ok(iret == -1, "got %d\n", iret);
7731 todo_wine ok(WSAGetLastError() == WSAEINVAL, "got error %u\n", WSAGetLastError());
7733 WSASetLastError(0xdeadbeef);
7734 iret = connect(acceptor, (struct sockaddr *)&address, sizeof(address));
7735 ok(iret == -1, "got %d\n", iret);
7736 ok(WSAGetLastError() == WSAEISCONN, "got error %u\n", WSAGetLastError());
7738 WSASetLastError(0xdeadbeef);
7739 overlapped.Internal = 0xdeadbeef;
7740 overlapped.InternalHigh = 0xdeadbeef;
7741 bret = pConnectEx(connector, (struct sockaddr *)&address, sizeof(address), NULL, 0, &bytesReturned, &overlapped);
7742 ok(!bret, "got %d\n", bret);
7743 ok(WSAGetLastError() == WSAEISCONN, "got error %u\n", WSAGetLastError());
7744 ok(overlapped.Internal == STATUS_PENDING, "got status %#lx\n", (NTSTATUS)overlapped.Internal);
7745 todo_wine ok(overlapped.InternalHigh == 0xdeadbeef, "got size %Iu\n", overlapped.InternalHigh);
7747 WSASetLastError(0xdeadbeef);
7748 overlapped.Internal = 0xdeadbeef;
7749 overlapped.InternalHigh = 0xdeadbeef;
7750 bret = pConnectEx(acceptor, (struct sockaddr *)&address, sizeof(address), NULL, 0, &bytesReturned, &overlapped);
7751 ok(!bret, "got %d\n", bret);
7752 ok(WSAGetLastError() == WSAEISCONN, "got error %u\n", WSAGetLastError());
7753 ok(overlapped.Internal == STATUS_PENDING, "got status %#lx\n", (NTSTATUS)overlapped.Internal);
7754 todo_wine ok(overlapped.InternalHigh == 0xdeadbeef, "got size %Iu\n", overlapped.InternalHigh);
7756 closesocket(connector);
7757 closesocket(acceptor);
7758 closesocket(listener);
7760 tcp_socketpair(&connector, &acceptor);
7762 WSASetLastError(0xdeadbeef);
7763 iret = connect(connector, (struct sockaddr *)&address, sizeof(address));
7764 ok(iret == -1, "got %d\n", iret);
7765 ok(WSAGetLastError() == WSAEISCONN, "got error %u\n", WSAGetLastError());
7767 WSASetLastError(0xdeadbeef);
7768 iret = connect(acceptor, (struct sockaddr *)&address, sizeof(address));
7769 ok(iret == -1, "got %d\n", iret);
7770 ok(WSAGetLastError() == WSAEISCONN, "got error %u\n", WSAGetLastError());
7772 WSASetLastError(0xdeadbeef);
7773 overlapped.Internal = 0xdeadbeef;
7774 overlapped.InternalHigh = 0xdeadbeef;
7775 bret = pConnectEx(connector, (struct sockaddr *)&address, sizeof(address), NULL, 0, &bytesReturned, &overlapped);
7776 ok(!bret, "got %d\n", bret);
7777 ok(WSAGetLastError() == WSAEISCONN, "got error %u\n", WSAGetLastError());
7778 ok(overlapped.Internal == STATUS_PENDING, "got status %#lx\n", (NTSTATUS)overlapped.Internal);
7779 todo_wine ok(overlapped.InternalHigh == 0xdeadbeef, "got size %Iu\n", overlapped.InternalHigh);
7781 WSASetLastError(0xdeadbeef);
7782 overlapped.Internal = 0xdeadbeef;
7783 overlapped.InternalHigh = 0xdeadbeef;
7784 bret = pConnectEx(acceptor, (struct sockaddr *)&address, sizeof(address), NULL, 0, &bytesReturned, &overlapped);
7785 ok(!bret, "got %d\n", bret);
7786 ok(WSAGetLastError() == WSAEISCONN, "got error %u\n", WSAGetLastError());
7787 ok(overlapped.Internal == STATUS_PENDING, "got status %#lx\n", (NTSTATUS)overlapped.Internal);
7788 todo_wine ok(overlapped.InternalHigh == 0xdeadbeef, "got size %Iu\n", overlapped.InternalHigh);
7790 closesocket(connector);
7791 closesocket(acceptor);
7793 /* Connect with error */
7795 connector = socket(AF_INET, SOCK_STREAM, 0);
7796 ok(connector != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
7797 /* ConnectEx needs a bound socket */
7798 memset(&conaddress, 0, sizeof(conaddress));
7799 conaddress.sin_family = AF_INET;
7800 conaddress.sin_addr.s_addr = inet_addr("127.0.0.1");
7801 iret = bind(connector, (struct sockaddr*)&conaddress, sizeof(conaddress));
7802 ok(!iret, "failed to bind, error %u\n", WSAGetLastError());
7804 address.sin_port = htons(1);
7806 bret = pConnectEx(connector, (struct sockaddr*)&address, addrlen, NULL, 0, &bytesReturned, &overlapped);
7807 ok(bret == FALSE && GetLastError() == ERROR_IO_PENDING, "ConnectEx to bad destination failed: "
7808 "returned %d + errno %ld\n", bret, GetLastError());
7809 dwret = WaitForSingleObject(overlapped.hEvent, 15000);
7810 ok(dwret == WAIT_OBJECT_0, "Waiting for connect event failed with %ld + errno %ld\n", dwret, GetLastError());
7812 bret = GetOverlappedResult((HANDLE)connector, &overlapped, &bytesReturned, FALSE);
7813 ok(bret == FALSE && GetLastError() == ERROR_CONNECTION_REFUSED,
7814 "Connecting to a disconnected host returned error %d - %d\n", bret, WSAGetLastError());
7816 WSACloseEvent(overlapped.hEvent);
7817 closesocket(connector);
7820 static void test_AcceptEx(void)
7822 const struct sockaddr_in bind_addr = {.sin_family = AF_INET, .sin_addr.s_addr = htonl(INADDR_LOOPBACK)};
7823 SOCKET listener, acceptor, acceptor2, connector, connector2;
7824 struct sockaddr_in bindAddress, peerAddress, *readBindAddress, *readRemoteAddress;
7825 int socklen, optlen;
7826 GUID acceptExGuid = WSAID_ACCEPTEX, getAcceptExGuid = WSAID_GETACCEPTEXSOCKADDRS;
7827 GUID connectex_guid = WSAID_CONNECTEX;
7828 LPFN_ACCEPTEX pAcceptEx = NULL;
7829 LPFN_GETACCEPTEXSOCKADDRS pGetAcceptExSockaddrs = NULL;
7830 LPFN_CONNECTEX pConnectEx = NULL;
7831 fd_set fds_accept, fds_send;
7832 static const struct timeval timeout = {1, 0};
7833 DWORD bytesReturned, connect_time;
7834 char buffer[1024], ipbuffer[32];
7835 OVERLAPPED overlapped = {0}, overlapped2 = {0};
7836 int iret, localSize = sizeof(struct sockaddr_in), remoteSize = localSize;
7837 BOOL bret;
7838 DWORD dwret;
7840 overlapped.hEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
7841 overlapped2.hEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
7843 listener = socket(AF_INET, SOCK_STREAM, 0);
7844 ok(listener != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
7846 acceptor = socket(AF_INET, SOCK_STREAM, 0);
7847 ok(acceptor != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
7849 memset(&bindAddress, 0, sizeof(bindAddress));
7850 bindAddress.sin_family = AF_INET;
7851 bindAddress.sin_addr.s_addr = inet_addr("127.0.0.1");
7852 iret = bind(listener, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
7853 ok(!iret, "failed to bind, error %u\n", WSAGetLastError());
7855 socklen = sizeof(bindAddress);
7856 iret = getsockname(listener, (struct sockaddr*)&bindAddress, &socklen);
7857 ok(!iret, "failed to get address, error %u\n", WSAGetLastError());
7859 iret = set_blocking(listener, FALSE);
7860 ok(!iret, "Failed to set nonblocking, error %u\n", WSAGetLastError());
7862 iret = WSAIoctl(listener, SIO_GET_EXTENSION_FUNCTION_POINTER, &acceptExGuid, sizeof(acceptExGuid),
7863 &pAcceptEx, sizeof(pAcceptEx), &bytesReturned, NULL, NULL);
7864 ok(!iret, "Failed to get AcceptEx, error %u\n", WSAGetLastError());
7866 iret = WSAIoctl(listener, SIO_GET_EXTENSION_FUNCTION_POINTER, &getAcceptExGuid, sizeof(getAcceptExGuid),
7867 &pGetAcceptExSockaddrs, sizeof(pGetAcceptExSockaddrs), &bytesReturned, NULL, NULL);
7868 ok(!iret, "Failed to get GetAcceptExSockaddrs, error %u\n", WSAGetLastError());
7870 iret = WSAIoctl(listener, SIO_GET_EXTENSION_FUNCTION_POINTER, &connectex_guid, sizeof(connectex_guid),
7871 &pConnectEx, sizeof(pConnectEx), &bytesReturned, NULL, NULL);
7872 ok(!iret, "Failed to get ConnectEx, error %u\n", WSAGetLastError());
7874 overlapped.Internal = 0xdeadbeef;
7875 bret = pAcceptEx(INVALID_SOCKET, acceptor, buffer, sizeof(buffer) - 2*(sizeof(struct sockaddr_in) + 16),
7876 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
7877 &bytesReturned, &overlapped);
7878 ok(bret == FALSE && WSAGetLastError() == WSAENOTSOCK, "AcceptEx on invalid listening socket "
7879 "returned %d + errno %d\n", bret, WSAGetLastError());
7880 ok(overlapped.Internal == STATUS_PENDING, "got %08lx\n", (ULONG)overlapped.Internal);
7882 overlapped.Internal = 0xdeadbeef;
7883 bret = pAcceptEx(listener, acceptor, buffer, sizeof(buffer) - 2*(sizeof(struct sockaddr_in) + 16),
7884 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
7885 &bytesReturned, &overlapped);
7886 todo_wine
7887 ok(bret == FALSE && WSAGetLastError() == WSAEINVAL, "AcceptEx on a non-listening socket "
7888 "returned %d + errno %d\n", bret, WSAGetLastError());
7889 ok(overlapped.Internal == STATUS_PENDING, "got %08lx\n", (ULONG)overlapped.Internal);
7890 if (!bret && WSAGetLastError() == ERROR_IO_PENDING)
7891 CancelIo((HANDLE)listener);
7893 iret = listen(listener, 5);
7894 ok(!iret, "failed to listen, error %lu\n", GetLastError());
7896 overlapped.Internal = 0xdeadbeef;
7897 bret = pAcceptEx(listener, INVALID_SOCKET, buffer, sizeof(buffer) - 2*(sizeof(struct sockaddr_in) + 16),
7898 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
7899 &bytesReturned, &overlapped);
7900 ok(bret == FALSE && WSAGetLastError() == WSAENOTSOCK, "AcceptEx on invalid accepting socket "
7901 "returned %d + errno %d\n", bret, WSAGetLastError());
7902 ok(overlapped.Internal == STATUS_PENDING, "got %08lx\n", (ULONG)overlapped.Internal);
7904 overlapped.Internal = 0xdeadbeef;
7905 bret = pAcceptEx(listener, acceptor, NULL, sizeof(buffer) - 2*(sizeof(struct sockaddr_in) + 16),
7906 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
7907 &bytesReturned, &overlapped);
7908 todo_wine ok(bret == FALSE && WSAGetLastError() == WSAEFAULT,
7909 "AcceptEx on NULL buffer returned %d + errno %d\n", bret, WSAGetLastError());
7910 ok(overlapped.Internal == STATUS_PENDING, "got %08lx\n", (ULONG)overlapped.Internal);
7912 overlapped.Internal = 0xdeadbeef;
7913 bret = pAcceptEx(listener, acceptor, buffer, 0, 0, sizeof(struct sockaddr_in) + 16,
7914 &bytesReturned, &overlapped);
7915 ok(bret == FALSE && WSAGetLastError() == ERROR_IO_PENDING,
7916 "AcceptEx on too small local address size returned %d + errno %d\n",
7917 bret, WSAGetLastError());
7918 ok(overlapped.Internal == STATUS_PENDING, "got %08lx\n", (ULONG)overlapped.Internal);
7920 connector = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
7921 ok(connector != -1, "failed to create socket, error %u\n", WSAGetLastError());
7922 iret = connect(connector, (struct sockaddr *)&bindAddress, sizeof(bindAddress));
7923 ok(!iret, "failed to connect, error %u\n", WSAGetLastError());
7924 iret = getsockname(connector, (struct sockaddr *)&peerAddress, &remoteSize);
7925 ok(!iret, "getsockname failed, error %u\n", WSAGetLastError());
7927 dwret = WaitForSingleObject(overlapped.hEvent, 1000);
7928 ok(!dwret, "wait failed\n");
7929 bret = GetOverlappedResult((HANDLE)listener, &overlapped, &bytesReturned, FALSE);
7930 ok(bret, "got error %lu\n", GetLastError());
7931 ok(!(NTSTATUS)overlapped.Internal, "got %#Ix\n", overlapped.Internal);
7932 ok(!bytesReturned, "got size %lu\n", bytesReturned);
7934 readBindAddress = readRemoteAddress = (struct sockaddr_in *)0xdeadbeef;
7935 localSize = remoteSize = 0xdeadbeef;
7936 pGetAcceptExSockaddrs(buffer, 0, 0, sizeof(struct sockaddr_in) + 16,
7937 (struct sockaddr **)&readBindAddress, &localSize, (struct sockaddr **)&readRemoteAddress, &remoteSize);
7938 todo_wine ok(readBindAddress == (struct sockaddr_in *)0xdeadbeef, "got local addr %p\n", readBindAddress);
7939 ok(!memcmp(readRemoteAddress, &peerAddress, sizeof(peerAddress)), "remote addr didn't match\n");
7940 todo_wine ok(localSize == 0xdeadbeef, "got local size %u\n", localSize);
7941 ok(remoteSize == sizeof(struct sockaddr_in), "got remote size %u\n", remoteSize);
7943 closesocket(connector);
7944 closesocket(acceptor);
7946 /* A UDP socket cannot be accepted into. */
7948 acceptor = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
7950 overlapped.Internal = 0xdeadbeef;
7951 bret = pAcceptEx(listener, acceptor, buffer, 0, 0, sizeof(struct sockaddr_in) + 16, &bytesReturned, &overlapped);
7952 ok(!bret, "expected failure\n");
7953 todo_wine ok(WSAGetLastError() == WSAEINVAL, "got error %u\n", WSAGetLastError());
7954 ok(overlapped.Internal == STATUS_PENDING, "got status %#lx\n", (NTSTATUS)overlapped.Internal);
7955 if (WSAGetLastError() == ERROR_IO_PENDING)
7956 CancelIo((HANDLE)listener);
7958 closesocket(acceptor);
7960 /* A bound socket cannot be accepted into. */
7962 acceptor = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
7963 iret = bind(acceptor, (const struct sockaddr *)&bind_addr, sizeof(bind_addr));
7964 ok(!iret, "got error %u\n", WSAGetLastError());
7966 overlapped.Internal = 0xdeadbeef;
7967 bret = pAcceptEx(listener, acceptor, buffer, 0, 0, sizeof(struct sockaddr_in) + 16, &bytesReturned, &overlapped);
7968 ok(!bret, "expected failure\n");
7969 todo_wine ok(WSAGetLastError() == WSAEINVAL, "got error %u\n", WSAGetLastError());
7970 ok(overlapped.Internal == STATUS_PENDING, "got status %#lx\n", (NTSTATUS)overlapped.Internal);
7971 if (WSAGetLastError() == ERROR_IO_PENDING)
7972 CancelIo((HANDLE)listener);
7974 closesocket(acceptor);
7976 /* A connected socket cannot be accepted into. */
7978 tcp_socketpair(&acceptor, &acceptor2);
7980 overlapped.Internal = 0xdeadbeef;
7981 bret = pAcceptEx(listener, acceptor, buffer, 0, 0, sizeof(struct sockaddr_in) + 16, &bytesReturned, &overlapped);
7982 ok(!bret, "expected failure\n");
7983 todo_wine ok(WSAGetLastError() == WSAEINVAL, "got error %u\n", WSAGetLastError());
7984 ok(overlapped.Internal == STATUS_PENDING, "got status %#lx\n", (NTSTATUS)overlapped.Internal);
7985 if (WSAGetLastError() == ERROR_IO_PENDING)
7986 CancelIo((HANDLE)listener);
7988 overlapped.Internal = 0xdeadbeef;
7989 bret = pAcceptEx(listener, acceptor2, buffer, 0, 0, sizeof(struct sockaddr_in) + 16, &bytesReturned, &overlapped);
7990 ok(!bret, "expected failure\n");
7991 todo_wine ok(WSAGetLastError() == WSAEINVAL, "got error %u\n", WSAGetLastError());
7992 ok(overlapped.Internal == STATUS_PENDING, "got status %#lx\n", (NTSTATUS)overlapped.Internal);
7993 if (WSAGetLastError() == ERROR_IO_PENDING)
7994 CancelIo((HANDLE)listener);
7996 closesocket(acceptor);
7997 closesocket(acceptor2);
7999 /* Pass an insufficient local address size. */
8001 acceptor = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
8002 ok(acceptor != -1, "failed to create socket, error %u\n", WSAGetLastError());
8004 overlapped.Internal = 0xdeadbeef;
8005 bret = pAcceptEx(listener, acceptor, buffer, 0, 3,
8006 sizeof(struct sockaddr_in) + 16, &bytesReturned, &overlapped);
8007 ok(!bret && WSAGetLastError() == ERROR_IO_PENDING, "got %d, error %u\n", bret, WSAGetLastError());
8008 ok((NTSTATUS)overlapped.Internal == STATUS_PENDING, "got %#Ix\n", overlapped.Internal);
8010 connector = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
8011 ok(connector != -1, "failed to create socket, error %u\n", WSAGetLastError());
8012 iret = connect(connector, (struct sockaddr *)&bindAddress, sizeof(bindAddress));
8013 ok(!iret, "failed to connect, error %u\n", WSAGetLastError());
8015 dwret = WaitForSingleObject(overlapped.hEvent, 1000);
8016 ok(!dwret, "wait failed\n");
8017 bytesReturned = 0xdeadbeef;
8018 SetLastError(0xdeadbeef);
8019 bret = GetOverlappedResult((HANDLE)listener, &overlapped, &bytesReturned, FALSE);
8020 ok(!bret, "expected failure\n");
8021 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got error %lu\n", GetLastError());
8022 ok((NTSTATUS)overlapped.Internal == STATUS_BUFFER_TOO_SMALL, "got %#Ix\n", overlapped.Internal);
8023 ok(!bytesReturned, "got size %lu\n", bytesReturned);
8025 closesocket(acceptor);
8027 /* The above connection request is not accepted. */
8028 acceptor = accept(listener, NULL, NULL);
8029 todo_wine ok(acceptor != INVALID_SOCKET, "failed to accept, error %u\n", WSAGetLastError());
8030 closesocket(acceptor);
8032 closesocket(connector);
8034 acceptor = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
8035 ok(acceptor != -1, "failed to create socket, error %u\n", WSAGetLastError());
8037 overlapped.Internal = 0xdeadbeef;
8038 bret = pAcceptEx(listener, acceptor, buffer, 0, sizeof(struct sockaddr_in) + 4,
8039 sizeof(struct sockaddr_in) + 16, &bytesReturned, &overlapped);
8040 ok(!bret && WSAGetLastError() == ERROR_IO_PENDING, "got %d, error %u\n", bret, WSAGetLastError());
8041 ok((NTSTATUS)overlapped.Internal == STATUS_PENDING, "got %#Ix\n", overlapped.Internal);
8043 connector = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
8044 ok(connector != -1, "failed to create socket, error %u\n", WSAGetLastError());
8045 iret = connect(connector, (struct sockaddr *)&bindAddress, sizeof(bindAddress));
8046 ok(!iret, "failed to connect, error %u\n", WSAGetLastError());
8048 dwret = WaitForSingleObject(overlapped.hEvent, 1000);
8049 ok(!dwret, "wait failed\n");
8050 bytesReturned = 0xdeadbeef;
8051 SetLastError(0xdeadbeef);
8052 bret = GetOverlappedResult((HANDLE)listener, &overlapped, &bytesReturned, FALSE);
8053 todo_wine ok(!bret, "expected failure\n");
8054 todo_wine ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got error %lu\n", GetLastError());
8055 todo_wine ok((NTSTATUS)overlapped.Internal == STATUS_BUFFER_TOO_SMALL, "got %#Ix\n", overlapped.Internal);
8056 ok(!bytesReturned, "got size %lu\n", bytesReturned);
8058 closesocket(acceptor);
8060 /* The above connection request is not accepted. */
8061 acceptor = accept(listener, NULL, NULL);
8062 todo_wine ok(acceptor != INVALID_SOCKET, "failed to accept, error %u\n", WSAGetLastError());
8063 closesocket(acceptor);
8065 closesocket(connector);
8067 acceptor = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
8068 ok(acceptor != -1, "failed to create socket, error %u\n", WSAGetLastError());
8070 overlapped.Internal = 0xdeadbeef;
8071 bret = pAcceptEx(listener, acceptor, buffer, 0, sizeof(struct sockaddr_in) + 15,
8072 sizeof(struct sockaddr_in) + 16, &bytesReturned, &overlapped);
8073 ok(bret == FALSE && WSAGetLastError() == ERROR_IO_PENDING, "AcceptEx on too small local address "
8074 "size returned %d + errno %d\n",
8075 bret, WSAGetLastError());
8076 ok(overlapped.Internal == STATUS_PENDING, "got %08lx\n", (ULONG)overlapped.Internal);
8077 bret = CancelIo((HANDLE) listener);
8078 ok(bret, "Failed to cancel pending accept socket\n");
8080 overlapped.Internal = 0xdeadbeef;
8081 bret = pAcceptEx(listener, acceptor, buffer, 0, sizeof(struct sockaddr_in) + 16, 0,
8082 &bytesReturned, &overlapped);
8083 ok(bret == FALSE && WSAGetLastError() == WSAEFAULT,
8084 "AcceptEx on too small remote address size returned %d + errno %d\n", bret, WSAGetLastError());
8085 ok(overlapped.Internal == STATUS_PENDING, "got %08lx\n", (ULONG)overlapped.Internal);
8087 overlapped.Internal = 0xdeadbeef;
8088 bret = pAcceptEx(listener, acceptor, buffer, 0, sizeof(struct sockaddr_in) + 16,
8089 sizeof(struct sockaddr_in) + 15, &bytesReturned, &overlapped);
8090 ok(bret == FALSE && WSAGetLastError() == ERROR_IO_PENDING,
8091 "AcceptEx on too small remote address size returned %d + errno %d\n", bret, WSAGetLastError());
8092 ok(overlapped.Internal == STATUS_PENDING, "got %08lx\n", (ULONG)overlapped.Internal);
8093 bret = CancelIo((HANDLE) listener);
8094 ok(bret, "Failed to cancel pending accept socket\n");
8096 bret = pAcceptEx(listener, acceptor, buffer, 0,
8097 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
8098 &bytesReturned, NULL);
8099 ok(bret == FALSE && WSAGetLastError() == ERROR_INVALID_PARAMETER, "AcceptEx on a NULL overlapped "
8100 "returned %d + errno %d\n", bret, WSAGetLastError());
8102 bret = pAcceptEx(listener, acceptor, buffer, 0, 0, 0, &bytesReturned, NULL);
8103 ok(bret == FALSE && WSAGetLastError() == ERROR_INVALID_PARAMETER, "AcceptEx on a NULL overlapped "
8104 "returned %d + errno %d\n", bret, WSAGetLastError());
8106 overlapped.Internal = 0xdeadbeef;
8107 bret = pAcceptEx(listener, acceptor, buffer, 0,
8108 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
8109 &bytesReturned, &overlapped);
8110 ok(bret == FALSE && WSAGetLastError() == ERROR_IO_PENDING, "AcceptEx returned %d + errno %d\n", bret, WSAGetLastError());
8111 ok(overlapped.Internal == STATUS_PENDING, "got %08lx\n", (ULONG)overlapped.Internal);
8113 /* try to accept into the same socket twice */
8114 overlapped.Internal = 0xdeadbeef;
8115 bret = pAcceptEx(listener, acceptor, buffer, 0,
8116 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
8117 &bytesReturned, &overlapped);
8118 ok(bret == FALSE && WSAGetLastError() == WSAEINVAL,
8119 "AcceptEx on already pending socket returned %d + errno %d\n", bret, WSAGetLastError());
8120 ok(overlapped.Internal == STATUS_PENDING, "got %08lx\n", (ULONG)overlapped.Internal);
8122 /* try to connect a socket that's being accepted into */
8123 iret = connect(acceptor, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
8124 ok(iret == SOCKET_ERROR && WSAGetLastError() == WSAEINVAL,
8125 "connecting to acceptex acceptor succeeded? return %d + errno %d\n", iret, WSAGetLastError());
8127 bret = pConnectEx(acceptor, (struct sockaddr *)&bindAddress, sizeof(bindAddress),
8128 NULL, 0, &bytesReturned, &overlapped2);
8129 ok(!bret, "expected failure\n");
8130 ok(WSAGetLastError() == WSAEINVAL, "got error %u\n", WSAGetLastError());
8132 connector = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
8133 ok(connector != -1, "failed to create socket, error %u\n", WSAGetLastError());
8134 overlapped.Internal = 0xdeadbeef;
8135 iret = connect(connector, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
8136 ok(iret == 0, "connecting to accepting socket failed, error %d\n", WSAGetLastError());
8138 dwret = WaitForSingleObject(overlapped.hEvent, INFINITE);
8139 ok(dwret == WAIT_OBJECT_0, "Waiting for accept event failed with %ld + errno %ld\n", dwret, GetLastError());
8140 ok(overlapped.Internal == STATUS_SUCCESS, "got %08lx\n", (ULONG)overlapped.Internal);
8142 bret = GetOverlappedResult((HANDLE)listener, &overlapped, &bytesReturned, FALSE);
8143 ok(bret, "GetOverlappedResult failed, error %ld\n", GetLastError());
8144 ok(bytesReturned == 0, "bytesReturned isn't supposed to be %ld\n", bytesReturned);
8146 closesocket(connector);
8147 connector = INVALID_SOCKET;
8148 closesocket(acceptor);
8150 /* Test short reads */
8152 acceptor = socket(AF_INET, SOCK_STREAM, 0);
8153 ok(acceptor != INVALID_SOCKET, "failed to create socket, error %lu\n", GetLastError());
8154 connector = socket(AF_INET, SOCK_STREAM, 0);
8155 ok(connector != INVALID_SOCKET, "failed to create socket, error %lu\n", GetLastError());
8156 overlapped.Internal = 0xdeadbeef;
8157 bret = pAcceptEx(listener, acceptor, buffer, 2,
8158 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
8159 &bytesReturned, &overlapped);
8160 ok(bret == FALSE && WSAGetLastError() == ERROR_IO_PENDING, "AcceptEx returned %d + errno %d\n", bret, WSAGetLastError());
8161 ok(overlapped.Internal == STATUS_PENDING, "got %08lx\n", (ULONG)overlapped.Internal);
8163 connect_time = 0xdeadbeef;
8164 optlen = sizeof(connect_time);
8165 iret = getsockopt(connector, SOL_SOCKET, SO_CONNECT_TIME, (char *)&connect_time, &optlen);
8166 ok(!iret, "getsockopt failed %d\n", WSAGetLastError());
8167 ok(connect_time == ~0u, "unexpected connect time %lu\n", connect_time);
8169 /* AcceptEx() still won't complete until we send data */
8170 iret = connect(connector, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
8171 ok(iret == 0, "connecting to accepting socket failed, error %d\n", WSAGetLastError());
8173 connect_time = 0xdeadbeef;
8174 optlen = sizeof(connect_time);
8175 iret = getsockopt(connector, SOL_SOCKET, SO_CONNECT_TIME, (char *)&connect_time, &optlen);
8176 ok(!iret, "getsockopt failed %d\n", WSAGetLastError());
8177 ok(connect_time < 0xdeadbeef, "unexpected connect time %lu\n", connect_time);
8179 dwret = WaitForSingleObject(overlapped.hEvent, 0);
8180 ok(dwret == WAIT_TIMEOUT, "Waiting for accept event timeout failed with %ld + errno %ld\n", dwret, GetLastError());
8181 ok(overlapped.Internal == STATUS_PENDING, "got %08lx\n", (ULONG)overlapped.Internal);
8183 iret = getsockname( connector, (struct sockaddr *)&peerAddress, &remoteSize);
8184 ok( !iret, "getsockname failed.\n");
8186 /* AcceptEx() could complete any time now */
8187 iret = send(connector, buffer, 1, 0);
8188 ok(iret == 1, "could not send 1 byte: send %d errno %d\n", iret, WSAGetLastError());
8190 dwret = WaitForSingleObject(overlapped.hEvent, 1000);
8191 ok(dwret == WAIT_OBJECT_0, "Waiting for accept event failed with %ld + errno %ld\n", dwret, GetLastError());
8192 ok(overlapped.Internal == STATUS_SUCCESS, "got %08lx\n", (ULONG)overlapped.Internal);
8194 /* Check if the buffer from AcceptEx is decoded correctly */
8195 pGetAcceptExSockaddrs(buffer, 2, sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
8196 (struct sockaddr **)&readBindAddress, &localSize,
8197 (struct sockaddr **)&readRemoteAddress, &remoteSize);
8198 strcpy( ipbuffer, inet_ntoa(readBindAddress->sin_addr));
8199 ok( readBindAddress->sin_addr.s_addr == bindAddress.sin_addr.s_addr,
8200 "Local socket address is different %s != %s\n",
8201 ipbuffer, inet_ntoa(bindAddress.sin_addr));
8202 ok( readBindAddress->sin_port == bindAddress.sin_port,
8203 "Local socket port is different: %d != %d\n",
8204 readBindAddress->sin_port, bindAddress.sin_port);
8205 strcpy( ipbuffer, inet_ntoa(readRemoteAddress->sin_addr));
8206 ok( readRemoteAddress->sin_addr.s_addr == peerAddress.sin_addr.s_addr,
8207 "Remote socket address is different %s != %s\n",
8208 ipbuffer, inet_ntoa(peerAddress.sin_addr));
8209 ok( readRemoteAddress->sin_port == peerAddress.sin_port,
8210 "Remote socket port is different: %d != %d\n",
8211 readRemoteAddress->sin_port, peerAddress.sin_port);
8213 bret = GetOverlappedResult((HANDLE)listener, &overlapped, &bytesReturned, FALSE);
8214 ok(bret, "GetOverlappedResult failed, error %ld\n", GetLastError());
8215 ok(bytesReturned == 1, "bytesReturned isn't supposed to be %ld\n", bytesReturned);
8217 closesocket(connector);
8218 connector = INVALID_SOCKET;
8219 closesocket(acceptor);
8221 /* Test CF_DEFER & AcceptEx interaction */
8223 acceptor = socket(AF_INET, SOCK_STREAM, 0);
8224 ok(acceptor != INVALID_SOCKET, "failed to create socket, error %lu\n", GetLastError());
8225 connector = socket(AF_INET, SOCK_STREAM, 0);
8226 ok(connector != INVALID_SOCKET, "failed to create socket, error %lu\n", GetLastError());
8227 connector2 = socket(AF_INET, SOCK_STREAM, 0);
8228 ok(connector2 != INVALID_SOCKET, "failed to create socket, error %lu\n", GetLastError());
8230 iret = set_blocking(connector, FALSE);
8231 ok(!iret, "failed to set nonblocking, error %lu\n", GetLastError());
8232 iret = set_blocking(connector2, FALSE);
8233 ok(!iret, "failed to set nonblocking, error %lu\n", GetLastError());
8235 /* Connect socket #1 */
8236 iret = connect(connector, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
8237 ok(iret == SOCKET_ERROR && WSAGetLastError() == WSAEWOULDBLOCK, "connecting to accepting socket failed, error %d\n", WSAGetLastError());
8239 buffer[0] = '0';
8241 FD_ZERO(&fds_accept);
8242 FD_SET(listener, &fds_accept);
8243 iret = select(0, &fds_accept, NULL, NULL, &timeout);
8244 ok(iret == 1, "wait timed out\n");
8246 acceptor2 = WSAAccept(listener, NULL, NULL, AlwaysDeferConditionFunc, 0);
8247 ok(acceptor2 == INVALID_SOCKET, "expected failure\n");
8248 ok(WSAGetLastError() == WSATRY_AGAIN, "got error %u\n", WSAGetLastError());
8249 bret = pAcceptEx(listener, acceptor, buffer, 0, sizeof(struct sockaddr_in) + 16,
8250 sizeof(struct sockaddr_in) + 16, &bytesReturned, &overlapped);
8251 ok(!bret, "expected failure\n");
8252 ok(WSAGetLastError() == ERROR_IO_PENDING, "got error %u\n", WSAGetLastError());
8254 FD_ZERO(&fds_send);
8255 FD_SET(connector, &fds_send);
8256 iret = select(0, NULL, &fds_send, NULL, &timeout);
8257 ok(iret == 1, "wait timed out\n");
8259 iret = send(connector, "1", 1, 0);
8260 ok(iret == 1, "got ret %d, error %u\n", iret, WSAGetLastError());
8262 iret = connect(connector2, (struct sockaddr *)&bindAddress, sizeof(bindAddress));
8263 ok(iret == SOCKET_ERROR, "expected failure\n");
8264 ok(WSAGetLastError() == WSAEWOULDBLOCK, "got error %u\n", WSAGetLastError());
8266 iret = select(0, &fds_accept, NULL, NULL, &timeout);
8267 ok(iret == 1, "wait timed out\n");
8269 acceptor2 = accept(listener, NULL, NULL);
8270 ok(acceptor2 != INVALID_SOCKET, "failed to accept, error %u\n", WSAGetLastError());
8271 closesocket(acceptor2);
8273 FD_ZERO(&fds_send);
8274 FD_SET(connector2, &fds_send);
8275 iret = select(0, NULL, &fds_send, NULL, &timeout);
8276 ok(iret == 1, "wait timed out\n");
8278 iret = send(connector2, "2", 1, 0);
8279 ok(iret == 1, "got ret %d, error %u\n", iret, WSAGetLastError());
8281 dwret = WaitForSingleObject(overlapped.hEvent, 0);
8282 ok(dwret == WAIT_OBJECT_0, "Waiting for accept event failed with %ld + errno %ld\n", dwret, GetLastError());
8284 bret = GetOverlappedResult((HANDLE)listener, &overlapped, &bytesReturned, FALSE);
8285 ok(bret, "GetOverlappedResult failed, error %ld\n", GetLastError());
8286 ok(bytesReturned == 0, "bytesReturned isn't supposed to be %ld\n", bytesReturned);
8288 set_blocking(acceptor, TRUE);
8289 iret = recv( acceptor, buffer, 2, 0);
8290 ok(iret == 1, "Failed to get data, %d, errno: %d\n", iret, WSAGetLastError());
8291 ok(buffer[0] == '1', "The wrong first client was accepted by acceptex: %c != 1\n", buffer[0]);
8293 closesocket(connector);
8294 closesocket(connector2);
8295 closesocket(acceptor);
8297 /* clean up in case of failures */
8298 while ((acceptor = accept(listener, NULL, NULL)) != INVALID_SOCKET)
8299 closesocket(acceptor);
8301 /* Disconnect during receive? */
8303 acceptor = socket(AF_INET, SOCK_STREAM, 0);
8304 ok(acceptor != INVALID_SOCKET, "failed to create socket, error %lu\n", GetLastError());
8305 connector = socket(AF_INET, SOCK_STREAM, 0);
8306 ok(connector != INVALID_SOCKET, "failed to create socket, error %lu\n", GetLastError());
8307 bret = pAcceptEx(listener, acceptor, buffer, sizeof(buffer) - 2*(sizeof(struct sockaddr_in) + 16),
8308 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
8309 &bytesReturned, &overlapped);
8310 ok(bret == FALSE && WSAGetLastError() == ERROR_IO_PENDING, "AcceptEx returned %d + errno %d\n", bret, WSAGetLastError());
8312 iret = connect(connector, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
8313 ok(iret == 0, "connecting to accepting socket failed, error %d\n", WSAGetLastError());
8315 closesocket(connector);
8316 connector = INVALID_SOCKET;
8318 dwret = WaitForSingleObject(overlapped.hEvent, 1000);
8319 ok(dwret == WAIT_OBJECT_0, "Waiting for accept event failed with %ld + errno %ld\n", dwret, GetLastError());
8321 bytesReturned = 123456;
8322 bret = GetOverlappedResult((HANDLE)listener, &overlapped, &bytesReturned, FALSE);
8323 ok(bret, "GetOverlappedResult failed, error %ld\n", GetLastError());
8324 ok(bytesReturned == 0, "bytesReturned isn't supposed to be %ld\n", bytesReturned);
8326 closesocket(acceptor);
8328 /* Test closing with pending requests */
8330 acceptor = socket(AF_INET, SOCK_STREAM, 0);
8331 ok(acceptor != INVALID_SOCKET, "failed to create socket, error %lu\n", GetLastError());
8332 bret = pAcceptEx(listener, acceptor, buffer, sizeof(buffer) - 2*(sizeof(struct sockaddr_in) + 16),
8333 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
8334 &bytesReturned, &overlapped);
8335 ok(bret == FALSE && WSAGetLastError() == ERROR_IO_PENDING, "AcceptEx returned %d + errno %d\n", bret, WSAGetLastError());
8337 closesocket(acceptor);
8339 dwret = WaitForSingleObject(overlapped.hEvent, 1000);
8340 ok(dwret == WAIT_OBJECT_0,
8341 "Waiting for accept event failed with %ld + errno %ld\n", dwret, GetLastError());
8342 bret = GetOverlappedResult((HANDLE)listener, &overlapped, &bytesReturned, FALSE);
8343 ok(!bret && GetLastError() == ERROR_OPERATION_ABORTED, "GetOverlappedResult failed, error %ld\n", GetLastError());
8345 acceptor = socket(AF_INET, SOCK_STREAM, 0);
8346 ok(acceptor != INVALID_SOCKET, "failed to create socket, error %lu\n", GetLastError());
8347 bret = pAcceptEx(listener, acceptor, buffer, sizeof(buffer) - 2*(sizeof(struct sockaddr_in) + 16),
8348 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
8349 &bytesReturned, &overlapped);
8350 ok(bret == FALSE && WSAGetLastError() == ERROR_IO_PENDING, "AcceptEx returned %d + errno %d\n", bret, WSAGetLastError());
8352 CancelIo((HANDLE) acceptor);
8354 dwret = WaitForSingleObject(overlapped.hEvent, 1000);
8355 ok(dwret == WAIT_TIMEOUT, "Waiting for timeout failed with %ld + errno %ld\n", dwret, GetLastError());
8357 closesocket(acceptor);
8359 acceptor = socket(AF_INET, SOCK_STREAM, 0);
8360 ok(acceptor != INVALID_SOCKET, "failed to create socket, error %lu\n", GetLastError());
8361 bret = pAcceptEx(listener, acceptor, buffer, sizeof(buffer) - 2*(sizeof(struct sockaddr_in) + 16),
8362 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
8363 &bytesReturned, &overlapped);
8364 ok(bret == FALSE && WSAGetLastError() == ERROR_IO_PENDING, "AcceptEx returned %d + errno %d\n", bret, WSAGetLastError());
8366 closesocket(listener);
8368 dwret = WaitForSingleObject(overlapped.hEvent, 1000);
8369 ok(dwret == WAIT_OBJECT_0, "Waiting for accept event failed with %ld + errno %ld\n", dwret, GetLastError());
8371 bret = GetOverlappedResult((HANDLE)listener, &overlapped, &bytesReturned, FALSE);
8372 ok(!bret && GetLastError() == ERROR_OPERATION_ABORTED, "GetOverlappedResult failed, error %ld\n", GetLastError());
8374 CloseHandle(overlapped.hEvent);
8375 CloseHandle(overlapped2.hEvent);
8376 closesocket(acceptor);
8377 closesocket(connector2);
8380 static void test_shutdown(void)
8382 struct sockaddr_in addr, server_addr, client_addr;
8383 SOCKET listener, client, server;
8384 OVERLAPPED overlapped = {0};
8385 DWORD size, flags = 0;
8386 int ret, addrlen;
8387 char buffer[5];
8388 WSABUF wsabuf;
8390 overlapped.hEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
8391 listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
8392 ok(listener != INVALID_SOCKET, "failed to create listener socket, error %d\n", WSAGetLastError());
8394 memset(&addr, 0, sizeof(addr));
8395 addr.sin_family = AF_INET;
8396 addr.sin_addr.s_addr = inet_addr("127.0.0.1");
8397 ret = bind(listener, (struct sockaddr *)&addr, sizeof(addr));
8398 ok(!ret, "failed to bind, error %u\n", WSAGetLastError());
8399 addrlen = sizeof(server_addr);
8400 ret = getsockname(listener, (struct sockaddr *)&server_addr, &addrlen);
8401 ok(!ret, "failed to get address, error %u\n", WSAGetLastError());
8403 ret = listen(listener, 1);
8404 ok(!ret, "failed to listen, error %u\n", WSAGetLastError());
8406 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
8407 ok(client != -1, "failed to create socket, error %u\n", WSAGetLastError());
8409 WSASetLastError(0xdeadbeef);
8410 ret = shutdown(client, SD_SEND);
8411 ok(ret == -1, "expected failure\n");
8412 ok(WSAGetLastError() == WSAENOTCONN, "got error %u\n", WSAGetLastError());
8414 WSASetLastError(0xdeadbeef);
8415 ret = shutdown(client, SD_RECEIVE);
8416 ok(ret == -1, "expected failure\n");
8417 ok(WSAGetLastError() == WSAENOTCONN, "got error %u\n", WSAGetLastError());
8419 ret = connect(client, (struct sockaddr *)&server_addr, sizeof(server_addr));
8420 ok(!ret, "failed to connect, error %u\n", WSAGetLastError());
8421 server = accept(listener, NULL, NULL);
8422 ok(server != -1, "failed to accept, error %u\n", WSAGetLastError());
8423 set_blocking(client, FALSE);
8425 WSASetLastError(0xdeadbeef);
8426 ret = shutdown(client, SD_SEND);
8427 ok(!ret, "expected success\n");
8428 ok(!WSAGetLastError() || WSAGetLastError() == 0xdeadbeef /* < 7 */, "got error %u\n", WSAGetLastError());
8430 WSASetLastError(0xdeadbeef);
8431 ret = shutdown(client, SD_SEND);
8432 ok(!ret, "expected success\n");
8433 ok(!WSAGetLastError() || WSAGetLastError() == 0xdeadbeef /* < 7 */, "got error %u\n", WSAGetLastError());
8435 WSASetLastError(0xdeadbeef);
8436 ret = send(client, "test", 5, 0);
8437 ok(ret == -1, "got %d\n", ret);
8438 ok(WSAGetLastError() == WSAESHUTDOWN, "got error %u\n", WSAGetLastError());
8440 ret = recv(server, buffer, sizeof(buffer), 0);
8441 ok(!ret, "got %d\n", ret);
8442 ret = recv(server, buffer, sizeof(buffer), 0);
8443 ok(!ret, "got %d\n", ret);
8445 WSASetLastError(0xdeadbeef);
8446 ret = shutdown(server, SD_RECEIVE);
8447 ok(!ret, "expected success\n");
8448 ok(!WSAGetLastError() || WSAGetLastError() == 0xdeadbeef /* < 7 */, "got error %u\n", WSAGetLastError());
8450 WSASetLastError(0xdeadbeef);
8451 ret = recv(server, buffer, sizeof(buffer), 0);
8452 ok(ret == -1, "got %d\n", ret);
8453 ok(WSAGetLastError() == WSAESHUTDOWN, "got error %u\n", WSAGetLastError());
8455 ret = send(server, "test", 5, 0);
8456 ok(ret == 5, "got %d\n", ret);
8458 ret = sync_recv(client, buffer, sizeof(buffer), 0);
8459 ok(ret == 5, "got %d\n", ret);
8460 ok(!strcmp(buffer, "test"), "got %s\n", debugstr_an(buffer, ret));
8462 WSASetLastError(0xdeadbeef);
8463 ret = shutdown(client, SD_RECEIVE);
8464 ok(!ret, "expected success\n");
8465 ok(!WSAGetLastError() || WSAGetLastError() == 0xdeadbeef /* < 7 */, "got error %u\n", WSAGetLastError());
8467 WSASetLastError(0xdeadbeef);
8468 ret = recv(client, buffer, sizeof(buffer), 0);
8469 ok(ret == -1, "got %d\n", ret);
8470 ok(WSAGetLastError() == WSAESHUTDOWN, "got error %u\n", WSAGetLastError());
8472 WSASetLastError(0xdeadbeef);
8473 ret = recv(client, buffer, sizeof(buffer), 0);
8474 ok(ret == -1, "got %d\n", ret);
8475 ok(WSAGetLastError() == WSAESHUTDOWN, "got error %u\n", WSAGetLastError());
8477 WSASetLastError(0xdeadbeef);
8478 ret = shutdown(server, SD_SEND);
8479 ok(!ret, "expected success\n");
8480 ok(!WSAGetLastError() || WSAGetLastError() == 0xdeadbeef /* < 7 */, "got error %u\n", WSAGetLastError());
8482 WSASetLastError(0xdeadbeef);
8483 ret = send(server, "test", 5, 0);
8484 ok(ret == -1, "got %d\n", ret);
8485 ok(WSAGetLastError() == WSAESHUTDOWN, "got error %u\n", WSAGetLastError());
8487 addrlen = sizeof(addr);
8488 ret = getpeername(client, (struct sockaddr *)&addr, &addrlen);
8489 todo_wine ok(!ret, "got error %u\n", WSAGetLastError());
8490 todo_wine ok(!memcmp(&addr, &server_addr, sizeof(server_addr)), "address didn't match\n");
8492 addrlen = sizeof(client_addr);
8493 ret = getsockname(client, (struct sockaddr *)&client_addr, &addrlen);
8494 ok(!ret, "got error %u\n", WSAGetLastError());
8495 addrlen = sizeof(addr);
8496 ret = getpeername(server, (struct sockaddr *)&addr, &addrlen);
8497 todo_wine ok(!ret, "got error %u\n", WSAGetLastError());
8498 todo_wine ok(!memcmp(&addr, &client_addr, sizeof(addr)), "address didn't match\n");
8500 WSASetLastError(0xdeadbeef);
8501 ret = connect(client, (struct sockaddr *)&server_addr, sizeof(server_addr));
8502 ok(ret == -1, "got %d\n", ret);
8503 ok(WSAGetLastError() == WSAEISCONN, "got error %u\n", WSAGetLastError());
8505 WSASetLastError(0xdeadbeef);
8506 ret = shutdown(client, 0xdeadbeef);
8507 ok(ret == -1, "expected failure\n");
8508 ok(WSAGetLastError() == WSAEINVAL, "got error %u\n", WSAGetLastError());
8510 closesocket(client);
8511 closesocket(server);
8513 /* Test SD_BOTH. */
8515 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
8516 ok(client != -1, "failed to create socket, error %u\n", WSAGetLastError());
8517 ret = connect(client, (struct sockaddr *)&server_addr, sizeof(server_addr));
8518 ok(!ret, "failed to connect, error %u\n", WSAGetLastError());
8519 server = accept(listener, NULL, NULL);
8520 ok(server != -1, "failed to accept, error %u\n", WSAGetLastError());
8522 WSASetLastError(0xdeadbeef);
8523 ret = shutdown(client, SD_BOTH);
8524 ok(!ret, "expected success\n");
8525 ok(!WSAGetLastError() || WSAGetLastError() == 0xdeadbeef /* < 7 */, "got error %u\n", WSAGetLastError());
8527 WSASetLastError(0xdeadbeef);
8528 ret = recv(client, buffer, sizeof(buffer), 0);
8529 ok(ret == -1, "got %d\n", ret);
8530 ok(WSAGetLastError() == WSAESHUTDOWN, "got error %u\n", WSAGetLastError());
8532 WSASetLastError(0xdeadbeef);
8533 ret = send(client, "test", 5, 0);
8534 ok(ret == -1, "got %d\n", ret);
8535 ok(WSAGetLastError() == WSAESHUTDOWN, "got error %u\n", WSAGetLastError());
8537 ret = recv(server, buffer, sizeof(buffer), 0);
8538 ok(!ret, "got %d\n", ret);
8540 WSASetLastError(0xdeadbeef);
8541 ret = shutdown(server, SD_BOTH);
8542 ok(!ret, "expected success\n");
8543 ok(!WSAGetLastError() || WSAGetLastError() == 0xdeadbeef /* < 7 */, "got error %u\n", WSAGetLastError());
8545 WSASetLastError(0xdeadbeef);
8546 ret = recv(server, buffer, sizeof(buffer), 0);
8547 ok(ret == -1, "got %d\n", ret);
8548 ok(WSAGetLastError() == WSAESHUTDOWN, "got error %u\n", WSAGetLastError());
8550 WSASetLastError(0xdeadbeef);
8551 ret = send(server, "test", 5, 0);
8552 ok(ret == -1, "got %d\n", ret);
8553 ok(WSAGetLastError() == WSAESHUTDOWN, "got error %u\n", WSAGetLastError());
8555 addrlen = sizeof(addr);
8556 ret = getpeername(client, (struct sockaddr *)&addr, &addrlen);
8557 todo_wine ok(!ret, "got error %u\n", WSAGetLastError());
8558 todo_wine ok(!memcmp(&addr, &server_addr, sizeof(server_addr)), "address didn't match\n");
8560 addrlen = sizeof(client_addr);
8561 ret = getsockname(client, (struct sockaddr *)&client_addr, &addrlen);
8562 ok(!ret, "got error %u\n", WSAGetLastError());
8563 addrlen = sizeof(addr);
8564 ret = getpeername(server, (struct sockaddr *)&addr, &addrlen);
8565 todo_wine ok(!ret, "got error %u\n", WSAGetLastError());
8566 todo_wine ok(!memcmp(&addr, &client_addr, sizeof(addr)), "address didn't match\n");
8568 closesocket(client);
8569 closesocket(server);
8571 /* Test shutting down with async I/O pending. */
8573 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
8574 ok(client != -1, "failed to create socket, error %u\n", WSAGetLastError());
8575 ret = connect(client, (struct sockaddr *)&server_addr, sizeof(server_addr));
8576 ok(!ret, "failed to connect, error %u\n", WSAGetLastError());
8577 server = accept(listener, NULL, NULL);
8578 ok(server != -1, "failed to accept, error %u\n", WSAGetLastError());
8579 set_blocking(client, FALSE);
8581 wsabuf.buf = buffer;
8582 wsabuf.len = sizeof(buffer);
8583 WSASetLastError(0xdeadbeef);
8584 ret = WSARecv(client, &wsabuf, 1, &size, &flags, &overlapped, NULL);
8585 ok(ret == -1, "got %d\n", ret);
8586 ok(WSAGetLastError() == ERROR_IO_PENDING, "got error %u\n", WSAGetLastError());
8588 ret = shutdown(client, SD_RECEIVE);
8589 ok(!ret, "got error %u\n", WSAGetLastError());
8591 WSASetLastError(0xdeadbeef);
8592 ret = WSARecv(client, &wsabuf, 1, &size, &flags, NULL, NULL);
8593 ok(ret == -1, "got %d\n", ret);
8594 ok(WSAGetLastError() == WSAESHUTDOWN, "got error %u\n", WSAGetLastError());
8596 ret = send(server, "test", 5, 0);
8597 ok(ret == 5, "got %d\n", ret);
8599 ret = WaitForSingleObject(overlapped.hEvent, 1000);
8600 ok(!ret, "wait timed out\n");
8601 size = 0xdeadbeef;
8602 ret = GetOverlappedResult((HANDLE)client, &overlapped, &size, FALSE);
8603 ok(ret, "got error %lu\n", GetLastError());
8604 ok(size == 5, "got size %lu\n", size);
8605 ok(!strcmp(buffer, "test"), "got %s\n", debugstr_an(buffer, size));
8607 WSASetLastError(0xdeadbeef);
8608 ret = WSARecv(client, &wsabuf, 1, &size, &flags, &overlapped, NULL);
8609 ok(ret == -1, "got %d\n", ret);
8610 ok(WSAGetLastError() == WSAESHUTDOWN, "got error %u\n", WSAGetLastError());
8612 WSASetLastError(0xdeadbeef);
8613 ret = WSARecv(server, &wsabuf, 1, &size, &flags, &overlapped, NULL);
8614 ok(ret == -1, "got %d\n", ret);
8615 ok(WSAGetLastError() == ERROR_IO_PENDING, "got error %u\n", WSAGetLastError());
8617 ret = shutdown(client, SD_SEND);
8618 ok(!ret, "got error %u\n", WSAGetLastError());
8620 ret = WaitForSingleObject(overlapped.hEvent, 1000);
8621 ok(!ret, "wait timed out\n");
8622 size = 0xdeadbeef;
8623 ret = GetOverlappedResult((HANDLE)client, &overlapped, &size, FALSE);
8624 ok(ret, "got error %lu\n", GetLastError());
8625 ok(!size, "got size %lu\n", size);
8627 closesocket(client);
8628 closesocket(server);
8630 /* Test shutting down a listening socket. */
8632 WSASetLastError(0xdeadbeef);
8633 ret = shutdown(listener, SD_SEND);
8634 ok(ret == -1, "expected failure\n");
8635 ok(WSAGetLastError() == WSAENOTCONN, "got error %u\n", WSAGetLastError());
8637 WSASetLastError(0xdeadbeef);
8638 ret = shutdown(listener, SD_RECEIVE);
8639 ok(ret == -1, "expected failure\n");
8640 ok(WSAGetLastError() == WSAENOTCONN, "got error %u\n", WSAGetLastError());
8642 closesocket(listener);
8644 /* Test shutting down UDP sockets. */
8646 client = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
8647 server = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
8648 memset(&addr, 0, sizeof(addr));
8649 addr.sin_family = AF_INET;
8650 addr.sin_addr.s_addr = inet_addr("127.0.0.1");
8651 ret = bind(server, (struct sockaddr *)&addr, sizeof(addr));
8652 ok(!ret, "failed to bind, error %u\n", WSAGetLastError());
8653 addrlen = sizeof(server_addr);
8654 ret = getsockname(server, (struct sockaddr *)&server_addr, &addrlen);
8655 ok(!ret, "failed to get address, error %u\n", WSAGetLastError());
8656 set_blocking(server, FALSE);
8658 WSASetLastError(0xdeadbeef);
8659 ret = shutdown(server, SD_RECEIVE);
8660 ok(!ret, "expected success\n");
8661 ok(!WSAGetLastError() || WSAGetLastError() == 0xdeadbeef /* < 7 */, "got error %u\n", WSAGetLastError());
8663 WSASetLastError(0xdeadbeef);
8664 ret = recvfrom(server, buffer, sizeof(buffer), 0, NULL, NULL);
8665 ok(ret == -1, "got %d\n", ret);
8666 ok(WSAGetLastError() == WSAESHUTDOWN, "got error %u\n", WSAGetLastError());
8668 ret = sendto(client, "test", 5, 0, (struct sockaddr *)&server_addr, sizeof(server_addr));
8669 ok(ret == 5, "got %d\n", ret);
8671 WSASetLastError(0xdeadbeef);
8672 ret = shutdown(client, SD_SEND);
8673 ok(!ret, "expected success\n");
8674 ok(!WSAGetLastError() || WSAGetLastError() == 0xdeadbeef /* < 7 */, "got error %u\n", WSAGetLastError());
8676 WSASetLastError(0xdeadbeef);
8677 ret = shutdown(client, SD_SEND);
8678 ok(!ret, "expected success\n");
8679 ok(!WSAGetLastError() || WSAGetLastError() == 0xdeadbeef /* < 7 */, "got error %u\n", WSAGetLastError());
8681 WSASetLastError(0xdeadbeef);
8682 ret = sendto(client, "test", 5, 0, (struct sockaddr *)&server_addr, sizeof(server_addr));
8683 ok(ret == -1, "got %d\n", ret);
8684 ok(WSAGetLastError() == WSAESHUTDOWN, "got error %u\n", WSAGetLastError());
8686 closesocket(client);
8687 closesocket(server);
8689 CloseHandle(overlapped.hEvent);
8692 static void test_DisconnectEx(void)
8694 struct sockaddr_in server_addr, client_addr, addr;
8695 GUID disconnectex_guid = WSAID_DISCONNECTEX;
8696 SOCKET listener, server, client;
8697 LPFN_DISCONNECTEX pDisconnectEx;
8698 OVERLAPPED overlapped = {0};
8699 int addrlen, ret;
8700 char buffer[5];
8701 DWORD size;
8703 overlapped.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
8705 client = socket(AF_INET, SOCK_STREAM, 0);
8706 ok(client != INVALID_SOCKET, "failed to create connector socket, error %u\n", WSAGetLastError());
8708 ret = WSAIoctl(client, SIO_GET_EXTENSION_FUNCTION_POINTER, &disconnectex_guid, sizeof(disconnectex_guid),
8709 &pDisconnectEx, sizeof(pDisconnectEx), &size, NULL, NULL);
8710 if (ret)
8712 win_skip("WSAIoctl failed to get DisconnectEx, error %d\n", WSAGetLastError());
8713 closesocket(client);
8714 return;
8717 listener = socket(AF_INET, SOCK_STREAM, 0);
8718 ok(listener != INVALID_SOCKET, "failed to create listener socket, error %d\n", WSAGetLastError());
8720 memset(&addr, 0, sizeof(addr));
8721 addr.sin_family = AF_INET;
8722 addr.sin_addr.s_addr = inet_addr("127.0.0.1");
8723 ret = bind(listener, (struct sockaddr *)&addr, sizeof(addr));
8724 ok(!ret, "failed to bind, error %u\n", WSAGetLastError());
8725 addrlen = sizeof(server_addr);
8726 ret = getsockname(listener, (struct sockaddr *)&server_addr, &addrlen);
8727 ok(!ret, "failed to get address, error %u\n", WSAGetLastError());
8728 ret = listen(listener, 1);
8729 ok(!ret, "failed to listen, error %u\n", WSAGetLastError());
8731 WSASetLastError(0xdeadbeef);
8732 ret = pDisconnectEx(INVALID_SOCKET, &overlapped, 0, 0);
8733 ok(!ret, "expected failure\n");
8734 ok(WSAGetLastError() == WSAENOTSOCK, "got error %u\n", WSAGetLastError());
8736 WSASetLastError(0xdeadbeef);
8737 ret = pDisconnectEx(client, &overlapped, 0, 0);
8738 ok(!ret, "expected failure\n");
8739 ok(WSAGetLastError() == WSAENOTCONN, "got error %u\n", WSAGetLastError());
8741 ret = connect(client, (struct sockaddr *)&server_addr, sizeof(server_addr));
8742 ok(!ret, "failed to connect, error %u\n", WSAGetLastError());
8743 server = accept(listener, NULL, NULL);
8744 ok(server != INVALID_SOCKET, "failed to accept, error %u\n", WSAGetLastError());
8746 WSASetLastError(0xdeadbeef);
8747 ret = pDisconnectEx(client, &overlapped, 0, 0);
8748 ok(!ret, "expected failure\n");
8749 ok(WSAGetLastError() == ERROR_IO_PENDING, "got error %u\n", WSAGetLastError());
8751 ret = WaitForSingleObject(overlapped.hEvent, 1000);
8752 ok(!ret, "wait timed out\n");
8753 size = 0xdeadbeef;
8754 ret = GetOverlappedResult((HANDLE)client, &overlapped, &size, FALSE);
8755 ok(ret, "got error %lu\n", GetLastError());
8756 ok(!size, "got size %lu\n", size);
8758 ret = connect(client, (struct sockaddr *)&server_addr, sizeof(server_addr));
8759 ok(ret == -1, "expected failure\n");
8760 ok(WSAGetLastError() == WSAEISCONN, "got error %u\n", WSAGetLastError());
8762 WSASetLastError(0xdeadbeef);
8763 ret = send(client, "test", 5, 0);
8764 ok(ret == -1, "expected failure\n");
8765 ok(WSAGetLastError() == WSAESHUTDOWN, "got error %u\n", WSAGetLastError());
8767 ret = recv(server, buffer, sizeof(buffer), 0);
8768 ok(!ret, "got %d\n", ret);
8770 ret = send(server, "test", 5, 0);
8771 ok(ret == 5, "got %d\n", ret);
8773 ret = recv(client, buffer, sizeof(buffer), 0);
8774 ok(ret == 5, "got %d\n", ret);
8775 ok(!strcmp(buffer, "test"), "got %s\n", debugstr_an(buffer, ret));
8777 addrlen = sizeof(addr);
8778 ret = getpeername(client, (struct sockaddr *)&addr, &addrlen);
8779 ok(!ret, "got error %u\n", WSAGetLastError());
8780 ok(!memcmp(&addr, &server_addr, sizeof(server_addr)), "address didn't match\n");
8782 addrlen = sizeof(client_addr);
8783 ret = getsockname(client, (struct sockaddr *)&client_addr, &addrlen);
8784 ok(!ret, "got error %u\n", WSAGetLastError());
8785 addrlen = sizeof(addr);
8786 ret = getpeername(server, (struct sockaddr *)&addr, &addrlen);
8787 ok(!ret, "got error %u\n", WSAGetLastError());
8788 ok(!memcmp(&addr, &client_addr, sizeof(addr)), "address didn't match\n");
8790 closesocket(client);
8791 closesocket(server);
8793 /* Test the synchronous case. */
8795 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
8796 ok(client != -1, "failed to create socket, error %u\n", WSAGetLastError());
8797 ret = connect(client, (struct sockaddr *)&server_addr, sizeof(server_addr));
8798 ok(!ret, "failed to connect, error %u\n", WSAGetLastError());
8799 server = accept(listener, NULL, NULL);
8800 ok(server != -1, "failed to accept, error %u\n", WSAGetLastError());
8802 WSASetLastError(0xdeadbeef);
8803 ret = pDisconnectEx(client, NULL, 0, 0);
8804 ok(ret, "expected success\n");
8805 ok(!WSAGetLastError() || WSAGetLastError() == 0xdeadbeef /* < 7 */, "got error %u\n", WSAGetLastError());
8807 WSASetLastError(0xdeadbeef);
8808 ret = pDisconnectEx(client, NULL, 0, 0);
8809 ok(ret, "expected success\n");
8810 ok(!WSAGetLastError() || WSAGetLastError() == 0xdeadbeef /* < 7 */, "got error %u\n", WSAGetLastError());
8812 ret = connect(client, (struct sockaddr *)&server_addr, sizeof(server_addr));
8813 ok(ret == -1, "expected failure\n");
8814 ok(WSAGetLastError() == WSAEISCONN, "got error %u\n", WSAGetLastError());
8816 WSASetLastError(0xdeadbeef);
8817 ret = send(client, "test", 5, 0);
8818 ok(ret == -1, "expected failure\n");
8819 ok(WSAGetLastError() == WSAESHUTDOWN, "got error %u\n", WSAGetLastError());
8821 ret = recv(server, buffer, sizeof(buffer), 0);
8822 ok(!ret, "got %d\n", ret);
8824 ret = send(server, "test", 5, 0);
8825 ok(ret == 5, "got %d\n", ret);
8827 ret = recv(client, buffer, sizeof(buffer), 0);
8828 ok(ret == 5, "got %d\n", ret);
8829 ok(!strcmp(buffer, "test"), "got %s\n", debugstr_an(buffer, ret));
8831 addrlen = sizeof(addr);
8832 ret = getpeername(client, (struct sockaddr *)&addr, &addrlen);
8833 ok(!ret, "got error %u\n", WSAGetLastError());
8834 ok(!memcmp(&addr, &server_addr, sizeof(server_addr)), "address didn't match\n");
8836 addrlen = sizeof(client_addr);
8837 ret = getsockname(client, (struct sockaddr *)&client_addr, &addrlen);
8838 ok(!ret, "got error %u\n", WSAGetLastError());
8839 addrlen = sizeof(addr);
8840 ret = getpeername(server, (struct sockaddr *)&addr, &addrlen);
8841 ok(!ret, "got error %u\n", WSAGetLastError());
8842 ok(!memcmp(&addr, &client_addr, sizeof(addr)), "address didn't match\n");
8844 closesocket(client);
8845 closesocket(server);
8847 closesocket(listener);
8848 CloseHandle(overlapped.hEvent);
8851 #define compare_file(h,s,o) compare_file2(h,s,o,__FILE__,__LINE__)
8853 static void compare_file2(HANDLE handle, SOCKET sock, int offset, const char *file, int line)
8855 char buf1[256], buf2[256];
8856 BOOL success;
8857 int i = 0;
8859 SetFilePointer(handle, offset, NULL, FILE_BEGIN);
8860 while (1)
8862 DWORD n1 = 0, n2 = 0;
8864 success = ReadFile(handle, buf1, sizeof(buf1), &n1, NULL);
8865 ok_(file,line)(success, "Failed to read from file.\n");
8866 if (success && n1 == 0)
8867 break;
8868 else if(!success)
8869 return;
8870 n2 = recv(sock, buf2, n1, 0);
8871 ok_(file,line)(n1 == n2, "Block %d size mismatch (%ld != %ld)\n", i, n1, n2);
8872 ok_(file,line)(memcmp(buf1, buf2, n2) == 0, "Block %d failed\n", i);
8873 i++;
8877 static void test_TransmitFile(void)
8879 DWORD num_bytes, err, file_size, total_sent;
8880 GUID transmitFileGuid = WSAID_TRANSMITFILE;
8881 LPFN_TRANSMITFILE pTransmitFile = NULL;
8882 HANDLE file = INVALID_HANDLE_VALUE;
8883 char header_msg[] = "hello world";
8884 char footer_msg[] = "goodbye!!!";
8885 char system_ini_path[MAX_PATH];
8886 struct sockaddr_in bindAddress;
8887 TRANSMIT_FILE_BUFFERS buffers;
8888 SOCKET client, server, dest;
8889 WSAOVERLAPPED ov;
8890 char buf[256];
8891 int iret, len;
8892 BOOL bret;
8894 memset( &ov, 0, sizeof(ov) );
8896 /* Setup sockets for testing TransmitFile */
8897 client = socket(AF_INET, SOCK_STREAM, 0);
8898 ok(client != INVALID_SOCKET, "failed to create socket, error %lu\n", GetLastError());
8899 server = socket(AF_INET, SOCK_STREAM, 0);
8900 ok(server != INVALID_SOCKET, "failed to create socket, error %lu\n", GetLastError());
8901 iret = WSAIoctl(client, SIO_GET_EXTENSION_FUNCTION_POINTER, &transmitFileGuid, sizeof(transmitFileGuid),
8902 &pTransmitFile, sizeof(pTransmitFile), &num_bytes, NULL, NULL);
8903 ok(!iret, "failed to get TransmitFile, error %lu\n", GetLastError());
8904 GetSystemWindowsDirectoryA(system_ini_path, MAX_PATH );
8905 strcat(system_ini_path, "\\system.ini");
8906 file = CreateFileA(system_ini_path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_ALWAYS, 0x0, NULL);
8907 ok(file != INVALID_HANDLE_VALUE, "failed to open file, error %lu\n", GetLastError());
8908 file_size = GetFileSize(file, NULL);
8910 /* Test TransmitFile with an invalid socket */
8911 bret = pTransmitFile(INVALID_SOCKET, file, 0, 0, NULL, NULL, 0);
8912 err = WSAGetLastError();
8913 ok(!bret, "TransmitFile succeeded unexpectedly.\n");
8914 ok(err == WSAENOTSOCK, "TransmitFile triggered unexpected errno (%ld != %d)\n", err, WSAENOTSOCK);
8916 /* Test a bogus TransmitFile without a connected socket */
8917 bret = pTransmitFile(client, NULL, 0, 0, NULL, NULL, TF_REUSE_SOCKET);
8918 err = WSAGetLastError();
8919 ok(!bret, "TransmitFile succeeded unexpectedly.\n");
8920 ok(err == WSAENOTCONN, "TransmitFile triggered unexpected errno (%ld != %d)\n", err, WSAENOTCONN);
8922 /* Setup a properly connected socket for transfers */
8923 memset(&bindAddress, 0, sizeof(bindAddress));
8924 bindAddress.sin_family = AF_INET;
8925 bindAddress.sin_port = htons(SERVERPORT+1);
8926 bindAddress.sin_addr.s_addr = inet_addr("127.0.0.1");
8927 iret = bind(server, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
8928 ok(!iret, "failed to bind socket, error %lu\n", GetLastError());
8929 iret = listen(server, 1);
8930 ok(!iret, "failed to listen, error %lu\n", GetLastError());
8931 iret = connect(client, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
8932 ok(!iret, "failed to connect, error %lu\n", GetLastError());
8933 len = sizeof(bindAddress);
8934 dest = accept(server, (struct sockaddr*)&bindAddress, &len);
8935 ok(dest != INVALID_SOCKET, "failed to accept, error %lu\n", GetLastError());
8936 iret = set_blocking(dest, FALSE);
8937 ok(!iret, "failed to set nonblocking, error %lu\n", GetLastError());
8939 /* Test TransmitFile with no possible buffer */
8940 bret = pTransmitFile(client, NULL, 0, 0, NULL, NULL, 0);
8941 ok(bret, "TransmitFile failed unexpectedly.\n");
8942 iret = recv(dest, buf, sizeof(buf), 0);
8943 ok(iret == -1, "Returned an unexpected buffer from TransmitFile (%d != -1).\n", iret);
8945 /* Test TransmitFile with only buffer data */
8946 buffers.Head = &header_msg[0];
8947 buffers.HeadLength = sizeof(header_msg);
8948 buffers.Tail = &footer_msg[0];
8949 buffers.TailLength = sizeof(footer_msg);
8950 bret = pTransmitFile(client, NULL, 0, 0, NULL, &buffers, 0);
8951 ok(bret, "TransmitFile failed unexpectedly.\n");
8952 iret = recv(dest, buf, sizeof(buf), 0);
8953 ok(iret == sizeof(header_msg)+sizeof(footer_msg),
8954 "Returned an unexpected buffer from TransmitFile: %d\n", iret );
8955 ok(memcmp(&buf[0], &header_msg[0], sizeof(header_msg)) == 0,
8956 "TransmitFile header buffer did not match!\n");
8957 ok(memcmp(&buf[sizeof(header_msg)], &footer_msg[0], sizeof(footer_msg)) == 0,
8958 "TransmitFile footer buffer did not match!\n");
8960 /* Test TransmitFile with only file data */
8961 bret = pTransmitFile(client, file, 0, 0, NULL, NULL, 0);
8962 ok(bret, "TransmitFile failed unexpectedly.\n");
8963 compare_file(file, dest, 0);
8965 /* Test TransmitFile with both file and buffer data */
8966 buffers.Head = &header_msg[0];
8967 buffers.HeadLength = sizeof(header_msg);
8968 buffers.Tail = &footer_msg[0];
8969 buffers.TailLength = sizeof(footer_msg);
8970 SetFilePointer(file, 0, NULL, FILE_BEGIN);
8971 bret = pTransmitFile(client, file, 0, 0, NULL, &buffers, 0);
8972 ok(bret, "TransmitFile failed unexpectedly.\n");
8973 iret = recv(dest, buf, sizeof(header_msg), 0);
8974 ok(memcmp(buf, &header_msg[0], sizeof(header_msg)) == 0,
8975 "TransmitFile header buffer did not match!\n");
8976 compare_file(file, dest, 0);
8977 iret = recv(dest, buf, sizeof(footer_msg), 0);
8978 ok(memcmp(buf, &footer_msg[0], sizeof(footer_msg)) == 0,
8979 "TransmitFile footer buffer did not match!\n");
8981 /* Test overlapped TransmitFile */
8982 ov.hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
8983 SetFilePointer(file, 0, NULL, FILE_BEGIN);
8984 bret = pTransmitFile(client, file, 0, 0, &ov, NULL, 0);
8985 err = WSAGetLastError();
8986 ok(!bret, "TransmitFile succeeded unexpectedly.\n");
8987 ok(err == ERROR_IO_PENDING, "TransmitFile triggered unexpected errno (%ld != %d)\n",
8988 err, ERROR_IO_PENDING);
8989 iret = WaitForSingleObject(ov.hEvent, 2000);
8990 ok(iret == WAIT_OBJECT_0, "Overlapped TransmitFile failed.\n");
8991 WSAGetOverlappedResult(client, &ov, &total_sent, FALSE, NULL);
8992 ok(total_sent == file_size,
8993 "Overlapped TransmitFile sent an unexpected number of bytes (%ld != %ld).\n",
8994 total_sent, file_size);
8995 compare_file(file, dest, 0);
8997 /* Test overlapped TransmitFile w/ start offset */
8998 ov.hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
8999 SetFilePointer(file, 0, NULL, FILE_BEGIN);
9000 ov.Offset = 10;
9001 bret = pTransmitFile(client, file, 0, 0, &ov, NULL, 0);
9002 err = WSAGetLastError();
9003 ok(!bret, "TransmitFile succeeded unexpectedly.\n");
9004 ok(err == ERROR_IO_PENDING, "TransmitFile triggered unexpected errno (%ld != %d)\n", err, ERROR_IO_PENDING);
9005 iret = WaitForSingleObject(ov.hEvent, 2000);
9006 ok(iret == WAIT_OBJECT_0, "Overlapped TransmitFile failed.\n");
9007 WSAGetOverlappedResult(client, &ov, &total_sent, FALSE, NULL);
9008 ok(total_sent == (file_size - ov.Offset),
9009 "Overlapped TransmitFile sent an unexpected number of bytes (%ld != %ld).\n",
9010 total_sent, file_size - ov.Offset);
9011 compare_file(file, dest, ov.Offset);
9013 /* Test overlapped TransmitFile w/ file and buffer data */
9014 ov.hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
9015 buffers.Head = &header_msg[0];
9016 buffers.HeadLength = sizeof(header_msg);
9017 buffers.Tail = &footer_msg[0];
9018 buffers.TailLength = sizeof(footer_msg);
9019 SetFilePointer(file, 0, NULL, FILE_BEGIN);
9020 ov.Offset = 0;
9021 bret = pTransmitFile(client, file, 0, 0, &ov, &buffers, 0);
9022 err = WSAGetLastError();
9023 ok(!bret, "TransmitFile succeeded unexpectedly.\n");
9024 ok(err == ERROR_IO_PENDING, "TransmitFile triggered unexpected errno (%ld != %d)\n", err, ERROR_IO_PENDING);
9025 iret = WaitForSingleObject(ov.hEvent, 2000);
9026 ok(iret == WAIT_OBJECT_0, "Overlapped TransmitFile failed.\n");
9027 WSAGetOverlappedResult(client, &ov, &total_sent, FALSE, NULL);
9028 ok(total_sent == (file_size + buffers.HeadLength + buffers.TailLength),
9029 "Overlapped TransmitFile sent an unexpected number of bytes (%ld != %ld).\n",
9030 total_sent, file_size + buffers.HeadLength + buffers.TailLength);
9031 iret = recv(dest, buf, sizeof(header_msg), 0);
9032 ok(memcmp(buf, &header_msg[0], sizeof(header_msg)) == 0,
9033 "TransmitFile header buffer did not match!\n");
9034 compare_file(file, dest, 0);
9035 iret = recv(dest, buf, sizeof(footer_msg), 0);
9036 ok(memcmp(buf, &footer_msg[0], sizeof(footer_msg)) == 0,
9037 "TransmitFile footer buffer did not match!\n");
9039 /* Test TransmitFile with a UDP datagram socket */
9040 closesocket(client);
9041 client = socket(AF_INET, SOCK_DGRAM, 0);
9042 bret = pTransmitFile(client, NULL, 0, 0, NULL, NULL, 0);
9043 err = WSAGetLastError();
9044 ok(!bret, "TransmitFile succeeded unexpectedly.\n");
9045 ok(err == WSAENOTCONN, "TransmitFile triggered unexpected errno (%ld != %d)\n", err, WSAENOTCONN);
9047 CloseHandle(file);
9048 CloseHandle(ov.hEvent);
9049 closesocket(client);
9050 closesocket(server);
9053 static void test_getpeername(void)
9055 SOCKET sock;
9056 struct sockaddr_in sa, sa_out;
9057 SOCKADDR_STORAGE ss;
9058 int sa_len;
9059 const char buf[] = "hello world";
9060 int ret;
9062 /* Test the parameter validation order. */
9063 ret = getpeername(INVALID_SOCKET, NULL, NULL);
9064 ok(ret == SOCKET_ERROR, "Expected getpeername to return SOCKET_ERROR, got %d\n", ret);
9065 ok(WSAGetLastError() == WSAENOTSOCK,
9066 "Expected WSAGetLastError() to return WSAENOTSOCK, got %d\n", WSAGetLastError());
9068 sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
9069 ok(sock != INVALID_SOCKET, "Expected socket to return a valid socket\n");
9071 ret = getpeername(sock, NULL, NULL);
9072 ok(ret == SOCKET_ERROR, "Expected getpeername to return SOCKET_ERROR, got %d\n", ret);
9073 todo_wine ok(WSAGetLastError() == WSAENOTCONN,
9074 "Expected WSAGetLastError() to return WSAENOTCONN, got %d\n", WSAGetLastError());
9076 memset(&sa, 0, sizeof(sa));
9077 sa.sin_family = AF_INET;
9078 sa.sin_port = htons(139);
9079 sa.sin_addr.s_addr = inet_addr("127.0.0.1");
9081 /* sendto does not change a socket's connection state. */
9082 ret = sendto(sock, buf, sizeof(buf), 0, (struct sockaddr*)&sa, sizeof(sa));
9083 ok(ret != SOCKET_ERROR,
9084 "Expected sendto to succeed, WSAGetLastError() = %d\n", WSAGetLastError());
9086 ret = getpeername(sock, NULL, NULL);
9087 ok(ret == SOCKET_ERROR, "Expected getpeername to return SOCKET_ERROR, got %d\n", ret);
9088 todo_wine ok(WSAGetLastError() == WSAENOTCONN,
9089 "Expected WSAGetLastError() to return WSAENOTCONN, got %d\n", WSAGetLastError());
9091 ret = connect(sock, (struct sockaddr*)&sa, sizeof(sa));
9092 ok(ret == 0,
9093 "Expected connect to succeed, WSAGetLastError() = %d\n", WSAGetLastError());
9095 ret = getpeername(sock, NULL, NULL);
9096 ok(ret == SOCKET_ERROR, "Expected getpeername to return SOCKET_ERROR, got %d\n", ret);
9097 ok(WSAGetLastError() == WSAEFAULT,
9098 "Expected WSAGetLastError() to return WSAEFAULT, got %d\n", WSAGetLastError());
9100 /* Test crashes on Wine. */
9101 if (0)
9103 ret = getpeername(sock, (void*)0xdeadbeef, (void*)0xcafebabe);
9104 ok(ret == SOCKET_ERROR, "Expected getpeername to return SOCKET_ERROR, got %d\n", ret);
9105 ok(WSAGetLastError() == WSAEFAULT,
9106 "Expected WSAGetLastError() to return WSAEFAULT, got %d\n", WSAGetLastError());
9109 ret = getpeername(sock, (struct sockaddr*)&sa_out, NULL);
9110 ok(ret == SOCKET_ERROR, "Expected getpeername to return 0, got %d\n", ret);
9111 ok(WSAGetLastError() == WSAEFAULT,
9112 "Expected WSAGetLastError() to return WSAEFAULT, got %d\n", WSAGetLastError());
9114 sa_len = 0;
9115 ret = getpeername(sock, NULL, &sa_len);
9116 ok(ret == SOCKET_ERROR, "Expected getpeername to return 0, got %d\n", ret);
9117 ok(WSAGetLastError() == WSAEFAULT,
9118 "Expected WSAGetLastError() to return WSAEFAULT, got %d\n", WSAGetLastError());
9119 ok(!sa_len, "got %d\n", sa_len);
9121 sa_len = 0;
9122 ret = getpeername(sock, (struct sockaddr *)&ss, &sa_len);
9123 ok(ret == SOCKET_ERROR, "Expected getpeername to return 0, got %d\n", ret);
9124 ok(WSAGetLastError() == WSAEFAULT,
9125 "Expected WSAGetLastError() to return WSAEFAULT, got %d\n", WSAGetLastError());
9126 ok(!sa_len, "got %d\n", sa_len);
9128 sa_len = sizeof(ss);
9129 ret = getpeername(sock, (struct sockaddr *)&ss, &sa_len);
9130 ok(ret == 0, "Expected getpeername to return 0, got %d\n", ret);
9131 ok(!memcmp(&sa, &ss, sizeof(sa)),
9132 "Expected the returned structure to be identical to the connect structure\n");
9133 ok(sa_len == sizeof(sa), "got %d\n", sa_len);
9135 closesocket(sock);
9138 static void test_sioRoutingInterfaceQuery(void)
9140 OVERLAPPED overlapped = {0}, *overlapped_ptr;
9141 struct sockaddr_in in = {0}, out = {0};
9142 ULONG_PTR key;
9143 HANDLE port;
9144 SOCKET sock;
9145 DWORD size;
9146 int ret;
9148 sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
9149 ok(sock != INVALID_SOCKET, "Expected socket to return a valid socket\n");
9150 port = CreateIoCompletionPort((HANDLE)sock, NULL, 123, 0);
9152 WSASetLastError(0xdeadbeef);
9153 ret = WSAIoctl(sock, SIO_ROUTING_INTERFACE_QUERY, &in, sizeof(in), &out, sizeof(out), NULL, NULL, NULL);
9154 ok(ret == -1, "expected failure\n");
9155 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
9157 size = 0xdeadbeef;
9158 ret = WSAIoctl(sock, SIO_ROUTING_INTERFACE_QUERY, &in, sizeof(in) - 1, &out, sizeof(out), &size, NULL, NULL);
9159 ok(ret == -1, "expected failure\n");
9160 todo_wine ok(WSAGetLastError() == WSAEINVAL, "got error %u\n", WSAGetLastError());
9161 ok(size == 0xdeadbeef, "got size %lu\n", size);
9163 size = 0xdeadbeef;
9164 ret = WSAIoctl(sock, SIO_ROUTING_INTERFACE_QUERY, NULL, sizeof(in), &out, sizeof(out), &size, NULL, NULL);
9165 ok(ret == -1, "expected failure\n");
9166 todo_wine ok(WSAGetLastError() == WSAEINVAL, "got error %u\n", WSAGetLastError());
9167 ok(size == 0xdeadbeef, "got size %lu\n", size);
9169 size = 0xdeadbeef;
9170 ret = WSAIoctl(sock, SIO_ROUTING_INTERFACE_QUERY, &in, sizeof(in), &out, sizeof(out), &size, NULL, NULL);
9171 ok(ret == -1, "expected failure\n");
9172 ok(WSAGetLastError() == WSAEAFNOSUPPORT, "got error %u\n", WSAGetLastError());
9173 ok(size == 0xdeadbeef, "got size %lu\n", size);
9175 in.sin_family = AF_INET;
9176 size = 0xdeadbeef;
9177 ret = WSAIoctl(sock, SIO_ROUTING_INTERFACE_QUERY, &in, sizeof(in), &out, sizeof(out), &size, NULL, NULL);
9178 todo_wine ok(ret == -1, "expected failure\n");
9179 todo_wine ok(WSAGetLastError() == WSAEINVAL, "got error %u\n", WSAGetLastError());
9180 todo_wine ok(size == 0xdeadbeef, "got size %lu\n", size);
9182 in.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
9183 WSASetLastError(0xdeadbeef);
9184 size = 0xdeadbeef;
9185 ret = WSAIoctl(sock, SIO_ROUTING_INTERFACE_QUERY, &in, sizeof(in), &out, sizeof(out), &size, NULL, NULL);
9186 ok(!ret, "expected failure\n");
9187 ok(!WSAGetLastError(), "got error %u\n", WSAGetLastError());
9188 ok(size == sizeof(out), "got size %lu\n", size);
9189 /* We expect the source address to be INADDR_LOOPBACK as well, but
9190 * there's no guarantee that a route to the loopback address exists,
9191 * so rather than introduce spurious test failures we do not test the
9192 * source address.
9195 size = 0xdeadbeef;
9196 ret = WSAIoctl(sock, SIO_ROUTING_INTERFACE_QUERY, &in, sizeof(in), &out, sizeof(out) - 1, &size, NULL, NULL);
9197 ok(ret == -1, "expected failure\n");
9198 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
9199 todo_wine ok(size == sizeof(out), "got size %lu\n", size);
9201 size = 0xdeadbeef;
9202 ret = WSAIoctl(sock, SIO_ROUTING_INTERFACE_QUERY, &in, sizeof(in), NULL, sizeof(out), &size, NULL, NULL);
9203 ok(ret == -1, "expected failure\n");
9204 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
9205 ok(size == 0xdeadbeef, "got size %lu\n", size);
9207 ret = WSAIoctl(sock, SIO_ROUTING_INTERFACE_QUERY, &in, sizeof(in), &out, sizeof(out), NULL, &overlapped, NULL);
9208 ok(ret == -1, "expected failure\n");
9209 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
9210 ok(size == 0xdeadbeef, "got size %lu\n", size);
9212 WSASetLastError(0xdeadbeef);
9213 size = 0xdeadbeef;
9214 overlapped.Internal = 0xdeadbeef;
9215 overlapped.InternalHigh = 0xdeadbeef;
9216 ret = WSAIoctl(sock, SIO_ROUTING_INTERFACE_QUERY, &in, sizeof(in), &out, sizeof(out), &size, &overlapped, NULL);
9217 ok(!ret, "expected failure\n");
9218 ok(!WSAGetLastError(), "got error %u\n", WSAGetLastError());
9219 ok(size == sizeof(out), "got size %lu\n", size);
9221 ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 0);
9222 ok(ret, "got error %lu\n", GetLastError());
9223 ok(!size, "got size %lu\n", size);
9224 ok(overlapped_ptr == &overlapped, "got overlapped %p\n", overlapped_ptr);
9225 ok(!overlapped.Internal, "got status %#lx\n", (NTSTATUS)overlapped.Internal);
9226 ok(!overlapped.InternalHigh, "got size %Iu\n", overlapped.InternalHigh);
9228 CloseHandle(port);
9229 closesocket(sock);
9231 sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
9233 ret = WSAIoctl(sock, SIO_ROUTING_INTERFACE_QUERY, &in, sizeof(in),
9234 &out, sizeof(out), NULL, &overlapped, socket_apc);
9235 ok(ret == -1, "expected failure\n");
9236 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
9238 apc_count = 0;
9239 size = 0xdeadbeef;
9240 ret = WSAIoctl(sock, SIO_ROUTING_INTERFACE_QUERY, &in, sizeof(in),
9241 &out, sizeof(out), &size, &overlapped, socket_apc);
9242 ok(!ret, "expected success\n");
9243 ok(size == sizeof(out), "got size %lu\n", size);
9245 ret = SleepEx(0, TRUE);
9246 ok(ret == WAIT_IO_COMPLETION, "got %d\n", ret);
9247 ok(apc_count == 1, "APC was called %u times\n", apc_count);
9248 ok(!apc_error, "got APC error %lu\n", apc_error);
9249 ok(!apc_size, "got APC size %lu\n", apc_size);
9250 ok(apc_overlapped == &overlapped, "got APC overlapped %p\n", apc_overlapped);
9252 closesocket(sock);
9255 static void test_sioAddressListChange(void)
9257 struct sockaddr_in bindAddress;
9258 struct in_addr net_address;
9259 WSAOVERLAPPED overlapped, *olp;
9260 struct hostent *h;
9261 DWORD num_bytes, error, tick;
9262 SOCKET sock, sock2, sock3;
9263 WSAEVENT event2, event3;
9264 HANDLE io_port;
9265 ULONG_PTR key;
9266 int acount;
9267 BOOL bret;
9268 int ret;
9270 /* Use gethostbyname to find the list of local network interfaces */
9271 h = gethostbyname("");
9272 ok(!!h, "failed to get interface list, error %u\n", WSAGetLastError());
9273 for (acount = 0; h->h_addr_list[acount]; acount++);
9274 if (acount == 0)
9276 skip("Cannot test SIO_ADDRESS_LIST_CHANGE, test requires a network card.\n");
9277 return;
9280 net_address.s_addr = *(ULONG *) h->h_addr_list[0];
9282 sock = socket(AF_INET, 0, IPPROTO_TCP);
9283 ok(sock != INVALID_SOCKET, "socket() failed\n");
9285 memset(&bindAddress, 0, sizeof(bindAddress));
9286 bindAddress.sin_family = AF_INET;
9287 bindAddress.sin_addr.s_addr = net_address.s_addr;
9288 SetLastError(0xdeadbeef);
9289 ret = bind(sock, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
9290 ok (!ret, "bind() failed with error %ld\n", GetLastError());
9291 set_blocking(sock, FALSE);
9293 memset(&overlapped, 0, sizeof(overlapped));
9294 overlapped.hEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
9295 SetLastError(0xdeadbeef);
9296 ret = WSAIoctl(sock, SIO_ADDRESS_LIST_CHANGE, NULL, 0, NULL, 0, &num_bytes, &overlapped, NULL);
9297 error = GetLastError();
9298 ok (ret == SOCKET_ERROR, "WSAIoctl(SIO_ADDRESS_LIST_CHANGE) failed with error %ld\n", error);
9299 ok (error == ERROR_IO_PENDING, "expected 0x3e5, got 0x%lx\n", error);
9301 CloseHandle(overlapped.hEvent);
9302 closesocket(sock);
9304 sock = socket(AF_INET, 0, IPPROTO_TCP);
9305 ok(sock != INVALID_SOCKET, "socket() failed\n");
9307 SetLastError(0xdeadbeef);
9308 ret = bind(sock, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
9309 ok (!ret, "bind() failed with error %ld\n", GetLastError());
9310 set_blocking(sock, TRUE);
9312 memset(&overlapped, 0, sizeof(overlapped));
9313 overlapped.hEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
9314 SetLastError(0xdeadbeef);
9315 ret = WSAIoctl(sock, SIO_ADDRESS_LIST_CHANGE, NULL, 0, NULL, 0, &num_bytes, &overlapped, NULL);
9316 error = GetLastError();
9317 ok (ret == SOCKET_ERROR, "WSAIoctl(SIO_ADDRESS_LIST_CHANGE) failed with error %ld\n", error);
9318 ok (error == ERROR_IO_PENDING, "expected 0x3e5, got 0x%lx\n", error);
9320 CloseHandle(overlapped.hEvent);
9321 closesocket(sock);
9323 sock = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
9324 ok(sock != INVALID_SOCKET, "socket() failed\n");
9326 SetLastError(0xdeadbeef);
9327 ret = bind(sock, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
9328 ok (!ret, "bind() failed with error %ld\n", GetLastError());
9329 set_blocking(sock, FALSE);
9331 memset(&overlapped, 0, sizeof(overlapped));
9332 overlapped.hEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
9333 SetLastError(0xdeadbeef);
9334 ret = WSAIoctl(sock, SIO_ADDRESS_LIST_CHANGE, NULL, 0, NULL, 0, &num_bytes, &overlapped, NULL);
9335 error = GetLastError();
9336 ok (ret == SOCKET_ERROR, "WSAIoctl(SIO_ADDRESS_LIST_CHANGE) failed with error %ld\n", error);
9337 ok (error == ERROR_IO_PENDING, "expected 0x3e5, got 0x%lx\n", error);
9339 CloseHandle(overlapped.hEvent);
9340 closesocket(sock);
9342 sock = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
9343 ok(sock != INVALID_SOCKET, "socket() failed\n");
9345 SetLastError(0xdeadbeef);
9346 ret = bind(sock, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
9347 ok (!ret, "bind() failed with error %ld\n", GetLastError());
9348 set_blocking(sock, TRUE);
9350 memset(&overlapped, 0, sizeof(overlapped));
9351 overlapped.hEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
9352 SetLastError(0xdeadbeef);
9353 ret = WSAIoctl(sock, SIO_ADDRESS_LIST_CHANGE, NULL, 0, NULL, 0, &num_bytes, &overlapped, NULL);
9354 error = GetLastError();
9355 ok (ret == SOCKET_ERROR, "WSAIoctl(SIO_ADDRESS_LIST_CHANGE) failed with error %ld\n", error);
9356 ok (error == ERROR_IO_PENDING, "expected 0x3e5, got 0x%lx\n", error);
9358 CloseHandle(overlapped.hEvent);
9359 closesocket(sock);
9361 /* When the socket is overlapped non-blocking and the list change is requested without
9362 * an overlapped structure the error will be different. */
9363 sock = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
9364 ok(sock != INVALID_SOCKET, "socket() failed\n");
9366 SetLastError(0xdeadbeef);
9367 ret = bind(sock, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
9368 ok (!ret, "bind() failed with error %ld\n", GetLastError());
9369 set_blocking(sock, FALSE);
9371 SetLastError(0xdeadbeef);
9372 ret = WSAIoctl(sock, SIO_ADDRESS_LIST_CHANGE, NULL, 0, NULL, 0, &num_bytes, NULL, NULL);
9373 error = GetLastError();
9374 ok (ret == SOCKET_ERROR, "WSAIoctl(SIO_ADDRESS_LIST_CHANGE) failed with error %ld\n", error);
9375 ok (error == WSAEWOULDBLOCK, "expected 10035, got %ld\n", error);
9377 io_port = CreateIoCompletionPort( (HANDLE)sock, NULL, 0, 0 );
9378 ok (io_port != NULL, "failed to create completion port %lu\n", GetLastError());
9380 set_blocking(sock, FALSE);
9381 memset(&overlapped, 0, sizeof(overlapped));
9382 SetLastError(0xdeadbeef);
9383 ret = WSAIoctl(sock, SIO_ADDRESS_LIST_CHANGE, NULL, 0, NULL, 0, &num_bytes, &overlapped, NULL);
9384 error = GetLastError();
9385 ok (ret == SOCKET_ERROR, "WSAIoctl(SIO_ADDRESS_LIST_CHANGE) failed with error %lu\n", error);
9386 ok (error == ERROR_IO_PENDING, "expected ERROR_IO_PENDING got %lu\n", error);
9388 olp = (WSAOVERLAPPED *)0xdeadbeef;
9389 bret = GetQueuedCompletionStatus( io_port, &num_bytes, &key, &olp, 0 );
9390 ok(!bret, "failed to get completion status %u\n", bret);
9391 ok(GetLastError() == WAIT_TIMEOUT, "Last error was %ld\n", GetLastError());
9392 ok(!olp, "Overlapped structure is at %p\n", olp);
9394 closesocket(sock);
9396 olp = (WSAOVERLAPPED *)0xdeadbeef;
9397 bret = GetQueuedCompletionStatus( io_port, &num_bytes, &key, &olp, 0 );
9398 ok(!bret, "failed to get completion status %u\n", bret);
9399 ok(GetLastError() == ERROR_OPERATION_ABORTED, "Last error was %lu\n", GetLastError());
9400 ok(olp == &overlapped, "Overlapped structure is at %p\n", olp);
9402 CloseHandle(io_port);
9404 /* Misuse of the API by using a blocking socket and not using an overlapped structure,
9405 * this leads to a hang forever. */
9406 if (0)
9408 sock = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
9410 SetLastError(0xdeadbeef);
9411 bind(sock, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
9413 set_blocking(sock, TRUE);
9414 WSAIoctl(sock, SIO_ADDRESS_LIST_CHANGE, NULL, 0, NULL, 0, &num_bytes, NULL, NULL);
9415 /* hang */
9417 closesocket(sock);
9420 if (!winetest_interactive)
9422 skip("Cannot test SIO_ADDRESS_LIST_CHANGE, interactive tests must be enabled\n");
9423 return;
9426 /* Bind an overlapped socket to the first found network interface */
9427 sock = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
9428 ok(sock != INVALID_SOCKET, "Expected socket to return a valid socket\n");
9429 sock2 = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
9430 ok(sock2 != INVALID_SOCKET, "Expected socket to return a valid socket\n");
9431 sock3 = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
9432 ok(sock3 != INVALID_SOCKET, "Expected socket to return a valid socket\n");
9434 ret = bind(sock, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
9435 ok(!ret, "bind failed unexpectedly\n");
9436 ret = bind(sock2, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
9437 ok(!ret, "bind failed unexpectedly\n");
9438 ret = bind(sock3, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
9439 ok(!ret, "bind failed unexpectedly\n");
9441 set_blocking(sock2, FALSE);
9442 set_blocking(sock3, FALSE);
9444 /* Wait for address changes, request that the user connects/disconnects an interface */
9445 memset(&overlapped, 0, sizeof(overlapped));
9446 overlapped.hEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
9447 ret = WSAIoctl(sock, SIO_ADDRESS_LIST_CHANGE, NULL, 0, NULL, 0, &num_bytes, &overlapped, NULL);
9448 ok(ret == SOCKET_ERROR, "WSAIoctl succeeded unexpectedly\n");
9449 ok(WSAGetLastError() == WSA_IO_PENDING, "Expected pending last error, got %d\n", WSAGetLastError());
9451 ret = WSAIoctl(sock2, SIO_ADDRESS_LIST_CHANGE, NULL, 0, NULL, 0, &num_bytes, NULL, NULL);
9452 ok(ret == SOCKET_ERROR, "WSAIoctl succeeded unexpectedly\n");
9453 ok(WSAGetLastError() == WSAEWOULDBLOCK, "Expected would block last error, got %d\n", WSAGetLastError());
9455 event2 = WSACreateEvent();
9456 event3 = WSACreateEvent();
9457 ret = WSAEventSelect (sock2, event2, FD_ADDRESS_LIST_CHANGE);
9458 ok(!ret, "WSAEventSelect failed with %d\n", WSAGetLastError());
9459 /* sock3 did not request SIO_ADDRESS_LIST_CHANGE but it is trying to wait anyway */
9460 ret = WSAEventSelect (sock3, event3, FD_ADDRESS_LIST_CHANGE);
9461 ok(!ret, "WSAEventSelect failed with %d\n", WSAGetLastError());
9463 trace("Testing socket-based ipv4 address list change notification. Please connect/disconnect or"
9464 " change the ipv4 address of any of the local network interfaces (15 second timeout).\n");
9465 tick = GetTickCount();
9466 ret = WaitForSingleObject(overlapped.hEvent, 15000);
9467 ok(ret == WAIT_OBJECT_0, "failed to get overlapped event %u\n", ret);
9469 ret = WaitForSingleObject(event2, 500);
9470 todo_wine
9471 ok(ret == WAIT_OBJECT_0, "failed to get change event %u\n", ret);
9473 ret = WaitForSingleObject(event3, 500);
9474 ok(ret == WAIT_TIMEOUT, "unexpected change event\n");
9476 trace("Spent %ld ms waiting.\n", GetTickCount() - tick);
9478 WSACloseEvent(event2);
9479 WSACloseEvent(event3);
9481 closesocket(sock);
9482 closesocket(sock2);
9483 closesocket(sock3);
9487 * Provide consistent initialization for the AcceptEx IOCP tests.
9489 static SOCKET setup_iocp_src(struct sockaddr_in *bindAddress)
9491 SOCKET src;
9492 int iret, socklen;
9494 src = socket(AF_INET, SOCK_STREAM, 0);
9495 ok(src != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
9497 memset(bindAddress, 0, sizeof(*bindAddress));
9498 bindAddress->sin_family = AF_INET;
9499 bindAddress->sin_addr.s_addr = inet_addr("127.0.0.1");
9500 iret = bind(src, (struct sockaddr*)bindAddress, sizeof(*bindAddress));
9501 ok(!iret, "failed to bind, error %u\n", WSAGetLastError());
9503 socklen = sizeof(*bindAddress);
9504 iret = getsockname(src, (struct sockaddr*)bindAddress, &socklen);
9505 ok(!iret, "failed to get address, error %u\n", WSAGetLastError());
9507 iret = set_blocking(src, FALSE);
9508 ok(!iret, "failed to make socket non-blocking, error %u\n", WSAGetLastError());
9510 iret = listen(src, 5);
9511 ok(!iret, "failed to listen, error %u\n", WSAGetLastError());
9513 return src;
9516 static void test_completion_port(void)
9518 HANDLE io_port;
9519 WSAOVERLAPPED ov, *olp;
9520 SOCKET src, dest, dup, connector = INVALID_SOCKET;
9521 WSAPROTOCOL_INFOA info;
9522 char buf[1024];
9523 WSABUF bufs;
9524 DWORD num_bytes, flags;
9525 int iret;
9526 BOOL bret;
9527 ULONG_PTR key;
9528 struct sockaddr_in bindAddress;
9529 GUID acceptExGuid = WSAID_ACCEPTEX;
9530 LPFN_ACCEPTEX pAcceptEx = NULL;
9531 fd_set fds_recv;
9533 memset(buf, 0, sizeof(buf));
9534 io_port = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
9535 ok( io_port != NULL, "Failed to create completion port %lu\n", GetLastError());
9537 memset(&ov, 0, sizeof(ov));
9539 tcp_socketpair(&src, &dest);
9541 bufs.len = sizeof(buf);
9542 bufs.buf = buf;
9543 flags = 0;
9545 io_port = CreateIoCompletionPort( (HANDLE)dest, io_port, 125, 0 );
9546 ok(io_port != NULL, "Failed to create completion port %lu\n", GetLastError());
9548 SetLastError(0xdeadbeef);
9550 iret = WSARecv(dest, &bufs, 1, &num_bytes, &flags, &ov, NULL);
9551 ok(iret == SOCKET_ERROR, "WSARecv returned %d\n", iret);
9552 ok(GetLastError() == ERROR_IO_PENDING, "Last error was %ld\n", GetLastError());
9554 Sleep(100);
9556 close_with_rst(src);
9558 SetLastError(0xdeadbeef);
9559 key = 0xdeadbeef;
9560 num_bytes = 0xdeadbeef;
9561 olp = (WSAOVERLAPPED *)0xdeadbeef;
9563 bret = GetQueuedCompletionStatus(io_port, &num_bytes, &key, &olp, 100);
9564 todo_wine ok(bret == FALSE, "GetQueuedCompletionStatus returned %d\n", bret);
9565 todo_wine ok(GetLastError() == ERROR_NETNAME_DELETED, "Last error was %ld\n", GetLastError());
9566 ok(key == 125, "Key is %Iu\n", key);
9567 ok(num_bytes == 0, "Number of bytes received is %lu\n", num_bytes);
9568 ok(olp == &ov, "Overlapped structure is at %p\n", olp);
9570 SetLastError(0xdeadbeef);
9571 key = 0xdeadbeef;
9572 num_bytes = 0xdeadbeef;
9573 olp = (WSAOVERLAPPED *)0xdeadbeef;
9575 bret = GetQueuedCompletionStatus(io_port, &num_bytes, &key, &olp, 100);
9576 ok(bret == FALSE, "GetQueuedCompletionStatus returned %d\n", bret );
9577 ok(GetLastError() == WAIT_TIMEOUT, "Last error was %ld\n", GetLastError());
9578 ok(key == 0xdeadbeef, "Key is %Iu\n", key);
9579 ok(num_bytes == 0xdeadbeef, "Number of bytes transferred is %lu\n", num_bytes);
9580 ok(!olp, "Overlapped structure is at %p\n", olp);
9582 if (dest != INVALID_SOCKET)
9583 closesocket(dest);
9585 memset(&ov, 0, sizeof(ov));
9587 tcp_socketpair(&src, &dest);
9589 bufs.len = sizeof(buf);
9590 bufs.buf = buf;
9591 flags = 0;
9593 io_port = CreateIoCompletionPort((HANDLE)dest, io_port, 125, 0);
9594 ok(io_port != NULL, "failed to create completion port %lu\n", GetLastError());
9596 set_blocking(dest, FALSE);
9598 close_with_rst(src);
9600 Sleep(100);
9602 num_bytes = 0xdeadbeef;
9603 SetLastError(0xdeadbeef);
9605 iret = WSASend(dest, &bufs, 1, &num_bytes, 0, &ov, NULL);
9606 ok(iret == SOCKET_ERROR, "WSASend failed - %d\n", iret);
9607 ok(GetLastError() == WSAECONNRESET, "Last error was %ld\n", GetLastError());
9608 ok(num_bytes == 0xdeadbeef, "Managed to send %ld\n", num_bytes);
9610 SetLastError(0xdeadbeef);
9611 key = 0xdeadbeef;
9612 num_bytes = 0xdeadbeef;
9613 olp = (WSAOVERLAPPED *)0xdeadbeef;
9615 bret = GetQueuedCompletionStatus( io_port, &num_bytes, &key, &olp, 200 );
9616 ok(bret == FALSE, "GetQueuedCompletionStatus returned %u\n", bret );
9617 ok(GetLastError() == WAIT_TIMEOUT, "Last error was %ld\n", GetLastError());
9618 ok(key == 0xdeadbeef, "Key is %Iu\n", key);
9619 ok(num_bytes == 0xdeadbeef, "Number of bytes transferred is %lu\n", num_bytes);
9620 ok(!olp, "Overlapped structure is at %p\n", olp);
9622 if (dest != INVALID_SOCKET)
9623 closesocket(dest);
9625 /* Test IOCP response on successful immediate read. */
9626 tcp_socketpair(&src, &dest);
9628 bufs.len = sizeof(buf);
9629 bufs.buf = buf;
9630 flags = 0;
9631 SetLastError(0xdeadbeef);
9633 iret = WSASend(src, &bufs, 1, &num_bytes, 0, &ov, NULL);
9634 ok(!iret, "WSASend failed - %d, last error %lu\n", iret, GetLastError());
9635 ok(num_bytes == sizeof(buf), "Managed to send %ld\n", num_bytes);
9637 io_port = CreateIoCompletionPort((HANDLE)dest, io_port, 125, 0);
9638 ok(io_port != NULL, "failed to create completion port %lu\n", GetLastError());
9639 set_blocking(dest, FALSE);
9641 FD_ZERO(&fds_recv);
9642 FD_SET(dest, &fds_recv);
9643 select(dest + 1, &fds_recv, NULL, NULL, NULL);
9645 num_bytes = 0xdeadbeef;
9646 flags = 0;
9648 iret = WSARecv(dest, &bufs, 1, &num_bytes, &flags, &ov, NULL);
9649 ok(!iret, "WSARecv failed - %d, last error %lu\n", iret, GetLastError());
9650 ok(num_bytes == sizeof(buf), "Managed to read %ld\n", num_bytes);
9652 SetLastError(0xdeadbeef);
9653 key = 0xdeadbeef;
9654 num_bytes = 0xdeadbeef;
9655 olp = (WSAOVERLAPPED *)0xdeadbeef;
9657 bret = GetQueuedCompletionStatus( io_port, &num_bytes, &key, &olp, 200 );
9658 ok(bret == TRUE, "failed to get completion status %u\n", bret);
9659 ok(GetLastError() == 0xdeadbeef, "Last error was %ld\n", GetLastError());
9660 ok(key == 125, "Key is %Iu\n", key);
9661 ok(num_bytes == sizeof(buf), "Number of bytes transferred is %lu\n", num_bytes);
9662 ok(olp == &ov, "Overlapped structure is at %p\n", olp);
9664 /* Test IOCP response on graceful shutdown. */
9665 closesocket(src);
9667 FD_ZERO(&fds_recv);
9668 FD_SET(dest, &fds_recv);
9669 select(dest + 1, &fds_recv, NULL, NULL, NULL);
9671 num_bytes = 0xdeadbeef;
9672 flags = 0;
9673 memset(&ov, 0, sizeof(ov));
9675 iret = WSARecv(dest, &bufs, 1, &num_bytes, &flags, &ov, NULL);
9676 ok(!iret, "WSARecv failed - %d, last error %lu\n", iret, GetLastError());
9677 ok(!num_bytes, "Managed to read %ld\n", num_bytes);
9679 SetLastError(0xdeadbeef);
9680 key = 0xdeadbeef;
9681 num_bytes = 0xdeadbeef;
9682 olp = (WSAOVERLAPPED *)0xdeadbeef;
9684 bret = GetQueuedCompletionStatus( io_port, &num_bytes, &key, &olp, 200 );
9685 ok(bret == TRUE, "failed to get completion status %u\n", bret);
9686 ok(GetLastError() == 0xdeadbeef, "Last error was %ld\n", GetLastError());
9687 ok(key == 125, "Key is %Iu\n", key);
9688 ok(!num_bytes, "Number of bytes transferred is %lu\n", num_bytes);
9689 ok(olp == &ov, "Overlapped structure is at %p\n", olp);
9691 closesocket(src);
9692 src = INVALID_SOCKET;
9693 closesocket(dest);
9694 dest = INVALID_SOCKET;
9696 /* Test IOCP response on hard shutdown. This was the condition that triggered
9697 * a crash in an actual app (bug 38980). */
9698 tcp_socketpair(&src, &dest);
9700 bufs.len = sizeof(buf);
9701 bufs.buf = buf;
9702 flags = 0;
9703 memset(&ov, 0, sizeof(ov));
9705 io_port = CreateIoCompletionPort((HANDLE)dest, io_port, 125, 0);
9706 ok(io_port != NULL, "failed to create completion port %lu\n", GetLastError());
9707 set_blocking(dest, FALSE);
9709 close_with_rst(src);
9711 FD_ZERO(&fds_recv);
9712 FD_SET(dest, &fds_recv);
9713 select(dest + 1, &fds_recv, NULL, NULL, NULL);
9715 num_bytes = 0xdeadbeef;
9716 SetLastError(0xdeadbeef);
9718 /* Somehow a hard shutdown doesn't work on my Linux box. It seems SO_LINGER is ignored. */
9719 iret = WSARecv(dest, &bufs, 1, &num_bytes, &flags, &ov, NULL);
9720 todo_wine ok(iret == SOCKET_ERROR, "WSARecv failed - %d\n", iret);
9721 todo_wine ok(GetLastError() == WSAECONNRESET, "Last error was %ld\n", GetLastError());
9722 todo_wine ok(num_bytes == 0xdeadbeef, "Managed to read %ld\n", num_bytes);
9724 SetLastError(0xdeadbeef);
9725 key = 0xdeadbeef;
9726 num_bytes = 0xdeadbeef;
9727 olp = (WSAOVERLAPPED *)0xdeadbeef;
9729 bret = GetQueuedCompletionStatus( io_port, &num_bytes, &key, &olp, 200 );
9730 todo_wine ok(bret == FALSE, "GetQueuedCompletionStatus returned %u\n", bret );
9731 todo_wine ok(GetLastError() == WAIT_TIMEOUT, "Last error was %ld\n", GetLastError());
9732 todo_wine ok(key == 0xdeadbeef, "Key is %Iu\n", key);
9733 todo_wine ok(num_bytes == 0xdeadbeef, "Number of bytes transferred is %lu\n", num_bytes);
9734 todo_wine ok(!olp, "Overlapped structure is at %p\n", olp);
9736 closesocket(dest);
9738 /* Test reading from a non-connected socket, mostly because the above test is marked todo. */
9739 dest = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
9740 ok(dest != INVALID_SOCKET, "socket() failed\n");
9742 io_port = CreateIoCompletionPort((HANDLE)dest, io_port, 125, 0);
9743 ok(io_port != NULL, "failed to create completion port %lu\n", GetLastError());
9744 set_blocking(dest, FALSE);
9746 num_bytes = 0xdeadbeef;
9747 SetLastError(0xdeadbeef);
9748 memset(&ov, 0, sizeof(ov));
9750 iret = WSARecv(dest, &bufs, 1, &num_bytes, &flags, &ov, NULL);
9751 ok(iret == SOCKET_ERROR, "WSARecv failed - %d\n", iret);
9752 ok(GetLastError() == WSAENOTCONN, "Last error was %ld\n", GetLastError());
9753 ok(num_bytes == 0xdeadbeef, "Managed to read %ld\n", num_bytes);
9755 SetLastError(0xdeadbeef);
9756 key = 0xdeadbeef;
9757 num_bytes = 0xdeadbeef;
9758 olp = (WSAOVERLAPPED *)0xdeadbeef;
9760 bret = GetQueuedCompletionStatus( io_port, &num_bytes, &key, &olp, 200 );
9761 ok(bret == FALSE, "GetQueuedCompletionStatus returned %u\n", bret );
9762 ok(GetLastError() == WAIT_TIMEOUT, "Last error was %ld\n", GetLastError());
9763 ok(key == 0xdeadbeef, "Key is %Iu\n", key);
9764 ok(num_bytes == 0xdeadbeef, "Number of bytes transferred is %lu\n", num_bytes);
9765 ok(!olp, "Overlapped structure is at %p\n", olp);
9767 num_bytes = 0xdeadbeef;
9768 closesocket(dest);
9770 dest = socket(AF_INET, SOCK_STREAM, 0);
9771 ok(dest != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
9773 iret = WSAIoctl(dest, SIO_GET_EXTENSION_FUNCTION_POINTER, &acceptExGuid, sizeof(acceptExGuid),
9774 &pAcceptEx, sizeof(pAcceptEx), &num_bytes, NULL, NULL);
9775 ok(!iret, "failed to get AcceptEx, error %u\n", WSAGetLastError());
9777 /* Test IOCP response on socket close (IOCP created after AcceptEx) */
9779 src = setup_iocp_src(&bindAddress);
9781 SetLastError(0xdeadbeef);
9783 bret = pAcceptEx(src, dest, buf, sizeof(buf) - 2*(sizeof(struct sockaddr_in) + 16),
9784 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
9785 &num_bytes, &ov);
9786 ok(bret == FALSE, "AcceptEx returned %d\n", bret);
9787 ok(GetLastError() == ERROR_IO_PENDING, "Last error was %ld\n", GetLastError());
9789 io_port = CreateIoCompletionPort((HANDLE)src, io_port, 125, 0);
9790 ok(io_port != NULL, "failed to create completion port %lu\n", GetLastError());
9792 closesocket(src);
9793 src = INVALID_SOCKET;
9795 SetLastError(0xdeadbeef);
9796 key = 0xdeadbeef;
9797 num_bytes = 0xdeadbeef;
9798 olp = (WSAOVERLAPPED *)0xdeadbeef;
9800 bret = GetQueuedCompletionStatus(io_port, &num_bytes, &key, &olp, 100);
9801 ok(bret == FALSE, "failed to get completion status %u\n", bret);
9802 ok(GetLastError() == ERROR_OPERATION_ABORTED, "Last error was %ld\n", GetLastError());
9803 ok(key == 125, "Key is %Iu\n", key);
9804 ok(num_bytes == 0, "Number of bytes transferred is %lu\n", num_bytes);
9805 ok(olp == &ov, "Overlapped structure is at %p\n", olp);
9806 ok(olp && (olp->Internal == (ULONG)STATUS_CANCELLED), "Internal status is %Ix\n", olp ? olp->Internal : 0);
9808 SetLastError(0xdeadbeef);
9809 key = 0xdeadbeef;
9810 num_bytes = 0xdeadbeef;
9811 olp = (WSAOVERLAPPED *)0xdeadbeef;
9812 bret = GetQueuedCompletionStatus( io_port, &num_bytes, &key, &olp, 200 );
9813 ok(bret == FALSE, "failed to get completion status %u\n", bret);
9814 ok(GetLastError() == WAIT_TIMEOUT, "Last error was %ld\n", GetLastError());
9815 ok(key == 0xdeadbeef, "Key is %Iu\n", key);
9816 ok(num_bytes == 0xdeadbeef, "Number of bytes transferred is %lu\n", num_bytes);
9817 ok(!olp, "Overlapped structure is at %p\n", olp);
9819 /* Test IOCP response on socket close (IOCP created before AcceptEx) */
9821 src = setup_iocp_src(&bindAddress);
9823 SetLastError(0xdeadbeef);
9825 io_port = CreateIoCompletionPort((HANDLE)src, io_port, 125, 0);
9826 ok(io_port != NULL, "failed to create completion port %lu\n", GetLastError());
9828 bret = pAcceptEx(src, dest, buf, sizeof(buf) - 2*(sizeof(struct sockaddr_in) + 16),
9829 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
9830 &num_bytes, &ov);
9831 ok(bret == FALSE, "AcceptEx returned %d\n", bret);
9832 ok(GetLastError() == ERROR_IO_PENDING, "Last error was %ld\n", GetLastError());
9834 closesocket(src);
9835 src = INVALID_SOCKET;
9837 SetLastError(0xdeadbeef);
9838 key = 0xdeadbeef;
9839 num_bytes = 0xdeadbeef;
9840 olp = (WSAOVERLAPPED *)0xdeadbeef;
9842 bret = GetQueuedCompletionStatus(io_port, &num_bytes, &key, &olp, 100);
9843 ok(bret == FALSE, "failed to get completion status %u\n", bret);
9844 ok(GetLastError() == ERROR_OPERATION_ABORTED, "Last error was %ld\n", GetLastError());
9845 ok(key == 125, "Key is %Iu\n", key);
9846 ok(num_bytes == 0, "Number of bytes transferred is %lu\n", num_bytes);
9847 ok(olp == &ov, "Overlapped structure is at %p\n", olp);
9848 ok(olp && (olp->Internal == (ULONG)STATUS_CANCELLED), "Internal status is %Ix\n", olp ? olp->Internal : 0);
9850 SetLastError(0xdeadbeef);
9851 key = 0xdeadbeef;
9852 num_bytes = 0xdeadbeef;
9853 olp = (WSAOVERLAPPED *)0xdeadbeef;
9854 bret = GetQueuedCompletionStatus( io_port, &num_bytes, &key, &olp, 200 );
9855 ok(bret == FALSE, "failed to get completion status %u\n", bret);
9856 ok(GetLastError() == WAIT_TIMEOUT, "Last error was %ld\n", GetLastError());
9857 ok(key == 0xdeadbeef, "Key is %Iu\n", key);
9858 ok(num_bytes == 0xdeadbeef, "Number of bytes transferred is %lu\n", num_bytes);
9859 ok(!olp, "Overlapped structure is at %p\n", olp);
9861 /* Test IOCP with duplicated handle */
9863 src = setup_iocp_src(&bindAddress);
9865 SetLastError(0xdeadbeef);
9867 io_port = CreateIoCompletionPort((HANDLE)src, io_port, 125, 0);
9868 ok(io_port != NULL, "failed to create completion port %lu\n", GetLastError());
9870 WSADuplicateSocketA( src, GetCurrentProcessId(), &info );
9871 dup = WSASocketA(AF_INET, SOCK_STREAM, 0, &info, 0, WSA_FLAG_OVERLAPPED);
9872 ok(dup != INVALID_SOCKET, "failed to duplicate socket!\n");
9874 bret = pAcceptEx(dup, dest, buf, sizeof(buf) - 2*(sizeof(struct sockaddr_in) + 16),
9875 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
9876 &num_bytes, &ov);
9877 ok(bret == FALSE, "AcceptEx returned %d\n", bret);
9878 ok(GetLastError() == ERROR_IO_PENDING, "Last error was %ld\n", GetLastError());
9880 SetLastError(0xdeadbeef);
9881 key = 0xdeadbeef;
9882 num_bytes = 0xdeadbeef;
9883 olp = (WSAOVERLAPPED *)0xdeadbeef;
9884 bret = GetQueuedCompletionStatus( io_port, &num_bytes, &key, &olp, 200 );
9885 ok(bret == FALSE, "failed to get completion status %u\n", bret);
9886 ok(GetLastError() == WAIT_TIMEOUT, "Last error was %ld\n", GetLastError());
9887 ok(key == 0xdeadbeef, "Key is %Iu\n", key);
9888 ok(num_bytes == 0xdeadbeef, "Number of bytes transferred is %lu\n", num_bytes);
9889 ok(!olp, "Overlapped structure is at %p\n", olp);
9891 closesocket(src);
9892 src = INVALID_SOCKET;
9893 closesocket(dup);
9894 dup = INVALID_SOCKET;
9896 SetLastError(0xdeadbeef);
9897 key = 0xdeadbeef;
9898 num_bytes = 0xdeadbeef;
9899 olp = (WSAOVERLAPPED *)0xdeadbeef;
9900 bret = GetQueuedCompletionStatus(io_port, &num_bytes, &key, &olp, 100);
9901 ok(bret == FALSE, "failed to get completion status %u\n", bret);
9902 ok(GetLastError() == ERROR_OPERATION_ABORTED, "Last error was %ld\n", GetLastError());
9903 ok(key == 125, "Key is %Iu\n", key);
9904 ok(num_bytes == 0, "Number of bytes transferred is %lu\n", num_bytes);
9905 ok(olp == &ov, "Overlapped structure is at %p\n", olp);
9906 ok(olp && olp->Internal == (ULONG)STATUS_CANCELLED, "Internal status is %Ix\n", olp ? olp->Internal : 0);
9908 SetLastError(0xdeadbeef);
9909 key = 0xdeadbeef;
9910 num_bytes = 0xdeadbeef;
9911 olp = (WSAOVERLAPPED *)0xdeadbeef;
9912 bret = GetQueuedCompletionStatus( io_port, &num_bytes, &key, &olp, 200 );
9913 ok(bret == FALSE, "failed to get completion status %u\n", bret);
9914 ok(GetLastError() == WAIT_TIMEOUT, "Last error was %ld\n", GetLastError());
9915 ok(key == 0xdeadbeef, "Key is %Iu\n", key);
9916 ok(num_bytes == 0xdeadbeef, "Number of bytes transferred is %lu\n", num_bytes);
9917 ok(!olp, "Overlapped structure is at %p\n", olp);
9919 /* Test IOCP with duplicated handle (closing duplicated handle) */
9921 src = setup_iocp_src(&bindAddress);
9923 SetLastError(0xdeadbeef);
9925 io_port = CreateIoCompletionPort((HANDLE)src, io_port, 125, 0);
9926 ok(io_port != NULL, "failed to create completion port %lu\n", GetLastError());
9928 WSADuplicateSocketA( src, GetCurrentProcessId(), &info );
9929 dup = WSASocketA(AF_INET, SOCK_STREAM, 0, &info, 0, WSA_FLAG_OVERLAPPED);
9930 ok(dup != INVALID_SOCKET, "failed to duplicate socket!\n");
9932 bret = pAcceptEx(dup, dest, buf, sizeof(buf) - 2*(sizeof(struct sockaddr_in) + 16),
9933 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
9934 &num_bytes, &ov);
9935 ok(bret == FALSE, "AcceptEx returned %d\n", bret);
9936 ok(GetLastError() == ERROR_IO_PENDING, "Last error was %ld\n", GetLastError());
9938 closesocket(dup);
9939 dup = INVALID_SOCKET;
9941 SetLastError(0xdeadbeef);
9942 key = 0xdeadbeef;
9943 num_bytes = 0xdeadbeef;
9944 olp = (WSAOVERLAPPED *)0xdeadbeef;
9945 bret = GetQueuedCompletionStatus( io_port, &num_bytes, &key, &olp, 200 );
9946 ok(bret == FALSE, "failed to get completion status %u\n", bret);
9947 ok(GetLastError() == WAIT_TIMEOUT, "Last error was %ld\n", GetLastError());
9948 ok(key == 0xdeadbeef, "Key is %Iu\n", key);
9949 ok(num_bytes == 0xdeadbeef, "Number of bytes transferred is %lu\n", num_bytes);
9950 ok(!olp, "Overlapped structure is at %p\n", olp);
9952 SetLastError(0xdeadbeef);
9953 key = 0xdeadbeef;
9954 num_bytes = 0xdeadbeef;
9955 olp = (WSAOVERLAPPED *)0xdeadbeef;
9956 bret = GetQueuedCompletionStatus( io_port, &num_bytes, &key, &olp, 200 );
9957 ok(bret == FALSE, "failed to get completion status %u\n", bret);
9958 ok(GetLastError() == WAIT_TIMEOUT, "Last error was %ld\n", GetLastError());
9959 ok(key == 0xdeadbeef, "Key is %Iu\n", key);
9960 ok(num_bytes == 0xdeadbeef, "Number of bytes transferred is %lu\n", num_bytes);
9961 ok(!olp, "Overlapped structure is at %p\n", olp);
9963 closesocket(src);
9964 src = INVALID_SOCKET;
9966 bret = GetQueuedCompletionStatus(io_port, &num_bytes, &key, &olp, 100);
9967 ok(bret == FALSE, "failed to get completion status %u\n", bret);
9968 ok(GetLastError() == ERROR_OPERATION_ABORTED, "Last error was %ld\n", GetLastError());
9969 ok(key == 125, "Key is %Iu\n", key);
9970 ok(num_bytes == 0, "Number of bytes transferred is %lu\n", num_bytes);
9971 ok(olp == &ov, "Overlapped structure is at %p\n", olp);
9972 ok(olp && (olp->Internal == (ULONG)STATUS_CANCELLED), "Internal status is %Ix\n", olp ? olp->Internal : 0);
9974 SetLastError(0xdeadbeef);
9975 key = 0xdeadbeef;
9976 num_bytes = 0xdeadbeef;
9977 olp = (WSAOVERLAPPED *)0xdeadbeef;
9978 bret = GetQueuedCompletionStatus( io_port, &num_bytes, &key, &olp, 200 );
9979 ok(bret == FALSE, "failed to get completion status %u\n", bret);
9980 ok(GetLastError() == WAIT_TIMEOUT, "Last error was %ld\n", GetLastError());
9981 ok(key == 0xdeadbeef, "Key is %Iu\n", key);
9982 ok(num_bytes == 0xdeadbeef, "Number of bytes transferred is %lu\n", num_bytes);
9983 ok(!olp, "Overlapped structure is at %p\n", olp);
9985 /* Test IOCP with duplicated handle (closing original handle) */
9987 src = setup_iocp_src(&bindAddress);
9989 SetLastError(0xdeadbeef);
9991 io_port = CreateIoCompletionPort((HANDLE)src, io_port, 125, 0);
9992 ok(io_port != NULL, "failed to create completion port %lu\n", GetLastError());
9994 WSADuplicateSocketA( src, GetCurrentProcessId(), &info );
9995 dup = WSASocketA(AF_INET, SOCK_STREAM, 0, &info, 0, WSA_FLAG_OVERLAPPED);
9996 ok(dup != INVALID_SOCKET, "failed to duplicate socket!\n");
9998 bret = pAcceptEx(dup, dest, buf, sizeof(buf) - 2*(sizeof(struct sockaddr_in) + 16),
9999 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
10000 &num_bytes, &ov);
10001 ok(bret == FALSE, "AcceptEx returned %d\n", bret);
10002 ok(GetLastError() == ERROR_IO_PENDING, "Last error was %ld\n", GetLastError());
10004 closesocket(src);
10005 src = INVALID_SOCKET;
10007 SetLastError(0xdeadbeef);
10008 key = 0xdeadbeef;
10009 num_bytes = 0xdeadbeef;
10010 olp = (WSAOVERLAPPED *)0xdeadbeef;
10011 bret = GetQueuedCompletionStatus( io_port, &num_bytes, &key, &olp, 200 );
10012 ok(bret == FALSE, "failed to get completion status %u\n", bret);
10013 ok(GetLastError() == WAIT_TIMEOUT, "Last error was %ld\n", GetLastError());
10014 ok(key == 0xdeadbeef, "Key is %Iu\n", key);
10015 ok(num_bytes == 0xdeadbeef, "Number of bytes transferred is %lu\n", num_bytes);
10016 ok(!olp, "Overlapped structure is at %p\n", olp);
10018 closesocket(dup);
10019 dup = INVALID_SOCKET;
10021 bret = GetQueuedCompletionStatus(io_port, &num_bytes, &key, &olp, 100);
10022 ok(bret == FALSE, "failed to get completion status %u\n", bret);
10023 ok(GetLastError() == ERROR_OPERATION_ABORTED, "Last error was %ld\n", GetLastError());
10024 ok(key == 125, "Key is %Iu\n", key);
10025 ok(num_bytes == 0, "Number of bytes transferred is %lu\n", num_bytes);
10026 ok(olp == &ov, "Overlapped structure is at %p\n", olp);
10027 ok(olp && (olp->Internal == (ULONG)STATUS_CANCELLED), "Internal status is %Ix\n", olp ? olp->Internal : 0);
10029 SetLastError(0xdeadbeef);
10030 key = 0xdeadbeef;
10031 num_bytes = 0xdeadbeef;
10032 olp = (WSAOVERLAPPED *)0xdeadbeef;
10033 bret = GetQueuedCompletionStatus( io_port, &num_bytes, &key, &olp, 200 );
10034 ok(bret == FALSE, "failed to get completion status %u\n", bret);
10035 ok(GetLastError() == WAIT_TIMEOUT, "Last error was %ld\n", GetLastError());
10036 ok(key == 0xdeadbeef, "Key is %Iu\n", key);
10037 ok(num_bytes == 0xdeadbeef, "Number of bytes transferred is %lu\n", num_bytes);
10038 ok(!olp, "Overlapped structure is at %p\n", olp);
10040 /* Test IOCP without AcceptEx */
10042 src = setup_iocp_src(&bindAddress);
10044 SetLastError(0xdeadbeef);
10046 io_port = CreateIoCompletionPort((HANDLE)src, io_port, 125, 0);
10047 ok(io_port != NULL, "failed to create completion port %lu\n", GetLastError());
10049 closesocket(src);
10050 src = INVALID_SOCKET;
10052 SetLastError(0xdeadbeef);
10053 key = 0xdeadbeef;
10054 num_bytes = 0xdeadbeef;
10055 olp = (WSAOVERLAPPED *)0xdeadbeef;
10056 bret = GetQueuedCompletionStatus( io_port, &num_bytes, &key, &olp, 200 );
10057 ok(bret == FALSE, "failed to get completion status %u\n", bret);
10058 ok(GetLastError() == WAIT_TIMEOUT, "Last error was %ld\n", GetLastError());
10059 ok(key == 0xdeadbeef, "Key is %Iu\n", key);
10060 ok(num_bytes == 0xdeadbeef, "Number of bytes transferred is %lu\n", num_bytes);
10061 ok(!olp, "Overlapped structure is at %p\n", olp);
10063 /* */
10065 src = setup_iocp_src(&bindAddress);
10067 connector = socket(AF_INET, SOCK_STREAM, 0);
10068 ok(connector != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
10070 io_port = CreateIoCompletionPort((HANDLE)src, io_port, 125, 0);
10071 ok(io_port != NULL, "failed to create completion port %lu\n", GetLastError());
10073 io_port = CreateIoCompletionPort((HANDLE)dest, io_port, 236, 0);
10074 ok(io_port != NULL, "failed to create completion port %lu\n", GetLastError());
10076 bret = pAcceptEx(src, dest, buf, sizeof(buf) - 2*(sizeof(struct sockaddr_in) + 16),
10077 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
10078 &num_bytes, &ov);
10079 ok(bret == FALSE, "AcceptEx returned %d\n", bret);
10080 ok(GetLastError() == ERROR_IO_PENDING, "Last error was %ld\n", GetLastError());
10082 iret = connect(connector, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
10083 ok(iret == 0, "connecting to accepting socket failed, error %ld\n", GetLastError());
10085 closesocket(connector);
10086 connector = INVALID_SOCKET;
10088 SetLastError(0xdeadbeef);
10089 key = 0xdeadbeef;
10090 num_bytes = 0xdeadbeef;
10091 olp = (WSAOVERLAPPED *)0xdeadbeef;
10093 bret = GetQueuedCompletionStatus(io_port, &num_bytes, &key, &olp, 100);
10094 ok(bret == TRUE, "failed to get completion status %u\n", bret);
10095 ok(GetLastError() == 0xdeadbeef, "Last error was %ld\n", GetLastError());
10096 ok(key == 125, "Key is %Iu\n", key);
10097 ok(num_bytes == 0, "Number of bytes transferred is %lu\n", num_bytes);
10098 ok(olp == &ov, "Overlapped structure is at %p\n", olp);
10099 ok(olp && (olp->Internal == (ULONG)STATUS_SUCCESS), "Internal status is %Ix\n", olp ? olp->Internal : 0);
10101 SetLastError(0xdeadbeef);
10102 key = 0xdeadbeef;
10103 num_bytes = 0xdeadbeef;
10104 olp = (WSAOVERLAPPED *)0xdeadbeef;
10105 bret = GetQueuedCompletionStatus( io_port, &num_bytes, &key, &olp, 200 );
10106 ok(bret == FALSE, "failed to get completion status %u\n", bret);
10107 ok(GetLastError() == WAIT_TIMEOUT, "Last error was %ld\n", GetLastError());
10108 ok(key == 0xdeadbeef, "Key is %Iu\n", key);
10109 ok(num_bytes == 0xdeadbeef, "Number of bytes transferred is %lu\n", num_bytes);
10110 ok(!olp, "Overlapped structure is at %p\n", olp);
10112 if (dest != INVALID_SOCKET)
10113 closesocket(dest);
10114 if (src != INVALID_SOCKET)
10115 closesocket(dest);
10117 /* */
10119 src = setup_iocp_src(&bindAddress);
10121 dest = socket(AF_INET, SOCK_STREAM, 0);
10122 ok(dest != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
10124 connector = socket(AF_INET, SOCK_STREAM, 0);
10125 ok(connector != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
10127 io_port = CreateIoCompletionPort((HANDLE)src, io_port, 125, 0);
10128 ok(io_port != NULL, "failed to create completion port %lu\n", GetLastError());
10130 io_port = CreateIoCompletionPort((HANDLE)dest, io_port, 236, 0);
10131 ok(io_port != NULL, "failed to create completion port %lu\n", GetLastError());
10133 bret = pAcceptEx(src, dest, buf, sizeof(buf) - 2*(sizeof(struct sockaddr_in) + 16),
10134 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
10135 &num_bytes, &ov);
10136 ok(bret == FALSE, "AcceptEx returned %d\n", bret);
10137 ok(GetLastError() == ERROR_IO_PENDING, "Last error was %ld\n", GetLastError());
10139 iret = connect(connector, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
10140 ok(iret == 0, "connecting to accepting socket failed, error %ld\n", GetLastError());
10142 iret = send(connector, buf, 1, 0);
10143 ok(iret == 1, "could not send 1 byte: send %d errno %d\n", iret, WSAGetLastError());
10145 Sleep(100);
10147 closesocket(dest);
10148 dest = INVALID_SOCKET;
10150 SetLastError(0xdeadbeef);
10151 key = 0xdeadbeef;
10152 num_bytes = 0xdeadbeef;
10153 olp = (WSAOVERLAPPED *)0xdeadbeef;
10155 bret = GetQueuedCompletionStatus(io_port, &num_bytes, &key, &olp, 100);
10156 ok(bret == TRUE, "failed to get completion status %u\n", bret);
10157 ok(GetLastError() == 0xdeadbeef, "Last error was %ld\n", GetLastError());
10158 ok(key == 125, "Key is %Iu\n", key);
10159 ok(num_bytes == 1, "Number of bytes transferred is %lu\n", num_bytes);
10160 ok(olp == &ov, "Overlapped structure is at %p\n", olp);
10161 ok(olp && (olp->Internal == (ULONG)STATUS_SUCCESS), "Internal status is %Ix\n", olp ? olp->Internal : 0);
10163 SetLastError(0xdeadbeef);
10164 key = 0xdeadbeef;
10165 num_bytes = 0xdeadbeef;
10166 olp = (WSAOVERLAPPED *)0xdeadbeef;
10167 bret = GetQueuedCompletionStatus( io_port, &num_bytes, &key, &olp, 200 );
10168 ok(bret == FALSE, "failed to get completion status %u\n", bret);
10169 ok(GetLastError() == WAIT_TIMEOUT, "Last error was %ld\n", GetLastError());
10170 ok(key == 0xdeadbeef, "Key is %Iu\n", key);
10171 ok(num_bytes == 0xdeadbeef, "Number of bytes transferred is %lu\n", num_bytes);
10172 ok(!olp, "Overlapped structure is at %p\n", olp);
10174 if (src != INVALID_SOCKET)
10175 closesocket(src);
10176 if (connector != INVALID_SOCKET)
10177 closesocket(connector);
10179 /* */
10181 src = setup_iocp_src(&bindAddress);
10183 dest = socket(AF_INET, SOCK_STREAM, 0);
10184 ok(dest != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
10186 connector = socket(AF_INET, SOCK_STREAM, 0);
10187 ok(connector != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
10189 io_port = CreateIoCompletionPort((HANDLE)src, io_port, 125, 0);
10190 ok(io_port != NULL, "failed to create completion port %lu\n", GetLastError());
10192 io_port = CreateIoCompletionPort((HANDLE)dest, io_port, 236, 0);
10193 ok(io_port != NULL, "failed to create completion port %lu\n", GetLastError());
10195 bret = pAcceptEx(src, dest, buf, sizeof(buf) - 2*(sizeof(struct sockaddr_in) + 16),
10196 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
10197 &num_bytes, &ov);
10198 ok(bret == FALSE, "AcceptEx returned %d\n", bret);
10199 ok(GetLastError() == ERROR_IO_PENDING, "Last error was %ld\n", GetLastError());
10201 iret = connect(connector, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
10202 ok(iret == 0, "connecting to accepting socket failed, error %ld\n", GetLastError());
10204 closesocket(dest);
10206 SetLastError(0xdeadbeef);
10207 key = 0xdeadbeef;
10208 num_bytes = 0xdeadbeef;
10209 olp = (WSAOVERLAPPED *)0xdeadbeef;
10211 bret = GetQueuedCompletionStatus(io_port, &num_bytes, &key, &olp, 100);
10212 ok(bret == FALSE, "failed to get completion status %u\n", bret);
10213 ok(GetLastError() == ERROR_OPERATION_ABORTED
10214 || GetLastError() == ERROR_CONNECTION_ABORTED, "got error %lu\n", GetLastError());
10215 ok(key == 125, "Key is %Iu\n", key);
10216 ok(num_bytes == 0, "Number of bytes transferred is %lu\n", num_bytes);
10217 ok(olp == &ov, "Overlapped structure is at %p\n", olp);
10218 ok((NTSTATUS)olp->Internal == STATUS_CANCELLED
10219 || (NTSTATUS)olp->Internal == STATUS_CONNECTION_ABORTED, "got status %#Ix\n", olp->Internal);
10221 SetLastError(0xdeadbeef);
10222 key = 0xdeadbeef;
10223 num_bytes = 0xdeadbeef;
10224 olp = (WSAOVERLAPPED *)0xdeadbeef;
10225 bret = GetQueuedCompletionStatus( io_port, &num_bytes, &key, &olp, 200 );
10226 ok(bret == FALSE, "failed to get completion status %u\n", bret);
10227 ok(GetLastError() == WAIT_TIMEOUT, "Last error was %ld\n", GetLastError());
10228 ok(key == 0xdeadbeef, "Key is %Iu\n", key);
10229 ok(num_bytes == 0xdeadbeef, "Number of bytes transferred is %lu\n", num_bytes);
10230 ok(!olp, "Overlapped structure is at %p\n", olp);
10232 closesocket(src);
10233 closesocket(connector);
10234 CloseHandle(io_port);
10237 static void test_connect_completion_port(void)
10239 OVERLAPPED overlapped = {0}, *overlapped_ptr;
10240 GUID connectex_guid = WSAID_CONNECTEX;
10241 SOCKET connector, listener, acceptor;
10242 struct sockaddr_in addr, destaddr;
10243 LPFN_CONNECTEX pConnectEx;
10244 int ret, addrlen;
10245 ULONG_PTR key;
10246 HANDLE port;
10247 DWORD size;
10249 overlapped.hEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
10251 listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
10252 ok(listener != -1, "failed to create socket, error %u\n", WSAGetLastError());
10254 memset(&addr, 0, sizeof(addr));
10255 addr.sin_family = AF_INET;
10256 addr.sin_addr.s_addr = inet_addr("127.0.0.1");
10257 ret = bind(listener, (struct sockaddr *)&addr, sizeof(addr));
10258 ok(!ret, "failed to bind, error %u\n", WSAGetLastError());
10259 addrlen = sizeof(destaddr);
10260 ret = getsockname(listener, (struct sockaddr *)&destaddr, &addrlen);
10261 ok(!ret, "failed to get address, error %u\n", WSAGetLastError());
10263 ret = listen(listener, 1);
10264 ok(!ret, "failed to listen, error %u\n", WSAGetLastError());
10266 connector = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
10267 ok(connector != -1, "failed to create socket, error %u\n", WSAGetLastError());
10269 ret = WSAIoctl(connector, SIO_GET_EXTENSION_FUNCTION_POINTER, &connectex_guid, sizeof(connectex_guid),
10270 &pConnectEx, sizeof(pConnectEx), &size, NULL, NULL);
10271 ok(!ret, "Failed to get ConnectEx, error %u\n", WSAGetLastError());
10273 /* connect() does not queue completion. */
10275 port = CreateIoCompletionPort((HANDLE)connector, NULL, 0, 0);
10276 ok(!!port, "failed to create port, error %lu\n", GetLastError());
10278 ret = connect(connector, (struct sockaddr *)&destaddr, sizeof(destaddr));
10279 ok(!ret, "failed to connect, error %u\n", WSAGetLastError());
10280 acceptor = accept(listener, NULL, NULL);
10281 ok(acceptor != -1, "failed to accept, error %u\n", WSAGetLastError());
10282 closesocket(acceptor);
10284 ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 0);
10285 ok(!ret, "expected failure\n");
10286 ok(GetLastError() == WAIT_TIMEOUT, "got error %lu\n", GetLastError());
10288 closesocket(connector);
10289 CloseHandle(port);
10291 connector = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
10292 ok(connector != -1, "failed to create socket, error %u\n", WSAGetLastError());
10293 port = CreateIoCompletionPort((HANDLE)connector, NULL, 0, 0);
10294 ok(!!port, "failed to create port, error %lu\n", GetLastError());
10295 set_blocking(connector, FALSE);
10297 ret = connect(connector, (struct sockaddr *)&destaddr, sizeof(destaddr));
10298 ok(ret == -1, "expected failure\n");
10299 ok(WSAGetLastError() == WSAEWOULDBLOCK, "got error %u\n", WSAGetLastError());
10300 acceptor = accept(listener, NULL, NULL);
10301 ok(acceptor != -1, "failed to accept, error %u\n", WSAGetLastError());
10302 closesocket(acceptor);
10304 ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 0);
10305 ok(!ret, "expected failure\n");
10306 ok(GetLastError() == WAIT_TIMEOUT, "got error %lu\n", GetLastError());
10308 closesocket(connector);
10309 CloseHandle(port);
10311 /* ConnectEx() queues completion. */
10313 connector = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
10314 ok(connector != -1, "failed to create socket, error %u\n", WSAGetLastError());
10315 port = CreateIoCompletionPort((HANDLE)connector, NULL, 0, 0);
10316 ok(!!port, "failed to create port, error %lu\n", GetLastError());
10317 ret = bind(connector, (struct sockaddr *)&addr, sizeof(addr));
10318 ok(!ret, "failed to bind, error %u\n", WSAGetLastError());
10320 ret = pConnectEx(connector, (struct sockaddr *)&destaddr, sizeof(destaddr),
10321 NULL, 0, &size, &overlapped);
10322 ok(!ret, "expected failure\n");
10323 ok(GetLastError() == ERROR_IO_PENDING, "got error %lu\n", GetLastError());
10324 ret = WaitForSingleObject(overlapped.hEvent, 1000);
10325 ok(!ret, "wait failed\n");
10326 ret = GetOverlappedResult((HANDLE)connector, &overlapped, &size, FALSE);
10327 ok(ret, "got error %lu\n", GetLastError());
10328 ok(!size, "got %lu bytes\n", size);
10329 acceptor = accept(listener, NULL, NULL);
10330 ok(acceptor != -1, "failed to accept, error %u\n", WSAGetLastError());
10331 closesocket(acceptor);
10333 size = 0xdeadbeef;
10334 key = 0xdeadbeef;
10335 overlapped_ptr = NULL;
10336 ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 0);
10337 ok(ret, "got error %lu\n", GetLastError());
10338 ok(!key, "got key %#Ix\n", key);
10339 ok(!size, "got %lu bytes\n", size);
10340 ok(overlapped_ptr == &overlapped, "got overlapped %p\n", overlapped_ptr);
10342 closesocket(connector);
10343 CloseHandle(port);
10345 /* Test ConnectEx() with a non-empty buffer. */
10347 connector = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
10348 ok(connector != -1, "failed to create socket, error %u\n", WSAGetLastError());
10349 port = CreateIoCompletionPort((HANDLE)connector, NULL, 0, 0);
10350 ok(!!port, "failed to create port, error %lu\n", GetLastError());
10351 ret = bind(connector, (struct sockaddr *)&addr, sizeof(addr));
10352 ok(!ret, "failed to bind, error %u\n", WSAGetLastError());
10354 ret = pConnectEx(connector, (struct sockaddr *)&destaddr, sizeof(destaddr),
10355 (void *)"one", 3, &size, &overlapped);
10356 ok(!ret, "expected failure\n");
10357 ok(GetLastError() == ERROR_IO_PENDING, "got error %lu\n", GetLastError());
10358 ret = WaitForSingleObject(overlapped.hEvent, 1000);
10359 ok(!ret, "wait failed\n");
10360 ret = GetOverlappedResult((HANDLE)connector, &overlapped, &size, FALSE);
10361 ok(ret, "got error %lu\n", GetLastError());
10362 ok(size == 3, "got %lu bytes\n", size);
10363 acceptor = accept(listener, NULL, NULL);
10364 ok(acceptor != -1, "failed to accept, error %u\n", WSAGetLastError());
10365 closesocket(acceptor);
10367 size = 0xdeadbeef;
10368 key = 0xdeadbeef;
10369 overlapped_ptr = NULL;
10370 ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 0);
10371 ok(ret, "got error %lu\n", GetLastError());
10372 ok(!key, "got key %#Ix\n", key);
10373 ok(size == 3, "got %lu bytes\n", size);
10374 ok(overlapped_ptr == &overlapped, "got overlapped %p\n", overlapped_ptr);
10376 closesocket(connector);
10377 CloseHandle(port);
10379 /* Suppress completion by setting the low bit. */
10381 connector = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
10382 ok(connector != -1, "failed to create socket, error %u\n", WSAGetLastError());
10383 port = CreateIoCompletionPort((HANDLE)connector, NULL, 0, 0);
10384 ok(!!port, "failed to create port, error %lu\n", GetLastError());
10385 ret = bind(connector, (struct sockaddr *)&addr, sizeof(addr));
10386 ok(!ret, "failed to bind, error %u\n", WSAGetLastError());
10388 overlapped.hEvent = (HANDLE)((ULONG_PTR)overlapped.hEvent | 1);
10390 ret = pConnectEx(connector, (struct sockaddr *)&destaddr, sizeof(destaddr),
10391 NULL, 0, &size, &overlapped);
10392 ok(!ret, "expected failure\n");
10393 ok(GetLastError() == ERROR_IO_PENDING, "got error %lu\n", GetLastError());
10394 ret = WaitForSingleObject(overlapped.hEvent, 1000);
10395 ok(!ret, "wait failed\n");
10396 ret = GetOverlappedResult((HANDLE)connector, &overlapped, &size, FALSE);
10397 ok(ret, "got error %lu\n", GetLastError());
10398 ok(!size, "got %lu bytes\n", size);
10399 acceptor = accept(listener, NULL, NULL);
10400 ok(acceptor != -1, "failed to accept, error %u\n", WSAGetLastError());
10401 closesocket(acceptor);
10403 ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 0);
10404 ok(!ret, "expected failure\n");
10405 ok(GetLastError() == WAIT_TIMEOUT, "got error %lu\n", GetLastError());
10407 closesocket(connector);
10408 CloseHandle(port);
10410 overlapped.hEvent = (HANDLE)((ULONG_PTR)overlapped.hEvent & ~1);
10412 /* Skip completion on success. */
10414 connector = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
10415 ok(connector != -1, "failed to create socket, error %u\n", WSAGetLastError());
10416 port = CreateIoCompletionPort((HANDLE)connector, NULL, 0, 0);
10417 ok(!!port, "failed to create port, error %lu\n", GetLastError());
10418 ret = SetFileCompletionNotificationModes((HANDLE)connector, FILE_SKIP_COMPLETION_PORT_ON_SUCCESS);
10419 ok(ret, "got error %lu\n", GetLastError());
10420 ret = bind(connector, (struct sockaddr *)&addr, sizeof(addr));
10421 ok(!ret, "failed to bind, error %u\n", WSAGetLastError());
10423 ret = pConnectEx(connector, (struct sockaddr *)&destaddr, sizeof(destaddr),
10424 NULL, 0, &size, &overlapped);
10425 ok(!ret, "expected failure\n");
10426 ok(GetLastError() == ERROR_IO_PENDING, "got error %lu\n", GetLastError());
10427 ret = WaitForSingleObject(overlapped.hEvent, 1000);
10428 ok(!ret, "wait failed\n");
10429 ret = GetOverlappedResult((HANDLE)connector, &overlapped, &size, FALSE);
10430 ok(ret, "got error %lu\n", GetLastError());
10431 ok(!size, "got %lu bytes\n", size);
10432 acceptor = accept(listener, NULL, NULL);
10433 ok(acceptor != -1, "failed to accept, error %u\n", WSAGetLastError());
10434 closesocket(acceptor);
10436 size = 0xdeadbeef;
10437 key = 0xdeadbeef;
10438 overlapped_ptr = NULL;
10439 ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 0);
10440 ok(ret, "got error %lu\n", GetLastError());
10441 ok(!key, "got key %#Ix\n", key);
10442 ok(!size, "got %lu bytes\n", size);
10443 ok(overlapped_ptr == &overlapped, "got overlapped %p\n", overlapped_ptr);
10445 closesocket(connector);
10446 CloseHandle(port);
10448 closesocket(listener);
10450 /* Connect to an invalid address. */
10452 connector = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
10453 ok(connector != -1, "failed to create socket, error %u\n", WSAGetLastError());
10454 port = CreateIoCompletionPort((HANDLE)connector, NULL, 0, 0);
10455 ok(!!port, "failed to create port, error %lu\n", GetLastError());
10456 ret = SetFileCompletionNotificationModes((HANDLE)connector, FILE_SKIP_COMPLETION_PORT_ON_SUCCESS);
10457 ok(ret, "got error %lu\n", GetLastError());
10458 ret = bind(connector, (struct sockaddr *)&addr, sizeof(addr));
10459 ok(!ret, "failed to bind, error %u\n", WSAGetLastError());
10461 ret = pConnectEx(connector, (struct sockaddr *)&destaddr, sizeof(destaddr),
10462 NULL, 0, &size, &overlapped);
10463 ok(!ret, "expected failure\n");
10464 ok(GetLastError() == ERROR_IO_PENDING, "got error %lu\n", GetLastError());
10465 ret = WaitForSingleObject(overlapped.hEvent, 15000);
10466 ok(!ret, "wait failed\n");
10467 ret = GetOverlappedResult((HANDLE)connector, &overlapped, &size, FALSE);
10468 ok(!ret, "expected failure\n");
10469 ok(GetLastError() == ERROR_CONNECTION_REFUSED, "got error %lu\n", GetLastError());
10470 ok(!size, "got %lu bytes\n", size);
10472 size = 0xdeadbeef;
10473 key = 0xdeadbeef;
10474 overlapped_ptr = NULL;
10475 ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 0);
10476 ok(!ret, "expected failure\n");
10477 ok(GetLastError() == ERROR_CONNECTION_REFUSED, "got error %lu\n", GetLastError());
10478 ok(!key, "got key %#Ix\n", key);
10479 ok(!size, "got %lu bytes\n", size);
10480 ok(overlapped_ptr == &overlapped, "got overlapped %p\n", overlapped_ptr);
10482 closesocket(connector);
10483 CloseHandle(port);
10486 static void test_shutdown_completion_port(void)
10488 OVERLAPPED overlapped = {0}, *overlapped_ptr;
10489 GUID disconnectex_guid = WSAID_DISCONNECTEX;
10490 struct sockaddr_in addr, destaddr;
10491 LPFN_DISCONNECTEX pDisconnectEx;
10492 SOCKET listener, server, client;
10493 int ret, addrlen;
10494 ULONG_PTR key;
10495 HANDLE port;
10496 DWORD size;
10498 overlapped.hEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
10500 listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
10501 ok(listener != -1, "failed to create socket, error %u\n", WSAGetLastError());
10503 memset(&addr, 0, sizeof(addr));
10504 addr.sin_family = AF_INET;
10505 addr.sin_addr.s_addr = inet_addr("127.0.0.1");
10506 ret = bind(listener, (struct sockaddr *)&addr, sizeof(addr));
10507 ok(!ret, "failed to bind, error %u\n", WSAGetLastError());
10508 addrlen = sizeof(destaddr);
10509 ret = getsockname(listener, (struct sockaddr *)&destaddr, &addrlen);
10510 ok(!ret, "failed to get address, error %u\n", WSAGetLastError());
10512 ret = listen(listener, 1);
10513 ok(!ret, "failed to listen, error %u\n", WSAGetLastError());
10515 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
10516 ok(client != -1, "failed to create socket, error %u\n", WSAGetLastError());
10518 ret = WSAIoctl(client, SIO_GET_EXTENSION_FUNCTION_POINTER, &disconnectex_guid, sizeof(disconnectex_guid),
10519 &pDisconnectEx, sizeof(pDisconnectEx), &size, NULL, NULL);
10520 ok(!ret, "Failed to get ConnectEx, error %u\n", WSAGetLastError());
10522 /* shutdown() does not queue completion. */
10524 port = CreateIoCompletionPort((HANDLE)client, NULL, 0, 0);
10525 ok(!!port, "failed to create port, error %lu\n", GetLastError());
10526 ret = connect(client, (struct sockaddr *)&destaddr, sizeof(destaddr));
10527 ok(!ret, "failed to connect, error %u\n", WSAGetLastError());
10528 server = accept(listener, NULL, NULL);
10529 ok(server != -1, "failed to accept, error %u\n", WSAGetLastError());
10531 ret = shutdown(client, SD_BOTH);
10532 ok(!ret, "failed to shutdown, error %u\n", WSAGetLastError());
10534 ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 0);
10535 ok(!ret, "expected failure\n");
10536 ok(GetLastError() == WAIT_TIMEOUT, "got error %lu\n", GetLastError());
10538 closesocket(server);
10539 closesocket(client);
10540 CloseHandle(port);
10542 /* WSASendDisconnect() and WSARecvDisconnect() do not queue completion. */
10544 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
10545 ok(client != -1, "failed to create socket, error %u\n", WSAGetLastError());
10546 port = CreateIoCompletionPort((HANDLE)client, NULL, 0, 0);
10547 ok(!!port, "failed to create port, error %lu\n", GetLastError());
10548 ret = connect(client, (struct sockaddr *)&destaddr, sizeof(destaddr));
10549 ok(!ret, "failed to connect, error %u\n", WSAGetLastError());
10550 server = accept(listener, NULL, NULL);
10551 ok(server != -1, "failed to accept, error %u\n", WSAGetLastError());
10553 ret = WSASendDisconnect(client, NULL);
10554 ok(!ret, "failed to shutdown, error %u\n", WSAGetLastError());
10556 ret = WSARecvDisconnect(client, NULL);
10557 ok(!ret, "failed to shutdown, error %u\n", WSAGetLastError());
10559 ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 0);
10560 ok(!ret, "expected failure\n");
10561 ok(GetLastError() == WAIT_TIMEOUT, "got error %lu\n", GetLastError());
10563 closesocket(server);
10564 closesocket(client);
10565 CloseHandle(port);
10567 /* DisconnectEx() queues completion. */
10569 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
10570 ok(client != -1, "failed to create socket, error %u\n", WSAGetLastError());
10571 port = CreateIoCompletionPort((HANDLE)client, NULL, 0, 0);
10572 ok(!!port, "failed to create port, error %lu\n", GetLastError());
10573 ret = SetFileCompletionNotificationModes((HANDLE)client, FILE_SKIP_COMPLETION_PORT_ON_SUCCESS);
10574 ok(ret, "got error %lu\n", GetLastError());
10575 ret = connect(client, (struct sockaddr *)&destaddr, sizeof(destaddr));
10576 ok(!ret, "failed to connect, error %u\n", WSAGetLastError());
10577 server = accept(listener, NULL, NULL);
10578 ok(server != -1, "failed to accept, error %u\n", WSAGetLastError());
10580 SetLastError(0xdeadbeef);
10581 ret = pDisconnectEx(client, &overlapped, 0, 0);
10582 ok(!ret, "expected failure\n");
10583 ok(GetLastError() == ERROR_IO_PENDING, "got error %lu\n", GetLastError());
10585 ret = WaitForSingleObject(overlapped.hEvent, 1000);
10586 ok(!ret, "wait failed\n");
10588 size = 0xdeadbeef;
10589 ret = GetOverlappedResult((HANDLE)client, &overlapped, &size, TRUE);
10590 ok(ret, "got error %lu\n", GetLastError());
10591 ok(!size, "got %lu bytes\n", size);
10593 size = 0xdeadbeef;
10594 key = 0xdeadbeef;
10595 overlapped_ptr = NULL;
10596 ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 0);
10597 todo_wine ok(ret, "got error %lu\n", GetLastError());
10598 todo_wine ok(!key, "got key %#Ix\n", key);
10599 todo_wine ok(!size, "got %lu bytes\n", size);
10600 todo_wine ok(overlapped_ptr == &overlapped, "got overlapped %p\n", overlapped_ptr);
10602 closesocket(server);
10603 closesocket(client);
10604 CloseHandle(port);
10606 /* Test passing a NULL overlapped structure to DisconnectEx(). */
10608 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
10609 ok(client != -1, "failed to create socket, error %u\n", WSAGetLastError());
10610 port = CreateIoCompletionPort((HANDLE)client, NULL, 0, 0);
10611 ok(!!port, "failed to create port, error %lu\n", GetLastError());
10612 ret = connect(client, (struct sockaddr *)&destaddr, sizeof(destaddr));
10613 ok(!ret, "failed to connect, error %u\n", WSAGetLastError());
10614 server = accept(listener, NULL, NULL);
10615 ok(server != -1, "failed to accept, error %u\n", WSAGetLastError());
10617 SetLastError(0xdeadbeef);
10618 ret = pDisconnectEx(client, NULL, 0, 0);
10619 ok(ret, "expected success\n");
10620 ok(!GetLastError() || GetLastError() == 0xdeadbeef /* < 7 */, "got error %lu\n", GetLastError());
10622 ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 0);
10623 ok(!ret, "expected failure\n");
10624 ok(GetLastError() == WAIT_TIMEOUT, "got error %lu\n", GetLastError());
10626 closesocket(server);
10627 closesocket(client);
10628 CloseHandle(port);
10630 /* Suppress completion by setting the low bit. */
10632 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
10633 ok(client != -1, "failed to create socket, error %u\n", WSAGetLastError());
10634 port = CreateIoCompletionPort((HANDLE)client, NULL, 0, 0);
10635 ok(!!port, "failed to create port, error %lu\n", GetLastError());
10636 ret = connect(client, (struct sockaddr *)&destaddr, sizeof(destaddr));
10637 ok(!ret, "failed to connect, error %u\n", WSAGetLastError());
10638 server = accept(listener, NULL, NULL);
10639 ok(server != -1, "failed to accept, error %u\n", WSAGetLastError());
10641 overlapped.hEvent = (HANDLE)((ULONG_PTR)overlapped.hEvent | 1);
10643 SetLastError(0xdeadbeef);
10644 ret = pDisconnectEx(client, &overlapped, 0, 0);
10645 ok(!ret, "expected failure\n");
10646 ok(GetLastError() == ERROR_IO_PENDING, "got error %lu\n", GetLastError());
10648 ret = WaitForSingleObject(overlapped.hEvent, 1000);
10649 ok(!ret, "wait failed\n");
10651 size = 0xdeadbeef;
10652 ret = GetOverlappedResult((HANDLE)client, &overlapped, &size, TRUE);
10653 ok(ret, "got error %lu\n", GetLastError());
10654 ok(!size, "got %lu bytes\n", size);
10656 ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 0);
10657 ok(!ret, "expected failure\n");
10658 ok(GetLastError() == WAIT_TIMEOUT, "got error %lu\n", GetLastError());
10660 closesocket(server);
10661 closesocket(client);
10662 CloseHandle(port);
10664 overlapped.hEvent = (HANDLE)((ULONG_PTR)overlapped.hEvent & ~1);
10666 CloseHandle(overlapped.hEvent);
10669 static void test_address_list_query(void)
10671 char buffer[1024];
10672 SOCKET_ADDRESS_LIST *address_list = (SOCKET_ADDRESS_LIST *)buffer;
10673 OVERLAPPED overlapped = {0}, *overlapped_ptr;
10674 DWORD size, expect_size;
10675 unsigned int i;
10676 ULONG_PTR key;
10677 HANDLE port;
10678 SOCKET s;
10679 int ret;
10681 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
10682 ok(s != INVALID_SOCKET, "Failed to create socket, error %d.\n", WSAGetLastError());
10683 port = CreateIoCompletionPort((HANDLE)s, NULL, 123, 0);
10685 size = 0;
10686 ret = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, NULL, 0, &size, NULL, NULL);
10687 ok(ret == SOCKET_ERROR, "Got unexpected ret %d.\n", ret);
10688 ok(WSAGetLastError() == WSAEFAULT, "Got unexpected error %d.\n", WSAGetLastError());
10689 ok(size >= FIELD_OFFSET(SOCKET_ADDRESS_LIST, Address[0]), "Got unexpected size %lu.\n", size);
10690 expect_size = size;
10692 size = 0;
10693 ret = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, buffer, sizeof(buffer), &size, NULL, NULL);
10694 ok(!ret, "Got unexpected ret %d.\n", ret);
10695 ok(!WSAGetLastError(), "Got unexpected error %d.\n", WSAGetLastError());
10696 ok(size == expect_size, "Expected size %lu, got %lu.\n", expect_size, size);
10698 expect_size = FIELD_OFFSET(SOCKET_ADDRESS_LIST, Address[address_list->iAddressCount]);
10699 for (i = 0; i < address_list->iAddressCount; ++i)
10701 expect_size += address_list->Address[i].iSockaddrLength;
10703 ok(size == expect_size, "Expected size %lu, got %lu.\n", expect_size, size);
10705 ret = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, buffer, sizeof(buffer), NULL, NULL, NULL);
10706 ok(ret == SOCKET_ERROR, "Got unexpected ret %d.\n", ret);
10707 ok(WSAGetLastError() == WSAEFAULT, "Got unexpected error %d.\n", WSAGetLastError());
10709 size = 0xdeadbeef;
10710 ret = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, NULL, sizeof(buffer), &size, NULL, NULL);
10711 ok(ret == SOCKET_ERROR, "Got unexpected ret %d.\n", ret);
10712 ok(WSAGetLastError() == WSAEFAULT, "Got unexpected error %d.\n", WSAGetLastError());
10713 ok(size == expect_size, "Expected size %lu, got %lu.\n", expect_size, size);
10715 size = 0xdeadbeef;
10716 ret = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, buffer, 0, &size, NULL, NULL);
10717 ok(ret == SOCKET_ERROR, "Got unexpected ret %d.\n", ret);
10718 ok(WSAGetLastError() == WSAEFAULT, "Got unexpected error %d.\n", WSAGetLastError());
10719 ok(size == expect_size, "Expected size %lu, got %lu.\n", expect_size, size);
10721 size = 0xdeadbeef;
10722 ret = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, buffer, 1, &size, NULL, NULL);
10723 ok(ret == SOCKET_ERROR, "Got unexpected ret %d.\n", ret);
10724 ok(WSAGetLastError() == WSAEINVAL, "Got unexpected error %d.\n", WSAGetLastError());
10725 ok(!size, "Got size %lu.\n", size);
10727 size = 0xdeadbeef;
10728 memset(buffer, 0xcc, sizeof(buffer));
10729 ret = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, buffer,
10730 FIELD_OFFSET(SOCKET_ADDRESS_LIST, Address[0]), &size, NULL, NULL);
10731 ok(ret == SOCKET_ERROR, "Got unexpected ret %d.\n", ret);
10732 ok(WSAGetLastError() == WSAEFAULT, "Got unexpected error %d.\n", WSAGetLastError());
10733 ok(size == expect_size, "Expected size %lu, got %lu.\n", expect_size, size);
10734 ok(address_list->iAddressCount == 0xcccccccc, "Got %u addresses.\n", address_list->iAddressCount);
10736 WSASetLastError(0xdeadbeef);
10737 overlapped.Internal = 0xdeadbeef;
10738 overlapped.InternalHigh = 0xdeadbeef;
10739 size = 0xdeadbeef;
10740 ret = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, buffer, 0, &size, &overlapped, NULL);
10741 ok(ret == -1, "Got unexpected ret %d.\n", ret);
10742 ok(WSAGetLastError() == WSAEFAULT, "Got unexpected error %d.\n", WSAGetLastError());
10743 ok(size == expect_size, "Expected size %lu, got %lu.\n", expect_size, size);
10744 ok(overlapped.Internal == 0xdeadbeef, "Got status %#lx.\n", (NTSTATUS)overlapped.Internal);
10745 ok(overlapped.InternalHigh == 0xdeadbeef, "Got size %Iu.\n", overlapped.InternalHigh);
10747 overlapped.Internal = 0xdeadbeef;
10748 overlapped.InternalHigh = 0xdeadbeef;
10749 size = 0xdeadbeef;
10750 ret = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, buffer, 1, &size, &overlapped, NULL);
10751 ok(ret == -1, "Got unexpected ret %d.\n", ret);
10752 ok(WSAGetLastError() == WSAEINVAL, "Got unexpected error %d.\n", WSAGetLastError());
10753 ok(!size, "Expected size %lu, got %lu.\n", expect_size, size);
10754 ok(overlapped.Internal == 0xdeadbeef, "Got status %#lx.\n", (NTSTATUS)overlapped.Internal);
10755 ok(overlapped.InternalHigh == 0xdeadbeef, "Got size %Iu.\n", overlapped.InternalHigh);
10757 overlapped.Internal = 0xdeadbeef;
10758 overlapped.InternalHigh = 0xdeadbeef;
10759 size = 0xdeadbeef;
10760 ret = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, buffer,
10761 FIELD_OFFSET(SOCKET_ADDRESS_LIST, Address[0]), &size, &overlapped, NULL);
10762 ok(ret == -1, "Got unexpected ret %d.\n", ret);
10763 ok(WSAGetLastError() == WSAEFAULT, "Got unexpected error %d.\n", WSAGetLastError());
10764 ok(size == expect_size, "Expected size %lu, got %lu.\n", expect_size, size);
10765 ok(overlapped.Internal == 0xdeadbeef, "Got status %#lx.\n", (NTSTATUS)overlapped.Internal);
10766 ok(overlapped.InternalHigh == 0xdeadbeef, "Got size %Iu.\n", overlapped.InternalHigh);
10767 ok(address_list->iAddressCount == 0xcccccccc, "Got %u addresses.\n", address_list->iAddressCount);
10769 overlapped.Internal = 0xdeadbeef;
10770 overlapped.InternalHigh = 0xdeadbeef;
10771 size = 0xdeadbeef;
10772 ret = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, buffer, sizeof(buffer), &size, &overlapped, NULL);
10773 ok(!ret, "Got unexpected ret %d.\n", ret);
10774 ok(!WSAGetLastError(), "Got unexpected error %d.\n", WSAGetLastError());
10775 ok(size == expect_size, "Expected size %lu, got %lu.\n", expect_size, size);
10777 ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 0);
10778 ok(ret, "Got error %lu.\n", GetLastError());
10779 ok(!size, "Got size %lu.\n", size);
10780 ok(overlapped_ptr == &overlapped, "Got overlapped %p.\n", overlapped_ptr);
10781 ok(!overlapped.Internal, "Got status %#lx.\n", (NTSTATUS)overlapped.Internal);
10782 ok(!overlapped.InternalHigh, "Got size %Iu.\n", overlapped.InternalHigh);
10784 ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 0);
10785 ok(!ret, "Expected failure.\n");
10786 ok(GetLastError() == WAIT_TIMEOUT, "Got error %lu.\n", GetLastError());
10788 closesocket(s);
10789 CloseHandle(port);
10791 /* Test with an APC. */
10793 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
10795 ret = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, buffer, sizeof(buffer), NULL, &overlapped, socket_apc);
10796 ok(ret == -1, "expected failure\n");
10797 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
10799 apc_count = 0;
10800 size = 0xdeadbeef;
10801 ret = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, buffer, sizeof(buffer), &size, &overlapped, socket_apc);
10802 ok(!ret, "expected success\n");
10803 ok(size == expect_size, "got size %lu\n", size);
10805 ret = SleepEx(0, TRUE);
10806 ok(ret == WAIT_IO_COMPLETION, "got %d\n", ret);
10807 ok(apc_count == 1, "APC was called %u times\n", apc_count);
10808 ok(!apc_error, "got APC error %lu\n", apc_error);
10809 ok(!apc_size, "got APC size %lu\n", apc_size);
10810 ok(apc_overlapped == &overlapped, "got APC overlapped %p\n", apc_overlapped);
10812 closesocket(s);
10815 static void sync_read(SOCKET src, SOCKET dst)
10817 int ret;
10818 char data[512];
10820 ret = send(dst, "Hello World!", 12, 0);
10821 ok(ret == 12, "send returned %d\n", ret);
10823 memset(data, 0, sizeof(data));
10824 ret = recv(src, data, sizeof(data), 0);
10825 ok(ret == 12, "expected 12, got %d\n", ret);
10826 ok(!memcmp(data, "Hello World!", 12), "got %u bytes (%*s)\n", ret, ret, data);
10829 static void iocp_async_read(SOCKET src, SOCKET dst)
10831 HANDLE port;
10832 WSAOVERLAPPED ovl, *ovl_iocp;
10833 WSABUF buf;
10834 int ret;
10835 char data[512];
10836 DWORD flags, bytes;
10837 ULONG_PTR key;
10839 memset(data, 0, sizeof(data));
10840 memset(&ovl, 0, sizeof(ovl));
10842 port = CreateIoCompletionPort((HANDLE)src, 0, 0x12345678, 0);
10843 ok(port != 0, "CreateIoCompletionPort error %lu\n", GetLastError());
10845 buf.len = sizeof(data);
10846 buf.buf = data;
10847 bytes = 0xdeadbeef;
10848 flags = 0;
10849 SetLastError(0xdeadbeef);
10850 ret = WSARecv(src, &buf, 1, &bytes, &flags, &ovl, NULL);
10851 ok(ret == SOCKET_ERROR, "got %d\n", ret);
10852 ok(GetLastError() == ERROR_IO_PENDING, "got %lu\n", GetLastError());
10853 ok(bytes == 0xdeadbeef, "got bytes %lu\n", bytes);
10855 bytes = 0xdeadbeef;
10856 key = 0xdeadbeef;
10857 ovl_iocp = (void *)0xdeadbeef;
10858 SetLastError(0xdeadbeef);
10859 ret = GetQueuedCompletionStatus(port, &bytes, &key, &ovl_iocp, 100);
10860 ok(!ret, "got %d\n", ret);
10861 ok(GetLastError() == WAIT_TIMEOUT, "got %lu\n", GetLastError());
10862 ok(bytes == 0xdeadbeef, "got bytes %lu\n", bytes);
10863 ok(key == 0xdeadbeef, "got key %#Ix\n", key);
10864 ok(!ovl_iocp, "got ovl %p\n", ovl_iocp);
10866 ret = send(dst, "Hello World!", 12, 0);
10867 ok(ret == 12, "send returned %d\n", ret);
10869 bytes = 0xdeadbeef;
10870 key = 0xdeadbeef;
10871 ovl_iocp = NULL;
10872 SetLastError(0xdeadbeef);
10873 ret = GetQueuedCompletionStatus(port, &bytes, &key, &ovl_iocp, 100);
10874 ok(ret, "got %d\n", ret);
10875 ok(bytes == 12, "got bytes %lu\n", bytes);
10876 ok(key == 0x12345678, "got key %#Ix\n", key);
10877 ok(ovl_iocp == &ovl, "got ovl %p\n", ovl_iocp);
10878 if (ovl_iocp)
10880 ok(ovl_iocp->InternalHigh == 12, "got %#Ix\n", ovl_iocp->InternalHigh);
10881 ok(!ovl_iocp->Internal , "got %#Ix\n", ovl_iocp->Internal);
10882 ok(!memcmp(data, "Hello World!", 12), "got %lu bytes (%*s)\n", bytes, (int)bytes, data);
10885 bytes = 0xdeadbeef;
10886 key = 0xdeadbeef;
10887 ovl_iocp = (void *)0xdeadbeef;
10888 SetLastError(0xdeadbeef);
10889 ret = GetQueuedCompletionStatus(port, &bytes, &key, &ovl_iocp, 100);
10890 ok(!ret, "got %d\n", ret);
10891 ok(GetLastError() == WAIT_TIMEOUT, "got %lu\n", GetLastError());
10892 ok(bytes == 0xdeadbeef, "got bytes %lu\n", bytes);
10893 ok(key == 0xdeadbeef, "got key %#Ix\n", key);
10894 ok(!ovl_iocp, "got ovl %p\n", ovl_iocp);
10896 CloseHandle(port);
10899 static void iocp_async_read_closesocket(SOCKET src, int how_to_close)
10901 HANDLE port;
10902 WSAOVERLAPPED ovl, *ovl_iocp;
10903 WSABUF buf;
10904 int ret;
10905 char data[512];
10906 DWORD flags, bytes;
10907 ULONG_PTR key;
10908 HWND hwnd;
10909 MSG msg;
10911 hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP,
10912 0, 0, 0, 0, NULL, NULL, 0, NULL);
10913 ok(hwnd != 0, "CreateWindowEx failed\n");
10915 ret = WSAAsyncSelect(src, hwnd, WM_SOCKET, FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE);
10916 ok(!ret, "got %d\n", ret);
10918 Sleep(100);
10919 memset(&msg, 0, sizeof(msg));
10920 ret = PeekMessageA(&msg, hwnd, WM_SOCKET, WM_SOCKET, PM_REMOVE);
10921 ok(ret, "got %d\n", ret);
10922 ok(msg.hwnd == hwnd, "got %p\n", msg.hwnd);
10923 ok(msg.message == WM_SOCKET, "got %04x\n", msg.message);
10924 ok(msg.wParam == src, "got %08Ix\n", msg.wParam);
10925 ok(msg.lParam == 2, "got %08Ix\n", msg.lParam);
10927 memset(data, 0, sizeof(data));
10928 memset(&ovl, 0, sizeof(ovl));
10930 port = CreateIoCompletionPort((HANDLE)src, 0, 0x12345678, 0);
10931 ok(port != 0, "CreateIoCompletionPort error %lu\n", GetLastError());
10933 Sleep(100);
10934 ret = PeekMessageA(&msg, hwnd, WM_SOCKET, WM_SOCKET, PM_REMOVE);
10935 ok(!ret, "got %04x,%08Ix,%08Ix\n", msg.message, msg.wParam, msg.lParam);
10937 buf.len = sizeof(data);
10938 buf.buf = data;
10939 bytes = 0xdeadbeef;
10940 flags = 0;
10941 SetLastError(0xdeadbeef);
10942 ret = WSARecv(src, &buf, 1, &bytes, &flags, &ovl, NULL);
10943 ok(ret == SOCKET_ERROR, "got %d\n", ret);
10944 ok(GetLastError() == ERROR_IO_PENDING, "got %lu\n", GetLastError());
10945 ok(bytes == 0xdeadbeef, "got bytes %lu\n", bytes);
10947 Sleep(100);
10948 ret = PeekMessageA(&msg, hwnd, WM_SOCKET, WM_SOCKET, PM_REMOVE);
10949 ok(!ret, "got %04x,%08Ix,%08Ix\n", msg.message, msg.wParam, msg.lParam);
10951 bytes = 0xdeadbeef;
10952 key = 0xdeadbeef;
10953 ovl_iocp = (void *)0xdeadbeef;
10954 SetLastError(0xdeadbeef);
10955 ret = GetQueuedCompletionStatus(port, &bytes, &key, &ovl_iocp, 100);
10956 ok(!ret, "got %d\n", ret);
10957 ok(GetLastError() == WAIT_TIMEOUT, "got %lu\n", GetLastError());
10958 ok(bytes == 0xdeadbeef, "got bytes %lu\n", bytes);
10959 ok(key == 0xdeadbeef, "got key %#Ix\n", key);
10960 ok(!ovl_iocp, "got ovl %p\n", ovl_iocp);
10962 Sleep(100);
10963 ret = PeekMessageA(&msg, hwnd, WM_SOCKET, WM_SOCKET, PM_REMOVE);
10964 ok(!ret, "got %04x,%08Ix,%08Ix\n", msg.message, msg.wParam, msg.lParam);
10966 switch (how_to_close)
10968 case 0:
10969 closesocket(src);
10970 break;
10971 case 1:
10972 CloseHandle((HANDLE)src);
10973 break;
10974 case 2:
10975 pNtClose((HANDLE)src);
10976 break;
10977 default:
10978 ok(0, "wrong value %d\n", how_to_close);
10979 break;
10982 Sleep(200);
10983 memset(&msg, 0, sizeof(msg));
10984 ret = PeekMessageA(&msg, hwnd, WM_SOCKET, WM_SOCKET, PM_REMOVE);
10985 switch (how_to_close)
10987 case 0:
10988 ok(!ret, "got %04x,%08Ix,%08Ix\n", msg.message, msg.wParam, msg.lParam);
10989 break;
10990 case 1:
10991 case 2:
10992 todo_wine
10994 ok(ret, "got %d\n", ret);
10995 ok(msg.hwnd == hwnd, "got %p\n", msg.hwnd);
10996 ok(msg.message == WM_SOCKET, "got %04x\n", msg.message);
10997 ok(msg.wParam == src, "got %08Ix\n", msg.wParam);
10998 ok(msg.lParam == 0x20, "got %08Ix\n", msg.lParam);
11000 break;
11001 default:
11002 ok(0, "wrong value %d\n", how_to_close);
11003 break;
11006 bytes = 0xdeadbeef;
11007 key = 0xdeadbeef;
11008 ovl_iocp = NULL;
11009 SetLastError(0xdeadbeef);
11010 ret = GetQueuedCompletionStatus(port, &bytes, &key, &ovl_iocp, 100);
11011 ok(!ret, "got %d\n", ret);
11012 todo_wine
11013 ok(GetLastError() == ERROR_CONNECTION_ABORTED || GetLastError() == ERROR_NETNAME_DELETED /* XP */, "got %lu\n", GetLastError());
11014 ok(!bytes, "got bytes %lu\n", bytes);
11015 ok(key == 0x12345678, "got key %#Ix\n", key);
11016 ok(ovl_iocp == &ovl, "got ovl %p\n", ovl_iocp);
11017 if (ovl_iocp)
11019 ok(!ovl_iocp->InternalHigh, "got %#Ix\n", ovl_iocp->InternalHigh);
11020 todo_wine
11021 ok(ovl_iocp->Internal == (ULONG)STATUS_CONNECTION_ABORTED || ovl_iocp->Internal == (ULONG)STATUS_LOCAL_DISCONNECT /* XP */, "got %#Ix\n", ovl_iocp->Internal);
11024 bytes = 0xdeadbeef;
11025 key = 0xdeadbeef;
11026 ovl_iocp = (void *)0xdeadbeef;
11027 SetLastError(0xdeadbeef);
11028 ret = GetQueuedCompletionStatus(port, &bytes, &key, &ovl_iocp, 100);
11029 ok(!ret, "got %d\n", ret);
11030 ok(GetLastError() == WAIT_TIMEOUT, "got %lu\n", GetLastError());
11031 ok(bytes == 0xdeadbeef, "got bytes %lu\n", bytes);
11032 ok(key == 0xdeadbeef, "got key %#Ix\n", key);
11033 ok(!ovl_iocp, "got ovl %p\n", ovl_iocp);
11035 CloseHandle(port);
11037 DestroyWindow(hwnd);
11040 static void iocp_async_closesocket(SOCKET src)
11042 HANDLE port;
11043 WSAOVERLAPPED *ovl_iocp;
11044 int ret;
11045 DWORD bytes;
11046 ULONG_PTR key;
11047 HWND hwnd;
11048 MSG msg;
11050 hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP,
11051 0, 0, 0, 0, NULL, NULL, 0, NULL);
11052 ok(hwnd != 0, "CreateWindowEx failed\n");
11054 ret = WSAAsyncSelect(src, hwnd, WM_SOCKET, FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE);
11055 ok(!ret, "got %d\n", ret);
11057 Sleep(100);
11058 memset(&msg, 0, sizeof(msg));
11059 ret = PeekMessageA(&msg, hwnd, WM_SOCKET, WM_SOCKET, PM_REMOVE);
11060 ok(ret, "got %d\n", ret);
11061 ok(msg.hwnd == hwnd, "got %p\n", msg.hwnd);
11062 ok(msg.message == WM_SOCKET, "got %04x\n", msg.message);
11063 ok(msg.wParam == src, "got %08Ix\n", msg.wParam);
11064 ok(msg.lParam == 2, "got %08Ix\n", msg.lParam);
11066 port = CreateIoCompletionPort((HANDLE)src, 0, 0x12345678, 0);
11067 ok(port != 0, "CreateIoCompletionPort error %lu\n", GetLastError());
11069 Sleep(100);
11070 ret = PeekMessageA(&msg, hwnd, WM_SOCKET, WM_SOCKET, PM_REMOVE);
11071 ok(!ret, "got %04x,%08Ix,%08Ix\n", msg.message, msg.wParam, msg.lParam);
11073 bytes = 0xdeadbeef;
11074 key = 0xdeadbeef;
11075 ovl_iocp = (void *)0xdeadbeef;
11076 SetLastError(0xdeadbeef);
11077 ret = GetQueuedCompletionStatus(port, &bytes, &key, &ovl_iocp, 100);
11078 ok(!ret, "got %d\n", ret);
11079 ok(GetLastError() == WAIT_TIMEOUT, "got %lu\n", GetLastError());
11080 ok(bytes == 0xdeadbeef, "got bytes %lu\n", bytes);
11081 ok(key == 0xdeadbeef, "got key %Iu\n", key);
11082 ok(!ovl_iocp, "got ovl %p\n", ovl_iocp);
11084 Sleep(100);
11085 ret = PeekMessageA(&msg, hwnd, WM_SOCKET, WM_SOCKET, PM_REMOVE);
11086 ok(!ret, "got %04x,%08Ix,%08Ix\n", msg.message, msg.wParam, msg.lParam);
11088 closesocket(src);
11090 Sleep(100);
11091 memset(&msg, 0, sizeof(msg));
11092 ret = PeekMessageA(&msg, hwnd, WM_SOCKET, WM_SOCKET, PM_REMOVE);
11093 ok(!ret, "got %04x,%08Ix,%08Ix\n", msg.message, msg.wParam, msg.lParam);
11095 bytes = 0xdeadbeef;
11096 key = 0xdeadbeef;
11097 ovl_iocp = (void *)0xdeadbeef;
11098 SetLastError(0xdeadbeef);
11099 ret = GetQueuedCompletionStatus(port, &bytes, &key, &ovl_iocp, 100);
11100 ok(!ret, "got %d\n", ret);
11101 ok(GetLastError() == WAIT_TIMEOUT, "got %lu\n", GetLastError());
11102 ok(bytes == 0xdeadbeef, "got bytes %lu\n", bytes);
11103 ok(key == 0xdeadbeef, "got key %Iu\n", key);
11104 ok(!ovl_iocp, "got ovl %p\n", ovl_iocp);
11106 CloseHandle(port);
11108 DestroyWindow(hwnd);
11111 struct wsa_async_select_info
11113 SOCKET sock;
11114 HWND hwnd;
11117 static DWORD WINAPI wsa_async_select_thread(void *param)
11119 struct wsa_async_select_info *info = param;
11120 int ret;
11122 ret = WSAAsyncSelect(info->sock, info->hwnd, WM_SOCKET, FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE);
11123 ok(!ret, "got %d\n", ret);
11125 return 0;
11128 struct wsa_recv_info
11130 SOCKET sock;
11131 WSABUF wsa_buf;
11132 WSAOVERLAPPED ovl;
11135 static DWORD WINAPI wsa_recv_thread(void *param)
11137 struct wsa_recv_info *info = param;
11138 int ret;
11139 DWORD flags, bytes;
11141 bytes = 0xdeadbeef;
11142 flags = 0;
11143 SetLastError(0xdeadbeef);
11144 ret = WSARecv(info->sock, &info->wsa_buf, 1, &bytes, &flags, &info->ovl, NULL);
11145 ok(ret == SOCKET_ERROR, "got %d\n", ret);
11146 ok(GetLastError() == ERROR_IO_PENDING, "got %lu\n", GetLastError());
11147 ok(bytes == 0xdeadbeef, "got bytes %lu\n", bytes);
11149 return 0;
11152 static void iocp_async_read_thread_closesocket(SOCKET src)
11154 struct wsa_async_select_info select_info;
11155 struct wsa_recv_info recv_info;
11156 HANDLE port, thread;
11157 WSAOVERLAPPED *ovl_iocp;
11158 int ret;
11159 char data[512];
11160 DWORD bytes, tid;
11161 ULONG_PTR key;
11162 HWND hwnd;
11163 MSG msg;
11165 hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP,
11166 0, 0, 0, 0, NULL, NULL, 0, NULL);
11167 ok(hwnd != 0, "CreateWindowEx failed\n");
11169 select_info.sock = src;
11170 select_info.hwnd = hwnd;
11171 thread = CreateThread(NULL, 0, wsa_async_select_thread, &select_info, 0, &tid);
11172 ok(thread != 0, "CreateThread error %lu\n", GetLastError());
11173 ret = WaitForSingleObject(thread, 10000);
11174 ok(ret == WAIT_OBJECT_0, "thread failed to terminate\n");
11176 Sleep(100);
11177 memset(&msg, 0, sizeof(msg));
11178 ret = PeekMessageA(&msg, hwnd, WM_SOCKET, WM_SOCKET, PM_REMOVE);
11179 ok(ret, "got %d\n", ret);
11180 ok(msg.hwnd == hwnd, "got %p\n", msg.hwnd);
11181 ok(msg.message == WM_SOCKET, "got %04x\n", msg.message);
11182 ok(msg.wParam == src, "got %08Ix\n", msg.wParam);
11183 ok(msg.lParam == 2, "got %08Ix\n", msg.lParam);
11185 port = CreateIoCompletionPort((HANDLE)src, 0, 0x12345678, 0);
11186 ok(port != 0, "CreateIoCompletionPort error %lu\n", GetLastError());
11188 Sleep(100);
11189 ret = PeekMessageA(&msg, hwnd, WM_SOCKET, WM_SOCKET, PM_REMOVE);
11190 ok(!ret, "got %04x,%08Ix,%08Ix\n", msg.message, msg.wParam, msg.lParam);
11192 memset(data, 0, sizeof(data));
11193 memset(&recv_info.ovl, 0, sizeof(recv_info.ovl));
11194 recv_info.sock = src;
11195 recv_info.wsa_buf.len = sizeof(data);
11196 recv_info.wsa_buf.buf = data;
11197 thread = CreateThread(NULL, 0, wsa_recv_thread, &recv_info, 0, &tid);
11198 ok(thread != 0, "CreateThread error %lu\n", GetLastError());
11199 ret = WaitForSingleObject(thread, 10000);
11200 ok(ret == WAIT_OBJECT_0, "thread failed to terminate\n");
11202 Sleep(100);
11203 ret = PeekMessageA(&msg, hwnd, WM_SOCKET, WM_SOCKET, PM_REMOVE);
11204 ok(!ret, "got %04x,%08Ix,%08Ix\n", msg.message, msg.wParam, msg.lParam);
11206 bytes = 0xdeadbeef;
11207 key = 0xdeadbeef;
11208 ovl_iocp = (void *)0xdeadbeef;
11209 SetLastError(0xdeadbeef);
11210 ret = GetQueuedCompletionStatus(port, &bytes, &key, &ovl_iocp, 100);
11211 ok(!ret, "got %d\n", ret);
11212 ok(GetLastError() == WAIT_TIMEOUT || broken(GetLastError() == ERROR_OPERATION_ABORTED) /* XP */,
11213 "got %lu\n", GetLastError());
11214 if (GetLastError() == WAIT_TIMEOUT)
11216 ok(bytes == 0xdeadbeef, "got bytes %lu\n", bytes);
11217 ok(key == 0xdeadbeef, "got key %Ix\n", key);
11218 ok(!ovl_iocp, "got ovl %p\n", ovl_iocp);
11220 else /* document XP behaviour */
11222 ok(!bytes, "got bytes %lu\n", bytes);
11223 ok(key == 0x12345678, "got key %#Ix\n", key);
11224 ok(ovl_iocp == &recv_info.ovl, "got ovl %p\n", ovl_iocp);
11225 if (ovl_iocp)
11227 ok(!ovl_iocp->InternalHigh, "got %#Ix\n", ovl_iocp->InternalHigh);
11228 ok(ovl_iocp->Internal == STATUS_CANCELLED, "got %#Ix\n", ovl_iocp->Internal);
11231 closesocket(src);
11232 goto xp_is_broken;
11235 Sleep(100);
11236 ret = PeekMessageA(&msg, hwnd, WM_SOCKET, WM_SOCKET, PM_REMOVE);
11237 ok(!ret, "got %04x,%08Ix,%08Ix\n", msg.message, msg.wParam, msg.lParam);
11239 closesocket(src);
11241 Sleep(100);
11242 ret = PeekMessageA(&msg, hwnd, WM_SOCKET, WM_SOCKET, PM_REMOVE);
11243 ok(!ret, "got %04x,%08Ix,%08Ix\n", msg.message, msg.wParam, msg.lParam);
11245 bytes = 0xdeadbeef;
11246 key = 0xdeadbeef;
11247 ovl_iocp = NULL;
11248 SetLastError(0xdeadbeef);
11249 ret = GetQueuedCompletionStatus(port, &bytes, &key, &ovl_iocp, 100);
11250 ok(!ret, "got %d\n", ret);
11251 todo_wine
11252 ok(GetLastError() == ERROR_CONNECTION_ABORTED || GetLastError() == ERROR_NETNAME_DELETED /* XP */, "got %lu\n", GetLastError());
11253 ok(!bytes, "got bytes %lu\n", bytes);
11254 ok(key == 0x12345678, "got key %#Ix\n", key);
11255 ok(ovl_iocp == &recv_info.ovl, "got ovl %p\n", ovl_iocp);
11256 if (ovl_iocp)
11258 ok(!ovl_iocp->InternalHigh, "got %#Ix\n", ovl_iocp->InternalHigh);
11259 todo_wine
11260 ok(ovl_iocp->Internal == (ULONG)STATUS_CONNECTION_ABORTED || ovl_iocp->Internal == (ULONG)STATUS_LOCAL_DISCONNECT /* XP */, "got %#Ix\n", ovl_iocp->Internal);
11263 xp_is_broken:
11264 bytes = 0xdeadbeef;
11265 key = 0xdeadbeef;
11266 ovl_iocp = (void *)0xdeadbeef;
11267 SetLastError(0xdeadbeef);
11268 ret = GetQueuedCompletionStatus(port, &bytes, &key, &ovl_iocp, 100);
11269 ok(!ret, "got %d\n", ret);
11270 ok(GetLastError() == WAIT_TIMEOUT, "got %lu\n", GetLastError());
11271 ok(bytes == 0xdeadbeef, "got bytes %lu\n", bytes);
11272 ok(key == 0xdeadbeef, "got key %Iu\n", key);
11273 ok(!ovl_iocp, "got ovl %p\n", ovl_iocp);
11275 CloseHandle(port);
11277 DestroyWindow(hwnd);
11280 static void iocp_async_read_thread(SOCKET src, SOCKET dst)
11282 struct wsa_async_select_info select_info;
11283 struct wsa_recv_info recv_info;
11284 HANDLE port, thread;
11285 WSAOVERLAPPED *ovl_iocp;
11286 int ret;
11287 char data[512];
11288 DWORD bytes, tid;
11289 ULONG_PTR key;
11290 HWND hwnd;
11291 MSG msg;
11293 hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP,
11294 0, 0, 0, 0, NULL, NULL, 0, NULL);
11295 ok(hwnd != 0, "CreateWindowEx failed\n");
11297 select_info.sock = src;
11298 select_info.hwnd = hwnd;
11299 thread = CreateThread(NULL, 0, wsa_async_select_thread, &select_info, 0, &tid);
11300 ok(thread != 0, "CreateThread error %lu\n", GetLastError());
11301 ret = WaitForSingleObject(thread, 10000);
11302 ok(ret == WAIT_OBJECT_0, "thread failed to terminate\n");
11304 Sleep(100);
11305 memset(&msg, 0, sizeof(msg));
11306 ret = PeekMessageA(&msg, hwnd, WM_SOCKET, WM_SOCKET, PM_REMOVE);
11307 ok(ret, "got %d\n", ret);
11308 ok(msg.hwnd == hwnd, "got %p\n", msg.hwnd);
11309 ok(msg.message == WM_SOCKET, "got %04x\n", msg.message);
11310 ok(msg.wParam == src, "got %08Ix\n", msg.wParam);
11311 ok(msg.lParam == 2, "got %08Ix\n", msg.lParam);
11313 port = CreateIoCompletionPort((HANDLE)src, 0, 0x12345678, 0);
11314 ok(port != 0, "CreateIoCompletionPort error %lu\n", GetLastError());
11316 Sleep(100);
11317 ret = PeekMessageA(&msg, hwnd, WM_SOCKET, WM_SOCKET, PM_REMOVE);
11318 ok(!ret, "got %04x,%08Ix,%08Ix\n", msg.message, msg.wParam, msg.lParam);
11320 memset(data, 0, sizeof(data));
11321 memset(&recv_info.ovl, 0, sizeof(recv_info.ovl));
11322 recv_info.sock = src;
11323 recv_info.wsa_buf.len = sizeof(data);
11324 recv_info.wsa_buf.buf = data;
11325 thread = CreateThread(NULL, 0, wsa_recv_thread, &recv_info, 0, &tid);
11326 ok(thread != 0, "CreateThread error %lu\n", GetLastError());
11327 ret = WaitForSingleObject(thread, 10000);
11328 ok(ret == WAIT_OBJECT_0, "thread failed to terminate\n");
11330 Sleep(100);
11331 ret = PeekMessageA(&msg, hwnd, WM_SOCKET, WM_SOCKET, PM_REMOVE);
11332 ok(!ret, "got %04x,%08Ix,%08Ix\n", msg.message, msg.wParam, msg.lParam);
11334 bytes = 0xdeadbeef;
11335 key = 0xdeadbeef;
11336 ovl_iocp = (void *)0xdeadbeef;
11337 SetLastError(0xdeadbeef);
11338 ret = GetQueuedCompletionStatus(port, &bytes, &key, &ovl_iocp, 100);
11339 ok(!ret, "got %d\n", ret);
11340 ok(GetLastError() == WAIT_TIMEOUT || broken(GetLastError() == ERROR_OPERATION_ABORTED) /* XP */, "got %lu\n", GetLastError());
11341 if (GetLastError() == WAIT_TIMEOUT)
11343 ok(bytes == 0xdeadbeef, "got bytes %lu\n", bytes);
11344 ok(key == 0xdeadbeef, "got key %Iu\n", key);
11345 ok(!ovl_iocp, "got ovl %p\n", ovl_iocp);
11347 else /* document XP behaviour */
11349 ok(bytes == 0, "got bytes %lu\n", bytes);
11350 ok(key == 0x12345678, "got key %#Ix\n", key);
11351 ok(ovl_iocp == &recv_info.ovl, "got ovl %p\n", ovl_iocp);
11352 if (ovl_iocp)
11354 ok(!ovl_iocp->InternalHigh, "got %#Ix\n", ovl_iocp->InternalHigh);
11355 ok(ovl_iocp->Internal == STATUS_CANCELLED, "got %#Ix\n", ovl_iocp->Internal);
11359 Sleep(100);
11360 memset(&msg, 0, sizeof(msg));
11361 ret = PeekMessageA(&msg, hwnd, WM_SOCKET, WM_SOCKET, PM_REMOVE);
11362 ok(!ret || broken(msg.hwnd == hwnd) /* XP */, "got %04x,%08Ix,%08Ix\n", msg.message, msg.wParam, msg.lParam);
11363 if (ret) /* document XP behaviour */
11365 ok(msg.message == WM_SOCKET, "got %04x\n", msg.message);
11366 ok(msg.wParam == src, "got %08Ix\n", msg.wParam);
11367 ok(msg.lParam == 1, "got %08Ix\n", msg.lParam);
11370 ret = send(dst, "Hello World!", 12, 0);
11371 ok(ret == 12, "send returned %d\n", ret);
11373 Sleep(100);
11374 memset(&msg, 0, sizeof(msg));
11375 ret = PeekMessageA(&msg, hwnd, WM_SOCKET, WM_SOCKET, PM_REMOVE);
11376 ok(!ret || broken(msg.hwnd == hwnd) /* XP */, "got %04x,%08Ix,%08Ix\n", msg.message, msg.wParam, msg.lParam);
11377 if (ret) /* document XP behaviour */
11379 ok(msg.hwnd == hwnd, "got %p\n", msg.hwnd);
11380 ok(msg.message == WM_SOCKET, "got %04x\n", msg.message);
11381 ok(msg.wParam == src, "got %08Ix\n", msg.wParam);
11382 ok(msg.lParam == 1, "got %08Ix\n", msg.lParam);
11385 bytes = 0xdeadbeef;
11386 key = 0xdeadbeef;
11387 ovl_iocp = (void *)0xdeadbeef;
11388 SetLastError(0xdeadbeef);
11389 ret = GetQueuedCompletionStatus(port, &bytes, &key, &ovl_iocp, 100);
11390 ok(ret || broken(GetLastError() == WAIT_TIMEOUT) /* XP */, "got %lu\n", GetLastError());
11391 if (ret)
11393 ok(bytes == 12, "got bytes %lu\n", bytes);
11394 ok(key == 0x12345678, "got key %#Ix\n", key);
11395 ok(ovl_iocp == &recv_info.ovl, "got ovl %p\n", ovl_iocp);
11396 if (ovl_iocp)
11398 ok(ovl_iocp->InternalHigh == 12, "got %#Ix\n", ovl_iocp->InternalHigh);
11399 ok(!ovl_iocp->Internal , "got %#Ix\n", ovl_iocp->Internal);
11400 ok(!memcmp(data, "Hello World!", 12), "got %lu bytes (%*s)\n", bytes, (int)bytes, data);
11403 else /* document XP behaviour */
11405 ok(bytes == 0xdeadbeef, "got bytes %lu\n", bytes);
11406 ok(key == 0xdeadbeef, "got key %Iu\n", key);
11407 ok(!ovl_iocp, "got ovl %p\n", ovl_iocp);
11410 CloseHandle(port);
11412 DestroyWindow(hwnd);
11415 static void test_iocp(void)
11417 SOCKET src, dst;
11418 int i;
11420 tcp_socketpair(&src, &dst);
11421 sync_read(src, dst);
11422 iocp_async_read(src, dst);
11423 closesocket(src);
11424 closesocket(dst);
11426 tcp_socketpair(&src, &dst);
11427 iocp_async_read_thread(src, dst);
11428 closesocket(src);
11429 closesocket(dst);
11431 for (i = 0; i <= 2; i++)
11433 tcp_socketpair(&src, &dst);
11434 iocp_async_read_closesocket(src, i);
11435 closesocket(dst);
11438 tcp_socketpair(&src, &dst);
11439 iocp_async_closesocket(src);
11440 closesocket(dst);
11442 tcp_socketpair(&src, &dst);
11443 iocp_async_read_thread_closesocket(src);
11444 closesocket(dst);
11447 static void test_get_interface_list(void)
11449 OVERLAPPED overlapped = {0}, *overlapped_ptr;
11450 DWORD size, expect_size;
11451 unsigned int i, count;
11452 INTERFACE_INFO *info;
11453 BOOL loopback_found;
11454 char buffer[4096];
11455 ULONG_PTR key;
11456 HANDLE port;
11457 SOCKET s;
11458 int ret;
11460 s = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
11461 ok(s != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
11462 port = CreateIoCompletionPort((HANDLE)s, NULL, 123, 0);
11464 size = 0xdeadbeef;
11465 WSASetLastError(0xdeadbeef);
11466 ret = WSAIoctl(s, SIO_GET_INTERFACE_LIST, NULL, 0, buffer, sizeof(buffer), &size, NULL, NULL);
11467 ok(!ret, "Got unexpected ret %d.\n", ret);
11468 ok(!WSAGetLastError(), "Got error %u.\n", WSAGetLastError());
11469 ok(size && size != 0xdeadbeef && !(size % sizeof(INTERFACE_INFO)), "Got unexpected size %lu.\n", size);
11470 expect_size = size;
11472 size = 0xdeadbeef;
11473 overlapped.Internal = 0xdeadbeef;
11474 overlapped.InternalHigh = 0xdeadbeef;
11475 ret = WSAIoctl(s, SIO_GET_INTERFACE_LIST, NULL, 0, buffer, sizeof(buffer), &size, &overlapped, NULL);
11476 ok(ret == -1, "Got unexpected ret %d.\n", ret);
11477 ok(WSAGetLastError() == ERROR_IO_PENDING, "Got error %u.\n", WSAGetLastError());
11478 ok(size == 0xdeadbeef, "Got size %lu.\n", size);
11480 ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 100);
11481 ok(ret, "Got error %lu.\n", GetLastError());
11482 ok(size == expect_size, "Expected size %lu, got %lu.\n", expect_size, size);
11483 ok(key == 123, "Got key %Iu.\n", key);
11484 ok(overlapped_ptr == &overlapped, "Got overlapped %p.\n", overlapped_ptr);
11485 ok(!overlapped.Internal, "Got status %#lx.\n", (NTSTATUS)overlapped.Internal);
11486 ok(overlapped.InternalHigh == expect_size, "Expected size %lu, got %Iu.\n", expect_size, overlapped.InternalHigh);
11488 info = (INTERFACE_INFO *)buffer;
11489 count = size / sizeof(INTERFACE_INFO);
11490 loopback_found = FALSE;
11491 for (i = 0; i < count; ++i)
11493 if (info[i].iiFlags & IFF_LOOPBACK)
11494 loopback_found = TRUE;
11496 ok(info[i].iiAddress.AddressIn.sin_family == AF_INET, "Got unexpected sin_family %#x.\n",
11497 info[i].iiAddress.AddressIn.sin_family);
11498 ok(info[i].iiNetmask.AddressIn.sin_family == AF_INET, "Got unexpected sin_family %#x.\n",
11499 info[i].iiNetmask.AddressIn.sin_family);
11500 ok(info[i].iiBroadcastAddress.AddressIn.sin_family
11501 == (info[i].iiFlags & IFF_BROADCAST) ? AF_INET : 0, "Got unexpected sin_family %#x.\n",
11502 info[i].iiBroadcastAddress.AddressIn.sin_family);
11503 ok(info[i].iiAddress.AddressIn.sin_addr.S_un.S_addr, "Got zero iiAddress.\n");
11504 ok(info[i].iiNetmask.AddressIn.sin_addr.S_un.S_addr, "Got zero iiNetmask.\n");
11505 ok((info[i].iiFlags & IFF_BROADCAST) ? info[i].iiBroadcastAddress.AddressIn.sin_addr.S_un.S_addr
11506 : !info[i].iiBroadcastAddress.AddressIn.sin_addr.S_un.S_addr,
11507 "Got unexpected iiBroadcastAddress %s.\n", inet_ntoa(info[i].iiBroadcastAddress.AddressIn.sin_addr));
11510 ok(loopback_found, "Loopback interface not found.\n");
11512 size = 0xdeadbeef;
11513 ret = WSAIoctl(s, SIO_GET_INTERFACE_LIST, NULL, 0, buffer, sizeof(INTERFACE_INFO) - 1, &size, NULL, NULL);
11514 ok(ret == -1, "Got unexpected ret %d.\n", ret);
11515 ok(WSAGetLastError() == WSAEFAULT, "Got unexpected error %d.\n", WSAGetLastError());
11516 ok(!size, "Got unexpected size %lu.\n", size);
11518 size = 0xdeadbeef;
11519 overlapped.Internal = 0xdeadbeef;
11520 overlapped.InternalHigh = 0xdeadbeef;
11521 ret = WSAIoctl(s, SIO_GET_INTERFACE_LIST, NULL, 0, buffer, sizeof(INTERFACE_INFO) - 1, &size, &overlapped, NULL);
11522 ok(ret == -1, "Got unexpected ret %d.\n", ret);
11523 ok(WSAGetLastError() == ERROR_IO_PENDING, "Got error %u.\n", WSAGetLastError());
11524 ok(size == 0xdeadbeef, "Got size %lu.\n", size);
11526 ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 100);
11527 ok(!ret, "Expected failure.\n");
11528 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Got error %lu.\n", GetLastError());
11529 ok(!size, "Got size %lu.\n", size);
11530 ok(key == 123, "Got key %Iu.\n", key);
11531 ok(overlapped_ptr == &overlapped, "Got overlapped %p.\n", overlapped_ptr);
11532 ok((NTSTATUS)overlapped.Internal == STATUS_BUFFER_TOO_SMALL, "Got status %#lx.\n", (NTSTATUS)overlapped.Internal);
11533 ok(!overlapped.InternalHigh, "Got size %Iu.\n", overlapped.InternalHigh);
11535 ret = WSAIoctl(s, SIO_GET_INTERFACE_LIST, NULL, 0, buffer, sizeof(buffer), NULL, NULL, NULL);
11536 ok(ret == -1, "Got unexpected ret %d.\n", ret);
11537 ok(WSAGetLastError() == WSAEFAULT, "Got unexpected error %d.\n", WSAGetLastError());
11539 CloseHandle(port);
11540 closesocket(s);
11542 /* Test with an APC. */
11544 s = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
11545 ok(s != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
11547 size = 0xdeadbeef;
11548 apc_count = 0;
11549 ret = WSAIoctl(s, SIO_GET_INTERFACE_LIST, NULL, 0, buffer,
11550 sizeof(INTERFACE_INFO) - 1, &size, &overlapped, socket_apc);
11551 ok(ret == -1, "Got unexpected ret %d.\n", ret);
11552 ok(WSAGetLastError() == ERROR_IO_PENDING, "Got error %u.\n", WSAGetLastError());
11553 ok(size == 0xdeadbeef, "Got size %lu.\n", size);
11555 ret = SleepEx(100, TRUE);
11556 ok(ret == WAIT_IO_COMPLETION, "got %d\n", ret);
11557 ok(apc_count == 1, "APC was called %u times\n", apc_count);
11558 ok(apc_error == WSAEFAULT, "got APC error %lu\n", apc_error);
11559 ok(!apc_size, "got APC size %lu\n", apc_size);
11560 ok(apc_overlapped == &overlapped, "got APC overlapped %p\n", apc_overlapped);
11562 closesocket(s);
11565 static void test_bind(void)
11567 const struct sockaddr_in invalid_addr = {.sin_family = AF_INET, .sin_addr.s_addr = inet_addr("192.0.2.0")};
11568 const struct sockaddr_in bind_addr = {.sin_family = AF_INET, .sin_addr.s_addr = htonl(INADDR_LOOPBACK)};
11569 IP_ADAPTER_ADDRESSES *adapters = NULL, *adapter;
11570 ULONG ip_addrs_size = 0;
11571 struct sockaddr addr;
11572 SOCKET s, s2;
11573 int ret, len;
11575 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
11577 WSASetLastError(0xdeadbeef);
11578 ret = bind(s, NULL, 0);
11579 ok(ret == -1, "expected failure\n");
11580 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
11582 WSASetLastError(0xdeadbeef);
11583 ret = bind(s, NULL, sizeof(addr));
11584 ok(ret == -1, "expected failure\n");
11585 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
11587 addr.sa_family = AF_INET;
11588 WSASetLastError(0xdeadbeef);
11589 ret = bind(s, &addr, 0);
11590 ok(ret == -1, "expected failure\n");
11591 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
11593 addr.sa_family = 0xdead;
11594 WSASetLastError(0xdeadbeef);
11595 ret = bind(s, &addr, sizeof(addr));
11596 ok(ret == -1, "expected failure\n");
11597 ok(WSAGetLastError() == WSAEAFNOSUPPORT, "got error %u\n", WSAGetLastError());
11599 WSASetLastError(0xdeadbeef);
11600 ret = bind(s, (const struct sockaddr *)&bind_addr, sizeof(bind_addr) - 1);
11601 ok(ret == -1, "expected failure\n");
11602 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
11604 WSASetLastError(0xdeadbeef);
11605 ret = bind(s, (const struct sockaddr *)&invalid_addr, sizeof(invalid_addr));
11606 ok(ret == -1, "expected failure\n");
11607 ok(WSAGetLastError() == WSAEADDRNOTAVAIL, "got error %u\n", WSAGetLastError());
11609 WSASetLastError(0xdeadbeef);
11610 ret = bind(s, (const struct sockaddr *)&bind_addr, sizeof(bind_addr));
11611 ok(!ret, "expected success\n");
11612 ok(!WSAGetLastError() || WSAGetLastError() == 0xdeadbeef /* win <7 */, "got error %u\n", WSAGetLastError());
11614 WSASetLastError(0xdeadbeef);
11615 ret = bind(s, (const struct sockaddr *)&bind_addr, sizeof(bind_addr));
11616 ok(ret == -1, "expected failure\n");
11617 ok(WSAGetLastError() == WSAEINVAL, "got error %u\n", WSAGetLastError());
11619 len = sizeof(addr);
11620 ret = getsockname(s, &addr, &len);
11621 ok(!ret, "got error %u\n", WSAGetLastError());
11623 s2 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
11625 WSASetLastError(0xdeadbeef);
11626 ret = bind(s2, &addr, sizeof(addr));
11627 ok(ret == -1, "expected failure\n");
11628 ok(WSAGetLastError() == WSAEADDRINUSE, "got error %u\n", WSAGetLastError());
11630 closesocket(s2);
11631 closesocket(s);
11633 s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
11635 WSASetLastError(0xdeadbeef);
11636 ret = bind(s, (const struct sockaddr *)&bind_addr, sizeof(bind_addr));
11637 ok(!ret, "expected success\n");
11638 ok(!WSAGetLastError() || WSAGetLastError() == 0xdeadbeef /* win <7 */, "got error %u\n", WSAGetLastError());
11640 closesocket(s);
11642 ret = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, adapters, &ip_addrs_size);
11643 ok(ret == ERROR_BUFFER_OVERFLOW, "got error %u\n", ret);
11644 adapters = malloc(ip_addrs_size);
11645 ret = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, adapters, &ip_addrs_size);
11646 ok(!ret, "got error %u\n", ret);
11648 for (adapter = adapters; adapter != NULL; adapter = adapter->Next)
11650 const IP_ADAPTER_UNICAST_ADDRESS *unicast_addr;
11652 for (unicast_addr = adapter->FirstUnicastAddress; unicast_addr != NULL; unicast_addr = unicast_addr->Next)
11654 short family = unicast_addr->Address.lpSockaddr->sa_family;
11656 s = socket(family, SOCK_STREAM, IPPROTO_TCP);
11657 ok(s != -1, "failed to create socket, error %u\n", WSAGetLastError());
11659 ret = bind(s, unicast_addr->Address.lpSockaddr, unicast_addr->Address.iSockaddrLength);
11660 ok(!ret, "got error %u\n", WSAGetLastError());
11662 closesocket(s);
11664 if (family == AF_INET6)
11666 struct sockaddr_in6 addr6, ret_addr6;
11668 memcpy(&addr6, unicast_addr->Address.lpSockaddr, sizeof(addr6));
11670 ok(unicast_addr->Address.iSockaddrLength == sizeof(struct sockaddr_in6),
11671 "got unexpected length %u\n", unicast_addr->Address.iSockaddrLength);
11673 s = socket(family, SOCK_STREAM, IPPROTO_TCP);
11674 ok(s != -1, "failed to create socket, error %u\n", WSAGetLastError());
11676 ret = bind(s, unicast_addr->Address.lpSockaddr, sizeof(struct sockaddr_in6_old));
11677 ok(ret == -1, "expected failure\n");
11678 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
11680 addr6.sin6_scope_id = 0xabacab;
11681 ret = bind(s, (struct sockaddr *)&addr6, sizeof(addr6));
11682 todo_wine_if (!((const struct sockaddr_in6 *)unicast_addr->Address.lpSockaddr)->sin6_scope_id)
11684 ok(ret == -1, "expected failure\n");
11685 ok(WSAGetLastError() == WSAEADDRNOTAVAIL, "got error %u\n", WSAGetLastError());
11688 addr6.sin6_scope_id = 0;
11689 ret = bind(s, (struct sockaddr *)&addr6, sizeof(addr6));
11690 todo_wine_if (!((const struct sockaddr_in6 *)unicast_addr->Address.lpSockaddr)->sin6_scope_id)
11691 ok(!ret, "got error %u\n", WSAGetLastError());
11693 memcpy(&addr6, unicast_addr->Address.lpSockaddr, sizeof(addr6));
11695 len = sizeof(struct sockaddr_in6_old);
11696 ret = getsockname(s, (struct sockaddr *)&ret_addr6, &len);
11697 ok(ret == -1, "expected failure\n");
11698 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
11700 len = sizeof(ret_addr6);
11701 memset(&ret_addr6, 0, sizeof(ret_addr6));
11702 ret = getsockname(s, (struct sockaddr *)&ret_addr6, &len);
11703 ok(!ret, "got error %u\n", WSAGetLastError());
11704 ok(ret_addr6.sin6_family == AF_INET6, "got family %u\n", ret_addr6.sin6_family);
11705 ok(ret_addr6.sin6_port != 0, "expected nonzero port\n");
11706 ok(!memcmp(&ret_addr6.sin6_addr, &addr6.sin6_addr, sizeof(addr6.sin6_addr)), "address didn't match\n");
11707 ok(ret_addr6.sin6_scope_id == addr6.sin6_scope_id, "got scope %lu\n", ret_addr6.sin6_scope_id);
11709 closesocket(s);
11714 free(adapters);
11717 /* Test calling methods on a socket which is currently connecting. */
11718 static void test_connecting_socket(void)
11720 const struct sockaddr_in bind_addr = {.sin_family = AF_INET, .sin_addr.s_addr = htonl(INADDR_ANY)};
11721 const struct sockaddr_in invalid_addr =
11723 .sin_family = AF_INET,
11724 .sin_addr.s_addr = inet_addr("192.0.2.0"),
11725 .sin_port = 255
11727 OVERLAPPED overlapped = {0}, overlapped2 = {0};
11728 GUID connectex_guid = WSAID_CONNECTEX;
11729 LPFN_CONNECTEX pConnectEx;
11730 struct sockaddr_in addr;
11731 char buffer[4];
11732 SOCKET client;
11733 int ret, len;
11734 DWORD size;
11736 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
11737 ok(client != -1, "failed to create socket, error %u\n", WSAGetLastError());
11738 set_blocking(client, FALSE);
11740 ret = bind(client, (const struct sockaddr *)&bind_addr, sizeof(bind_addr));
11741 ok(!ret, "expected success\n");
11742 ok(!WSAGetLastError(), "got %u\n", WSAGetLastError());
11744 ret = connect(client, (struct sockaddr *)&invalid_addr, sizeof(invalid_addr));
11745 ok(ret == -1, "got %d\n", ret);
11746 ok(WSAGetLastError() == WSAEWOULDBLOCK, "got %u\n", WSAGetLastError());
11748 /* Mortal Kombat 11 connects to the same address twice and expects the
11749 * second to return WSAEALREADY. */
11750 ret = connect(client, (struct sockaddr *)&invalid_addr, sizeof(invalid_addr));
11751 ok(ret == -1, "got %d\n", ret);
11752 ok(WSAGetLastError() == WSAEALREADY, "got %u\n", WSAGetLastError());
11754 ret = WSAIoctl(client, SIO_GET_EXTENSION_FUNCTION_POINTER, &connectex_guid, sizeof(connectex_guid),
11755 &pConnectEx, sizeof(pConnectEx), &size, NULL, NULL);
11756 ok(!ret, "failed to get ConnectEx, error %u\n", WSAGetLastError());
11757 overlapped.Internal = 0xdeadbeef;
11758 overlapped.InternalHigh = 0xdeadbeef;
11759 ret = pConnectEx(client, (struct sockaddr *)&invalid_addr, sizeof(invalid_addr), NULL, 0, &size, &overlapped);
11760 ok(!ret, "got %d\n", ret);
11761 ok(WSAGetLastError() == WSAEINVAL, "got %u\n", WSAGetLastError());
11762 ok((NTSTATUS)overlapped.Internal == STATUS_PENDING, "got status %#lx\n", (NTSTATUS)overlapped.Internal);
11763 todo_wine ok(overlapped.InternalHigh == 0xdeadbeef, "got size %Iu\n", overlapped.InternalHigh);
11765 len = sizeof(addr);
11766 ret = getsockname(client, (struct sockaddr *)&addr, &len);
11767 ok(!ret, "got error %u\n", WSAGetLastError());
11768 ok(addr.sin_family == AF_INET, "got family %u\n", addr.sin_family);
11769 ok(addr.sin_port, "expected nonzero port\n");
11771 len = sizeof(addr);
11772 ret = getpeername(client, (struct sockaddr *)&addr, &len);
11773 todo_wine ok(!ret, "got error %u\n", WSAGetLastError());
11774 if (!ret)
11776 ok(addr.sin_family == AF_INET, "got family %u\n", addr.sin_family);
11777 ok(addr.sin_addr.s_addr == inet_addr("192.0.2.0"), "got address %#08lx\n", addr.sin_addr.s_addr);
11778 ok(addr.sin_port == 255, "expected nonzero port\n");
11781 ret = recv(client, buffer, sizeof(buffer), 0);
11782 ok(ret == -1, "got %d\n", ret);
11783 todo_wine ok(WSAGetLastError() == WSAENOTCONN, "got %u\n", WSAGetLastError());
11785 ret = send(client, "data", 5, 0);
11786 ok(ret == -1, "got %d\n", ret);
11787 todo_wine ok(WSAGetLastError() == WSAENOTCONN, "got %u\n", WSAGetLastError());
11789 closesocket(client);
11791 /* Test with ConnectEx(). */
11793 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
11794 ok(client != -1, "failed to create socket, error %u\n", WSAGetLastError());
11795 set_blocking(client, FALSE);
11797 ret = bind(client, (const struct sockaddr *)&bind_addr, sizeof(bind_addr));
11798 ok(!ret, "expected success\n");
11799 ok(!WSAGetLastError(), "got %u\n", WSAGetLastError());
11801 ret = pConnectEx(client, (struct sockaddr *)&invalid_addr, sizeof(invalid_addr), NULL, 0, &size, &overlapped2);
11802 ok(!ret, "got %d\n", ret);
11803 ok(WSAGetLastError() == ERROR_IO_PENDING, "got error %u\n", WSAGetLastError());
11805 ret = connect(client, (struct sockaddr *)&invalid_addr, sizeof(invalid_addr));
11806 ok(ret == -1, "got %d\n", ret);
11807 ok(WSAGetLastError() == WSAEINVAL, "got %u\n", WSAGetLastError());
11809 overlapped.Internal = 0xdeadbeef;
11810 overlapped.InternalHigh = 0xdeadbeef;
11811 ret = pConnectEx(client, (struct sockaddr *)&invalid_addr, sizeof(invalid_addr), NULL, 0, &size, &overlapped);
11812 ok(!ret, "got %d\n", ret);
11813 ok(WSAGetLastError() == WSAEINVAL, "got %u\n", WSAGetLastError());
11814 ok((NTSTATUS)overlapped.Internal == STATUS_PENDING, "got status %#lx\n", (NTSTATUS)overlapped.Internal);
11815 todo_wine ok(overlapped.InternalHigh == 0xdeadbeef, "got size %Iu\n", overlapped.InternalHigh);
11817 len = sizeof(addr);
11818 ret = getsockname(client, (struct sockaddr *)&addr, &len);
11819 ok(!ret, "got error %u\n", WSAGetLastError());
11820 ok(addr.sin_family == AF_INET, "got family %u\n", addr.sin_family);
11821 ok(addr.sin_port, "expected nonzero port\n");
11823 len = sizeof(addr);
11824 ret = getpeername(client, (struct sockaddr *)&addr, &len);
11825 ok(ret == -1, "got %d\n", ret);
11826 ok(WSAGetLastError() == WSAENOTCONN, "got %u\n", WSAGetLastError());
11828 ret = recv(client, buffer, sizeof(buffer), 0);
11829 ok(ret == -1, "got %d\n", ret);
11830 todo_wine ok(WSAGetLastError() == WSAENOTCONN, "got %u\n", WSAGetLastError());
11832 ret = send(client, "data", 5, 0);
11833 ok(ret == -1, "got %d\n", ret);
11834 todo_wine ok(WSAGetLastError() == WSAENOTCONN, "got %u\n", WSAGetLastError());
11836 closesocket(client);
11839 static DWORD map_status( NTSTATUS status )
11841 static const struct
11843 NTSTATUS status;
11844 DWORD error;
11846 errors[] =
11848 {STATUS_PENDING, ERROR_IO_INCOMPLETE},
11850 {STATUS_BUFFER_OVERFLOW, WSAEMSGSIZE},
11852 {STATUS_NOT_IMPLEMENTED, WSAEOPNOTSUPP},
11853 {STATUS_ACCESS_VIOLATION, WSAEFAULT},
11854 {STATUS_PAGEFILE_QUOTA, WSAENOBUFS},
11855 {STATUS_INVALID_HANDLE, WSAENOTSOCK},
11856 {STATUS_NO_SUCH_DEVICE, WSAENETDOWN},
11857 {STATUS_NO_SUCH_FILE, WSAENETDOWN},
11858 {STATUS_NO_MEMORY, WSAENOBUFS},
11859 {STATUS_CONFLICTING_ADDRESSES, WSAENOBUFS},
11860 {STATUS_ACCESS_DENIED, WSAEACCES},
11861 {STATUS_BUFFER_TOO_SMALL, WSAEFAULT},
11862 {STATUS_OBJECT_TYPE_MISMATCH, WSAENOTSOCK},
11863 {STATUS_OBJECT_NAME_NOT_FOUND, WSAENETDOWN},
11864 {STATUS_OBJECT_PATH_NOT_FOUND, WSAENETDOWN},
11865 {STATUS_SHARING_VIOLATION, WSAEADDRINUSE},
11866 {STATUS_QUOTA_EXCEEDED, WSAENOBUFS},
11867 {STATUS_TOO_MANY_PAGING_FILES, WSAENOBUFS},
11868 {STATUS_INSUFFICIENT_RESOURCES, WSAENOBUFS},
11869 {STATUS_WORKING_SET_QUOTA, WSAENOBUFS},
11870 {STATUS_DEVICE_NOT_READY, WSAEWOULDBLOCK},
11871 {STATUS_PIPE_DISCONNECTED, WSAESHUTDOWN},
11872 {STATUS_IO_TIMEOUT, WSAETIMEDOUT},
11873 {STATUS_NOT_SUPPORTED, WSAEOPNOTSUPP},
11874 {STATUS_REMOTE_NOT_LISTENING, WSAECONNREFUSED},
11875 {STATUS_BAD_NETWORK_PATH, WSAENETUNREACH},
11876 {STATUS_NETWORK_BUSY, WSAENETDOWN},
11877 {STATUS_INVALID_NETWORK_RESPONSE, WSAENETDOWN},
11878 {STATUS_UNEXPECTED_NETWORK_ERROR, WSAENETDOWN},
11879 {STATUS_REQUEST_NOT_ACCEPTED, WSAEWOULDBLOCK},
11880 {STATUS_CANCELLED, ERROR_OPERATION_ABORTED},
11881 {STATUS_COMMITMENT_LIMIT, WSAENOBUFS},
11882 {STATUS_LOCAL_DISCONNECT, WSAECONNABORTED},
11883 {STATUS_REMOTE_DISCONNECT, WSAECONNRESET},
11884 {STATUS_REMOTE_RESOURCES, WSAENOBUFS},
11885 {STATUS_LINK_FAILED, WSAECONNRESET},
11886 {STATUS_LINK_TIMEOUT, WSAETIMEDOUT},
11887 {STATUS_INVALID_CONNECTION, WSAENOTCONN},
11888 {STATUS_INVALID_ADDRESS, WSAEADDRNOTAVAIL},
11889 {STATUS_INVALID_BUFFER_SIZE, WSAEMSGSIZE},
11890 {STATUS_INVALID_ADDRESS_COMPONENT, WSAEADDRNOTAVAIL},
11891 {STATUS_TOO_MANY_ADDRESSES, WSAENOBUFS},
11892 {STATUS_ADDRESS_ALREADY_EXISTS, WSAEADDRINUSE},
11893 {STATUS_CONNECTION_DISCONNECTED, WSAECONNRESET},
11894 {STATUS_CONNECTION_RESET, WSAECONNRESET},
11895 {STATUS_TRANSACTION_ABORTED, WSAECONNABORTED},
11896 {STATUS_CONNECTION_REFUSED, WSAECONNREFUSED},
11897 {STATUS_GRACEFUL_DISCONNECT, WSAEDISCON},
11898 {STATUS_CONNECTION_ACTIVE, WSAEISCONN},
11899 {STATUS_NETWORK_UNREACHABLE, WSAENETUNREACH},
11900 {STATUS_HOST_UNREACHABLE, WSAEHOSTUNREACH},
11901 {STATUS_PROTOCOL_UNREACHABLE, WSAENETUNREACH},
11902 {STATUS_PORT_UNREACHABLE, WSAECONNRESET},
11903 {STATUS_REQUEST_ABORTED, WSAEINTR},
11904 {STATUS_CONNECTION_ABORTED, WSAECONNABORTED},
11905 {STATUS_DATATYPE_MISALIGNMENT_ERROR,WSAEFAULT},
11906 {STATUS_HOST_DOWN, WSAEHOSTDOWN},
11907 {0x80070000 | ERROR_IO_INCOMPLETE, ERROR_IO_INCOMPLETE},
11908 {0xc0010000 | ERROR_IO_INCOMPLETE, ERROR_IO_INCOMPLETE},
11909 {0xc0070000 | ERROR_IO_INCOMPLETE, ERROR_IO_INCOMPLETE},
11912 unsigned int i;
11914 for (i = 0; i < ARRAY_SIZE(errors); ++i)
11916 if (errors[i].status == status)
11917 return errors[i].error;
11920 return NT_SUCCESS(status) ? RtlNtStatusToDosErrorNoTeb(status) : WSAEINVAL;
11923 static void test_WSAGetOverlappedResult(void)
11925 OVERLAPPED overlapped = {0};
11926 DWORD size, flags;
11927 NTSTATUS status;
11928 unsigned int i;
11929 SOCKET s;
11930 HANDLE h;
11931 BOOL ret;
11933 static const NTSTATUS ranges[][2] =
11935 {0x0, 0x10000},
11936 {0x40000000, 0x40001000},
11937 {0x80000000, 0x80001000},
11938 {0x80070000, 0x80080000},
11939 {0xc0000000, 0xc0001000},
11940 {0xc0070000, 0xc0080000},
11941 {0xd0000000, 0xd0001000},
11942 {0xd0070000, 0xd0080000},
11945 WSASetLastError(0xdeadbeef);
11946 ret = WSAGetOverlappedResult(0xdeadbeef, &overlapped, &size, FALSE, &flags);
11947 ok(!ret, "got %d.\n", ret);
11948 ok(WSAGetLastError() == WSAENOTSOCK, "got %u.\n", WSAGetLastError());
11950 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
11952 ret = DuplicateHandle(GetCurrentProcess(), (HANDLE)s, GetCurrentProcess(), &h, 0, FALSE, DUPLICATE_SAME_ACCESS);
11953 ok(ret, "got %d.\n", ret);
11954 ret = WSAGetOverlappedResult((SOCKET)h, &overlapped, &size, FALSE, &flags);
11955 ok(!ret, "got %d.\n", ret);
11956 ok(WSAGetLastError() == WSAENOTSOCK, "got %u.\n", WSAGetLastError());
11957 CloseHandle(h);
11959 for (i = 0; i < ARRAY_SIZE(ranges); ++i)
11961 for (status = ranges[i][0]; status < ranges[i][1]; ++status)
11963 BOOL expect_ret = NT_SUCCESS(status) && status != STATUS_PENDING;
11964 DWORD expect = map_status(status);
11966 overlapped.Internal = status;
11967 WSASetLastError(0xdeadbeef);
11968 ret = WSAGetOverlappedResult(s, &overlapped, &size, FALSE, &flags);
11969 ok(ret == expect_ret, "status %#lx: expected %d, got %d\n", status, expect_ret, ret);
11970 if (ret)
11972 ok(WSAGetLastError() == expect /* >= win10 1809 */
11973 || !WSAGetLastError() /* < win10 1809 */
11974 || WSAGetLastError() == 0xdeadbeef, /* < win7 */
11975 "status %#lx: expected error %lu, got %u\n", status, expect, WSAGetLastError());
11977 else
11979 ok(WSAGetLastError() == expect
11980 || (status == (0xc0070000 | ERROR_IO_INCOMPLETE) && WSAGetLastError() == WSAEINVAL), /* < win8 */
11981 "status %#lx: expected error %lu, got %u\n", status, expect, WSAGetLastError());
11986 closesocket(s);
11989 struct nonblocking_async_recv_params
11991 SOCKET client;
11992 HANDLE event;
11995 static DWORD CALLBACK nonblocking_async_recv_thread(void *arg)
11997 const struct nonblocking_async_recv_params *params = arg;
11998 OVERLAPPED overlapped = {0};
11999 DWORD flags = 0, size;
12000 char buffer[5];
12001 WSABUF wsabuf;
12002 int ret;
12004 overlapped.hEvent = params->event;
12005 wsabuf.buf = buffer;
12006 wsabuf.len = sizeof(buffer);
12007 memset(buffer, 0, sizeof(buffer));
12008 ret = WSARecv(params->client, &wsabuf, 1, NULL, &flags, &overlapped, NULL);
12009 ok(!ret, "got %d\n", ret);
12010 ret = GetOverlappedResult((HANDLE)params->client, &overlapped, &size, FALSE);
12011 ok(ret, "got error %lu\n", GetLastError());
12012 ok(size == 4, "got size %lu\n", size);
12013 ok(!strcmp(buffer, "data"), "got %s\n", debugstr_an(buffer, size));
12015 return 0;
12018 static void test_nonblocking_async_recv(void)
12020 struct nonblocking_async_recv_params params;
12021 OVERLAPPED overlapped = {0};
12022 SOCKET client, server;
12023 DWORD flags = 0, size;
12024 HANDLE thread, event;
12025 char buffer[5];
12026 WSABUF wsabuf;
12027 int ret;
12029 event = CreateEventW(NULL, TRUE, FALSE, NULL);
12030 wsabuf.buf = buffer;
12031 wsabuf.len = sizeof(buffer);
12033 tcp_socketpair(&client, &server);
12034 set_blocking(client, FALSE);
12035 set_blocking(server, FALSE);
12037 WSASetLastError(0xdeadbeef);
12038 ret = recv(client, buffer, sizeof(buffer), 0);
12039 ok(ret == -1, "got %d\n", ret);
12040 ok(WSAGetLastError() == WSAEWOULDBLOCK, "got error %u\n", WSAGetLastError());
12042 WSASetLastError(0xdeadbeef);
12043 overlapped.Internal = 0xdeadbeef;
12044 ret = WSARecv(client, &wsabuf, 1, &size, &flags, NULL, NULL);
12045 ok(ret == -1, "got %d\n", ret);
12046 ok(WSAGetLastError() == WSAEWOULDBLOCK, "got error %u\n", WSAGetLastError());
12047 ok(overlapped.Internal == 0xdeadbeef, "got status %#lx\n", (NTSTATUS)overlapped.Internal);
12049 /* Overlapped, with a NULL event. */
12051 overlapped.hEvent = NULL;
12053 memset(buffer, 0, sizeof(buffer));
12054 WSASetLastError(0xdeadbeef);
12055 ret = WSARecv(client, &wsabuf, 1, NULL, &flags, &overlapped, NULL);
12056 ok(ret == -1, "got %d\n", ret);
12057 ok(WSAGetLastError() == ERROR_IO_PENDING, "got error %u\n", WSAGetLastError());
12058 ret = WaitForSingleObject((HANDLE)client, 0);
12059 ok(ret == WAIT_TIMEOUT, "expected timeout\n");
12061 ret = send(server, "data", 4, 0);
12062 ok(ret == 4, "got %d\n", ret);
12064 ret = WaitForSingleObject((HANDLE)client, 1000);
12065 ok(!ret, "wait timed out\n");
12066 ret = GetOverlappedResult((HANDLE)client, &overlapped, &size, FALSE);
12067 ok(ret, "got error %lu\n", GetLastError());
12068 ok(size == 4, "got size %lu\n", size);
12069 ok(!strcmp(buffer, "data"), "got %s\n", debugstr_an(buffer, size));
12071 /* Overlapped, with a non-NULL event. */
12073 overlapped.hEvent = event;
12075 memset(buffer, 0, sizeof(buffer));
12076 WSASetLastError(0xdeadbeef);
12077 ret = WSARecv(client, &wsabuf, 1, NULL, &flags, &overlapped, NULL);
12078 ok(ret == -1, "got %d\n", ret);
12079 ok(WSAGetLastError() == ERROR_IO_PENDING, "got error %u\n", WSAGetLastError());
12080 ret = WaitForSingleObject(event, 0);
12081 ok(ret == WAIT_TIMEOUT, "expected timeout\n");
12083 ret = send(server, "data", 4, 0);
12084 ok(ret == 4, "got %d\n", ret);
12086 ret = WaitForSingleObject(event, 1000);
12087 ok(!ret, "wait timed out\n");
12088 ret = GetOverlappedResult((HANDLE)client, &overlapped, &size, FALSE);
12089 ok(ret, "got error %lu\n", GetLastError());
12090 ok(size == 4, "got size %lu\n", size);
12091 ok(!strcmp(buffer, "data"), "got %s\n", debugstr_an(buffer, size));
12093 /* With data already in the pipe; usually this does return 0 (but not
12094 * reliably). */
12096 ret = send(server, "data", 4, 0);
12097 ok(ret == 4, "got %d\n", ret);
12099 memset(buffer, 0, sizeof(buffer));
12100 ret = WSARecv(client, &wsabuf, 1, NULL, &flags, &overlapped, NULL);
12101 ok(!ret || WSAGetLastError() == ERROR_IO_PENDING, "got error %u\n", WSAGetLastError());
12102 ret = WaitForSingleObject(event, 1000);
12103 ok(!ret, "wait timed out\n");
12104 ret = GetOverlappedResult((HANDLE)client, &overlapped, &size, FALSE);
12105 ok(ret, "got error %lu\n", GetLastError());
12106 ok(size == 4, "got size %lu\n", size);
12107 ok(!strcmp(buffer, "data"), "got %s\n", debugstr_an(buffer, size));
12109 closesocket(client);
12110 closesocket(server);
12112 /* With a non-overlapped socket, WSARecv() always blocks when passed an
12113 * overlapped structure, but returns WSAEWOULDBLOCK otherwise. */
12115 tcp_socketpair_flags(&client, &server, 0);
12116 set_blocking(client, FALSE);
12117 set_blocking(server, FALSE);
12119 WSASetLastError(0xdeadbeef);
12120 ret = recv(client, buffer, sizeof(buffer), 0);
12121 ok(ret == -1, "got %d\n", ret);
12122 ok(WSAGetLastError() == WSAEWOULDBLOCK, "got error %u\n", WSAGetLastError());
12124 WSASetLastError(0xdeadbeef);
12125 overlapped.Internal = 0xdeadbeef;
12126 ret = WSARecv(client, &wsabuf, 1, &size, &flags, NULL, NULL);
12127 ok(ret == -1, "got %d\n", ret);
12128 ok(WSAGetLastError() == WSAEWOULDBLOCK, "got error %u\n", WSAGetLastError());
12129 ok(overlapped.Internal == 0xdeadbeef, "got status %#lx\n", (NTSTATUS)overlapped.Internal);
12131 /* Overlapped, with a NULL event. */
12133 params.client = client;
12134 params.event = NULL;
12135 thread = CreateThread(NULL, 0, nonblocking_async_recv_thread, &params, 0, NULL);
12137 ret = WaitForSingleObject(thread, 200);
12138 ok(ret == WAIT_TIMEOUT, "expected timeout\n");
12140 ret = send(server, "data", 4, 0);
12141 ok(ret == 4, "got %d\n", ret);
12143 ret = WaitForSingleObject(thread, 200);
12144 ok(!ret, "wait timed out\n");
12145 CloseHandle(thread);
12147 /* Overlapped, with a non-NULL event. */
12149 params.client = client;
12150 params.event = event;
12151 thread = CreateThread(NULL, 0, nonblocking_async_recv_thread, &params, 0, NULL);
12153 ret = WaitForSingleObject(thread, 200);
12154 ok(ret == WAIT_TIMEOUT, "expected timeout\n");
12156 ret = send(server, "data", 4, 0);
12157 ok(ret == 4, "got %d\n", ret);
12159 ret = WaitForSingleObject(thread, 200);
12160 ok(!ret, "wait timed out\n");
12161 CloseHandle(thread);
12163 /* With data already in the pipe. */
12165 ret = send(server, "data", 4, 0);
12166 ok(ret == 4, "got %d\n", ret);
12168 memset(buffer, 0, sizeof(buffer));
12169 ret = WSARecv(client, &wsabuf, 1, NULL, &flags, &overlapped, NULL);
12170 ok(!ret, "got %d\n", ret);
12171 ret = GetOverlappedResult((HANDLE)client, &overlapped, &size, FALSE);
12172 ok(ret, "got error %lu\n", GetLastError());
12173 ok(size == 4, "got size %lu\n", size);
12174 ok(!strcmp(buffer, "data"), "got %s\n", debugstr_an(buffer, size));
12176 closesocket(client);
12177 closesocket(server);
12179 CloseHandle(overlapped.hEvent);
12182 static void test_simultaneous_async_recv(void)
12184 SOCKET client, server;
12185 OVERLAPPED overlappeds[2] = {{0}};
12186 HANDLE events[2];
12187 WSABUF wsabufs[2];
12188 DWORD flags[2] = {0};
12189 size_t num_io = 2, stride = 16, i;
12190 char resbuf[32] = "";
12191 static const char msgstr[32] = "-- Lorem ipsum dolor sit amet -";
12192 int ret;
12194 for (i = 0; i < num_io; i++) events[i] = CreateEventW(NULL, TRUE, FALSE, NULL);
12196 tcp_socketpair(&client, &server);
12198 for (i = 0; i < num_io; i++)
12200 wsabufs[i].buf = resbuf + i * stride;
12201 wsabufs[i].len = stride;
12202 overlappeds[i].hEvent = events[i];
12203 ret = WSARecv(client, &wsabufs[i], 1, NULL, &flags[i], &overlappeds[i], NULL);
12204 ok(ret == -1, "got %d\n", ret);
12205 ok(WSAGetLastError() == ERROR_IO_PENDING, "got error %u\n", WSAGetLastError());
12208 ret = send(server, msgstr, sizeof(msgstr), 0);
12209 ok(ret == sizeof(msgstr), "got %d\n", ret);
12211 for (i = 0; i < num_io; i++)
12213 const void *expect = msgstr + i * stride;
12214 const void *actual = resbuf + i * stride;
12215 DWORD size;
12217 ret = WaitForSingleObject(events[i], 1000);
12218 ok(!ret, "wait timed out\n");
12220 size = 0;
12221 ret = GetOverlappedResult((HANDLE)client, &overlappeds[i], &size, FALSE);
12222 ok(ret, "got error %lu\n", GetLastError());
12223 ok(size == stride, "got size %lu\n", size);
12224 ok(!memcmp(expect, actual, stride), "expected %s, got %s\n", debugstr_an(expect, stride), debugstr_an(actual, stride));
12227 closesocket(client);
12228 closesocket(server);
12230 for (i = 0; i < num_io; i++) CloseHandle(events[i]);
12233 static void test_empty_recv(void)
12235 OVERLAPPED overlapped = {0};
12236 SOCKET client, server;
12237 DWORD size, flags = 0;
12238 char buffer[5];
12239 WSABUF wsabuf;
12240 int ret;
12242 overlapped.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
12243 tcp_socketpair(&client, &server);
12245 WSASetLastError(0xdeadbeef);
12246 ret = WSARecv(client, NULL, 0, NULL, &flags, &overlapped, NULL);
12247 ok(ret == -1, "expected failure\n");
12248 todo_wine ok(WSAGetLastError() == WSAEINVAL, "got error %u\n", WSAGetLastError());
12250 wsabuf.buf = buffer;
12251 wsabuf.len = 0;
12252 WSASetLastError(0xdeadbeef);
12253 ret = WSARecv(client, &wsabuf, 0, NULL, &flags, &overlapped, NULL);
12254 ok(ret == -1, "expected failure\n");
12255 todo_wine ok(WSAGetLastError() == WSAEINVAL, "got error %u\n", WSAGetLastError());
12257 WSASetLastError(0xdeadbeef);
12258 ret = WSARecv(client, &wsabuf, 1, NULL, &flags, &overlapped, NULL);
12259 ok(ret == -1, "expected failure\n");
12260 ok(WSAGetLastError() == ERROR_IO_PENDING, "got error %u\n", WSAGetLastError());
12262 ret = send(server, "data", 5, 0);
12263 ok(ret == 5, "got %d\n", ret);
12265 ret = WaitForSingleObject(overlapped.hEvent, 1000);
12266 ok(!ret, "wait failed\n");
12267 ret = GetOverlappedResult((HANDLE)client, &overlapped, &size, FALSE);
12268 ok(ret, "got error %lu\n", GetLastError());
12269 ok(!size, "got size %lu\n", size);
12271 WSASetLastError(0xdeadbeef);
12272 ret = WSARecv(client, &wsabuf, 1, &size, &flags, &overlapped, NULL);
12273 ok(!ret, "got error %u\n", WSAGetLastError());
12274 ok(!size, "got size %lu\n", size);
12276 ret = recv(client, NULL, 0, 0);
12277 ok(!ret, "got %d\n", ret);
12279 ret = recv(client, buffer, sizeof(buffer), 0);
12280 ok(ret == 5, "got %d\n", ret);
12281 ok(!strcmp(buffer, "data"), "got %s\n", debugstr_an(buffer, ret));
12283 closesocket(client);
12284 closesocket(server);
12285 CloseHandle(overlapped.hEvent);
12288 static void test_timeout(void)
12290 DWORD timeout, flags = 0, size;
12291 OVERLAPPED overlapped = {0};
12292 SOCKET client, server;
12293 WSABUF wsabuf;
12294 int ret, len;
12295 char buffer;
12297 tcp_socketpair(&client, &server);
12298 overlapped.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
12300 timeout = 0xdeadbeef;
12301 len = sizeof(timeout);
12302 WSASetLastError(0xdeadbeef);
12303 ret = getsockopt(client, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, &len);
12304 ok(!ret, "expected success\n");
12305 ok(!WSAGetLastError(), "got error %u\n", WSAGetLastError());
12306 ok(len == sizeof(timeout), "got size %u\n", len);
12307 ok(!timeout, "got timeout %lu\n", timeout);
12309 timeout = 100;
12310 WSASetLastError(0xdeadbeef);
12311 ret = setsockopt(client, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout));
12312 ok(!ret, "expected success\n");
12313 ok(!WSAGetLastError(), "got error %u\n", WSAGetLastError());
12315 timeout = 0xdeadbeef;
12316 len = sizeof(timeout);
12317 WSASetLastError(0xdeadbeef);
12318 ret = getsockopt(client, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, &len);
12319 ok(!ret, "expected success\n");
12320 ok(!WSAGetLastError(), "got error %u\n", WSAGetLastError());
12321 ok(timeout == 100, "got timeout %lu\n", timeout);
12323 WSASetLastError(0xdeadbeef);
12324 ret = recv(client, &buffer, 1, 0);
12325 ok(ret == -1, "got %d\n", ret);
12326 ok(WSAGetLastError() == WSAETIMEDOUT, "got error %u\n", WSAGetLastError());
12328 wsabuf.buf = &buffer;
12329 wsabuf.len = 1;
12330 WSASetLastError(0xdeadbeef);
12331 size = 0xdeadbeef;
12332 ret = WSARecv(client, &wsabuf, 1, &size, &flags, NULL, NULL);
12333 ok(ret == -1, "got %d\n", ret);
12334 ok(WSAGetLastError() == WSAETIMEDOUT, "got error %u\n", WSAGetLastError());
12335 ok(size == 0xdeadbeef, "got size %lu\n", size);
12337 wsabuf.buf = &buffer;
12338 wsabuf.len = 1;
12339 WSASetLastError(0xdeadbeef);
12340 size = 0xdeadbeef;
12341 ret = WSARecv(client, &wsabuf, 1, &size, &flags, &overlapped, NULL);
12342 ok(ret == -1, "got %d\n", ret);
12343 ok(WSAGetLastError() == ERROR_IO_PENDING, "got error %u\n", WSAGetLastError());
12345 ret = WaitForSingleObject(overlapped.hEvent, 200);
12346 ok(ret == WAIT_TIMEOUT, "got %d\n", ret);
12348 ret = send(server, "a", 1, 0);
12349 ok(ret == 1, "got %d\n", ret);
12351 ret = WaitForSingleObject(overlapped.hEvent, 200);
12352 ok(!ret, "got %d\n", ret);
12353 ret = GetOverlappedResult((HANDLE)client, &overlapped, &size, FALSE);
12354 ok(ret, "got error %lu\n", GetLastError());
12355 ok(size == 1, "got size %lu\n", size);
12357 closesocket(client);
12358 closesocket(server);
12359 CloseHandle(overlapped.hEvent);
12362 static void test_so_debug(void)
12364 int ret, len;
12365 DWORD debug;
12366 SOCKET s;
12368 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
12370 len = sizeof(debug);
12371 WSASetLastError(0xdeadbeef);
12372 debug = 0xdeadbeef;
12373 ret = getsockopt(s, SOL_SOCKET, SO_DEBUG, (char *)&debug, &len);
12374 ok(!ret, "got %d\n", ret);
12375 ok(!WSAGetLastError(), "got error %u\n", WSAGetLastError());
12376 ok(len == sizeof(debug), "got len %u\n", len);
12377 ok(!debug, "got debug %lu\n", debug);
12379 WSASetLastError(0xdeadbeef);
12380 debug = 2;
12381 ret = setsockopt(s, SOL_SOCKET, SO_DEBUG, (char *)&debug, sizeof(debug));
12382 ok(!ret, "got %d\n", ret);
12383 todo_wine ok(!WSAGetLastError(), "got error %u\n", WSAGetLastError());
12385 len = sizeof(debug);
12386 WSASetLastError(0xdeadbeef);
12387 debug = 0xdeadbeef;
12388 ret = getsockopt(s, SOL_SOCKET, SO_DEBUG, (char *)&debug, &len);
12389 ok(!ret, "got %d\n", ret);
12390 ok(!WSAGetLastError(), "got error %u\n", WSAGetLastError());
12391 ok(len == sizeof(debug), "got len %u\n", len);
12392 todo_wine ok(debug == 1, "got debug %lu\n", debug);
12394 closesocket(s);
12397 struct sockopt_validity_test
12399 int opt;
12400 int get_error;
12401 int set_error;
12402 BOOL todo;
12405 static void do_sockopt_validity_tests(const char *type, SOCKET sock, int level,
12406 const struct sockopt_validity_test *tests)
12408 char value[256];
12409 int count, rc, expected_rc, i;
12411 for (i = 0; tests[i].opt; i++)
12413 winetest_push_context("%s option %i", type, tests[i].opt);
12414 memset(value, 0, sizeof(value));
12415 count = sizeof(value);
12417 WSASetLastError(0);
12418 rc = getsockopt(sock, level, tests[i].opt, value, &count);
12419 expected_rc = tests[i].get_error ? SOCKET_ERROR : 0;
12420 todo_wine_if(!tests[i].get_error && tests[i].todo)
12421 ok(rc == expected_rc || broken(rc == SOCKET_ERROR && WSAGetLastError() == WSAENOPROTOOPT),
12422 "expected getsockopt to return %i, got %i\n", expected_rc, rc);
12423 todo_wine_if(tests[i].todo)
12424 ok(WSAGetLastError() == tests[i].get_error || broken(rc == SOCKET_ERROR && WSAGetLastError() == WSAENOPROTOOPT),
12425 "expected getsockopt to set error %i, got %i\n", tests[i].get_error, WSAGetLastError());
12427 if (tests[i].get_error)
12429 winetest_pop_context();
12430 continue;
12433 WSASetLastError(0);
12434 rc = setsockopt(sock, level, tests[i].opt, value, count);
12435 expected_rc = tests[i].set_error ? SOCKET_ERROR : 0;
12436 todo_wine_if(!tests[i].set_error && tests[i].todo)
12437 ok(rc == expected_rc || broken(rc == SOCKET_ERROR && WSAGetLastError() == WSAENOPROTOOPT),
12438 "expected setsockopt to return %i, got %i\n", expected_rc, rc);
12439 todo_wine_if(tests[i].todo)
12440 ok(WSAGetLastError() == tests[i].set_error || broken(rc == SOCKET_ERROR && WSAGetLastError() == WSAENOPROTOOPT),
12441 "expected setsockopt to set error %i, got %i\n", tests[i].set_error, WSAGetLastError());
12443 winetest_pop_context();
12447 static void test_sockopt_validity(void)
12449 static const struct sockopt_validity_test ipv4_tcp_tests[] =
12451 { -1, WSAENOPROTOOPT },
12452 { IP_OPTIONS },
12453 { IP_HDRINCL, WSAEINVAL },
12454 { IP_TOS },
12455 { IP_TTL },
12456 { IP_MULTICAST_IF, WSAEINVAL },
12457 { IP_MULTICAST_TTL, WSAEINVAL },
12458 { IP_MULTICAST_LOOP, WSAEINVAL },
12459 { IP_ADD_MEMBERSHIP, WSAENOPROTOOPT },
12460 { IP_DROP_MEMBERSHIP, WSAENOPROTOOPT },
12461 { IP_DONTFRAGMENT },
12462 { IP_PKTINFO, WSAEINVAL },
12463 { IP_RECVTTL, WSAEINVAL },
12464 { IP_RECEIVE_BROADCAST, WSAEINVAL, 0, TRUE },
12465 { IP_RECVIF, WSAEINVAL, 0, TRUE },
12466 { IP_RECVDSTADDR, WSAEINVAL, 0, TRUE },
12467 { IP_IFLIST, 0, 0, TRUE },
12468 { IP_UNICAST_IF },
12469 { IP_RTHDR, 0, 0, TRUE },
12470 { IP_GET_IFLIST, WSAEINVAL, 0, TRUE },
12471 { IP_RECVRTHDR, WSAEINVAL, 0, TRUE },
12472 { IP_RECVTOS, WSAEINVAL },
12473 { IP_ORIGINAL_ARRIVAL_IF, WSAEINVAL, 0, TRUE },
12474 { IP_ECN, WSAEINVAL, 0, TRUE },
12475 { IP_PKTINFO_EX, WSAEINVAL, 0, TRUE },
12476 { IP_WFP_REDIRECT_RECORDS, WSAEINVAL, 0, TRUE },
12477 { IP_WFP_REDIRECT_CONTEXT, WSAEINVAL, 0, TRUE },
12478 { IP_MTU_DISCOVER, 0, WSAEINVAL, TRUE },
12479 { IP_MTU, WSAENOTCONN, 0, TRUE },
12480 { IP_RECVERR, WSAEINVAL, 0, TRUE },
12481 { IP_USER_MTU, 0, 0, TRUE },
12484 static const struct sockopt_validity_test ipv4_udp_tests[] =
12486 { -1, WSAENOPROTOOPT },
12487 { IP_OPTIONS },
12488 { IP_HDRINCL, WSAEINVAL },
12489 { IP_TOS },
12490 { IP_TTL },
12491 { IP_MULTICAST_IF },
12492 { IP_MULTICAST_TTL },
12493 { IP_MULTICAST_LOOP },
12494 { IP_ADD_MEMBERSHIP, WSAENOPROTOOPT },
12495 { IP_DROP_MEMBERSHIP, WSAENOPROTOOPT },
12496 { IP_DONTFRAGMENT },
12497 { IP_PKTINFO },
12498 { IP_RECVTTL },
12499 { IP_RECEIVE_BROADCAST, 0, 0, TRUE },
12500 { IP_RECVIF, 0, 0, TRUE },
12501 { IP_RECVDSTADDR, 0, 0, TRUE },
12502 { IP_IFLIST, 0, 0, TRUE },
12503 { IP_UNICAST_IF },
12504 { IP_RTHDR, 0, 0, TRUE },
12505 { IP_GET_IFLIST, WSAEINVAL, 0, TRUE },
12506 { IP_RECVRTHDR, 0, 0, TRUE },
12507 { IP_RECVTOS },
12508 { IP_ORIGINAL_ARRIVAL_IF, 0, 0, TRUE },
12509 { IP_ECN, 0, 0, TRUE },
12510 { IP_PKTINFO_EX, 0, 0, TRUE },
12511 { IP_WFP_REDIRECT_RECORDS, 0, 0, TRUE },
12512 { IP_WFP_REDIRECT_CONTEXT, 0, 0, TRUE },
12513 { IP_MTU_DISCOVER, 0, WSAEINVAL, TRUE },
12514 { IP_MTU, WSAENOTCONN, 0, TRUE },
12515 { IP_RECVERR, 0, 0, TRUE },
12516 { IP_USER_MTU, 0, 0, TRUE },
12519 static const struct sockopt_validity_test ipv4_raw_tests[] =
12521 { -1, WSAENOPROTOOPT },
12522 { IP_OPTIONS },
12523 { IP_HDRINCL, },
12524 { IP_TOS },
12525 { IP_TTL },
12526 { IP_MULTICAST_IF },
12527 { IP_MULTICAST_TTL },
12528 { IP_MULTICAST_LOOP },
12529 { IP_ADD_MEMBERSHIP, WSAENOPROTOOPT },
12530 { IP_DROP_MEMBERSHIP, WSAENOPROTOOPT },
12531 { IP_DONTFRAGMENT },
12532 { IP_PKTINFO },
12533 { IP_RECVTTL },
12534 { IP_RECEIVE_BROADCAST, 0, 0, TRUE },
12535 { IP_RECVIF, 0, 0, TRUE },
12536 { IP_RECVDSTADDR, 0, 0, TRUE },
12537 { IP_IFLIST, 0, 0, TRUE },
12538 { IP_UNICAST_IF },
12539 { IP_RTHDR, 0, 0, TRUE },
12540 { IP_GET_IFLIST, WSAEINVAL, 0, TRUE },
12541 { IP_RECVRTHDR, 0, 0, TRUE },
12542 { IP_RECVTOS },
12543 { IP_ORIGINAL_ARRIVAL_IF, 0, 0, TRUE },
12544 { IP_ECN, 0, 0, TRUE },
12545 { IP_PKTINFO_EX, 0, 0, TRUE },
12546 { IP_WFP_REDIRECT_RECORDS, 0, 0, TRUE },
12547 { IP_WFP_REDIRECT_CONTEXT, 0, 0, TRUE },
12548 { IP_MTU_DISCOVER, 0, WSAEINVAL, TRUE },
12549 { IP_MTU, WSAENOTCONN, 0, TRUE },
12550 { IP_RECVERR, WSAEINVAL, 0, TRUE },
12551 { IP_USER_MTU, 0, 0, TRUE },
12554 static const struct sockopt_validity_test ipv6_tcp_tests[] =
12556 { -1, WSAENOPROTOOPT },
12557 { IPV6_HOPOPTS, 0, 0, TRUE },
12558 { IPV6_HDRINCL, WSAEINVAL, 0, TRUE },
12559 { IPV6_UNICAST_HOPS },
12560 { IPV6_MULTICAST_IF, WSAEINVAL },
12561 { IPV6_MULTICAST_HOPS, WSAEINVAL },
12562 { IPV6_MULTICAST_LOOP, WSAEINVAL },
12563 { IPV6_ADD_MEMBERSHIP, WSAENOPROTOOPT },
12564 { IPV6_DROP_MEMBERSHIP, WSAENOPROTOOPT },
12565 { IPV6_DONTFRAG },
12566 { IPV6_PKTINFO, WSAEINVAL },
12567 { IPV6_HOPLIMIT, WSAEINVAL },
12568 { IPV6_PROTECTION_LEVEL },
12569 { IPV6_RECVIF, WSAEINVAL, 0, TRUE },
12570 { IPV6_RECVDSTADDR, WSAEINVAL, 0, TRUE },
12571 { IPV6_V6ONLY },
12572 { IPV6_IFLIST, 0, 0, TRUE },
12573 { IPV6_UNICAST_IF },
12574 { IPV6_RTHDR, 0, 0, TRUE },
12575 { IPV6_GET_IFLIST, WSAEINVAL, 0, TRUE },
12576 { IPV6_RECVRTHDR, WSAEINVAL, 0, TRUE },
12577 { IPV6_RECVTCLASS, WSAEINVAL },
12578 { IP_ORIGINAL_ARRIVAL_IF, WSAEINVAL, 0, TRUE },
12579 { IPV6_ECN, WSAEINVAL, 0, TRUE },
12580 { IPV6_PKTINFO_EX, WSAEINVAL, 0, TRUE },
12581 { IPV6_WFP_REDIRECT_RECORDS, WSAEINVAL, 0, TRUE },
12582 { IPV6_WFP_REDIRECT_CONTEXT, WSAEINVAL, 0, TRUE },
12583 { IPV6_MTU_DISCOVER, 0, WSAEINVAL, TRUE },
12584 { IPV6_MTU, WSAENOTCONN, 0, TRUE },
12585 { IPV6_RECVERR, WSAEINVAL, 0, TRUE },
12586 { IPV6_USER_MTU, 0, 0, TRUE },
12589 static const struct sockopt_validity_test ipv6_udp_tests[] =
12591 { -1, WSAENOPROTOOPT },
12592 { IPV6_HOPOPTS, 0, 0, TRUE },
12593 { IPV6_HDRINCL, WSAEINVAL, 0, TRUE },
12594 { IPV6_UNICAST_HOPS },
12595 { IPV6_MULTICAST_IF },
12596 { IPV6_MULTICAST_HOPS },
12597 { IPV6_MULTICAST_LOOP },
12598 { IPV6_ADD_MEMBERSHIP, WSAENOPROTOOPT },
12599 { IPV6_DROP_MEMBERSHIP, WSAENOPROTOOPT },
12600 { IPV6_DONTFRAG },
12601 { IPV6_PKTINFO },
12602 { IPV6_HOPLIMIT },
12603 { IPV6_PROTECTION_LEVEL },
12604 { IPV6_RECVIF, 0, 0, TRUE },
12605 { IPV6_RECVDSTADDR, 0, 0, TRUE },
12606 { IPV6_V6ONLY },
12607 { IPV6_IFLIST, 0, 0, TRUE },
12608 { IPV6_UNICAST_IF },
12609 { IPV6_RTHDR, 0, 0, TRUE },
12610 { IPV6_GET_IFLIST, WSAEINVAL, 0, TRUE },
12611 { IPV6_RECVRTHDR, 0, 0, TRUE },
12612 { IPV6_RECVTCLASS },
12613 { IP_ORIGINAL_ARRIVAL_IF, 0, 0, TRUE },
12614 { IPV6_ECN, 0, 0, TRUE },
12615 { IPV6_PKTINFO_EX, 0, 0, TRUE },
12616 { IPV6_WFP_REDIRECT_RECORDS, 0, 0, TRUE },
12617 { IPV6_WFP_REDIRECT_CONTEXT, 0, 0, TRUE },
12618 { IPV6_MTU_DISCOVER, 0, WSAEINVAL, TRUE },
12619 { IPV6_MTU, WSAENOTCONN, 0, TRUE },
12620 { IPV6_RECVERR, 0, 0, TRUE },
12621 { IPV6_USER_MTU, 0, 0, TRUE },
12624 static const struct sockopt_validity_test ipv6_raw_tests[] =
12626 { -1, WSAENOPROTOOPT },
12627 { IPV6_HOPOPTS, 0, 0, TRUE },
12628 { IPV6_HDRINCL, 0, 0, TRUE },
12629 { IPV6_UNICAST_HOPS },
12630 { IPV6_MULTICAST_IF },
12631 { IPV6_MULTICAST_HOPS },
12632 { IPV6_MULTICAST_LOOP },
12633 { IPV6_ADD_MEMBERSHIP, WSAENOPROTOOPT },
12634 { IPV6_DROP_MEMBERSHIP, WSAENOPROTOOPT },
12635 { IPV6_DONTFRAG },
12636 { IPV6_PKTINFO },
12637 { IPV6_HOPLIMIT },
12638 { IPV6_PROTECTION_LEVEL },
12639 { IPV6_RECVIF, 0, 0, TRUE },
12640 { IPV6_RECVDSTADDR, 0, 0, TRUE },
12641 { IPV6_V6ONLY },
12642 { IPV6_IFLIST, 0, 0, TRUE },
12643 { IPV6_UNICAST_IF },
12644 { IPV6_RTHDR, 0, 0, TRUE },
12645 { IPV6_GET_IFLIST, WSAEINVAL, 0, TRUE },
12646 { IPV6_RECVRTHDR, 0, 0, TRUE },
12647 { IPV6_RECVTCLASS },
12648 { IP_ORIGINAL_ARRIVAL_IF, 0, 0, TRUE },
12649 { IPV6_ECN, 0, 0, TRUE },
12650 { IPV6_PKTINFO_EX, 0, 0, TRUE },
12651 { IPV6_WFP_REDIRECT_RECORDS, 0, 0, TRUE },
12652 { IPV6_WFP_REDIRECT_CONTEXT, 0, 0, TRUE },
12653 { IPV6_MTU_DISCOVER, 0, WSAEINVAL, TRUE },
12654 { IPV6_MTU, WSAENOTCONN, 0, TRUE },
12655 { IPV6_RECVERR, WSAEINVAL, 0, TRUE },
12656 { IPV6_USER_MTU, 0, 0, TRUE },
12659 static const struct sockopt_validity_test file_handle_tests[] =
12661 { -1, WSAENOTSOCK },
12662 { SO_TYPE, WSAENOTSOCK },
12663 { SO_OPENTYPE },
12666 char path[MAX_PATH];
12667 HANDLE file;
12668 SOCKET sock;
12670 sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
12671 ok(sock != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
12672 do_sockopt_validity_tests("IPv4 TCP", sock, IPPROTO_IP, ipv4_tcp_tests);
12673 closesocket(sock);
12675 sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
12676 ok(sock != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
12677 do_sockopt_validity_tests("IPv4 UDP", sock, IPPROTO_IP, ipv4_udp_tests);
12678 closesocket(sock);
12680 sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
12681 if (sock == INVALID_SOCKET && WSAGetLastError() == WSAEACCES)
12683 skip("Raw IPv4 sockets are not available\n");
12685 else
12687 ok(sock != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
12688 do_sockopt_validity_tests("IPv4 raw", sock, IPPROTO_IP, ipv4_raw_tests);
12689 closesocket(sock);
12692 sock = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
12693 ok(sock != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
12694 do_sockopt_validity_tests("IPv6 TCP", sock, IPPROTO_IPV6, ipv6_tcp_tests);
12695 closesocket(sock);
12697 sock = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
12698 ok(sock != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
12699 do_sockopt_validity_tests("IPv6 UDP", sock, IPPROTO_IPV6, ipv6_udp_tests);
12700 closesocket(sock);
12702 sock = socket(AF_INET6, SOCK_RAW, IPPROTO_RAW);
12703 if (sock == INVALID_SOCKET && WSAGetLastError() == WSAEACCES)
12705 skip("Raw IPv6 sockets are not available\n");
12707 else
12709 ok(sock != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
12710 do_sockopt_validity_tests("IPv6 raw", sock, IPPROTO_IPV6, ipv6_raw_tests);
12711 closesocket(sock);
12714 GetSystemWindowsDirectoryA(path, ARRAY_SIZE(path));
12715 strcat(path, "\\system.ini");
12716 file = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_ALWAYS, 0x0, NULL);
12717 do_sockopt_validity_tests("file", (SOCKET)file, SOL_SOCKET, file_handle_tests);
12718 CloseHandle(file);
12721 static void test_tcp_reset(void)
12723 static const struct timeval select_timeout;
12724 fd_set readfds, writefds, exceptfds;
12725 OVERLAPPED overlapped = {0};
12726 SOCKET client, server;
12727 DWORD size, flags = 0;
12728 int ret, len, error;
12729 char buffer[10];
12730 WSABUF wsabuf;
12732 overlapped.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
12734 tcp_socketpair(&client, &server);
12736 wsabuf.buf = buffer;
12737 wsabuf.len = sizeof(buffer);
12738 WSASetLastError(0xdeadbeef);
12739 size = 0xdeadbeef;
12740 ret = WSARecv(client, &wsabuf, 1, &size, &flags, &overlapped, NULL);
12741 ok(ret == -1, "got %d\n", ret);
12742 ok(WSAGetLastError() == ERROR_IO_PENDING, "got error %u\n", WSAGetLastError());
12744 close_with_rst(server);
12746 ret = WaitForSingleObject(overlapped.hEvent, 1000);
12747 ok(!ret, "wait failed\n");
12748 ret = GetOverlappedResult((HANDLE)client, &overlapped, &size, FALSE);
12749 todo_wine ok(!ret, "expected failure\n");
12750 todo_wine ok(GetLastError() == ERROR_NETNAME_DELETED, "got error %lu\n", GetLastError());
12751 ok(!size, "got size %lu\n", size);
12752 todo_wine ok((NTSTATUS)overlapped.Internal == STATUS_CONNECTION_RESET, "got status %#lx\n", (NTSTATUS)overlapped.Internal);
12754 len = sizeof(error);
12755 ret = getsockopt(client, SOL_SOCKET, SO_ERROR, (char *)&error, &len);
12756 ok(!ret, "got error %u\n", WSAGetLastError());
12757 todo_wine ok(!error, "got error %u\n", error);
12759 wsabuf.buf = buffer;
12760 wsabuf.len = sizeof(buffer);
12761 WSASetLastError(0xdeadbeef);
12762 size = 0xdeadbeef;
12763 ret = WSARecv(client, &wsabuf, 1, &size, &flags, &overlapped, NULL);
12764 todo_wine ok(ret == -1, "got %d\n", ret);
12765 todo_wine ok(WSAGetLastError() == WSAECONNRESET, "got error %u\n", WSAGetLastError());
12767 check_poll_todo(client, POLLERR | POLLHUP | POLLWRNORM);
12769 FD_ZERO(&readfds);
12770 FD_ZERO(&writefds);
12771 FD_ZERO(&exceptfds);
12772 FD_SET(client, &readfds);
12773 FD_SET(client, &writefds);
12774 FD_SET(client, &exceptfds);
12775 ret = select(0, &readfds, &writefds, &exceptfds, &select_timeout);
12776 ok(ret == 2, "got %d\n", ret);
12777 ok(FD_ISSET(client, &readfds), "FD should be set\n");
12778 ok(FD_ISSET(client, &writefds), "FD should be set\n");
12779 ok(!FD_ISSET(client, &exceptfds), "FD should be set\n");
12781 FD_ZERO(&exceptfds);
12782 FD_SET(client, &exceptfds);
12783 ret = select(0, NULL, NULL, &exceptfds, &select_timeout);
12784 ok(!ret, "got %d\n", ret);
12785 ok(!FD_ISSET(client, &exceptfds), "FD should be set\n");
12787 closesocket(server);
12788 CloseHandle(overlapped.hEvent);
12791 START_TEST( sock )
12793 int i;
12795 /* Leave these tests at the beginning. They depend on WSAStartup not having been
12796 * called, which is done by Init() below. */
12797 test_WithoutWSAStartup();
12798 test_WithWSAStartup();
12800 Init();
12802 test_set_getsockopt();
12803 test_so_reuseaddr();
12804 test_ip_pktinfo();
12805 test_ipv4_cmsg();
12806 test_ipv6_cmsg();
12807 test_extendedSocketOptions();
12808 test_so_debug();
12809 test_sockopt_validity();
12811 for (i = 0; i < ARRAY_SIZE(tests); i++)
12812 do_test(&tests[i]);
12814 test_UDP();
12816 test_WSASocket();
12817 test_WSADuplicateSocket();
12818 test_WSAConnectByName();
12819 test_WSAEnumNetworkEvents();
12821 test_errors();
12822 test_listen();
12823 test_select();
12824 test_accept();
12825 test_getpeername();
12826 test_getsockname();
12828 test_address_list_query();
12829 test_fionbio();
12830 test_fionread_siocatmark();
12831 test_get_extension_func();
12832 test_get_interface_list();
12833 test_keepalive_vals();
12834 test_sioRoutingInterfaceQuery();
12835 test_sioAddressListChange();
12836 test_base_handle();
12837 test_circular_queueing();
12838 test_unsupported_ioctls();
12840 test_WSASendMsg();
12841 test_WSASendTo();
12842 test_WSARecv();
12843 test_WSAPoll();
12844 test_write_watch();
12845 test_iocp();
12847 test_events();
12849 test_ipv6only();
12850 test_TransmitFile();
12851 test_AcceptEx();
12852 test_connect();
12853 test_shutdown();
12854 test_DisconnectEx();
12856 test_completion_port();
12857 test_connect_completion_port();
12858 test_shutdown_completion_port();
12859 test_bind();
12860 test_connecting_socket();
12861 test_WSAGetOverlappedResult();
12862 test_nonblocking_async_recv();
12863 test_simultaneous_async_recv();
12864 test_empty_recv();
12865 test_timeout();
12866 test_tcp_reset();
12868 /* this is an io heavy test, do it at the end so the kernel doesn't start dropping packets */
12869 test_send();
12871 Exit();