ws2_32: Manage shorter length for SO_BROADCAST.
[wine.git] / dlls / ws2_32 / tests / sock.c
bloba868bc946a75f211a9390917c1237c360298ab16
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 #define check_poll(a, b) check_poll_(__LINE__, a, POLLRDNORM | POLLRDBAND | POLLWRNORM, b, FALSE)
206 #define check_poll_todo(a, b) check_poll_(__LINE__, a, POLLRDNORM | POLLRDBAND | POLLWRNORM, b, TRUE)
207 #define check_poll_mask(a, b, c) check_poll_(__LINE__, a, b, c, FALSE)
208 #define check_poll_mask_todo(a, b, c) check_poll_(__LINE__, a, b, c, TRUE)
209 static void check_poll_(int line, SOCKET s, short mask, short expect, BOOL todo)
211 WSAPOLLFD pollfd;
212 int ret;
214 pollfd.fd = s;
215 pollfd.events = mask;
216 pollfd.revents = 0xdead;
217 ret = pWSAPoll(&pollfd, 1, 1000);
218 ok_(__FILE__, line)(ret == (pollfd.revents ? 1 : 0), "WSAPoll() returned %d\n", ret);
219 todo_wine_if (todo) ok_(__FILE__, line)(pollfd.revents == expect, "got wrong events %#x\n", pollfd.revents);
222 static void set_so_opentype ( BOOL overlapped )
224 int optval = !overlapped, newval, len = sizeof (int);
226 ok ( setsockopt ( INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE,
227 (LPVOID) &optval, sizeof (optval) ) == 0,
228 "setting SO_OPENTYPE failed\n" );
229 ok ( getsockopt ( INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE,
230 (LPVOID) &newval, &len ) == 0,
231 "getting SO_OPENTYPE failed\n" );
232 ok ( optval == newval, "failed to set SO_OPENTYPE\n" );
235 static int set_blocking ( SOCKET s, BOOL blocking )
237 u_long val = !blocking;
238 return ioctlsocket ( s, FIONBIO, &val );
241 static void fill_buffer ( char *buf, int chunk_size, int n_chunks )
243 char c, *p;
244 for ( c = FIRST_CHAR, p = buf; c < FIRST_CHAR + n_chunks; c++, p += chunk_size )
245 memset ( p, c, chunk_size );
248 static int test_buffer ( char *buf, int chunk_size, int n_chunks )
250 char c, *p;
251 int i;
252 for ( c = FIRST_CHAR, p = buf; c < FIRST_CHAR + n_chunks; c++, p += chunk_size )
254 for ( i = 0; i < chunk_size; i++ )
255 if ( p[i] != c ) return i;
257 return -1;
261 * This routine is called when a client / server does not expect any more data,
262 * but needs to acknowledge the closing of the connection (by reading 0 bytes).
264 static void read_zero_bytes ( SOCKET s )
266 char buf[256];
267 int tmp, n = 0;
268 while ( ( tmp = recv ( s, buf, 256, 0 ) ) > 0 )
269 n += tmp;
270 ok ( n <= 0, "garbage data received: %d bytes\n", n );
273 static int do_synchronous_send ( SOCKET s, char *buf, int buflen, int flags, int sendlen )
275 char* last = buf + buflen, *p;
276 int n = 1;
277 for ( p = buf; n > 0 && p < last; )
279 n = send ( s, p, min ( sendlen, last - p ), flags );
280 if (n > 0) p += n;
282 wsa_ok ( n, 0 <=, "do_synchronous_send (%x): error %d\n" );
283 return p - buf;
286 static int do_synchronous_recv ( SOCKET s, char *buf, int buflen, int flags, int recvlen )
288 char* last = buf + buflen, *p;
289 int n = 1;
290 for ( p = buf; n > 0 && p < last; )
292 n = recv ( s, p, min ( recvlen, last - p ), flags );
293 if (n > 0) p += n;
295 wsa_ok ( n, 0 <=, "do_synchronous_recv (%x): error %d:\n" );
296 return p - buf;
299 static int do_synchronous_recvfrom ( SOCKET s, char *buf, int buflen, int flags, struct sockaddr *from, int *fromlen, int recvlen )
301 char* last = buf + buflen, *p;
302 int n = 1;
303 for ( p = buf; n > 0 && p < last; )
305 n = recvfrom ( s, p, min ( recvlen, last - p ), flags, from, fromlen );
306 if (n > 0) p += n;
308 wsa_ok ( n, 0 <=, "do_synchronous_recv (%x): error %d:\n" );
309 return p - buf;
313 * Call this routine right after thread startup.
314 * SO_OPENTYPE must by 0, regardless what the server did.
316 static void check_so_opentype (void)
318 int tmp = 1, len;
319 len = sizeof (tmp);
320 getsockopt ( INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE, (LPVOID) &tmp, &len );
321 ok ( tmp == 0, "check_so_opentype: wrong startup value of SO_OPENTYPE: %d\n", tmp );
324 /**************** Server utility functions ***************/
327 * Even if we have closed our server socket cleanly,
328 * the OS may mark the address "in use" for some time -
329 * this happens with native Linux apps, too.
331 static void do_bind ( SOCKET s, struct sockaddr* addr, int addrlen )
333 int err, wsaerr = 0, n_try = BIND_TRIES;
335 while ( ( err = bind ( s, addr, addrlen ) ) != 0 &&
336 ( wsaerr = WSAGetLastError () ) == WSAEADDRINUSE &&
337 n_try-- >= 0)
339 trace ( "address in use, waiting ...\n" );
340 Sleep ( 1000 * BIND_SLEEP );
342 ok ( err == 0, "failed to bind: %d\n", wsaerr );
345 static void server_start ( server_params *par )
347 int i;
348 test_params *gen = par->general;
349 server_memory *mem = LocalAlloc ( LPTR, sizeof ( server_memory ) );
351 TlsSetValue ( tls, mem );
352 mem->s = WSASocketA ( AF_INET, gen->sock_type, gen->sock_prot,
353 NULL, 0, par->sock_flags );
354 ok ( mem->s != INVALID_SOCKET, "Server: WSASocket failed\n" );
356 mem->addr.sin_family = AF_INET;
357 mem->addr.sin_addr.s_addr = inet_addr ( gen->inet_addr );
358 mem->addr.sin_port = htons ( gen->inet_port );
360 for (i = 0; i < MAX_CLIENTS; i++)
362 mem->sock[i].s = INVALID_SOCKET;
363 mem->sock[i].buf = LocalAlloc ( LPTR, gen->n_chunks * gen->chunk_size );
364 mem->sock[i].n_recvd = 0;
365 mem->sock[i].n_sent = 0;
368 if ( gen->sock_type == SOCK_STREAM )
369 do_bind ( mem->s, (struct sockaddr*) &mem->addr, sizeof (mem->addr) );
372 static void server_stop (void)
374 int i;
375 server_memory *mem = TlsGetValue ( tls );
377 for (i = 0; i < MAX_CLIENTS; i++ )
379 LocalFree ( mem->sock[i].buf );
380 if ( mem->sock[i].s != INVALID_SOCKET )
381 closesocket ( mem->sock[i].s );
383 ok ( closesocket ( mem->s ) == 0, "closesocket failed\n" );
384 LocalFree ( mem );
385 ExitThread ( GetCurrentThreadId () );
388 /**************** Client utilitiy functions ***************/
390 static void client_start ( client_params *par )
392 test_params *gen = par->general;
393 client_memory *mem = LocalAlloc (LPTR, sizeof (client_memory));
395 TlsSetValue ( tls, mem );
397 WaitForSingleObject ( server_ready, INFINITE );
399 mem->s = WSASocketA ( AF_INET, gen->sock_type, gen->sock_prot,
400 NULL, 0, par->sock_flags );
402 mem->addr.sin_family = AF_INET;
403 mem->addr.sin_addr.s_addr = inet_addr ( gen->inet_addr );
404 mem->addr.sin_port = htons ( gen->inet_port );
406 ok ( mem->s != INVALID_SOCKET, "Client: WSASocket failed\n" );
408 mem->send_buf = LocalAlloc ( LPTR, 2 * gen->n_chunks * gen->chunk_size );
409 mem->recv_buf = mem->send_buf + gen->n_chunks * gen->chunk_size;
410 fill_buffer ( mem->send_buf, gen->chunk_size, gen->n_chunks );
412 SetEvent ( client_ready[client_id] );
413 /* Wait for the other clients to come up */
414 WaitForMultipleObjects ( min ( gen->n_clients, MAX_CLIENTS ), client_ready, TRUE, INFINITE );
417 static void client_stop (void)
419 client_memory *mem = TlsGetValue ( tls );
420 wsa_ok ( closesocket ( mem->s ), 0 ==, "closesocket error (%x): %d\n" );
421 LocalFree ( mem->send_buf );
422 LocalFree ( mem );
423 ExitThread(0);
426 /**************** Servers ***************/
429 * simple_server: A very basic server doing synchronous IO.
431 static VOID WINAPI simple_server ( server_params *par )
433 test_params *gen = par->general;
434 server_memory *mem;
435 int pos, n_recvd, n_sent, n_expected = gen->n_chunks * gen->chunk_size, tmp, i,
436 id = GetCurrentThreadId();
438 set_so_opentype ( FALSE ); /* non-overlapped */
439 server_start ( par );
440 mem = TlsGetValue ( tls );
442 wsa_ok ( set_blocking ( mem->s, TRUE ), 0 ==, "simple_server (%x): failed to set blocking mode: %d\n");
443 wsa_ok ( listen ( mem->s, SOMAXCONN ), 0 ==, "simple_server (%x): listen failed: %d\n");
445 SetEvent ( server_ready ); /* notify clients */
447 for ( i = 0; i < min ( gen->n_clients, MAX_CLIENTS ); i++ )
449 /* accept a single connection */
450 tmp = sizeof ( mem->sock[0].peer );
451 mem->sock[0].s = accept ( mem->s, (struct sockaddr*) &mem->sock[0].peer, &tmp );
452 wsa_ok ( mem->sock[0].s, INVALID_SOCKET !=, "simple_server (%x): accept failed: %d\n" );
454 ok ( mem->sock[0].peer.sin_addr.s_addr == inet_addr ( gen->inet_addr ),
455 "simple_server (%x): strange peer address\n", id );
457 /* Receive data & check it */
458 n_recvd = do_synchronous_recv ( mem->sock[0].s, mem->sock[0].buf, n_expected, 0, par->buflen );
459 ok ( n_recvd == n_expected,
460 "simple_server (%x): received less data than expected: %d of %d\n", id, n_recvd, n_expected );
461 pos = test_buffer ( mem->sock[0].buf, gen->chunk_size, gen->n_chunks );
462 ok ( pos == -1, "simple_server (%x): test pattern error: %d\n", id, pos);
464 /* Echo data back */
465 n_sent = do_synchronous_send ( mem->sock[0].s, mem->sock[0].buf, n_expected, 0, par->buflen );
466 ok ( n_sent == n_expected,
467 "simple_server (%x): sent less data than expected: %d of %d\n", id, n_sent, n_expected );
469 /* cleanup */
470 read_zero_bytes ( mem->sock[0].s );
471 wsa_ok ( closesocket ( mem->sock[0].s ), 0 ==, "simple_server (%x): closesocket error: %d\n" );
472 mem->sock[0].s = INVALID_SOCKET;
475 server_stop ();
479 * oob_server: A very basic server receiving out-of-band data.
481 static VOID WINAPI oob_server ( server_params *par )
483 test_params *gen = par->general;
484 server_memory *mem;
485 u_long atmark = 0;
486 int pos, n_sent, n_recvd, n_expected = gen->n_chunks * gen->chunk_size, tmp,
487 id = GetCurrentThreadId();
489 set_so_opentype ( FALSE ); /* non-overlapped */
490 server_start ( par );
491 mem = TlsGetValue ( tls );
493 wsa_ok ( set_blocking ( mem->s, TRUE ), 0 ==, "oob_server (%x): failed to set blocking mode: %d\n");
494 wsa_ok ( listen ( mem->s, SOMAXCONN ), 0 ==, "oob_server (%x): listen failed: %d\n");
496 SetEvent ( server_ready ); /* notify clients */
498 /* accept a single connection */
499 tmp = sizeof ( mem->sock[0].peer );
500 mem->sock[0].s = accept ( mem->s, (struct sockaddr*) &mem->sock[0].peer, &tmp );
501 wsa_ok ( mem->sock[0].s, INVALID_SOCKET !=, "oob_server (%x): accept failed: %d\n" );
503 ok ( mem->sock[0].peer.sin_addr.s_addr == inet_addr ( gen->inet_addr ),
504 "oob_server (%x): strange peer address\n", id );
506 /* check initial atmark state */
507 ioctlsocket ( mem->sock[0].s, SIOCATMARK, &atmark );
508 ok ( atmark == 1, "oob_server (%x): unexpectedly at the OOB mark: %i\n", id, atmark );
510 /* Receive normal data */
511 n_recvd = do_synchronous_recv ( mem->sock[0].s, mem->sock[0].buf, n_expected, 0, par->buflen );
512 ok ( n_recvd == n_expected,
513 "oob_server (%x): received less data than expected: %d of %d\n", id, n_recvd, n_expected );
514 pos = test_buffer ( mem->sock[0].buf, gen->chunk_size, gen->n_chunks );
515 ok ( pos == -1, "oob_server (%x): test pattern error: %d\n", id, pos);
517 /* check atmark state */
518 ioctlsocket ( mem->sock[0].s, SIOCATMARK, &atmark );
519 ok ( atmark == 1, "oob_server (%x): unexpectedly at the OOB mark: %i\n", id, atmark );
521 /* Echo data back */
522 n_sent = do_synchronous_send ( mem->sock[0].s, mem->sock[0].buf, n_expected, 0, par->buflen );
523 ok ( n_sent == n_expected,
524 "oob_server (%x): sent less data than expected: %d of %d\n", id, n_sent, n_expected );
526 /* Receive a part of the out-of-band data and print atmark state */
527 n_recvd = do_synchronous_recv ( mem->sock[0].s, mem->sock[0].buf, 8, 0, par->buflen );
528 ok ( n_recvd == 8,
529 "oob_server (%x): received less data than expected: %d of %d\n", id, n_recvd, 8 );
530 n_expected -= 8;
532 ioctlsocket ( mem->sock[0].s, SIOCATMARK, &atmark );
534 /* Receive the rest of the out-of-band data and check atmark state */
535 do_synchronous_recv ( mem->sock[0].s, mem->sock[0].buf, n_expected, 0, par->buflen );
537 ioctlsocket ( mem->sock[0].s, SIOCATMARK, &atmark );
538 todo_wine ok ( atmark == 0, "oob_server (%x): not at the OOB mark: %i\n", id, atmark );
540 /* cleanup */
541 wsa_ok ( closesocket ( mem->sock[0].s ), 0 ==, "oob_server (%x): closesocket error: %d\n" );
542 mem->sock[0].s = INVALID_SOCKET;
544 server_stop ();
548 * select_server: A non-blocking server.
550 static VOID WINAPI select_server ( server_params *par )
552 test_params *gen = par->general;
553 server_memory *mem;
554 int n_expected = gen->n_chunks * gen->chunk_size, tmp, i,
555 id = GetCurrentThreadId(), n_connections = 0, n_sent, n_recvd,
556 n_set, delta, n_ready;
557 struct timeval timeout = {0,10}; /* wait for 10 milliseconds */
558 fd_set fds_recv, fds_send, fds_openrecv, fds_opensend;
560 set_so_opentype ( FALSE ); /* non-overlapped */
561 server_start ( par );
562 mem = TlsGetValue ( tls );
564 wsa_ok ( set_blocking ( mem->s, FALSE ), 0 ==, "select_server (%x): failed to set blocking mode: %d\n");
565 wsa_ok ( listen ( mem->s, SOMAXCONN ), 0 ==, "select_server (%x): listen failed: %d\n");
567 SetEvent ( server_ready ); /* notify clients */
569 FD_ZERO ( &fds_openrecv );
570 FD_ZERO ( &fds_recv );
571 FD_ZERO ( &fds_send );
572 FD_ZERO ( &fds_opensend );
574 FD_SET ( mem->s, &fds_openrecv );
576 while(1)
578 fds_recv = fds_openrecv;
579 fds_send = fds_opensend;
581 n_set = 0;
583 wsa_ok ( ( n_ready = select ( 0, &fds_recv, &fds_send, NULL, &timeout ) ), SOCKET_ERROR !=,
584 "select_server (%x): select() failed: %d\n" );
586 /* check for incoming requests */
587 if ( FD_ISSET ( mem->s, &fds_recv ) ) {
588 n_set += 1;
590 /* accept a single connection */
591 tmp = sizeof ( mem->sock[n_connections].peer );
592 mem->sock[n_connections].s = accept ( mem->s, (struct sockaddr*) &mem->sock[n_connections].peer, &tmp );
593 wsa_ok ( mem->sock[n_connections].s, INVALID_SOCKET !=, "select_server (%x): accept() failed: %d\n" );
595 ok ( mem->sock[n_connections].peer.sin_addr.s_addr == inet_addr ( gen->inet_addr ),
596 "select_server (%x): strange peer address\n", id );
598 /* add to list of open connections */
599 FD_SET ( mem->sock[n_connections].s, &fds_openrecv );
600 FD_SET ( mem->sock[n_connections].s, &fds_opensend );
602 n_connections++;
605 /* handle open requests */
607 for ( i = 0; i < n_connections; i++ )
609 if ( FD_ISSET( mem->sock[i].s, &fds_recv ) ) {
610 n_set += 1;
612 if ( mem->sock[i].n_recvd < n_expected ) {
613 /* Receive data & check it */
614 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 );
615 ok ( n_recvd != SOCKET_ERROR, "select_server (%x): error in recv(): %d\n", id, WSAGetLastError() );
616 mem->sock[i].n_recvd += n_recvd;
618 if ( mem->sock[i].n_recvd == n_expected ) {
619 int pos = test_buffer ( mem->sock[i].buf, gen->chunk_size, gen->n_chunks );
620 ok ( pos == -1, "select_server (%x): test pattern error: %d\n", id, pos );
621 FD_CLR ( mem->sock[i].s, &fds_openrecv );
624 ok ( mem->sock[i].n_recvd <= n_expected, "select_server (%x): received too many bytes: %d\n", id, mem->sock[i].n_recvd );
628 /* only echo back what we've received */
629 delta = mem->sock[i].n_recvd - mem->sock[i].n_sent;
631 if ( FD_ISSET ( mem->sock[i].s, &fds_send ) ) {
632 n_set += 1;
634 if ( ( delta > 0 ) && ( mem->sock[i].n_sent < n_expected ) ) {
635 /* Echo data back */
636 n_sent = send ( mem->sock[i].s, mem->sock[i].buf + mem->sock[i].n_sent, min ( delta, par->buflen ), 0 );
637 ok ( n_sent != SOCKET_ERROR, "select_server (%x): error in send(): %d\n", id, WSAGetLastError() );
638 mem->sock[i].n_sent += n_sent;
640 if ( mem->sock[i].n_sent == n_expected ) {
641 FD_CLR ( mem->sock[i].s, &fds_opensend );
644 ok ( mem->sock[i].n_sent <= n_expected, "select_server (%x): sent too many bytes: %d\n", id, mem->sock[i].n_sent );
649 /* check that select returned the correct number of ready sockets */
650 ok ( ( n_set == n_ready ), "select_server (%x): select() returns wrong number of ready sockets\n", id );
652 /* check if all clients are done */
653 if ( ( fds_opensend.fd_count == 0 )
654 && ( fds_openrecv.fd_count == 1 ) /* initial socket that accepts clients */
655 && ( n_connections == min ( gen->n_clients, MAX_CLIENTS ) ) ) {
656 break;
660 for ( i = 0; i < min ( gen->n_clients, MAX_CLIENTS ); i++ )
662 /* cleanup */
663 read_zero_bytes ( mem->sock[i].s );
664 wsa_ok ( closesocket ( mem->sock[i].s ), 0 ==, "select_server (%x): closesocket error: %d\n" );
665 mem->sock[i].s = INVALID_SOCKET;
668 server_stop ();
671 /**************** Clients ***************/
674 * simple_client: A very basic client doing synchronous IO.
676 static VOID WINAPI simple_client ( client_params *par )
678 test_params *gen = par->general;
679 client_memory *mem;
680 int pos, n_sent, n_recvd, n_expected = gen->n_chunks * gen->chunk_size, id;
682 id = GetCurrentThreadId();
683 /* wait here because we want to call set_so_opentype before creating a socket */
684 WaitForSingleObject ( server_ready, INFINITE );
686 check_so_opentype ();
687 set_so_opentype ( FALSE ); /* non-overlapped */
688 client_start ( par );
689 mem = TlsGetValue ( tls );
691 /* Connect */
692 wsa_ok ( connect ( mem->s, (struct sockaddr*) &mem->addr, sizeof ( mem->addr ) ),
693 0 ==, "simple_client (%x): connect error: %d\n" );
694 ok ( set_blocking ( mem->s, TRUE ) == 0,
695 "simple_client (%x): failed to set blocking mode\n", id );
697 /* send data to server */
698 n_sent = do_synchronous_send ( mem->s, mem->send_buf, n_expected, 0, par->buflen );
699 ok ( n_sent == n_expected,
700 "simple_client (%x): sent less data than expected: %d of %d\n", id, n_sent, n_expected );
702 /* shutdown send direction */
703 wsa_ok ( shutdown ( mem->s, SD_SEND ), 0 ==, "simple_client (%x): shutdown failed: %d\n" );
705 /* Receive data echoed back & check it */
706 n_recvd = do_synchronous_recv ( mem->s, mem->recv_buf, n_expected, 0, par->buflen );
707 ok ( n_recvd == n_expected,
708 "simple_client (%x): received less data than expected: %d of %d\n", id, n_recvd, n_expected );
710 /* check data */
711 pos = test_buffer ( mem->recv_buf, gen->chunk_size, gen->n_chunks );
712 ok ( pos == -1, "simple_client (%x): test pattern error: %d\n", id, pos);
714 /* cleanup */
715 read_zero_bytes ( mem->s );
716 client_stop ();
720 * oob_client: A very basic client sending out-of-band data.
722 static VOID WINAPI oob_client ( client_params *par )
724 test_params *gen = par->general;
725 client_memory *mem;
726 int pos, n_sent, n_recvd, n_expected = gen->n_chunks * gen->chunk_size, id;
728 id = GetCurrentThreadId();
729 /* wait here because we want to call set_so_opentype before creating a socket */
730 WaitForSingleObject ( server_ready, INFINITE );
732 check_so_opentype ();
733 set_so_opentype ( FALSE ); /* non-overlapped */
734 client_start ( par );
735 mem = TlsGetValue ( tls );
737 /* Connect */
738 wsa_ok ( connect ( mem->s, (struct sockaddr*) &mem->addr, sizeof ( mem->addr ) ),
739 0 ==, "oob_client (%x): connect error: %d\n" );
740 ok ( set_blocking ( mem->s, TRUE ) == 0,
741 "oob_client (%x): failed to set blocking mode\n", id );
743 /* send data to server */
744 n_sent = do_synchronous_send ( mem->s, mem->send_buf, n_expected, 0, par->buflen );
745 ok ( n_sent == n_expected,
746 "oob_client (%x): sent less data than expected: %d of %d\n", id, n_sent, n_expected );
748 /* Receive data echoed back & check it */
749 n_recvd = do_synchronous_recv ( mem->s, mem->recv_buf, n_expected, 0, par->buflen );
750 ok ( n_recvd == n_expected,
751 "simple_client (%x): received less data than expected: %d of %d\n", id, n_recvd, n_expected );
752 pos = test_buffer ( mem->recv_buf, gen->chunk_size, gen->n_chunks );
753 ok ( pos == -1, "simple_client (%x): test pattern error: %d\n", id, pos);
755 /* send out-of-band data to server */
756 n_sent = do_synchronous_send ( mem->s, mem->send_buf, n_expected, MSG_OOB, par->buflen );
757 ok ( n_sent == n_expected,
758 "oob_client (%x): sent less data than expected: %d of %d\n", id, n_sent, n_expected );
760 /* shutdown send direction */
761 wsa_ok ( shutdown ( mem->s, SD_SEND ), 0 ==, "simple_client (%x): shutdown failed: %d\n" );
763 /* cleanup */
764 read_zero_bytes ( mem->s );
765 client_stop ();
769 * simple_mixed_client: mixing send and recvfrom
771 static VOID WINAPI simple_mixed_client ( client_params *par )
773 test_params *gen = par->general;
774 client_memory *mem;
775 int pos, n_sent, n_recvd, n_expected = gen->n_chunks * gen->chunk_size, id;
776 int fromLen = sizeof(mem->addr);
777 struct sockaddr test;
779 id = GetCurrentThreadId();
780 /* wait here because we want to call set_so_opentype before creating a socket */
781 WaitForSingleObject ( server_ready, INFINITE );
783 check_so_opentype ();
784 set_so_opentype ( FALSE ); /* non-overlapped */
785 client_start ( par );
786 mem = TlsGetValue ( tls );
788 /* Connect */
789 wsa_ok ( connect ( mem->s, (struct sockaddr*) &mem->addr, sizeof ( mem->addr ) ),
790 0 ==, "simple_client (%x): connect error: %d\n" );
791 ok ( set_blocking ( mem->s, TRUE ) == 0,
792 "simple_client (%x): failed to set blocking mode\n", id );
794 /* send data to server */
795 n_sent = do_synchronous_send ( mem->s, mem->send_buf, n_expected, 0, par->buflen );
796 ok ( n_sent == n_expected,
797 "simple_client (%x): sent less data than expected: %d of %d\n", id, n_sent, n_expected );
799 /* shutdown send direction */
800 wsa_ok ( shutdown ( mem->s, SD_SEND ), 0 ==, "simple_client (%x): shutdown failed: %d\n" );
802 /* this shouldn't change, since lpFrom, is not updated on
803 connection oriented sockets - exposed by bug 11640
805 ((struct sockaddr_in*)&test)->sin_addr.s_addr = inet_addr("0.0.0.0");
807 /* Receive data echoed back & check it */
808 n_recvd = do_synchronous_recvfrom ( mem->s,
809 mem->recv_buf,
810 n_expected,
812 (struct sockaddr *)&test,
813 &fromLen,
814 par->buflen );
815 ok ( n_recvd == n_expected,
816 "simple_client (%x): received less data than expected: %d of %d\n", id, n_recvd, n_expected );
818 /* check that lpFrom was not updated */
819 ok(0 ==
820 strcmp(
821 inet_ntoa(((struct sockaddr_in*)&test)->sin_addr),
822 "0.0.0.0"), "lpFrom shouldn't be updated on connection oriented sockets\n");
824 /* check data */
825 pos = test_buffer ( mem->recv_buf, gen->chunk_size, gen->n_chunks );
826 ok ( pos == -1, "simple_client (%x): test pattern error: %d\n", id, pos);
828 /* cleanup */
829 read_zero_bytes ( mem->s );
830 client_stop ();
834 * event_client: An event-driven client
836 static void WINAPI event_client ( client_params *par )
838 test_params *gen = par->general;
839 client_memory *mem;
840 int id = GetCurrentThreadId(), n_expected = gen->n_chunks * gen->chunk_size,
841 tmp, err, n;
842 HANDLE event;
843 WSANETWORKEVENTS wsa_events;
844 char *send_last, *recv_last, *send_p, *recv_p;
845 LONG mask = FD_READ | FD_WRITE | FD_CLOSE;
847 client_start ( par );
849 mem = TlsGetValue ( tls );
851 /* Prepare event notification for connect, makes socket nonblocking */
852 event = WSACreateEvent ();
853 WSAEventSelect ( mem->s, event, FD_CONNECT );
854 tmp = connect ( mem->s, (struct sockaddr*) &mem->addr, sizeof ( mem->addr ) );
855 if ( tmp != 0 ) {
856 err = WSAGetLastError ();
857 ok ( err == WSAEWOULDBLOCK, "event_client (%x): connect error: %d\n", id, err );
858 tmp = WaitForSingleObject ( event, INFINITE );
859 ok ( tmp == WAIT_OBJECT_0, "event_client (%x): wait for connect event failed: %d\n", id, tmp );
860 err = WSAEnumNetworkEvents ( mem->s, event, &wsa_events );
861 ok ( err == 0, "event_client (%x): WSAEnumNetworkEvents error: %d\n", id, err );
862 err = wsa_events.iErrorCode[ FD_CONNECT_BIT ];
863 ok ( err == 0, "event_client (%x): connect error: %d\n", id, err );
864 if ( err ) goto out;
867 WSAEventSelect ( mem->s, event, mask );
869 recv_p = mem->recv_buf;
870 recv_last = mem->recv_buf + n_expected;
871 send_p = mem->send_buf;
872 send_last = mem->send_buf + n_expected;
874 while ( TRUE )
876 err = WaitForSingleObject ( event, INFINITE );
877 ok ( err == WAIT_OBJECT_0, "event_client (%x): wait failed\n", id );
879 err = WSAEnumNetworkEvents ( mem->s, event, &wsa_events );
880 ok( err == 0, "event_client (%x): WSAEnumNetworkEvents error: %d\n", id, err );
882 if ( wsa_events.lNetworkEvents & FD_WRITE )
884 err = wsa_events.iErrorCode[ FD_WRITE_BIT ];
885 ok ( err == 0, "event_client (%x): FD_WRITE error code: %d\n", id, err );
887 if ( err== 0 )
890 n = send ( mem->s, send_p, min ( send_last - send_p, par->buflen ), 0 );
891 if ( n < 0 )
893 err = WSAGetLastError ();
894 ok ( err == WSAEWOULDBLOCK, "event_client (%x): send error: %d\n", id, err );
896 else
897 send_p += n;
899 while ( n >= 0 && send_p < send_last );
901 if ( send_p == send_last )
903 shutdown ( mem->s, SD_SEND );
904 mask &= ~FD_WRITE;
905 WSAEventSelect ( mem->s, event, mask );
908 if ( wsa_events.lNetworkEvents & FD_READ )
910 err = wsa_events.iErrorCode[ FD_READ_BIT ];
911 ok ( err == 0, "event_client (%x): FD_READ error code: %d\n", id, err );
912 if ( err != 0 ) break;
914 /* First read must succeed */
915 n = recv ( mem->s, recv_p, min ( recv_last - recv_p, par->buflen ), 0 );
916 wsa_ok ( n, 0 <=, "event_client (%x): recv error: %d\n" );
918 while ( n >= 0 ) {
919 recv_p += n;
920 if ( recv_p == recv_last )
922 mask &= ~FD_READ;
923 WSAEventSelect ( mem->s, event, mask );
924 break;
926 n = recv ( mem->s, recv_p, min ( recv_last - recv_p, par->buflen ), 0 );
927 ok(n >= 0 || WSAGetLastError() == WSAEWOULDBLOCK,
928 "event_client (%x): got error %u\n", id, WSAGetLastError());
932 if ( wsa_events.lNetworkEvents & FD_CLOSE )
934 err = wsa_events.iErrorCode[ FD_CLOSE_BIT ];
935 ok ( err == 0, "event_client (%x): FD_CLOSE error code: %d\n", id, err );
936 break;
940 n = send_p - mem->send_buf;
941 ok ( send_p == send_last,
942 "simple_client (%x): sent less data than expected: %d of %d\n", id, n, n_expected );
943 n = recv_p - mem->recv_buf;
944 ok ( recv_p == recv_last,
945 "simple_client (%x): received less data than expected: %d of %d\n", id, n, n_expected );
946 n = test_buffer ( mem->recv_buf, gen->chunk_size, gen->n_chunks );
947 ok ( n == -1, "event_client (%x): test pattern error: %d\n", id, n);
949 out:
950 WSACloseEvent ( event );
951 client_stop ();
954 /* Tests for WSAStartup */
955 static void test_WithoutWSAStartup(void)
957 DWORD err;
959 WSASetLastError(0xdeadbeef);
960 ok(WSASocketA(0, 0, 0, NULL, 0, 0) == INVALID_SOCKET, "WSASocketA should have failed\n");
961 err = WSAGetLastError();
962 ok(err == WSANOTINITIALISED, "Expected 10093, received %d\n", err);
964 WSASetLastError(0xdeadbeef);
965 ok(gethostbyname("localhost") == NULL, "gethostbyname() succeeded unexpectedly\n");
966 err = WSAGetLastError();
967 ok(err == WSANOTINITIALISED, "Expected 10093, received %d\n", err);
970 static void test_WithWSAStartup(void)
972 WSADATA data;
973 WORD version = MAKEWORD( 2, 2 );
974 INT res, socks, i, j;
975 SOCKET sock;
976 LPVOID ptr;
977 struct
979 SOCKET src, dst, dup_src, dup_dst;
980 } pairs[32];
981 DWORD error;
983 res = WSAStartup( version, &data );
984 ok(res == 0, "WSAStartup() failed unexpectedly: %d\n", res);
986 ptr = gethostbyname("localhost");
987 ok(ptr != NULL, "gethostbyname() failed unexpectedly: %d\n", WSAGetLastError());
989 /* Alloc some sockets to check if they are destroyed on WSACleanup */
990 for (socks = 0; socks < ARRAY_SIZE(pairs); socks++)
992 WSAPROTOCOL_INFOA info;
993 tcp_socketpair(&pairs[socks].src, &pairs[socks].dst);
995 memset(&info, 0, sizeof(info));
996 ok(!WSADuplicateSocketA(pairs[socks].src, GetCurrentProcessId(), &info),
997 "WSADuplicateSocketA should have worked\n");
998 pairs[socks].dup_src = WSASocketA(0, 0, 0, &info, 0, 0);
999 ok(pairs[socks].dup_src != SOCKET_ERROR, "expected != -1\n");
1001 memset(&info, 0, sizeof(info));
1002 ok(!WSADuplicateSocketA(pairs[socks].dst, GetCurrentProcessId(), &info),
1003 "WSADuplicateSocketA should have worked\n");
1004 pairs[socks].dup_dst = WSASocketA(0, 0, 0, &info, 0, 0);
1005 ok(pairs[socks].dup_dst != SOCKET_ERROR, "expected != -1\n");
1008 res = send(pairs[0].src, "TEST", 4, 0);
1009 ok(res == 4, "send failed with error %d\n", WSAGetLastError());
1011 WSACleanup();
1013 res = WSAStartup( version, &data );
1014 ok(res == 0, "WSAStartup() failed unexpectedly: %d\n", res);
1016 /* show that sockets are destroyed automatically after WSACleanup */
1017 SetLastError(0xdeadbeef);
1018 res = send(pairs[0].src, "TEST", 4, 0);
1019 error = WSAGetLastError();
1020 ok(res == SOCKET_ERROR, "send should have failed\n");
1021 ok(error == WSAENOTSOCK, "expected 10038, got %d\n", error);
1023 SetLastError(0xdeadbeef);
1024 res = send(pairs[0].dst, "TEST", 4, 0);
1025 error = WSAGetLastError();
1026 ok(res == SOCKET_ERROR, "send should have failed\n");
1027 ok(error == WSAENOTSOCK, "expected 10038, got %d\n", error);
1029 /* Check that all sockets were destroyed */
1030 for (i = 0; i < socks; i++)
1032 for (j = 0; j < 4; j++)
1034 struct sockaddr_in saddr;
1035 int size = sizeof(saddr);
1036 switch(j)
1038 case 0: sock = pairs[i].src; break;
1039 case 1: sock = pairs[i].dup_src; break;
1040 case 2: sock = pairs[i].dst; break;
1041 case 3: sock = pairs[i].dup_dst; break;
1044 SetLastError(0xdeadbeef);
1045 res = getsockname(sock, (struct sockaddr *)&saddr, &size);
1046 error = WSAGetLastError();
1047 ok(res == SOCKET_ERROR, "Test[%d]: getsockname should have failed\n", i);
1048 if (res == SOCKET_ERROR)
1049 ok(error == WSAENOTSOCK, "Test[%d]: expected 10038, got %d\n", i, error);
1053 /* While wine is not fixed, close all sockets manually */
1054 for (i = 0; i < socks; i++)
1056 closesocket(pairs[i].src);
1057 closesocket(pairs[i].dst);
1058 closesocket(pairs[i].dup_src);
1059 closesocket(pairs[i].dup_dst);
1062 res = WSACleanup();
1063 ok(res == 0, "expected 0, got %d\n", res);
1064 WSASetLastError(0xdeadbeef);
1065 res = WSACleanup();
1066 error = WSAGetLastError();
1067 ok ( res == SOCKET_ERROR && error == WSANOTINITIALISED,
1068 "WSACleanup returned %d WSAGetLastError is %d\n", res, error);
1071 /**************** Main program utility functions ***************/
1073 static void Init (void)
1075 WORD ver = MAKEWORD (2, 2);
1076 WSADATA data;
1077 HMODULE hws2_32 = GetModuleHandleA("ws2_32.dll"), ntdll;
1079 pWSAPoll = (void *)GetProcAddress(hws2_32, "WSAPoll");
1081 ntdll = LoadLibraryA("ntdll.dll");
1082 if (ntdll)
1083 pNtClose = (void *)GetProcAddress(ntdll, "NtClose");
1085 ok ( WSAStartup ( ver, &data ) == 0, "WSAStartup failed\n" );
1086 tls = TlsAlloc();
1089 static void Exit (void)
1091 INT ret, err;
1092 TlsFree ( tls );
1093 ret = WSACleanup();
1094 err = WSAGetLastError();
1095 ok ( ret == 0, "WSACleanup failed ret = %d GetLastError is %d\n", ret, err);
1098 static void StartServer (LPTHREAD_START_ROUTINE routine,
1099 test_params *general, server_params *par)
1101 par->general = general;
1102 thread[0] = CreateThread ( NULL, 0, routine, par, 0, &thread_id[0] );
1103 ok ( thread[0] != NULL, "Failed to create server thread\n" );
1106 static void StartClients (LPTHREAD_START_ROUTINE routine,
1107 test_params *general, client_params *par)
1109 int i;
1110 par->general = general;
1111 for ( i = 1; i <= min ( general->n_clients, MAX_CLIENTS ); i++ )
1113 client_id = i - 1;
1114 thread[i] = CreateThread ( NULL, 0, routine, par, 0, &thread_id[i] );
1115 ok ( thread[i] != NULL, "Failed to create client thread\n" );
1116 /* Make sure the client is up and running */
1117 WaitForSingleObject ( client_ready[client_id], INFINITE );
1121 static void do_test( test_setup *test )
1123 DWORD i, n = min (test->general.n_clients, MAX_CLIENTS);
1124 DWORD wait;
1126 server_ready = CreateEventA ( NULL, TRUE, FALSE, NULL );
1127 for (i = 0; i <= n; i++)
1128 client_ready[i] = CreateEventA ( NULL, TRUE, FALSE, NULL );
1130 StartServer ( test->srv, &test->general, &test->srv_params );
1131 StartClients ( test->clt, &test->general, &test->clt_params );
1132 WaitForSingleObject ( server_ready, INFINITE );
1134 wait = WaitForMultipleObjects ( 1 + n, thread, TRUE, 1000 * TEST_TIMEOUT );
1135 ok(!wait, "wait failed, error %u\n", wait);
1137 CloseHandle ( server_ready );
1138 for (i = 0; i <= n; i++)
1139 CloseHandle ( client_ready[i] );
1142 /********* some tests for getsockopt(setsockopt(X)) == X ***********/
1143 /* optname = SO_LINGER */
1144 static const LINGER linger_testvals[] = {
1145 {0,0},
1146 {0,73},
1147 {1,0},
1148 {5,189}
1151 /* optname = SO_RCVTIMEO, SOSNDTIMEO */
1152 #define SOCKTIMEOUT1 63000 /* 63 seconds. Do not test fractional part because of a
1153 bug in the linux kernel (fixed in 2.6.8) */
1154 #define SOCKTIMEOUT2 997000 /* 997 seconds */
1156 static void test_set_getsockopt(void)
1158 static struct
1160 int af;
1161 int type;
1162 int level;
1163 int optname;
1164 BOOL accepts_short_len;
1165 unsigned int sizes[3];
1166 DWORD values[3];
1167 BOOL accepts_large_value;
1168 BOOL bool_value;
1170 test_optsize[] =
1172 {AF_INET, SOCK_DGRAM, SOL_SOCKET, SO_BROADCAST, TRUE, {1, 1, 4}, {0, 0xdead0001, 0}, TRUE, TRUE},
1173 {AF_INET, SOCK_STREAM, SOL_SOCKET, SO_RCVTIMEO, FALSE, {1, 2, 4}, {0}, TRUE},
1174 {AF_INET, SOCK_STREAM, SOL_SOCKET, SO_SNDTIMEO, FALSE, {1, 2, 4}, {0}, TRUE},
1175 {AF_INET, SOCK_DGRAM, IPPROTO_IP, IP_MULTICAST_LOOP, TRUE, {1, 1, 4}, {0}, TRUE, TRUE},
1176 {AF_INET, SOCK_DGRAM, IPPROTO_IP, IP_MULTICAST_TTL, TRUE, {1, 1, 4}, {0}, FALSE},
1177 {AF_INET, SOCK_DGRAM, IPPROTO_IP, IP_TOS, TRUE, {1, 1, 4}, {0}, FALSE},
1178 {AF_INET, SOCK_DGRAM, IPPROTO_IP, IP_TTL, TRUE, {1, 1, 4}, {0}, FALSE},
1180 SOCKET s, s2;
1181 int i, j, err, lasterr;
1182 int timeout;
1183 LINGER lingval;
1184 int size;
1185 WSAPROTOCOL_INFOA infoA;
1186 WSAPROTOCOL_INFOW infoW;
1187 char providername[WSAPROTOCOL_LEN + 1];
1188 DWORD expected_last_error, expected_value;
1189 int expected_err, expected_size;
1190 DWORD value, save_value;
1191 UINT64 value64;
1193 struct _prottest
1195 int family, type, proto;
1196 } prottest[] = {
1197 {AF_INET, SOCK_STREAM, IPPROTO_TCP},
1198 {AF_INET, SOCK_DGRAM, IPPROTO_UDP},
1199 {AF_INET6, SOCK_STREAM, IPPROTO_TCP},
1200 {AF_INET6, SOCK_DGRAM, IPPROTO_UDP}
1202 union _csspace
1204 CSADDR_INFO cs;
1205 char space[128];
1206 } csinfoA, csinfoB;
1208 s = socket(AF_INET, SOCK_STREAM, 0);
1209 ok(s!=INVALID_SOCKET, "socket() failed error: %d\n", WSAGetLastError());
1210 if( s == INVALID_SOCKET) return;
1211 /* SO_RCVTIMEO */
1212 timeout = SOCKTIMEOUT1;
1213 size = sizeof(timeout);
1214 err = setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char *) &timeout, size);
1215 if( !err)
1216 err = getsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char *) &timeout, &size);
1217 ok( !err, "get/setsockopt(SO_RCVTIMEO) failed error: %d\n", WSAGetLastError());
1218 ok( timeout == SOCKTIMEOUT1, "getsockopt(SO_RCVTIMEO) returned wrong value %d\n", timeout);
1220 timeout = 0;
1221 size = sizeof(timeout);
1222 err = setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char *) &timeout, size);
1223 if( !err)
1224 err = getsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char *) &timeout, &size);
1225 ok( !err, "get/setsockopt(SO_RCVTIMEO) failed error: %d\n", WSAGetLastError());
1226 ok( timeout == 0, "getsockopt(SO_RCVTIMEO) returned wrong value %d\n", timeout);
1228 /* SO_SNDTIMEO */
1229 timeout = SOCKTIMEOUT2; /* 997 seconds. See remark above */
1230 size = sizeof(timeout);
1231 err = setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, (char *) &timeout, size);
1232 if( !err)
1233 err = getsockopt(s, SOL_SOCKET, SO_SNDTIMEO, (char *) &timeout, &size);
1234 ok( !err, "get/setsockopt(SO_SNDTIMEO) failed error: %d\n", WSAGetLastError());
1235 ok( timeout == SOCKTIMEOUT2, "getsockopt(SO_SNDTIMEO) returned wrong value %d\n", timeout);
1237 /* SO_SNDBUF */
1238 value = 4096;
1239 size = sizeof(value);
1240 err = setsockopt(s, SOL_SOCKET, SO_SNDBUF, (char *)&value, size);
1241 ok( !err, "setsockopt(SO_SNDBUF) failed error: %u\n", WSAGetLastError() );
1242 value = 0xdeadbeef;
1243 err = getsockopt(s, SOL_SOCKET, SO_SNDBUF, (char *)&value, &size);
1244 ok( !err, "getsockopt(SO_SNDBUF) failed error: %u\n", WSAGetLastError() );
1245 ok( value == 4096, "expected 4096, got %u\n", value );
1247 /* SO_RCVBUF */
1248 value = 4096;
1249 size = sizeof(value);
1250 err = setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&value, size);
1251 ok( !err, "setsockopt(SO_RCVBUF) failed error: %u\n", WSAGetLastError() );
1252 value = 0xdeadbeef;
1253 err = getsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&value, &size);
1254 ok( !err, "getsockopt(SO_RCVBUF) failed error: %u\n", WSAGetLastError() );
1255 ok( value == 4096, "expected 4096, got %u\n", value );
1257 /* SO_LINGER */
1258 for( i = 0; i < ARRAY_SIZE(linger_testvals);i++) {
1259 size = sizeof(lingval);
1260 lingval = linger_testvals[i];
1261 err = setsockopt(s, SOL_SOCKET, SO_LINGER, (char *)&lingval, size);
1262 ok(!err, "Test %u: failed to set SO_LINGER, error %u\n", i, WSAGetLastError());
1263 err = getsockopt(s, SOL_SOCKET, SO_LINGER, (char *)&lingval, &size);
1264 ok(!err, "Test %u: failed to get SO_LINGER, error %u\n", i, WSAGetLastError());
1265 ok(!lingval.l_onoff == !linger_testvals[i].l_onoff, "Test %u: expected %d, got %d\n",
1266 i, linger_testvals[i].l_onoff, lingval.l_onoff);
1267 if (lingval.l_onoff)
1268 ok(lingval.l_linger == linger_testvals[i].l_linger, "Test %u: expected %d, got %d\n",
1269 i, linger_testvals[i].l_linger, lingval.l_linger);
1272 size = sizeof(lingval);
1273 err = setsockopt(s, SOL_SOCKET, SO_LINGER, NULL, size);
1274 ok(err == SOCKET_ERROR && WSAGetLastError() == WSAEFAULT,
1275 "got %d with %d (expected SOCKET_ERROR with WSAEFAULT)\n", err, WSAGetLastError());
1276 err = setsockopt(s, SOL_SOCKET, SO_LINGER, NULL, 0);
1277 ok(err == SOCKET_ERROR && WSAGetLastError() == WSAEFAULT,
1278 "got %d with %d (expected SOCKET_ERROR with WSAEFAULT)\n", err, WSAGetLastError());
1280 size = sizeof(BOOL);
1281 err = setsockopt(s, SOL_SOCKET, SO_DONTLINGER, NULL, size);
1282 ok(err == SOCKET_ERROR && WSAGetLastError() == WSAEFAULT,
1283 "got %d with %d (expected SOCKET_ERROR with WSAEFAULT)\n", err, WSAGetLastError());
1284 err = setsockopt(s, SOL_SOCKET, SO_DONTLINGER, NULL, 0);
1285 ok(err == SOCKET_ERROR && WSAGetLastError() == WSAEFAULT,
1286 "got %d with %d (expected SOCKET_ERROR with WSAEFAULT)\n", err, WSAGetLastError());
1288 /* TCP_NODELAY: optlen doesn't matter on windows, it should work with any positive value */
1289 size = sizeof(value);
1291 value = 1;
1292 err = setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char*)&value, 1);
1293 ok (!err, "setsockopt TCP_NODELAY failed with optlen == 1\n");
1294 value = 0xff;
1295 err = getsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char*)&value, &size);
1296 ok(!err, "getsockopt TCP_NODELAY failed\n");
1297 ok(value == 1, "TCP_NODELAY should be 1\n");
1298 value = 0;
1299 err = setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char*)&value, sizeof(value));
1300 ok(!err, "Failed to reset TCP_NODELAY to 0\n");
1302 value = 1;
1303 err = setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char*)&value, 4);
1304 ok (!err, "setsockopt TCP_NODELAY failed with optlen == 4\n");
1305 value = 0xff;
1306 err = getsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char*)&value, &size);
1307 ok(!err, "getsockopt TCP_NODELAY failed\n");
1308 ok(value == 1, "TCP_NODELAY should be 1\n");
1309 value = 0;
1310 err = setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char*)&value, sizeof(value));
1311 ok(!err, "Failed to reset TCP_NODELAY to 0\n");
1313 value = 1;
1314 err = setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char*)&value, 42);
1315 ok (!err, "setsockopt TCP_NODELAY failed with optlen == 42\n");
1316 value = 0xff;
1317 err = getsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char*)&value, &size);
1318 ok(!err, "getsockopt TCP_NODELAY failed\n");
1319 ok(value == 1, "TCP_NODELAY should be 1\n");
1320 value = 0;
1321 err = setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char*)&value, sizeof(value));
1322 ok(!err, "Failed to reset TCP_NODELAY to 0\n");
1324 value = 1;
1325 err = setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char*)&value, 0);
1326 ok(err == SOCKET_ERROR && WSAGetLastError() == WSAEFAULT,
1327 "got %d with %d (expected SOCKET_ERROR with WSAEFAULT)\n", err, WSAGetLastError());
1328 value = 0xff;
1329 err = getsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char*)&value, &size);
1330 ok(!err, "getsockopt TCP_NODELAY failed\n");
1331 ok(!value, "TCP_NODELAY should be 0\n");
1333 value = 1;
1334 err = setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char*)&value, -1);
1335 /* On win 10 pro, this sets the error to WSAENOBUFS instead of WSAEFAULT */
1336 ok(err == SOCKET_ERROR && (WSAGetLastError() == WSAEFAULT || WSAGetLastError() == WSAENOBUFS),
1337 "got %d with %d (expected SOCKET_ERROR with either WSAEFAULT or WSAENOBUFS)\n", err, WSAGetLastError());
1338 value = 0xff;
1339 err = getsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char*)&value, &size);
1340 ok(!err, "getsockopt TCP_NODELAY failed\n");
1341 ok(!value, "TCP_NODELAY should be 0\n");
1343 value = 0x100;
1344 err = setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char*)&value, 4);
1345 ok (!err, "setsockopt TCP_NODELAY failed with optlen == 4 and optvalue = 0x100\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, "TCP_NODELAY should be 0\n");
1351 /* Test for erroneously passing a value instead of a pointer as optval */
1352 size = sizeof(char);
1353 err = setsockopt(s, SOL_SOCKET, SO_DONTROUTE, (char *)1, size);
1354 ok(err == SOCKET_ERROR, "setsockopt with optval being a value passed "
1355 "instead of failing.\n");
1356 lasterr = WSAGetLastError();
1357 ok(lasterr == WSAEFAULT, "setsockopt with optval being a value "
1358 "returned 0x%08x, not WSAEFAULT(0x%08x)\n",
1359 lasterr, WSAEFAULT);
1361 /* SO_RCVTIMEO with invalid values for level */
1362 size = sizeof(timeout);
1363 timeout = SOCKTIMEOUT1;
1364 SetLastError(0xdeadbeef);
1365 err = setsockopt(s, 0xffffffff, SO_RCVTIMEO, (char *) &timeout, size);
1366 ok( (err == SOCKET_ERROR) && (WSAGetLastError() == WSAEINVAL),
1367 "got %d with %d (expected SOCKET_ERROR with WSAEINVAL)\n",
1368 err, WSAGetLastError());
1370 timeout = SOCKTIMEOUT1;
1371 SetLastError(0xdeadbeef);
1372 err = setsockopt(s, 0x00008000, SO_RCVTIMEO, (char *) &timeout, size);
1373 ok( (err == SOCKET_ERROR) && (WSAGetLastError() == WSAEINVAL),
1374 "got %d with %d (expected SOCKET_ERROR with WSAEINVAL)\n",
1375 err, WSAGetLastError());
1377 /* Test SO_ERROR set/get */
1378 SetLastError(0xdeadbeef);
1379 i = 1234;
1380 err = setsockopt(s, SOL_SOCKET, SO_ERROR, (char *) &i, size);
1381 todo_wine
1382 ok( !err && !WSAGetLastError(),
1383 "got %d with %d (expected 0 with 0)\n",
1384 err, WSAGetLastError());
1386 SetLastError(0xdeadbeef);
1387 i = 4321;
1388 err = getsockopt(s, SOL_SOCKET, SO_ERROR, (char *) &i, &size);
1389 ok( !err && !WSAGetLastError(),
1390 "got %d with %d (expected 0 with 0)\n",
1391 err, WSAGetLastError());
1392 todo_wine
1393 ok (i == 1234, "got %d (expected 1234)\n", i);
1395 /* Test invalid optlen */
1396 SetLastError(0xdeadbeef);
1397 size = 1;
1398 err = getsockopt(s, SOL_SOCKET, SO_ERROR, (char *) &i, &size);
1399 ok( (err == SOCKET_ERROR) && (WSAGetLastError() == WSAEFAULT),
1400 "got %d with %d (expected SOCKET_ERROR with WSAEFAULT)\n",
1401 err, WSAGetLastError());
1403 closesocket(s);
1405 /* Test option length. */
1406 for (i = 0; i < ARRAY_SIZE(test_optsize); ++i)
1408 winetest_push_context("i %u, level %d, optname %d",
1409 i, test_optsize[i].level, test_optsize[i].optname);
1411 s2 = socket( test_optsize[i].af, test_optsize[i].type, 0 );
1412 ok(s2 != INVALID_SOCKET, "socket() failed error %d\n", WSAGetLastError());
1414 size = sizeof(save_value);
1415 err = getsockopt(s2, test_optsize[i].level, test_optsize[i].optname, (char*)&save_value, &size);
1416 ok(!err, "Unexpected getsockopt result %d.\n", err);
1418 value64 = 0xffffffff00000001;
1419 err = setsockopt(s2, test_optsize[i].level, test_optsize[i].optname, (char *)&value64, sizeof(value64));
1420 ok(!err, "Unexpected setsockopt result %d.\n", err);
1421 ok(!WSAGetLastError(), "Unexpected WSAGetLastError() %u.\n", WSAGetLastError());
1423 size = sizeof(value64);
1424 err = getsockopt(s2, test_optsize[i].level, test_optsize[i].optname, (char*)&value64, &size);
1425 ok(!err, "Unexpected getsockopt result %d.\n", err);
1426 ok(size == test_optsize[i].sizes[2], "Got unexpected size %d.\n", size);
1427 /* The behaviour regarding filling the high dword is different between options without the obvious
1428 * pattern, it is either left untouched (more often) or zeroed. Wine doesn't touch the high dword. */
1430 if (test_optsize[i].sizes[2] == 1 || test_optsize[i].level != SOL_SOCKET)
1432 expected_err = -1;
1433 expected_last_error = WSAENOBUFS;
1435 else
1437 expected_err = 0;
1438 expected_last_error = 0;
1441 value = 1;
1442 err = setsockopt(s2, test_optsize[i].level, test_optsize[i].optname, (char *)&value, -1);
1443 ok(err == expected_err, "Unexpected setsockopt result %d.\n", err);
1444 /* Broken between Win7 and Win10 21H1. */
1445 ok(WSAGetLastError() == expected_last_error || broken(expected_last_error && WSAGetLastError() == WSAEFAULT),
1446 "Unexpected WSAGetLastError() %u.\n", WSAGetLastError());
1448 size = -1;
1449 value = 0xdeadbeef;
1450 err = getsockopt(s2, test_optsize[i].level, test_optsize[i].optname, (char*)&value, &size);
1451 if (test_optsize[i].optname == SO_OPENTYPE)
1453 ok(!err, "Unexpected getsockopt result %d.\n", err);
1454 ok(!WSAGetLastError(), "Unexpected WSAGetLastError() %u.\n", WSAGetLastError());
1456 else
1458 ok(err == -1, "Unexpected getsockopt result %d.\n", err);
1459 ok(WSAGetLastError() == WSAEFAULT, "Unexpected WSAGetLastError() %u.\n", WSAGetLastError());
1461 ok(size == (test_optsize[i].optname == SO_OPENTYPE ? 4 : -1), "Got unexpected size %d.\n", size);
1463 if (test_optsize[i].level == SOL_SOCKET && test_optsize[i].bool_value)
1465 expected_err = 0;
1466 expected_last_error = 0;
1468 else
1470 expected_err = -1;
1471 expected_last_error = WSAEFAULT;
1473 value = 1;
1474 SetLastError(0xdeadbeef);
1475 err = setsockopt(s2, test_optsize[i].level, test_optsize[i].optname, (char*)&value, 0);
1476 ok(err == expected_err, "Unexpected setsockopt result %d.\n", err);
1477 ok(WSAGetLastError() == expected_last_error, "Unexpected WSAGetLastError() %u.\n", WSAGetLastError());
1479 size = 0;
1480 err = getsockopt(s2, test_optsize[i].level, test_optsize[i].optname, (char*)&value, &size);
1481 ok(err == -1, "Unexpected getsockopt result %d.\n", err);
1482 ok(WSAGetLastError() == WSAEFAULT, "Unexpected WSAGetLastError() %u.\n", WSAGetLastError());
1484 expected_size = test_optsize[i].sizes[2];
1485 if (expected_size == 1)
1486 expected_value = 0xdeadbe00;
1487 else
1488 expected_value = test_optsize[i].bool_value ? 0x1 : 0x100;
1489 if (test_optsize[i].accepts_large_value)
1491 expected_err = 0;
1492 expected_last_error = 0;
1494 else
1496 expected_err = -1;
1497 expected_last_error = WSAEINVAL;
1500 value = 0x100;
1501 SetLastError(0xdeadbeef);
1502 err = setsockopt(s2, test_optsize[i].level, test_optsize[i].optname, (char*)&value, 4);
1503 ok(err == expected_err, "Unexpected setsockopt result %d.\n", err);
1504 ok(WSAGetLastError() == expected_last_error, "Unexpected WSAGetLastError() %u.\n", WSAGetLastError());
1506 if (test_optsize[i].accepts_large_value)
1508 value = 0xdeadbeef;
1509 SetLastError(0xdeadbeef);
1510 size = 4;
1511 err = getsockopt(s2, test_optsize[i].level, test_optsize[i].optname, (char*)&value, &size);
1512 ok(err == expected_err, "Unexpected getsockopt result %d.\n", err);
1513 ok(WSAGetLastError() == expected_last_error, "Unexpected WSAGetLastError() %u.\n", WSAGetLastError());
1514 todo_wine_if(test_optsize[i].optname == SO_DONTROUTE || test_optsize[i].optname == SO_LINGER)
1515 ok(value == expected_value, "Got unexpected value %#x, expected %#x.\n", value, expected_value);
1516 ok(size == expected_size, "Got unexpected size %u, expected %u.\n", size, expected_size);
1519 winetest_pop_context();
1521 for (j = 0; j < ARRAY_SIZE(test_optsize[i].sizes); ++j)
1523 size = 1 << j;
1524 winetest_push_context("i %u, level %d, optname %d, len %u",
1525 i, test_optsize[i].level, test_optsize[i].optname, size);
1527 value = 1;
1528 if (test_optsize[i].values[j])
1529 expected_value = test_optsize[i].values[j];
1530 else
1531 expected_value = 0xdeadbeef;
1533 if (test_optsize[i].accepts_short_len || size == 4)
1535 expected_err = 0;
1536 expected_last_error = 0;
1537 expected_size = test_optsize[i].sizes[j];
1539 if (!test_optsize[i].values[j])
1540 memcpy(&expected_value, &value, expected_size);
1542 else
1544 expected_err = -1;
1545 expected_last_error = WSAEFAULT;
1546 expected_size = test_optsize[i].sizes[j];
1549 SetLastError(0xdeadbeef);
1550 err = setsockopt(s2, test_optsize[i].level, test_optsize[i].optname, (char*)&value, size);
1551 ok(err == expected_err, "Unexpected setsockopt result %d.\n", err);
1552 ok(WSAGetLastError() == expected_last_error, "Unexpected WSAGetLastError() %u.\n", WSAGetLastError());
1554 value = 0xdeadbeef;
1555 SetLastError(0xdeadbeef);
1556 err = getsockopt(s2, test_optsize[i].level, test_optsize[i].optname, (char*)&value, &size);
1557 ok(err == expected_err, "Unexpected getsockopt result %d.\n", err);
1558 ok(WSAGetLastError() == expected_last_error, "Unexpected WSAGetLastError() %u.\n", WSAGetLastError());
1559 ok(value == expected_value, "Got unexpected value %#x, expected %#x.\n", value, expected_value);
1560 ok(size == expected_size, "Got unexpected size %d, expected %d.\n", size, expected_size);
1562 winetest_pop_context();
1565 err = setsockopt(s2, test_optsize[i].level, test_optsize[i].optname,
1566 (char*)&save_value, sizeof(save_value));
1567 ok(!err, "Unexpected getsockopt result %d.\n", err);
1568 closesocket(s2);
1571 /* Test with the closed socket */
1572 SetLastError(0xdeadbeef);
1573 size = sizeof(i);
1574 i = 1234;
1575 err = getsockopt(s, SOL_SOCKET, SO_ERROR, (char *) &i, &size);
1576 ok( (err == SOCKET_ERROR) && (WSAGetLastError() == WSAENOTSOCK),
1577 "got %d with %d (expected SOCKET_ERROR with WSAENOTSOCK)\n",
1578 err, WSAGetLastError());
1579 ok (i == 1234, "expected 1234, got %d\n", i);
1581 /* Test WS_IP_MULTICAST_TTL with 8, 16, 24 and 32 bits values */
1582 s = socket(AF_INET, SOCK_DGRAM, 0);
1583 ok(s != INVALID_SOCKET, "Failed to create socket\n");
1584 size = sizeof(i);
1585 i = 0x0000000a;
1586 err = setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, (char *) &i, size);
1587 if (!err)
1589 for (i = 0; i < 4; i++)
1591 int k, j;
1592 const int tests[] = {0xffffff0a, 0xffff000b, 0xff00000c, 0x0000000d};
1593 err = setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, (char *) &tests[i], i + 1);
1594 ok(!err, "Test [%d] Expected 0, got %d\n", i, err);
1595 err = getsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, (char *) &k, &size);
1596 ok(!err, "Test [%d] Expected 0, got %d\n", i, err);
1597 j = i != 3 ? tests[i] & ((1 << (i + 1) * 8) - 1) : tests[i];
1598 ok(k == j, "Test [%d] Expected 0x%x, got 0x%x\n", i, j, k);
1601 else
1602 win_skip("IP_MULTICAST_TTL is unsupported\n");
1603 closesocket(s);
1605 /* test SO_PROTOCOL_INFOA invalid parameters */
1606 ok(getsockopt(INVALID_SOCKET, SOL_SOCKET, SO_PROTOCOL_INFOA, NULL, NULL),
1607 "getsockopt should have failed\n");
1608 err = WSAGetLastError();
1609 ok(err == WSAENOTSOCK, "expected 10038, got %d instead\n", err);
1610 size = sizeof(WSAPROTOCOL_INFOA);
1611 ok(getsockopt(INVALID_SOCKET, SOL_SOCKET, SO_PROTOCOL_INFOA, (char *) &infoA, &size),
1612 "getsockopt should have failed\n");
1613 ok(size == sizeof(WSAPROTOCOL_INFOA), "got size %d\n", size);
1614 err = WSAGetLastError();
1615 ok(err == WSAENOTSOCK, "expected 10038, got %d instead\n", err);
1616 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1617 ok(getsockopt(s, SOL_SOCKET, SO_PROTOCOL_INFOA, NULL, NULL),
1618 "getsockopt should have failed\n");
1619 err = WSAGetLastError();
1620 ok(err == WSAEFAULT, "expected 10014, got %d instead\n", err);
1621 ok(getsockopt(s, SOL_SOCKET, SO_PROTOCOL_INFOA, (char *) &infoA, NULL),
1622 "getsockopt should have failed\n");
1623 err = WSAGetLastError();
1624 ok(err == WSAEFAULT, "expected 10014, got %d instead\n", err);
1625 ok(getsockopt(s, SOL_SOCKET, SO_PROTOCOL_INFOA, NULL, &size),
1626 "getsockopt should have failed\n");
1627 err = WSAGetLastError();
1628 ok(err == WSAEFAULT, "expected 10014, got %d instead\n", err);
1629 size = sizeof(WSAPROTOCOL_INFOA) / 2;
1630 ok(getsockopt(s, SOL_SOCKET, SO_PROTOCOL_INFOA, (char *) &infoA, &size),
1631 "getsockopt should have failed\n");
1632 err = WSAGetLastError();
1633 ok(err == WSAEFAULT, "expected 10014, got %d instead\n", err);
1634 ok(size == sizeof(WSAPROTOCOL_INFOA), "got size %d\n", size);
1635 size = sizeof(WSAPROTOCOL_INFOA) * 2;
1636 err = getsockopt(s, SOL_SOCKET, SO_PROTOCOL_INFOA, (char *) &infoA, &size);
1637 ok(!err,"getsockopt failed with %d\n", WSAGetLastError());
1638 ok(size == sizeof(WSAPROTOCOL_INFOA) * 2, "got size %d\n", size);
1640 closesocket(s);
1642 /* test SO_PROTOCOL_INFO structure returned for different protocols */
1643 for (i = 0; i < ARRAY_SIZE(prottest); i++)
1645 int k;
1647 s = socket(prottest[i].family, prottest[i].type, prottest[i].proto);
1648 if (s == INVALID_SOCKET && prottest[i].family == AF_INET6) continue;
1650 ok(s != INVALID_SOCKET, "Failed to create socket: %d\n",
1651 WSAGetLastError());
1653 /* compare both A and W version */
1654 infoA.szProtocol[0] = 0;
1655 size = sizeof(WSAPROTOCOL_INFOA);
1656 err = getsockopt(s, SOL_SOCKET, SO_PROTOCOL_INFOA, (char *) &infoA, &size);
1657 ok(!err,"getsockopt failed with %d\n", WSAGetLastError());
1658 ok(size == sizeof(WSAPROTOCOL_INFOA), "got size %d\n", size);
1660 infoW.szProtocol[0] = 0;
1661 size = sizeof(WSAPROTOCOL_INFOW);
1662 err = getsockopt(s, SOL_SOCKET, SO_PROTOCOL_INFOW, (char *) &infoW, &size);
1663 ok(!err,"getsockopt failed with %d\n", WSAGetLastError());
1664 ok(size == sizeof(WSAPROTOCOL_INFOW), "got size %d\n", size);
1666 ok(infoA.szProtocol[0], "WSAPROTOCOL_INFOA was not filled\n");
1667 ok(infoW.szProtocol[0], "WSAPROTOCOL_INFOW was not filled\n");
1669 WideCharToMultiByte(CP_ACP, 0, infoW.szProtocol, -1,
1670 providername, sizeof(providername), NULL, NULL);
1671 ok(!strcmp(infoA.szProtocol,providername),
1672 "different provider names '%s' != '%s'\n", infoA.szProtocol, providername);
1674 ok(!memcmp(&infoA, &infoW, FIELD_OFFSET(WSAPROTOCOL_INFOA, szProtocol)),
1675 "SO_PROTOCOL_INFO[A/W] comparison failed\n");
1677 /* Remove IF when WSAEnumProtocols support IPV6 data */
1678 ok(infoA.iAddressFamily == prottest[i].family, "socket family invalid, expected %d received %d\n",
1679 prottest[i].family, infoA.iAddressFamily);
1680 ok(infoA.iSocketType == prottest[i].type, "socket type invalid, expected %d received %d\n",
1681 prottest[i].type, infoA.iSocketType);
1682 ok(infoA.iProtocol == prottest[i].proto, "socket protocol invalid, expected %d received %d\n",
1683 prottest[i].proto, infoA.iProtocol);
1685 /* IP_HDRINCL is supported only on SOCK_RAW but passed to SOCK_DGRAM by Impossible Creatures */
1686 size = sizeof(i);
1687 k = 1;
1688 SetLastError(0xdeadbeef);
1689 err = setsockopt(s, IPPROTO_IP, IP_HDRINCL, (char *) &k, size);
1690 if (err == -1) /* >= Vista */
1692 ok(GetLastError() == WSAEINVAL, "Expected 10022, got %d\n", GetLastError());
1693 k = 99;
1694 SetLastError(0xdeadbeef);
1695 err = getsockopt(s, IPPROTO_IP, IP_HDRINCL, (char *) &k, &size);
1696 ok(err == -1, "Expected -1, got %d\n", err);
1697 ok(GetLastError() == WSAEINVAL, "Expected 10022, got %d\n", GetLastError());
1698 ok(k == 99, "Expected 99, got %d\n", k);
1700 size = sizeof(k);
1701 k = 0;
1702 SetLastError(0xdeadbeef);
1703 err = setsockopt(s, IPPROTO_IP, IP_HDRINCL, (char *) &k, size);
1704 ok(err == -1, "Expected -1, got %d\n", err);
1705 ok(GetLastError() == WSAEINVAL, "Expected 10022, got %d\n", GetLastError());
1706 k = 99;
1707 SetLastError(0xdeadbeef);
1708 err = getsockopt(s, IPPROTO_IP, IP_HDRINCL, (char *) &k, &size);
1709 ok(err == -1, "Expected -1, got %d\n", err);
1710 ok(GetLastError() == WSAEINVAL, "Expected 10022, got %d\n", GetLastError());
1711 ok(k == 99, "Expected 99, got %d\n", k);
1713 else /* <= 2003 the tests differ between TCP and UDP, UDP silently accepts */
1715 SetLastError(0xdeadbeef);
1716 k = 99;
1717 err = getsockopt(s, IPPROTO_IP, IP_HDRINCL, (char *) &k, &size);
1718 if (prottest[i].type == SOCK_DGRAM)
1720 ok(err == 0, "Expected 0, got %d\n", err);
1721 ok(k == 1, "Expected 1, got %d\n", k);
1723 else
1725 /* contratry to what we could expect the function returns error but k is changed */
1726 ok(err == -1, "Expected -1, got %d\n", err);
1727 ok(GetLastError() == WSAENOPROTOOPT, "Expected 10042, got %d\n", GetLastError());
1728 ok(k == 0, "Expected 0, got %d\n", k);
1731 k = 0;
1732 err = setsockopt(s, IPPROTO_IP, IP_HDRINCL, (char *) &k, size);
1733 ok(err == 0, "Expected 0, got %d\n", err);
1735 k = 99;
1736 err = getsockopt(s, IPPROTO_IP, IP_HDRINCL, (char *) &k, &size);
1737 if (prottest[i].type == SOCK_DGRAM)
1739 ok(err == 0, "Expected 0, got %d\n", err);
1740 ok(k == 0, "Expected 0, got %d\n", k);
1742 else
1744 /* contratry to what we could expect the function returns error but k is changed */
1745 ok(err == -1, "Expected -1, got %d\n", err);
1746 ok(GetLastError() == WSAENOPROTOOPT, "Expected 10042, got %d\n", GetLastError());
1747 ok(k == 0, "Expected 0, got %d\n", k);
1751 closesocket(s);
1754 /* Test SO_BSP_STATE - Present only in >= Win 2008 */
1755 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1756 ok(s != INVALID_SOCKET, "Failed to create socket\n");
1757 s2 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1758 ok(s2 != INVALID_SOCKET, "Failed to create socket\n");
1760 SetLastError(0xdeadbeef);
1761 size = sizeof(csinfoA);
1762 err = getsockopt(s, SOL_SOCKET, SO_BSP_STATE, (char *) &csinfoA, &size);
1763 if (!err)
1765 struct sockaddr_in saddr;
1766 memset(&saddr, 0, sizeof(saddr));
1767 saddr.sin_family = AF_INET;
1768 saddr.sin_addr.s_addr = inet_addr("127.0.0.1");
1770 /* Socket is not bound, no information provided */
1771 ok(!csinfoA.cs.LocalAddr.iSockaddrLength, "Expected 0, got %d\n", csinfoA.cs.LocalAddr.iSockaddrLength);
1772 ok(csinfoA.cs.LocalAddr.lpSockaddr == NULL, "Expected NULL, got %p\n", csinfoA.cs.LocalAddr.lpSockaddr);
1773 /* Socket is not connected, no information provided */
1774 ok(!csinfoA.cs.RemoteAddr.iSockaddrLength, "Expected 0, got %d\n", csinfoA.cs.RemoteAddr.iSockaddrLength);
1775 ok(csinfoA.cs.RemoteAddr.lpSockaddr == NULL, "Expected NULL, got %p\n", csinfoA.cs.RemoteAddr.lpSockaddr);
1777 err = bind(s, (struct sockaddr*)&saddr, sizeof(saddr));
1778 ok(!err, "Expected 0, got %d\n", err);
1779 size = sizeof(csinfoA);
1780 err = getsockopt(s, SOL_SOCKET, SO_BSP_STATE, (char *) &csinfoA, &size);
1781 ok(!err, "Expected 0, got %d\n", err);
1783 /* Socket is bound */
1784 ok(csinfoA.cs.LocalAddr.iSockaddrLength, "Expected non-zero\n");
1785 ok(csinfoA.cs.LocalAddr.lpSockaddr != NULL, "Expected non-null\n");
1786 /* Socket is not connected, no information provided */
1787 ok(!csinfoA.cs.RemoteAddr.iSockaddrLength, "Expected 0, got %d\n", csinfoA.cs.RemoteAddr.iSockaddrLength);
1788 ok(csinfoA.cs.RemoteAddr.lpSockaddr == NULL, "Expected NULL, got %p\n", csinfoA.cs.RemoteAddr.lpSockaddr);
1790 err = bind(s2, (struct sockaddr*)&saddr, sizeof(saddr));
1791 ok(!err, "Expected 0, got %d\n", err);
1792 err = getsockname(s2, (struct sockaddr *)&saddr, &size);
1793 ok(!err, "Expected 0, got %d\n", err);
1794 err = listen(s2, 1);
1795 ok(!err, "Expected 0, got %d\n", err);
1796 err = connect(s, (struct sockaddr*)&saddr, sizeof(saddr));
1797 ok(!err, "Expected 0, got %d\n", err);
1798 size = sizeof(saddr);
1799 err = accept(s2, (struct sockaddr*)&saddr, &size);
1800 ok(err != INVALID_SOCKET, "Failed to accept socket\n");
1801 closesocket(s2);
1802 s2 = err;
1804 size = sizeof(csinfoA);
1805 err = getsockopt(s, SOL_SOCKET, SO_BSP_STATE, (char *) &csinfoA, &size);
1806 ok(!err, "Expected 0, got %d\n", err);
1807 err = getsockopt(s2, SOL_SOCKET, SO_BSP_STATE, (char *) &csinfoB, &size);
1808 ok(!err, "Expected 0, got %d\n", err);
1809 ok(size == sizeof(csinfoA), "Got %d\n", size);
1810 size = sizeof(saddr);
1811 ok(size == csinfoA.cs.LocalAddr.iSockaddrLength, "Expected %d, got %d\n", size,
1812 csinfoA.cs.LocalAddr.iSockaddrLength);
1813 ok(size == csinfoA.cs.RemoteAddr.iSockaddrLength, "Expected %d, got %d\n", size,
1814 csinfoA.cs.RemoteAddr.iSockaddrLength);
1815 ok(!memcmp(csinfoA.cs.LocalAddr.lpSockaddr, csinfoB.cs.RemoteAddr.lpSockaddr, size),
1816 "Expected matching addresses\n");
1817 ok(!memcmp(csinfoB.cs.LocalAddr.lpSockaddr, csinfoA.cs.RemoteAddr.lpSockaddr, size),
1818 "Expected matching addresses\n");
1819 ok(csinfoA.cs.iSocketType == SOCK_STREAM, "Wrong socket type\n");
1820 ok(csinfoB.cs.iSocketType == SOCK_STREAM, "Wrong socket type\n");
1821 ok(csinfoA.cs.iProtocol == IPPROTO_TCP, "Wrong socket protocol\n");
1822 ok(csinfoB.cs.iProtocol == IPPROTO_TCP, "Wrong socket protocol\n");
1824 err = getpeername(s, (struct sockaddr *)&saddr, &size);
1825 ok(!err, "Expected 0, got %d\n", err);
1826 ok(!memcmp(&saddr, csinfoA.cs.RemoteAddr.lpSockaddr, size), "Expected matching addresses\n");
1827 ok(!memcmp(&saddr, csinfoB.cs.LocalAddr.lpSockaddr, size), "Expected matching addresses\n");
1828 err = getpeername(s2, (struct sockaddr *)&saddr, &size);
1829 ok(!err, "Expected 0, got %d\n", err);
1830 ok(!memcmp(&saddr, csinfoB.cs.RemoteAddr.lpSockaddr, size), "Expected matching addresses\n");
1831 ok(!memcmp(&saddr, csinfoA.cs.LocalAddr.lpSockaddr, size), "Expected matching addresses\n");
1832 err = getsockname(s, (struct sockaddr *)&saddr, &size);
1833 ok(!err, "Expected 0, got %d\n", err);
1834 ok(!memcmp(&saddr, csinfoA.cs.LocalAddr.lpSockaddr, size), "Expected matching addresses\n");
1835 ok(!memcmp(&saddr, csinfoB.cs.RemoteAddr.lpSockaddr, size), "Expected matching addresses\n");
1836 err = getsockname(s2, (struct sockaddr *)&saddr, &size);
1837 ok(!err, "Expected 0, got %d\n", err);
1838 ok(!memcmp(&saddr, csinfoB.cs.LocalAddr.lpSockaddr, size), "Expected matching addresses\n");
1839 ok(!memcmp(&saddr, csinfoA.cs.RemoteAddr.lpSockaddr, size), "Expected matching addresses\n");
1841 SetLastError(0xdeadbeef);
1842 size = sizeof(CSADDR_INFO);
1843 err = getsockopt(s, SOL_SOCKET, SO_BSP_STATE, (char *) &csinfoA, &size);
1844 ok(err, "Expected non-zero\n");
1845 ok(size == sizeof(CSADDR_INFO), "Got %d\n", size);
1846 ok(GetLastError() == WSAEFAULT, "Expected 10014, got %d\n", GetLastError());
1848 /* At least for IPv4 the size is exactly 56 bytes */
1849 size = sizeof(*csinfoA.cs.LocalAddr.lpSockaddr) * 2 + sizeof(csinfoA.cs);
1850 err = getsockopt(s, SOL_SOCKET, SO_BSP_STATE, (char *) &csinfoA, &size);
1851 ok(!err, "Expected 0, got %d\n", err);
1852 size--;
1853 SetLastError(0xdeadbeef);
1854 err = getsockopt(s, SOL_SOCKET, SO_BSP_STATE, (char *) &csinfoA, &size);
1855 ok(err, "Expected non-zero\n");
1856 ok(GetLastError() == WSAEFAULT, "Expected 10014, got %d\n", GetLastError());
1858 else
1859 ok(GetLastError() == WSAENOPROTOOPT, "Expected 10042, got %d\n", GetLastError());
1861 closesocket(s);
1862 closesocket(s2);
1864 for (i = 0; i < 2; i++)
1866 int family, level;
1868 if (i)
1870 family = AF_INET6;
1871 level = IPPROTO_IPV6;
1873 else
1875 family = AF_INET;
1876 level = IPPROTO_IP;
1879 s = socket(family, SOCK_DGRAM, 0);
1880 if (s == INVALID_SOCKET && i)
1882 skip("IPv6 is not supported\n");
1883 break;
1885 ok(s != INVALID_SOCKET, "socket failed with error %d\n", GetLastError());
1887 size = sizeof(value);
1888 value = 0xdead;
1889 err = getsockopt(s, level, IP_DONTFRAGMENT, (char *) &value, &size);
1890 ok(!err, "Expected 0, got %d with error %d\n", err, GetLastError());
1891 ok(value == 0, "Expected 0, got %d\n", value);
1893 size = sizeof(value);
1894 value = 1;
1895 err = setsockopt(s, level, IP_DONTFRAGMENT, (char *) &value, size);
1896 ok(!err, "Expected 0, got %d with error %d\n", err, GetLastError());
1898 value = 0xdead;
1899 err = getsockopt(s, level, IP_DONTFRAGMENT, (char *) &value, &size);
1900 ok(!err, "Expected 0, got %d with error %d\n", err, GetLastError());
1901 ok(value == 1, "Expected 1, got %d\n", value);
1903 size = sizeof(value);
1904 value = 0xdead;
1905 err = setsockopt(s, level, IP_DONTFRAGMENT, (char *) &value, size);
1906 ok(!err, "Expected 0, got %d with error %d\n", err, GetLastError());
1908 err = getsockopt(s, level, IP_DONTFRAGMENT, (char *) &value, &size);
1909 ok(!err, "Expected 0, got %d with error %d\n", err, GetLastError());
1910 ok(value == 1, "Expected 1, got %d\n", value);
1912 closesocket(s);
1914 s = socket(family, SOCK_STREAM, 0);
1915 ok(s != INVALID_SOCKET, "socket failed with error %d\n", GetLastError());
1917 size = sizeof(value);
1918 value = 0xdead;
1919 err = getsockopt(s, level, IP_DONTFRAGMENT, (char *) &value, &size);
1920 ok(!err, "Expected 0, got %d with error %d\n", err, GetLastError());
1921 ok(value == 1 || broken(value == 0) /* < vista */, "Expected 1, got %d\n", value);
1923 size = sizeof(value);
1924 value = 0;
1925 err = setsockopt(s, level, IP_DONTFRAGMENT, (char *) &value, size);
1926 ok(!err, "Expected 0, got %d with error %d\n", err, GetLastError());
1928 value = 0xdead;
1929 err = getsockopt(s, level, IP_DONTFRAGMENT, (char *) &value, &size);
1930 ok(!err, "Expected 0, got %d with error %d\n", err, GetLastError());
1931 ok(value == 0, "Expected 0, got %d\n", value);
1933 closesocket(s);
1935 s = socket(family, SOCK_RAW, 0);
1936 if (s == INVALID_SOCKET)
1938 if (WSAGetLastError() == WSAEACCES) skip("SOCK_RAW is not available\n");
1939 else if (i) skip("IPv6 is not supported\n");
1940 break;
1942 ok(s != INVALID_SOCKET, "socket failed with error %d\n", GetLastError());
1944 size = sizeof(value);
1945 value = 0xdead;
1946 err = getsockopt(s, level, IP_DONTFRAGMENT, (char *) &value, &size);
1947 ok(!err, "Expected 0, got %d with error %d\n", err, GetLastError());
1948 ok(value == 0, "Expected 0, got %d\n", value);
1950 size = sizeof(value);
1951 value = 1;
1952 err = setsockopt(s, level, IP_DONTFRAGMENT, (char *) &value, size);
1953 ok(!err, "Expected 0, got %d with error %d\n", err, GetLastError());
1955 value = 0xdead;
1956 err = getsockopt(s, level, IP_DONTFRAGMENT, (char *) &value, &size);
1957 ok(!err, "Expected 0, got %d with error %d\n", err, GetLastError());
1958 ok(value == 1, "Expected 1, got %d\n", value);
1960 closesocket(s);
1964 static void test_so_reuseaddr(void)
1966 struct sockaddr_in saddr;
1967 SOCKET s1,s2;
1968 unsigned int rc,reuse;
1969 int size;
1970 DWORD err;
1972 saddr.sin_family = AF_INET;
1973 saddr.sin_port = htons(SERVERPORT+1);
1974 saddr.sin_addr.s_addr = inet_addr("127.0.0.1");
1976 s1=socket(AF_INET, SOCK_STREAM, 0);
1977 ok(s1!=INVALID_SOCKET, "socket() failed error: %d\n", WSAGetLastError());
1978 rc = bind(s1, (struct sockaddr*)&saddr, sizeof(saddr));
1979 ok(rc!=SOCKET_ERROR, "bind(s1) failed error: %d\n", WSAGetLastError());
1981 s2=socket(AF_INET, SOCK_STREAM, 0);
1982 ok(s2!=INVALID_SOCKET, "socket() failed error: %d\n", WSAGetLastError());
1984 reuse=0x1234;
1985 size=sizeof(reuse);
1986 rc=getsockopt(s2, SOL_SOCKET, SO_REUSEADDR, (char*)&reuse, &size );
1987 ok(rc==0 && reuse==0,"wrong result in getsockopt(SO_REUSEADDR): rc=%d reuse=%d\n",rc,reuse);
1989 rc = bind(s2, (struct sockaddr*)&saddr, sizeof(saddr));
1990 ok(rc==SOCKET_ERROR, "bind() succeeded\n");
1992 reuse = 1;
1993 rc = setsockopt(s2, SOL_SOCKET, SO_REUSEADDR, (char*)&reuse, sizeof(reuse));
1994 ok(rc==0, "setsockopt() failed error: %d\n", WSAGetLastError());
1996 /* On Win2k3 and above, all SO_REUSEADDR seems to do is to allow binding to
1997 * a port immediately after closing another socket on that port, so
1998 * basically following the BSD socket semantics here. */
1999 rc = bind(s2, (struct sockaddr*)&saddr, sizeof(saddr));
2000 if(rc==0)
2002 int s3=socket(AF_INET, SOCK_STREAM, 0), s4;
2004 /* If we could bind again in the same port this is Windows version <= XP.
2005 * Lets test if we can really connect to one of them. */
2006 set_blocking(s1, FALSE);
2007 set_blocking(s2, FALSE);
2008 rc = listen(s1, 1);
2009 ok(!rc, "listen() failed with error: %d\n", WSAGetLastError());
2010 rc = listen(s2, 1);
2011 ok(!rc, "listen() failed with error: %d\n", WSAGetLastError());
2012 rc = connect(s3, (struct sockaddr*)&saddr, sizeof(saddr));
2013 ok(!rc, "connecting to accepting socket failed %d\n", WSAGetLastError());
2015 /* the delivery of the connection is random so we need to try on both sockets */
2016 size = sizeof(saddr);
2017 s4 = accept(s1, (struct sockaddr*)&saddr, &size);
2018 if(s4 == INVALID_SOCKET)
2019 s4 = accept(s2, (struct sockaddr*)&saddr, &size);
2020 ok(s4 != INVALID_SOCKET, "none of the listening sockets could get the connection\n");
2022 closesocket(s1);
2023 closesocket(s3);
2024 closesocket(s4);
2026 else
2028 err = WSAGetLastError();
2029 ok(err==WSAEACCES, "expected 10013, got %d\n", err);
2031 closesocket(s1);
2032 rc = bind(s2, (struct sockaddr*)&saddr, sizeof(saddr));
2033 ok(rc==0, "bind() failed error: %d\n", WSAGetLastError());
2036 closesocket(s2);
2039 #define IP_PKTINFO_LEN (sizeof(WSACMSGHDR) + WSA_CMSG_ALIGN(sizeof(struct in_pktinfo)))
2041 static unsigned int got_ip_pktinfo_apc;
2043 static void WINAPI ip_pktinfo_apc(DWORD error, DWORD size, OVERLAPPED *overlapped, DWORD flags)
2045 ok(error == WSAEMSGSIZE, "got error %u\n", error);
2046 ok(size == 6, "got size %u\n", size);
2047 ok(!flags, "got flags %#x\n", flags);
2048 ++got_ip_pktinfo_apc;
2051 static void test_ip_pktinfo(void)
2053 ULONG addresses[2] = {inet_addr("127.0.0.1"), htonl(INADDR_ANY)};
2054 char recvbuf[10], pktbuf[512], msg[] = "HELLO";
2055 struct sockaddr_in s1addr, s2addr, s3addr;
2056 LPFN_WSARECVMSG pWSARecvMsg = NULL;
2057 unsigned int rc, yes = 1;
2058 BOOL foundhdr;
2059 DWORD dwBytes, dwSize, dwFlags;
2060 socklen_t addrlen;
2061 WSACMSGHDR *cmsg;
2062 WSAOVERLAPPED ov;
2063 WSABUF iovec[1];
2064 SOCKET s1, s2;
2065 WSAMSG hdr;
2066 int i, err;
2068 memset(&ov, 0, sizeof(ov));
2069 ov.hEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
2071 memset(&hdr, 0x00, sizeof(hdr));
2072 s1addr.sin_family = AF_INET;
2073 s1addr.sin_port = htons(0);
2074 /* Note: s1addr.sin_addr is set below */
2075 iovec[0].buf = recvbuf;
2076 iovec[0].len = sizeof(recvbuf);
2077 hdr.name = (struct sockaddr*)&s3addr;
2078 hdr.namelen = sizeof(s3addr);
2079 hdr.lpBuffers = &iovec[0];
2080 hdr.dwBufferCount = 1;
2081 hdr.Control.buf = pktbuf;
2082 /* Note: hdr.Control.len is set below */
2083 hdr.dwFlags = 0;
2085 for (i=0;i<ARRAY_SIZE(addresses);i++)
2087 s1addr.sin_addr.s_addr = addresses[i];
2089 /* Build "server" side socket */
2090 s1=socket(AF_INET, SOCK_DGRAM, 0);
2091 ok(s1 != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
2093 /* Obtain the WSARecvMsg function */
2094 rc = WSAIoctl(s1, SIO_GET_EXTENSION_FUNCTION_POINTER, &WSARecvMsg_GUID, sizeof(WSARecvMsg_GUID),
2095 &pWSARecvMsg, sizeof(pWSARecvMsg), &dwBytes, NULL, NULL);
2096 ok(!rc, "failed to get WSARecvMsg, error %u\n", WSAGetLastError());
2098 /* Setup the server side socket */
2099 rc=bind(s1, (struct sockaddr*)&s1addr, sizeof(s1addr));
2100 ok(rc != SOCKET_ERROR, "bind() failed error: %d\n", WSAGetLastError());
2102 /* Build "client" side socket */
2103 addrlen = sizeof(s2addr);
2104 rc = getsockname(s1, (struct sockaddr *) &s2addr, &addrlen);
2105 ok(!rc, "failed to get address, error %u\n", WSAGetLastError());
2106 s2addr.sin_addr.s_addr = addresses[0]; /* Always target the local adapter address */
2107 s2=socket(AF_INET, SOCK_DGRAM, 0);
2108 ok(s2 != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
2110 /* Test an empty message header */
2111 rc=pWSARecvMsg(s1, NULL, NULL, NULL, NULL);
2112 err=WSAGetLastError();
2113 ok(rc == SOCKET_ERROR && err == WSAEFAULT, "WSARecvMsg() failed error: %d (ret = %d)\n", err, rc);
2115 /* Test that when no control data arrives, a 0-length NULL-valued control buffer should succeed */
2116 SetLastError(0xdeadbeef);
2117 rc=sendto(s2, msg, sizeof(msg), 0, (struct sockaddr*)&s2addr, sizeof(s2addr));
2118 ok(rc == sizeof(msg), "sendto() failed error: %d\n", WSAGetLastError());
2119 ok(GetLastError() == ERROR_SUCCESS, "Expected 0, got %d\n", GetLastError());
2120 hdr.Control.buf = NULL;
2121 hdr.Control.len = 0;
2122 rc=pWSARecvMsg(s1, &hdr, &dwSize, NULL, NULL);
2123 ok(rc == 0, "WSARecvMsg() failed error: %d\n", WSAGetLastError());
2124 hdr.Control.buf = pktbuf;
2126 /* Now start IP_PKTINFO for future tests */
2127 rc=setsockopt(s1, IPPROTO_IP, IP_PKTINFO, (const char*)&yes, sizeof(yes));
2128 ok(rc == 0, "failed to set IPPROTO_IP flag IP_PKTINFO!\n");
2131 * Send a packet from the client to the server and test for specifying
2132 * a short control header.
2134 SetLastError(0xdeadbeef);
2135 rc=sendto(s2, msg, sizeof(msg), 0, (struct sockaddr*)&s2addr, sizeof(s2addr));
2136 ok(rc == sizeof(msg), "sendto() failed error: %d\n", WSAGetLastError());
2137 ok(GetLastError() == ERROR_SUCCESS, "Expected 0, got %d\n", GetLastError());
2138 hdr.Control.len = 1;
2139 dwSize = 0xdeadbeef;
2140 rc = pWSARecvMsg(s1, &hdr, &dwSize, NULL, NULL);
2141 ok(rc == -1, "expected failure\n");
2142 ok(WSAGetLastError() == WSAEMSGSIZE, "got error %u\n", WSAGetLastError());
2143 todo_wine ok(dwSize == sizeof(msg), "got size %u\n", dwSize);
2144 ok(hdr.dwFlags == MSG_CTRUNC, "got flags %#x\n", hdr.dwFlags);
2145 hdr.dwFlags = 0; /* Reset flags */
2147 /* Perform another short control header test, this time with an overlapped receive */
2148 hdr.Control.len = 1;
2149 ov.Internal = 0xdead1;
2150 ov.InternalHigh = 0xdead2;
2151 ov.Offset = 0xdead3;
2152 ov.OffsetHigh = 0xdead4;
2153 rc=pWSARecvMsg(s1, &hdr, NULL, &ov, NULL);
2154 err=WSAGetLastError();
2155 ok(rc != 0 && err == WSA_IO_PENDING, "WSARecvMsg() failed error: %d\n", err);
2156 SetLastError(0xdeadbeef);
2157 rc=sendto(s2, msg, sizeof(msg), 0, (struct sockaddr*)&s2addr, sizeof(s2addr));
2158 ok(rc == sizeof(msg), "sendto() failed error: %d\n", WSAGetLastError());
2159 ok(GetLastError() == ERROR_SUCCESS, "Expected 0, got %d\n", GetLastError());
2160 ok(!WaitForSingleObject(ov.hEvent, 100), "wait failed\n");
2161 ok((NTSTATUS)ov.Internal == STATUS_BUFFER_OVERFLOW, "got status %#x\n", (NTSTATUS)ov.Internal);
2162 ok(ov.InternalHigh == sizeof(msg), "got size %Iu\n", ov.InternalHigh);
2163 ok(ov.Offset == 0xdead3, "got Offset %Iu\n", ov.Offset);
2164 ok(ov.OffsetHigh == 0xdead4, "got OffsetHigh %Iu\n", ov.OffsetHigh);
2165 dwFlags = 0xdeadbeef;
2166 rc = WSAGetOverlappedResult(s1, &ov, &dwSize, FALSE, &dwFlags);
2167 ok(!rc, "expected failure\n");
2168 ok(WSAGetLastError() == WSAEMSGSIZE, "got error %u\n", WSAGetLastError());
2169 ok(dwSize == sizeof(msg), "got size %u\n", dwSize);
2170 todo_wine ok(dwFlags == 0xdeadbeef, "got flags %#x\n", dwFlags);
2171 ok(hdr.dwFlags == MSG_CTRUNC,
2172 "WSARecvMsg() overlapped operation set unexpected flags %d.\n", hdr.dwFlags);
2173 hdr.dwFlags = 0; /* Reset flags */
2175 /* And with an APC. */
2177 SetLastError(0xdeadbeef);
2178 rc = sendto(s2, msg, sizeof(msg), 0, (struct sockaddr *)&s2addr, sizeof(s2addr));
2179 ok(rc == sizeof(msg), "sendto() failed error: %d\n", WSAGetLastError());
2180 ok(GetLastError() == ERROR_SUCCESS, "Expected 0, got %d\n", GetLastError());
2181 hdr.Control.len = 1;
2183 ov.Internal = 0xdead1;
2184 ov.InternalHigh = 0xdead2;
2185 ov.Offset = 0xdead3;
2186 ov.OffsetHigh = 0xdead4;
2187 dwSize = 0xdeadbeef;
2188 rc = pWSARecvMsg(s1, &hdr, NULL, &ov, ip_pktinfo_apc);
2189 ok(rc == -1, "expected failure\n");
2190 todo_wine ok(WSAGetLastError() == ERROR_IO_PENDING, "got error %u\n", WSAGetLastError());
2192 rc = SleepEx(1000, TRUE);
2193 ok(rc == WAIT_IO_COMPLETION, "got %d\n", rc);
2194 ok(got_ip_pktinfo_apc == 1, "apc was called %u times\n", got_ip_pktinfo_apc);
2195 ok(hdr.dwFlags == MSG_CTRUNC, "got flags %#x\n", hdr.dwFlags);
2196 got_ip_pktinfo_apc = 0;
2198 hdr.dwFlags = 0; /* Reset flags */
2201 * Setup an overlapped receive, send a packet, then wait for the packet to be retrieved
2202 * on the server end and check that the returned packet matches what was sent.
2204 hdr.Control.len = sizeof(pktbuf);
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 ok(hdr.Control.len == sizeof(pktbuf),
2209 "WSARecvMsg() control length mismatch (%d != sizeof pktbuf).\n", hdr.Control.len);
2210 rc=sendto(s2, msg, sizeof(msg), 0, (struct sockaddr*)&s2addr, sizeof(s2addr));
2211 ok(rc == sizeof(msg), "sendto() failed error: %d\n", WSAGetLastError());
2212 ok(!WaitForSingleObject(ov.hEvent, 100), "wait failed\n");
2213 dwSize = 0;
2214 WSAGetOverlappedResult(s1, &ov, &dwSize, FALSE, NULL);
2215 ok(dwSize == sizeof(msg),
2216 "WSARecvMsg() buffer length does not match transmitted data!\n");
2217 ok(strncmp(iovec[0].buf, msg, sizeof(msg)) == 0,
2218 "WSARecvMsg() buffer does not match transmitted data!\n");
2219 ok(hdr.Control.len == IP_PKTINFO_LEN,
2220 "WSARecvMsg() control length mismatch (%d).\n", hdr.Control.len);
2222 /* Test for the expected IP_PKTINFO return information. */
2223 foundhdr = FALSE;
2224 for (cmsg = WSA_CMSG_FIRSTHDR(&hdr); cmsg != NULL; cmsg = WSA_CMSG_NXTHDR(&hdr, cmsg))
2226 if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO)
2228 struct in_pktinfo *pi = (struct in_pktinfo *)WSA_CMSG_DATA(cmsg);
2230 ok(pi->ipi_addr.s_addr == s2addr.sin_addr.s_addr, "destination ip mismatch!\n");
2231 foundhdr = TRUE;
2234 ok(foundhdr, "IP_PKTINFO header information was not returned!\n");
2236 closesocket(s2);
2237 closesocket(s1);
2240 CloseHandle(ov.hEvent);
2243 static void test_ipv4_cmsg(void)
2245 static const DWORD off = 0;
2246 static const DWORD on = 1;
2247 SOCKADDR_IN localhost = {0};
2248 SOCKET client, server;
2249 char payload[] = "HELLO";
2250 char control[100];
2251 WSABUF payload_buf = {sizeof(payload), payload};
2252 WSAMSG msg = {NULL, 0, &payload_buf, 1, {sizeof(control), control}, 0};
2253 WSACMSGHDR *header = (WSACMSGHDR *)control;
2254 LPFN_WSARECVMSG pWSARecvMsg;
2255 INT *int_data = (INT *)WSA_CMSG_DATA(header);
2256 IN_PKTINFO *pkt_info = (IN_PKTINFO *)WSA_CMSG_DATA(header);
2257 DWORD count, state;
2258 int rc;
2260 localhost.sin_family = AF_INET;
2261 localhost.sin_port = htons(SERVERPORT);
2262 inet_pton(AF_INET, "127.0.0.1", &localhost.sin_addr);
2264 client = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
2265 ok(client != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
2266 server = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
2267 ok(server != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
2269 rc = bind(server, (SOCKADDR *)&localhost, sizeof(localhost));
2270 ok(rc != SOCKET_ERROR, "bind failed, error %u\n", WSAGetLastError());
2271 rc = connect(client, (SOCKADDR *)&localhost, sizeof(localhost));
2272 ok(rc != SOCKET_ERROR, "connect failed, error %u\n", WSAGetLastError());
2274 rc = WSAIoctl(server, SIO_GET_EXTENSION_FUNCTION_POINTER, &WSARecvMsg_GUID, sizeof(WSARecvMsg_GUID),
2275 &pWSARecvMsg, sizeof(pWSARecvMsg), &count, NULL, NULL);
2276 ok(!rc, "failed to get WSARecvMsg, error %u\n", WSAGetLastError());
2278 memset(control, 0, sizeof(control));
2279 msg.Control.len = sizeof(control);
2280 rc = setsockopt(server, IPPROTO_IP, IP_RECVTTL, (const char *)&on, sizeof(on));
2281 ok(!rc, "failed to set IP_RECVTTL, error %u\n", WSAGetLastError());
2282 state = 0;
2283 count = sizeof(state);
2284 rc = getsockopt(server, IPPROTO_IP, IP_RECVTTL, (char *)&state, (INT *)&count);
2285 ok(!rc, "failed to get IP_RECVTTL, error %u\n", WSAGetLastError());
2286 ok(state == 1, "expected 1, got %u\n", state);
2287 rc = send(client, payload, sizeof(payload), 0);
2288 ok(rc == sizeof(payload), "send failed, error %u\n", WSAGetLastError());
2289 rc = pWSARecvMsg(server, &msg, &count, NULL, NULL);
2290 ok(!rc, "WSARecvMsg failed, error %u\n", WSAGetLastError());
2291 ok(count == sizeof(payload), "expected length %Iu, got %u\n", sizeof(payload), count);
2292 ok(header->cmsg_level == IPPROTO_IP, "expected IPPROTO_IP, got %i\n", header->cmsg_level);
2293 ok(header->cmsg_type == IP_TTL || broken(header->cmsg_type == IP_HOPLIMIT) /* <= win10 v1607 */,
2294 "expected IP_TTL, got %i\n", header->cmsg_type);
2295 ok(header->cmsg_len == sizeof(*header) + sizeof(INT),
2296 "expected length %Iu, got %Iu\n", sizeof(*header) + sizeof(INT), header->cmsg_len);
2297 ok(*int_data >= 32, "expected at least 32, got %i\n", *int_data);
2298 setsockopt(server, IPPROTO_IP, IP_RECVTTL, (const char *)&off, sizeof(off));
2299 ok(!rc, "failed to clear IP_RECVTTL, error %u\n", WSAGetLastError());
2301 memset(control, 0, sizeof(control));
2302 msg.Control.len = sizeof(control);
2303 rc = setsockopt(server, IPPROTO_IP, IP_PKTINFO, (const char *)&on, sizeof(on));
2304 ok(!rc, "failed to set IP_PKTINFO, error %u\n", WSAGetLastError());
2305 state = 0;
2306 count = sizeof(state);
2307 rc = getsockopt(server, IPPROTO_IP, IP_PKTINFO, (char *)&state, (INT *)&count);
2308 ok(!rc, "failed to get IP_PKTINFO, error %u\n", WSAGetLastError());
2309 ok(state == 1, "expected 1, got %u\n", state);
2310 rc = send(client, payload, sizeof(payload), 0);
2311 ok(rc == sizeof(payload), "send failed, error %u\n", WSAGetLastError());
2312 rc = pWSARecvMsg(server, &msg, &count, NULL, NULL);
2313 ok(!rc, "WSARecvMsg failed, error %u\n", WSAGetLastError());
2314 ok(count == sizeof(payload), "expected length %Iu, got %u\n", sizeof(payload), count);
2315 ok(header->cmsg_level == IPPROTO_IP, "expected IPPROTO_IP, got %i\n", header->cmsg_level);
2316 ok(header->cmsg_type == IP_PKTINFO, "expected IP_PKTINFO, got %i\n", header->cmsg_type);
2317 ok(header->cmsg_len == sizeof(*header) + sizeof(IN_PKTINFO),
2318 "expected length %Iu, got %Iu\n", sizeof(*header) + sizeof(IN_PKTINFO), header->cmsg_len);
2319 ok(!memcmp(&pkt_info->ipi_addr, &localhost.sin_addr, sizeof(IN_ADDR)), "expected 127.0.0.1\n");
2320 rc = setsockopt(server, IPPROTO_IP, IP_PKTINFO, (const char *)&off, sizeof(off));
2321 ok(!rc, "failed to clear IP_PKTINFO, error %u\n", WSAGetLastError());
2323 memset(control, 0, sizeof(control));
2324 msg.Control.len = sizeof(control);
2325 rc = setsockopt(server, IPPROTO_IP, IP_RECVTOS, (const char *)&on, sizeof(on));
2326 ok(!rc, "failed to set IP_RECVTOS, error %u\n", WSAGetLastError());
2327 state = 0;
2328 count = sizeof(state);
2329 rc = getsockopt(server, IPPROTO_IP, IP_RECVTOS, (char *)&state, (INT *)&count);
2330 ok(!rc, "failed to get IP_RECVTOS, error %u\n", WSAGetLastError());
2331 ok(state == 1, "expected 1, got %u\n", state);
2332 rc = send(client, payload, sizeof(payload), 0);
2333 ok(rc == sizeof(payload), "send failed, error %u\n", WSAGetLastError());
2334 rc = pWSARecvMsg(server, &msg, &count, NULL, NULL);
2335 ok(!rc, "WSARecvMsg failed, error %u\n", WSAGetLastError());
2336 ok(count == sizeof(payload), "expected length %Iu, got %u\n", sizeof(payload), count);
2337 ok(header->cmsg_level == IPPROTO_IP, "expected IPPROTO_IP, got %i\n", header->cmsg_level);
2338 ok(header->cmsg_type == IP_TOS || broken(header->cmsg_type == IP_TCLASS) /* <= win10 v1607 */,
2339 "expected IP_TOS, got %i\n", header->cmsg_type);
2340 ok(header->cmsg_len == sizeof(*header) + sizeof(INT),
2341 "expected length %Iu, got %Iu\n", sizeof(*header) + sizeof(INT), header->cmsg_len);
2342 ok(*int_data == 0, "expected 0, got %i\n", *int_data);
2343 rc = setsockopt(server, IPPROTO_IP, IP_RECVTOS, (const char *)&off, sizeof(off));
2344 ok(!rc, "failed to clear IP_RECVTOS, error %u\n", WSAGetLastError());
2346 closesocket(server);
2347 closesocket(client);
2350 static void test_ipv6_cmsg(void)
2352 static const DWORD off = 0;
2353 static const DWORD on = 1;
2354 SOCKADDR_IN6 localhost = {0};
2355 SOCKET client, server;
2356 char payload[] = "HELLO";
2357 char control[100];
2358 WSABUF payload_buf = {sizeof(payload), payload};
2359 WSAMSG msg = {NULL, 0, &payload_buf, 1, {sizeof(control), control}, 0};
2360 WSACMSGHDR *header = (WSACMSGHDR *)control;
2361 LPFN_WSARECVMSG pWSARecvMsg;
2362 INT *int_data = (INT *)WSA_CMSG_DATA(header);
2363 IN6_PKTINFO *pkt_info = (IN6_PKTINFO *)WSA_CMSG_DATA(header);
2364 DWORD count, state;
2365 int rc;
2367 localhost.sin6_family = AF_INET6;
2368 localhost.sin6_port = htons(SERVERPORT);
2369 inet_pton(AF_INET6, "::1", &localhost.sin6_addr);
2371 client = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
2372 ok(client != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
2373 server = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
2374 ok(server != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
2376 rc = bind(server, (SOCKADDR *)&localhost, sizeof(localhost));
2377 ok(rc != SOCKET_ERROR, "bind failed, error %u\n", WSAGetLastError());
2378 rc = connect(client, (SOCKADDR *)&localhost, sizeof(localhost));
2379 ok(rc != SOCKET_ERROR, "connect failed, error %u\n", WSAGetLastError());
2381 rc = WSAIoctl(server, SIO_GET_EXTENSION_FUNCTION_POINTER, &WSARecvMsg_GUID, sizeof(WSARecvMsg_GUID),
2382 &pWSARecvMsg, sizeof(pWSARecvMsg), &count, NULL, NULL);
2383 ok(!rc, "failed to get WSARecvMsg, error %u\n", WSAGetLastError());
2385 memset(control, 0, sizeof(control));
2386 msg.Control.len = sizeof(control);
2387 rc = setsockopt(server, IPPROTO_IPV6, IPV6_HOPLIMIT, (const char *)&on, sizeof(on));
2388 ok(!rc, "failed to set IPV6_HOPLIMIT, error %u\n", WSAGetLastError());
2389 state = 0;
2390 count = sizeof(state);
2391 rc = getsockopt(server, IPPROTO_IPV6, IPV6_HOPLIMIT, (char *)&state, (INT *)&count);
2392 ok(!rc, "failed to get IPV6_HOPLIMIT, error %u\n", WSAGetLastError());
2393 ok(state == 1, "expected 1, got %u\n", state);
2394 rc = send(client, payload, sizeof(payload), 0);
2395 ok(rc == sizeof(payload), "send failed, error %u\n", WSAGetLastError());
2396 rc = pWSARecvMsg(server, &msg, &count, NULL, NULL);
2397 ok(!rc, "WSARecvMsg failed, error %u\n", WSAGetLastError());
2398 ok(count == sizeof(payload), "expected length %Iu, got %u\n", sizeof(payload), count);
2399 ok(header->cmsg_level == IPPROTO_IPV6, "expected IPPROTO_IPV6, got %i\n", header->cmsg_level);
2400 ok(header->cmsg_type == IPV6_HOPLIMIT, "expected IPV6_HOPLIMIT, got %i\n", header->cmsg_type);
2401 ok(header->cmsg_len == sizeof(*header) + sizeof(INT),
2402 "expected length %Iu, got %Iu\n", sizeof(*header) + sizeof(INT), header->cmsg_len);
2403 ok(*int_data >= 32, "expected at least 32, got %i\n", *int_data);
2404 setsockopt(server, IPPROTO_IPV6, IPV6_HOPLIMIT, (const char *)&off, sizeof(off));
2405 ok(!rc, "failed to clear IPV6_HOPLIMIT, error %u\n", WSAGetLastError());
2407 memset(control, 0, sizeof(control));
2408 msg.Control.len = sizeof(control);
2409 rc = setsockopt(server, IPPROTO_IPV6, IPV6_PKTINFO, (const char *)&on, sizeof(on));
2410 ok(!rc, "failed to set IPV6_PKTINFO, error %u\n", WSAGetLastError());
2411 state = 0;
2412 count = sizeof(state);
2413 rc = getsockopt(server, IPPROTO_IPV6, IPV6_PKTINFO, (char *)&state, (INT *)&count);
2414 ok(!rc, "failed to get IPV6_PKTINFO, error %u\n", WSAGetLastError());
2415 ok(state == 1, "expected 1, got %u\n", state);
2416 rc = send(client, payload, sizeof(payload), 0);
2417 ok(rc == sizeof(payload), "send failed, error %u\n", WSAGetLastError());
2418 rc = pWSARecvMsg(server, &msg, &count, NULL, NULL);
2419 ok(!rc, "WSARecvMsg failed, error %u\n", WSAGetLastError());
2420 ok(count == sizeof(payload), "expected length %Iu, got %u\n", sizeof(payload), count);
2421 ok(header->cmsg_level == IPPROTO_IPV6, "expected IPPROTO_IPV6, got %i\n", header->cmsg_level);
2422 ok(header->cmsg_type == IPV6_PKTINFO, "expected IPV6_PKTINFO, got %i\n", header->cmsg_type);
2423 ok(header->cmsg_len == sizeof(*header) + sizeof(IN6_PKTINFO),
2424 "expected length %Iu, got %Iu\n", sizeof(*header) + sizeof(IN6_PKTINFO), header->cmsg_len);
2425 ok(!memcmp(&pkt_info->ipi6_addr, &localhost.sin6_addr, sizeof(IN6_ADDR)), "expected ::1\n");
2426 rc = setsockopt(server, IPPROTO_IPV6, IPV6_PKTINFO, (const char *)&off, sizeof(off));
2427 ok(!rc, "failed to clear IPV6_PKTINFO, error %u\n", WSAGetLastError());
2429 memset(control, 0, sizeof(control));
2430 msg.Control.len = sizeof(control);
2431 rc = setsockopt(server, IPPROTO_IPV6, IPV6_RECVTCLASS, (const char *)&on, sizeof(on));
2432 ok(!rc, "failed to set IPV6_RECVTCLASS, error %u\n", WSAGetLastError());
2433 state = 0;
2434 count = sizeof(state);
2435 rc = getsockopt(server, IPPROTO_IPV6, IPV6_RECVTCLASS, (char *)&state, (INT *)&count);
2436 ok(!rc, "failed to get IPV6_RECVTCLASS, error %u\n", WSAGetLastError());
2437 ok(state == 1, "expected 1, got %u\n", state);
2438 rc = send(client, payload, sizeof(payload), 0);
2439 ok(rc == sizeof(payload), "send failed, error %u\n", WSAGetLastError());
2440 rc = pWSARecvMsg(server, &msg, &count, NULL, NULL);
2441 ok(!rc, "WSARecvMsg failed, error %u\n", WSAGetLastError());
2442 ok(count == sizeof(payload), "expected length %Iu, got %u\n", sizeof(payload), count);
2443 ok(header->cmsg_level == IPPROTO_IPV6, "expected IPPROTO_IPV6, got %i\n", header->cmsg_level);
2444 ok(header->cmsg_type == IPV6_TCLASS, "expected IPV6_TCLASS, got %i\n", header->cmsg_type);
2445 ok(header->cmsg_len == sizeof(*header) + sizeof(INT),
2446 "expected length %Iu, got %Iu\n", sizeof(*header) + sizeof(INT), header->cmsg_len);
2447 ok(*int_data == 0, "expected 0, got %i\n", *int_data);
2448 rc = setsockopt(server, IPPROTO_IPV6, IPV6_RECVTCLASS, (const char *)&off, sizeof(off));
2449 ok(!rc, "failed to clear IPV6_RECVTCLASS, error %u\n", WSAGetLastError());
2451 closesocket(server);
2452 closesocket(client);
2455 /************* Array containing the tests to run **********/
2457 #define STD_STREAM_SOCKET \
2458 SOCK_STREAM, \
2459 0, \
2460 SERVERIP, \
2461 SERVERPORT
2463 static test_setup tests [] =
2465 /* Test 0: synchronous client and server */
2468 STD_STREAM_SOCKET,
2469 2048,
2473 simple_server,
2475 NULL,
2479 simple_client,
2481 NULL,
2486 /* Test 1: event-driven client, synchronous server */
2489 STD_STREAM_SOCKET,
2490 2048,
2494 simple_server,
2496 NULL,
2500 event_client,
2502 NULL,
2503 WSA_FLAG_OVERLAPPED,
2507 /* Test 2: synchronous client, non-blocking server via select() */
2510 STD_STREAM_SOCKET,
2511 2048,
2515 select_server,
2517 NULL,
2521 simple_client,
2523 NULL,
2528 /* Test 3: OOB client, OOB server */
2531 STD_STREAM_SOCKET,
2532 128,
2536 oob_server,
2538 NULL,
2542 oob_client,
2544 NULL,
2549 /* Test 4: synchronous mixed client and server */
2552 STD_STREAM_SOCKET,
2553 2048,
2557 simple_server,
2559 NULL,
2563 simple_mixed_client,
2565 NULL,
2572 static void test_UDP(void)
2574 /* This function tests UDP sendto() and recvfrom(). UDP is unreliable, so it is
2575 possible that this test fails due to dropped packets. */
2577 /* peer 0 receives data from all other peers */
2578 struct sock_info peer[NUM_UDP_PEERS];
2579 char buf[16];
2580 int ss, i, n_recv, n_sent;
2582 memset (buf,0,sizeof(buf));
2583 for ( i = NUM_UDP_PEERS - 1; i >= 0; i-- ) {
2584 ok ( ( peer[i].s = socket ( AF_INET, SOCK_DGRAM, 0 ) ) != INVALID_SOCKET, "UDP: socket failed\n" );
2586 peer[i].addr.sin_family = AF_INET;
2587 peer[i].addr.sin_addr.s_addr = inet_addr ( SERVERIP );
2589 if ( i == 0 ) {
2590 peer[i].addr.sin_port = htons ( SERVERPORT );
2591 } else {
2592 peer[i].addr.sin_port = htons ( 0 );
2595 do_bind ( peer[i].s, (struct sockaddr *) &peer[i].addr, sizeof( peer[i].addr ) );
2597 /* test getsockname() to get peer's port */
2598 ss = sizeof ( peer[i].addr );
2599 ok ( getsockname ( peer[i].s, (struct sockaddr *) &peer[i].addr, &ss ) != SOCKET_ERROR, "UDP: could not getsockname()\n" );
2600 ok ( peer[i].addr.sin_port != htons ( 0 ), "UDP: bind() did not associate port\n" );
2603 /* test getsockname() */
2604 ok ( peer[0].addr.sin_port == htons ( SERVERPORT ), "UDP: getsockname returned incorrect peer port\n" );
2606 for ( i = 1; i < NUM_UDP_PEERS; i++ ) {
2607 /* send client's ip */
2608 memcpy( buf, &peer[i].addr.sin_port, sizeof(peer[i].addr.sin_port) );
2609 n_sent = sendto ( peer[i].s, buf, sizeof(buf), 0, (struct sockaddr*) &peer[0].addr, sizeof(peer[0].addr) );
2610 ok ( n_sent == sizeof(buf), "UDP: sendto() sent wrong amount of data or socket error: %d\n", n_sent );
2613 for ( i = 1; i < NUM_UDP_PEERS; i++ ) {
2614 n_recv = recvfrom ( peer[0].s, buf, sizeof(buf), 0,(struct sockaddr *) &peer[0].peer, &ss );
2615 ok ( n_recv == sizeof(buf), "UDP: recvfrom() received wrong amount of data or socket error: %d\n", n_recv );
2616 ok ( memcmp ( &peer[0].peer.sin_port, buf, sizeof(peer[0].addr.sin_port) ) == 0, "UDP: port numbers do not match\n" );
2620 static void test_WSASocket(void)
2622 SOCKET sock = INVALID_SOCKET;
2623 WSAPROTOCOL_INFOA *pi;
2624 int wsaproviders[] = {IPPROTO_TCP, IPPROTO_IP};
2625 int autoprotocols[] = {IPPROTO_TCP, IPPROTO_UDP};
2626 int items, err, size, socktype, i, j;
2627 UINT pi_size;
2629 static const struct
2631 int family, type, protocol;
2632 DWORD error;
2633 int ret_family, ret_type, ret_protocol;
2635 tests[] =
2637 /* 0 */
2638 {0xdead, SOCK_STREAM, IPPROTO_TCP, WSAEAFNOSUPPORT},
2639 {-1, SOCK_STREAM, IPPROTO_TCP, WSAEAFNOSUPPORT},
2640 {AF_INET, 0xdead, IPPROTO_TCP, WSAESOCKTNOSUPPORT},
2641 {AF_INET, -1, IPPROTO_TCP, WSAESOCKTNOSUPPORT},
2642 {AF_INET, SOCK_STREAM, 0xdead, WSAEPROTONOSUPPORT},
2643 {AF_INET, SOCK_STREAM, -1, WSAEPROTONOSUPPORT},
2644 {0xdead, 0xdead, IPPROTO_TCP, WSAESOCKTNOSUPPORT},
2645 {0xdead, SOCK_STREAM, 0xdead, WSAEAFNOSUPPORT},
2646 {AF_INET, 0xdead, 0xdead, WSAESOCKTNOSUPPORT},
2647 {0xdead, SOCK_STREAM, IPPROTO_UDP, WSAEAFNOSUPPORT},
2649 /* 10 */
2650 {AF_INET, SOCK_STREAM, 0, 0, AF_INET, SOCK_STREAM, IPPROTO_TCP},
2651 {AF_INET, SOCK_DGRAM, 0, 0, AF_INET, SOCK_DGRAM, IPPROTO_UDP},
2652 {AF_INET, 0xdead, 0, WSAESOCKTNOSUPPORT},
2653 {AF_INET, 0, IPPROTO_TCP, 0, AF_INET, SOCK_STREAM, IPPROTO_TCP},
2654 {AF_INET, 0, IPPROTO_UDP, 0, AF_INET, SOCK_DGRAM, IPPROTO_UDP},
2655 {AF_INET, 0, 0xdead, WSAEPROTONOSUPPORT},
2656 {AF_INET, 0, 0, 0, AF_INET, SOCK_STREAM, IPPROTO_TCP},
2657 {AF_INET, SOCK_STREAM, IPPROTO_UDP, WSAEPROTONOSUPPORT},
2658 {AF_INET, SOCK_DGRAM, IPPROTO_TCP, WSAEPROTONOSUPPORT},
2660 /* 19 */
2661 {AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP, 0, AF_INET, SOCK_STREAM, IPPROTO_TCP},
2662 {AF_UNSPEC, SOCK_STREAM, 0xdead, WSAEPROTONOSUPPORT},
2663 {AF_UNSPEC, 0xdead, IPPROTO_UDP, WSAESOCKTNOSUPPORT},
2664 {AF_UNSPEC, SOCK_STREAM, 0, WSAEINVAL},
2665 {AF_UNSPEC, SOCK_DGRAM, 0, WSAEINVAL},
2666 {AF_UNSPEC, 0xdead, 0, WSAEINVAL},
2667 {AF_UNSPEC, 0, IPPROTO_TCP, 0, AF_INET, SOCK_STREAM, IPPROTO_TCP},
2668 {AF_UNSPEC, 0, IPPROTO_UDP, 0, AF_INET, SOCK_DGRAM, IPPROTO_UDP},
2669 {AF_UNSPEC, 0, 0xdead, WSAEPROTONOSUPPORT},
2670 {AF_UNSPEC, 0, 0, WSAEINVAL},
2673 for (i = 0; i < ARRAY_SIZE(tests); ++i)
2675 SetLastError( 0xdeadbeef );
2676 sock = WSASocketA( tests[i].family, tests[i].type, tests[i].protocol, NULL, 0, 0 );
2677 todo_wine_if (i == 7)
2678 ok(WSAGetLastError() == tests[i].error, "Test %u: got wrong error %u\n", i, WSAGetLastError());
2679 if (tests[i].error)
2681 ok(sock == INVALID_SOCKET, "Test %u: expected failure\n", i);
2683 else
2685 WSAPROTOCOL_INFOA info;
2687 ok(sock != INVALID_SOCKET, "Text %u: expected success\n", i);
2689 size = sizeof(info);
2690 err = getsockopt( sock, SOL_SOCKET, SO_PROTOCOL_INFOA, (char *)&info, &size );
2691 ok(!err, "Test %u: getsockopt failed, error %u\n", i, WSAGetLastError());
2692 ok(info.iAddressFamily == tests[i].ret_family, "Test %u: got wrong family %d\n", i, info.iAddressFamily);
2693 ok(info.iSocketType == tests[i].ret_type, "Test %u: got wrong type %d\n", i, info.iSocketType);
2694 ok(info.iProtocol == tests[i].ret_protocol, "Test %u: got wrong protocol %d\n", i, info.iProtocol);
2696 closesocket( sock );
2700 /* Set pi_size explicitly to a value below 2*sizeof(WSAPROTOCOL_INFOA)
2701 * to avoid a crash on win98.
2703 pi_size = 0;
2704 items = WSAEnumProtocolsA(wsaproviders, NULL, &pi_size);
2705 ok(items == SOCKET_ERROR, "WSAEnumProtocolsA({6,0}, NULL, 0) returned %d\n",
2706 items);
2707 err = WSAGetLastError();
2708 ok(err == WSAENOBUFS, "WSAEnumProtocolsA error is %d, not WSAENOBUFS(%d)\n",
2709 err, WSAENOBUFS);
2711 pi = HeapAlloc(GetProcessHeap(), 0, pi_size);
2712 ok(pi != NULL, "Failed to allocate memory\n");
2714 items = WSAEnumProtocolsA(wsaproviders, pi, &pi_size);
2715 ok(items != SOCKET_ERROR, "WSAEnumProtocolsA failed, last error is %d\n",
2716 WSAGetLastError());
2718 if (items == 0) {
2719 skip("No protocols enumerated.\n");
2720 HeapFree(GetProcessHeap(), 0, pi);
2721 return;
2724 sock = WSASocketA(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO,
2725 FROM_PROTOCOL_INFO, &pi[0], 0, 0);
2726 ok(sock != INVALID_SOCKET, "Failed to create socket: %d\n",
2727 WSAGetLastError());
2728 closesocket(sock);
2730 /* find what parameters are used first: plain parameters or protocol info struct */
2731 pi[0].iProtocol = -1;
2732 pi[0].iSocketType = -1;
2733 pi[0].iAddressFamily = -1;
2734 ok(WSASocketA(0, 0, IPPROTO_UDP, &pi[0], 0, 0) == INVALID_SOCKET,
2735 "WSASocketA should have failed\n");
2736 err = WSAGetLastError();
2737 ok(err == WSAEAFNOSUPPORT, "Expected 10047, received %d\n", err);
2739 pi[0].iProtocol = 0;
2740 pi[0].iSocketType = 0;
2741 pi[0].iAddressFamily = 0;
2742 sock = WSASocketA(0, 0, IPPROTO_UDP, &pi[0], 0, 0);
2743 if(sock != INVALID_SOCKET)
2745 win_skip("must work only in OS <= 2003\n");
2746 closesocket(sock);
2748 else
2750 err = WSAGetLastError();
2751 ok(err == WSAEAFNOSUPPORT, "Expected 10047, received %d\n", err);
2754 pi[0].iProtocol = IPPROTO_UDP;
2755 pi[0].iSocketType = SOCK_DGRAM;
2756 pi[0].iAddressFamily = AF_INET;
2757 sock = WSASocketA(0, 0, 0, &pi[0], 0, 0);
2758 ok(sock != INVALID_SOCKET, "Failed to create socket: %d\n",
2759 WSAGetLastError());
2761 size = sizeof(socktype);
2762 socktype = 0xdead;
2763 err = getsockopt(sock, SOL_SOCKET, SO_TYPE, (char *) &socktype, &size);
2764 ok(!err,"getsockopt failed with %d\n", WSAGetLastError());
2765 ok(socktype == SOCK_DGRAM, "Wrong socket type, expected %d received %d\n",
2766 SOCK_DGRAM, socktype);
2768 socktype = SOCK_STREAM;
2769 WSASetLastError(0xdeadbeef);
2770 err = setsockopt(sock, SOL_SOCKET, SO_TYPE, (char *)&socktype, sizeof(socktype));
2771 ok(err == -1, "expected failure\n");
2772 todo_wine ok(WSAGetLastError() == WSAEINVAL, "got error %u\n", WSAGetLastError());
2774 socktype = SOCK_DGRAM;
2775 WSASetLastError(0xdeadbeef);
2776 err = setsockopt(sock, SOL_SOCKET, SO_TYPE, (char *)&socktype, sizeof(socktype));
2777 ok(err == -1, "expected failure\n");
2778 todo_wine ok(WSAGetLastError() == WSAEINVAL, "got error %u\n", WSAGetLastError());
2780 closesocket(sock);
2782 sock = WSASocketA(AF_INET, SOCK_STREAM, IPPROTO_TCP, &pi[0], 0, 0);
2783 ok(sock != INVALID_SOCKET, "Failed to create socket: %d\n",
2784 WSAGetLastError());
2786 size = sizeof(socktype);
2787 socktype = 0xdead;
2788 err = getsockopt(sock, SOL_SOCKET, SO_TYPE, (char *) &socktype, &size);
2789 ok(!err,"getsockopt failed with %d\n", WSAGetLastError());
2790 ok(socktype == SOCK_STREAM, "Wrong socket type, expected %d received %d\n",
2791 SOCK_STREAM, socktype);
2793 socktype = SOCK_STREAM;
2794 WSASetLastError(0xdeadbeef);
2795 err = setsockopt(sock, SOL_SOCKET, SO_TYPE, (char *)&socktype, sizeof(socktype));
2796 ok(err == -1, "expected failure\n");
2797 ok(WSAGetLastError() == WSAENOPROTOOPT, "got error %u\n", WSAGetLastError());
2799 socktype = SOCK_DGRAM;
2800 WSASetLastError(0xdeadbeef);
2801 err = setsockopt(sock, SOL_SOCKET, SO_TYPE, (char *)&socktype, sizeof(socktype));
2802 ok(err == -1, "expected failure\n");
2803 ok(WSAGetLastError() == WSAENOPROTOOPT, "got error %u\n", WSAGetLastError());
2805 closesocket(sock);
2807 HeapFree(GetProcessHeap(), 0, pi);
2809 pi_size = 0;
2810 items = WSAEnumProtocolsA(NULL, NULL, &pi_size);
2811 ok(items == SOCKET_ERROR, "WSAEnumProtocolsA(NULL, NULL, 0) returned %d\n",
2812 items);
2813 err = WSAGetLastError();
2814 ok(err == WSAENOBUFS, "WSAEnumProtocolsA error is %d, not WSAENOBUFS(%d)\n",
2815 err, WSAENOBUFS);
2817 pi = HeapAlloc(GetProcessHeap(), 0, pi_size);
2818 ok(pi != NULL, "Failed to allocate memory\n");
2820 items = WSAEnumProtocolsA(NULL, pi, &pi_size);
2821 ok(items != SOCKET_ERROR, "WSAEnumProtocolsA failed, last error is %d\n",
2822 WSAGetLastError());
2824 /* when no protocol and socket type are specified the first entry
2825 * from WSAEnumProtocols that has the flag PFL_MATCHES_PROTOCOL_ZERO
2826 * is returned */
2827 sock = WSASocketA(AF_INET, 0, 0, NULL, 0, 0);
2828 ok(sock != INVALID_SOCKET, "Failed to create socket: %d\n",
2829 WSAGetLastError());
2831 size = sizeof(socktype);
2832 socktype = 0xdead;
2833 err = getsockopt(sock, SOL_SOCKET, SO_TYPE, (char *) &socktype, &size);
2834 ok(!err, "getsockopt failed with %d\n", WSAGetLastError());
2835 for(i = 0; i < items; i++)
2837 if(pi[i].dwProviderFlags & PFL_MATCHES_PROTOCOL_ZERO)
2839 ok(socktype == pi[i].iSocketType, "Wrong socket type, expected %d received %d\n",
2840 pi[i].iSocketType, socktype);
2841 break;
2844 ok(i != items, "Creating a socket without protocol and socket type didn't work\n");
2845 closesocket(sock);
2847 /* when no socket type is specified the first entry from WSAEnumProtocols
2848 * that matches the protocol is returned */
2849 for (i = 0; i < ARRAY_SIZE(autoprotocols); i++)
2851 sock = WSASocketA(0, 0, autoprotocols[i], NULL, 0, 0);
2852 ok(sock != INVALID_SOCKET, "Failed to create socket for protocol %d, received %d\n",
2853 autoprotocols[i], WSAGetLastError());
2855 size = sizeof(socktype);
2856 socktype = 0xdead;
2857 err = getsockopt(sock, SOL_SOCKET, SO_TYPE, (char *) &socktype, &size);
2858 ok(!err, "getsockopt failed with %d\n", WSAGetLastError());
2860 for (err = 1, j = 0; j < items; j++)
2862 if (pi[j].iProtocol == autoprotocols[i])
2864 ok(pi[j].iSocketType == socktype, "expected %d, got %d\n", socktype, pi[j].iSocketType);
2865 err = 0;
2866 break;
2869 ok(!err, "Protocol %d not found in WSAEnumProtocols\n", autoprotocols[i]);
2871 closesocket(sock);
2874 HeapFree(GetProcessHeap(), 0, pi);
2876 SetLastError(0xdeadbeef);
2877 /* starting on vista the socket function returns error during the socket
2878 creation and no longer in the socket operations (sendto, readfrom) */
2879 sock = WSASocketA(AF_INET, SOCK_RAW, IPPROTO_ICMP, NULL, 0, 0);
2880 if (sock == INVALID_SOCKET)
2882 err = WSAGetLastError();
2883 ok(err == WSAEACCES, "Expected 10013, received %d\n", err);
2884 skip("SOCK_RAW is not supported\n");
2886 else
2888 size = sizeof(socktype);
2889 socktype = 0xdead;
2890 err = getsockopt(sock, SOL_SOCKET, SO_TYPE, (char *) &socktype, &size);
2891 ok(!err, "getsockopt failed with %d\n", WSAGetLastError());
2892 ok(socktype == SOCK_RAW, "Wrong socket type, expected %d received %d\n",
2893 SOCK_RAW, socktype);
2894 closesocket(sock);
2896 sock = WSASocketA(0, 0, IPPROTO_RAW, NULL, 0, 0);
2897 if (sock != INVALID_SOCKET)
2899 todo_wine {
2900 size = sizeof(socktype);
2901 socktype = 0xdead;
2902 err = getsockopt(sock, SOL_SOCKET, SO_TYPE, (char *) &socktype, &size);
2903 ok(!err, "getsockopt failed with %d\n", WSAGetLastError());
2904 ok(socktype == SOCK_RAW, "Wrong socket type, expected %d received %d\n",
2905 SOCK_RAW, socktype);
2906 closesocket(sock);
2909 sock = WSASocketA(AF_INET, SOCK_RAW, IPPROTO_TCP, NULL, 0, 0);
2910 ok(sock != INVALID_SOCKET, "Failed to create socket: %d\n",
2911 WSAGetLastError());
2912 size = sizeof(socktype);
2913 socktype = 0xdead;
2914 err = getsockopt(sock, SOL_SOCKET, SO_TYPE, (char *) &socktype, &size);
2915 ok(!err, "getsockopt failed with %d\n", WSAGetLastError());
2916 ok(socktype == SOCK_RAW, "Wrong socket type, expected %d received %d\n",
2917 SOCK_RAW, socktype);
2918 closesocket(sock);
2920 else if (WSAGetLastError() == WSAEACCES)
2921 skip("SOCK_RAW is not available\n");
2922 else
2923 ok(0, "Failed to create socket: %d\n", WSAGetLastError());
2927 /* IPX socket tests */
2929 SetLastError(0xdeadbeef);
2930 sock = WSASocketA(AF_IPX, SOCK_DGRAM, NSPROTO_IPX, NULL, 0, 0);
2931 if (sock == INVALID_SOCKET)
2933 ok(WSAGetLastError() == WSAEAFNOSUPPORT, "got error %u\n", WSAGetLastError());
2934 skip("IPX is not supported\n");
2936 else
2938 WSAPROTOCOL_INFOA info;
2939 closesocket(sock);
2941 sock = WSASocketA(0, 0, NSPROTO_IPX, NULL, 0, 0);
2942 ok(sock != INVALID_SOCKET, "Failed to create socket: %d\n",
2943 WSAGetLastError());
2945 size = sizeof(socktype);
2946 socktype = 0xdead;
2947 err = getsockopt(sock, SOL_SOCKET, SO_TYPE, (char *) &socktype, &size);
2948 ok(!err,"getsockopt failed with %d\n", WSAGetLastError());
2949 ok(socktype == SOCK_DGRAM, "Wrong socket type, expected %d received %d\n",
2950 SOCK_DGRAM, socktype);
2952 /* check socket family, type and protocol */
2953 size = sizeof(WSAPROTOCOL_INFOA);
2954 err = getsockopt(sock, SOL_SOCKET, SO_PROTOCOL_INFOA, (char *) &info, &size);
2955 ok(!err,"getsockopt failed with %d\n", WSAGetLastError());
2956 ok(info.iProtocol == NSPROTO_IPX, "expected protocol %d, received %d\n",
2957 NSPROTO_IPX, info.iProtocol);
2958 ok(info.iAddressFamily == AF_IPX, "expected family %d, received %d\n",
2959 AF_IPX, info.iProtocol);
2960 ok(info.iSocketType == SOCK_DGRAM, "expected type %d, received %d\n",
2961 SOCK_DGRAM, info.iSocketType);
2962 closesocket(sock);
2964 /* SOCK_STREAM does not support NSPROTO_IPX */
2965 SetLastError(0xdeadbeef);
2966 ok(WSASocketA(AF_IPX, SOCK_STREAM, NSPROTO_IPX, NULL, 0, 0) == INVALID_SOCKET,
2967 "WSASocketA should have failed\n");
2968 err = WSAGetLastError();
2969 ok(err == WSAEPROTONOSUPPORT, "Expected 10043, received %d\n", err);
2971 /* test extended IPX support - that is adding any number between 0 and 255
2972 * to the IPX protocol value will make it be used as IPX packet type */
2973 for(i = 0;i <= 255;i += 17)
2975 SetLastError(0xdeadbeef);
2976 sock = WSASocketA(0, 0, NSPROTO_IPX + i, NULL, 0, 0);
2977 ok(sock != INVALID_SOCKET, "Failed to create socket: %d\n",
2978 WSAGetLastError());
2980 size = sizeof(int);
2981 socktype = -1;
2982 err = getsockopt(sock, NSPROTO_IPX, IPX_PTYPE, (char *) &socktype, &size);
2983 ok(!err, "getsockopt failed with %d\n", WSAGetLastError());
2984 ok(socktype == i, "Wrong IPX packet type, expected %d received %d\n",
2985 i, socktype);
2987 closesocket(sock);
2992 static void test_WSADuplicateSocket(void)
2994 SOCKET source, dupsock;
2995 WSAPROTOCOL_INFOA info;
2996 DWORD err;
2997 struct sockaddr_in addr;
2998 int socktype, size, addrsize, ret;
2999 char teststr[] = "TEST", buffer[16];
3001 source = WSASocketA(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0);
3002 ok(source != INVALID_SOCKET, "WSASocketA should have succeeded\n");
3004 /* test invalid parameters */
3005 SetLastError(0xdeadbeef);
3006 ok(WSADuplicateSocketA(0, 0, NULL), "WSADuplicateSocketA should have failed\n");
3007 err = WSAGetLastError();
3008 ok(err == WSAENOTSOCK, "expected 10038, received %d\n", err);
3010 SetLastError(0xdeadbeef);
3011 ok(WSADuplicateSocketA(source, 0, NULL),
3012 "WSADuplicateSocketA should have failed\n");
3013 err = WSAGetLastError();
3014 ok(err == WSAEINVAL, "expected 10022, received %d\n", err);
3016 SetLastError(0xdeadbeef);
3017 ok(WSADuplicateSocketA(source, ~0, &info),
3018 "WSADuplicateSocketA should have failed\n");
3019 err = WSAGetLastError();
3020 ok(err == WSAEINVAL, "expected 10022, received %d\n", err);
3022 SetLastError(0xdeadbeef);
3023 ok(WSADuplicateSocketA(0, GetCurrentProcessId(), &info),
3024 "WSADuplicateSocketA should have failed\n");
3025 err = WSAGetLastError();
3026 ok(err == WSAENOTSOCK, "expected 10038, received %d\n", err);
3028 SetLastError(0xdeadbeef);
3029 ok(WSADuplicateSocketA(source, GetCurrentProcessId(), NULL),
3030 "WSADuplicateSocketA should have failed\n");
3031 err = WSAGetLastError();
3032 ok(err == WSAEFAULT, "expected 10014, received %d\n", err);
3034 /* test returned structure */
3035 memset(&info, 0, sizeof(info));
3036 ok(!WSADuplicateSocketA(source, GetCurrentProcessId(), &info),
3037 "WSADuplicateSocketA should have worked\n");
3039 ok(info.iProtocol == IPPROTO_TCP, "expected protocol %d, received %d\n",
3040 IPPROTO_TCP, info.iProtocol);
3041 ok(info.iAddressFamily == AF_INET, "expected family %d, received %d\n",
3042 AF_INET, info.iProtocol);
3043 ok(info.iSocketType == SOCK_STREAM, "expected type %d, received %d\n",
3044 SOCK_STREAM, info.iSocketType);
3046 dupsock = WSASocketA(0, 0, 0, &info, 0, 0);
3047 ok(dupsock != INVALID_SOCKET, "WSASocketA should have succeeded\n");
3049 closesocket(dupsock);
3050 closesocket(source);
3052 /* create a socket, bind it, duplicate it then send data on source and
3053 * receive in the duplicated socket */
3054 source = WSASocketA(AF_INET, SOCK_DGRAM, IPPROTO_UDP, NULL, 0, 0);
3055 ok(source != INVALID_SOCKET, "WSASocketA should have succeeded\n");
3057 memset(&info, 0, sizeof(info));
3058 ok(!WSADuplicateSocketA(source, GetCurrentProcessId(), &info),
3059 "WSADuplicateSocketA should have worked\n");
3061 ok(info.iProtocol == IPPROTO_UDP, "expected protocol %d, received %d\n",
3062 IPPROTO_UDP, info.iProtocol);
3063 ok(info.iAddressFamily == AF_INET, "expected family %d, received %d\n",
3064 AF_INET, info.iProtocol);
3065 ok(info.iSocketType == SOCK_DGRAM, "expected type %d, received %d\n",
3066 SOCK_DGRAM, info.iSocketType);
3068 memset(&addr, 0, sizeof(addr));
3069 addr.sin_family = AF_INET;
3070 addr.sin_addr.s_addr = inet_addr("127.0.0.1");
3071 ok(!bind(source, (struct sockaddr*)&addr, sizeof(addr)),
3072 "bind should have worked\n");
3074 /* read address to find out the port number to be used in sendto */
3075 memset(&addr, 0, sizeof(addr));
3076 addrsize = sizeof(addr);
3077 ok(!getsockname(source, (struct sockaddr *) &addr, &addrsize),
3078 "getsockname should have worked\n");
3079 ok(addr.sin_port, "socket port should be != 0\n");
3081 dupsock = WSASocketA(0, 0, 0, &info, 0, 0);
3082 ok(dupsock != INVALID_SOCKET, "WSASocketA should have succeeded\n");
3084 size = sizeof(int);
3085 ret = getsockopt(dupsock, SOL_SOCKET, SO_TYPE, (char *) &socktype, &size);
3086 ok(!ret, "getsockopt failed with %d\n", WSAGetLastError());
3087 ok(socktype == SOCK_DGRAM, "Wrong socket type, expected %d received %d\n",
3088 SOCK_DGRAM, socktype);
3090 set_blocking(source, TRUE);
3092 /* send data on source socket */
3093 addrsize = sizeof(addr);
3094 size = sendto(source, teststr, sizeof(teststr), 0, (struct sockaddr *) &addr, addrsize);
3095 ok(size == sizeof(teststr), "got %d (err %d)\n", size, WSAGetLastError());
3097 /* receive on duplicated socket */
3098 addrsize = sizeof(addr);
3099 memset(buffer, 0, sizeof(buffer));
3100 size = recvfrom(dupsock, buffer, sizeof(teststr), 0, (struct sockaddr *) &addr, &addrsize);
3101 ok(size == sizeof(teststr), "got %d (err %d)\n", size, WSAGetLastError());
3102 buffer[sizeof(teststr) - 1] = 0;
3103 ok(!strcmp(buffer, teststr), "expected '%s', received '%s'\n", teststr, buffer);
3105 closesocket(dupsock);
3106 closesocket(source);
3108 /* show that the source socket need to be bound before the duplicated
3109 * socket is created */
3110 source = WSASocketA(AF_INET, SOCK_DGRAM, IPPROTO_UDP, NULL, 0, 0);
3111 ok(source != INVALID_SOCKET, "WSASocketA should have succeeded\n");
3113 memset(&info, 0, sizeof(info));
3114 ok(!WSADuplicateSocketA(source, GetCurrentProcessId(), &info),
3115 "WSADuplicateSocketA should have worked\n");
3117 dupsock = WSASocketA(0, 0, 0, &info, 0, 0);
3118 ok(dupsock != INVALID_SOCKET, "WSASocketA should have succeeded\n");
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 set_blocking(source, TRUE);
3135 addrsize = sizeof(addr);
3136 size = sendto(source, teststr, sizeof(teststr), 0, (struct sockaddr *) &addr, addrsize);
3137 ok(size == sizeof(teststr), "got %d (err %d)\n", size, WSAGetLastError());
3139 SetLastError(0xdeadbeef);
3140 addrsize = sizeof(addr);
3141 memset(buffer, 0, sizeof(buffer));
3142 todo_wine {
3143 ok(recvfrom(dupsock, buffer, sizeof(teststr), 0, (struct sockaddr *) &addr, &addrsize) == -1,
3144 "recvfrom should have failed\n");
3145 err = WSAGetLastError();
3146 ok(err == WSAEINVAL, "expected 10022, received %d\n", err);
3149 closesocket(dupsock);
3150 closesocket(source);
3153 static void test_WSAEnumNetworkEvents(void)
3155 SOCKET s, s2;
3156 int sock_type[] = {SOCK_STREAM, SOCK_DGRAM, SOCK_STREAM}, i, j, k, l;
3157 struct sockaddr_in address;
3158 HANDLE event;
3159 WSANETWORKEVENTS net_events;
3161 memset(&address, 0, sizeof(address));
3162 address.sin_addr.s_addr = htonl(INADDR_ANY);
3163 address.sin_family = AF_INET;
3165 /* This test follows the steps from bugs 10204 and 24946 */
3166 for (l = 0; l < 2; l++)
3168 for (i = 0; i < ARRAY_SIZE(sock_type); i++)
3170 if (i == 2)
3171 tcp_socketpair(&s, &s2);
3172 else
3174 s = socket(AF_INET, sock_type[i], 0);
3175 ok (s != SOCKET_ERROR, "Test[%d]: failed to create socket\n", i);
3176 ok (!bind(s, (struct sockaddr*) &address, sizeof(address)), "Test[%d]: bind failed\n", i);
3178 event = WSACreateEvent();
3179 ok (event != NULL, "Test[%d]: failed to create event\n", i);
3180 for (j = 0; j < 5; j++) /* Repeat sometimes and the result must be the same */
3182 /* When the TCP socket is not connected NO events will be returned.
3183 * When connected and no data pending it will get the write event.
3184 * UDP sockets don't have connections so as soon as they are bound
3185 * they can read/write data. Since nobody is sendind us data only
3186 * the write event will be returned and ONLY once.
3188 ok (!WSAEventSelect(s, event, FD_READ | FD_WRITE), "Test[%d]: WSAEventSelect failed\n", i);
3189 memset(&net_events, 0xAB, sizeof(net_events));
3190 ok (!WSAEnumNetworkEvents(s, l == 0 ? event : NULL, &net_events),
3191 "Test[%d]: WSAEnumNetworkEvents failed\n", i);
3192 if (i >= 1 && j == 0) /* FD_WRITE is SET on first try for UDP and connected TCP */
3194 ok (net_events.lNetworkEvents == FD_WRITE, "Test[%d]: expected 2, got %d\n",
3195 i, net_events.lNetworkEvents);
3197 else
3199 ok (net_events.lNetworkEvents == 0, "Test[%d]: expected 0, got %d\n",
3200 i, net_events.lNetworkEvents);
3202 for (k = 0; k < FD_MAX_EVENTS; k++)
3204 if (net_events.lNetworkEvents & (1 << k))
3206 ok (net_events.iErrorCode[k] == 0x0, "Test[%d][%d]: expected 0x0, got 0x%x\n",
3207 i, k, net_events.iErrorCode[k]);
3209 else
3211 /* Bits that are not set in lNetworkEvents MUST not be changed */
3212 ok (net_events.iErrorCode[k] == 0xABABABAB, "Test[%d][%d]: expected 0xABABABAB, got 0x%x\n",
3213 i, k, net_events.iErrorCode[k]);
3217 closesocket(s);
3218 WSACloseEvent(event);
3219 if (i == 2) closesocket(s2);
3224 static DWORD WINAPI SelectReadThread(void *param)
3226 select_thread_params *par = param;
3227 fd_set readfds;
3228 int ret;
3229 struct sockaddr_in addr;
3230 struct timeval select_timeout;
3232 FD_ZERO(&readfds);
3233 FD_SET(par->s, &readfds);
3234 select_timeout.tv_sec=5;
3235 select_timeout.tv_usec=0;
3236 addr.sin_family = AF_INET;
3237 addr.sin_addr.s_addr = inet_addr(SERVERIP);
3238 addr.sin_port = htons(SERVERPORT);
3240 do_bind(par->s, (struct sockaddr *)&addr, sizeof(addr));
3241 wsa_ok(listen(par->s, SOMAXCONN ), 0 ==, "SelectReadThread (%x): listen failed: %d\n");
3243 SetEvent(server_ready);
3244 ret = select(par->s+1, &readfds, NULL, NULL, &select_timeout);
3245 par->ReadKilled = (ret == 1);
3247 return 0;
3250 static DWORD WINAPI SelectCloseThread(void *param)
3252 SOCKET s = *(SOCKET*)param;
3253 Sleep(500);
3254 closesocket(s);
3255 return 0;
3258 static void test_errors(void)
3260 SOCKET sock;
3261 SOCKADDR_IN SockAddr;
3262 int ret, err;
3264 WSASetLastError(NO_ERROR);
3265 sock = socket(PF_INET, SOCK_STREAM, 0);
3266 ok( (sock != INVALID_SOCKET), "socket failed unexpectedly: %d\n", WSAGetLastError() );
3267 memset(&SockAddr, 0, sizeof(SockAddr));
3268 SockAddr.sin_family = AF_INET;
3269 SockAddr.sin_port = htons(6924);
3270 SockAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
3272 ret = connect(sock, (PSOCKADDR)&SockAddr, sizeof(SockAddr));
3273 ok( (ret == SOCKET_ERROR), "expected SOCKET_ERROR, got: %d\n", ret );
3274 if (ret == SOCKET_ERROR)
3276 err = WSAGetLastError();
3277 ok( (err == WSAECONNREFUSED), "expected WSAECONNREFUSED, got: %d\n", err );
3281 TIMEVAL timeval;
3282 fd_set set = {1, {sock}};
3284 timeval.tv_sec = 0;
3285 timeval.tv_usec = 50000;
3287 ret = select(1, NULL, &set, NULL, &timeval);
3288 ok( (ret == 0), "expected 0 (timeout), got: %d\n", ret );
3291 ret = closesocket(sock);
3292 ok ( (ret == 0), "closesocket failed unexpectedly: %d\n", WSAGetLastError());
3295 static void test_listen(void)
3297 SOCKET fdA, fdB;
3298 int ret, acceptc, olen = sizeof(acceptc);
3299 struct sockaddr_in address;
3301 memset(&address, 0, sizeof(address));
3302 address.sin_addr.s_addr = inet_addr("127.0.0.1");
3303 address.sin_family = AF_INET;
3304 address.sin_port = htons(SERVERPORT);
3306 /* invalid socket tests */
3307 SetLastError(0xdeadbeef);
3308 ok ((listen(0, 0) == SOCKET_ERROR), "listen did not fail\n");
3309 ret = WSAGetLastError();
3310 ok (ret == WSAENOTSOCK, "expected 10038, received %d\n", ret);
3312 SetLastError(0xdeadbeef);
3313 ok ((listen(0xdeadbeef, 0) == SOCKET_ERROR), "listen did not fail\n");
3314 ret = WSAGetLastError();
3315 ok (ret == WSAENOTSOCK, "expected 10038, received %d\n", ret);
3317 /* tcp tests */
3318 fdA = socket(AF_INET, SOCK_STREAM, 0);
3319 ok ((fdA != INVALID_SOCKET), "socket failed unexpectedly: %d\n", WSAGetLastError() );
3321 fdB = socket(AF_INET, SOCK_STREAM, 0);
3322 ok ((fdB != INVALID_SOCKET), "socket failed unexpectedly: %d\n", WSAGetLastError() );
3324 SetLastError(0xdeadbeef);
3325 ok ((listen(fdA, -2) == SOCKET_ERROR), "listen did not fail\n");
3326 ret = WSAGetLastError();
3327 ok (ret == WSAEINVAL, "expected 10022, received %d\n", ret);
3329 SetLastError(0xdeadbeef);
3330 ok ((listen(fdA, 1) == SOCKET_ERROR), "listen did not fail\n");
3331 ret = WSAGetLastError();
3332 ok (ret == WSAEINVAL, "expected 10022, received %d\n", ret);
3334 SetLastError(0xdeadbeef);
3335 ok ((listen(fdA, SOMAXCONN) == SOCKET_ERROR), "listen did not fail\n");
3336 ret = WSAGetLastError();
3337 ok (ret == WSAEINVAL, "expected 10022, received %d\n", ret);
3339 ok (!bind(fdA, (struct sockaddr*) &address, sizeof(address)), "bind failed\n");
3341 SetLastError(0xdeadbeef);
3342 ok (bind(fdB, (struct sockaddr*) &address, sizeof(address)), "bind should have failed\n");
3343 ok (ret == WSAEINVAL, "expected 10022, received %d\n", ret);
3345 acceptc = 0xdead;
3346 ret = getsockopt(fdA, SOL_SOCKET, SO_ACCEPTCONN, (char*)&acceptc, &olen);
3347 ok (!ret, "getsockopt failed\n");
3348 ok (acceptc == 0, "SO_ACCEPTCONN should be 0, received %d\n", acceptc);
3350 acceptc = 1;
3351 WSASetLastError(0xdeadbeef);
3352 ret = setsockopt(fdA, SOL_SOCKET, SO_ACCEPTCONN, (char *)&acceptc, sizeof(acceptc));
3353 ok(ret == -1, "expected failure\n");
3354 ok(WSAGetLastError() == WSAENOPROTOOPT, "got error %u\n", WSAGetLastError());
3356 acceptc = 0;
3357 WSASetLastError(0xdeadbeef);
3358 ret = setsockopt(fdA, SOL_SOCKET, SO_ACCEPTCONN, (char *)&acceptc, sizeof(acceptc));
3359 ok(ret == -1, "expected failure\n");
3360 ok(WSAGetLastError() == WSAENOPROTOOPT, "got error %u\n", WSAGetLastError());
3362 ok (!listen(fdA, 0), "listen failed\n");
3363 ok (!listen(fdA, SOMAXCONN), "double listen failed\n");
3365 acceptc = 0xdead;
3366 ret = getsockopt(fdA, SOL_SOCKET, SO_ACCEPTCONN, (char*)&acceptc, &olen);
3367 ok (!ret, "getsockopt failed\n");
3368 ok (acceptc == 1, "SO_ACCEPTCONN should be 1, received %d\n", acceptc);
3370 acceptc = 1;
3371 WSASetLastError(0xdeadbeef);
3372 ret = setsockopt(fdA, SOL_SOCKET, SO_ACCEPTCONN, (char *)&acceptc, sizeof(acceptc));
3373 ok(ret == -1, "expected failure\n");
3374 ok(WSAGetLastError() == WSAENOPROTOOPT, "got error %u\n", WSAGetLastError());
3376 acceptc = 0;
3377 WSASetLastError(0xdeadbeef);
3378 ret = setsockopt(fdA, SOL_SOCKET, SO_ACCEPTCONN, (char *)&acceptc, sizeof(acceptc));
3379 ok(ret == -1, "expected failure\n");
3380 ok(WSAGetLastError() == WSAENOPROTOOPT, "got error %u\n", WSAGetLastError());
3382 SetLastError(0xdeadbeef);
3383 ok ((listen(fdB, SOMAXCONN) == SOCKET_ERROR), "listen did not fail\n");
3384 ret = WSAGetLastError();
3385 ok (ret == WSAEINVAL, "expected 10022, received %d\n", ret);
3387 ret = closesocket(fdB);
3388 ok (ret == 0, "closesocket failed unexpectedly: %d\n", ret);
3390 fdB = socket(AF_INET, SOCK_STREAM, 0);
3391 ok ((fdB != INVALID_SOCKET), "socket failed unexpectedly: %d\n", WSAGetLastError() );
3393 SetLastError(0xdeadbeef);
3394 ok (bind(fdB, (struct sockaddr*) &address, sizeof(address)), "bind should have failed\n");
3395 ret = WSAGetLastError();
3396 ok (ret == WSAEADDRINUSE, "expected 10048, received %d\n", ret);
3398 ret = closesocket(fdA);
3399 ok (ret == 0, "closesocket failed unexpectedly: %d\n", ret);
3400 ret = closesocket(fdB);
3401 ok (ret == 0, "closesocket failed unexpectedly: %d\n", ret);
3404 #define FD_ZERO_ALL() { FD_ZERO(&readfds); FD_ZERO(&writefds); FD_ZERO(&exceptfds); }
3405 #define FD_SET_ALL(s) { FD_SET(s, &readfds); FD_SET(s, &writefds); FD_SET(s, &exceptfds); }
3406 static void test_select(void)
3408 static char tmp_buf[1024];
3410 fd_set readfds, writefds, exceptfds, *alloc_fds;
3411 SOCKET fdListen, fdRead, fdWrite, sockets[200];
3412 int ret, len;
3413 char buffer;
3414 struct timeval select_timeout;
3415 struct sockaddr_in address;
3416 select_thread_params thread_params;
3417 HANDLE thread_handle;
3418 DWORD ticks, id, old_protect;
3419 unsigned int maxfd, i;
3420 char *page_pair;
3422 fdRead = socket(AF_INET, SOCK_STREAM, 0);
3423 ok( (fdRead != INVALID_SOCKET), "socket failed unexpectedly: %d\n", WSAGetLastError() );
3424 fdWrite = socket(AF_INET, SOCK_STREAM, 0);
3425 ok( (fdWrite != INVALID_SOCKET), "socket failed unexpectedly: %d\n", WSAGetLastError() );
3427 maxfd = fdRead;
3428 if (fdWrite > maxfd)
3429 maxfd = fdWrite;
3431 FD_ZERO_ALL();
3432 FD_SET_ALL(fdRead);
3433 FD_SET_ALL(fdWrite);
3434 select_timeout.tv_sec=0;
3435 select_timeout.tv_usec=0;
3437 ticks = GetTickCount();
3438 ret = select(maxfd+1, &readfds, &writefds, &exceptfds, &select_timeout);
3439 ticks = GetTickCount() - ticks;
3440 ok(ret == 0, "select should not return any socket handles\n");
3441 ok(ticks < 100, "select was blocking for %u ms\n", ticks);
3442 ok(!FD_ISSET(fdRead, &readfds), "FD should not be set\n");
3443 ok(!FD_ISSET(fdWrite, &writefds), "FD should not be set\n");
3444 ok(!FD_ISSET(fdRead, &exceptfds), "FD should not be set\n");
3445 ok(!FD_ISSET(fdWrite, &exceptfds), "FD should not be set\n");
3447 FD_ZERO_ALL();
3448 FD_SET_ALL(fdRead);
3449 FD_SET_ALL(fdWrite);
3450 select_timeout.tv_sec=0;
3451 select_timeout.tv_usec=500;
3453 ret = select(maxfd+1, &readfds, &writefds, &exceptfds, &select_timeout);
3454 ok(ret == 0, "select should not return any socket handles\n");
3455 ok(!FD_ISSET(fdRead, &readfds), "FD should not be set\n");
3456 ok(!FD_ISSET(fdWrite, &writefds), "FD should not be set\n");
3457 ok(!FD_ISSET(fdRead, &exceptfds), "FD should not be set\n");
3458 ok(!FD_ISSET(fdWrite, &exceptfds), "FD should not be set\n");
3460 ok ((listen(fdWrite, SOMAXCONN) == SOCKET_ERROR), "listen did not fail\n");
3461 ret = closesocket(fdWrite);
3462 ok ( (ret == 0), "closesocket failed unexpectedly: %d\n", ret);
3464 thread_params.s = fdRead;
3465 thread_params.ReadKilled = FALSE;
3466 server_ready = CreateEventA(NULL, TRUE, FALSE, NULL);
3467 thread_handle = CreateThread (NULL, 0, SelectReadThread, &thread_params, 0, &id );
3468 ok ( (thread_handle != NULL), "CreateThread failed unexpectedly: %d\n", GetLastError());
3470 WaitForSingleObject (server_ready, INFINITE);
3471 Sleep(200);
3472 ret = closesocket(fdRead);
3473 ok ( (ret == 0), "closesocket failed unexpectedly: %d\n", ret);
3475 WaitForSingleObject (thread_handle, 1000);
3476 ok ( thread_params.ReadKilled, "closesocket did not wake up select\n");
3477 ret = recv(fdRead, &buffer, 1, MSG_PEEK);
3478 ok( (ret == -1), "peek at closed socket expected -1 got %d\n", ret);
3480 /* Test selecting invalid handles */
3481 FD_ZERO_ALL();
3483 SetLastError(0);
3484 ret = select(maxfd+1, 0, 0, 0, &select_timeout);
3485 ok ( (ret == SOCKET_ERROR), "expected SOCKET_ERROR, got %i\n", ret);
3486 ok ( WSAGetLastError() == WSAEINVAL, "expected WSAEINVAL, got %i\n", WSAGetLastError());
3488 SetLastError(0);
3489 ret = select(maxfd+1, &readfds, &writefds, &exceptfds, &select_timeout);
3490 ok ( (ret == SOCKET_ERROR), "expected SOCKET_ERROR, got %i\n", ret);
3491 ok ( WSAGetLastError() == WSAEINVAL, "expected WSAEINVAL, got %i\n", WSAGetLastError());
3493 FD_SET(INVALID_SOCKET, &readfds);
3494 SetLastError(0);
3495 ret = select(maxfd+1, &readfds, &writefds, &exceptfds, &select_timeout);
3496 ok ( (ret == SOCKET_ERROR), "expected SOCKET_ERROR, got %i\n", ret);
3497 ok ( WSAGetLastError() == WSAENOTSOCK, "expected WSAENOTSOCK, got %i\n", WSAGetLastError());
3498 ok ( !FD_ISSET(fdRead, &readfds), "FD should not be set\n");
3500 FD_ZERO(&readfds);
3501 FD_SET(INVALID_SOCKET, &writefds);
3502 SetLastError(0);
3503 ret = select(maxfd+1, &readfds, &writefds, &exceptfds, &select_timeout);
3504 ok ( (ret == SOCKET_ERROR), "expected SOCKET_ERROR, got %i\n", ret);
3505 ok ( WSAGetLastError() == WSAENOTSOCK, "expected WSAENOTSOCK, got %i\n", WSAGetLastError());
3506 ok ( !FD_ISSET(fdRead, &writefds), "FD should not be set\n");
3508 FD_ZERO(&writefds);
3509 FD_SET(INVALID_SOCKET, &exceptfds);
3510 SetLastError(0);
3511 ret = select(maxfd+1, &readfds, &writefds, &exceptfds, &select_timeout);
3512 ok ( (ret == SOCKET_ERROR), "expected SOCKET_ERROR, got %i\n", ret);
3513 ok ( WSAGetLastError() == WSAENOTSOCK, "expected WSAENOTSOCK, got %i\n", WSAGetLastError());
3514 ok ( !FD_ISSET(fdRead, &exceptfds), "FD should not be set\n");
3516 tcp_socketpair(&fdRead, &fdWrite);
3517 maxfd = fdRead;
3518 if(fdWrite > maxfd) maxfd = fdWrite;
3520 FD_ZERO(&readfds);
3521 FD_SET(fdRead, &readfds);
3522 ret = select(fdRead+1, &readfds, NULL, NULL, &select_timeout);
3523 ok(!ret, "select returned %d\n", ret);
3525 FD_ZERO(&writefds);
3526 FD_SET(fdWrite, &writefds);
3527 ret = select(fdWrite+1, NULL, &writefds, NULL, &select_timeout);
3528 ok(ret == 1, "select returned %d\n", ret);
3529 ok(FD_ISSET(fdWrite, &writefds), "fdWrite socket is not in the set\n");
3531 /* select the same socket twice */
3532 writefds.fd_count = 2;
3533 writefds.fd_array[0] = fdWrite;
3534 writefds.fd_array[1] = fdWrite;
3535 ret = select(0, NULL, &writefds, NULL, &select_timeout);
3536 ok(ret == 1, "select returned %d\n", ret);
3537 ok(writefds.fd_count == 1, "got count %u\n", writefds.fd_count);
3538 ok(writefds.fd_array[0] == fdWrite, "got fd %#Ix\n", writefds.fd_array[0]);
3539 ok(writefds.fd_array[1] == fdWrite, "got fd %#Ix\n", writefds.fd_array[1]);
3541 /* tests for overlapping fd_set pointers */
3542 FD_ZERO(&readfds);
3543 FD_SET(fdWrite, &readfds);
3544 ret = select(fdWrite+1, &readfds, &readfds, NULL, &select_timeout);
3545 ok(ret == 1, "select returned %d\n", ret);
3546 ok(FD_ISSET(fdWrite, &readfds), "fdWrite socket is not in the set\n");
3548 FD_ZERO(&readfds);
3549 FD_SET(fdWrite, &readfds);
3550 FD_SET(fdRead, &readfds);
3551 ret = select(maxfd+1, &readfds, &readfds, NULL, &select_timeout);
3552 ok(ret == 2, "select returned %d\n", ret);
3553 ok(FD_ISSET(fdWrite, &readfds), "fdWrite socket is not in the set\n");
3554 ok(FD_ISSET(fdRead, &readfds), "fdRead socket is not in the set\n");
3556 ok(send(fdWrite, "test", 4, 0) == 4, "failed to send data\n");
3557 FD_ZERO(&readfds);
3558 FD_SET(fdRead, &readfds);
3559 ret = select(fdRead+1, &readfds, NULL, NULL, &select_timeout);
3560 ok(ret == 1, "select returned %d\n", ret);
3561 ok(FD_ISSET(fdRead, &readfds), "fdRead socket is not in the set\n");
3563 FD_ZERO(&readfds);
3564 FD_SET(fdWrite, &readfds);
3565 FD_SET(fdRead, &readfds);
3566 ret = select(maxfd+1, &readfds, &readfds, NULL, &select_timeout);
3567 ok(ret == 2, "select returned %d\n", ret);
3568 ok(FD_ISSET(fdWrite, &readfds), "fdWrite socket is not in the set\n");
3569 ok(FD_ISSET(fdRead, &readfds), "fdRead socket is not in the set\n");
3571 while(1) {
3572 FD_ZERO(&writefds);
3573 FD_SET(fdWrite, &writefds);
3574 ret = select(fdWrite+1, NULL, &writefds, NULL, &select_timeout);
3575 if(!ret) break;
3576 ok(send(fdWrite, tmp_buf, sizeof(tmp_buf), 0) > 0, "failed to send data\n");
3578 FD_ZERO(&readfds);
3579 FD_SET(fdWrite, &readfds);
3580 FD_SET(fdRead, &readfds);
3581 ret = select(maxfd+1, &readfds, &readfds, NULL, &select_timeout);
3582 ok(ret == 1, "select returned %d\n", ret);
3583 ok(!FD_ISSET(fdWrite, &readfds), "fdWrite socket is in the set\n");
3584 ok(FD_ISSET(fdRead, &readfds), "fdRead socket is not in the set\n");
3586 ok(send(fdRead, "test", 4, 0) == 4, "failed to send data\n");
3587 Sleep(100);
3588 FD_ZERO(&readfds);
3589 FD_SET(fdWrite, &readfds);
3590 FD_SET(fdRead, &readfds);
3591 ret = select(maxfd+1, &readfds, &readfds, NULL, &select_timeout);
3592 ok(ret == 2, "select returned %d\n", ret);
3593 ok(FD_ISSET(fdWrite, &readfds), "fdWrite socket is not in the set\n");
3594 ok(FD_ISSET(fdRead, &readfds), "fdRead socket is not in the set\n");
3596 page_pair = VirtualAlloc(NULL, 0x1000 * 2, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
3597 VirtualProtect(page_pair + 0x1000, 0x1000, PAGE_NOACCESS, &old_protect);
3598 alloc_fds = (fd_set *)((page_pair + 0x1000) - offsetof(fd_set, fd_array[1]));
3599 alloc_fds->fd_count = 1;
3600 alloc_fds->fd_array[0] = fdRead;
3601 ret = select(fdRead+1, alloc_fds, NULL, NULL, &select_timeout);
3602 ok(ret == 1, "select returned %d\n", ret);
3603 VirtualFree(page_pair, 0, MEM_RELEASE);
3605 closesocket(fdRead);
3606 closesocket(fdWrite);
3608 alloc_fds = malloc(offsetof(fd_set, fd_array[ARRAY_SIZE(sockets)]));
3609 alloc_fds->fd_count = ARRAY_SIZE(sockets);
3610 for (i = 0; i < ARRAY_SIZE(sockets); i += 2)
3612 tcp_socketpair(&sockets[i], &sockets[i + 1]);
3613 alloc_fds->fd_array[i] = sockets[i];
3614 alloc_fds->fd_array[i + 1] = sockets[i + 1];
3616 ret = select(0, NULL, alloc_fds, NULL, &select_timeout);
3617 ok(ret == ARRAY_SIZE(sockets), "got %d\n", ret);
3618 for (i = 0; i < ARRAY_SIZE(sockets); ++i)
3620 ok(alloc_fds->fd_array[i] == sockets[i], "got socket %#Ix at index %u\n", alloc_fds->fd_array[i], i);
3621 closesocket(sockets[i]);
3623 free(alloc_fds);
3625 /* select() works in 3 distinct states:
3626 * - to check if a connection attempt ended with success or error;
3627 * - to check if a pending connection is waiting for acceptance;
3628 * - to check for data to read, availability for write and OOB data
3630 * The tests below ensure that all conditions are tested.
3632 memset(&address, 0, sizeof(address));
3633 address.sin_addr.s_addr = inet_addr("127.0.0.1");
3634 address.sin_family = AF_INET;
3635 len = sizeof(address);
3636 fdListen = setup_server_socket(&address, &len);
3637 select_timeout.tv_sec = 1;
3638 select_timeout.tv_usec = 250000;
3640 /* When no events are pending select returns 0 with no error */
3641 FD_ZERO_ALL();
3642 FD_SET_ALL(fdListen);
3643 ret = select(0, &readfds, &writefds, &exceptfds, &select_timeout);
3644 ok(ret == 0, "expected 0, got %d\n", ret);
3646 /* When a socket is attempting to connect the listening socket receives the read descriptor */
3647 fdWrite = setup_connector_socket(&address, len, TRUE);
3648 FD_ZERO_ALL();
3649 FD_SET_ALL(fdListen);
3650 ret = select(0, &readfds, &writefds, &exceptfds, &select_timeout);
3651 ok(ret == 1, "expected 1, got %d\n", ret);
3652 ok(FD_ISSET(fdListen, &readfds), "fdListen socket is not in the set\n");
3653 len = sizeof(address);
3654 fdRead = accept(fdListen, (struct sockaddr*) &address, &len);
3655 ok(fdRead != INVALID_SOCKET, "expected a valid socket\n");
3657 /* The connector is signaled through the write descriptor */
3658 FD_ZERO_ALL();
3659 FD_SET_ALL(fdListen);
3660 FD_SET_ALL(fdRead);
3661 FD_SET_ALL(fdWrite);
3662 ret = select(0, &readfds, &writefds, &exceptfds, &select_timeout);
3663 ok(ret == 2, "expected 2, got %d\n", ret);
3664 ok(FD_ISSET(fdWrite, &writefds), "fdWrite socket is not in the set\n");
3665 ok(FD_ISSET(fdRead, &writefds), "fdRead socket is not in the set\n");
3666 len = sizeof(id);
3667 id = 0xdeadbeef;
3668 ret = getsockopt(fdWrite, SOL_SOCKET, SO_ERROR, (char*)&id, &len);
3669 ok(!ret, "getsockopt failed with %d\n", WSAGetLastError());
3670 ok(id == 0, "expected 0, got %d\n", id);
3672 /* When data is received the receiver gets the read descriptor */
3673 ret = send(fdWrite, "1234", 4, 0);
3674 ok(ret == 4, "expected 4, got %d\n", ret);
3675 FD_ZERO_ALL();
3676 FD_SET_ALL(fdListen);
3677 FD_SET(fdRead, &readfds);
3678 FD_SET(fdRead, &exceptfds);
3679 ret = select(0, &readfds, &writefds, &exceptfds, &select_timeout);
3680 ok(ret == 1, "expected 1, got %d\n", ret);
3681 ok(FD_ISSET(fdRead, &readfds), "fdRead socket is not in the set\n");
3682 ok(!FD_ISSET(fdRead, &exceptfds), "fdRead socket is in the set\n");
3683 FD_ZERO_ALL();
3684 FD_SET_ALL(fdRead);
3685 ret = select(0, &readfds, &writefds, &exceptfds, &select_timeout);
3686 ok(ret == 2, "expected 1, got %d\n", ret);
3687 ok(FD_ISSET(fdRead, &readfds), "fdRead socket is not in the set\n");
3688 ok(FD_ISSET(fdRead, &writefds), "fdRead socket is not in the set\n");
3689 ok(!FD_ISSET(fdRead, &exceptfds), "fdRead socket is in the set\n");
3690 ret = recv(fdRead, tmp_buf, sizeof(tmp_buf), 0);
3691 ok(ret == 4, "expected 4, got %d\n", ret);
3692 ok(!strcmp(tmp_buf, "1234"), "data received differs from sent\n");
3694 /* When OOB data is received the socket is set in the except descriptor */
3695 ret = send(fdWrite, "A", 1, MSG_OOB);
3696 ok(ret == 1, "expected 1, got %d\n", ret);
3697 FD_ZERO_ALL();
3698 FD_SET_ALL(fdListen);
3699 FD_SET(fdRead, &readfds);
3700 FD_SET(fdRead, &exceptfds);
3701 ret = select(0, &readfds, &writefds, &exceptfds, &select_timeout);
3702 ok(ret == 1, "expected 1, got %d\n", ret);
3703 ok(FD_ISSET(fdRead, &exceptfds), "fdRead socket is not in the set\n");
3704 tmp_buf[0] = 0xAF;
3705 ret = recv(fdRead, tmp_buf, sizeof(tmp_buf), MSG_OOB);
3706 ok(ret == 1, "expected 1, got %d\n", ret);
3707 ok(tmp_buf[0] == 'A', "expected 'A', got 0x%02X\n", tmp_buf[0]);
3709 /* If the socket is OOBINLINED it will not receive the OOB in except fds */
3710 ret = 1;
3711 ret = setsockopt(fdRead, SOL_SOCKET, SO_OOBINLINE, (char*) &ret, sizeof(ret));
3712 ok(ret == 0, "expected 0, got %d\n", ret);
3713 ret = send(fdWrite, "A", 1, MSG_OOB);
3714 ok(ret == 1, "expected 1, got %d\n", ret);
3715 FD_ZERO_ALL();
3716 FD_SET_ALL(fdListen);
3717 FD_SET(fdRead, &readfds);
3718 FD_SET(fdRead, &exceptfds);
3719 ret = select(0, &readfds, &writefds, &exceptfds, &select_timeout);
3720 ok(ret == 1, "expected 1, got %d\n", ret);
3721 ok(FD_ISSET(fdRead, &readfds), "fdRead socket is not in the set\n");
3722 tmp_buf[0] = 0xAF;
3723 SetLastError(0xdeadbeef);
3724 ret = recv(fdRead, tmp_buf, sizeof(tmp_buf), MSG_OOB);
3725 ok(ret == SOCKET_ERROR, "expected SOCKET_ERROR, got %d\n", ret);
3726 ok(GetLastError() == WSAEINVAL, "expected 10022, got %d\n", GetLastError());
3727 ret = recv(fdRead, tmp_buf, sizeof(tmp_buf), 0);
3728 ok(ret == 1, "expected 1, got %d\n", ret);
3729 ok(tmp_buf[0] == 'A', "expected 'A', got 0x%02X\n", tmp_buf[0]);
3731 /* When the connection is closed the socket is set in the read descriptor */
3732 ret = closesocket(fdRead);
3733 ok(ret == 0, "expected 0, got %d\n", ret);
3734 FD_ZERO_ALL();
3735 FD_SET_ALL(fdListen);
3736 FD_SET(fdWrite, &readfds);
3737 ret = select(0, &readfds, &writefds, &exceptfds, &select_timeout);
3738 ok(ret == 1, "expected 1, got %d\n", ret);
3739 ok(FD_ISSET(fdWrite, &readfds), "fdWrite socket is not in the set\n");
3740 ret = recv(fdWrite, tmp_buf, sizeof(tmp_buf), 0);
3741 ok(ret == 0, "expected 0, got %d\n", ret);
3742 ret = closesocket(fdWrite);
3743 ok(ret == 0, "expected 0, got %d\n", ret);
3745 /* w10pro64 sometimes takes over 2 seconds for an error to be reported. */
3746 if (winetest_interactive)
3748 const struct sockaddr_in invalid_addr =
3750 .sin_family = AF_INET,
3751 .sin_addr.s_addr = htonl(INADDR_LOOPBACK),
3752 .sin_port = 255,
3755 fdWrite = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
3756 set_blocking(fdWrite, FALSE);
3758 ret = connect(fdWrite, (struct sockaddr *)&invalid_addr, sizeof(invalid_addr));
3759 ok(ret == -1, "got %d\n", ret);
3760 ok(WSAGetLastError() == WSAEWOULDBLOCK, "got error %u\n", WSAGetLastError());
3762 FD_ZERO_ALL();
3763 FD_SET(fdWrite, &readfds);
3764 FD_SET(fdWrite, &writefds);
3765 FD_SET(fdWrite, &exceptfds);
3766 select_timeout.tv_sec = 10;
3767 ret = select(0, &readfds, &writefds, &exceptfds, &select_timeout);
3768 ok(ret == 1, "expected 1, got %d\n", ret);
3769 ok(FD_ISSET(fdWrite, &exceptfds), "fdWrite socket is not in the set\n");
3770 ok(select_timeout.tv_usec == 250000, "select timeout should not have changed\n");
3772 len = sizeof(id);
3773 id = 0xdeadbeef;
3774 ret = getsockopt(fdWrite, SOL_SOCKET, SO_ERROR, (char *)&id, &len);
3775 ok(!ret, "getsockopt failed with %d\n", WSAGetLastError());
3776 ok(id == WSAECONNREFUSED, "got error %u\n", id);
3778 len = sizeof(id);
3779 id = 0xdeadbeef;
3780 ret = getsockopt(fdWrite, SOL_SOCKET, SO_ERROR, (char *)&id, &len);
3781 ok(!ret, "getsockopt failed with %d\n", WSAGetLastError());
3782 ok(id == WSAECONNREFUSED, "got error %u\n", id);
3784 FD_ZERO_ALL();
3785 FD_SET(fdWrite, &readfds);
3786 FD_SET(fdWrite, &writefds);
3787 FD_SET(fdWrite, &exceptfds);
3788 select_timeout.tv_sec = 10;
3789 ret = select(0, &readfds, &writefds, &exceptfds, &select_timeout);
3790 ok(ret == 1, "got %d\n", ret);
3791 ok(FD_ISSET(fdWrite, &exceptfds), "fdWrite socket is not in the set\n");
3793 /* Calling connect() doesn't reset the socket error, but a successful
3794 * connection does. This is kind of tricky to test, because while
3795 * Windows takes a couple seconds to actually fail the connection,
3796 * Linux will fail the connection almost immediately. */
3798 ret = connect(fdWrite, (const struct sockaddr *)&invalid_addr, sizeof(invalid_addr));
3799 ok(ret == -1, "got %d\n", ret);
3800 todo_wine ok(WSAGetLastError() == WSAEWOULDBLOCK, "got error %u\n", WSAGetLastError());
3801 if (WSAGetLastError() == WSAECONNABORTED)
3803 ret = connect(fdWrite, (const struct sockaddr *)&invalid_addr, sizeof(invalid_addr));
3804 ok(ret == -1, "got %d\n", ret);
3805 ok(WSAGetLastError() == WSAEWOULDBLOCK, "got error %u\n", WSAGetLastError());
3808 len = sizeof(id);
3809 id = 0xdeadbeef;
3810 ret = getsockopt(fdWrite, SOL_SOCKET, SO_ERROR, (char *)&id, &len);
3811 ok(!ret, "getsockopt failed with %d\n", WSAGetLastError());
3812 ok(id == WSAECONNREFUSED, "got error %u\n", id);
3814 FD_ZERO_ALL();
3815 FD_SET(fdWrite, &readfds);
3816 FD_SET(fdWrite, &writefds);
3817 FD_SET(fdWrite, &exceptfds);
3818 select_timeout.tv_sec = 10;
3819 ret = select(0, &readfds, &writefds, &exceptfds, &select_timeout);
3820 ok(ret == 1, "got %d\n", ret);
3821 ok(FD_ISSET(fdWrite, &exceptfds), "fdWrite socket is not in the set\n");
3823 len = sizeof(address);
3824 ret = getsockname(fdListen, (struct sockaddr *)&address, &len);
3825 ok(!ret, "got error %u\n", WSAGetLastError());
3826 ret = connect(fdWrite, (const struct sockaddr *)&address, sizeof(address));
3827 ok(ret == -1, "got %d\n", ret);
3828 todo_wine ok(WSAGetLastError() == WSAEWOULDBLOCK, "got error %u\n", WSAGetLastError());
3829 if (WSAGetLastError() == WSAECONNABORTED)
3831 ret = connect(fdWrite, (const struct sockaddr *)&address, sizeof(address));
3832 ok(ret == -1, "got %d\n", ret);
3833 ok(WSAGetLastError() == WSAEWOULDBLOCK, "got error %u\n", WSAGetLastError());
3836 FD_ZERO_ALL();
3837 FD_SET(fdWrite, &readfds);
3838 FD_SET(fdWrite, &writefds);
3839 FD_SET(fdWrite, &exceptfds);
3840 select_timeout.tv_sec = 1;
3841 ret = select(0, &readfds, &writefds, &exceptfds, &select_timeout);
3842 ok(ret == 1, "expected 1, got %d\n", ret);
3843 ok(FD_ISSET(fdWrite, &writefds), "fdWrite socket is not in the set\n");
3845 len = sizeof(id);
3846 id = 0xdeadbeef;
3847 ret = getsockopt(fdWrite, SOL_SOCKET, SO_ERROR, (char *)&id, &len);
3848 ok(!ret, "getsockopt failed with %d\n", WSAGetLastError());
3849 ok(!id, "got error %u\n", id);
3851 closesocket(fdWrite);
3853 /* test polling after a (synchronous) failure */
3855 fdWrite = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
3857 ret = connect(fdWrite, (const struct sockaddr *)&invalid_addr, sizeof(invalid_addr));
3858 ok(ret == -1, "got %d\n", ret);
3859 ok(WSAGetLastError() == WSAECONNREFUSED, "got error %u\n", WSAGetLastError());
3861 FD_ZERO_ALL();
3862 FD_SET(fdWrite, &readfds);
3863 FD_SET(fdWrite, &writefds);
3864 FD_SET(fdWrite, &exceptfds);
3865 select_timeout.tv_sec = 0;
3866 ret = select(0, &readfds, &writefds, &exceptfds, &select_timeout);
3867 ok(ret == 1, "expected 1, got %d\n", ret);
3868 ok(FD_ISSET(fdWrite, &exceptfds), "fdWrite socket is not in the set\n");
3870 len = sizeof(id);
3871 id = 0xdeadbeef;
3872 ret = getsockopt(fdWrite, SOL_SOCKET, SO_ERROR, (char *)&id, &len);
3873 ok(!ret, "getsockopt failed with %d\n", WSAGetLastError());
3874 todo_wine ok(!id, "got error %u\n", id);
3876 closesocket(fdWrite);
3879 ret = closesocket(fdListen);
3880 ok(ret == 0, "expected 0, got %d\n", ret);
3882 select_timeout.tv_sec = 1;
3883 select_timeout.tv_usec = 250000;
3885 /* Try select() on a closed socket after connection */
3886 tcp_socketpair(&fdRead, &fdWrite);
3887 closesocket(fdRead);
3888 FD_ZERO_ALL();
3889 FD_SET_ALL(fdWrite);
3890 FD_SET_ALL(fdRead);
3891 SetLastError(0xdeadbeef);
3892 ret = select(0, &readfds, NULL, &exceptfds, &select_timeout);
3893 ok(ret == SOCKET_ERROR, "expected -1, got %d\n", ret);
3894 ok(GetLastError() == WSAENOTSOCK, "got %d\n", GetLastError());
3895 /* descriptor sets are unchanged */
3896 ok(readfds.fd_count == 2, "expected 2, got %d\n", readfds.fd_count);
3897 ok(exceptfds.fd_count == 2, "expected 2, got %d\n", exceptfds.fd_count);
3898 closesocket(fdWrite);
3900 /* Close the socket currently being selected in a thread - bug 38399 */
3901 tcp_socketpair(&fdRead, &fdWrite);
3902 thread_handle = CreateThread(NULL, 0, SelectCloseThread, &fdWrite, 0, &id);
3903 ok(thread_handle != NULL, "CreateThread failed unexpectedly: %d\n", GetLastError());
3904 FD_ZERO_ALL();
3905 FD_SET_ALL(fdWrite);
3906 ret = select(0, &readfds, NULL, &exceptfds, &select_timeout);
3907 ok(ret == 1, "expected 1, got %d\n", ret);
3908 ok(FD_ISSET(fdWrite, &readfds), "fdWrite socket is not in the set\n");
3909 WaitForSingleObject (thread_handle, 1000);
3910 closesocket(fdRead);
3911 /* test again with only the except descriptor */
3912 tcp_socketpair(&fdRead, &fdWrite);
3913 thread_handle = CreateThread(NULL, 0, SelectCloseThread, &fdWrite, 0, &id);
3914 ok(thread_handle != NULL, "CreateThread failed unexpectedly: %d\n", GetLastError());
3915 FD_ZERO_ALL();
3916 FD_SET(fdWrite, &exceptfds);
3917 SetLastError(0xdeadbeef);
3918 ret = select(0, NULL, NULL, &exceptfds, &select_timeout);
3919 ok(ret == SOCKET_ERROR, "expected -1, got %d\n", ret);
3920 ok(GetLastError() == WSAENOTSOCK, "got %d\n", GetLastError());
3921 ok(!FD_ISSET(fdWrite, &exceptfds), "fdWrite socket is in the set\n");
3922 WaitForSingleObject (thread_handle, 1000);
3923 closesocket(fdRead);
3925 /* test UDP behavior of unbound sockets */
3926 select_timeout.tv_sec = 0;
3927 select_timeout.tv_usec = 250000;
3928 fdWrite = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
3929 ok(fdWrite != INVALID_SOCKET, "socket call failed\n");
3930 FD_ZERO_ALL();
3931 FD_SET_ALL(fdWrite);
3932 ret = select(0, &readfds, &writefds, &exceptfds, &select_timeout);
3933 ok(ret == 1, "expected 1, got %d\n", ret);
3934 ok(FD_ISSET(fdWrite, &writefds), "fdWrite socket is not in the set\n");
3935 closesocket(fdWrite);
3937 #undef FD_SET_ALL
3938 #undef FD_ZERO_ALL
3940 static DWORD WINAPI AcceptKillThread(void *param)
3942 select_thread_params *par = param;
3943 struct sockaddr_in address;
3944 int len = sizeof(address);
3945 SOCKET client_socket;
3947 SetEvent(server_ready);
3948 client_socket = accept(par->s, (struct sockaddr*) &address, &len);
3949 if (client_socket != INVALID_SOCKET)
3950 closesocket(client_socket);
3951 par->ReadKilled = (client_socket == INVALID_SOCKET);
3952 return 0;
3956 static int CALLBACK AlwaysDeferConditionFunc(LPWSABUF lpCallerId, LPWSABUF lpCallerData, LPQOS pQos,
3957 LPQOS lpGQOS, LPWSABUF lpCalleeId, LPWSABUF lpCalleeData,
3958 GROUP *g, DWORD_PTR dwCallbackData)
3960 return CF_DEFER;
3963 static SOCKET setup_server_socket(struct sockaddr_in *addr, int *len)
3965 int ret, val;
3966 SOCKET server_socket;
3968 server_socket = socket(AF_INET, SOCK_STREAM, 0);
3969 ok(server_socket != INVALID_SOCKET, "failed to bind socket, error %u\n", WSAGetLastError());
3971 val = 1;
3972 ret = setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val));
3973 ok(!ret, "failed to set SO_REUSEADDR, error %u\n", WSAGetLastError());
3975 ret = bind(server_socket, (struct sockaddr *)addr, *len);
3976 ok(!ret, "failed to bind socket, error %u\n", WSAGetLastError());
3978 ret = getsockname(server_socket, (struct sockaddr *)addr, len);
3979 ok(!ret, "failed to get address, error %u\n", WSAGetLastError());
3981 ret = listen(server_socket, 5);
3982 ok(!ret, "failed to listen, error %u\n", WSAGetLastError());
3984 return server_socket;
3987 static SOCKET setup_connector_socket(const struct sockaddr_in *addr, int len, BOOL nonblock)
3989 int ret;
3990 SOCKET connector;
3992 connector = socket(AF_INET, SOCK_STREAM, 0);
3993 ok(connector != INVALID_SOCKET, "failed to create connector socket %d\n", WSAGetLastError());
3995 if (nonblock)
3996 set_blocking(connector, !nonblock);
3998 ret = connect(connector, (const struct sockaddr *)addr, len);
3999 if (!nonblock)
4000 ok(!ret, "connecting to accepting socket failed %d\n", WSAGetLastError());
4001 else if (ret == SOCKET_ERROR)
4002 ok(WSAGetLastError() == WSAEWOULDBLOCK, "got error %u\n", WSAGetLastError());
4004 return connector;
4007 static void test_accept(void)
4009 int ret;
4010 SOCKET server_socket, accepted = INVALID_SOCKET, connector;
4011 struct sockaddr_in address;
4012 SOCKADDR_STORAGE ss, ss_empty;
4013 int socklen;
4014 select_thread_params thread_params;
4015 HANDLE thread_handle = NULL;
4016 DWORD id;
4018 memset(&address, 0, sizeof(address));
4019 address.sin_addr.s_addr = inet_addr("127.0.0.1");
4020 address.sin_family = AF_INET;
4022 socklen = sizeof(address);
4023 server_socket = setup_server_socket(&address, &socklen);
4025 connector = setup_connector_socket(&address, socklen, FALSE);
4026 if (connector == INVALID_SOCKET) goto done;
4028 accepted = WSAAccept(server_socket, NULL, NULL, AlwaysDeferConditionFunc, 0);
4029 ok(accepted == INVALID_SOCKET && WSAGetLastError() == WSATRY_AGAIN, "Failed to defer connection, %d\n", WSAGetLastError());
4031 accepted = accept(server_socket, NULL, 0);
4032 ok(accepted != INVALID_SOCKET, "Failed to accept deferred connection, error %d\n", WSAGetLastError());
4034 server_ready = CreateEventA(NULL, TRUE, FALSE, NULL);
4036 thread_params.s = server_socket;
4037 thread_params.ReadKilled = FALSE;
4038 thread_handle = CreateThread(NULL, 0, AcceptKillThread, &thread_params, 0, &id);
4040 WaitForSingleObject(server_ready, INFINITE);
4041 Sleep(200);
4042 ret = closesocket(server_socket);
4043 ok(!ret, "failed to close socket, error %u\n", WSAGetLastError());
4045 WaitForSingleObject(thread_handle, 1000);
4046 ok(thread_params.ReadKilled, "closesocket did not wake up accept\n");
4048 closesocket(accepted);
4049 closesocket(connector);
4050 accepted = connector = INVALID_SOCKET;
4052 socklen = sizeof(address);
4053 server_socket = setup_server_socket(&address, &socklen);
4055 connector = setup_connector_socket(&address, socklen, FALSE);
4056 if (connector == INVALID_SOCKET) goto done;
4058 socklen = 0;
4059 accepted = WSAAccept(server_socket, (struct sockaddr *)&ss, &socklen, NULL, 0);
4060 ok(accepted == INVALID_SOCKET && WSAGetLastError() == WSAEFAULT, "got %d\n", WSAGetLastError());
4061 ok(!socklen, "got %d\n", socklen);
4062 closesocket(connector);
4063 connector = INVALID_SOCKET;
4065 socklen = sizeof(address);
4066 connector = setup_connector_socket(&address, socklen, FALSE);
4067 if (connector == INVALID_SOCKET) goto done;
4069 accepted = WSAAccept(server_socket, NULL, NULL, NULL, 0);
4070 ok(accepted != INVALID_SOCKET, "Failed to accept connection, %d\n", WSAGetLastError());
4071 closesocket(accepted);
4072 closesocket(connector);
4073 accepted = connector = INVALID_SOCKET;
4075 socklen = sizeof(address);
4076 connector = setup_connector_socket(&address, socklen, FALSE);
4077 if (connector == INVALID_SOCKET) goto done;
4079 socklen = sizeof(ss);
4080 memset(&ss, 0, sizeof(ss));
4081 accepted = WSAAccept(server_socket, (struct sockaddr *)&ss, &socklen, NULL, 0);
4082 ok(accepted != INVALID_SOCKET, "Failed to accept connection, %d\n", WSAGetLastError());
4083 ok(socklen != sizeof(ss), "unexpected length\n");
4084 ok(ss.ss_family, "family not set\n");
4085 closesocket(accepted);
4086 closesocket(connector);
4087 accepted = connector = INVALID_SOCKET;
4089 socklen = sizeof(address);
4090 connector = setup_connector_socket(&address, socklen, FALSE);
4091 if (connector == INVALID_SOCKET) goto done;
4093 socklen = 0;
4094 accepted = accept(server_socket, (struct sockaddr *)&ss, &socklen);
4095 ok(accepted == INVALID_SOCKET && WSAGetLastError() == WSAEFAULT, "got %d\n", WSAGetLastError());
4096 ok(!socklen, "got %d\n", socklen);
4097 closesocket(connector);
4098 accepted = connector = INVALID_SOCKET;
4100 socklen = sizeof(address);
4101 connector = setup_connector_socket(&address, socklen, FALSE);
4102 if (connector == INVALID_SOCKET) goto done;
4104 accepted = accept(server_socket, NULL, NULL);
4105 ok(accepted != INVALID_SOCKET, "Failed to accept connection, %d\n", WSAGetLastError());
4106 closesocket(accepted);
4107 closesocket(connector);
4108 accepted = connector = INVALID_SOCKET;
4110 socklen = sizeof(address);
4111 connector = setup_connector_socket(&address, socklen, FALSE);
4112 if (connector == INVALID_SOCKET) goto done;
4114 socklen = sizeof(ss);
4115 memset(&ss, 0, sizeof(ss));
4116 accepted = accept(server_socket, (struct sockaddr *)&ss, &socklen);
4117 ok(accepted != INVALID_SOCKET, "Failed to accept connection, %d\n", WSAGetLastError());
4118 ok(socklen != sizeof(ss), "unexpected length\n");
4119 ok(ss.ss_family, "family not set\n");
4120 closesocket(accepted);
4121 closesocket(connector);
4122 accepted = connector = INVALID_SOCKET;
4124 socklen = sizeof(address);
4125 connector = setup_connector_socket(&address, socklen, FALSE);
4126 if (connector == INVALID_SOCKET) goto done;
4128 memset(&ss, 0, sizeof(ss));
4129 memset(&ss_empty, 0, sizeof(ss_empty));
4130 accepted = accept(server_socket, (struct sockaddr *)&ss, NULL);
4131 ok(accepted != INVALID_SOCKET, "Failed to accept connection, %d\n", WSAGetLastError());
4132 ok(!memcmp(&ss, &ss_empty, sizeof(ss)), "structure is different\n");
4134 done:
4135 if (accepted != INVALID_SOCKET)
4136 closesocket(accepted);
4137 if (connector != INVALID_SOCKET)
4138 closesocket(connector);
4139 if (thread_handle != NULL)
4140 CloseHandle(thread_handle);
4141 if (server_ready != INVALID_HANDLE_VALUE)
4142 CloseHandle(server_ready);
4143 if (server_socket != INVALID_SOCKET)
4144 closesocket(server_socket);
4147 static void test_extendedSocketOptions(void)
4149 WSADATA wsa;
4150 SOCKET sock;
4151 struct sockaddr_in sa;
4152 int sa_len = sizeof(struct sockaddr_in);
4153 int optval, optlen = sizeof(int), ret;
4154 BOOL bool_opt_val;
4155 LINGER linger_val;
4157 ret = WSAStartup(MAKEWORD(2,0), &wsa);
4158 ok(!ret, "failed to startup, error %u\n", WSAGetLastError());
4160 memset(&sa, 0, sa_len);
4162 sa.sin_family = AF_INET;
4163 sa.sin_port = htons(0);
4164 sa.sin_addr.s_addr = htonl(INADDR_ANY);
4166 sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
4167 ok(sock != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
4169 ret = bind(sock, (struct sockaddr *) &sa, sa_len);
4170 ok(!ret, "failed to bind socket, error %u\n", WSAGetLastError());
4172 ret = getsockopt(sock, SOL_SOCKET, SO_MAX_MSG_SIZE, (char *)&optval, &optlen);
4174 ok(ret == 0, "getsockopt failed to query SO_MAX_MSG_SIZE, return value is 0x%08x\n", ret);
4175 ok((optval == 65507) || (optval == 65527),
4176 "SO_MAX_MSG_SIZE reported %d, expected 65507 or 65527\n", optval);
4178 /* IE 3 use 0xffffffff instead of SOL_SOCKET (0xffff) */
4179 SetLastError(0xdeadbeef);
4180 optval = 0xdeadbeef;
4181 optlen = sizeof(int);
4182 ret = getsockopt(sock, 0xffffffff, SO_MAX_MSG_SIZE, (char *)&optval, &optlen);
4183 ok( (ret == SOCKET_ERROR) && (WSAGetLastError() == WSAEINVAL),
4184 "got %d with %d and optval: 0x%x/%d (expected SOCKET_ERROR with WSAEINVAL)\n",
4185 ret, WSAGetLastError(), optval, optval);
4187 /* more invalid values for level */
4188 SetLastError(0xdeadbeef);
4189 optval = 0xdeadbeef;
4190 optlen = sizeof(int);
4191 ret = getsockopt(sock, 0x1234ffff, SO_MAX_MSG_SIZE, (char *)&optval, &optlen);
4192 ok( (ret == SOCKET_ERROR) && (WSAGetLastError() == WSAEINVAL),
4193 "got %d with %d and optval: 0x%x/%d (expected SOCKET_ERROR with WSAEINVAL)\n",
4194 ret, WSAGetLastError(), optval, optval);
4196 SetLastError(0xdeadbeef);
4197 optval = 0xdeadbeef;
4198 optlen = sizeof(int);
4199 ret = getsockopt(sock, 0x8000ffff, SO_MAX_MSG_SIZE, (char *)&optval, &optlen);
4200 ok( (ret == SOCKET_ERROR) && (WSAGetLastError() == WSAEINVAL),
4201 "got %d with %d and optval: 0x%x/%d (expected SOCKET_ERROR with WSAEINVAL)\n",
4202 ret, WSAGetLastError(), optval, optval);
4204 SetLastError(0xdeadbeef);
4205 optval = 0xdeadbeef;
4206 optlen = sizeof(int);
4207 ret = getsockopt(sock, 0x00008000, SO_MAX_MSG_SIZE, (char *)&optval, &optlen);
4208 ok( (ret == SOCKET_ERROR) && (WSAGetLastError() == WSAEINVAL),
4209 "got %d with %d and optval: 0x%x/%d (expected SOCKET_ERROR with WSAEINVAL)\n",
4210 ret, WSAGetLastError(), optval, optval);
4212 SetLastError(0xdeadbeef);
4213 optval = 0xdeadbeef;
4214 optlen = sizeof(int);
4215 ret = getsockopt(sock, 0x00000800, SO_MAX_MSG_SIZE, (char *)&optval, &optlen);
4216 ok( (ret == SOCKET_ERROR) && (WSAGetLastError() == WSAEINVAL),
4217 "got %d with %d and optval: 0x%x/%d (expected SOCKET_ERROR with WSAEINVAL)\n",
4218 ret, WSAGetLastError(), optval, optval);
4220 SetLastError(0xdeadbeef);
4221 optlen = sizeof(LINGER);
4222 ret = getsockopt(sock, SOL_SOCKET, SO_LINGER, (char *)&linger_val, &optlen);
4223 ok( (ret == SOCKET_ERROR) && (WSAGetLastError() == WSAENOPROTOOPT),
4224 "getsockopt should fail for UDP sockets setting last error to WSAENOPROTOOPT, got %d with %d\n",
4225 ret, WSAGetLastError());
4226 closesocket(sock);
4228 sock = socket(PF_INET, SOCK_STREAM, IPPROTO_IP);
4229 ok(sock != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
4231 ret = bind(sock, (struct sockaddr *) &sa, sa_len);
4232 ok(!ret, "failed to bind socket, error %u\n", WSAGetLastError());
4234 ret = getsockopt(sock, SOL_SOCKET, SO_LINGER, (char *)&linger_val, &optlen);
4235 ok(ret == 0, "getsockopt failed to query SO_LINGER, return value is 0x%08x\n", ret);
4237 optlen = sizeof(BOOL);
4238 ret = getsockopt(sock, SOL_SOCKET, SO_DONTLINGER, (char *)&bool_opt_val, &optlen);
4239 ok(ret == 0, "getsockopt failed to query SO_DONTLINGER, return value is 0x%08x\n", ret);
4240 ok((linger_val.l_onoff && !bool_opt_val) || (!linger_val.l_onoff && bool_opt_val),
4241 "Return value of SO_DONTLINGER is %d, but SO_LINGER returned l_onoff == %d.\n",
4242 bool_opt_val, linger_val.l_onoff);
4244 closesocket(sock);
4245 WSACleanup();
4248 static void test_getsockname(void)
4250 WSADATA wsa;
4251 SOCKET sock;
4252 struct sockaddr_in sa_set, sa_get;
4253 int sa_set_len = sizeof(struct sockaddr_in);
4254 int sa_get_len = sa_set_len;
4255 static const unsigned char null_padding[] = {0,0,0,0,0,0,0,0};
4256 int ret;
4257 struct hostent *h;
4259 ret = WSAStartup(MAKEWORD(2,0), &wsa);
4260 ok(!ret, "failed to startup, error %u\n", WSAGetLastError());
4262 memset(&sa_set, 0, sa_set_len);
4264 sa_set.sin_family = AF_INET;
4265 sa_set.sin_port = htons(0);
4266 sa_set.sin_addr.s_addr = htonl(INADDR_ANY);
4268 sock = socket(PF_INET, SOCK_STREAM, IPPROTO_IP);
4269 ok(sock != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
4271 sa_get = sa_set;
4272 WSASetLastError(0xdeadbeef);
4273 ret = getsockname(sock, (struct sockaddr *)&sa_get, &sa_get_len);
4274 ok(ret == SOCKET_ERROR, "expected failure\n");
4275 ok(WSAGetLastError() == WSAEINVAL, "got error %u\n", WSAGetLastError());
4276 ok(!memcmp(&sa_get, &sa_set, sizeof(sa_get)), "address should not be changed\n");
4278 ret = bind(sock, (struct sockaddr *) &sa_set, sa_set_len);
4279 ok(!ret, "failed to bind, error %u\n", WSAGetLastError());
4281 WSASetLastError(0xdeadbeef);
4282 memset(&sa_get, 0, sizeof(sa_get));
4283 ret = getsockname(sock, (struct sockaddr *) &sa_get, &sa_get_len);
4284 ok(!ret, "got %d\n", ret);
4285 ok(!WSAGetLastError() || WSAGetLastError() == 0xdeadbeef /* < 7 */, "got error %u\n", WSAGetLastError());
4286 ok(sa_get.sin_family == AF_INET, "got family %#x\n", sa_get.sin_family);
4287 ok(sa_get.sin_port != 0, "got zero port\n");
4288 ok(sa_get.sin_addr.s_addr == INADDR_ANY, "got addr %08x\n", sa_get.sin_addr.s_addr);
4290 ret = memcmp(sa_get.sin_zero, null_padding, 8);
4291 ok(ret == 0, "getsockname did not zero the sockaddr_in structure\n");
4293 sa_get_len = sizeof(sa_get) - 1;
4294 WSASetLastError(0xdeadbeef);
4295 ret = getsockname(sock, (struct sockaddr *)&sa_get, &sa_get_len);
4296 ok(ret == -1, "expected failure\n");
4297 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
4298 ok(sa_get_len == sizeof(sa_get) - 1, "got size %d\n", sa_get_len);
4300 closesocket(sock);
4302 h = gethostbyname("");
4303 if (h && h->h_length == 4) /* this test is only meaningful in IPv4 */
4305 int i;
4306 for (i = 0; h->h_addr_list[i]; i++)
4308 char ipstr[32];
4309 struct in_addr ip;
4310 ip.s_addr = *(ULONG *) h->h_addr_list[i];
4312 sock = socket(AF_INET, SOCK_DGRAM, 0);
4313 ok(sock != INVALID_SOCKET, "socket failed with %d\n", GetLastError());
4315 memset(&sa_set, 0, sizeof(sa_set));
4316 sa_set.sin_family = AF_INET;
4317 sa_set.sin_addr.s_addr = ip.s_addr;
4318 /* The same address we bind must be the same address we get */
4319 ret = bind(sock, (struct sockaddr*)&sa_set, sizeof(sa_set));
4320 ok(ret == 0, "bind failed with %d\n", GetLastError());
4321 sa_get_len = sizeof(sa_get);
4322 ret = getsockname(sock, (struct sockaddr*)&sa_get, &sa_get_len);
4323 ok(ret == 0, "getsockname failed with %d\n", GetLastError());
4324 strcpy(ipstr, inet_ntoa(sa_get.sin_addr));
4325 ok(sa_get.sin_addr.s_addr == sa_set.sin_addr.s_addr,
4326 "address does not match: %s != %s\n", ipstr, inet_ntoa(sa_set.sin_addr));
4328 closesocket(sock);
4332 WSACleanup();
4335 static DWORD apc_error, apc_size;
4336 static OVERLAPPED *apc_overlapped;
4337 static unsigned int apc_count;
4339 static void WINAPI socket_apc(DWORD error, DWORD size, OVERLAPPED *overlapped, DWORD flags)
4341 ok(!flags, "got flags %#x\n", flags);
4342 ++apc_count;
4343 apc_error = error;
4344 apc_size = size;
4345 apc_overlapped = overlapped;
4348 #define check_fionread_siocatmark(a, b, c) check_fionread_siocatmark_(__LINE__, a, b, c, FALSE, FALSE)
4349 #define check_fionread_siocatmark_todo(a, b, c) check_fionread_siocatmark_(__LINE__, a, b, c, TRUE, TRUE)
4350 #define check_fionread_siocatmark_todo_oob(a, b, c) check_fionread_siocatmark_(__LINE__, a, b, c, FALSE, TRUE)
4351 static void check_fionread_siocatmark_(int line, SOCKET s, unsigned int normal, unsigned int oob,
4352 BOOL todo_normal, BOOL todo_oob)
4354 int ret, value;
4355 DWORD size;
4357 value = 0xdeadbeef;
4358 WSASetLastError(0xdeadbeef);
4359 ret = WSAIoctl(s, FIONREAD, NULL, 0, &value, sizeof(value), &size, NULL, NULL);
4360 ok_(__FILE__, line)(!ret, "expected success\n");
4361 ok_(__FILE__, line)(!WSAGetLastError(), "got error %u\n", WSAGetLastError());
4362 todo_wine_if (todo_normal) ok_(__FILE__, line)(value == normal, "FIONBIO returned %u\n", value);
4364 value = 0xdeadbeef;
4365 WSASetLastError(0xdeadbeef);
4366 ret = WSAIoctl(s, SIOCATMARK, NULL, 0, &value, sizeof(value), &size, NULL, NULL);
4367 ok_(__FILE__, line)(!ret, "expected success\n");
4368 ok_(__FILE__, line)(!WSAGetLastError(), "got error %u\n", WSAGetLastError());
4369 todo_wine_if (todo_oob) ok_(__FILE__, line)(value == oob, "SIOCATMARK returned %u\n", value);
4372 static void test_fionread_siocatmark(void)
4374 const struct sockaddr_in bind_addr = {.sin_family = AF_INET, .sin_addr.s_addr = htonl(INADDR_LOOPBACK)};
4375 OVERLAPPED overlapped = {0}, *overlapped_ptr;
4376 SOCKET client, server;
4377 char buffer[5];
4378 int ret, value;
4379 ULONG_PTR key;
4380 HANDLE port;
4381 DWORD size;
4383 tcp_socketpair(&client, &server);
4384 set_blocking(client, FALSE);
4385 overlapped.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
4387 WSASetLastError(0xdeadbeef);
4388 ret = ioctlsocket(client, FIONREAD, (u_long *)1);
4389 ok(ret == -1, "expected failure\n");
4390 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
4392 WSASetLastError(0xdeadbeef);
4393 ret = ioctlsocket(client, SIOCATMARK, (u_long *)1);
4394 ok(ret == -1, "expected failure\n");
4395 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
4397 WSASetLastError(0xdeadbeef);
4398 ret = WSAIoctl(client, FIONREAD, NULL, 0, &value, sizeof(value), NULL, NULL, NULL);
4399 ok(ret == -1, "expected failure\n");
4400 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
4402 WSASetLastError(0xdeadbeef);
4403 size = 0xdeadbeef;
4404 ret = WSAIoctl(client, FIONREAD, NULL, 0, &value, sizeof(value) - 1, &size, NULL, NULL);
4405 ok(ret == -1, "expected failure\n");
4406 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
4407 ok(size == 0xdeadbeef, "got size %u\n", size);
4409 WSASetLastError(0xdeadbeef);
4410 ret = WSAIoctl(client, SIOCATMARK, NULL, 0, &value, sizeof(value), NULL, NULL, NULL);
4411 ok(ret == -1, "expected failure\n");
4412 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
4414 WSASetLastError(0xdeadbeef);
4415 size = 0xdeadbeef;
4416 ret = WSAIoctl(client, SIOCATMARK, NULL, 0, &value, sizeof(value) - 1, &size, NULL, NULL);
4417 ok(ret == -1, "expected failure\n");
4418 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
4419 ok(size == 0xdeadbeef, "got size %u\n", size);
4421 check_fionread_siocatmark(client, 0, TRUE);
4423 port = CreateIoCompletionPort((HANDLE)client, NULL, 123, 0);
4425 ret = WSAIoctl(client, FIONREAD, NULL, 0, &value, sizeof(value), NULL, &overlapped, NULL);
4426 ok(ret == -1, "expected failure\n");
4427 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
4429 ret = WSAIoctl(client, SIOCATMARK, NULL, 0, &value, sizeof(value), NULL, &overlapped, NULL);
4430 ok(ret == -1, "expected failure\n");
4431 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
4433 WSASetLastError(0xdeadbeef);
4434 size = 0xdeadbeef;
4435 value = 0xdeadbeef;
4436 overlapped.Internal = 0xdeadbeef;
4437 overlapped.InternalHigh = 0xdeadbeef;
4438 ret = WSAIoctl(client, FIONREAD, NULL, 0, &value, sizeof(value), &size, &overlapped, NULL);
4439 ok(!ret, "expected success\n");
4440 ok(!WSAGetLastError(), "got error %u\n", WSAGetLastError());
4441 ok(!value, "got %u\n", value);
4442 ok(size == sizeof(value), "got size %u\n", size);
4443 ok(!overlapped.Internal, "got status %#x\n", (NTSTATUS)overlapped.Internal);
4444 ok(!overlapped.InternalHigh, "got size %Iu\n", overlapped.InternalHigh);
4446 ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 0);
4447 ok(ret, "got error %u\n", GetLastError());
4448 ok(!size, "got size %u\n", size);
4449 ok(key == 123, "got key %Iu\n", key);
4450 ok(overlapped_ptr == &overlapped, "got overlapped %p\n", overlapped_ptr);
4452 WSASetLastError(0xdeadbeef);
4453 size = 0xdeadbeef;
4454 value = 0xdeadbeef;
4455 overlapped.Internal = 0xdeadbeef;
4456 overlapped.InternalHigh = 0xdeadbeef;
4457 ret = WSAIoctl(client, SIOCATMARK, NULL, 0, &value, sizeof(value), &size, &overlapped, NULL);
4458 ok(!ret, "expected success\n");
4459 ok(!WSAGetLastError(), "got error %u\n", WSAGetLastError());
4460 ok(value == TRUE, "got %u\n", value);
4461 ok(size == sizeof(value), "got size %u\n", size);
4462 ok(!overlapped.Internal, "got status %#x\n", (NTSTATUS)overlapped.Internal);
4463 ok(!overlapped.InternalHigh, "got size %Iu\n", overlapped.InternalHigh);
4465 ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 0);
4466 ok(ret, "got error %u\n", GetLastError());
4467 ok(!size, "got size %u\n", size);
4468 ok(key == 123, "got key %Iu\n", key);
4469 ok(overlapped_ptr == &overlapped, "got overlapped %p\n", overlapped_ptr);
4471 ret = send(server, "data", 5, 0);
4472 ok(ret == 5, "got %d\n", ret);
4474 /* wait for the data to be available */
4475 check_poll_mask(client, POLLRDNORM, POLLRDNORM);
4477 check_fionread_siocatmark(client, 5, TRUE);
4479 ret = send(server, "a", 1, MSG_OOB);
4480 ok(ret == 1, "got %d\n", ret);
4482 /* wait for the data to be available */
4483 check_poll_mask(client, POLLRDBAND, POLLRDBAND);
4485 check_fionread_siocatmark_todo_oob(client, 5, FALSE);
4487 ret = send(server, "a", 1, MSG_OOB);
4488 ok(ret == 1, "got %d\n", ret);
4490 check_fionread_siocatmark_todo(client, 5, FALSE);
4492 ret = recv(client, buffer, 3, 0);
4493 ok(ret == 3, "got %d\n", ret);
4495 check_fionread_siocatmark_todo(client, 2, FALSE);
4497 ret = recv(client, buffer, 1, MSG_OOB);
4498 ok(ret == 1, "got %d\n", ret);
4500 /* wait for the data to be available */
4501 check_poll_mask_todo(client, POLLRDBAND, POLLRDBAND);
4503 check_fionread_siocatmark_todo(client, 2, FALSE);
4505 ret = recv(client, buffer, 5, 0);
4506 todo_wine ok(ret == 2, "got %d\n", ret);
4508 check_fionread_siocatmark(client, 0, FALSE);
4510 ret = recv(client, buffer, 1, MSG_OOB);
4511 todo_wine ok(ret == 1, "got %d\n", ret);
4513 check_fionread_siocatmark_todo_oob(client, 0, TRUE);
4515 ret = send(server, "a", 1, MSG_OOB);
4516 ok(ret == 1, "got %d\n", ret);
4518 /* wait for the data to be available */
4519 check_poll_mask(client, POLLRDBAND, POLLRDBAND);
4521 ret = 1;
4522 ret = setsockopt(client, SOL_SOCKET, SO_OOBINLINE, (char *)&ret, sizeof(ret));
4523 ok(!ret, "got error %u\n", WSAGetLastError());
4525 check_fionread_siocatmark_todo_oob(client, 1, FALSE);
4527 ret = recv(client, buffer, 1, 0);
4528 ok(ret == 1, "got %d\n", ret);
4530 check_fionread_siocatmark(client, 0, TRUE);
4532 ret = send(server, "a", 1, MSG_OOB);
4533 ok(ret == 1, "got %d\n", ret);
4535 /* wait for the data to be available */
4536 check_poll_mask(client, POLLRDNORM, POLLRDNORM);
4538 check_fionread_siocatmark(client, 1, TRUE);
4540 closesocket(client);
4541 closesocket(server);
4543 server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
4545 check_fionread_siocatmark(server, 0, TRUE);
4547 ret = bind(server, (const struct sockaddr *)&bind_addr, sizeof(bind_addr));
4548 ok(!ret, "got error %u\n", WSAGetLastError());
4550 check_fionread_siocatmark(server, 0, TRUE);
4552 closesocket(server);
4553 CloseHandle(overlapped.hEvent);
4555 /* test with APCs */
4557 server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
4559 ret = WSAIoctl(server, FIONREAD, NULL, 0, &value, sizeof(value), NULL, &overlapped, socket_apc);
4560 ok(ret == -1, "expected failure\n");
4561 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
4563 ret = WSAIoctl(server, SIOCATMARK, NULL, 0, &value, sizeof(value), NULL, &overlapped, socket_apc);
4564 ok(ret == -1, "expected failure\n");
4565 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
4567 apc_count = 0;
4568 size = 0xdeadbeef;
4569 ret = WSAIoctl(server, FIONREAD, NULL, 0, &value, sizeof(value), &size, &overlapped, socket_apc);
4570 ok(!ret, "expected success\n");
4571 ok(size == sizeof(value), "got size %u\n", size);
4573 ret = SleepEx(0, TRUE);
4574 ok(ret == WAIT_IO_COMPLETION, "got %d\n", ret);
4575 ok(apc_count == 1, "APC was called %u times\n", apc_count);
4576 ok(!apc_error, "got APC error %u\n", apc_error);
4577 ok(!apc_size, "got APC size %u\n", apc_size);
4578 ok(apc_overlapped == &overlapped, "got APC overlapped %p\n", apc_overlapped);
4580 apc_count = 0;
4581 size = 0xdeadbeef;
4582 ret = WSAIoctl(server, SIOCATMARK, NULL, 0, &value, sizeof(value), &size, &overlapped, socket_apc);
4583 ok(!ret, "expected success\n");
4584 ok(size == sizeof(value), "got size %u\n", size);
4586 ret = SleepEx(0, TRUE);
4587 ok(ret == WAIT_IO_COMPLETION, "got %d\n", ret);
4588 ok(apc_count == 1, "APC was called %u times\n", apc_count);
4589 ok(!apc_error, "got APC error %u\n", apc_error);
4590 ok(!apc_size, "got APC size %u\n", apc_size);
4591 ok(apc_overlapped == &overlapped, "got APC overlapped %p\n", apc_overlapped);
4593 closesocket(server);
4596 static void test_fionbio(void)
4598 OVERLAPPED overlapped = {0}, *overlapped_ptr;
4599 u_long one = 1, zero = 0;
4600 HANDLE port, event;
4601 ULONG_PTR key;
4602 void *output;
4603 DWORD size;
4604 SOCKET s;
4605 int ret;
4607 event = CreateEventW(NULL, TRUE, FALSE, NULL);
4608 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
4609 port = CreateIoCompletionPort((HANDLE)s, NULL, 123, 0);
4611 WSASetLastError(0xdeadbeef);
4612 ret = ioctlsocket(s, FIONBIO, (u_long *)1);
4613 ok(ret == -1, "expected failure\n");
4614 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
4616 WSASetLastError(0xdeadbeef);
4617 ret = WSAIoctl(s, FIONBIO, &one, sizeof(one), NULL, 0, NULL, NULL, NULL);
4618 ok(ret == -1, "expected failure\n");
4619 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
4621 ret = WSAIoctl(s, FIONBIO, &one, sizeof(one) - 1, NULL, 0, &size, &overlapped, NULL);
4622 ok(ret == -1, "expected failure\n");
4623 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
4625 size = 0xdeadbeef;
4626 WSASetLastError(0xdeadbeef);
4627 ret = WSAIoctl(s, FIONBIO, &one, sizeof(one), NULL, 0, &size, NULL, NULL);
4628 ok(!ret, "expected success\n");
4629 ok(!WSAGetLastError(), "got error %u\n", WSAGetLastError());
4630 ok(!size, "got size %u\n", size);
4632 ret = WSAIoctl(s, FIONBIO, &one, sizeof(one) + 1, NULL, 0, &size, NULL, NULL);
4633 ok(!ret, "got error %u\n", WSAGetLastError());
4635 output = VirtualAlloc(NULL, 4, MEM_RESERVE | MEM_COMMIT, PAGE_NOACCESS);
4636 ret = WSAIoctl(s, FIONBIO, &one, sizeof(one) + 1, output, 4, &size, NULL, NULL);
4637 ok(!ret, "got error %u\n", WSAGetLastError());
4638 VirtualFree(output, 0, MEM_FREE);
4640 overlapped.Internal = 0xdeadbeef;
4641 overlapped.InternalHigh = 0xdeadbeef;
4642 size = 0xdeadbeef;
4643 ret = WSAIoctl(s, FIONBIO, &one, sizeof(one), NULL, 0, &size, &overlapped, NULL);
4644 ok(!ret, "expected success\n");
4645 ok(!size, "got size %u\n", size);
4647 ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 0);
4648 ok(ret, "got error %u\n", GetLastError());
4649 ok(!size, "got size %u\n", size);
4650 ok(overlapped_ptr == &overlapped, "got overlapped %p\n", overlapped_ptr);
4651 ok(!overlapped.Internal, "got status %#x\n", (NTSTATUS)overlapped.Internal);
4652 ok(!overlapped.InternalHigh, "got size %Iu\n", overlapped.InternalHigh);
4654 ret = WSAIoctl(s, FIONBIO, &one, sizeof(one), NULL, 0, NULL, &overlapped, NULL);
4655 ok(ret == -1, "expected failure\n");
4656 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
4658 ret = WSAEventSelect(s, event, FD_READ);
4659 ok(!ret, "got error %u\n", WSAGetLastError());
4661 ret = WSAIoctl(s, FIONBIO, &one, sizeof(one), NULL, 0, &size, NULL, NULL);
4662 ok(!ret, "got error %u\n", WSAGetLastError());
4664 size = 0xdeadbeef;
4665 ret = WSAIoctl(s, FIONBIO, &zero, sizeof(zero), NULL, 0, &size, NULL, NULL);
4666 ok(ret == -1, "expected failure\n");
4667 ok(WSAGetLastError() == WSAEINVAL, "got error %u\n", WSAGetLastError());
4668 todo_wine ok(!size, "got size %u\n", size);
4670 CloseHandle(port);
4671 closesocket(s);
4672 CloseHandle(event);
4674 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
4676 ret = WSAIoctl(s, FIONBIO, &one, sizeof(one), NULL, 0, NULL, &overlapped, socket_apc);
4677 ok(ret == -1, "expected failure\n");
4678 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
4680 apc_count = 0;
4681 size = 0xdeadbeef;
4682 ret = WSAIoctl(s, FIONBIO, &one, sizeof(one), NULL, 0, &size, &overlapped, socket_apc);
4683 ok(!ret, "expected success\n");
4684 ok(!size, "got size %u\n", size);
4686 ret = SleepEx(0, TRUE);
4687 ok(ret == WAIT_IO_COMPLETION, "got %d\n", ret);
4688 ok(apc_count == 1, "APC was called %u times\n", apc_count);
4689 ok(!apc_error, "got APC error %u\n", apc_error);
4690 ok(!apc_size, "got APC size %u\n", apc_size);
4691 ok(apc_overlapped == &overlapped, "got APC overlapped %p\n", apc_overlapped);
4693 closesocket(s);
4696 static void test_keepalive_vals(void)
4698 OVERLAPPED overlapped = {0}, *overlapped_ptr;
4699 struct tcp_keepalive kalive;
4700 ULONG_PTR key;
4701 HANDLE port;
4702 SOCKET sock;
4703 DWORD size;
4704 int ret;
4706 sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
4707 ok(sock != INVALID_SOCKET, "Creating the socket failed: %d\n", WSAGetLastError());
4708 port = CreateIoCompletionPort((HANDLE)sock, NULL, 123, 0);
4710 WSASetLastError(0xdeadbeef);
4711 size = 0xdeadbeef;
4712 ret = WSAIoctl(sock, SIO_KEEPALIVE_VALS, &kalive, 0, NULL, 0, &size, NULL, NULL);
4713 ok(ret == SOCKET_ERROR, "WSAIoctl succeeded unexpectedly\n");
4714 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
4715 ok(!size, "got size %u\n", size);
4717 WSASetLastError(0xdeadbeef);
4718 size = 0xdeadbeef;
4719 ret = WSAIoctl(sock, SIO_KEEPALIVE_VALS, NULL, sizeof(kalive), NULL, 0, &size, NULL, NULL);
4720 ok(ret == SOCKET_ERROR, "WSAIoctl succeeded unexpectedly\n");
4721 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
4722 ok(!size, "got size %u\n", size);
4724 WSASetLastError(0xdeadbeef);
4725 size = 0xdeadbeef;
4726 make_keepalive(kalive, 0, 0, 0);
4727 ret = WSAIoctl(sock, SIO_KEEPALIVE_VALS, &kalive, sizeof(kalive), NULL, 0, &size, NULL, NULL);
4728 ok(ret == 0, "WSAIoctl failed unexpectedly\n");
4729 ok(!WSAGetLastError(), "got error %u\n", WSAGetLastError());
4730 ok(!size, "got size %u\n", size);
4732 ret = WSAIoctl(sock, SIO_KEEPALIVE_VALS, &kalive, sizeof(kalive), NULL, 0, NULL, NULL, NULL);
4733 ok(ret == SOCKET_ERROR, "WSAIoctl succeeded unexpectedly\n");
4734 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
4736 ret = WSAIoctl(sock, SIO_KEEPALIVE_VALS, &kalive, sizeof(kalive), NULL, 0, NULL, &overlapped, NULL);
4737 ok(ret == SOCKET_ERROR, "WSAIoctl succeeded unexpectedly\n");
4738 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
4740 WSASetLastError(0xdeadbeef);
4741 size = 0xdeadbeef;
4742 overlapped.Internal = 0xdeadbeef;
4743 overlapped.InternalHigh = 0xdeadbeef;
4744 ret = WSAIoctl(sock, SIO_KEEPALIVE_VALS, &kalive, sizeof(kalive) - 1, NULL, 0, &size, &overlapped, NULL);
4745 ok(ret == SOCKET_ERROR, "WSAIoctl succeeded unexpectedly\n");
4746 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
4747 ok(size == 0xdeadbeef, "got size %u\n", size);
4748 todo_wine ok(overlapped.Internal == STATUS_PENDING, "got status %#x\n", (NTSTATUS)overlapped.Internal);
4749 ok(overlapped.InternalHigh == 0xdeadbeef, "got size %Iu\n", overlapped.InternalHigh);
4751 WSASetLastError(0xdeadbeef);
4752 size = 0xdeadbeef;
4753 overlapped.Internal = 0xdeadbeef;
4754 overlapped.InternalHigh = 0xdeadbeef;
4755 ret = WSAIoctl(sock, SIO_KEEPALIVE_VALS, &kalive, sizeof(kalive), NULL, 0, &size, &overlapped, NULL);
4756 ok(ret == 0, "WSAIoctl failed unexpectedly\n");
4757 ok(!WSAGetLastError(), "got error %u\n", WSAGetLastError());
4758 todo_wine ok(size == 0xdeadbeef, "got size %u\n", size);
4760 ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 0);
4761 ok(ret, "got error %u\n", GetLastError());
4762 ok(!size, "got size %u\n", size);
4763 ok(overlapped_ptr == &overlapped, "got overlapped %p\n", overlapped_ptr);
4764 ok(!overlapped.Internal, "got status %#x\n", (NTSTATUS)overlapped.Internal);
4765 ok(!overlapped.InternalHigh, "got size %Iu\n", overlapped.InternalHigh);
4767 make_keepalive(kalive, 1, 0, 0);
4768 ret = WSAIoctl(sock, SIO_KEEPALIVE_VALS, &kalive, sizeof(kalive), NULL, 0, &size, NULL, NULL);
4769 ok(ret == 0, "WSAIoctl failed unexpectedly\n");
4771 make_keepalive(kalive, 1, 1000, 1000);
4772 ret = WSAIoctl(sock, SIO_KEEPALIVE_VALS, &kalive, sizeof(kalive), NULL, 0, &size, NULL, NULL);
4773 ok(ret == 0, "WSAIoctl failed unexpectedly\n");
4775 make_keepalive(kalive, 1, 10000, 10000);
4776 ret = WSAIoctl(sock, SIO_KEEPALIVE_VALS, &kalive, sizeof(kalive), NULL, 0, &size, NULL, NULL);
4777 ok(ret == 0, "WSAIoctl failed unexpectedly\n");
4779 make_keepalive(kalive, 1, 100, 100);
4780 ret = WSAIoctl(sock, SIO_KEEPALIVE_VALS, &kalive, sizeof(kalive), NULL, 0, &size, NULL, NULL);
4781 ok(ret == 0, "WSAIoctl failed unexpectedly\n");
4783 make_keepalive(kalive, 0, 100, 100);
4784 ret = WSAIoctl(sock, SIO_KEEPALIVE_VALS, &kalive, sizeof(kalive), NULL, 0, &size, NULL, NULL);
4785 ok(ret == 0, "WSAIoctl failed unexpectedly\n");
4787 CloseHandle(port);
4788 closesocket(sock);
4790 sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
4792 ret = WSAIoctl(sock, SIO_KEEPALIVE_VALS, &kalive, sizeof(kalive), NULL, 0, NULL, &overlapped, socket_apc);
4793 ok(ret == -1, "expected failure\n");
4794 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
4796 apc_count = 0;
4797 size = 0xdeadbeef;
4798 ret = WSAIoctl(sock, SIO_KEEPALIVE_VALS, &kalive, sizeof(kalive), NULL, 0, &size, &overlapped, socket_apc);
4799 ok(!ret, "expected success\n");
4800 ok(!size, "got size %u\n", size);
4802 ret = SleepEx(0, TRUE);
4803 ok(ret == WAIT_IO_COMPLETION, "got %d\n", ret);
4804 ok(apc_count == 1, "APC was called %u times\n", apc_count);
4805 ok(!apc_error, "got APC error %u\n", apc_error);
4806 ok(!apc_size, "got APC size %u\n", apc_size);
4807 ok(apc_overlapped == &overlapped, "got APC overlapped %p\n", apc_overlapped);
4809 closesocket(sock);
4812 static void test_unsupported_ioctls(void)
4814 OVERLAPPED overlapped = {0}, *overlapped_ptr;
4815 unsigned int i;
4816 ULONG_PTR key;
4817 HANDLE port;
4818 DWORD size;
4819 SOCKET s;
4820 int ret;
4822 static const DWORD codes[] = {0xdeadbeef, FIOASYNC, 0x667e, SIO_FLUSH};
4824 for (i = 0; i < ARRAY_SIZE(codes); ++i)
4826 winetest_push_context("ioctl %#x", codes[i]);
4827 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
4828 port = CreateIoCompletionPort((HANDLE)s, NULL, 123, 0);
4830 WSASetLastError(0xdeadbeef);
4831 ret = WSAIoctl(s, codes[i], NULL, 0, NULL, 0, NULL, &overlapped, NULL);
4832 ok(ret == -1, "expected failure\n");
4833 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
4835 WSASetLastError(0xdeadbeef);
4836 size = 0xdeadbeef;
4837 ret = WSAIoctl(s, codes[i], NULL, 0, NULL, 0, &size, NULL, NULL);
4838 ok(ret == -1, "expected failure\n");
4839 ok(WSAGetLastError() == WSAEOPNOTSUPP, "got error %u\n", WSAGetLastError());
4840 ok(!size, "got size %u\n", size);
4842 WSASetLastError(0xdeadbeef);
4843 size = 0xdeadbeef;
4844 overlapped.Internal = 0xdeadbeef;
4845 overlapped.InternalHigh = 0xdeadbeef;
4846 ret = WSAIoctl(s, codes[i], NULL, 0, NULL, 0, &size, &overlapped, NULL);
4847 ok(ret == -1, "expected failure\n");
4848 ok(WSAGetLastError() == ERROR_IO_PENDING, "got error %u\n", WSAGetLastError());
4849 ok(size == 0xdeadbeef, "got size %u\n", size);
4851 ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 0);
4852 ok(!ret, "expected failure\n");
4853 ok(GetLastError() == ERROR_NOT_SUPPORTED, "got error %u\n", GetLastError());
4854 ok(!size, "got size %u\n", size);
4855 ok(key == 123, "got key %Iu\n", key);
4856 ok(overlapped_ptr == &overlapped, "got overlapped %p\n", overlapped_ptr);
4857 ok((NTSTATUS)overlapped.Internal == STATUS_NOT_SUPPORTED,
4858 "got status %#x\n", (NTSTATUS)overlapped.Internal);
4859 ok(!overlapped.InternalHigh, "got size %Iu\n", overlapped.InternalHigh);
4861 CloseHandle(port);
4862 closesocket(s);
4864 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
4866 ret = WSAIoctl(s, codes[i], NULL, 0, NULL, 0, NULL, &overlapped, socket_apc);
4867 ok(ret == -1, "expected failure\n");
4868 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
4870 apc_count = 0;
4871 size = 0xdeadbeef;
4872 ret = WSAIoctl(s, codes[i], NULL, 0, NULL, 0, &size, &overlapped, socket_apc);
4873 ok(ret == -1, "expected failure\n");
4874 ok(WSAGetLastError() == ERROR_IO_PENDING, "got error %u\n", WSAGetLastError());
4875 ok(size == 0xdeadbeef, "got size %u\n", size);
4877 ret = SleepEx(0, TRUE);
4878 ok(ret == WAIT_IO_COMPLETION, "got %d\n", ret);
4879 ok(apc_count == 1, "APC was called %u times\n", apc_count);
4880 ok(apc_error == WSAEOPNOTSUPP, "got APC error %u\n", apc_error);
4881 ok(!apc_size, "got APC size %u\n", apc_size);
4882 ok(apc_overlapped == &overlapped, "got APC overlapped %p\n", apc_overlapped);
4884 closesocket(s);
4885 winetest_pop_context();
4889 static void test_get_extension_func(void)
4891 OVERLAPPED overlapped = {0}, *overlapped_ptr;
4892 GUID acceptex_guid = WSAID_ACCEPTEX;
4893 GUID bogus_guid = {0xdeadbeef};
4894 ULONG_PTR key;
4895 HANDLE port;
4896 DWORD size;
4897 void *func;
4898 SOCKET s;
4899 int ret;
4901 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
4902 port = CreateIoCompletionPort((HANDLE)s, NULL, 123, 0);
4904 WSASetLastError(0xdeadbeef);
4905 ret = WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &acceptex_guid, sizeof(GUID),
4906 &func, sizeof(func), NULL, &overlapped, NULL);
4907 ok(ret == -1, "expected failure\n");
4908 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
4910 WSASetLastError(0xdeadbeef);
4911 size = 0xdeadbeef;
4912 ret = WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &acceptex_guid, sizeof(GUID),
4913 &func, sizeof(func), &size, NULL, NULL);
4914 ok(!ret, "expected success\n");
4915 ok(!WSAGetLastError(), "got error %u\n", WSAGetLastError());
4916 ok(size == sizeof(func), "got size %u\n", size);
4918 WSASetLastError(0xdeadbeef);
4919 size = 0xdeadbeef;
4920 overlapped.Internal = 0xdeadbeef;
4921 overlapped.InternalHigh = 0xdeadbeef;
4922 ret = WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &acceptex_guid, sizeof(GUID),
4923 &func, sizeof(func), &size, &overlapped, NULL);
4924 ok(!ret, "expected success\n");
4925 ok(!WSAGetLastError(), "got error %u\n", WSAGetLastError());
4926 ok(size == sizeof(func), "got size %u\n", size);
4928 ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 0);
4929 ok(ret, "got error %u\n", GetLastError());
4930 ok(!size, "got size %u\n", size);
4931 ok(key == 123, "got key %Iu\n", key);
4932 ok(overlapped_ptr == &overlapped, "got overlapped %p\n", overlapped_ptr);
4933 ok(!overlapped.Internal, "got status %#x\n", (NTSTATUS)overlapped.Internal);
4934 ok(!overlapped.InternalHigh, "got size %Iu\n", overlapped.InternalHigh);
4936 size = 0xdeadbeef;
4937 overlapped.Internal = 0xdeadbeef;
4938 overlapped.InternalHigh = 0xdeadbeef;
4939 ret = WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &bogus_guid, sizeof(GUID),
4940 &func, sizeof(func), &size, &overlapped, NULL);
4941 ok(ret == -1, "expected failure\n");
4942 ok(WSAGetLastError() == WSAEINVAL, "got error %u\n", WSAGetLastError());
4943 ok(size == 0xdeadbeef, "got size %u\n", size);
4944 ok(overlapped.Internal == 0xdeadbeef, "got status %#x\n", (NTSTATUS)overlapped.Internal);
4945 ok(overlapped.InternalHigh == 0xdeadbeef, "got size %Iu\n", overlapped.InternalHigh);
4947 ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 0);
4948 ok(!ret, "expected failure\n");
4949 ok(GetLastError() == WAIT_TIMEOUT, "got error %u\n", WSAGetLastError());
4951 CloseHandle(port);
4952 closesocket(s);
4954 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
4956 ret = WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &acceptex_guid, sizeof(GUID),
4957 &func, sizeof(func), NULL, &overlapped, socket_apc);
4958 ok(ret == -1, "expected failure\n");
4959 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
4961 apc_count = 0;
4962 size = 0xdeadbeef;
4963 ret = WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &acceptex_guid, sizeof(GUID),
4964 &func, sizeof(func), &size, &overlapped, socket_apc);
4965 ok(!ret, "got error %u\n", WSAGetLastError());
4966 ok(size == sizeof(func), "got size %u\n", size);
4968 ret = SleepEx(0, TRUE);
4969 ok(ret == WAIT_IO_COMPLETION, "got %d\n", ret);
4970 ok(apc_count == 1, "APC was called %u times\n", apc_count);
4971 ok(!apc_error, "got APC error %u\n", apc_error);
4972 ok(!apc_size, "got APC size %u\n", apc_size);
4973 ok(apc_overlapped == &overlapped, "got APC overlapped %p\n", apc_overlapped);
4975 closesocket(s);
4978 static void test_base_handle(void)
4980 OVERLAPPED overlapped = {0}, *overlapped_ptr;
4981 unsigned int i;
4982 SOCKET s, base;
4983 ULONG_PTR key;
4984 HANDLE port;
4985 DWORD size;
4986 int ret;
4988 static const struct
4990 int family, type, protocol;
4992 tests[] =
4994 {AF_INET, SOCK_STREAM, IPPROTO_TCP},
4995 {AF_INET, SOCK_DGRAM, IPPROTO_UDP},
4996 {AF_INET6, SOCK_STREAM, IPPROTO_TCP},
4997 {AF_INET6, SOCK_DGRAM, IPPROTO_UDP},
5000 for (i = 0; i < ARRAY_SIZE(tests); ++i)
5002 s = socket(tests[i].family, tests[i].type, tests[i].protocol);
5003 if (s == INVALID_SOCKET) continue;
5004 port = CreateIoCompletionPort((HANDLE)s, NULL, 123, 0);
5006 WSASetLastError(0xdeadbeef);
5007 ret = WSAIoctl(s, SIO_BASE_HANDLE, NULL, 0, &base, sizeof(base), NULL, &overlapped, NULL);
5008 ok(ret == -1, "expected failure\n");
5009 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
5011 WSASetLastError(0xdeadbeef);
5012 size = 0xdeadbeef;
5013 base = 0xdeadbeef;
5014 ret = WSAIoctl(s, SIO_BASE_HANDLE, NULL, 0, &base, sizeof(base), &size, NULL, NULL);
5015 ok(!ret, "expected success\n");
5016 ok(!WSAGetLastError(), "got error %u\n", WSAGetLastError());
5017 ok(size == sizeof(base), "got size %u\n", size);
5018 ok(base == s, "expected %#Ix, got %#Ix\n", s, base);
5020 WSASetLastError(0xdeadbeef);
5021 size = 0xdeadbeef;
5022 base = 0xdeadbeef;
5023 overlapped.Internal = 0xdeadbeef;
5024 overlapped.InternalHigh = 0xdeadbeef;
5025 ret = WSAIoctl(s, SIO_BASE_HANDLE, NULL, 0, &base, sizeof(base), &size, &overlapped, NULL);
5026 ok(ret == -1, "expected failure\n");
5027 ok(WSAGetLastError() == ERROR_IO_PENDING, "got error %u\n", WSAGetLastError());
5028 ok(size == 0xdeadbeef, "got size %u\n", size);
5030 ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 0);
5031 ok(!ret, "expected failure\n");
5032 ok(GetLastError() == ERROR_NOT_SUPPORTED, "got error %u\n", GetLastError());
5033 ok(!size, "got size %u\n", size);
5034 ok(key == 123, "got key %Iu\n", key);
5035 ok(overlapped_ptr == &overlapped, "got overlapped %p\n", overlapped_ptr);
5036 ok((NTSTATUS)overlapped.Internal == STATUS_NOT_SUPPORTED, "got status %#x\n", (NTSTATUS)overlapped.Internal);
5037 ok(!overlapped.InternalHigh, "got size %Iu\n", overlapped.InternalHigh);
5038 ok(base == 0xdeadbeef, "expected %#Ix, got %#Ix\n", s, base);
5040 CloseHandle(port);
5041 closesocket(s);
5043 s = socket(tests[i].family, tests[i].type, tests[i].protocol);
5045 ret = WSAIoctl(s, SIO_BASE_HANDLE, NULL, 0, &base, sizeof(base), NULL, &overlapped, socket_apc);
5046 ok(ret == -1, "expected failure\n");
5047 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
5049 apc_count = 0;
5050 size = 0xdeadbeef;
5051 base = 0xdeadbeef;
5052 ret = WSAIoctl(s, SIO_BASE_HANDLE, NULL, 0, &base, sizeof(base), &size, &overlapped, socket_apc);
5053 ok(ret == -1, "expected failure\n");
5054 ok(WSAGetLastError() == ERROR_IO_PENDING, "got error %u\n", WSAGetLastError());
5055 ok(size == 0xdeadbeef, "got size %u\n", size);
5057 ret = SleepEx(0, TRUE);
5058 ok(ret == WAIT_IO_COMPLETION, "got %d\n", ret);
5059 ok(apc_count == 1, "APC was called %u times\n", apc_count);
5060 ok(apc_error == WSAEOPNOTSUPP, "got APC error %u\n", apc_error);
5061 ok(!apc_size, "got APC size %u\n", apc_size);
5062 ok(apc_overlapped == &overlapped, "got APC overlapped %p\n", apc_overlapped);
5063 ok(base == 0xdeadbeef, "expected %#Ix, got %#Ix\n", s, base);
5065 closesocket(s);
5069 static BOOL drain_pause = FALSE;
5070 static DWORD WINAPI drain_socket_thread(LPVOID arg)
5072 char buffer[1024];
5073 SOCKET sock = *(SOCKET*)arg;
5074 int ret;
5076 while ((ret = recv(sock, buffer, sizeof(buffer), 0)) != 0)
5078 if (ret < 0)
5080 if (WSAGetLastError() == WSAEWOULDBLOCK)
5082 fd_set readset;
5083 FD_ZERO(&readset);
5084 FD_SET(sock, &readset);
5085 select(sock+1, &readset, NULL, NULL, NULL);
5086 while (drain_pause)
5087 Sleep(100);
5089 else
5090 break;
5093 return 0;
5096 static void test_send(void)
5098 SOCKET src = INVALID_SOCKET;
5099 SOCKET dst = INVALID_SOCKET;
5100 HANDLE hThread = NULL;
5101 const int buflen = 1024*1024;
5102 char *buffer = NULL;
5103 int ret, i, zero = 0;
5104 WSABUF buf;
5105 OVERLAPPED ov;
5106 BOOL bret;
5107 DWORD id, bytes_sent, dwRet;
5109 memset(&ov, 0, sizeof(ov));
5111 tcp_socketpair(&src, &dst);
5113 set_blocking(dst, FALSE);
5114 /* force disable buffering so we can get a pending overlapped request */
5115 ret = setsockopt(dst, SOL_SOCKET, SO_SNDBUF, (char *) &zero, sizeof(zero));
5116 ok(!ret, "setsockopt SO_SNDBUF failed: %d - %d\n", ret, GetLastError());
5118 hThread = CreateThread(NULL, 0, drain_socket_thread, &dst, 0, &id);
5120 buffer = HeapAlloc(GetProcessHeap(), 0, buflen);
5122 /* fill the buffer with some nonsense */
5123 for (i = 0; i < buflen; ++i)
5125 buffer[i] = (char) i;
5128 ret = send(src, buffer, buflen, 0);
5129 ok(ret == buflen, "send should have sent %d bytes, but it only sent %d\n", buflen, ret);
5131 buf.buf = buffer;
5132 buf.len = buflen;
5134 ov.hEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
5135 ok(ov.hEvent != NULL, "could not create event object, errno = %d\n", GetLastError());
5136 if (!ov.hEvent)
5137 goto end;
5139 bytes_sent = 0;
5140 WSASetLastError(12345);
5141 ret = WSASend(dst, &buf, 1, &bytes_sent, 0, &ov, NULL);
5142 ok(ret == SOCKET_ERROR, "expected failure\n");
5143 ok(WSAGetLastError() == ERROR_IO_PENDING, "wrong error %u\n", WSAGetLastError());
5145 /* don't check for completion yet, we may need to drain the buffer while still sending */
5146 set_blocking(src, FALSE);
5147 for (i = 0; i < buflen; ++i)
5149 int j = 0;
5151 ret = recv(src, buffer, 1, 0);
5152 while (ret == SOCKET_ERROR && GetLastError() == WSAEWOULDBLOCK && j < 100)
5154 j++;
5155 Sleep(50);
5156 ret = recv(src, buffer, 1, 0);
5159 ok(ret == 1, "Failed to receive data %d - %d (got %d/%d)\n", ret, GetLastError(), i, buflen);
5160 if (ret != 1)
5161 break;
5163 ok(buffer[0] == (char) i, "Received bad data at position %d\n", i);
5166 dwRet = WaitForSingleObject(ov.hEvent, 1000);
5167 ok(dwRet == WAIT_OBJECT_0, "Failed to wait for recv message: %d - %d\n", dwRet, GetLastError());
5168 if (dwRet == WAIT_OBJECT_0)
5170 bret = GetOverlappedResult((HANDLE)dst, &ov, &bytes_sent, FALSE);
5171 ok(bret && bytes_sent == buflen,
5172 "Got %d instead of %d (%d - %d)\n", bytes_sent, buflen, bret, GetLastError());
5175 WSASetLastError(12345);
5176 ret = WSASend(INVALID_SOCKET, &buf, 1, NULL, 0, &ov, NULL);
5177 ok(ret == SOCKET_ERROR && WSAGetLastError() == WSAENOTSOCK,
5178 "WSASend failed %d - %d\n", ret, WSAGetLastError());
5180 WSASetLastError(12345);
5181 ret = WSASend(dst, &buf, 1, NULL, 0, &ov, NULL);
5182 ok(ret == SOCKET_ERROR && WSAGetLastError() == ERROR_IO_PENDING,
5183 "Failed to start overlapped send %d - %d\n", ret, WSAGetLastError());
5185 end:
5186 if (src != INVALID_SOCKET)
5187 closesocket(src);
5188 if (dst != INVALID_SOCKET)
5189 closesocket(dst);
5190 if (hThread != NULL)
5192 dwRet = WaitForSingleObject(hThread, 500);
5193 ok(dwRet == WAIT_OBJECT_0, "failed to wait for thread termination: %d\n", GetLastError());
5194 CloseHandle(hThread);
5196 if (ov.hEvent)
5197 CloseHandle(ov.hEvent);
5198 HeapFree(GetProcessHeap(), 0, buffer);
5201 #define WM_SOCKET (WM_USER+100)
5203 struct event_test_ctx
5205 int is_message;
5206 SOCKET socket;
5207 HANDLE event;
5208 HWND window;
5211 static void select_events(struct event_test_ctx *ctx, SOCKET socket, LONG events)
5213 int ret;
5215 if (ctx->is_message)
5216 ret = WSAAsyncSelect(socket, ctx->window, WM_USER, events);
5217 else
5218 ret = WSAEventSelect(socket, ctx->event, events);
5219 ok(!ret, "failed to select, error %u\n", WSAGetLastError());
5220 ctx->socket = socket;
5223 #define check_events(a, b, c, d) check_events_(__LINE__, a, b, c, d, FALSE, FALSE)
5224 #define check_events_todo(a, b, c, d) check_events_(__LINE__, a, b, c, d, TRUE, TRUE)
5225 #define check_events_todo_event(a, b, c, d) check_events_(__LINE__, a, b, c, d, TRUE, FALSE)
5226 #define check_events_todo_msg(a, b, c, d) check_events_(__LINE__, a, b, c, d, FALSE, TRUE)
5227 static void check_events_(int line, struct event_test_ctx *ctx,
5228 LONG flag1, LONG flag2, DWORD timeout, BOOL todo_event, BOOL todo_msg)
5230 int ret;
5232 if (ctx->is_message)
5234 BOOL any_fail = FALSE;
5235 MSG msg;
5237 if (flag1)
5239 ret = PeekMessageA(&msg, ctx->window, WM_USER, WM_USER, PM_REMOVE);
5240 while (!ret && !MsgWaitForMultipleObjects(0, NULL, FALSE, timeout, QS_POSTMESSAGE))
5241 ret = PeekMessageA(&msg, ctx->window, WM_USER, WM_USER, PM_REMOVE);
5242 todo_wine_if (todo_msg && !ret) ok_(__FILE__, line)(ret, "expected a message\n");
5243 if (ret)
5245 ok_(__FILE__, line)(msg.wParam == ctx->socket,
5246 "expected wparam %#Ix, got %#Ix\n", ctx->socket, msg.wParam);
5247 todo_wine_if (todo_msg && msg.lParam != flag1)
5248 ok_(__FILE__, line)(msg.lParam == flag1, "got first event %#Ix\n", msg.lParam);
5249 if (msg.lParam != flag1) any_fail = TRUE;
5251 else
5252 any_fail = TRUE;
5254 if (flag2)
5256 ret = PeekMessageA(&msg, ctx->window, WM_USER, WM_USER, PM_REMOVE);
5257 while (!ret && !MsgWaitForMultipleObjects(0, NULL, FALSE, timeout, QS_POSTMESSAGE))
5258 ret = PeekMessageA(&msg, ctx->window, WM_USER, WM_USER, PM_REMOVE);
5259 ok_(__FILE__, line)(ret, "expected a message\n");
5260 ok_(__FILE__, line)(msg.wParam == ctx->socket, "got wparam %#Ix\n", msg.wParam);
5261 todo_wine_if (todo_msg) ok_(__FILE__, line)(msg.lParam == flag2, "got second event %#Ix\n", msg.lParam);
5263 ret = PeekMessageA(&msg, ctx->window, WM_USER, WM_USER, PM_REMOVE);
5264 todo_wine_if (todo_msg && ret) ok_(__FILE__, line)(!ret, "got unexpected event %#Ix\n", msg.lParam);
5265 if (ret) any_fail = TRUE;
5267 /* catch tests which succeed */
5268 todo_wine_if (todo_msg) ok_(__FILE__, line)(!any_fail, "event series matches\n");
5270 else
5272 WSANETWORKEVENTS events;
5274 ret = WaitForSingleObject(ctx->event, timeout);
5275 if (flag1 | flag2)
5276 todo_wine_if (todo_event && ret) ok_(__FILE__, line)(!ret, "event wait timed out\n");
5277 else
5278 todo_wine_if (todo_event) ok_(__FILE__, line)(ret == WAIT_TIMEOUT, "expected timeout\n");
5279 ret = WSAEnumNetworkEvents(ctx->socket, ctx->event, &events);
5280 ok_(__FILE__, line)(!ret, "failed to get events, error %u\n", WSAGetLastError());
5281 todo_wine_if (todo_event)
5282 ok_(__FILE__, line)(events.lNetworkEvents == (flag1 | flag2), "got events %#x\n", events.lNetworkEvents);
5286 static void test_accept_events(struct event_test_ctx *ctx)
5288 const struct sockaddr_in addr = {.sin_family = AF_INET, .sin_addr.s_addr = htonl(INADDR_LOOPBACK)};
5289 SOCKET listener, server, client, client2;
5290 struct sockaddr_in destaddr;
5291 int len, ret;
5293 listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
5294 ok(listener != -1, "failed to create socket, error %u\n", WSAGetLastError());
5296 select_events(ctx, listener, FD_CONNECT | FD_READ | FD_OOB | FD_ACCEPT);
5298 ret = bind(listener, (const struct sockaddr *)&addr, sizeof(addr));
5299 ok(!ret, "failed to bind, error %u\n", WSAGetLastError());
5300 len = sizeof(destaddr);
5301 ret = getsockname(listener, (struct sockaddr *)&destaddr, &len);
5302 ok(!ret, "failed to get address, error %u\n", WSAGetLastError());
5303 ret = listen(listener, 2);
5304 ok(!ret, "failed to listen, error %u\n", WSAGetLastError());
5306 check_events(ctx, 0, 0, 0);
5308 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
5309 ok(client != -1, "failed to create socket, error %u\n", WSAGetLastError());
5310 ret = connect(client, (struct sockaddr *)&destaddr, sizeof(destaddr));
5311 ok(!ret, "failed to connect, error %u\n", WSAGetLastError());
5313 check_events(ctx, FD_ACCEPT, 0, 200);
5314 check_events(ctx, 0, 0, 0);
5315 select_events(ctx, listener, FD_CONNECT | FD_READ | FD_OOB | FD_ACCEPT);
5316 if (ctx->is_message)
5317 check_events(ctx, FD_ACCEPT, 0, 200);
5318 check_events(ctx, 0, 0, 0);
5319 select_events(ctx, listener, 0);
5320 select_events(ctx, listener, FD_CONNECT | FD_READ | FD_OOB | FD_ACCEPT);
5321 if (ctx->is_message)
5322 check_events(ctx, FD_ACCEPT, 0, 200);
5323 check_events(ctx, 0, 0, 0);
5325 client2 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
5326 ok(client2 != -1, "failed to create socket, error %u\n", WSAGetLastError());
5327 ret = connect(client2, (struct sockaddr *)&destaddr, sizeof(destaddr));
5328 ok(!ret, "failed to connect, error %u\n", WSAGetLastError());
5330 if (!ctx->is_message)
5331 check_events_todo(ctx, FD_ACCEPT, 0, 200);
5332 check_events(ctx, 0, 0, 0);
5334 server = accept(listener, NULL, NULL);
5335 ok(server != -1, "failed to accept, error %u\n", WSAGetLastError());
5336 closesocket(server);
5338 check_events(ctx, FD_ACCEPT, 0, 200);
5339 check_events(ctx, 0, 0, 0);
5341 server = accept(listener, NULL, NULL);
5342 ok(server != -1, "failed to accept, error %u\n", WSAGetLastError());
5343 closesocket(server);
5345 check_events(ctx, 0, 0, 0);
5347 closesocket(client2);
5348 closesocket(client);
5350 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
5351 ok(client != -1, "failed to create socket, error %u\n", WSAGetLastError());
5352 ret = connect(client, (struct sockaddr *)&destaddr, sizeof(destaddr));
5353 ok(!ret, "failed to connect, error %u\n", WSAGetLastError());
5355 check_events(ctx, FD_ACCEPT, 0, 200);
5357 server = accept(listener, NULL, NULL);
5358 ok(server != -1, "failed to accept, error %u\n", WSAGetLastError());
5359 closesocket(server);
5360 closesocket(client);
5362 check_events(ctx, 0, 0, 200);
5364 closesocket(listener);
5366 /* Connect and then select. */
5368 listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
5369 ok(listener != -1, "failed to create socket, error %u\n", WSAGetLastError());
5370 ret = bind(listener, (const struct sockaddr *)&addr, sizeof(addr));
5371 ok(!ret, "failed to bind, error %u\n", WSAGetLastError());
5372 len = sizeof(destaddr);
5373 ret = getsockname(listener, (struct sockaddr *)&destaddr, &len);
5374 ok(!ret, "failed to get address, error %u\n", WSAGetLastError());
5375 ret = listen(listener, 2);
5376 ok(!ret, "failed to listen, error %u\n", WSAGetLastError());
5378 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
5379 ok(client != -1, "failed to create socket, error %u\n", WSAGetLastError());
5380 ret = connect(client, (struct sockaddr *)&destaddr, sizeof(destaddr));
5381 ok(!ret, "failed to connect, error %u\n", WSAGetLastError());
5383 select_events(ctx, listener, FD_CONNECT | FD_READ | FD_OOB | FD_ACCEPT);
5385 check_events(ctx, FD_ACCEPT, 0, 200);
5387 server = accept(listener, NULL, NULL);
5388 ok(server != -1, "failed to accept, error %u\n", WSAGetLastError());
5389 closesocket(server);
5390 closesocket(client);
5392 /* As above, but select on a subset containing FD_ACCEPT first. */
5394 if (!ctx->is_message)
5396 select_events(ctx, listener, FD_CONNECT | FD_READ | FD_OOB | FD_ACCEPT);
5398 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
5399 ok(client != -1, "failed to create socket, error %u\n", WSAGetLastError());
5400 ret = connect(client, (struct sockaddr *)&destaddr, sizeof(destaddr));
5401 ok(!ret, "failed to connect, error %u\n", WSAGetLastError());
5403 ret = WaitForSingleObject(ctx->event, 200);
5404 ok(!ret, "wait timed out\n");
5406 select_events(ctx, listener, FD_CONNECT | FD_READ | FD_OOB);
5407 ret = WaitForSingleObject(ctx->event, 0);
5408 ok(!ret, "wait timed out\n");
5410 ResetEvent(ctx->event);
5412 select_events(ctx, listener, FD_CONNECT | FD_READ | FD_OOB);
5413 ret = WaitForSingleObject(ctx->event, 0);
5414 ok(ret == WAIT_TIMEOUT, "expected timeout\n");
5416 select_events(ctx, listener, FD_CONNECT | FD_READ | FD_OOB | FD_ACCEPT);
5417 ret = WaitForSingleObject(ctx->event, 0);
5418 ok(!ret, "wait timed out\n");
5419 check_events(ctx, FD_ACCEPT, 0, 0);
5421 server = accept(listener, NULL, NULL);
5422 ok(server != -1, "failed to accept, error %u\n", WSAGetLastError());
5423 closesocket(server);
5424 closesocket(client);
5427 /* As above, but select on a subset not containing FD_ACCEPT first. */
5429 select_events(ctx, listener, FD_CONNECT | FD_READ | FD_OOB);
5431 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
5432 ok(client != -1, "failed to create socket, error %u\n", WSAGetLastError());
5433 ret = connect(client, (struct sockaddr *)&destaddr, sizeof(destaddr));
5434 ok(!ret, "failed to connect, error %u\n", WSAGetLastError());
5436 select_events(ctx, listener, FD_CONNECT | FD_READ | FD_OOB | FD_ACCEPT);
5437 check_events(ctx, FD_ACCEPT, 0, 200);
5439 server = accept(listener, NULL, NULL);
5440 ok(server != -1, "failed to accept, error %u\n", WSAGetLastError());
5441 closesocket(server);
5442 closesocket(client);
5444 /* As above, but call accept() before selecting. */
5446 select_events(ctx, listener, FD_CONNECT | FD_READ | FD_OOB);
5448 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
5449 ok(client != -1, "failed to create socket, error %u\n", WSAGetLastError());
5450 ret = connect(client, (struct sockaddr *)&destaddr, sizeof(destaddr));
5451 ok(!ret, "failed to connect, error %u\n", WSAGetLastError());
5452 Sleep(200);
5453 server = accept(listener, NULL, NULL);
5454 ok(server != -1, "failed to accept, error %u\n", WSAGetLastError());
5456 select_events(ctx, listener, FD_CONNECT | FD_READ | FD_OOB | FD_ACCEPT);
5457 check_events(ctx, 0, 0, 200);
5459 closesocket(server);
5460 closesocket(client);
5462 closesocket(listener);
5464 /* The socket returned from accept() inherits the same parameters. */
5466 listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
5467 ok(listener != -1, "failed to create socket, error %u\n", WSAGetLastError());
5468 ret = bind(listener, (const struct sockaddr *)&addr, sizeof(addr));
5469 ok(!ret, "failed to bind, error %u\n", WSAGetLastError());
5470 len = sizeof(destaddr);
5471 ret = getsockname(listener, (struct sockaddr *)&destaddr, &len);
5472 ok(!ret, "failed to get address, error %u\n", WSAGetLastError());
5473 ret = listen(listener, 2);
5474 ok(!ret, "failed to listen, error %u\n", WSAGetLastError());
5476 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
5477 ok(client != -1, "failed to create socket, error %u\n", WSAGetLastError());
5478 ret = connect(client, (struct sockaddr *)&destaddr, sizeof(destaddr));
5479 ok(!ret, "failed to connect, error %u\n", WSAGetLastError());
5481 select_events(ctx, listener, FD_CONNECT | FD_READ | FD_OOB | FD_ACCEPT | FD_WRITE);
5482 check_events(ctx, FD_ACCEPT, 0, 200);
5484 server = accept(listener, NULL, NULL);
5485 ok(server != -1, "failed to accept, error %u\n", WSAGetLastError());
5486 ctx->socket = server;
5487 check_events(ctx, FD_WRITE, 0, 200);
5488 check_events(ctx, 0, 0, 0);
5490 closesocket(server);
5491 closesocket(client);
5493 closesocket(listener);
5496 static void test_connect_events(struct event_test_ctx *ctx)
5498 const struct sockaddr_in addr = {.sin_family = AF_INET, .sin_addr.s_addr = htonl(INADDR_LOOPBACK)};
5499 SOCKET listener, server, client;
5500 struct sockaddr_in destaddr;
5501 int len, ret;
5503 listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
5504 ok(listener != -1, "failed to create socket, error %u\n", WSAGetLastError());
5505 ret = bind(listener, (const struct sockaddr *)&addr, sizeof(addr));
5506 ok(!ret, "failed to bind, error %u\n", WSAGetLastError());
5507 len = sizeof(destaddr);
5508 ret = getsockname(listener, (struct sockaddr *)&destaddr, &len);
5509 ok(!ret, "failed to get address, error %u\n", WSAGetLastError());
5510 ret = listen(listener, 2);
5511 ok(!ret, "failed to listen, error %u\n", WSAGetLastError());
5513 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
5514 ok(client != -1, "failed to create socket, error %u\n", WSAGetLastError());
5516 select_events(ctx, client, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ | FD_WRITE);
5517 check_events(ctx, 0, 0, 0);
5519 ret = connect(client, (struct sockaddr *)&destaddr, sizeof(destaddr));
5520 ok(!ret || WSAGetLastError() == WSAEWOULDBLOCK, "failed to connect, error %u\n", WSAGetLastError());
5522 check_events(ctx, FD_CONNECT, FD_WRITE, 200);
5523 check_events(ctx, 0, 0, 0);
5524 select_events(ctx, client, 0);
5525 select_events(ctx, client, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ | FD_WRITE);
5526 if (ctx->is_message)
5527 check_events(ctx, FD_WRITE, 0, 200);
5528 check_events(ctx, 0, 0, 0);
5530 server = accept(listener, NULL, NULL);
5531 ok(server != -1, "failed to accept, error %u\n", WSAGetLastError());
5533 closesocket(client);
5534 closesocket(server);
5536 /* Connect and then select. */
5538 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
5539 ok(client != -1, "failed to create socket, error %u\n", WSAGetLastError());
5541 ret = connect(client, (struct sockaddr *)&destaddr, sizeof(destaddr));
5542 ok(!ret, "failed to connect, error %u\n", WSAGetLastError());
5544 server = accept(listener, NULL, NULL);
5545 ok(server != -1, "failed to accept, error %u\n", WSAGetLastError());
5547 ret = send(client, "data", 5, 0);
5548 ok(ret == 5, "got %d\n", ret);
5550 select_events(ctx, client, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ | FD_WRITE);
5551 if (ctx->is_message)
5552 check_events(ctx, FD_WRITE, 0, 200);
5553 else
5554 check_events(ctx, FD_CONNECT, FD_WRITE, 200);
5556 closesocket(client);
5557 closesocket(server);
5559 /* As above, but select on a subset not containing FD_CONNECT first. */
5561 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
5562 ok(client != -1, "failed to create socket, error %u\n", WSAGetLastError());
5564 select_events(ctx, client, FD_ACCEPT | FD_CLOSE | FD_OOB | FD_READ | FD_WRITE);
5566 ret = connect(client, (struct sockaddr *)&destaddr, sizeof(destaddr));
5567 ok(!ret || WSAGetLastError() == WSAEWOULDBLOCK, "failed to connect, error %u\n", WSAGetLastError());
5569 server = accept(listener, NULL, NULL);
5570 ok(server != -1, "failed to accept, error %u\n", WSAGetLastError());
5572 check_events(ctx, FD_WRITE, 0, 200);
5574 select_events(ctx, client, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ | FD_WRITE);
5576 if (ctx->is_message)
5577 check_events(ctx, FD_WRITE, 0, 200);
5578 else
5579 check_events_todo(ctx, FD_CONNECT, 0, 200);
5581 closesocket(client);
5582 closesocket(server);
5584 closesocket(listener);
5587 /* perform a blocking recv() even on a nonblocking socket */
5588 static int sync_recv(SOCKET s, void *buffer, int len, DWORD flags)
5590 OVERLAPPED overlapped = {0};
5591 WSABUF wsabuf;
5592 DWORD ret_len;
5593 int ret;
5595 overlapped.hEvent = CreateEventA(NULL, TRUE, FALSE, NULL);
5596 wsabuf.buf = buffer;
5597 wsabuf.len = len;
5598 ret = WSARecv(s, &wsabuf, 1, &ret_len, &flags, &overlapped, NULL);
5599 if (ret == -1 && WSAGetLastError() == ERROR_IO_PENDING)
5601 ret = WaitForSingleObject(overlapped.hEvent, 1000);
5602 ok(!ret, "wait timed out\n");
5603 ret = WSAGetOverlappedResult(s, &overlapped, &ret_len, FALSE, &flags);
5604 ret = (ret ? 0 : -1);
5606 CloseHandle(overlapped.hEvent);
5607 if (!ret) return ret_len;
5608 return -1;
5611 static void test_write_events(struct event_test_ctx *ctx)
5613 static const int buffer_size = 1024 * 1024;
5614 SOCKET server, client;
5615 char *buffer;
5616 int ret;
5618 buffer = malloc(buffer_size);
5620 tcp_socketpair(&client, &server);
5621 set_blocking(client, FALSE);
5623 select_events(ctx, server, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ | FD_WRITE);
5624 check_events(ctx, FD_WRITE, 0, 200);
5625 check_events(ctx, 0, 0, 0);
5626 select_events(ctx, server, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ | FD_WRITE);
5627 if (ctx->is_message)
5628 check_events(ctx, FD_WRITE, 0, 200);
5629 check_events(ctx, 0, 0, 0);
5630 select_events(ctx, server, 0);
5631 select_events(ctx, server, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ | FD_WRITE);
5632 if (ctx->is_message)
5633 check_events(ctx, FD_WRITE, 0, 200);
5634 check_events(ctx, 0, 0, 0);
5636 ret = send(server, "data", 5, 0);
5637 ok(ret == 5, "got %d\n", ret);
5639 check_events(ctx, 0, 0, 0);
5641 ret = sync_recv(client, buffer, buffer_size, 0);
5642 ok(ret == 5, "got %d\n", ret);
5644 check_events(ctx, 0, 0, 0);
5646 if (!broken(1))
5648 while ((ret = send(server, buffer, buffer_size, 0)) == buffer_size);
5649 /* Windows will never send less than buffer_size bytes here, but Linux
5650 * may do a short write. */
5651 todo_wine_if (ret > 0)
5653 ok(ret == -1, "got %d\n", ret);
5654 ok(WSAGetLastError() == WSAEWOULDBLOCK, "got error %u\n", WSAGetLastError());
5657 while (recv(client, buffer, buffer_size, 0) > 0);
5658 ok(WSAGetLastError() == WSAEWOULDBLOCK, "got error %u\n", WSAGetLastError());
5660 /* Broken on Windows versions older than win10v1607 (though sometimes
5661 * works regardless, for unclear reasons. */
5662 check_events(ctx, FD_WRITE, 0, 200);
5663 check_events(ctx, 0, 0, 0);
5664 select_events(ctx, server, 0);
5665 select_events(ctx, server, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ | FD_WRITE);
5666 if (ctx->is_message)
5667 check_events(ctx, FD_WRITE, 0, 200);
5668 check_events(ctx, 0, 0, 0);
5671 closesocket(server);
5672 closesocket(client);
5674 /* Despite the documentation, and unlike FD_ACCEPT and FD_RECV, calling
5675 * send() doesn't clear the FD_WRITE bit. */
5677 tcp_socketpair(&client, &server);
5679 select_events(ctx, server, FD_ACCEPT | FD_CONNECT | FD_OOB | FD_READ | FD_WRITE);
5681 ret = send(server, "data", 5, 0);
5682 ok(ret == 5, "got %d\n", ret);
5684 check_events(ctx, FD_WRITE, 0, 200);
5686 closesocket(server);
5687 closesocket(client);
5689 free(buffer);
5692 static void test_read_events(struct event_test_ctx *ctx)
5694 SOCKET server, client;
5695 unsigned int i;
5696 char buffer[8];
5697 int ret;
5699 tcp_socketpair(&client, &server);
5700 set_blocking(client, FALSE);
5702 select_events(ctx, server, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ);
5703 check_events(ctx, 0, 0, 0);
5705 ret = send(client, "data", 5, 0);
5706 ok(ret == 5, "got %d\n", ret);
5708 check_events(ctx, FD_READ, 0, 200);
5709 check_events(ctx, 0, 0, 0);
5710 select_events(ctx, server, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ);
5711 if (ctx->is_message)
5712 check_events(ctx, FD_READ, 0, 200);
5713 check_events(ctx, 0, 0, 0);
5714 select_events(ctx, server, 0);
5715 select_events(ctx, server, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ);
5716 if (ctx->is_message)
5717 check_events(ctx, FD_READ, 0, 200);
5718 check_events(ctx, 0, 0, 0);
5720 ret = send(client, "data", 5, 0);
5721 ok(ret == 5, "got %d\n", ret);
5723 if (!ctx->is_message)
5724 check_events_todo(ctx, FD_READ, 0, 200);
5725 check_events(ctx, 0, 0, 0);
5727 ret = recv(server, buffer, 2, 0);
5728 ok(ret == 2, "got %d\n", ret);
5730 check_events(ctx, FD_READ, 0, 200);
5731 check_events(ctx, 0, 0, 0);
5733 ret = recv(server, buffer, -1, 0);
5734 ok(ret == -1, "got %d\n", ret);
5735 ok(WSAGetLastError() == WSAEFAULT || WSAGetLastError() == WSAENOBUFS /* < Windows 7 */,
5736 "got error %u\n", WSAGetLastError());
5738 if (ctx->is_message)
5739 check_events_todo_msg(ctx, FD_READ, 0, 200);
5740 check_events(ctx, 0, 0, 0);
5742 for (i = 0; i < 8; ++i)
5744 ret = sync_recv(server, buffer, 1, 0);
5745 ok(ret == 1, "got %d\n", ret);
5747 if (i < 7)
5748 check_events(ctx, FD_READ, 0, 200);
5749 check_events(ctx, 0, 0, 0);
5752 /* Send data while we're not selecting. */
5754 select_events(ctx, server, 0);
5755 ret = send(client, "data", 5, 0);
5756 ok(ret == 5, "got %d\n", ret);
5757 select_events(ctx, server, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ);
5759 check_events(ctx, FD_READ, 0, 200);
5761 ret = recv(server, buffer, 5, 0);
5762 ok(ret == 5, "got %d\n", ret);
5764 select_events(ctx, server, 0);
5765 ret = send(client, "data", 5, 0);
5766 ok(ret == 5, "got %d\n", ret);
5767 ret = sync_recv(server, buffer, 5, 0);
5768 ok(ret == 5, "got %d\n", ret);
5769 select_events(ctx, server, FD_ACCEPT | FD_CONNECT | FD_OOB | FD_READ);
5771 check_events(ctx, 0, 0, 200);
5773 closesocket(server);
5774 closesocket(client);
5777 static void test_oob_events(struct event_test_ctx *ctx)
5779 SOCKET server, client;
5780 char buffer[1];
5781 int ret;
5783 tcp_socketpair(&client, &server);
5784 set_blocking(client, FALSE);
5786 select_events(ctx, server, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ);
5787 check_events(ctx, 0, 0, 0);
5789 ret = send(client, "a", 1, MSG_OOB);
5790 ok(ret == 1, "got %d\n", ret);
5792 check_events(ctx, FD_OOB, 0, 200);
5793 check_events(ctx, 0, 0, 0);
5794 select_events(ctx, server, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ);
5795 if (ctx->is_message)
5796 check_events(ctx, FD_OOB, 0, 200);
5797 check_events(ctx, 0, 0, 0);
5798 select_events(ctx, server, 0);
5799 select_events(ctx, server, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ);
5800 if (ctx->is_message)
5801 check_events(ctx, FD_OOB, 0, 200);
5802 check_events(ctx, 0, 0, 0);
5804 ret = send(client, "b", 1, MSG_OOB);
5805 ok(ret == 1, "got %d\n", ret);
5807 if (!ctx->is_message)
5808 check_events_todo_event(ctx, FD_OOB, 0, 200);
5809 check_events(ctx, 0, 0, 0);
5811 ret = recv(server, buffer, 1, MSG_OOB);
5812 ok(ret == 1, "got %d\n", ret);
5814 check_events_todo(ctx, FD_OOB, 0, 200);
5815 check_events(ctx, 0, 0, 0);
5817 ret = recv(server, buffer, 1, MSG_OOB);
5818 todo_wine ok(ret == 1, "got %d\n", ret);
5820 check_events(ctx, 0, 0, 0);
5822 /* Send data while we're not selecting. */
5824 select_events(ctx, server, 0);
5825 ret = send(client, "a", 1, MSG_OOB);
5826 ok(ret == 1, "got %d\n", ret);
5827 select_events(ctx, server, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ);
5829 check_events(ctx, FD_OOB, 0, 200);
5831 ret = recv(server, buffer, 1, MSG_OOB);
5832 ok(ret == 1, "got %d\n", ret);
5834 closesocket(server);
5835 closesocket(client);
5838 static void test_close_events(struct event_test_ctx *ctx)
5840 SOCKET server, client;
5841 char buffer[5];
5842 int ret;
5844 /* Test closesocket(). */
5846 tcp_socketpair(&client, &server);
5848 select_events(ctx, server, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ);
5850 closesocket(client);
5852 check_events(ctx, FD_CLOSE, 0, 200);
5853 check_events(ctx, 0, 0, 0);
5854 select_events(ctx, server, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ);
5855 if (ctx->is_message)
5856 check_events(ctx, FD_CLOSE, 0, 200);
5857 check_events(ctx, 0, 0, 0);
5858 select_events(ctx, server, 0);
5859 select_events(ctx, server, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ);
5860 if (ctx->is_message)
5861 check_events(ctx, FD_CLOSE, 0, 200);
5862 check_events(ctx, 0, 0, 0);
5864 ret = recv(server, buffer, 5, 0);
5865 ok(!ret, "got %d\n", ret);
5867 check_events(ctx, 0, 0, 0);
5869 closesocket(server);
5871 /* Test shutdown(remote end, SD_SEND). */
5873 tcp_socketpair(&client, &server);
5875 select_events(ctx, server, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ);
5877 shutdown(client, SD_SEND);
5879 check_events(ctx, FD_CLOSE, 0, 200);
5880 check_events(ctx, 0, 0, 0);
5882 closesocket(client);
5884 check_events(ctx, 0, 0, 0);
5886 closesocket(server);
5888 /* No other shutdown() call generates an event. */
5890 tcp_socketpair(&client, &server);
5892 select_events(ctx, server, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ);
5894 shutdown(client, SD_RECEIVE);
5895 shutdown(server, SD_BOTH);
5897 check_events(ctx, 0, 0, 200);
5899 shutdown(client, SD_SEND);
5901 check_events_todo(ctx, FD_CLOSE, 0, 200);
5902 check_events(ctx, 0, 0, 0);
5904 closesocket(server);
5905 closesocket(client);
5907 /* Test sending data before calling closesocket(). */
5909 tcp_socketpair(&client, &server);
5911 select_events(ctx, server, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ);
5913 ret = send(client, "data", 5, 0);
5914 ok(ret == 5, "got %d\n", ret);
5916 check_events(ctx, FD_READ, 0, 200);
5918 closesocket(client);
5920 check_events_todo(ctx, FD_CLOSE, 0, 200);
5922 ret = recv(server, buffer, 3, 0);
5923 ok(ret == 3, "got %d\n", ret);
5925 check_events(ctx, FD_READ, 0, 200);
5927 ret = recv(server, buffer, 5, 0);
5928 ok(ret == 2, "got %d\n", ret);
5930 check_events_todo(ctx, 0, 0, 0);
5932 closesocket(server);
5934 /* Close and then select. */
5936 tcp_socketpair(&client, &server);
5937 closesocket(client);
5939 select_events(ctx, server, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ);
5940 check_events(ctx, FD_CLOSE, 0, 200);
5942 closesocket(server);
5944 /* As above, but select on a subset not containing FD_CLOSE first. */
5946 tcp_socketpair(&client, &server);
5948 select_events(ctx, server, FD_ACCEPT | FD_CONNECT | FD_OOB | FD_READ);
5950 closesocket(client);
5952 check_events(ctx, 0, 0, 200);
5953 select_events(ctx, server, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ);
5954 check_events_todo_event(ctx, FD_CLOSE, 0, 200);
5956 closesocket(server);
5959 static void test_events(void)
5961 struct event_test_ctx ctx;
5963 ctx.is_message = FALSE;
5964 ctx.event = CreateEventW(NULL, TRUE, FALSE, NULL);
5966 test_accept_events(&ctx);
5967 test_connect_events(&ctx);
5968 test_write_events(&ctx);
5969 test_read_events(&ctx);
5970 test_close_events(&ctx);
5971 test_oob_events(&ctx);
5973 CloseHandle(ctx.event);
5975 ctx.is_message = TRUE;
5976 ctx.window = CreateWindowA("Message", NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL);
5978 test_accept_events(&ctx);
5979 test_connect_events(&ctx);
5980 test_write_events(&ctx);
5981 test_read_events(&ctx);
5982 test_close_events(&ctx);
5983 test_oob_events(&ctx);
5985 DestroyWindow(ctx.window);
5988 static void test_ipv6only(void)
5990 SOCKET v4 = INVALID_SOCKET, v6;
5991 struct sockaddr_in sin4;
5992 struct sockaddr_in6 sin6;
5993 int ret, enabled, len = sizeof(enabled);
5995 memset(&sin4, 0, sizeof(sin4));
5996 sin4.sin_family = AF_INET;
5997 sin4.sin_port = htons(SERVERPORT);
5999 memset(&sin6, 0, sizeof(sin6));
6000 sin6.sin6_family = AF_INET6;
6001 sin6.sin6_port = htons(SERVERPORT);
6003 v6 = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
6004 if (v6 == INVALID_SOCKET)
6006 skip("Could not create IPv6 socket (LastError: %d)\n", WSAGetLastError());
6007 goto end;
6010 enabled = 2;
6011 ret = getsockopt(v6, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&enabled, &len);
6012 ok(!ret, "getsockopt(IPV6_V6ONLY) failed (LastError: %d)\n", WSAGetLastError());
6013 ok(enabled == 1, "expected 1, got %d\n", enabled);
6015 ret = bind(v6, (struct sockaddr*)&sin6, sizeof(sin6));
6016 ok(!ret, "failed to bind, error %u\n", WSAGetLastError());
6018 v4 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
6019 ok(v4 != INVALID_SOCKET, "Could not create IPv4 socket (LastError: %d)\n", WSAGetLastError());
6021 todo_wine {
6022 enabled = 2;
6023 ret = getsockopt(v4, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&enabled, &len);
6024 ok(!ret, "getsockopt(IPV6_V6ONLY) failed (LastError: %d)\n", WSAGetLastError());
6025 ok(enabled == 1, "expected 1, got %d\n", enabled);
6028 enabled = 0;
6029 len = sizeof(enabled);
6030 ret = setsockopt(v4, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&enabled, len);
6031 ok(!ret, "setsockopt(IPV6_V6ONLY) failed (LastError: %d)\n", WSAGetLastError());
6033 todo_wine {
6034 enabled = 2;
6035 ret = getsockopt(v4, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&enabled, &len);
6036 ok(!ret, "getsockopt(IPV6_V6ONLY) failed (LastError: %d)\n", WSAGetLastError());
6037 ok(!enabled, "expected 0, got %d\n", enabled);
6040 enabled = 1;
6041 len = sizeof(enabled);
6042 ret = setsockopt(v4, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&enabled, len);
6043 ok(!ret, "setsockopt(IPV6_V6ONLY) failed (LastError: %d)\n", WSAGetLastError());
6045 /* bind on IPv4 socket should succeed - IPV6_V6ONLY is enabled by default */
6046 ret = bind(v4, (struct sockaddr*)&sin4, sizeof(sin4));
6047 ok(!ret, "Could not bind IPv4 address (LastError: %d)\n", WSAGetLastError());
6049 todo_wine {
6050 enabled = 2;
6051 ret = getsockopt(v4, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&enabled, &len);
6052 ok(!ret, "getsockopt(IPV6_V6ONLY) failed (LastError: %d)\n", WSAGetLastError());
6053 ok(enabled == 1, "expected 1, got %d\n", enabled);
6056 enabled = 0;
6057 len = sizeof(enabled);
6058 ret = setsockopt(v4, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&enabled, len);
6059 ok(ret, "setsockopt(IPV6_V6ONLY) succeeded (LastError: %d)\n", WSAGetLastError());
6061 todo_wine {
6062 enabled = 0;
6063 ret = getsockopt(v4, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&enabled, &len);
6064 ok(!ret, "getsockopt(IPV6_V6ONLY) failed (LastError: %d)\n", WSAGetLastError());
6065 ok(enabled == 1, "expected 1, got %d\n", enabled);
6068 enabled = 1;
6069 len = sizeof(enabled);
6070 ret = setsockopt(v4, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&enabled, len);
6071 ok(ret, "setsockopt(IPV6_V6ONLY) succeeded (LastError: %d)\n", WSAGetLastError());
6073 closesocket(v4);
6074 closesocket(v6);
6076 /* Test again, this time disabling IPV6_V6ONLY. */
6077 sin4.sin_port = htons(SERVERPORT+2);
6078 sin6.sin6_port = htons(SERVERPORT+2);
6080 v6 = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
6081 ok(v6 != INVALID_SOCKET, "Could not create IPv6 socket (LastError: %d; %d expected if IPv6 not available).\n",
6082 WSAGetLastError(), WSAEAFNOSUPPORT);
6084 enabled = 0;
6085 ret = setsockopt(v6, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&enabled, len);
6086 ok(!ret, "Could not disable IPV6_V6ONLY (LastError: %d).\n", WSAGetLastError());
6088 enabled = 2;
6089 ret = getsockopt(v6, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&enabled, &len);
6090 ok(!ret, "getsockopt(IPV6_V6ONLY) failed (LastError: %d)\n", WSAGetLastError());
6091 ok(!enabled, "expected 0, got %d\n", enabled);
6094 Observaition:
6095 On Windows, bind on both IPv4 and IPv6 with IPV6_V6ONLY disabled succeeds by default.
6096 Application must set SO_EXCLUSIVEADDRUSE on first socket to disallow another successful bind.
6097 In general, a standard application should not use SO_REUSEADDR.
6098 Setting both SO_EXCLUSIVEADDRUSE and SO_REUSEADDR on the same socket is not possible in
6099 either order, the later setsockopt call always fails.
6101 enabled = 1;
6102 ret = setsockopt(v6, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (char*)&enabled, len);
6103 ok(!ret, "Could not set SO_EXCLUSIVEADDRUSE on IPv6 socket (LastError: %d)\n", WSAGetLastError());
6105 ret = bind(v6, (struct sockaddr*)&sin6, sizeof(sin6));
6106 ok(!ret, "Could not bind IPv6 address (LastError: %d)\n", WSAGetLastError());
6108 enabled = 2;
6109 len = sizeof(enabled);
6110 getsockopt(v6, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&enabled, &len);
6111 ok(!ret, "getsockopt(IPV6_V6ONLY) failed (LastError: %d)\n", WSAGetLastError());
6112 ok(!enabled, "IPV6_V6ONLY is enabled after bind\n");
6114 v4 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
6115 ok(v4 != INVALID_SOCKET, "Could not create IPv4 socket (LastError: %d)\n", WSAGetLastError());
6117 enabled = 1;
6118 ret = setsockopt(v4, SOL_SOCKET, SO_REUSEADDR, (char*)&enabled, len);
6119 ok(!ret, "Could not set SO_REUSEADDR on IPv4 socket (LastError: %d)\n", WSAGetLastError());
6121 WSASetLastError(0xdeadbeef);
6122 ret = bind(v4, (struct sockaddr*)&sin4, sizeof(sin4));
6123 ok(ret, "bind succeeded unexpectedly for the IPv4 socket\n");
6124 ok(WSAGetLastError() == WSAEACCES, "Expected 10013, got %d\n", WSAGetLastError());
6126 end:
6127 if (v4 != INVALID_SOCKET)
6128 closesocket(v4);
6129 if (v6 != INVALID_SOCKET)
6130 closesocket(v6);
6133 static void test_WSASendMsg(void)
6135 SOCKET sock, dst;
6136 struct sockaddr_in sendaddr, sockaddr;
6137 GUID WSASendMsg_GUID = WSAID_WSASENDMSG;
6138 LPFN_WSASENDMSG pWSASendMsg = NULL;
6139 char teststr[12] = "hello world", buffer[32];
6140 WSABUF iovec[2];
6141 WSAMSG msg;
6142 DWORD bytesSent, err;
6143 int ret, addrlen;
6145 /* FIXME: Missing OVERLAPPED and OVERLAPPED COMPLETION ROUTINE tests */
6147 sock = socket(AF_INET, SOCK_DGRAM, 0);
6148 ok(sock != INVALID_SOCKET, "socket() failed\n");
6150 /* Obtain the WSASendMsg function */
6151 WSAIoctl(sock, SIO_GET_EXTENSION_FUNCTION_POINTER, &WSASendMsg_GUID, sizeof(WSASendMsg_GUID),
6152 &pWSASendMsg, sizeof(pWSASendMsg), &err, NULL, NULL);
6153 if (!pWSASendMsg)
6155 closesocket(sock);
6156 win_skip("WSASendMsg is unsupported, some tests will be skipped.\n");
6157 return;
6160 /* fake address for now */
6161 sendaddr.sin_family = AF_INET;
6162 sendaddr.sin_port = htons(139);
6163 sendaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
6165 memset(&msg, 0, sizeof(msg));
6166 iovec[0].buf = teststr;
6167 iovec[0].len = sizeof(teststr);
6168 iovec[1].buf = teststr;
6169 iovec[1].len = sizeof(teststr) / 2;
6170 msg.name = (struct sockaddr *) &sendaddr;
6171 msg.namelen = sizeof(sendaddr);
6172 msg.lpBuffers = iovec;
6173 msg.dwBufferCount = 1; /* send only one buffer for now */
6175 WSASetLastError(0xdeadbeef);
6176 ret = pWSASendMsg(INVALID_SOCKET, &msg, 0, NULL, NULL, NULL);
6177 ok(ret == SOCKET_ERROR, "WSASendMsg should have failed\n");
6178 err = WSAGetLastError();
6179 ok(err == WSAENOTSOCK, "expected 10038, got %d instead\n", err);
6181 WSASetLastError(0xdeadbeef);
6182 ret = pWSASendMsg(sock, NULL, 0, NULL, NULL, NULL);
6183 ok(ret == SOCKET_ERROR, "WSASendMsg should have failed\n");
6184 err = WSAGetLastError();
6185 ok(err == WSAEFAULT, "expected 10014, got %d instead\n", err);
6187 WSASetLastError(0xdeadbeef);
6188 ret = pWSASendMsg(sock, NULL, 0, &bytesSent, NULL, NULL);
6189 ok(ret == SOCKET_ERROR, "WSASendMsg should have failed\n");
6190 err = WSAGetLastError();
6191 ok(err == WSAEFAULT, "expected 10014, got %d instead\n", err);
6193 WSASetLastError(0xdeadbeef);
6194 ret = pWSASendMsg(sock, &msg, 0, NULL, NULL, NULL);
6195 ok(ret == SOCKET_ERROR, "WSASendMsg should have failed\n");
6196 err = WSAGetLastError();
6197 ok(err == WSAEFAULT, "expected 10014, got %d instead\n", err);
6199 closesocket(sock);
6201 sock = socket(AF_INET, SOCK_DGRAM, 0);
6202 ok(sock != INVALID_SOCKET, "socket() failed\n");
6204 dst = socket(AF_INET, SOCK_DGRAM, 0);
6205 ok(dst != INVALID_SOCKET, "socket() failed\n");
6207 memset(&sockaddr, 0, sizeof(sockaddr));
6208 sockaddr.sin_family = AF_INET;
6209 sockaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
6210 ok(!bind(dst, (struct sockaddr*)&sockaddr, sizeof(sockaddr)),
6211 "bind should have worked\n");
6213 /* read address to find out the port number to be used in send */
6214 memset(&sendaddr, 0, sizeof(sendaddr));
6215 addrlen = sizeof(sendaddr);
6216 ok(!getsockname(dst, (struct sockaddr *) &sendaddr, &addrlen),
6217 "getsockname should have worked\n");
6218 ok(sendaddr.sin_port, "socket port should be != 0\n");
6220 /* ensure the sending socket is not bound */
6221 WSASetLastError(0xdeadbeef);
6222 addrlen = sizeof(sockaddr);
6223 ret = getsockname(sock, (struct sockaddr*)&sockaddr, &addrlen);
6224 ok(ret == SOCKET_ERROR, "getsockname should have failed\n");
6225 err = WSAGetLastError();
6226 ok(err == WSAEINVAL, "expected 10022, got %d instead\n", err);
6228 set_blocking(sock, TRUE);
6230 bytesSent = 0;
6231 SetLastError(0xdeadbeef);
6232 ret = pWSASendMsg(sock, &msg, 0, &bytesSent, NULL, NULL);
6233 ok(!ret, "WSASendMsg should have worked\n");
6234 ok(GetLastError() == 0 || broken(GetLastError() == 0xdeadbeef) /* Win <= 2008 */,
6235 "Expected 0, got %d\n", GetLastError());
6236 ok(bytesSent == iovec[0].len, "incorrect bytes sent, expected %d, sent %d\n",
6237 iovec[0].len, bytesSent);
6239 /* receive data */
6240 addrlen = sizeof(sockaddr);
6241 memset(buffer, 0, sizeof(buffer));
6242 SetLastError(0xdeadbeef);
6243 ret = recvfrom(dst, buffer, sizeof(buffer), 0, (struct sockaddr *) &sockaddr, &addrlen);
6244 ok(ret == bytesSent, "got %d, expected %d\n",
6245 ret, bytesSent);
6246 ok(GetLastError() == ERROR_SUCCESS, "Expected 0, got %d\n", GetLastError());
6248 /* A successful call to WSASendMsg must have bound the socket */
6249 addrlen = sizeof(sockaddr);
6250 sockaddr.sin_port = 0;
6251 sockaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
6252 ret = getsockname(sock, (struct sockaddr*)&sockaddr, &addrlen);
6253 ok(!ret, "getsockname should have worked\n");
6254 ok(sockaddr.sin_addr.s_addr == htonl(INADDR_ANY), "expected 0.0.0.0, got %s\n",
6255 inet_ntoa(sockaddr.sin_addr));
6256 ok(sockaddr.sin_port, "sin_port should be != 0\n");
6258 msg.dwBufferCount = 2; /* send both buffers */
6260 bytesSent = 0;
6261 SetLastError(0xdeadbeef);
6262 ret = pWSASendMsg(sock, &msg, 0, &bytesSent, NULL, NULL);
6263 ok(!ret, "WSASendMsg should have worked\n");
6264 ok(bytesSent == iovec[0].len + iovec[1].len, "incorrect bytes sent, expected %d, sent %d\n",
6265 iovec[0].len + iovec[1].len, bytesSent);
6266 ok(GetLastError() == 0 || broken(GetLastError() == 0xdeadbeef) /* Win <= 2008 */,
6267 "Expected 0, got %d\n", GetLastError());
6269 /* receive data */
6270 addrlen = sizeof(sockaddr);
6271 memset(buffer, 0, sizeof(buffer));
6272 SetLastError(0xdeadbeef);
6273 ret = recvfrom(dst, buffer, sizeof(buffer), 0, (struct sockaddr *) &sockaddr, &addrlen);
6274 ok(ret == bytesSent, "got %d, expected %d\n",
6275 ret, bytesSent);
6276 ok(GetLastError() == ERROR_SUCCESS, "Expected 0, got %d\n", GetLastError());
6278 closesocket(sock);
6279 closesocket(dst);
6281 /* a bad call to WSASendMsg will also bind the socket */
6282 addrlen = sizeof(sockaddr);
6283 sockaddr.sin_port = 0;
6284 sockaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
6285 sock = socket(AF_INET, SOCK_DGRAM, 0);
6286 ok(sock != INVALID_SOCKET, "socket() failed\n");
6287 ok(pWSASendMsg(sock, &msg, 0, NULL, NULL, NULL) == SOCKET_ERROR, "WSASendMsg should have failed\n");
6288 todo_wine {
6289 ok(!getsockname(sock, (struct sockaddr*)&sockaddr, &addrlen), "getsockname should have worked\n");
6290 ok(sockaddr.sin_addr.s_addr == htonl(INADDR_ANY), "expected 0.0.0.0, got %s\n",
6291 inet_ntoa(sockaddr.sin_addr));
6292 ok(sockaddr.sin_port, "sin_port should be > 0\n");
6294 closesocket(sock);
6296 /* a bad call without msg parameter will not trigger the auto-bind */
6297 sock = socket(AF_INET, SOCK_DGRAM, 0);
6298 ok(sock != INVALID_SOCKET, "socket() failed\n");
6299 ok(pWSASendMsg(sock, NULL, 0, NULL, NULL, NULL) == SOCKET_ERROR, "WSASendMsg should have failed\n");
6300 ok(getsockname(sock, (struct sockaddr*)&sockaddr, &addrlen), "getsockname should have failed\n");
6301 err = WSAGetLastError();
6302 ok(err == WSAEINVAL, "expected 10022, got %d instead\n", err);
6303 closesocket(sock);
6305 /* SOCK_STREAM sockets are not supported */
6306 bytesSent = 0;
6307 sock = socket(AF_INET, SOCK_STREAM, 0);
6308 ok(sock != INVALID_SOCKET, "socket() failed\n");
6309 SetLastError(0xdeadbeef);
6310 ret = pWSASendMsg(sock, &msg, 0, &bytesSent, NULL, NULL);
6311 ok(ret == SOCKET_ERROR, "WSASendMsg should have failed\n");
6312 err = WSAGetLastError();
6313 todo_wine
6314 ok(err == WSAEINVAL, "expected 10014, got %d instead\n", err);
6315 closesocket(sock);
6318 static void test_WSASendTo(void)
6320 SOCKET s;
6321 struct sockaddr_in addr, ret_addr;
6322 char buf[12] = "hello world";
6323 WSABUF data_buf;
6324 DWORD bytesSent;
6325 int ret, len;
6327 addr.sin_family = AF_INET;
6328 addr.sin_port = htons(139);
6329 addr.sin_addr.s_addr = inet_addr("127.0.0.1");
6330 data_buf.len = sizeof(buf);
6331 data_buf.buf = buf;
6333 s = socket(AF_INET, SOCK_DGRAM, 0);
6334 ok(s != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
6336 WSASetLastError(12345);
6337 ret = WSASendTo(INVALID_SOCKET, &data_buf, 1, NULL, 0, (struct sockaddr*)&addr, sizeof(addr), NULL, NULL);
6338 ok(ret == SOCKET_ERROR && WSAGetLastError() == WSAENOTSOCK,
6339 "WSASendTo() failed: %d/%d\n", ret, WSAGetLastError());
6341 len = sizeof(ret_addr);
6342 ret = getsockname(s, (struct sockaddr *)&ret_addr, &len);
6343 ok(ret == -1, "expected failure\n");
6344 ok(WSAGetLastError() == WSAEINVAL, "got error %u\n", WSAGetLastError());
6346 WSASetLastError(12345);
6347 ret = WSASendTo(s, &data_buf, 1, NULL, 0, (struct sockaddr*)&addr, sizeof(addr), NULL, NULL);
6348 ok(ret == SOCKET_ERROR && WSAGetLastError() == WSAEFAULT,
6349 "WSASendTo() failed: %d/%d\n", ret, WSAGetLastError());
6351 WSASetLastError(12345);
6352 ret = WSASendTo(s, &data_buf, 1, &bytesSent, 0, (struct sockaddr *)&addr, sizeof(addr), NULL, NULL);
6353 ok(!ret, "expected success\n");
6354 ok(!WSAGetLastError(), "got error %u\n", WSAGetLastError());
6356 len = sizeof(ret_addr);
6357 ret = getsockname(s, (struct sockaddr *)&ret_addr, &len);
6358 ok(!ret, "got error %u\n", WSAGetLastError());
6359 ok(ret_addr.sin_family == AF_INET, "got family %u\n", ret_addr.sin_family);
6360 ok(ret_addr.sin_port, "expected nonzero port\n");
6363 static DWORD WINAPI recv_thread(LPVOID arg)
6365 SOCKET sock = *(SOCKET *)arg;
6366 char buffer[32];
6367 WSABUF wsa;
6368 WSAOVERLAPPED ov;
6369 DWORD flags = 0;
6371 wsa.buf = buffer;
6372 wsa.len = sizeof(buffer);
6373 ov.hEvent = WSACreateEvent();
6374 WSARecv(sock, &wsa, 1, NULL, &flags, &ov, NULL);
6376 WaitForSingleObject(ov.hEvent, 1000);
6377 WSACloseEvent(ov.hEvent);
6378 return 0;
6381 static int completion_called;
6383 static void WINAPI io_completion(DWORD error, DWORD transferred, WSAOVERLAPPED *overlapped, DWORD flags)
6385 completion_called++;
6388 static void test_WSARecv(void)
6390 SOCKET src, dest, server = INVALID_SOCKET;
6391 char buf[20];
6392 WSABUF bufs[2];
6393 WSAOVERLAPPED ov;
6394 DWORD bytesReturned, flags, id;
6395 struct linger ling;
6396 struct sockaddr_in addr;
6397 int iret, len;
6398 DWORD dwret;
6399 BOOL bret;
6400 HANDLE thread, event = NULL, io_port;
6402 tcp_socketpair(&src, &dest);
6404 memset(&ov, 0, sizeof(ov));
6405 flags = 0;
6406 bufs[0].len = 2;
6407 bufs[0].buf = buf;
6409 /* Send 4 bytes and receive in two calls of 2 */
6410 SetLastError(0xdeadbeef);
6411 iret = send(src, "test", 4, 0);
6412 ok(iret == 4, "Expected 4, got %d\n", iret);
6413 ok(GetLastError() == ERROR_SUCCESS, "Expected 0, got %d\n", GetLastError());
6414 SetLastError(0xdeadbeef);
6415 bytesReturned = 0xdeadbeef;
6416 iret = WSARecv(dest, bufs, 1, &bytesReturned, &flags, NULL, NULL);
6417 ok(!iret, "Expected 0, got %d\n", iret);
6418 ok(bytesReturned == 2, "Expected 2, got %d\n", bytesReturned);
6419 ok(GetLastError() == ERROR_SUCCESS, "Expected 0, got %d\n", GetLastError());
6420 SetLastError(0xdeadbeef);
6421 bytesReturned = 0xdeadbeef;
6422 iret = WSARecv(dest, bufs, 1, &bytesReturned, &flags, NULL, NULL);
6423 ok(!iret, "Expected 0, got %d\n", iret);
6424 ok(bytesReturned == 2, "Expected 2, got %d\n", bytesReturned);
6425 ok(GetLastError() == ERROR_SUCCESS, "Expected 0, got %d\n", GetLastError());
6427 bufs[0].len = 4;
6428 SetLastError(0xdeadbeef);
6429 iret = send(src, "test", 4, 0);
6430 ok(iret == 4, "Expected 4, got %d\n", iret);
6431 ok(GetLastError() == ERROR_SUCCESS, "Expected 0, got %d\n", GetLastError());
6432 SetLastError(0xdeadbeef);
6433 bytesReturned = 0xdeadbeef;
6434 iret = WSARecv(dest, bufs, 1, &bytesReturned, &flags, NULL, NULL);
6435 ok(!iret, "Expected 0, got %d\n", iret);
6436 ok(bytesReturned == 4, "Expected 4, got %d\n", bytesReturned);
6437 ok(GetLastError() == ERROR_SUCCESS, "Expected 0, got %d\n", GetLastError());
6439 /* Test 2 buffers */
6440 bufs[0].len = 4;
6441 bufs[1].len = 5;
6442 bufs[1].buf = buf + 10;
6443 SetLastError(0xdeadbeef);
6444 iret = send(src, "deadbeefs", 9, 0);
6445 ok(iret == 9, "Expected 9, got %d\n", iret);
6446 ok(GetLastError() == ERROR_SUCCESS, "Expected 0, got %d\n", GetLastError());
6447 SetLastError(0xdeadbeef);
6448 bytesReturned = 0xdeadbeef;
6449 iret = WSARecv(dest, bufs, 2, &bytesReturned, &flags, NULL, NULL);
6450 ok(!iret, "Expected 0, got %d\n", iret);
6451 ok(bytesReturned == 9, "Expected 9, got %d\n", bytesReturned);
6452 bufs[0].buf[4] = '\0';
6453 bufs[1].buf[5] = '\0';
6454 ok(!strcmp(bufs[0].buf, "dead"), "buf[0] doesn't match: %s != dead\n", bufs[0].buf);
6455 ok(!strcmp(bufs[1].buf, "beefs"), "buf[1] doesn't match: %s != beefs\n", bufs[1].buf);
6456 ok(GetLastError() == ERROR_SUCCESS, "Expected 0, got %d\n", GetLastError());
6458 bufs[0].len = sizeof(buf);
6459 ov.hEvent = event = CreateEventA(NULL, FALSE, FALSE, NULL);
6460 ok(ov.hEvent != NULL, "could not create event object, errno = %d\n", GetLastError());
6461 if (!event)
6462 goto end;
6464 ling.l_onoff = 1;
6465 ling.l_linger = 0;
6466 iret = setsockopt (src, SOL_SOCKET, SO_LINGER, (char *) &ling, sizeof(ling));
6467 ok(!iret, "Failed to set linger %d\n", GetLastError());
6469 iret = WSARecv(dest, bufs, 1, NULL, &flags, &ov, NULL);
6470 ok(iret == SOCKET_ERROR && GetLastError() == ERROR_IO_PENDING, "WSARecv failed - %d error %d\n", iret, GetLastError());
6472 iret = WSARecv(dest, bufs, 1, &bytesReturned, &flags, &ov, NULL);
6473 ok(iret == SOCKET_ERROR && GetLastError() == ERROR_IO_PENDING, "WSARecv failed - %d error %d\n", iret, GetLastError());
6475 closesocket(src);
6476 src = INVALID_SOCKET;
6478 dwret = WaitForSingleObject(ov.hEvent, 1000);
6479 ok(dwret == WAIT_OBJECT_0, "Waiting for disconnect event failed with %d + errno %d\n", dwret, GetLastError());
6481 bret = GetOverlappedResult((HANDLE)dest, &ov, &bytesReturned, FALSE);
6482 todo_wine ok(!bret, "expected failure\n");
6483 todo_wine ok(GetLastError() == ERROR_NETNAME_DELETED, "got error %u\n", GetLastError());
6484 ok(bytesReturned == 0, "Bytes received is %d\n", bytesReturned);
6485 closesocket(dest);
6486 dest = INVALID_SOCKET;
6488 src = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0);
6489 ok(src != INVALID_SOCKET, "failed to create socket %d\n", WSAGetLastError());
6490 if (src == INVALID_SOCKET) goto end;
6492 server = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
6493 ok(server != INVALID_SOCKET, "failed to create socket %d\n", WSAGetLastError());
6494 if (server == INVALID_SOCKET) goto end;
6496 memset(&addr, 0, sizeof(addr));
6497 addr.sin_family = AF_INET;
6498 addr.sin_addr.s_addr = inet_addr("127.0.0.1");
6499 iret = bind(server, (struct sockaddr *)&addr, sizeof(addr));
6500 ok(!iret, "failed to bind, error %u\n", WSAGetLastError());
6502 len = sizeof(addr);
6503 iret = getsockname(server, (struct sockaddr *)&addr, &len);
6504 ok(!iret, "failed to get address, error %u\n", WSAGetLastError());
6506 iret = listen(server, 1);
6507 ok(!iret, "failed to listen, error %u\n", WSAGetLastError());
6509 iret = connect(src, (struct sockaddr *)&addr, sizeof(addr));
6510 ok(!iret, "failed to connect, error %u\n", WSAGetLastError());
6512 len = sizeof(addr);
6513 dest = accept(server, (struct sockaddr *)&addr, &len);
6514 ok(dest != INVALID_SOCKET, "failed to create socket %d\n", WSAGetLastError());
6515 if (dest == INVALID_SOCKET) goto end;
6517 send(src, "test message", sizeof("test message"), 0);
6518 thread = CreateThread(NULL, 0, recv_thread, &dest, 0, &id);
6519 WaitForSingleObject(thread, 3000);
6520 CloseHandle(thread);
6522 memset(&ov, 0, sizeof(ov));
6523 ov.hEvent = event;
6524 ResetEvent(event);
6525 iret = WSARecv(dest, bufs, 1, NULL, &flags, &ov, io_completion);
6526 ok(iret == SOCKET_ERROR && GetLastError() == ERROR_IO_PENDING, "WSARecv failed - %d error %d\n", iret, GetLastError());
6527 send(src, "test message", sizeof("test message"), 0);
6529 completion_called = 0;
6530 dwret = SleepEx(1000, TRUE);
6531 ok(dwret == WAIT_IO_COMPLETION, "got %u\n", dwret);
6532 ok(completion_called == 1, "completion not called\n");
6534 dwret = WaitForSingleObject(event, 1);
6535 ok(dwret == WAIT_TIMEOUT, "got %u\n", dwret);
6537 io_port = CreateIoCompletionPort( (HANDLE)dest, NULL, 0, 0 );
6538 ok(io_port != NULL, "failed to create completion port %u\n", GetLastError());
6540 /* Using completion function on socket associated with completion port is not allowed. */
6541 memset(&ov, 0, sizeof(ov));
6542 completion_called = 0;
6543 iret = WSARecv(dest, bufs, 1, NULL, &flags, &ov, io_completion);
6544 ok(iret == SOCKET_ERROR && GetLastError() == WSAEINVAL, "WSARecv failed - %d error %d\n", iret, GetLastError());
6545 ok(!completion_called, "completion called\n");
6547 CloseHandle(io_port);
6549 end:
6550 if (server != INVALID_SOCKET)
6551 closesocket(server);
6552 if (dest != INVALID_SOCKET)
6553 closesocket(dest);
6554 if (src != INVALID_SOCKET)
6555 closesocket(src);
6556 if (event)
6557 WSACloseEvent(event);
6560 struct write_watch_thread_args
6562 int func;
6563 SOCKET dest;
6564 void *base;
6565 DWORD size;
6566 const char *expect;
6569 static DWORD CALLBACK write_watch_thread( void *arg )
6571 struct write_watch_thread_args *args = arg;
6572 struct sockaddr addr;
6573 int addr_len = sizeof(addr), ret;
6574 DWORD bytes, flags = 0;
6575 WSABUF buf[1];
6577 switch (args->func)
6579 case 0:
6580 ret = recv( args->dest, args->base, args->size, 0 );
6581 ok( ret == strlen(args->expect) + 1, "wrong len %d\n", ret );
6582 ok( !strcmp( args->base, args->expect ), "wrong data\n" );
6583 break;
6584 case 1:
6585 ret = recvfrom( args->dest, args->base, args->size, 0, &addr, &addr_len );
6586 ok( ret == strlen(args->expect) + 1, "wrong len %d\n", ret );
6587 ok( !strcmp( args->base, args->expect ), "wrong data\n" );
6588 break;
6589 case 2:
6590 buf[0].len = args->size;
6591 buf[0].buf = args->base;
6592 ret = WSARecv( args->dest, buf, 1, &bytes, &flags, NULL, NULL );
6593 ok( !ret, "WSARecv failed %u\n", GetLastError() );
6594 ok( bytes == strlen(args->expect) + 1, "wrong len %d\n", bytes );
6595 ok( !strcmp( args->base, args->expect ), "wrong data\n" );
6596 break;
6597 case 3:
6598 buf[0].len = args->size;
6599 buf[0].buf = args->base;
6600 ret = WSARecvFrom( args->dest, buf, 1, &bytes, &flags, &addr, &addr_len, NULL, NULL );
6601 ok( !ret, "WSARecvFrom failed %u\n", GetLastError() );
6602 ok( bytes == strlen(args->expect) + 1, "wrong len %d\n", bytes );
6603 ok( !strcmp( args->base, args->expect ), "wrong data\n" );
6604 break;
6606 return 0;
6609 static void test_write_watch(void)
6611 SOCKET src, dest;
6612 WSABUF bufs[2];
6613 WSAOVERLAPPED ov;
6614 struct write_watch_thread_args args;
6615 DWORD bytesReturned, flags, size;
6616 struct sockaddr addr;
6617 int addr_len, ret;
6618 HANDLE thread, event;
6619 char *base;
6620 void *results[64];
6621 ULONG_PTR count;
6622 ULONG pagesize;
6623 UINT (WINAPI *pGetWriteWatch)(DWORD,LPVOID,SIZE_T,LPVOID*,ULONG_PTR*,ULONG*);
6625 pGetWriteWatch = (void *)GetProcAddress( GetModuleHandleA("kernel32.dll"), "GetWriteWatch" );
6626 if (!pGetWriteWatch)
6628 win_skip( "write watched not supported\n" );
6629 return;
6632 tcp_socketpair(&src, &dest);
6634 memset(&ov, 0, sizeof(ov));
6635 ov.hEvent = event = CreateEventA(NULL, FALSE, FALSE, NULL);
6636 ok(ov.hEvent != NULL, "could not create event object, errno = %d\n", GetLastError());
6638 flags = 0;
6640 size = 0x10000;
6641 base = VirtualAlloc( 0, size, MEM_RESERVE | MEM_COMMIT | MEM_WRITE_WATCH, PAGE_READWRITE );
6642 ok( base != NULL, "VirtualAlloc failed %u\n", GetLastError() );
6644 memset( base, 0, size );
6645 count = 64;
6646 ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize );
6647 ok( !ret, "GetWriteWatch failed %u\n", GetLastError() );
6648 ok( count == 16, "wrong count %lu\n", count );
6650 bufs[0].len = 5;
6651 bufs[0].buf = base;
6652 bufs[1].len = 0x8000;
6653 bufs[1].buf = base + 0x4000;
6655 ret = WSARecv( dest, bufs, 2, NULL, &flags, &ov, NULL);
6656 ok(ret == SOCKET_ERROR && GetLastError() == ERROR_IO_PENDING,
6657 "WSARecv failed - %d error %d\n", ret, GetLastError());
6659 count = 64;
6660 ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize );
6661 ok( !ret, "GetWriteWatch failed %u\n", GetLastError() );
6662 ok( count == 9, "wrong count %lu\n", count );
6663 ok( !base[0], "data set\n" );
6665 send(src, "test message", sizeof("test message"), 0);
6667 ret = GetOverlappedResult( (HANDLE)dest, &ov, &bytesReturned, TRUE );
6668 ok( ret, "GetOverlappedResult failed %u\n", GetLastError() );
6669 ok( bytesReturned == sizeof("test message"), "wrong size %u\n", bytesReturned );
6670 ok( !memcmp( base, "test ", 5 ), "wrong data %s\n", base );
6671 ok( !memcmp( base + 0x4000, "message", 8 ), "wrong data %s\n", base + 0x4000 );
6673 count = 64;
6674 ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize );
6675 ok( !ret, "GetWriteWatch failed %u\n", GetLastError() );
6676 ok( count == 0, "wrong count %lu\n", count );
6678 memset( base, 0, size );
6679 count = 64;
6680 ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize );
6681 ok( !ret, "GetWriteWatch failed %u\n", GetLastError() );
6682 ok( count == 16, "wrong count %lu\n", count );
6684 bufs[1].len = 0x4000;
6685 bufs[1].buf = base + 0x2000;
6686 ret = WSARecvFrom( dest, bufs, 2, NULL, &flags, &addr, &addr_len, &ov, NULL);
6687 ok(ret == SOCKET_ERROR && GetLastError() == ERROR_IO_PENDING,
6688 "WSARecv failed - %d error %d\n", ret, GetLastError());
6690 count = 64;
6691 ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize );
6692 ok( !ret, "GetWriteWatch failed %u\n", GetLastError() );
6693 ok( count == 5, "wrong count %lu\n", count );
6694 ok( !base[0], "data set\n" );
6696 send(src, "test message", sizeof("test message"), 0);
6698 ret = GetOverlappedResult( (HANDLE)dest, &ov, &bytesReturned, TRUE );
6699 ok( ret, "GetOverlappedResult failed %u\n", GetLastError() );
6700 ok( bytesReturned == sizeof("test message"), "wrong size %u\n", bytesReturned );
6701 ok( !memcmp( base, "test ", 5 ), "wrong data %s\n", base );
6702 ok( !memcmp( base + 0x2000, "message", 8 ), "wrong data %s\n", base + 0x2000 );
6704 count = 64;
6705 ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize );
6706 ok( !ret, "GetWriteWatch failed %u\n", GetLastError() );
6707 ok( count == 0, "wrong count %lu\n", count );
6709 memset( base, 0, size );
6710 count = 64;
6711 ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize );
6712 ok( !ret, "GetWriteWatch failed %u\n", GetLastError() );
6713 ok( count == 16, "wrong count %lu\n", count );
6715 args.dest = dest;
6716 args.base = base;
6717 args.size = 0x7002;
6718 args.expect = "test message";
6719 for (args.func = 0; args.func < 4; args.func++)
6721 thread = CreateThread( NULL, 0, write_watch_thread, &args, 0, NULL );
6722 Sleep( 200 );
6724 count = 64;
6725 ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize );
6726 ok( !ret, "GetWriteWatch failed %u\n", GetLastError() );
6727 ok( count == 8, "wrong count %lu\n", count );
6729 send(src, "test message", sizeof("test message"), 0);
6730 WaitForSingleObject( thread, 10000 );
6731 CloseHandle( thread );
6733 count = 64;
6734 ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize );
6735 ok( !ret, "GetWriteWatch failed %u\n", GetLastError() );
6736 ok( count == 0, "wrong count %lu\n", count );
6738 WSACloseEvent( event );
6739 closesocket( dest );
6740 closesocket( src );
6741 VirtualFree( base, 0, MEM_FREE );
6744 static void test_WSAPoll(void)
6746 const struct sockaddr_in bind_addr = {.sin_family = AF_INET, .sin_addr.s_addr = htonl(INADDR_LOOPBACK)};
6747 int ret, err, len;
6748 SOCKET listener, server, client;
6749 struct sockaddr_in address;
6750 WSAPOLLFD fds[16];
6751 HANDLE thread_handle;
6752 unsigned int i;
6753 char buffer[6];
6755 static const short invalid_flags[] =
6756 {POLLERR, POLLHUP, POLLNVAL, 0x8, POLLWRBAND, 0x40, 0x80, POLLPRI, 0x800, 0x1000, 0x2000, 0x4000, 0x8000};
6758 if (!pWSAPoll) /* >= Vista */
6760 win_skip("WSAPoll is unsupported, some tests will be skipped.\n");
6761 return;
6764 /* Invalid parameters test */
6765 SetLastError(0xdeadbeef);
6766 ret = pWSAPoll(NULL, 0, 0);
6767 err = GetLastError();
6768 ok(ret == SOCKET_ERROR, "expected -1, got %d\n", ret);
6769 ok(err == WSAEINVAL, "expected 10022, got %d\n", err);
6770 SetLastError(0xdeadbeef);
6771 ret = pWSAPoll(NULL, 1, 0);
6772 err = GetLastError();
6773 ok(ret == SOCKET_ERROR, "expected -1, got %d\n", ret);
6774 ok(err == WSAEFAULT, "expected 10014, got %d\n", err);
6775 SetLastError(0xdeadbeef);
6776 ret = pWSAPoll(NULL, 0, 1);
6777 err = GetLastError();
6778 ok(ret == SOCKET_ERROR, "expected -1, got %d\n", ret);
6779 ok(err == WSAEINVAL, "expected 10022, got %d\n", err);
6780 SetLastError(0xdeadbeef);
6781 ret = pWSAPoll(NULL, 1, 1);
6782 err = GetLastError();
6783 ok(ret == SOCKET_ERROR, "expected -1, got %d\n", ret);
6784 ok(err == WSAEFAULT, "expected 10014, got %d\n", err);
6786 memset(&address, 0, sizeof(address));
6787 address.sin_addr.s_addr = inet_addr("127.0.0.1");
6788 address.sin_family = AF_INET;
6789 len = sizeof(address);
6790 listener = setup_server_socket(&address, &len);
6792 for (i = 0; i < ARRAY_SIZE(invalid_flags); ++i)
6794 fds[0].fd = listener;
6795 fds[0].events = invalid_flags[i];
6796 fds[0].revents = 0xdead;
6797 WSASetLastError(0xdeadbeef);
6798 ret = pWSAPoll(fds, 1, 0);
6799 todo_wine ok(ret == -1, "got %d\n", ret);
6800 todo_wine ok(WSAGetLastError() == WSAEINVAL, "got error %u\n", WSAGetLastError());
6803 /* When no events are pending poll returns 0 with no error */
6804 fds[0].fd = listener;
6805 fds[0].events = POLLRDNORM | POLLRDBAND | POLLWRNORM;
6806 fds[0].revents = 0xdead;
6807 ret = pWSAPoll(fds, 1, 0);
6808 ok(ret == 0, "got %d\n", ret);
6809 ok(!fds[0].revents, "got events %#x\n", fds[0].revents);
6811 fds[0].fd = -1;
6812 fds[0].events = POLLERR;
6813 fds[0].revents = 0xdead;
6814 fds[1].fd = listener;
6815 fds[1].events = POLLIN;
6816 fds[1].revents = 0xdead;
6817 WSASetLastError(0xdeadbeef);
6818 ret = pWSAPoll(fds, 2, 0);
6819 ok(!ret, "got %d\n", ret);
6820 ok(!WSAGetLastError(), "got error %u\n", WSAGetLastError());
6821 ok(fds[0].revents == POLLNVAL, "got events %#x\n", fds[0].revents);
6822 ok(!fds[1].revents, "got events %#x\n", fds[1].revents);
6824 fds[0].fd = listener;
6825 fds[0].events = POLLIN;
6826 fds[0].revents = 0xdead;
6827 fds[1].fd = 0xabacab;
6828 fds[1].events = POLLIN;
6829 fds[1].revents = 0xdead;
6830 WSASetLastError(0xdeadbeef);
6831 ret = pWSAPoll(fds, 2, 0);
6832 ok(!ret, "got %d\n", ret);
6833 ok(!WSAGetLastError(), "got error %u\n", WSAGetLastError());
6834 ok(!fds[0].revents, "got events %#x\n", fds[0].revents);
6835 ok(fds[1].revents == POLLNVAL, "got events %#x\n", fds[1].revents);
6837 fds[0].fd = listener;
6838 fds[0].events = POLLIN;
6839 fds[0].revents = 0xdead;
6840 fds[1].fd = 0xabacab;
6841 fds[1].events = POLLERR;
6842 fds[1].revents = 0xdead;
6843 WSASetLastError(0xdeadbeef);
6844 ret = pWSAPoll(fds, 2, 0);
6845 todo_wine ok(ret == -1, "got %d\n", ret);
6846 todo_wine ok(WSAGetLastError() == WSAEINVAL, "got error %u\n", WSAGetLastError());
6847 ok(!fds[0].revents, "got events %#x\n", fds[0].revents);
6848 todo_wine ok(!fds[1].revents, "got events %#x\n", fds[1].revents);
6850 fds[0].fd = -1;
6851 fds[0].events = POLLERR;
6852 fds[0].revents = 0xdead;
6853 fds[1].fd = 0xabacab;
6854 fds[1].events = POLLERR;
6855 fds[1].revents = 0xdead;
6856 WSASetLastError(0xdeadbeef);
6857 ret = pWSAPoll(fds, 2, 0);
6858 ok(ret == -1, "got %d\n", ret);
6859 ok(WSAGetLastError() == WSAENOTSOCK, "got error %u\n", WSAGetLastError());
6860 ok(fds[0].revents == POLLNVAL, "got events %#x\n", fds[0].revents);
6861 ok(fds[1].revents == POLLNVAL, "got events %#x\n", fds[1].revents);
6863 /* Test listening socket connection attempt notifications */
6864 client = setup_connector_socket(&address, len, TRUE);
6866 fds[0].fd = listener;
6867 fds[0].events = POLLIN;
6868 fds[0].revents = 0xdead;
6869 ret = pWSAPoll(fds, 1, 100);
6870 ok(ret == 1, "got %d\n", ret);
6871 ok(fds[0].revents == POLLRDNORM, "got events %#x\n", fds[0].revents);
6873 fds[0].revents = 0xdead;
6874 ret = pWSAPoll(fds, 1, 0);
6875 ok(ret == 1, "got %d\n", ret);
6876 ok(fds[0].revents == POLLRDNORM, "got events %#x\n", fds[0].revents);
6878 fds[0].events = POLLRDBAND | POLLWRNORM;
6879 fds[0].revents = 0xdead;
6880 ret = pWSAPoll(fds, 1, 0);
6881 ok(ret == 0, "got %d\n", ret);
6882 ok(!fds[0].revents, "got events %#x\n", fds[0].revents);
6884 server = accept(listener, NULL, NULL);
6885 ok(server != INVALID_SOCKET, "failed to accept, error %u\n", WSAGetLastError());
6886 set_blocking(client, FALSE);
6887 set_blocking(server, FALSE);
6889 for (i = 0; i < ARRAY_SIZE(invalid_flags); ++i)
6891 fds[0].fd = server;
6892 fds[0].events = invalid_flags[i];
6893 fds[0].revents = 0xdead;
6894 WSASetLastError(0xdeadbeef);
6895 ret = pWSAPoll(fds, 1, 0);
6896 todo_wine ok(ret == -1, "got %d\n", ret);
6897 todo_wine ok(WSAGetLastError() == WSAEINVAL, "got error %u\n", WSAGetLastError());
6900 /* Test flags exposed by connected sockets. */
6902 fds[0].fd = listener;
6903 fds[0].events = POLLRDNORM | POLLRDBAND | POLLWRNORM;
6904 fds[0].revents = 0xdead;
6905 fds[1].fd = server;
6906 fds[1].events = POLLRDNORM | POLLRDBAND | POLLWRNORM;
6907 fds[1].revents = 0xdead;
6908 fds[2].fd = client;
6909 fds[2].events = POLLRDNORM | POLLRDBAND | POLLWRNORM;
6910 fds[2].revents = 0xdead;
6911 ret = pWSAPoll(fds, 3, 0);
6912 ok(ret == 2, "got %d\n", ret);
6913 ok(!fds[0].revents, "got events %#x\n", fds[0].revents);
6914 ok(fds[1].revents == POLLWRNORM, "got events %#x\n", fds[1].revents);
6915 ok(fds[2].revents == POLLWRNORM, "got events %#x\n", fds[2].revents);
6917 /* Test data receiving notifications */
6919 ret = send(server, "1234", 4, 0);
6920 ok(ret == 4, "got %d\n", ret);
6922 check_poll_mask(client, POLLRDNORM | POLLRDBAND, POLLRDNORM);
6923 check_poll(client, POLLRDNORM | POLLWRNORM);
6924 check_poll(server, POLLWRNORM);
6926 ret = sync_recv(client, buffer, sizeof(buffer), 0);
6927 ok(ret == 4, "got %d\n", ret);
6929 check_poll(client, POLLWRNORM);
6930 check_poll(server, POLLWRNORM);
6932 /* Because the kernel asynchronously buffers data, this test is not reliable. */
6934 if (0)
6936 static const int large_buffer_size = 1024 * 1024;
6937 char *large_buffer = malloc(large_buffer_size);
6939 while (send(server, large_buffer, large_buffer_size, 0) == large_buffer_size);
6941 check_poll(client, POLLWRNORM | POLLRDNORM);
6942 check_poll(server, 0);
6944 while (recv(client, large_buffer, large_buffer_size, 0) > 0);
6946 check_poll(client, POLLWRNORM);
6947 check_poll(server, POLLWRNORM);
6949 free(large_buffer);
6952 /* Test OOB data notifications */
6954 ret = send(client, "A", 1, MSG_OOB);
6955 ok(ret == 1, "got %d\n", ret);
6957 check_poll(client, POLLWRNORM);
6958 check_poll_mask(server, POLLRDNORM | POLLRDBAND, POLLRDBAND);
6959 check_poll(server, POLLWRNORM | POLLRDBAND);
6961 buffer[0] = 0xcc;
6962 ret = recv(server, buffer, 1, MSG_OOB);
6963 ok(ret == 1, "got %d\n", ret);
6964 ok(buffer[0] == 'A', "got %#x\n", buffer[0]);
6966 check_poll(client, POLLWRNORM);
6967 check_poll(server, POLLWRNORM);
6969 /* If the socket is OOBINLINED the notification is like normal data */
6971 ret = 1;
6972 ret = setsockopt(server, SOL_SOCKET, SO_OOBINLINE, (char *)&ret, sizeof(ret));
6973 ok(!ret, "got error %u\n", WSAGetLastError());
6974 ret = send(client, "A", 1, MSG_OOB);
6975 ok(ret == 1, "got %d\n", ret);
6977 check_poll(client, POLLWRNORM);
6978 check_poll_mask(server, POLLRDNORM | POLLRDBAND, POLLRDNORM);
6979 check_poll(server, POLLWRNORM | POLLRDNORM);
6981 buffer[0] = 0xcc;
6982 ret = recv(server, buffer, 1, 0);
6983 ok(ret == 1, "got %d\n", ret);
6984 ok(buffer[0] == 'A', "got %#x\n", buffer[0]);
6986 check_poll(client, POLLWRNORM);
6987 check_poll_todo(server, POLLWRNORM);
6989 /* Test shutdown. */
6991 ret = shutdown(client, SD_RECEIVE);
6992 ok(!ret, "got error %u\n", WSAGetLastError());
6994 check_poll(client, POLLWRNORM);
6995 check_poll_todo(server, POLLWRNORM);
6997 ret = shutdown(client, SD_SEND);
6998 ok(!ret, "got error %u\n", WSAGetLastError());
7000 check_poll(client, POLLWRNORM);
7001 check_poll_mask_todo(server, 0, POLLHUP);
7002 check_poll_todo(server, POLLWRNORM | POLLHUP);
7004 closesocket(client);
7005 closesocket(server);
7007 /* Test shutdown via closesocket(). */
7009 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
7010 ret = connect(client, (struct sockaddr *)&address, sizeof(address));
7011 ok(!ret, "got error %u\n", WSAGetLastError());
7012 server = accept(listener, NULL, NULL);
7013 ok(server != -1, "got error %u\n", WSAGetLastError());
7015 closesocket(client);
7017 check_poll_mask(server, 0, POLLHUP);
7018 check_poll(server, POLLWRNORM | POLLHUP);
7020 closesocket(server);
7022 /* Test shutdown with data in the pipe. */
7024 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
7025 ret = connect(client, (struct sockaddr *)&address, sizeof(address));
7026 ok(!ret, "got error %u\n", WSAGetLastError());
7027 server = accept(listener, NULL, NULL);
7028 ok(server != -1, "got error %u\n", WSAGetLastError());
7030 ret = send(client, "data", 5, 0);
7031 ok(ret == 5, "got %d\n", ret);
7033 check_poll(client, POLLWRNORM);
7034 check_poll_mask(server, POLLRDNORM | POLLRDBAND, POLLRDNORM);
7035 check_poll(server, POLLWRNORM | POLLRDNORM);
7037 ret = shutdown(client, SD_SEND);
7039 check_poll(client, POLLWRNORM);
7040 check_poll_mask_todo(server, 0, POLLHUP);
7041 check_poll_todo(server, POLLWRNORM | POLLRDNORM | POLLHUP);
7043 closesocket(client);
7044 closesocket(server);
7046 /* Test closing a socket while selecting on it. */
7048 tcp_socketpair(&client, &server);
7050 thread_handle = CreateThread(NULL, 0, SelectCloseThread, &client, 0, NULL);
7051 fds[0].fd = client;
7052 fds[0].events = POLLRDNORM | POLLRDBAND;
7053 fds[0].revents = 0xdead;
7054 ret = pWSAPoll(fds, 1, 2000);
7055 ok(ret == 1, "got %d\n", ret);
7056 ok(fds[0].revents == POLLNVAL, "got events %#x\n", fds[0].revents);
7057 ret = WaitForSingleObject(thread_handle, 1000);
7058 ok(!ret, "wait failed\n");
7059 CloseHandle(thread_handle);
7061 closesocket(server);
7063 /* Test a failed connection.
7065 * The following WSAPoll() call times out on versions older than w10pro64,
7066 * but even on w10pro64 it takes over 2 seconds for an error to be reported,
7067 * so make the test interactive-only. */
7068 if (winetest_interactive)
7070 const struct sockaddr_in invalid_addr =
7072 .sin_family = AF_INET,
7073 .sin_addr.s_addr = htonl(INADDR_LOOPBACK),
7074 .sin_port = 255,
7076 SOCKET client;
7078 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
7079 set_blocking(client, FALSE);
7081 ret = connect(client, (const struct sockaddr *)&invalid_addr, sizeof(invalid_addr));
7082 ok(ret == -1, "got %d\n", ret);
7083 ok(WSAGetLastError() == WSAEWOULDBLOCK, "got error %u\n", WSAGetLastError());
7085 fds[0].fd = client;
7086 fds[0].events = POLLRDNORM | POLLRDBAND | POLLWRNORM;
7087 fds[0].revents = 0xdead;
7088 ret = pWSAPoll(fds, 1, 10000);
7089 ok(ret == 1, "got %d\n", ret);
7090 todo_wine ok(fds[0].revents == (POLLWRNORM | POLLHUP | POLLERR), "got events %#x\n", fds[0].revents);
7092 len = sizeof(err);
7093 err = 0xdeadbeef;
7094 ret = getsockopt(client, SOL_SOCKET, SO_ERROR, (char *)&err, &len);
7095 ok(!ret, "getsockopt failed with %d\n", WSAGetLastError());
7096 ok(err == WSAECONNREFUSED, "got error %u\n", err);
7098 len = sizeof(err);
7099 err = 0xdeadbeef;
7100 ret = getsockopt(client, SOL_SOCKET, SO_ERROR, (char *)&err, &len);
7101 ok(!ret, "getsockopt failed with %d\n", WSAGetLastError());
7102 ok(err == WSAECONNREFUSED, "got error %u\n", err);
7104 check_poll_todo(client, POLLWRNORM | POLLHUP | POLLERR);
7106 closesocket(client);
7108 /* test polling after a (synchronous) failure */
7110 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
7112 ret = connect(client, (const struct sockaddr *)&invalid_addr, sizeof(invalid_addr));
7113 ok(ret == -1, "got %d\n", ret);
7114 ok(WSAGetLastError() == WSAECONNREFUSED, "got error %u\n", WSAGetLastError());
7116 check_poll_todo(client, POLLWRNORM | POLLHUP | POLLERR);
7118 len = sizeof(err);
7119 err = 0xdeadbeef;
7120 ret = getsockopt(client, SOL_SOCKET, SO_ERROR, (char *)&err, &len);
7121 ok(!ret, "getsockopt failed with %d\n", WSAGetLastError());
7122 todo_wine ok(!err, "got error %u\n", err);
7124 closesocket(client);
7127 closesocket(listener);
7129 /* Test UDP sockets. */
7131 client = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
7132 server = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
7134 check_poll(client, POLLWRNORM);
7135 check_poll(server, POLLWRNORM);
7137 ret = bind(client, (const struct sockaddr *)&bind_addr, sizeof(bind_addr));
7138 ok(!ret, "got error %u\n", WSAGetLastError());
7139 len = sizeof(address);
7140 ret = getsockname(client, (struct sockaddr *)&address, &len);
7141 ok(!ret, "got error %u\n", WSAGetLastError());
7143 check_poll(client, POLLWRNORM);
7144 check_poll(server, POLLWRNORM);
7146 ret = sendto(server, "data", 5, 0, (struct sockaddr *)&address, sizeof(address));
7147 ok(ret == 5, "got %d\n", ret);
7149 check_poll_mask(client, POLLRDNORM | POLLRDBAND, POLLRDNORM);
7150 check_poll(client, POLLWRNORM | POLLRDNORM);
7151 check_poll(server, POLLWRNORM);
7153 closesocket(client);
7154 closesocket(server);
7157 static void test_connect(void)
7159 SOCKET listener = INVALID_SOCKET;
7160 SOCKET acceptor = INVALID_SOCKET;
7161 SOCKET connector = INVALID_SOCKET;
7162 struct sockaddr_in address, conaddress;
7163 int addrlen;
7164 OVERLAPPED overlapped;
7165 LPFN_CONNECTEX pConnectEx;
7166 GUID connectExGuid = WSAID_CONNECTEX;
7167 DWORD bytesReturned;
7168 char buffer[1024];
7169 BOOL bret;
7170 DWORD dwret;
7171 int iret;
7173 memset(&overlapped, 0, sizeof(overlapped));
7175 listener = socket(AF_INET, SOCK_STREAM, 0);
7176 ok(listener != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
7178 connector = socket(AF_INET, SOCK_STREAM, 0);
7179 ok(connector != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
7181 memset(&address, 0, sizeof(address));
7182 address.sin_family = AF_INET;
7183 address.sin_addr.s_addr = inet_addr("127.0.0.1");
7184 iret = bind(listener, (struct sockaddr*)&address, sizeof(address));
7185 ok(!iret, "failed to bind, error %u\n", WSAGetLastError());
7187 addrlen = sizeof(address);
7188 iret = getsockname(listener, (struct sockaddr*)&address, &addrlen);
7189 ok(!iret, "failed to get address, error %u\n", WSAGetLastError());
7191 iret = listen(listener, 1);
7192 ok(!iret, "failed to listen, error %u\n", WSAGetLastError());
7194 iret = set_blocking(listener, TRUE);
7195 ok(!iret, "failed to set nonblocking, error %u\n", WSAGetLastError());
7197 bytesReturned = 0xdeadbeef;
7198 iret = WSAIoctl(connector, SIO_GET_EXTENSION_FUNCTION_POINTER, &connectExGuid, sizeof(connectExGuid),
7199 &pConnectEx, sizeof(pConnectEx), &bytesReturned, NULL, NULL);
7200 ok(!iret, "failed to get ConnectEx, error %u\n", WSAGetLastError());
7202 ok(bytesReturned == sizeof(pConnectEx), "expected sizeof(pConnectEx), got %u\n", bytesReturned);
7204 WSASetLastError(0xdeadbeef);
7205 iret = connect(listener, (struct sockaddr *)&address, sizeof(address));
7206 ok(iret == -1, "got %d\n", iret);
7207 ok(WSAGetLastError() == WSAEINVAL, "got error %u\n", WSAGetLastError());
7209 WSASetLastError(0xdeadbeef);
7210 overlapped.Internal = 0xdeadbeef;
7211 overlapped.InternalHigh = 0xdeadbeef;
7212 iret = pConnectEx(listener, (struct sockaddr *)&address, sizeof(address), NULL, 0, &bytesReturned, &overlapped);
7213 ok(!iret, "got %d\n", iret);
7214 ok(WSAGetLastError() == WSAEINVAL, "got error %u\n", WSAGetLastError());
7215 ok(overlapped.Internal == STATUS_PENDING, "got status %#x\n", (NTSTATUS)overlapped.Internal);
7216 todo_wine ok(overlapped.InternalHigh == 0xdeadbeef, "got size %Iu\n", overlapped.InternalHigh);
7218 bret = pConnectEx(INVALID_SOCKET, (struct sockaddr*)&address, addrlen, NULL, 0, &bytesReturned, &overlapped);
7219 ok(bret == FALSE && WSAGetLastError() == WSAENOTSOCK, "ConnectEx on invalid socket "
7220 "returned %d + errno %d\n", bret, WSAGetLastError());
7222 bret = pConnectEx(connector, (struct sockaddr*)&address, addrlen, NULL, 0, &bytesReturned, &overlapped);
7223 ok(bret == FALSE && WSAGetLastError() == WSAEINVAL, "ConnectEx on a unbound socket "
7224 "returned %d + errno %d\n", bret, WSAGetLastError());
7226 /* ConnectEx needs a bound socket */
7227 memset(&conaddress, 0, sizeof(conaddress));
7228 conaddress.sin_family = AF_INET;
7229 conaddress.sin_addr.s_addr = inet_addr("127.0.0.1");
7230 iret = bind(connector, (struct sockaddr*)&conaddress, sizeof(conaddress));
7231 ok(!iret, "failed to bind, error %u\n", WSAGetLastError());
7233 bret = pConnectEx(connector, (struct sockaddr*)&address, addrlen, NULL, 0, &bytesReturned, NULL);
7234 ok(bret == FALSE && WSAGetLastError() == ERROR_INVALID_PARAMETER, "ConnectEx on a NULL overlapped "
7235 "returned %d + errno %d\n", bret, WSAGetLastError());
7237 overlapped.hEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
7239 bret = pConnectEx(connector, (struct sockaddr*)&address, addrlen, NULL, 0, &bytesReturned, &overlapped);
7240 ok(bret == FALSE && WSAGetLastError() == ERROR_IO_PENDING, "ConnectEx failed: "
7241 "returned %d + errno %d\n", bret, WSAGetLastError());
7242 dwret = WaitForSingleObject(overlapped.hEvent, 15000);
7243 ok(dwret == WAIT_OBJECT_0, "Waiting for connect event failed with %d + errno %d\n", dwret, GetLastError());
7245 bret = GetOverlappedResult((HANDLE)connector, &overlapped, &bytesReturned, FALSE);
7246 ok(bret, "Connecting failed, error %d\n", GetLastError());
7247 ok(bytesReturned == 0, "Bytes sent is %d\n", bytesReturned);
7249 closesocket(connector);
7250 connector = socket(AF_INET, SOCK_STREAM, 0);
7251 ok(connector != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
7252 /* ConnectEx needs a bound socket */
7253 memset(&conaddress, 0, sizeof(conaddress));
7254 conaddress.sin_family = AF_INET;
7255 conaddress.sin_addr.s_addr = inet_addr("127.0.0.1");
7256 iret = bind(connector, (struct sockaddr*)&conaddress, sizeof(conaddress));
7257 ok(!iret, "failed to bind, error %u\n", WSAGetLastError());
7259 acceptor = accept(listener, NULL, NULL);
7260 ok(acceptor != INVALID_SOCKET, "failed to accept socket, error %u\n", WSAGetLastError());
7262 buffer[0] = '1';
7263 buffer[1] = '2';
7264 buffer[2] = '3';
7265 bret = pConnectEx(connector, (struct sockaddr*)&address, addrlen, buffer, 3, &bytesReturned, &overlapped);
7266 memset(buffer, 0, 3);
7267 ok(bret == FALSE && WSAGetLastError() == ERROR_IO_PENDING, "ConnectEx failed: "
7268 "returned %d + errno %d\n", bret, WSAGetLastError());
7269 dwret = WaitForSingleObject(overlapped.hEvent, 15000);
7270 ok(dwret == WAIT_OBJECT_0, "Waiting for connect event failed with %d + errno %d\n", dwret, GetLastError());
7272 bret = GetOverlappedResult((HANDLE)connector, &overlapped, &bytesReturned, FALSE);
7273 ok(bret, "Connecting failed, error %d\n", GetLastError());
7274 ok(bytesReturned == 3, "Bytes sent is %d\n", bytesReturned);
7276 acceptor = accept(listener, NULL, NULL);
7277 ok(acceptor != INVALID_SOCKET, "could not accept socket error %d\n", WSAGetLastError());
7279 bytesReturned = recv(acceptor, buffer, 3, 0);
7280 buffer[4] = 0;
7281 ok(bytesReturned == 3, "Didn't get all sent data, got only %d\n", bytesReturned);
7282 ok(buffer[0] == '1' && buffer[1] == '2' && buffer[2] == '3',
7283 "Failed to get the right data, expected '123', got '%s'\n", buffer);
7285 WSASetLastError(0xdeadbeef);
7286 iret = connect(connector, (struct sockaddr *)&address, sizeof(address));
7287 ok(iret == -1, "got %d\n", iret);
7288 todo_wine ok(WSAGetLastError() == WSAEINVAL, "got error %u\n", WSAGetLastError());
7290 WSASetLastError(0xdeadbeef);
7291 iret = connect(acceptor, (struct sockaddr *)&address, sizeof(address));
7292 ok(iret == -1, "got %d\n", iret);
7293 ok(WSAGetLastError() == WSAEISCONN, "got error %u\n", WSAGetLastError());
7295 WSASetLastError(0xdeadbeef);
7296 overlapped.Internal = 0xdeadbeef;
7297 overlapped.InternalHigh = 0xdeadbeef;
7298 bret = pConnectEx(connector, (struct sockaddr *)&address, sizeof(address), NULL, 0, &bytesReturned, &overlapped);
7299 ok(!bret, "got %d\n", bret);
7300 ok(WSAGetLastError() == WSAEISCONN, "got error %u\n", WSAGetLastError());
7301 ok(overlapped.Internal == STATUS_PENDING, "got status %#x\n", (NTSTATUS)overlapped.Internal);
7302 todo_wine ok(overlapped.InternalHigh == 0xdeadbeef, "got size %Iu\n", overlapped.InternalHigh);
7304 WSASetLastError(0xdeadbeef);
7305 overlapped.Internal = 0xdeadbeef;
7306 overlapped.InternalHigh = 0xdeadbeef;
7307 bret = pConnectEx(acceptor, (struct sockaddr *)&address, sizeof(address), NULL, 0, &bytesReturned, &overlapped);
7308 ok(!bret, "got %d\n", bret);
7309 ok(WSAGetLastError() == WSAEISCONN, "got error %u\n", WSAGetLastError());
7310 ok(overlapped.Internal == STATUS_PENDING, "got status %#x\n", (NTSTATUS)overlapped.Internal);
7311 todo_wine ok(overlapped.InternalHigh == 0xdeadbeef, "got size %Iu\n", overlapped.InternalHigh);
7313 closesocket(connector);
7314 closesocket(acceptor);
7315 closesocket(listener);
7317 tcp_socketpair(&connector, &acceptor);
7319 WSASetLastError(0xdeadbeef);
7320 iret = connect(connector, (struct sockaddr *)&address, sizeof(address));
7321 ok(iret == -1, "got %d\n", iret);
7322 ok(WSAGetLastError() == WSAEISCONN, "got error %u\n", WSAGetLastError());
7324 WSASetLastError(0xdeadbeef);
7325 iret = connect(acceptor, (struct sockaddr *)&address, sizeof(address));
7326 ok(iret == -1, "got %d\n", iret);
7327 ok(WSAGetLastError() == WSAEISCONN, "got error %u\n", WSAGetLastError());
7329 WSASetLastError(0xdeadbeef);
7330 overlapped.Internal = 0xdeadbeef;
7331 overlapped.InternalHigh = 0xdeadbeef;
7332 bret = pConnectEx(connector, (struct sockaddr *)&address, sizeof(address), NULL, 0, &bytesReturned, &overlapped);
7333 ok(!bret, "got %d\n", bret);
7334 ok(WSAGetLastError() == WSAEISCONN, "got error %u\n", WSAGetLastError());
7335 ok(overlapped.Internal == STATUS_PENDING, "got status %#x\n", (NTSTATUS)overlapped.Internal);
7336 todo_wine ok(overlapped.InternalHigh == 0xdeadbeef, "got size %Iu\n", overlapped.InternalHigh);
7338 WSASetLastError(0xdeadbeef);
7339 overlapped.Internal = 0xdeadbeef;
7340 overlapped.InternalHigh = 0xdeadbeef;
7341 bret = pConnectEx(acceptor, (struct sockaddr *)&address, sizeof(address), NULL, 0, &bytesReturned, &overlapped);
7342 ok(!bret, "got %d\n", bret);
7343 ok(WSAGetLastError() == WSAEISCONN, "got error %u\n", WSAGetLastError());
7344 ok(overlapped.Internal == STATUS_PENDING, "got status %#x\n", (NTSTATUS)overlapped.Internal);
7345 todo_wine ok(overlapped.InternalHigh == 0xdeadbeef, "got size %Iu\n", overlapped.InternalHigh);
7347 closesocket(connector);
7348 closesocket(acceptor);
7350 /* Connect with error */
7352 connector = socket(AF_INET, SOCK_STREAM, 0);
7353 ok(connector != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
7354 /* ConnectEx needs a bound socket */
7355 memset(&conaddress, 0, sizeof(conaddress));
7356 conaddress.sin_family = AF_INET;
7357 conaddress.sin_addr.s_addr = inet_addr("127.0.0.1");
7358 iret = bind(connector, (struct sockaddr*)&conaddress, sizeof(conaddress));
7359 ok(!iret, "failed to bind, error %u\n", WSAGetLastError());
7361 address.sin_port = htons(1);
7363 bret = pConnectEx(connector, (struct sockaddr*)&address, addrlen, NULL, 0, &bytesReturned, &overlapped);
7364 ok(bret == FALSE && GetLastError() == ERROR_IO_PENDING, "ConnectEx to bad destination failed: "
7365 "returned %d + errno %d\n", bret, GetLastError());
7366 dwret = WaitForSingleObject(overlapped.hEvent, 15000);
7367 ok(dwret == WAIT_OBJECT_0, "Waiting for connect event failed with %d + errno %d\n", dwret, GetLastError());
7369 bret = GetOverlappedResult((HANDLE)connector, &overlapped, &bytesReturned, FALSE);
7370 ok(bret == FALSE && GetLastError() == ERROR_CONNECTION_REFUSED,
7371 "Connecting to a disconnected host returned error %d - %d\n", bret, WSAGetLastError());
7373 WSACloseEvent(overlapped.hEvent);
7374 closesocket(connector);
7377 static void test_AcceptEx(void)
7379 const struct sockaddr_in bind_addr = {.sin_family = AF_INET, .sin_addr.s_addr = htonl(INADDR_LOOPBACK)};
7380 SOCKET listener, acceptor, acceptor2, connector, connector2;
7381 struct sockaddr_in bindAddress, peerAddress, *readBindAddress, *readRemoteAddress;
7382 int socklen, optlen;
7383 GUID acceptExGuid = WSAID_ACCEPTEX, getAcceptExGuid = WSAID_GETACCEPTEXSOCKADDRS;
7384 GUID connectex_guid = WSAID_CONNECTEX;
7385 LPFN_ACCEPTEX pAcceptEx = NULL;
7386 LPFN_GETACCEPTEXSOCKADDRS pGetAcceptExSockaddrs = NULL;
7387 LPFN_CONNECTEX pConnectEx = NULL;
7388 fd_set fds_accept, fds_send;
7389 static const struct timeval timeout = {1, 0};
7390 DWORD bytesReturned, connect_time;
7391 char buffer[1024], ipbuffer[32];
7392 OVERLAPPED overlapped = {0}, overlapped2 = {0};
7393 int iret, localSize = sizeof(struct sockaddr_in), remoteSize = localSize;
7394 BOOL bret;
7395 DWORD dwret;
7397 overlapped.hEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
7398 overlapped2.hEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
7400 listener = socket(AF_INET, SOCK_STREAM, 0);
7401 ok(listener != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
7403 acceptor = socket(AF_INET, SOCK_STREAM, 0);
7404 ok(acceptor != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
7406 memset(&bindAddress, 0, sizeof(bindAddress));
7407 bindAddress.sin_family = AF_INET;
7408 bindAddress.sin_addr.s_addr = inet_addr("127.0.0.1");
7409 iret = bind(listener, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
7410 ok(!iret, "failed to bind, error %u\n", WSAGetLastError());
7412 socklen = sizeof(bindAddress);
7413 iret = getsockname(listener, (struct sockaddr*)&bindAddress, &socklen);
7414 ok(!iret, "failed to get address, error %u\n", WSAGetLastError());
7416 iret = set_blocking(listener, FALSE);
7417 ok(!iret, "Failed to set nonblocking, error %u\n", WSAGetLastError());
7419 iret = WSAIoctl(listener, SIO_GET_EXTENSION_FUNCTION_POINTER, &acceptExGuid, sizeof(acceptExGuid),
7420 &pAcceptEx, sizeof(pAcceptEx), &bytesReturned, NULL, NULL);
7421 ok(!iret, "Failed to get AcceptEx, error %u\n", WSAGetLastError());
7423 iret = WSAIoctl(listener, SIO_GET_EXTENSION_FUNCTION_POINTER, &getAcceptExGuid, sizeof(getAcceptExGuid),
7424 &pGetAcceptExSockaddrs, sizeof(pGetAcceptExSockaddrs), &bytesReturned, NULL, NULL);
7425 ok(!iret, "Failed to get GetAcceptExSockaddrs, error %u\n", WSAGetLastError());
7427 iret = WSAIoctl(listener, SIO_GET_EXTENSION_FUNCTION_POINTER, &connectex_guid, sizeof(connectex_guid),
7428 &pConnectEx, sizeof(pConnectEx), &bytesReturned, NULL, NULL);
7429 ok(!iret, "Failed to get ConnectEx, error %u\n", WSAGetLastError());
7431 overlapped.Internal = 0xdeadbeef;
7432 bret = pAcceptEx(INVALID_SOCKET, acceptor, buffer, sizeof(buffer) - 2*(sizeof(struct sockaddr_in) + 16),
7433 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
7434 &bytesReturned, &overlapped);
7435 ok(bret == FALSE && WSAGetLastError() == WSAENOTSOCK, "AcceptEx on invalid listening socket "
7436 "returned %d + errno %d\n", bret, WSAGetLastError());
7437 ok(overlapped.Internal == STATUS_PENDING, "got %08x\n", (ULONG)overlapped.Internal);
7439 overlapped.Internal = 0xdeadbeef;
7440 bret = pAcceptEx(listener, acceptor, buffer, sizeof(buffer) - 2*(sizeof(struct sockaddr_in) + 16),
7441 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
7442 &bytesReturned, &overlapped);
7443 todo_wine
7444 ok(bret == FALSE && WSAGetLastError() == WSAEINVAL, "AcceptEx on a non-listening socket "
7445 "returned %d + errno %d\n", bret, WSAGetLastError());
7446 ok(overlapped.Internal == STATUS_PENDING, "got %08x\n", (ULONG)overlapped.Internal);
7447 if (!bret && WSAGetLastError() == ERROR_IO_PENDING)
7448 CancelIo((HANDLE)listener);
7450 iret = listen(listener, 5);
7451 ok(!iret, "failed to listen, error %u\n", GetLastError());
7453 overlapped.Internal = 0xdeadbeef;
7454 bret = pAcceptEx(listener, INVALID_SOCKET, buffer, sizeof(buffer) - 2*(sizeof(struct sockaddr_in) + 16),
7455 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
7456 &bytesReturned, &overlapped);
7457 ok(bret == FALSE && WSAGetLastError() == WSAENOTSOCK, "AcceptEx on invalid accepting socket "
7458 "returned %d + errno %d\n", bret, WSAGetLastError());
7459 ok(overlapped.Internal == STATUS_PENDING, "got %08x\n", (ULONG)overlapped.Internal);
7461 overlapped.Internal = 0xdeadbeef;
7462 bret = pAcceptEx(listener, acceptor, NULL, sizeof(buffer) - 2*(sizeof(struct sockaddr_in) + 16),
7463 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
7464 &bytesReturned, &overlapped);
7465 todo_wine ok(bret == FALSE && WSAGetLastError() == WSAEFAULT,
7466 "AcceptEx on NULL buffer returned %d + errno %d\n", bret, WSAGetLastError());
7467 ok(overlapped.Internal == STATUS_PENDING, "got %08x\n", (ULONG)overlapped.Internal);
7469 overlapped.Internal = 0xdeadbeef;
7470 bret = pAcceptEx(listener, acceptor, buffer, 0, 0, sizeof(struct sockaddr_in) + 16,
7471 &bytesReturned, &overlapped);
7472 ok(bret == FALSE && WSAGetLastError() == ERROR_IO_PENDING,
7473 "AcceptEx on too small local address size returned %d + errno %d\n",
7474 bret, WSAGetLastError());
7475 ok(overlapped.Internal == STATUS_PENDING, "got %08x\n", (ULONG)overlapped.Internal);
7477 connector = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
7478 ok(connector != -1, "failed to create socket, error %u\n", WSAGetLastError());
7479 iret = connect(connector, (struct sockaddr *)&bindAddress, sizeof(bindAddress));
7480 ok(!iret, "failed to connect, error %u\n", WSAGetLastError());
7481 iret = getsockname(connector, (struct sockaddr *)&peerAddress, &remoteSize);
7482 ok(!iret, "getsockname failed, error %u\n", WSAGetLastError());
7484 dwret = WaitForSingleObject(overlapped.hEvent, 1000);
7485 ok(!dwret, "wait failed\n");
7486 bret = GetOverlappedResult((HANDLE)listener, &overlapped, &bytesReturned, FALSE);
7487 ok(bret, "got error %u\n", GetLastError());
7488 ok(!(NTSTATUS)overlapped.Internal, "got %#lx\n", overlapped.Internal);
7489 ok(!bytesReturned, "got size %u\n", bytesReturned);
7491 readBindAddress = readRemoteAddress = (struct sockaddr_in *)0xdeadbeef;
7492 localSize = remoteSize = 0xdeadbeef;
7493 pGetAcceptExSockaddrs(buffer, 0, 0, sizeof(struct sockaddr_in) + 16,
7494 (struct sockaddr **)&readBindAddress, &localSize, (struct sockaddr **)&readRemoteAddress, &remoteSize);
7495 todo_wine ok(readBindAddress == (struct sockaddr_in *)0xdeadbeef, "got local addr %p\n", readBindAddress);
7496 ok(!memcmp(readRemoteAddress, &peerAddress, sizeof(peerAddress)), "remote addr didn't match\n");
7497 todo_wine ok(localSize == 0xdeadbeef, "got local size %u\n", localSize);
7498 ok(remoteSize == sizeof(struct sockaddr_in), "got remote size %u\n", remoteSize);
7500 closesocket(connector);
7501 closesocket(acceptor);
7503 /* A UDP socket cannot be accepted into. */
7505 acceptor = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
7507 overlapped.Internal = 0xdeadbeef;
7508 bret = pAcceptEx(listener, acceptor, buffer, 0, 0, sizeof(struct sockaddr_in) + 16, &bytesReturned, &overlapped);
7509 ok(!bret, "expected failure\n");
7510 todo_wine ok(WSAGetLastError() == WSAEINVAL, "got error %u\n", WSAGetLastError());
7511 ok(overlapped.Internal == STATUS_PENDING, "got status %#x\n", (NTSTATUS)overlapped.Internal);
7512 if (WSAGetLastError() == ERROR_IO_PENDING)
7513 CancelIo((HANDLE)listener);
7515 closesocket(acceptor);
7517 /* A bound socket cannot be accepted into. */
7519 acceptor = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
7520 iret = bind(acceptor, (const struct sockaddr *)&bind_addr, sizeof(bind_addr));
7521 ok(!iret, "got error %u\n", WSAGetLastError());
7523 overlapped.Internal = 0xdeadbeef;
7524 bret = pAcceptEx(listener, acceptor, buffer, 0, 0, sizeof(struct sockaddr_in) + 16, &bytesReturned, &overlapped);
7525 ok(!bret, "expected failure\n");
7526 todo_wine ok(WSAGetLastError() == WSAEINVAL, "got error %u\n", WSAGetLastError());
7527 ok(overlapped.Internal == STATUS_PENDING, "got status %#x\n", (NTSTATUS)overlapped.Internal);
7528 if (WSAGetLastError() == ERROR_IO_PENDING)
7529 CancelIo((HANDLE)listener);
7531 closesocket(acceptor);
7533 /* A connected socket cannot be accepted into. */
7535 tcp_socketpair(&acceptor, &acceptor2);
7537 overlapped.Internal = 0xdeadbeef;
7538 bret = pAcceptEx(listener, acceptor, buffer, 0, 0, sizeof(struct sockaddr_in) + 16, &bytesReturned, &overlapped);
7539 ok(!bret, "expected failure\n");
7540 todo_wine ok(WSAGetLastError() == WSAEINVAL, "got error %u\n", WSAGetLastError());
7541 ok(overlapped.Internal == STATUS_PENDING, "got status %#x\n", (NTSTATUS)overlapped.Internal);
7542 if (WSAGetLastError() == ERROR_IO_PENDING)
7543 CancelIo((HANDLE)listener);
7545 overlapped.Internal = 0xdeadbeef;
7546 bret = pAcceptEx(listener, acceptor2, buffer, 0, 0, sizeof(struct sockaddr_in) + 16, &bytesReturned, &overlapped);
7547 ok(!bret, "expected failure\n");
7548 todo_wine ok(WSAGetLastError() == WSAEINVAL, "got error %u\n", WSAGetLastError());
7549 ok(overlapped.Internal == STATUS_PENDING, "got status %#x\n", (NTSTATUS)overlapped.Internal);
7550 if (WSAGetLastError() == ERROR_IO_PENDING)
7551 CancelIo((HANDLE)listener);
7553 closesocket(acceptor);
7554 closesocket(acceptor2);
7556 /* Pass an insufficient local address size. */
7558 acceptor = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
7559 ok(acceptor != -1, "failed to create socket, error %u\n", WSAGetLastError());
7561 overlapped.Internal = 0xdeadbeef;
7562 bret = pAcceptEx(listener, acceptor, buffer, 0, 3,
7563 sizeof(struct sockaddr_in) + 16, &bytesReturned, &overlapped);
7564 ok(!bret && WSAGetLastError() == ERROR_IO_PENDING, "got %d, error %u\n", bret, WSAGetLastError());
7565 ok((NTSTATUS)overlapped.Internal == STATUS_PENDING, "got %#lx\n", overlapped.Internal);
7567 connector = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
7568 ok(connector != -1, "failed to create socket, error %u\n", WSAGetLastError());
7569 iret = connect(connector, (struct sockaddr *)&bindAddress, sizeof(bindAddress));
7570 ok(!iret, "failed to connect, error %u\n", WSAGetLastError());
7572 dwret = WaitForSingleObject(overlapped.hEvent, 1000);
7573 ok(!dwret, "wait failed\n");
7574 bytesReturned = 0xdeadbeef;
7575 SetLastError(0xdeadbeef);
7576 bret = GetOverlappedResult((HANDLE)listener, &overlapped, &bytesReturned, FALSE);
7577 ok(!bret, "expected failure\n");
7578 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got error %u\n", GetLastError());
7579 ok((NTSTATUS)overlapped.Internal == STATUS_BUFFER_TOO_SMALL, "got %#lx\n", overlapped.Internal);
7580 ok(!bytesReturned, "got size %u\n", bytesReturned);
7582 closesocket(acceptor);
7584 /* The above connection request is not accepted. */
7585 acceptor = accept(listener, NULL, NULL);
7586 todo_wine ok(acceptor != INVALID_SOCKET, "failed to accept, error %u\n", WSAGetLastError());
7587 closesocket(acceptor);
7589 closesocket(connector);
7591 acceptor = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
7592 ok(acceptor != -1, "failed to create socket, error %u\n", WSAGetLastError());
7594 overlapped.Internal = 0xdeadbeef;
7595 bret = pAcceptEx(listener, acceptor, buffer, 0, sizeof(struct sockaddr_in) + 4,
7596 sizeof(struct sockaddr_in) + 16, &bytesReturned, &overlapped);
7597 ok(!bret && WSAGetLastError() == ERROR_IO_PENDING, "got %d, error %u\n", bret, WSAGetLastError());
7598 ok((NTSTATUS)overlapped.Internal == STATUS_PENDING, "got %#lx\n", overlapped.Internal);
7600 connector = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
7601 ok(connector != -1, "failed to create socket, error %u\n", WSAGetLastError());
7602 iret = connect(connector, (struct sockaddr *)&bindAddress, sizeof(bindAddress));
7603 ok(!iret, "failed to connect, error %u\n", WSAGetLastError());
7605 dwret = WaitForSingleObject(overlapped.hEvent, 1000);
7606 ok(!dwret, "wait failed\n");
7607 bytesReturned = 0xdeadbeef;
7608 SetLastError(0xdeadbeef);
7609 bret = GetOverlappedResult((HANDLE)listener, &overlapped, &bytesReturned, FALSE);
7610 todo_wine ok(!bret, "expected failure\n");
7611 todo_wine ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got error %u\n", GetLastError());
7612 todo_wine ok((NTSTATUS)overlapped.Internal == STATUS_BUFFER_TOO_SMALL, "got %#lx\n", overlapped.Internal);
7613 ok(!bytesReturned, "got size %u\n", bytesReturned);
7615 closesocket(acceptor);
7617 /* The above connection request is not accepted. */
7618 acceptor = accept(listener, NULL, NULL);
7619 todo_wine ok(acceptor != INVALID_SOCKET, "failed to accept, error %u\n", WSAGetLastError());
7620 closesocket(acceptor);
7622 closesocket(connector);
7624 acceptor = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
7625 ok(acceptor != -1, "failed to create socket, error %u\n", WSAGetLastError());
7627 overlapped.Internal = 0xdeadbeef;
7628 bret = pAcceptEx(listener, acceptor, buffer, 0, sizeof(struct sockaddr_in) + 15,
7629 sizeof(struct sockaddr_in) + 16, &bytesReturned, &overlapped);
7630 ok(bret == FALSE && WSAGetLastError() == ERROR_IO_PENDING, "AcceptEx on too small local address "
7631 "size returned %d + errno %d\n",
7632 bret, WSAGetLastError());
7633 ok(overlapped.Internal == STATUS_PENDING, "got %08x\n", (ULONG)overlapped.Internal);
7634 bret = CancelIo((HANDLE) listener);
7635 ok(bret, "Failed to cancel pending accept socket\n");
7637 overlapped.Internal = 0xdeadbeef;
7638 bret = pAcceptEx(listener, acceptor, buffer, 0, sizeof(struct sockaddr_in) + 16, 0,
7639 &bytesReturned, &overlapped);
7640 ok(bret == FALSE && WSAGetLastError() == WSAEFAULT,
7641 "AcceptEx on too small remote address size returned %d + errno %d\n", bret, WSAGetLastError());
7642 ok(overlapped.Internal == STATUS_PENDING, "got %08x\n", (ULONG)overlapped.Internal);
7644 overlapped.Internal = 0xdeadbeef;
7645 bret = pAcceptEx(listener, acceptor, buffer, 0, sizeof(struct sockaddr_in) + 16,
7646 sizeof(struct sockaddr_in) + 15, &bytesReturned, &overlapped);
7647 ok(bret == FALSE && WSAGetLastError() == ERROR_IO_PENDING,
7648 "AcceptEx on too small remote address size returned %d + errno %d\n", bret, WSAGetLastError());
7649 ok(overlapped.Internal == STATUS_PENDING, "got %08x\n", (ULONG)overlapped.Internal);
7650 bret = CancelIo((HANDLE) listener);
7651 ok(bret, "Failed to cancel pending accept socket\n");
7653 bret = pAcceptEx(listener, acceptor, buffer, 0,
7654 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
7655 &bytesReturned, NULL);
7656 ok(bret == FALSE && WSAGetLastError() == ERROR_INVALID_PARAMETER, "AcceptEx on a NULL overlapped "
7657 "returned %d + errno %d\n", bret, WSAGetLastError());
7659 bret = pAcceptEx(listener, acceptor, buffer, 0, 0, 0, &bytesReturned, NULL);
7660 ok(bret == FALSE && WSAGetLastError() == ERROR_INVALID_PARAMETER, "AcceptEx on a NULL overlapped "
7661 "returned %d + errno %d\n", bret, WSAGetLastError());
7663 overlapped.Internal = 0xdeadbeef;
7664 bret = pAcceptEx(listener, acceptor, buffer, 0,
7665 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
7666 &bytesReturned, &overlapped);
7667 ok(bret == FALSE && WSAGetLastError() == ERROR_IO_PENDING, "AcceptEx returned %d + errno %d\n", bret, WSAGetLastError());
7668 ok(overlapped.Internal == STATUS_PENDING, "got %08x\n", (ULONG)overlapped.Internal);
7670 /* try to accept into the same socket twice */
7671 overlapped.Internal = 0xdeadbeef;
7672 bret = pAcceptEx(listener, acceptor, buffer, 0,
7673 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
7674 &bytesReturned, &overlapped);
7675 ok(bret == FALSE && WSAGetLastError() == WSAEINVAL,
7676 "AcceptEx on already pending socket returned %d + errno %d\n", bret, WSAGetLastError());
7677 ok(overlapped.Internal == STATUS_PENDING, "got %08x\n", (ULONG)overlapped.Internal);
7679 /* try to connect a socket that's being accepted into */
7680 iret = connect(acceptor, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
7681 ok(iret == SOCKET_ERROR && WSAGetLastError() == WSAEINVAL,
7682 "connecting to acceptex acceptor succeeded? return %d + errno %d\n", iret, WSAGetLastError());
7684 bret = pConnectEx(acceptor, (struct sockaddr *)&bindAddress, sizeof(bindAddress),
7685 NULL, 0, &bytesReturned, &overlapped2);
7686 ok(!bret, "expected failure\n");
7687 ok(WSAGetLastError() == WSAEINVAL, "got error %u\n", WSAGetLastError());
7689 connector = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
7690 ok(connector != -1, "failed to create socket, error %u\n", WSAGetLastError());
7691 overlapped.Internal = 0xdeadbeef;
7692 iret = connect(connector, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
7693 ok(iret == 0, "connecting to accepting socket failed, error %d\n", WSAGetLastError());
7695 dwret = WaitForSingleObject(overlapped.hEvent, INFINITE);
7696 ok(dwret == WAIT_OBJECT_0, "Waiting for accept event failed with %d + errno %d\n", dwret, GetLastError());
7697 ok(overlapped.Internal == STATUS_SUCCESS, "got %08x\n", (ULONG)overlapped.Internal);
7699 bret = GetOverlappedResult((HANDLE)listener, &overlapped, &bytesReturned, FALSE);
7700 ok(bret, "GetOverlappedResult failed, error %d\n", GetLastError());
7701 ok(bytesReturned == 0, "bytesReturned isn't supposed to be %d\n", bytesReturned);
7703 closesocket(connector);
7704 connector = INVALID_SOCKET;
7705 closesocket(acceptor);
7707 /* Test short reads */
7709 acceptor = socket(AF_INET, SOCK_STREAM, 0);
7710 ok(acceptor != INVALID_SOCKET, "failed to create socket, error %u\n", GetLastError());
7711 connector = socket(AF_INET, SOCK_STREAM, 0);
7712 ok(connector != INVALID_SOCKET, "failed to create socket, error %u\n", GetLastError());
7713 overlapped.Internal = 0xdeadbeef;
7714 bret = pAcceptEx(listener, acceptor, buffer, 2,
7715 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
7716 &bytesReturned, &overlapped);
7717 ok(bret == FALSE && WSAGetLastError() == ERROR_IO_PENDING, "AcceptEx returned %d + errno %d\n", bret, WSAGetLastError());
7718 ok(overlapped.Internal == STATUS_PENDING, "got %08x\n", (ULONG)overlapped.Internal);
7720 connect_time = 0xdeadbeef;
7721 optlen = sizeof(connect_time);
7722 iret = getsockopt(connector, SOL_SOCKET, SO_CONNECT_TIME, (char *)&connect_time, &optlen);
7723 ok(!iret, "getsockopt failed %d\n", WSAGetLastError());
7724 ok(connect_time == ~0u, "unexpected connect time %u\n", connect_time);
7726 /* AcceptEx() still won't complete until we send data */
7727 iret = connect(connector, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
7728 ok(iret == 0, "connecting to accepting socket failed, error %d\n", WSAGetLastError());
7730 connect_time = 0xdeadbeef;
7731 optlen = sizeof(connect_time);
7732 iret = getsockopt(connector, SOL_SOCKET, SO_CONNECT_TIME, (char *)&connect_time, &optlen);
7733 ok(!iret, "getsockopt failed %d\n", WSAGetLastError());
7734 ok(connect_time < 0xdeadbeef, "unexpected connect time %u\n", connect_time);
7736 dwret = WaitForSingleObject(overlapped.hEvent, 0);
7737 ok(dwret == WAIT_TIMEOUT, "Waiting for accept event timeout failed with %d + errno %d\n", dwret, GetLastError());
7738 ok(overlapped.Internal == STATUS_PENDING, "got %08x\n", (ULONG)overlapped.Internal);
7740 iret = getsockname( connector, (struct sockaddr *)&peerAddress, &remoteSize);
7741 ok( !iret, "getsockname failed.\n");
7743 /* AcceptEx() could complete any time now */
7744 iret = send(connector, buffer, 1, 0);
7745 ok(iret == 1, "could not send 1 byte: send %d errno %d\n", iret, WSAGetLastError());
7747 dwret = WaitForSingleObject(overlapped.hEvent, 1000);
7748 ok(dwret == WAIT_OBJECT_0, "Waiting for accept event failed with %d + errno %d\n", dwret, GetLastError());
7749 ok(overlapped.Internal == STATUS_SUCCESS, "got %08x\n", (ULONG)overlapped.Internal);
7751 /* Check if the buffer from AcceptEx is decoded correctly */
7752 pGetAcceptExSockaddrs(buffer, 2, sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
7753 (struct sockaddr **)&readBindAddress, &localSize,
7754 (struct sockaddr **)&readRemoteAddress, &remoteSize);
7755 strcpy( ipbuffer, inet_ntoa(readBindAddress->sin_addr));
7756 ok( readBindAddress->sin_addr.s_addr == bindAddress.sin_addr.s_addr,
7757 "Local socket address is different %s != %s\n",
7758 ipbuffer, inet_ntoa(bindAddress.sin_addr));
7759 ok( readBindAddress->sin_port == bindAddress.sin_port,
7760 "Local socket port is different: %d != %d\n",
7761 readBindAddress->sin_port, bindAddress.sin_port);
7762 strcpy( ipbuffer, inet_ntoa(readRemoteAddress->sin_addr));
7763 ok( readRemoteAddress->sin_addr.s_addr == peerAddress.sin_addr.s_addr,
7764 "Remote socket address is different %s != %s\n",
7765 ipbuffer, inet_ntoa(peerAddress.sin_addr));
7766 ok( readRemoteAddress->sin_port == peerAddress.sin_port,
7767 "Remote socket port is different: %d != %d\n",
7768 readRemoteAddress->sin_port, peerAddress.sin_port);
7770 bret = GetOverlappedResult((HANDLE)listener, &overlapped, &bytesReturned, FALSE);
7771 ok(bret, "GetOverlappedResult failed, error %d\n", GetLastError());
7772 ok(bytesReturned == 1, "bytesReturned isn't supposed to be %d\n", bytesReturned);
7774 closesocket(connector);
7775 connector = INVALID_SOCKET;
7776 closesocket(acceptor);
7778 /* Test CF_DEFER & AcceptEx interaction */
7780 acceptor = socket(AF_INET, SOCK_STREAM, 0);
7781 ok(acceptor != INVALID_SOCKET, "failed to create socket, error %u\n", GetLastError());
7782 connector = socket(AF_INET, SOCK_STREAM, 0);
7783 ok(connector != INVALID_SOCKET, "failed to create socket, error %u\n", GetLastError());
7784 connector2 = socket(AF_INET, SOCK_STREAM, 0);
7785 ok(connector2 != INVALID_SOCKET, "failed to create socket, error %u\n", GetLastError());
7787 iret = set_blocking(connector, FALSE);
7788 ok(!iret, "failed to set nonblocking, error %u\n", GetLastError());
7789 iret = set_blocking(connector2, FALSE);
7790 ok(!iret, "failed to set nonblocking, error %u\n", GetLastError());
7792 /* Connect socket #1 */
7793 iret = connect(connector, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
7794 ok(iret == SOCKET_ERROR && WSAGetLastError() == WSAEWOULDBLOCK, "connecting to accepting socket failed, error %d\n", WSAGetLastError());
7796 buffer[0] = '0';
7798 FD_ZERO(&fds_accept);
7799 FD_SET(listener, &fds_accept);
7800 iret = select(0, &fds_accept, NULL, NULL, &timeout);
7801 ok(iret == 1, "wait timed out\n");
7803 acceptor2 = WSAAccept(listener, NULL, NULL, AlwaysDeferConditionFunc, 0);
7804 ok(acceptor2 == INVALID_SOCKET, "expected failure\n");
7805 ok(WSAGetLastError() == WSATRY_AGAIN, "got error %u\n", WSAGetLastError());
7806 bret = pAcceptEx(listener, acceptor, buffer, 0, sizeof(struct sockaddr_in) + 16,
7807 sizeof(struct sockaddr_in) + 16, &bytesReturned, &overlapped);
7808 ok(!bret, "expected failure\n");
7809 ok(WSAGetLastError() == ERROR_IO_PENDING, "got error %u\n", WSAGetLastError());
7811 FD_ZERO(&fds_send);
7812 FD_SET(connector, &fds_send);
7813 iret = select(0, NULL, &fds_send, NULL, &timeout);
7814 ok(iret == 1, "wait timed out\n");
7816 iret = send(connector, "1", 1, 0);
7817 ok(iret == 1, "got ret %d, error %u\n", iret, WSAGetLastError());
7819 iret = connect(connector2, (struct sockaddr *)&bindAddress, sizeof(bindAddress));
7820 ok(iret == SOCKET_ERROR, "expected failure\n");
7821 ok(WSAGetLastError() == WSAEWOULDBLOCK, "got error %u\n", WSAGetLastError());
7823 iret = select(0, &fds_accept, NULL, NULL, &timeout);
7824 ok(iret == 1, "wait timed out\n");
7826 acceptor2 = accept(listener, NULL, NULL);
7827 ok(acceptor2 != INVALID_SOCKET, "failed to accept, error %u\n", WSAGetLastError());
7828 closesocket(acceptor2);
7830 FD_ZERO(&fds_send);
7831 FD_SET(connector2, &fds_send);
7832 iret = select(0, NULL, &fds_send, NULL, &timeout);
7833 ok(iret == 1, "wait timed out\n");
7835 iret = send(connector2, "2", 1, 0);
7836 ok(iret == 1, "got ret %d, error %u\n", iret, WSAGetLastError());
7838 dwret = WaitForSingleObject(overlapped.hEvent, 0);
7839 ok(dwret == WAIT_OBJECT_0, "Waiting for accept event failed with %d + errno %d\n", dwret, GetLastError());
7841 bret = GetOverlappedResult((HANDLE)listener, &overlapped, &bytesReturned, FALSE);
7842 ok(bret, "GetOverlappedResult failed, error %d\n", GetLastError());
7843 ok(bytesReturned == 0, "bytesReturned isn't supposed to be %d\n", bytesReturned);
7845 set_blocking(acceptor, TRUE);
7846 iret = recv( acceptor, buffer, 2, 0);
7847 ok(iret == 1, "Failed to get data, %d, errno: %d\n", iret, WSAGetLastError());
7848 ok(buffer[0] == '1', "The wrong first client was accepted by acceptex: %c != 1\n", buffer[0]);
7850 closesocket(connector);
7851 closesocket(connector2);
7852 closesocket(acceptor);
7854 /* clean up in case of failures */
7855 while ((acceptor = accept(listener, NULL, NULL)) != INVALID_SOCKET)
7856 closesocket(acceptor);
7858 /* Disconnect during receive? */
7860 acceptor = socket(AF_INET, SOCK_STREAM, 0);
7861 ok(acceptor != INVALID_SOCKET, "failed to create socket, error %u\n", GetLastError());
7862 connector = socket(AF_INET, SOCK_STREAM, 0);
7863 ok(connector != INVALID_SOCKET, "failed to create socket, error %u\n", GetLastError());
7864 bret = pAcceptEx(listener, acceptor, buffer, sizeof(buffer) - 2*(sizeof(struct sockaddr_in) + 16),
7865 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
7866 &bytesReturned, &overlapped);
7867 ok(bret == FALSE && WSAGetLastError() == ERROR_IO_PENDING, "AcceptEx returned %d + errno %d\n", bret, WSAGetLastError());
7869 iret = connect(connector, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
7870 ok(iret == 0, "connecting to accepting socket failed, error %d\n", WSAGetLastError());
7872 closesocket(connector);
7873 connector = INVALID_SOCKET;
7875 dwret = WaitForSingleObject(overlapped.hEvent, 1000);
7876 ok(dwret == WAIT_OBJECT_0, "Waiting for accept event failed with %d + errno %d\n", dwret, GetLastError());
7878 bytesReturned = 123456;
7879 bret = GetOverlappedResult((HANDLE)listener, &overlapped, &bytesReturned, FALSE);
7880 ok(bret, "GetOverlappedResult failed, error %d\n", GetLastError());
7881 ok(bytesReturned == 0, "bytesReturned isn't supposed to be %d\n", bytesReturned);
7883 closesocket(acceptor);
7885 /* Test closing with pending requests */
7887 acceptor = socket(AF_INET, SOCK_STREAM, 0);
7888 ok(acceptor != INVALID_SOCKET, "failed to create socket, error %u\n", GetLastError());
7889 bret = pAcceptEx(listener, acceptor, buffer, sizeof(buffer) - 2*(sizeof(struct sockaddr_in) + 16),
7890 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
7891 &bytesReturned, &overlapped);
7892 ok(bret == FALSE && WSAGetLastError() == ERROR_IO_PENDING, "AcceptEx returned %d + errno %d\n", bret, WSAGetLastError());
7894 closesocket(acceptor);
7896 dwret = WaitForSingleObject(overlapped.hEvent, 1000);
7897 ok(dwret == WAIT_OBJECT_0,
7898 "Waiting for accept event failed with %d + errno %d\n", dwret, GetLastError());
7899 bret = GetOverlappedResult((HANDLE)listener, &overlapped, &bytesReturned, FALSE);
7900 ok(!bret && GetLastError() == ERROR_OPERATION_ABORTED, "GetOverlappedResult failed, error %d\n", GetLastError());
7902 acceptor = socket(AF_INET, SOCK_STREAM, 0);
7903 ok(acceptor != INVALID_SOCKET, "failed to create socket, error %u\n", GetLastError());
7904 bret = pAcceptEx(listener, acceptor, buffer, sizeof(buffer) - 2*(sizeof(struct sockaddr_in) + 16),
7905 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
7906 &bytesReturned, &overlapped);
7907 ok(bret == FALSE && WSAGetLastError() == ERROR_IO_PENDING, "AcceptEx returned %d + errno %d\n", bret, WSAGetLastError());
7909 CancelIo((HANDLE) acceptor);
7911 dwret = WaitForSingleObject(overlapped.hEvent, 1000);
7912 ok(dwret == WAIT_TIMEOUT, "Waiting for timeout failed with %d + errno %d\n", dwret, GetLastError());
7914 closesocket(acceptor);
7916 acceptor = socket(AF_INET, SOCK_STREAM, 0);
7917 ok(acceptor != INVALID_SOCKET, "failed to create socket, error %u\n", GetLastError());
7918 bret = pAcceptEx(listener, acceptor, buffer, sizeof(buffer) - 2*(sizeof(struct sockaddr_in) + 16),
7919 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
7920 &bytesReturned, &overlapped);
7921 ok(bret == FALSE && WSAGetLastError() == ERROR_IO_PENDING, "AcceptEx returned %d + errno %d\n", bret, WSAGetLastError());
7923 closesocket(listener);
7925 dwret = WaitForSingleObject(overlapped.hEvent, 1000);
7926 ok(dwret == WAIT_OBJECT_0, "Waiting for accept event failed with %d + errno %d\n", dwret, GetLastError());
7928 bret = GetOverlappedResult((HANDLE)listener, &overlapped, &bytesReturned, FALSE);
7929 ok(!bret && GetLastError() == ERROR_OPERATION_ABORTED, "GetOverlappedResult failed, error %d\n", GetLastError());
7931 CloseHandle(overlapped.hEvent);
7932 CloseHandle(overlapped2.hEvent);
7933 closesocket(acceptor);
7934 closesocket(connector2);
7937 static void test_shutdown(void)
7939 struct sockaddr_in addr, server_addr, client_addr;
7940 SOCKET listener, client, server;
7941 OVERLAPPED overlapped = {0};
7942 DWORD size, flags = 0;
7943 int ret, addrlen;
7944 char buffer[5];
7945 WSABUF wsabuf;
7947 overlapped.hEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
7948 listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
7949 ok(listener != INVALID_SOCKET, "failed to create listener socket, error %d\n", WSAGetLastError());
7951 memset(&addr, 0, sizeof(addr));
7952 addr.sin_family = AF_INET;
7953 addr.sin_addr.s_addr = inet_addr("127.0.0.1");
7954 ret = bind(listener, (struct sockaddr *)&addr, sizeof(addr));
7955 ok(!ret, "failed to bind, error %u\n", WSAGetLastError());
7956 addrlen = sizeof(server_addr);
7957 ret = getsockname(listener, (struct sockaddr *)&server_addr, &addrlen);
7958 ok(!ret, "failed to get address, error %u\n", WSAGetLastError());
7960 ret = listen(listener, 1);
7961 ok(!ret, "failed to listen, error %u\n", WSAGetLastError());
7963 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
7964 ok(client != -1, "failed to create socket, error %u\n", WSAGetLastError());
7966 WSASetLastError(0xdeadbeef);
7967 ret = shutdown(client, SD_SEND);
7968 ok(ret == -1, "expected failure\n");
7969 ok(WSAGetLastError() == WSAENOTCONN, "got error %u\n", WSAGetLastError());
7971 WSASetLastError(0xdeadbeef);
7972 ret = shutdown(client, SD_RECEIVE);
7973 ok(ret == -1, "expected failure\n");
7974 ok(WSAGetLastError() == WSAENOTCONN, "got error %u\n", WSAGetLastError());
7976 ret = connect(client, (struct sockaddr *)&server_addr, sizeof(server_addr));
7977 ok(!ret, "failed to connect, error %u\n", WSAGetLastError());
7978 server = accept(listener, NULL, NULL);
7979 ok(server != -1, "failed to accept, error %u\n", WSAGetLastError());
7980 set_blocking(client, FALSE);
7982 WSASetLastError(0xdeadbeef);
7983 ret = shutdown(client, SD_SEND);
7984 ok(!ret, "expected success\n");
7985 ok(!WSAGetLastError() || WSAGetLastError() == 0xdeadbeef /* < 7 */, "got error %u\n", WSAGetLastError());
7987 WSASetLastError(0xdeadbeef);
7988 ret = shutdown(client, SD_SEND);
7989 ok(!ret, "expected success\n");
7990 ok(!WSAGetLastError() || WSAGetLastError() == 0xdeadbeef /* < 7 */, "got error %u\n", WSAGetLastError());
7992 WSASetLastError(0xdeadbeef);
7993 ret = send(client, "test", 5, 0);
7994 ok(ret == -1, "got %d\n", ret);
7995 todo_wine ok(WSAGetLastError() == WSAESHUTDOWN, "got error %u\n", WSAGetLastError());
7997 ret = recv(server, buffer, sizeof(buffer), 0);
7998 ok(!ret, "got %d\n", ret);
7999 ret = recv(server, buffer, sizeof(buffer), 0);
8000 ok(!ret, "got %d\n", ret);
8002 WSASetLastError(0xdeadbeef);
8003 ret = shutdown(server, SD_RECEIVE);
8004 ok(!ret, "expected success\n");
8005 ok(!WSAGetLastError() || WSAGetLastError() == 0xdeadbeef /* < 7 */, "got error %u\n", WSAGetLastError());
8007 WSASetLastError(0xdeadbeef);
8008 ret = recv(server, buffer, sizeof(buffer), 0);
8009 ok(ret == -1, "got %d\n", ret);
8010 ok(WSAGetLastError() == WSAESHUTDOWN, "got error %u\n", WSAGetLastError());
8012 ret = send(server, "test", 5, 0);
8013 ok(ret == 5, "got %d\n", ret);
8015 ret = sync_recv(client, buffer, sizeof(buffer), 0);
8016 ok(ret == 5, "got %d\n", ret);
8017 ok(!strcmp(buffer, "test"), "got %s\n", debugstr_an(buffer, ret));
8019 WSASetLastError(0xdeadbeef);
8020 ret = shutdown(client, SD_RECEIVE);
8021 ok(!ret, "expected success\n");
8022 ok(!WSAGetLastError() || WSAGetLastError() == 0xdeadbeef /* < 7 */, "got error %u\n", WSAGetLastError());
8024 WSASetLastError(0xdeadbeef);
8025 ret = recv(client, buffer, sizeof(buffer), 0);
8026 ok(ret == -1, "got %d\n", ret);
8027 ok(WSAGetLastError() == WSAESHUTDOWN, "got error %u\n", WSAGetLastError());
8029 WSASetLastError(0xdeadbeef);
8030 ret = recv(client, buffer, sizeof(buffer), 0);
8031 ok(ret == -1, "got %d\n", ret);
8032 ok(WSAGetLastError() == WSAESHUTDOWN, "got error %u\n", WSAGetLastError());
8034 WSASetLastError(0xdeadbeef);
8035 ret = shutdown(server, SD_SEND);
8036 ok(!ret, "expected success\n");
8037 ok(!WSAGetLastError() || WSAGetLastError() == 0xdeadbeef /* < 7 */, "got error %u\n", WSAGetLastError());
8039 WSASetLastError(0xdeadbeef);
8040 ret = send(server, "test", 5, 0);
8041 ok(ret == -1, "got %d\n", ret);
8042 todo_wine ok(WSAGetLastError() == WSAESHUTDOWN, "got error %u\n", WSAGetLastError());
8044 addrlen = sizeof(addr);
8045 ret = getpeername(client, (struct sockaddr *)&addr, &addrlen);
8046 todo_wine ok(!ret, "got error %u\n", WSAGetLastError());
8047 todo_wine ok(!memcmp(&addr, &server_addr, sizeof(server_addr)), "address didn't match\n");
8049 addrlen = sizeof(client_addr);
8050 ret = getsockname(client, (struct sockaddr *)&client_addr, &addrlen);
8051 ok(!ret, "got error %u\n", WSAGetLastError());
8052 addrlen = sizeof(addr);
8053 ret = getpeername(server, (struct sockaddr *)&addr, &addrlen);
8054 todo_wine ok(!ret, "got error %u\n", WSAGetLastError());
8055 todo_wine ok(!memcmp(&addr, &client_addr, sizeof(addr)), "address didn't match\n");
8057 WSASetLastError(0xdeadbeef);
8058 ret = connect(client, (struct sockaddr *)&server_addr, sizeof(server_addr));
8059 ok(ret == -1, "got %d\n", ret);
8060 ok(WSAGetLastError() == WSAEISCONN, "got error %u\n", WSAGetLastError());
8062 WSASetLastError(0xdeadbeef);
8063 ret = shutdown(client, 0xdeadbeef);
8064 ok(ret == -1, "expected failure\n");
8065 ok(WSAGetLastError() == WSAEINVAL, "got error %u\n", WSAGetLastError());
8067 closesocket(client);
8068 closesocket(server);
8070 /* Test SD_BOTH. */
8072 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
8073 ok(client != -1, "failed to create socket, error %u\n", WSAGetLastError());
8074 ret = connect(client, (struct sockaddr *)&server_addr, sizeof(server_addr));
8075 ok(!ret, "failed to connect, error %u\n", WSAGetLastError());
8076 server = accept(listener, NULL, NULL);
8077 ok(server != -1, "failed to accept, error %u\n", WSAGetLastError());
8079 WSASetLastError(0xdeadbeef);
8080 ret = shutdown(client, SD_BOTH);
8081 ok(!ret, "expected success\n");
8082 ok(!WSAGetLastError() || WSAGetLastError() == 0xdeadbeef /* < 7 */, "got error %u\n", WSAGetLastError());
8084 WSASetLastError(0xdeadbeef);
8085 ret = recv(client, buffer, sizeof(buffer), 0);
8086 ok(ret == -1, "got %d\n", ret);
8087 ok(WSAGetLastError() == WSAESHUTDOWN, "got error %u\n", WSAGetLastError());
8089 WSASetLastError(0xdeadbeef);
8090 ret = send(client, "test", 5, 0);
8091 ok(ret == -1, "got %d\n", ret);
8092 todo_wine ok(WSAGetLastError() == WSAESHUTDOWN, "got error %u\n", WSAGetLastError());
8094 ret = recv(server, buffer, sizeof(buffer), 0);
8095 ok(!ret, "got %d\n", ret);
8097 WSASetLastError(0xdeadbeef);
8098 ret = shutdown(server, SD_BOTH);
8099 ok(!ret, "expected success\n");
8100 ok(!WSAGetLastError() || WSAGetLastError() == 0xdeadbeef /* < 7 */, "got error %u\n", WSAGetLastError());
8102 WSASetLastError(0xdeadbeef);
8103 ret = recv(server, buffer, sizeof(buffer), 0);
8104 ok(ret == -1, "got %d\n", ret);
8105 ok(WSAGetLastError() == WSAESHUTDOWN, "got error %u\n", WSAGetLastError());
8107 WSASetLastError(0xdeadbeef);
8108 ret = send(server, "test", 5, 0);
8109 ok(ret == -1, "got %d\n", ret);
8110 todo_wine ok(WSAGetLastError() == WSAESHUTDOWN, "got error %u\n", WSAGetLastError());
8112 addrlen = sizeof(addr);
8113 ret = getpeername(client, (struct sockaddr *)&addr, &addrlen);
8114 todo_wine ok(!ret, "got error %u\n", WSAGetLastError());
8115 todo_wine ok(!memcmp(&addr, &server_addr, sizeof(server_addr)), "address didn't match\n");
8117 addrlen = sizeof(client_addr);
8118 ret = getsockname(client, (struct sockaddr *)&client_addr, &addrlen);
8119 ok(!ret, "got error %u\n", WSAGetLastError());
8120 addrlen = sizeof(addr);
8121 ret = getpeername(server, (struct sockaddr *)&addr, &addrlen);
8122 todo_wine ok(!ret, "got error %u\n", WSAGetLastError());
8123 todo_wine ok(!memcmp(&addr, &client_addr, sizeof(addr)), "address didn't match\n");
8125 closesocket(client);
8126 closesocket(server);
8128 /* Test shutting down with async I/O pending. */
8130 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
8131 ok(client != -1, "failed to create socket, error %u\n", WSAGetLastError());
8132 ret = connect(client, (struct sockaddr *)&server_addr, sizeof(server_addr));
8133 ok(!ret, "failed to connect, error %u\n", WSAGetLastError());
8134 server = accept(listener, NULL, NULL);
8135 ok(server != -1, "failed to accept, error %u\n", WSAGetLastError());
8136 set_blocking(client, FALSE);
8138 wsabuf.buf = buffer;
8139 wsabuf.len = sizeof(buffer);
8140 WSASetLastError(0xdeadbeef);
8141 ret = WSARecv(client, &wsabuf, 1, &size, &flags, &overlapped, NULL);
8142 ok(ret == -1, "got %d\n", ret);
8143 ok(WSAGetLastError() == ERROR_IO_PENDING, "got error %u\n", WSAGetLastError());
8145 ret = shutdown(client, SD_RECEIVE);
8146 ok(!ret, "got error %u\n", WSAGetLastError());
8148 WSASetLastError(0xdeadbeef);
8149 ret = WSARecv(client, &wsabuf, 1, &size, &flags, NULL, NULL);
8150 ok(ret == -1, "got %d\n", ret);
8151 ok(WSAGetLastError() == WSAESHUTDOWN, "got error %u\n", WSAGetLastError());
8153 ret = send(server, "test", 5, 0);
8154 ok(ret == 5, "got %d\n", ret);
8156 ret = WaitForSingleObject(overlapped.hEvent, 1000);
8157 ok(!ret, "wait timed out\n");
8158 size = 0xdeadbeef;
8159 ret = GetOverlappedResult((HANDLE)client, &overlapped, &size, FALSE);
8160 ok(ret, "got error %u\n", GetLastError());
8161 ok(size == 5, "got size %u\n", size);
8162 ok(!strcmp(buffer, "test"), "got %s\n", debugstr_an(buffer, size));
8164 WSASetLastError(0xdeadbeef);
8165 ret = WSARecv(client, &wsabuf, 1, &size, &flags, &overlapped, NULL);
8166 ok(ret == -1, "got %d\n", ret);
8167 ok(WSAGetLastError() == WSAESHUTDOWN, "got error %u\n", WSAGetLastError());
8169 WSASetLastError(0xdeadbeef);
8170 ret = WSARecv(server, &wsabuf, 1, &size, &flags, &overlapped, NULL);
8171 ok(ret == -1, "got %d\n", ret);
8172 ok(WSAGetLastError() == ERROR_IO_PENDING, "got error %u\n", WSAGetLastError());
8174 ret = shutdown(client, SD_SEND);
8175 ok(!ret, "got error %u\n", WSAGetLastError());
8177 ret = WaitForSingleObject(overlapped.hEvent, 1000);
8178 ok(!ret, "wait timed out\n");
8179 size = 0xdeadbeef;
8180 ret = GetOverlappedResult((HANDLE)client, &overlapped, &size, FALSE);
8181 ok(ret, "got error %u\n", GetLastError());
8182 ok(!size, "got size %u\n", size);
8184 closesocket(client);
8185 closesocket(server);
8187 /* Test shutting down a listening socket. */
8189 WSASetLastError(0xdeadbeef);
8190 ret = shutdown(listener, SD_SEND);
8191 ok(ret == -1, "expected failure\n");
8192 ok(WSAGetLastError() == WSAENOTCONN, "got error %u\n", WSAGetLastError());
8194 WSASetLastError(0xdeadbeef);
8195 ret = shutdown(listener, SD_RECEIVE);
8196 ok(ret == -1, "expected failure\n");
8197 ok(WSAGetLastError() == WSAENOTCONN, "got error %u\n", WSAGetLastError());
8199 closesocket(listener);
8201 /* Test shutting down UDP sockets. */
8203 client = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
8204 server = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
8205 memset(&addr, 0, sizeof(addr));
8206 addr.sin_family = AF_INET;
8207 addr.sin_addr.s_addr = inet_addr("127.0.0.1");
8208 ret = bind(server, (struct sockaddr *)&addr, sizeof(addr));
8209 ok(!ret, "failed to bind, error %u\n", WSAGetLastError());
8210 addrlen = sizeof(server_addr);
8211 ret = getsockname(server, (struct sockaddr *)&server_addr, &addrlen);
8212 ok(!ret, "failed to get address, error %u\n", WSAGetLastError());
8213 set_blocking(server, FALSE);
8215 WSASetLastError(0xdeadbeef);
8216 ret = shutdown(server, SD_RECEIVE);
8217 ok(!ret, "expected success\n");
8218 ok(!WSAGetLastError() || WSAGetLastError() == 0xdeadbeef /* < 7 */, "got error %u\n", WSAGetLastError());
8220 WSASetLastError(0xdeadbeef);
8221 ret = recvfrom(server, buffer, sizeof(buffer), 0, NULL, NULL);
8222 ok(ret == -1, "got %d\n", ret);
8223 ok(WSAGetLastError() == WSAESHUTDOWN, "got error %u\n", WSAGetLastError());
8225 ret = sendto(client, "test", 5, 0, (struct sockaddr *)&server_addr, sizeof(server_addr));
8226 ok(ret == 5, "got %d\n", ret);
8228 WSASetLastError(0xdeadbeef);
8229 ret = shutdown(client, SD_SEND);
8230 ok(!ret, "expected success\n");
8231 ok(!WSAGetLastError() || WSAGetLastError() == 0xdeadbeef /* < 7 */, "got error %u\n", WSAGetLastError());
8233 WSASetLastError(0xdeadbeef);
8234 ret = shutdown(client, SD_SEND);
8235 ok(!ret, "expected success\n");
8236 ok(!WSAGetLastError() || WSAGetLastError() == 0xdeadbeef /* < 7 */, "got error %u\n", WSAGetLastError());
8238 WSASetLastError(0xdeadbeef);
8239 ret = sendto(client, "test", 5, 0, (struct sockaddr *)&server_addr, sizeof(server_addr));
8240 ok(ret == -1, "got %d\n", ret);
8241 todo_wine ok(WSAGetLastError() == WSAESHUTDOWN, "got error %u\n", WSAGetLastError());
8243 closesocket(client);
8244 closesocket(server);
8246 CloseHandle(overlapped.hEvent);
8249 static void test_DisconnectEx(void)
8251 struct sockaddr_in server_addr, client_addr, addr;
8252 GUID disconnectex_guid = WSAID_DISCONNECTEX;
8253 SOCKET listener, server, client;
8254 LPFN_DISCONNECTEX pDisconnectEx;
8255 OVERLAPPED overlapped = {0};
8256 int addrlen, ret;
8257 char buffer[5];
8258 DWORD size;
8260 overlapped.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
8262 client = socket(AF_INET, SOCK_STREAM, 0);
8263 ok(client != INVALID_SOCKET, "failed to create connector socket, error %u\n", WSAGetLastError());
8265 ret = WSAIoctl(client, SIO_GET_EXTENSION_FUNCTION_POINTER, &disconnectex_guid, sizeof(disconnectex_guid),
8266 &pDisconnectEx, sizeof(pDisconnectEx), &size, NULL, NULL);
8267 if (ret)
8269 win_skip("WSAIoctl failed to get DisconnectEx, error %d\n", WSAGetLastError());
8270 closesocket(client);
8271 return;
8274 listener = socket(AF_INET, SOCK_STREAM, 0);
8275 ok(listener != INVALID_SOCKET, "failed to create listener socket, error %d\n", WSAGetLastError());
8277 memset(&addr, 0, sizeof(addr));
8278 addr.sin_family = AF_INET;
8279 addr.sin_addr.s_addr = inet_addr("127.0.0.1");
8280 ret = bind(listener, (struct sockaddr *)&addr, sizeof(addr));
8281 ok(!ret, "failed to bind, error %u\n", WSAGetLastError());
8282 addrlen = sizeof(server_addr);
8283 ret = getsockname(listener, (struct sockaddr *)&server_addr, &addrlen);
8284 ok(!ret, "failed to get address, error %u\n", WSAGetLastError());
8285 ret = listen(listener, 1);
8286 ok(!ret, "failed to listen, error %u\n", WSAGetLastError());
8288 WSASetLastError(0xdeadbeef);
8289 ret = pDisconnectEx(INVALID_SOCKET, &overlapped, 0, 0);
8290 ok(!ret, "expected failure\n");
8291 ok(WSAGetLastError() == WSAENOTSOCK, "got error %u\n", WSAGetLastError());
8293 WSASetLastError(0xdeadbeef);
8294 ret = pDisconnectEx(client, &overlapped, 0, 0);
8295 ok(!ret, "expected failure\n");
8296 ok(WSAGetLastError() == WSAENOTCONN, "got error %u\n", WSAGetLastError());
8298 ret = connect(client, (struct sockaddr *)&server_addr, sizeof(server_addr));
8299 ok(!ret, "failed to connect, error %u\n", WSAGetLastError());
8300 server = accept(listener, NULL, NULL);
8301 ok(server != INVALID_SOCKET, "failed to accept, error %u\n", WSAGetLastError());
8303 WSASetLastError(0xdeadbeef);
8304 ret = pDisconnectEx(client, &overlapped, 0, 0);
8305 ok(!ret, "expected failure\n");
8306 ok(WSAGetLastError() == ERROR_IO_PENDING, "got error %u\n", WSAGetLastError());
8308 ret = WaitForSingleObject(overlapped.hEvent, 1000);
8309 ok(!ret, "wait timed out\n");
8310 size = 0xdeadbeef;
8311 ret = GetOverlappedResult((HANDLE)client, &overlapped, &size, FALSE);
8312 ok(ret, "got error %u\n", GetLastError());
8313 ok(!size, "got size %u\n", size);
8315 ret = connect(client, (struct sockaddr *)&server_addr, sizeof(server_addr));
8316 ok(ret == -1, "expected failure\n");
8317 ok(WSAGetLastError() == WSAEISCONN, "got error %u\n", WSAGetLastError());
8319 WSASetLastError(0xdeadbeef);
8320 ret = send(client, "test", 5, 0);
8321 ok(ret == -1, "expected failure\n");
8322 todo_wine ok(WSAGetLastError() == WSAESHUTDOWN, "got error %u\n", WSAGetLastError());
8324 ret = recv(server, buffer, sizeof(buffer), 0);
8325 ok(!ret, "got %d\n", ret);
8327 ret = send(server, "test", 5, 0);
8328 ok(ret == 5, "got %d\n", ret);
8330 ret = recv(client, buffer, sizeof(buffer), 0);
8331 ok(ret == 5, "got %d\n", ret);
8332 ok(!strcmp(buffer, "test"), "got %s\n", debugstr_an(buffer, ret));
8334 addrlen = sizeof(addr);
8335 ret = getpeername(client, (struct sockaddr *)&addr, &addrlen);
8336 ok(!ret, "got error %u\n", WSAGetLastError());
8337 ok(!memcmp(&addr, &server_addr, sizeof(server_addr)), "address didn't match\n");
8339 addrlen = sizeof(client_addr);
8340 ret = getsockname(client, (struct sockaddr *)&client_addr, &addrlen);
8341 ok(!ret, "got error %u\n", WSAGetLastError());
8342 addrlen = sizeof(addr);
8343 ret = getpeername(server, (struct sockaddr *)&addr, &addrlen);
8344 ok(!ret, "got error %u\n", WSAGetLastError());
8345 ok(!memcmp(&addr, &client_addr, sizeof(addr)), "address didn't match\n");
8347 closesocket(client);
8348 closesocket(server);
8350 /* Test the synchronous case. */
8352 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
8353 ok(client != -1, "failed to create socket, error %u\n", WSAGetLastError());
8354 ret = connect(client, (struct sockaddr *)&server_addr, sizeof(server_addr));
8355 ok(!ret, "failed to connect, error %u\n", WSAGetLastError());
8356 server = accept(listener, NULL, NULL);
8357 ok(server != -1, "failed to accept, error %u\n", WSAGetLastError());
8359 WSASetLastError(0xdeadbeef);
8360 ret = pDisconnectEx(client, NULL, 0, 0);
8361 ok(ret, "expected success\n");
8362 ok(!WSAGetLastError() || WSAGetLastError() == 0xdeadbeef /* < 7 */, "got error %u\n", WSAGetLastError());
8364 WSASetLastError(0xdeadbeef);
8365 ret = pDisconnectEx(client, NULL, 0, 0);
8366 ok(ret, "expected success\n");
8367 ok(!WSAGetLastError() || WSAGetLastError() == 0xdeadbeef /* < 7 */, "got error %u\n", WSAGetLastError());
8369 ret = connect(client, (struct sockaddr *)&server_addr, sizeof(server_addr));
8370 ok(ret == -1, "expected failure\n");
8371 ok(WSAGetLastError() == WSAEISCONN, "got error %u\n", WSAGetLastError());
8373 WSASetLastError(0xdeadbeef);
8374 ret = send(client, "test", 5, 0);
8375 ok(ret == -1, "expected failure\n");
8376 todo_wine ok(WSAGetLastError() == WSAESHUTDOWN, "got error %u\n", WSAGetLastError());
8378 ret = recv(server, buffer, sizeof(buffer), 0);
8379 ok(!ret, "got %d\n", ret);
8381 ret = send(server, "test", 5, 0);
8382 ok(ret == 5, "got %d\n", ret);
8384 ret = recv(client, buffer, sizeof(buffer), 0);
8385 ok(ret == 5, "got %d\n", ret);
8386 ok(!strcmp(buffer, "test"), "got %s\n", debugstr_an(buffer, ret));
8388 addrlen = sizeof(addr);
8389 ret = getpeername(client, (struct sockaddr *)&addr, &addrlen);
8390 ok(!ret, "got error %u\n", WSAGetLastError());
8391 ok(!memcmp(&addr, &server_addr, sizeof(server_addr)), "address didn't match\n");
8393 addrlen = sizeof(client_addr);
8394 ret = getsockname(client, (struct sockaddr *)&client_addr, &addrlen);
8395 ok(!ret, "got error %u\n", WSAGetLastError());
8396 addrlen = sizeof(addr);
8397 ret = getpeername(server, (struct sockaddr *)&addr, &addrlen);
8398 ok(!ret, "got error %u\n", WSAGetLastError());
8399 ok(!memcmp(&addr, &client_addr, sizeof(addr)), "address didn't match\n");
8401 closesocket(client);
8402 closesocket(server);
8404 closesocket(listener);
8405 CloseHandle(overlapped.hEvent);
8408 #define compare_file(h,s,o) compare_file2(h,s,o,__FILE__,__LINE__)
8410 static void compare_file2(HANDLE handle, SOCKET sock, int offset, const char *file, int line)
8412 char buf1[256], buf2[256];
8413 BOOL success;
8414 int i = 0;
8416 SetFilePointer(handle, offset, NULL, FILE_BEGIN);
8417 while (1)
8419 DWORD n1 = 0, n2 = 0;
8421 success = ReadFile(handle, buf1, sizeof(buf1), &n1, NULL);
8422 ok_(file,line)(success, "Failed to read from file.\n");
8423 if (success && n1 == 0)
8424 break;
8425 else if(!success)
8426 return;
8427 n2 = recv(sock, buf2, n1, 0);
8428 ok_(file,line)(n1 == n2, "Block %d size mismatch (%d != %d)\n", i, n1, n2);
8429 ok_(file,line)(memcmp(buf1, buf2, n2) == 0, "Block %d failed\n", i);
8430 i++;
8434 static void test_TransmitFile(void)
8436 DWORD num_bytes, err, file_size, total_sent;
8437 GUID transmitFileGuid = WSAID_TRANSMITFILE;
8438 LPFN_TRANSMITFILE pTransmitFile = NULL;
8439 HANDLE file = INVALID_HANDLE_VALUE;
8440 char header_msg[] = "hello world";
8441 char footer_msg[] = "goodbye!!!";
8442 char system_ini_path[MAX_PATH];
8443 struct sockaddr_in bindAddress;
8444 TRANSMIT_FILE_BUFFERS buffers;
8445 SOCKET client, server, dest;
8446 WSAOVERLAPPED ov;
8447 char buf[256];
8448 int iret, len;
8449 BOOL bret;
8451 memset( &ov, 0, sizeof(ov) );
8453 /* Setup sockets for testing TransmitFile */
8454 client = socket(AF_INET, SOCK_STREAM, 0);
8455 ok(client != INVALID_SOCKET, "failed to create socket, error %u\n", GetLastError());
8456 server = socket(AF_INET, SOCK_STREAM, 0);
8457 ok(server != INVALID_SOCKET, "failed to create socket, error %u\n", GetLastError());
8458 iret = WSAIoctl(client, SIO_GET_EXTENSION_FUNCTION_POINTER, &transmitFileGuid, sizeof(transmitFileGuid),
8459 &pTransmitFile, sizeof(pTransmitFile), &num_bytes, NULL, NULL);
8460 ok(!iret, "failed to get TransmitFile, error %u\n", GetLastError());
8461 GetSystemWindowsDirectoryA(system_ini_path, MAX_PATH );
8462 strcat(system_ini_path, "\\system.ini");
8463 file = CreateFileA(system_ini_path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_ALWAYS, 0x0, NULL);
8464 ok(file != INVALID_HANDLE_VALUE, "failed to open file, error %u\n", GetLastError());
8465 file_size = GetFileSize(file, NULL);
8467 /* Test TransmitFile with an invalid socket */
8468 bret = pTransmitFile(INVALID_SOCKET, file, 0, 0, NULL, NULL, 0);
8469 err = WSAGetLastError();
8470 ok(!bret, "TransmitFile succeeded unexpectedly.\n");
8471 ok(err == WSAENOTSOCK, "TransmitFile triggered unexpected errno (%d != %d)\n", err, WSAENOTSOCK);
8473 /* Test a bogus TransmitFile without a connected socket */
8474 bret = pTransmitFile(client, NULL, 0, 0, NULL, NULL, TF_REUSE_SOCKET);
8475 err = WSAGetLastError();
8476 ok(!bret, "TransmitFile succeeded unexpectedly.\n");
8477 ok(err == WSAENOTCONN, "TransmitFile triggered unexpected errno (%d != %d)\n", err, WSAENOTCONN);
8479 /* Setup a properly connected socket for transfers */
8480 memset(&bindAddress, 0, sizeof(bindAddress));
8481 bindAddress.sin_family = AF_INET;
8482 bindAddress.sin_port = htons(SERVERPORT+1);
8483 bindAddress.sin_addr.s_addr = inet_addr("127.0.0.1");
8484 iret = bind(server, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
8485 ok(!iret, "failed to bind socket, error %u\n", GetLastError());
8486 iret = listen(server, 1);
8487 ok(!iret, "failed to listen, error %u\n", GetLastError());
8488 iret = connect(client, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
8489 ok(!iret, "failed to connect, error %u\n", GetLastError());
8490 len = sizeof(bindAddress);
8491 dest = accept(server, (struct sockaddr*)&bindAddress, &len);
8492 ok(dest != INVALID_SOCKET, "failed to accept, error %u\n", GetLastError());
8493 iret = set_blocking(dest, FALSE);
8494 ok(!iret, "failed to set nonblocking, error %u\n", GetLastError());
8496 /* Test TransmitFile with no possible buffer */
8497 bret = pTransmitFile(client, NULL, 0, 0, NULL, NULL, 0);
8498 ok(bret, "TransmitFile failed unexpectedly.\n");
8499 iret = recv(dest, buf, sizeof(buf), 0);
8500 ok(iret == -1, "Returned an unexpected buffer from TransmitFile (%d != -1).\n", iret);
8502 /* Test TransmitFile with only buffer data */
8503 buffers.Head = &header_msg[0];
8504 buffers.HeadLength = sizeof(header_msg);
8505 buffers.Tail = &footer_msg[0];
8506 buffers.TailLength = sizeof(footer_msg);
8507 bret = pTransmitFile(client, NULL, 0, 0, NULL, &buffers, 0);
8508 ok(bret, "TransmitFile failed unexpectedly.\n");
8509 iret = recv(dest, buf, sizeof(buf), 0);
8510 ok(iret == sizeof(header_msg)+sizeof(footer_msg),
8511 "Returned an unexpected buffer from TransmitFile: %d\n", iret );
8512 ok(memcmp(&buf[0], &header_msg[0], sizeof(header_msg)) == 0,
8513 "TransmitFile header buffer did not match!\n");
8514 ok(memcmp(&buf[sizeof(header_msg)], &footer_msg[0], sizeof(footer_msg)) == 0,
8515 "TransmitFile footer buffer did not match!\n");
8517 /* Test TransmitFile with only file data */
8518 bret = pTransmitFile(client, file, 0, 0, NULL, NULL, 0);
8519 ok(bret, "TransmitFile failed unexpectedly.\n");
8520 compare_file(file, dest, 0);
8522 /* Test TransmitFile with both file and buffer data */
8523 buffers.Head = &header_msg[0];
8524 buffers.HeadLength = sizeof(header_msg);
8525 buffers.Tail = &footer_msg[0];
8526 buffers.TailLength = sizeof(footer_msg);
8527 SetFilePointer(file, 0, NULL, FILE_BEGIN);
8528 bret = pTransmitFile(client, file, 0, 0, NULL, &buffers, 0);
8529 ok(bret, "TransmitFile failed unexpectedly.\n");
8530 iret = recv(dest, buf, sizeof(header_msg), 0);
8531 ok(memcmp(buf, &header_msg[0], sizeof(header_msg)) == 0,
8532 "TransmitFile header buffer did not match!\n");
8533 compare_file(file, dest, 0);
8534 iret = recv(dest, buf, sizeof(footer_msg), 0);
8535 ok(memcmp(buf, &footer_msg[0], sizeof(footer_msg)) == 0,
8536 "TransmitFile footer buffer did not match!\n");
8538 /* Test overlapped TransmitFile */
8539 ov.hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
8540 SetFilePointer(file, 0, NULL, FILE_BEGIN);
8541 bret = pTransmitFile(client, file, 0, 0, &ov, NULL, 0);
8542 err = WSAGetLastError();
8543 ok(!bret, "TransmitFile succeeded unexpectedly.\n");
8544 ok(err == ERROR_IO_PENDING, "TransmitFile triggered unexpected errno (%d != %d)\n",
8545 err, ERROR_IO_PENDING);
8546 iret = WaitForSingleObject(ov.hEvent, 2000);
8547 ok(iret == WAIT_OBJECT_0, "Overlapped TransmitFile failed.\n");
8548 WSAGetOverlappedResult(client, &ov, &total_sent, FALSE, NULL);
8549 ok(total_sent == file_size,
8550 "Overlapped TransmitFile sent an unexpected number of bytes (%d != %d).\n",
8551 total_sent, file_size);
8552 compare_file(file, dest, 0);
8554 /* Test overlapped TransmitFile w/ start offset */
8555 ov.hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
8556 SetFilePointer(file, 0, NULL, FILE_BEGIN);
8557 ov.Offset = 10;
8558 bret = pTransmitFile(client, file, 0, 0, &ov, NULL, 0);
8559 err = WSAGetLastError();
8560 ok(!bret, "TransmitFile succeeded unexpectedly.\n");
8561 ok(err == ERROR_IO_PENDING, "TransmitFile triggered unexpected errno (%d != %d)\n", err, ERROR_IO_PENDING);
8562 iret = WaitForSingleObject(ov.hEvent, 2000);
8563 ok(iret == WAIT_OBJECT_0, "Overlapped TransmitFile failed.\n");
8564 WSAGetOverlappedResult(client, &ov, &total_sent, FALSE, NULL);
8565 ok(total_sent == (file_size - ov.Offset),
8566 "Overlapped TransmitFile sent an unexpected number of bytes (%d != %d).\n",
8567 total_sent, file_size - ov.Offset);
8568 compare_file(file, dest, ov.Offset);
8570 /* Test overlapped TransmitFile w/ file and buffer data */
8571 ov.hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
8572 buffers.Head = &header_msg[0];
8573 buffers.HeadLength = sizeof(header_msg);
8574 buffers.Tail = &footer_msg[0];
8575 buffers.TailLength = sizeof(footer_msg);
8576 SetFilePointer(file, 0, NULL, FILE_BEGIN);
8577 ov.Offset = 0;
8578 bret = pTransmitFile(client, file, 0, 0, &ov, &buffers, 0);
8579 err = WSAGetLastError();
8580 ok(!bret, "TransmitFile succeeded unexpectedly.\n");
8581 ok(err == ERROR_IO_PENDING, "TransmitFile triggered unexpected errno (%d != %d)\n", err, ERROR_IO_PENDING);
8582 iret = WaitForSingleObject(ov.hEvent, 2000);
8583 ok(iret == WAIT_OBJECT_0, "Overlapped TransmitFile failed.\n");
8584 WSAGetOverlappedResult(client, &ov, &total_sent, FALSE, NULL);
8585 ok(total_sent == (file_size + buffers.HeadLength + buffers.TailLength),
8586 "Overlapped TransmitFile sent an unexpected number of bytes (%d != %d).\n",
8587 total_sent, file_size + buffers.HeadLength + buffers.TailLength);
8588 iret = recv(dest, buf, sizeof(header_msg), 0);
8589 ok(memcmp(buf, &header_msg[0], sizeof(header_msg)) == 0,
8590 "TransmitFile header buffer did not match!\n");
8591 compare_file(file, dest, 0);
8592 iret = recv(dest, buf, sizeof(footer_msg), 0);
8593 ok(memcmp(buf, &footer_msg[0], sizeof(footer_msg)) == 0,
8594 "TransmitFile footer buffer did not match!\n");
8596 /* Test TransmitFile with a UDP datagram socket */
8597 closesocket(client);
8598 client = socket(AF_INET, SOCK_DGRAM, 0);
8599 bret = pTransmitFile(client, NULL, 0, 0, NULL, NULL, 0);
8600 err = WSAGetLastError();
8601 ok(!bret, "TransmitFile succeeded unexpectedly.\n");
8602 ok(err == WSAENOTCONN, "TransmitFile triggered unexpected errno (%d != %d)\n", err, WSAENOTCONN);
8604 CloseHandle(file);
8605 CloseHandle(ov.hEvent);
8606 closesocket(client);
8607 closesocket(server);
8610 static void test_getpeername(void)
8612 SOCKET sock;
8613 struct sockaddr_in sa, sa_out;
8614 SOCKADDR_STORAGE ss;
8615 int sa_len;
8616 const char buf[] = "hello world";
8617 int ret;
8619 /* Test the parameter validation order. */
8620 ret = getpeername(INVALID_SOCKET, NULL, NULL);
8621 ok(ret == SOCKET_ERROR, "Expected getpeername to return SOCKET_ERROR, got %d\n", ret);
8622 ok(WSAGetLastError() == WSAENOTSOCK,
8623 "Expected WSAGetLastError() to return WSAENOTSOCK, got %d\n", WSAGetLastError());
8625 sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
8626 ok(sock != INVALID_SOCKET, "Expected socket to return a valid socket\n");
8628 ret = getpeername(sock, NULL, NULL);
8629 ok(ret == SOCKET_ERROR, "Expected getpeername to return SOCKET_ERROR, got %d\n", ret);
8630 todo_wine ok(WSAGetLastError() == WSAENOTCONN,
8631 "Expected WSAGetLastError() to return WSAENOTCONN, got %d\n", WSAGetLastError());
8633 memset(&sa, 0, sizeof(sa));
8634 sa.sin_family = AF_INET;
8635 sa.sin_port = htons(139);
8636 sa.sin_addr.s_addr = inet_addr("127.0.0.1");
8638 /* sendto does not change a socket's connection state. */
8639 ret = sendto(sock, buf, sizeof(buf), 0, (struct sockaddr*)&sa, sizeof(sa));
8640 ok(ret != SOCKET_ERROR,
8641 "Expected sendto to succeed, WSAGetLastError() = %d\n", WSAGetLastError());
8643 ret = getpeername(sock, NULL, NULL);
8644 ok(ret == SOCKET_ERROR, "Expected getpeername to return SOCKET_ERROR, got %d\n", ret);
8645 todo_wine ok(WSAGetLastError() == WSAENOTCONN,
8646 "Expected WSAGetLastError() to return WSAENOTCONN, got %d\n", WSAGetLastError());
8648 ret = connect(sock, (struct sockaddr*)&sa, sizeof(sa));
8649 ok(ret == 0,
8650 "Expected connect to succeed, WSAGetLastError() = %d\n", WSAGetLastError());
8652 ret = getpeername(sock, NULL, NULL);
8653 ok(ret == SOCKET_ERROR, "Expected getpeername to return SOCKET_ERROR, got %d\n", ret);
8654 ok(WSAGetLastError() == WSAEFAULT,
8655 "Expected WSAGetLastError() to return WSAEFAULT, got %d\n", WSAGetLastError());
8657 /* Test crashes on Wine. */
8658 if (0)
8660 ret = getpeername(sock, (void*)0xdeadbeef, (void*)0xcafebabe);
8661 ok(ret == SOCKET_ERROR, "Expected getpeername to return SOCKET_ERROR, got %d\n", ret);
8662 ok(WSAGetLastError() == WSAEFAULT,
8663 "Expected WSAGetLastError() to return WSAEFAULT, got %d\n", WSAGetLastError());
8666 ret = getpeername(sock, (struct sockaddr*)&sa_out, NULL);
8667 ok(ret == SOCKET_ERROR, "Expected getpeername to return 0, got %d\n", ret);
8668 ok(WSAGetLastError() == WSAEFAULT,
8669 "Expected WSAGetLastError() to return WSAEFAULT, got %d\n", WSAGetLastError());
8671 sa_len = 0;
8672 ret = getpeername(sock, NULL, &sa_len);
8673 ok(ret == SOCKET_ERROR, "Expected getpeername to return 0, got %d\n", ret);
8674 ok(WSAGetLastError() == WSAEFAULT,
8675 "Expected WSAGetLastError() to return WSAEFAULT, got %d\n", WSAGetLastError());
8676 ok(!sa_len, "got %d\n", sa_len);
8678 sa_len = 0;
8679 ret = getpeername(sock, (struct sockaddr *)&ss, &sa_len);
8680 ok(ret == SOCKET_ERROR, "Expected getpeername to return 0, got %d\n", ret);
8681 ok(WSAGetLastError() == WSAEFAULT,
8682 "Expected WSAGetLastError() to return WSAEFAULT, got %d\n", WSAGetLastError());
8683 ok(!sa_len, "got %d\n", sa_len);
8685 sa_len = sizeof(ss);
8686 ret = getpeername(sock, (struct sockaddr *)&ss, &sa_len);
8687 ok(ret == 0, "Expected getpeername to return 0, got %d\n", ret);
8688 ok(!memcmp(&sa, &ss, sizeof(sa)),
8689 "Expected the returned structure to be identical to the connect structure\n");
8690 ok(sa_len == sizeof(sa), "got %d\n", sa_len);
8692 closesocket(sock);
8695 static void test_sioRoutingInterfaceQuery(void)
8697 OVERLAPPED overlapped = {0}, *overlapped_ptr;
8698 struct sockaddr_in in = {0}, out = {0};
8699 ULONG_PTR key;
8700 HANDLE port;
8701 SOCKET sock;
8702 DWORD size;
8703 int ret;
8705 sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
8706 ok(sock != INVALID_SOCKET, "Expected socket to return a valid socket\n");
8707 port = CreateIoCompletionPort((HANDLE)sock, NULL, 123, 0);
8709 WSASetLastError(0xdeadbeef);
8710 ret = WSAIoctl(sock, SIO_ROUTING_INTERFACE_QUERY, &in, sizeof(in), &out, sizeof(out), NULL, NULL, NULL);
8711 ok(ret == -1, "expected failure\n");
8712 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
8714 size = 0xdeadbeef;
8715 ret = WSAIoctl(sock, SIO_ROUTING_INTERFACE_QUERY, &in, sizeof(in) - 1, &out, sizeof(out), &size, NULL, NULL);
8716 ok(ret == -1, "expected failure\n");
8717 todo_wine ok(WSAGetLastError() == WSAEINVAL, "got error %u\n", WSAGetLastError());
8718 ok(size == 0xdeadbeef, "got size %u\n", size);
8720 size = 0xdeadbeef;
8721 ret = WSAIoctl(sock, SIO_ROUTING_INTERFACE_QUERY, NULL, sizeof(in), &out, sizeof(out), &size, NULL, NULL);
8722 ok(ret == -1, "expected failure\n");
8723 todo_wine ok(WSAGetLastError() == WSAEINVAL, "got error %u\n", WSAGetLastError());
8724 ok(size == 0xdeadbeef, "got size %u\n", size);
8726 size = 0xdeadbeef;
8727 ret = WSAIoctl(sock, SIO_ROUTING_INTERFACE_QUERY, &in, sizeof(in), &out, sizeof(out), &size, NULL, NULL);
8728 ok(ret == -1, "expected failure\n");
8729 ok(WSAGetLastError() == WSAEAFNOSUPPORT, "got error %u\n", WSAGetLastError());
8730 ok(size == 0xdeadbeef, "got size %u\n", size);
8732 in.sin_family = AF_INET;
8733 size = 0xdeadbeef;
8734 ret = WSAIoctl(sock, SIO_ROUTING_INTERFACE_QUERY, &in, sizeof(in), &out, sizeof(out), &size, NULL, NULL);
8735 todo_wine ok(ret == -1, "expected failure\n");
8736 todo_wine ok(WSAGetLastError() == WSAEINVAL, "got error %u\n", WSAGetLastError());
8737 todo_wine ok(size == 0xdeadbeef, "got size %u\n", size);
8739 in.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
8740 WSASetLastError(0xdeadbeef);
8741 size = 0xdeadbeef;
8742 ret = WSAIoctl(sock, SIO_ROUTING_INTERFACE_QUERY, &in, sizeof(in), &out, sizeof(out), &size, NULL, NULL);
8743 ok(!ret, "expected failure\n");
8744 ok(!WSAGetLastError(), "got error %u\n", WSAGetLastError());
8745 ok(size == sizeof(out), "got size %u\n", size);
8746 /* We expect the source address to be INADDR_LOOPBACK as well, but
8747 * there's no guarantee that a route to the loopback address exists,
8748 * so rather than introduce spurious test failures we do not test the
8749 * source address.
8752 size = 0xdeadbeef;
8753 ret = WSAIoctl(sock, SIO_ROUTING_INTERFACE_QUERY, &in, sizeof(in), &out, sizeof(out) - 1, &size, NULL, NULL);
8754 ok(ret == -1, "expected failure\n");
8755 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
8756 todo_wine ok(size == sizeof(out), "got size %u\n", size);
8758 size = 0xdeadbeef;
8759 ret = WSAIoctl(sock, SIO_ROUTING_INTERFACE_QUERY, &in, sizeof(in), NULL, sizeof(out), &size, NULL, NULL);
8760 ok(ret == -1, "expected failure\n");
8761 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
8762 ok(size == 0xdeadbeef, "got size %u\n", size);
8764 ret = WSAIoctl(sock, SIO_ROUTING_INTERFACE_QUERY, &in, sizeof(in), &out, sizeof(out), NULL, &overlapped, NULL);
8765 ok(ret == -1, "expected failure\n");
8766 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
8767 ok(size == 0xdeadbeef, "got size %u\n", size);
8769 WSASetLastError(0xdeadbeef);
8770 size = 0xdeadbeef;
8771 overlapped.Internal = 0xdeadbeef;
8772 overlapped.InternalHigh = 0xdeadbeef;
8773 ret = WSAIoctl(sock, SIO_ROUTING_INTERFACE_QUERY, &in, sizeof(in), &out, sizeof(out), &size, &overlapped, NULL);
8774 ok(!ret, "expected failure\n");
8775 ok(!WSAGetLastError(), "got error %u\n", WSAGetLastError());
8776 ok(size == sizeof(out), "got size %u\n", size);
8778 ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 0);
8779 ok(ret, "got error %u\n", GetLastError());
8780 ok(!size, "got size %u\n", size);
8781 ok(overlapped_ptr == &overlapped, "got overlapped %p\n", overlapped_ptr);
8782 ok(!overlapped.Internal, "got status %#x\n", (NTSTATUS)overlapped.Internal);
8783 ok(!overlapped.InternalHigh, "got size %Iu\n", overlapped.InternalHigh);
8785 CloseHandle(port);
8786 closesocket(sock);
8788 sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
8790 ret = WSAIoctl(sock, SIO_ROUTING_INTERFACE_QUERY, &in, sizeof(in),
8791 &out, sizeof(out), NULL, &overlapped, socket_apc);
8792 ok(ret == -1, "expected failure\n");
8793 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
8795 apc_count = 0;
8796 size = 0xdeadbeef;
8797 ret = WSAIoctl(sock, SIO_ROUTING_INTERFACE_QUERY, &in, sizeof(in),
8798 &out, sizeof(out), &size, &overlapped, socket_apc);
8799 ok(!ret, "expected success\n");
8800 ok(size == sizeof(out), "got size %u\n", size);
8802 ret = SleepEx(0, TRUE);
8803 ok(ret == WAIT_IO_COMPLETION, "got %d\n", ret);
8804 ok(apc_count == 1, "APC was called %u times\n", apc_count);
8805 ok(!apc_error, "got APC error %u\n", apc_error);
8806 ok(!apc_size, "got APC size %u\n", apc_size);
8807 ok(apc_overlapped == &overlapped, "got APC overlapped %p\n", apc_overlapped);
8809 closesocket(sock);
8812 static void test_sioAddressListChange(void)
8814 struct sockaddr_in bindAddress;
8815 struct in_addr net_address;
8816 WSAOVERLAPPED overlapped, *olp;
8817 struct hostent *h;
8818 DWORD num_bytes, error, tick;
8819 SOCKET sock, sock2, sock3;
8820 WSAEVENT event2, event3;
8821 HANDLE io_port;
8822 ULONG_PTR key;
8823 int acount;
8824 BOOL bret;
8825 int ret;
8827 /* Use gethostbyname to find the list of local network interfaces */
8828 h = gethostbyname("");
8829 ok(!!h, "failed to get interface list, error %u\n", WSAGetLastError());
8830 for (acount = 0; h->h_addr_list[acount]; acount++);
8831 if (acount == 0)
8833 skip("Cannot test SIO_ADDRESS_LIST_CHANGE, test requires a network card.\n");
8834 return;
8837 net_address.s_addr = *(ULONG *) h->h_addr_list[0];
8839 sock = socket(AF_INET, 0, IPPROTO_TCP);
8840 ok(sock != INVALID_SOCKET, "socket() failed\n");
8842 memset(&bindAddress, 0, sizeof(bindAddress));
8843 bindAddress.sin_family = AF_INET;
8844 bindAddress.sin_addr.s_addr = net_address.s_addr;
8845 SetLastError(0xdeadbeef);
8846 ret = bind(sock, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
8847 ok (!ret, "bind() failed with error %d\n", GetLastError());
8848 set_blocking(sock, FALSE);
8850 memset(&overlapped, 0, sizeof(overlapped));
8851 overlapped.hEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
8852 SetLastError(0xdeadbeef);
8853 ret = WSAIoctl(sock, SIO_ADDRESS_LIST_CHANGE, NULL, 0, NULL, 0, &num_bytes, &overlapped, NULL);
8854 error = GetLastError();
8855 ok (ret == SOCKET_ERROR, "WSAIoctl(SIO_ADDRESS_LIST_CHANGE) failed with error %d\n", error);
8856 ok (error == ERROR_IO_PENDING, "expected 0x3e5, got 0x%x\n", error);
8858 CloseHandle(overlapped.hEvent);
8859 closesocket(sock);
8861 sock = socket(AF_INET, 0, IPPROTO_TCP);
8862 ok(sock != INVALID_SOCKET, "socket() failed\n");
8864 SetLastError(0xdeadbeef);
8865 ret = bind(sock, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
8866 ok (!ret, "bind() failed with error %d\n", GetLastError());
8867 set_blocking(sock, TRUE);
8869 memset(&overlapped, 0, sizeof(overlapped));
8870 overlapped.hEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
8871 SetLastError(0xdeadbeef);
8872 ret = WSAIoctl(sock, SIO_ADDRESS_LIST_CHANGE, NULL, 0, NULL, 0, &num_bytes, &overlapped, NULL);
8873 error = GetLastError();
8874 ok (ret == SOCKET_ERROR, "WSAIoctl(SIO_ADDRESS_LIST_CHANGE) failed with error %d\n", error);
8875 ok (error == ERROR_IO_PENDING, "expected 0x3e5, got 0x%x\n", error);
8877 CloseHandle(overlapped.hEvent);
8878 closesocket(sock);
8880 sock = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
8881 ok(sock != INVALID_SOCKET, "socket() failed\n");
8883 SetLastError(0xdeadbeef);
8884 ret = bind(sock, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
8885 ok (!ret, "bind() failed with error %d\n", GetLastError());
8886 set_blocking(sock, FALSE);
8888 memset(&overlapped, 0, sizeof(overlapped));
8889 overlapped.hEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
8890 SetLastError(0xdeadbeef);
8891 ret = WSAIoctl(sock, SIO_ADDRESS_LIST_CHANGE, NULL, 0, NULL, 0, &num_bytes, &overlapped, NULL);
8892 error = GetLastError();
8893 ok (ret == SOCKET_ERROR, "WSAIoctl(SIO_ADDRESS_LIST_CHANGE) failed with error %d\n", error);
8894 ok (error == ERROR_IO_PENDING, "expected 0x3e5, got 0x%x\n", error);
8896 CloseHandle(overlapped.hEvent);
8897 closesocket(sock);
8899 sock = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
8900 ok(sock != INVALID_SOCKET, "socket() failed\n");
8902 SetLastError(0xdeadbeef);
8903 ret = bind(sock, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
8904 ok (!ret, "bind() failed with error %d\n", GetLastError());
8905 set_blocking(sock, TRUE);
8907 memset(&overlapped, 0, sizeof(overlapped));
8908 overlapped.hEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
8909 SetLastError(0xdeadbeef);
8910 ret = WSAIoctl(sock, SIO_ADDRESS_LIST_CHANGE, NULL, 0, NULL, 0, &num_bytes, &overlapped, NULL);
8911 error = GetLastError();
8912 ok (ret == SOCKET_ERROR, "WSAIoctl(SIO_ADDRESS_LIST_CHANGE) failed with error %d\n", error);
8913 ok (error == ERROR_IO_PENDING, "expected 0x3e5, got 0x%x\n", error);
8915 CloseHandle(overlapped.hEvent);
8916 closesocket(sock);
8918 /* When the socket is overlapped non-blocking and the list change is requested without
8919 * an overlapped structure the error will be different. */
8920 sock = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
8921 ok(sock != INVALID_SOCKET, "socket() failed\n");
8923 SetLastError(0xdeadbeef);
8924 ret = bind(sock, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
8925 ok (!ret, "bind() failed with error %d\n", GetLastError());
8926 set_blocking(sock, FALSE);
8928 SetLastError(0xdeadbeef);
8929 ret = WSAIoctl(sock, SIO_ADDRESS_LIST_CHANGE, NULL, 0, NULL, 0, &num_bytes, NULL, NULL);
8930 error = GetLastError();
8931 ok (ret == SOCKET_ERROR, "WSAIoctl(SIO_ADDRESS_LIST_CHANGE) failed with error %d\n", error);
8932 ok (error == WSAEWOULDBLOCK, "expected 10035, got %d\n", error);
8934 io_port = CreateIoCompletionPort( (HANDLE)sock, NULL, 0, 0 );
8935 ok (io_port != NULL, "failed to create completion port %u\n", GetLastError());
8937 set_blocking(sock, FALSE);
8938 memset(&overlapped, 0, sizeof(overlapped));
8939 SetLastError(0xdeadbeef);
8940 ret = WSAIoctl(sock, SIO_ADDRESS_LIST_CHANGE, NULL, 0, NULL, 0, &num_bytes, &overlapped, NULL);
8941 error = GetLastError();
8942 ok (ret == SOCKET_ERROR, "WSAIoctl(SIO_ADDRESS_LIST_CHANGE) failed with error %u\n", error);
8943 ok (error == ERROR_IO_PENDING, "expected ERROR_IO_PENDING got %u\n", error);
8945 olp = (WSAOVERLAPPED *)0xdeadbeef;
8946 bret = GetQueuedCompletionStatus( io_port, &num_bytes, &key, &olp, 0 );
8947 ok(!bret, "failed to get completion status %u\n", bret);
8948 ok(GetLastError() == WAIT_TIMEOUT, "Last error was %d\n", GetLastError());
8949 ok(!olp, "Overlapped structure is at %p\n", olp);
8951 closesocket(sock);
8953 olp = (WSAOVERLAPPED *)0xdeadbeef;
8954 bret = GetQueuedCompletionStatus( io_port, &num_bytes, &key, &olp, 0 );
8955 ok(!bret, "failed to get completion status %u\n", bret);
8956 ok(GetLastError() == ERROR_OPERATION_ABORTED, "Last error was %u\n", GetLastError());
8957 ok(olp == &overlapped, "Overlapped structure is at %p\n", olp);
8959 CloseHandle(io_port);
8961 /* Misuse of the API by using a blocking socket and not using an overlapped structure,
8962 * this leads to a hang forever. */
8963 if (0)
8965 sock = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
8967 SetLastError(0xdeadbeef);
8968 bind(sock, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
8970 set_blocking(sock, TRUE);
8971 WSAIoctl(sock, SIO_ADDRESS_LIST_CHANGE, NULL, 0, NULL, 0, &num_bytes, NULL, NULL);
8972 /* hang */
8974 closesocket(sock);
8977 if (!winetest_interactive)
8979 skip("Cannot test SIO_ADDRESS_LIST_CHANGE, interactive tests must be enabled\n");
8980 return;
8983 /* Bind an overlapped socket to the first found network interface */
8984 sock = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
8985 ok(sock != INVALID_SOCKET, "Expected socket to return a valid socket\n");
8986 sock2 = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
8987 ok(sock2 != INVALID_SOCKET, "Expected socket to return a valid socket\n");
8988 sock3 = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
8989 ok(sock3 != INVALID_SOCKET, "Expected socket to return a valid socket\n");
8991 ret = bind(sock, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
8992 ok(!ret, "bind failed unexpectedly\n");
8993 ret = bind(sock2, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
8994 ok(!ret, "bind failed unexpectedly\n");
8995 ret = bind(sock3, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
8996 ok(!ret, "bind failed unexpectedly\n");
8998 set_blocking(sock2, FALSE);
8999 set_blocking(sock3, FALSE);
9001 /* Wait for address changes, request that the user connects/disconnects an interface */
9002 memset(&overlapped, 0, sizeof(overlapped));
9003 overlapped.hEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
9004 ret = WSAIoctl(sock, SIO_ADDRESS_LIST_CHANGE, NULL, 0, NULL, 0, &num_bytes, &overlapped, NULL);
9005 ok(ret == SOCKET_ERROR, "WSAIoctl succeeded unexpectedly\n");
9006 ok(WSAGetLastError() == WSA_IO_PENDING, "Expected pending last error, got %d\n", WSAGetLastError());
9008 ret = WSAIoctl(sock2, SIO_ADDRESS_LIST_CHANGE, NULL, 0, NULL, 0, &num_bytes, NULL, NULL);
9009 ok(ret == SOCKET_ERROR, "WSAIoctl succeeded unexpectedly\n");
9010 ok(WSAGetLastError() == WSAEWOULDBLOCK, "Expected would block last error, got %d\n", WSAGetLastError());
9012 event2 = WSACreateEvent();
9013 event3 = WSACreateEvent();
9014 ret = WSAEventSelect (sock2, event2, FD_ADDRESS_LIST_CHANGE);
9015 ok(!ret, "WSAEventSelect failed with %d\n", WSAGetLastError());
9016 /* sock3 did not request SIO_ADDRESS_LIST_CHANGE but it is trying to wait anyway */
9017 ret = WSAEventSelect (sock3, event3, FD_ADDRESS_LIST_CHANGE);
9018 ok(!ret, "WSAEventSelect failed with %d\n", WSAGetLastError());
9020 trace("Testing socket-based ipv4 address list change notification. Please connect/disconnect or"
9021 " change the ipv4 address of any of the local network interfaces (15 second timeout).\n");
9022 tick = GetTickCount();
9023 ret = WaitForSingleObject(overlapped.hEvent, 15000);
9024 ok(ret == WAIT_OBJECT_0, "failed to get overlapped event %u\n", ret);
9026 ret = WaitForSingleObject(event2, 500);
9027 todo_wine
9028 ok(ret == WAIT_OBJECT_0, "failed to get change event %u\n", ret);
9030 ret = WaitForSingleObject(event3, 500);
9031 ok(ret == WAIT_TIMEOUT, "unexpected change event\n");
9033 trace("Spent %d ms waiting.\n", GetTickCount() - tick);
9035 WSACloseEvent(event2);
9036 WSACloseEvent(event3);
9038 closesocket(sock);
9039 closesocket(sock2);
9040 closesocket(sock3);
9044 * Provide consistent initialization for the AcceptEx IOCP tests.
9046 static SOCKET setup_iocp_src(struct sockaddr_in *bindAddress)
9048 SOCKET src;
9049 int iret, socklen;
9051 src = socket(AF_INET, SOCK_STREAM, 0);
9052 ok(src != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
9054 memset(bindAddress, 0, sizeof(*bindAddress));
9055 bindAddress->sin_family = AF_INET;
9056 bindAddress->sin_addr.s_addr = inet_addr("127.0.0.1");
9057 iret = bind(src, (struct sockaddr*)bindAddress, sizeof(*bindAddress));
9058 ok(!iret, "failed to bind, error %u\n", WSAGetLastError());
9060 socklen = sizeof(*bindAddress);
9061 iret = getsockname(src, (struct sockaddr*)bindAddress, &socklen);
9062 ok(!iret, "failed to get address, error %u\n", WSAGetLastError());
9064 iret = set_blocking(src, FALSE);
9065 ok(!iret, "failed to make socket non-blocking, error %u\n", WSAGetLastError());
9067 iret = listen(src, 5);
9068 ok(!iret, "failed to listen, error %u\n", WSAGetLastError());
9070 return src;
9073 static void test_completion_port(void)
9075 HANDLE io_port;
9076 WSAOVERLAPPED ov, *olp;
9077 SOCKET src, dest, dup, connector = INVALID_SOCKET;
9078 WSAPROTOCOL_INFOA info;
9079 char buf[1024];
9080 WSABUF bufs;
9081 DWORD num_bytes, flags;
9082 struct linger ling;
9083 int iret;
9084 BOOL bret;
9085 ULONG_PTR key;
9086 struct sockaddr_in bindAddress;
9087 GUID acceptExGuid = WSAID_ACCEPTEX;
9088 LPFN_ACCEPTEX pAcceptEx = NULL;
9089 fd_set fds_recv;
9091 memset(buf, 0, sizeof(buf));
9092 io_port = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
9093 ok( io_port != NULL, "Failed to create completion port %u\n", GetLastError());
9095 memset(&ov, 0, sizeof(ov));
9097 tcp_socketpair(&src, &dest);
9099 bufs.len = sizeof(buf);
9100 bufs.buf = buf;
9101 flags = 0;
9103 ling.l_onoff = 1;
9104 ling.l_linger = 0;
9105 iret = setsockopt (src, SOL_SOCKET, SO_LINGER, (char *) &ling, sizeof(ling));
9106 ok(!iret, "Failed to set linger %d\n", GetLastError());
9108 io_port = CreateIoCompletionPort( (HANDLE)dest, io_port, 125, 0 );
9109 ok(io_port != NULL, "Failed to create completion port %u\n", GetLastError());
9111 SetLastError(0xdeadbeef);
9113 iret = WSARecv(dest, &bufs, 1, &num_bytes, &flags, &ov, NULL);
9114 ok(iret == SOCKET_ERROR, "WSARecv returned %d\n", iret);
9115 ok(GetLastError() == ERROR_IO_PENDING, "Last error was %d\n", GetLastError());
9117 Sleep(100);
9119 closesocket(src);
9120 src = INVALID_SOCKET;
9122 SetLastError(0xdeadbeef);
9123 key = 0xdeadbeef;
9124 num_bytes = 0xdeadbeef;
9125 olp = (WSAOVERLAPPED *)0xdeadbeef;
9127 bret = GetQueuedCompletionStatus(io_port, &num_bytes, &key, &olp, 100);
9128 todo_wine ok(bret == FALSE, "GetQueuedCompletionStatus returned %d\n", bret);
9129 todo_wine ok(GetLastError() == ERROR_NETNAME_DELETED, "Last error was %d\n", GetLastError());
9130 ok(key == 125, "Key is %lu\n", key);
9131 ok(num_bytes == 0, "Number of bytes received is %u\n", num_bytes);
9132 ok(olp == &ov, "Overlapped structure is at %p\n", olp);
9134 SetLastError(0xdeadbeef);
9135 key = 0xdeadbeef;
9136 num_bytes = 0xdeadbeef;
9137 olp = (WSAOVERLAPPED *)0xdeadbeef;
9139 bret = GetQueuedCompletionStatus(io_port, &num_bytes, &key, &olp, 100);
9140 ok(bret == FALSE, "GetQueuedCompletionStatus returned %d\n", bret );
9141 ok(GetLastError() == WAIT_TIMEOUT, "Last error was %d\n", GetLastError());
9142 ok(key == 0xdeadbeef, "Key is %lu\n", key);
9143 ok(num_bytes == 0xdeadbeef, "Number of bytes transferred is %u\n", num_bytes);
9144 ok(!olp, "Overlapped structure is at %p\n", olp);
9146 if (dest != INVALID_SOCKET)
9147 closesocket(dest);
9149 memset(&ov, 0, sizeof(ov));
9151 tcp_socketpair(&src, &dest);
9153 bufs.len = sizeof(buf);
9154 bufs.buf = buf;
9155 flags = 0;
9157 ling.l_onoff = 1;
9158 ling.l_linger = 0;
9159 iret = setsockopt (src, SOL_SOCKET, SO_LINGER, (char *) &ling, sizeof(ling));
9160 ok(!iret, "Failed to set linger %d\n", GetLastError());
9162 io_port = CreateIoCompletionPort((HANDLE)dest, io_port, 125, 0);
9163 ok(io_port != NULL, "failed to create completion port %u\n", GetLastError());
9165 set_blocking(dest, FALSE);
9167 closesocket(src);
9168 src = INVALID_SOCKET;
9170 Sleep(100);
9172 num_bytes = 0xdeadbeef;
9173 SetLastError(0xdeadbeef);
9175 iret = WSASend(dest, &bufs, 1, &num_bytes, 0, &ov, NULL);
9176 ok(iret == SOCKET_ERROR, "WSASend failed - %d\n", iret);
9177 ok(GetLastError() == WSAECONNRESET, "Last error was %d\n", GetLastError());
9178 ok(num_bytes == 0xdeadbeef, "Managed to send %d\n", num_bytes);
9180 SetLastError(0xdeadbeef);
9181 key = 0xdeadbeef;
9182 num_bytes = 0xdeadbeef;
9183 olp = (WSAOVERLAPPED *)0xdeadbeef;
9185 bret = GetQueuedCompletionStatus( io_port, &num_bytes, &key, &olp, 200 );
9186 ok(bret == FALSE, "GetQueuedCompletionStatus returned %u\n", bret );
9187 ok(GetLastError() == WAIT_TIMEOUT, "Last error was %d\n", GetLastError());
9188 ok(key == 0xdeadbeef, "Key is %lu\n", key);
9189 ok(num_bytes == 0xdeadbeef, "Number of bytes transferred is %u\n", num_bytes);
9190 ok(!olp, "Overlapped structure is at %p\n", olp);
9192 if (dest != INVALID_SOCKET)
9193 closesocket(dest);
9195 /* Test IOCP response on successful immediate read. */
9196 tcp_socketpair(&src, &dest);
9198 bufs.len = sizeof(buf);
9199 bufs.buf = buf;
9200 flags = 0;
9201 SetLastError(0xdeadbeef);
9203 iret = WSASend(src, &bufs, 1, &num_bytes, 0, &ov, NULL);
9204 ok(!iret, "WSASend failed - %d, last error %u\n", iret, GetLastError());
9205 ok(num_bytes == sizeof(buf), "Managed to send %d\n", num_bytes);
9207 io_port = CreateIoCompletionPort((HANDLE)dest, io_port, 125, 0);
9208 ok(io_port != NULL, "failed to create completion port %u\n", GetLastError());
9209 set_blocking(dest, FALSE);
9211 FD_ZERO(&fds_recv);
9212 FD_SET(dest, &fds_recv);
9213 select(dest + 1, &fds_recv, NULL, NULL, NULL);
9215 num_bytes = 0xdeadbeef;
9216 flags = 0;
9218 iret = WSARecv(dest, &bufs, 1, &num_bytes, &flags, &ov, NULL);
9219 ok(!iret, "WSARecv failed - %d, last error %u\n", iret, GetLastError());
9220 ok(num_bytes == sizeof(buf), "Managed to read %d\n", num_bytes);
9222 SetLastError(0xdeadbeef);
9223 key = 0xdeadbeef;
9224 num_bytes = 0xdeadbeef;
9225 olp = (WSAOVERLAPPED *)0xdeadbeef;
9227 bret = GetQueuedCompletionStatus( io_port, &num_bytes, &key, &olp, 200 );
9228 ok(bret == TRUE, "failed to get completion status %u\n", bret);
9229 ok(GetLastError() == 0xdeadbeef, "Last error was %d\n", GetLastError());
9230 ok(key == 125, "Key is %lu\n", key);
9231 ok(num_bytes == sizeof(buf), "Number of bytes transferred is %u\n", num_bytes);
9232 ok(olp == &ov, "Overlapped structure is at %p\n", olp);
9234 /* Test IOCP response on graceful shutdown. */
9235 closesocket(src);
9237 FD_ZERO(&fds_recv);
9238 FD_SET(dest, &fds_recv);
9239 select(dest + 1, &fds_recv, NULL, NULL, NULL);
9241 num_bytes = 0xdeadbeef;
9242 flags = 0;
9243 memset(&ov, 0, sizeof(ov));
9245 iret = WSARecv(dest, &bufs, 1, &num_bytes, &flags, &ov, NULL);
9246 ok(!iret, "WSARecv failed - %d, last error %u\n", iret, GetLastError());
9247 ok(!num_bytes, "Managed to read %d\n", num_bytes);
9249 SetLastError(0xdeadbeef);
9250 key = 0xdeadbeef;
9251 num_bytes = 0xdeadbeef;
9252 olp = (WSAOVERLAPPED *)0xdeadbeef;
9254 bret = GetQueuedCompletionStatus( io_port, &num_bytes, &key, &olp, 200 );
9255 ok(bret == TRUE, "failed to get completion status %u\n", bret);
9256 ok(GetLastError() == 0xdeadbeef, "Last error was %d\n", GetLastError());
9257 ok(key == 125, "Key is %lu\n", key);
9258 ok(!num_bytes, "Number of bytes transferred is %u\n", num_bytes);
9259 ok(olp == &ov, "Overlapped structure is at %p\n", olp);
9261 closesocket(src);
9262 src = INVALID_SOCKET;
9263 closesocket(dest);
9264 dest = INVALID_SOCKET;
9266 /* Test IOCP response on hard shutdown. This was the condition that triggered
9267 * a crash in an actual app (bug 38980). */
9268 tcp_socketpair(&src, &dest);
9270 bufs.len = sizeof(buf);
9271 bufs.buf = buf;
9272 flags = 0;
9273 memset(&ov, 0, sizeof(ov));
9275 ling.l_onoff = 1;
9276 ling.l_linger = 0;
9277 iret = setsockopt (src, SOL_SOCKET, SO_LINGER, (char *) &ling, sizeof(ling));
9278 ok(!iret, "Failed to set linger %d\n", GetLastError());
9280 io_port = CreateIoCompletionPort((HANDLE)dest, io_port, 125, 0);
9281 ok(io_port != NULL, "failed to create completion port %u\n", GetLastError());
9282 set_blocking(dest, FALSE);
9284 closesocket(src);
9285 src = INVALID_SOCKET;
9287 FD_ZERO(&fds_recv);
9288 FD_SET(dest, &fds_recv);
9289 select(dest + 1, &fds_recv, NULL, NULL, NULL);
9291 num_bytes = 0xdeadbeef;
9292 SetLastError(0xdeadbeef);
9294 /* Somehow a hard shutdown doesn't work on my Linux box. It seems SO_LINGER is ignored. */
9295 iret = WSARecv(dest, &bufs, 1, &num_bytes, &flags, &ov, NULL);
9296 todo_wine ok(iret == SOCKET_ERROR, "WSARecv failed - %d\n", iret);
9297 todo_wine ok(GetLastError() == WSAECONNRESET, "Last error was %d\n", GetLastError());
9298 todo_wine ok(num_bytes == 0xdeadbeef, "Managed to read %d\n", num_bytes);
9300 SetLastError(0xdeadbeef);
9301 key = 0xdeadbeef;
9302 num_bytes = 0xdeadbeef;
9303 olp = (WSAOVERLAPPED *)0xdeadbeef;
9305 bret = GetQueuedCompletionStatus( io_port, &num_bytes, &key, &olp, 200 );
9306 todo_wine ok(bret == FALSE, "GetQueuedCompletionStatus returned %u\n", bret );
9307 todo_wine ok(GetLastError() == WAIT_TIMEOUT, "Last error was %d\n", GetLastError());
9308 todo_wine ok(key == 0xdeadbeef, "Key is %lu\n", key);
9309 todo_wine ok(num_bytes == 0xdeadbeef, "Number of bytes transferred is %u\n", num_bytes);
9310 todo_wine ok(!olp, "Overlapped structure is at %p\n", olp);
9312 closesocket(dest);
9314 /* Test reading from a non-connected socket, mostly because the above test is marked todo. */
9315 dest = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
9316 ok(dest != INVALID_SOCKET, "socket() failed\n");
9318 io_port = CreateIoCompletionPort((HANDLE)dest, io_port, 125, 0);
9319 ok(io_port != NULL, "failed to create completion port %u\n", GetLastError());
9320 set_blocking(dest, FALSE);
9322 num_bytes = 0xdeadbeef;
9323 SetLastError(0xdeadbeef);
9324 memset(&ov, 0, sizeof(ov));
9326 iret = WSARecv(dest, &bufs, 1, &num_bytes, &flags, &ov, NULL);
9327 ok(iret == SOCKET_ERROR, "WSARecv failed - %d\n", iret);
9328 ok(GetLastError() == WSAENOTCONN, "Last error was %d\n", GetLastError());
9329 ok(num_bytes == 0xdeadbeef, "Managed to read %d\n", num_bytes);
9331 SetLastError(0xdeadbeef);
9332 key = 0xdeadbeef;
9333 num_bytes = 0xdeadbeef;
9334 olp = (WSAOVERLAPPED *)0xdeadbeef;
9336 bret = GetQueuedCompletionStatus( io_port, &num_bytes, &key, &olp, 200 );
9337 ok(bret == FALSE, "GetQueuedCompletionStatus returned %u\n", bret );
9338 ok(GetLastError() == WAIT_TIMEOUT, "Last error was %d\n", GetLastError());
9339 ok(key == 0xdeadbeef, "Key is %lu\n", key);
9340 ok(num_bytes == 0xdeadbeef, "Number of bytes transferred is %u\n", num_bytes);
9341 ok(!olp, "Overlapped structure is at %p\n", olp);
9343 num_bytes = 0xdeadbeef;
9344 closesocket(dest);
9346 dest = socket(AF_INET, SOCK_STREAM, 0);
9347 ok(dest != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
9349 iret = WSAIoctl(dest, SIO_GET_EXTENSION_FUNCTION_POINTER, &acceptExGuid, sizeof(acceptExGuid),
9350 &pAcceptEx, sizeof(pAcceptEx), &num_bytes, NULL, NULL);
9351 ok(!iret, "failed to get AcceptEx, error %u\n", WSAGetLastError());
9353 /* Test IOCP response on socket close (IOCP created after AcceptEx) */
9355 src = setup_iocp_src(&bindAddress);
9357 SetLastError(0xdeadbeef);
9359 bret = pAcceptEx(src, dest, buf, sizeof(buf) - 2*(sizeof(struct sockaddr_in) + 16),
9360 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
9361 &num_bytes, &ov);
9362 ok(bret == FALSE, "AcceptEx returned %d\n", bret);
9363 ok(GetLastError() == ERROR_IO_PENDING, "Last error was %d\n", GetLastError());
9365 io_port = CreateIoCompletionPort((HANDLE)src, io_port, 125, 0);
9366 ok(io_port != NULL, "failed to create completion port %u\n", GetLastError());
9368 closesocket(src);
9369 src = INVALID_SOCKET;
9371 SetLastError(0xdeadbeef);
9372 key = 0xdeadbeef;
9373 num_bytes = 0xdeadbeef;
9374 olp = (WSAOVERLAPPED *)0xdeadbeef;
9376 bret = GetQueuedCompletionStatus(io_port, &num_bytes, &key, &olp, 100);
9377 ok(bret == FALSE, "failed to get completion status %u\n", bret);
9378 ok(GetLastError() == ERROR_OPERATION_ABORTED, "Last error was %d\n", GetLastError());
9379 ok(key == 125, "Key is %lu\n", key);
9380 ok(num_bytes == 0, "Number of bytes transferred is %u\n", num_bytes);
9381 ok(olp == &ov, "Overlapped structure is at %p\n", olp);
9382 ok(olp && (olp->Internal == (ULONG)STATUS_CANCELLED), "Internal status is %lx\n", olp ? olp->Internal : 0);
9384 SetLastError(0xdeadbeef);
9385 key = 0xdeadbeef;
9386 num_bytes = 0xdeadbeef;
9387 olp = (WSAOVERLAPPED *)0xdeadbeef;
9388 bret = GetQueuedCompletionStatus( io_port, &num_bytes, &key, &olp, 200 );
9389 ok(bret == FALSE, "failed to get completion status %u\n", bret);
9390 ok(GetLastError() == WAIT_TIMEOUT, "Last error was %d\n", GetLastError());
9391 ok(key == 0xdeadbeef, "Key is %lu\n", key);
9392 ok(num_bytes == 0xdeadbeef, "Number of bytes transferred is %u\n", num_bytes);
9393 ok(!olp, "Overlapped structure is at %p\n", olp);
9395 /* Test IOCP response on socket close (IOCP created before AcceptEx) */
9397 src = setup_iocp_src(&bindAddress);
9399 SetLastError(0xdeadbeef);
9401 io_port = CreateIoCompletionPort((HANDLE)src, io_port, 125, 0);
9402 ok(io_port != NULL, "failed to create completion port %u\n", GetLastError());
9404 bret = pAcceptEx(src, dest, buf, sizeof(buf) - 2*(sizeof(struct sockaddr_in) + 16),
9405 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
9406 &num_bytes, &ov);
9407 ok(bret == FALSE, "AcceptEx returned %d\n", bret);
9408 ok(GetLastError() == ERROR_IO_PENDING, "Last error was %d\n", GetLastError());
9410 closesocket(src);
9411 src = INVALID_SOCKET;
9413 SetLastError(0xdeadbeef);
9414 key = 0xdeadbeef;
9415 num_bytes = 0xdeadbeef;
9416 olp = (WSAOVERLAPPED *)0xdeadbeef;
9418 bret = GetQueuedCompletionStatus(io_port, &num_bytes, &key, &olp, 100);
9419 ok(bret == FALSE, "failed to get completion status %u\n", bret);
9420 ok(GetLastError() == ERROR_OPERATION_ABORTED, "Last error was %d\n", GetLastError());
9421 ok(key == 125, "Key is %lu\n", key);
9422 ok(num_bytes == 0, "Number of bytes transferred is %u\n", num_bytes);
9423 ok(olp == &ov, "Overlapped structure is at %p\n", olp);
9424 ok(olp && (olp->Internal == (ULONG)STATUS_CANCELLED), "Internal status is %lx\n", olp ? olp->Internal : 0);
9426 SetLastError(0xdeadbeef);
9427 key = 0xdeadbeef;
9428 num_bytes = 0xdeadbeef;
9429 olp = (WSAOVERLAPPED *)0xdeadbeef;
9430 bret = GetQueuedCompletionStatus( io_port, &num_bytes, &key, &olp, 200 );
9431 ok(bret == FALSE, "failed to get completion status %u\n", bret);
9432 ok(GetLastError() == WAIT_TIMEOUT, "Last error was %d\n", GetLastError());
9433 ok(key == 0xdeadbeef, "Key is %lu\n", key);
9434 ok(num_bytes == 0xdeadbeef, "Number of bytes transferred is %u\n", num_bytes);
9435 ok(!olp, "Overlapped structure is at %p\n", olp);
9437 /* Test IOCP with duplicated handle */
9439 src = setup_iocp_src(&bindAddress);
9441 SetLastError(0xdeadbeef);
9443 io_port = CreateIoCompletionPort((HANDLE)src, io_port, 125, 0);
9444 ok(io_port != NULL, "failed to create completion port %u\n", GetLastError());
9446 WSADuplicateSocketA( src, GetCurrentProcessId(), &info );
9447 dup = WSASocketA(AF_INET, SOCK_STREAM, 0, &info, 0, WSA_FLAG_OVERLAPPED);
9448 ok(dup != INVALID_SOCKET, "failed to duplicate socket!\n");
9450 bret = pAcceptEx(dup, dest, buf, sizeof(buf) - 2*(sizeof(struct sockaddr_in) + 16),
9451 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
9452 &num_bytes, &ov);
9453 ok(bret == FALSE, "AcceptEx returned %d\n", bret);
9454 ok(GetLastError() == ERROR_IO_PENDING, "Last error was %d\n", GetLastError());
9456 SetLastError(0xdeadbeef);
9457 key = 0xdeadbeef;
9458 num_bytes = 0xdeadbeef;
9459 olp = (WSAOVERLAPPED *)0xdeadbeef;
9460 bret = GetQueuedCompletionStatus( io_port, &num_bytes, &key, &olp, 200 );
9461 ok(bret == FALSE, "failed to get completion status %u\n", bret);
9462 ok(GetLastError() == WAIT_TIMEOUT, "Last error was %d\n", GetLastError());
9463 ok(key == 0xdeadbeef, "Key is %lu\n", key);
9464 ok(num_bytes == 0xdeadbeef, "Number of bytes transferred is %u\n", num_bytes);
9465 ok(!olp, "Overlapped structure is at %p\n", olp);
9467 closesocket(src);
9468 src = INVALID_SOCKET;
9469 closesocket(dup);
9470 dup = INVALID_SOCKET;
9472 SetLastError(0xdeadbeef);
9473 key = 0xdeadbeef;
9474 num_bytes = 0xdeadbeef;
9475 olp = (WSAOVERLAPPED *)0xdeadbeef;
9476 bret = GetQueuedCompletionStatus(io_port, &num_bytes, &key, &olp, 100);
9477 ok(bret == FALSE, "failed to get completion status %u\n", bret);
9478 ok(GetLastError() == ERROR_OPERATION_ABORTED, "Last error was %d\n", GetLastError());
9479 ok(key == 125, "Key is %lu\n", key);
9480 ok(num_bytes == 0, "Number of bytes transferred is %u\n", num_bytes);
9481 ok(olp == &ov, "Overlapped structure is at %p\n", olp);
9482 ok(olp && olp->Internal == (ULONG)STATUS_CANCELLED, "Internal status is %lx\n", olp ? olp->Internal : 0);
9484 SetLastError(0xdeadbeef);
9485 key = 0xdeadbeef;
9486 num_bytes = 0xdeadbeef;
9487 olp = (WSAOVERLAPPED *)0xdeadbeef;
9488 bret = GetQueuedCompletionStatus( io_port, &num_bytes, &key, &olp, 200 );
9489 ok(bret == FALSE, "failed to get completion status %u\n", bret);
9490 ok(GetLastError() == WAIT_TIMEOUT, "Last error was %d\n", GetLastError());
9491 ok(key == 0xdeadbeef, "Key is %lu\n", key);
9492 ok(num_bytes == 0xdeadbeef, "Number of bytes transferred is %u\n", num_bytes);
9493 ok(!olp, "Overlapped structure is at %p\n", olp);
9495 /* Test IOCP with duplicated handle (closing duplicated handle) */
9497 src = setup_iocp_src(&bindAddress);
9499 SetLastError(0xdeadbeef);
9501 io_port = CreateIoCompletionPort((HANDLE)src, io_port, 125, 0);
9502 ok(io_port != NULL, "failed to create completion port %u\n", GetLastError());
9504 WSADuplicateSocketA( src, GetCurrentProcessId(), &info );
9505 dup = WSASocketA(AF_INET, SOCK_STREAM, 0, &info, 0, WSA_FLAG_OVERLAPPED);
9506 ok(dup != INVALID_SOCKET, "failed to duplicate socket!\n");
9508 bret = pAcceptEx(dup, dest, buf, sizeof(buf) - 2*(sizeof(struct sockaddr_in) + 16),
9509 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
9510 &num_bytes, &ov);
9511 ok(bret == FALSE, "AcceptEx returned %d\n", bret);
9512 ok(GetLastError() == ERROR_IO_PENDING, "Last error was %d\n", GetLastError());
9514 closesocket(dup);
9515 dup = INVALID_SOCKET;
9517 SetLastError(0xdeadbeef);
9518 key = 0xdeadbeef;
9519 num_bytes = 0xdeadbeef;
9520 olp = (WSAOVERLAPPED *)0xdeadbeef;
9521 bret = GetQueuedCompletionStatus( io_port, &num_bytes, &key, &olp, 200 );
9522 ok(bret == FALSE, "failed to get completion status %u\n", bret);
9523 ok(GetLastError() == WAIT_TIMEOUT, "Last error was %d\n", GetLastError());
9524 ok(key == 0xdeadbeef, "Key is %lu\n", key);
9525 ok(num_bytes == 0xdeadbeef, "Number of bytes transferred is %u\n", num_bytes);
9526 ok(!olp, "Overlapped structure is at %p\n", olp);
9528 SetLastError(0xdeadbeef);
9529 key = 0xdeadbeef;
9530 num_bytes = 0xdeadbeef;
9531 olp = (WSAOVERLAPPED *)0xdeadbeef;
9532 bret = GetQueuedCompletionStatus( io_port, &num_bytes, &key, &olp, 200 );
9533 ok(bret == FALSE, "failed to get completion status %u\n", bret);
9534 ok(GetLastError() == WAIT_TIMEOUT, "Last error was %d\n", GetLastError());
9535 ok(key == 0xdeadbeef, "Key is %lu\n", key);
9536 ok(num_bytes == 0xdeadbeef, "Number of bytes transferred is %u\n", num_bytes);
9537 ok(!olp, "Overlapped structure is at %p\n", olp);
9539 closesocket(src);
9540 src = INVALID_SOCKET;
9542 bret = GetQueuedCompletionStatus(io_port, &num_bytes, &key, &olp, 100);
9543 ok(bret == FALSE, "failed to get completion status %u\n", bret);
9544 ok(GetLastError() == ERROR_OPERATION_ABORTED, "Last error was %d\n", GetLastError());
9545 ok(key == 125, "Key is %lu\n", key);
9546 ok(num_bytes == 0, "Number of bytes transferred is %u\n", num_bytes);
9547 ok(olp == &ov, "Overlapped structure is at %p\n", olp);
9548 ok(olp && (olp->Internal == (ULONG)STATUS_CANCELLED), "Internal status is %lx\n", olp ? olp->Internal : 0);
9550 SetLastError(0xdeadbeef);
9551 key = 0xdeadbeef;
9552 num_bytes = 0xdeadbeef;
9553 olp = (WSAOVERLAPPED *)0xdeadbeef;
9554 bret = GetQueuedCompletionStatus( io_port, &num_bytes, &key, &olp, 200 );
9555 ok(bret == FALSE, "failed to get completion status %u\n", bret);
9556 ok(GetLastError() == WAIT_TIMEOUT, "Last error was %d\n", GetLastError());
9557 ok(key == 0xdeadbeef, "Key is %lu\n", key);
9558 ok(num_bytes == 0xdeadbeef, "Number of bytes transferred is %u\n", num_bytes);
9559 ok(!olp, "Overlapped structure is at %p\n", olp);
9561 /* Test IOCP with duplicated handle (closing original handle) */
9563 src = setup_iocp_src(&bindAddress);
9565 SetLastError(0xdeadbeef);
9567 io_port = CreateIoCompletionPort((HANDLE)src, io_port, 125, 0);
9568 ok(io_port != NULL, "failed to create completion port %u\n", GetLastError());
9570 WSADuplicateSocketA( src, GetCurrentProcessId(), &info );
9571 dup = WSASocketA(AF_INET, SOCK_STREAM, 0, &info, 0, WSA_FLAG_OVERLAPPED);
9572 ok(dup != INVALID_SOCKET, "failed to duplicate socket!\n");
9574 bret = pAcceptEx(dup, dest, buf, sizeof(buf) - 2*(sizeof(struct sockaddr_in) + 16),
9575 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
9576 &num_bytes, &ov);
9577 ok(bret == FALSE, "AcceptEx returned %d\n", bret);
9578 ok(GetLastError() == ERROR_IO_PENDING, "Last error was %d\n", GetLastError());
9580 closesocket(src);
9581 src = INVALID_SOCKET;
9583 SetLastError(0xdeadbeef);
9584 key = 0xdeadbeef;
9585 num_bytes = 0xdeadbeef;
9586 olp = (WSAOVERLAPPED *)0xdeadbeef;
9587 bret = GetQueuedCompletionStatus( io_port, &num_bytes, &key, &olp, 200 );
9588 ok(bret == FALSE, "failed to get completion status %u\n", bret);
9589 ok(GetLastError() == WAIT_TIMEOUT, "Last error was %d\n", GetLastError());
9590 ok(key == 0xdeadbeef, "Key is %lu\n", key);
9591 ok(num_bytes == 0xdeadbeef, "Number of bytes transferred is %u\n", num_bytes);
9592 ok(!olp, "Overlapped structure is at %p\n", olp);
9594 closesocket(dup);
9595 dup = INVALID_SOCKET;
9597 bret = GetQueuedCompletionStatus(io_port, &num_bytes, &key, &olp, 100);
9598 ok(bret == FALSE, "failed to get completion status %u\n", bret);
9599 ok(GetLastError() == ERROR_OPERATION_ABORTED, "Last error was %d\n", GetLastError());
9600 ok(key == 125, "Key is %lu\n", key);
9601 ok(num_bytes == 0, "Number of bytes transferred is %u\n", num_bytes);
9602 ok(olp == &ov, "Overlapped structure is at %p\n", olp);
9603 ok(olp && (olp->Internal == (ULONG)STATUS_CANCELLED), "Internal status is %lx\n", olp ? olp->Internal : 0);
9605 SetLastError(0xdeadbeef);
9606 key = 0xdeadbeef;
9607 num_bytes = 0xdeadbeef;
9608 olp = (WSAOVERLAPPED *)0xdeadbeef;
9609 bret = GetQueuedCompletionStatus( io_port, &num_bytes, &key, &olp, 200 );
9610 ok(bret == FALSE, "failed to get completion status %u\n", bret);
9611 ok(GetLastError() == WAIT_TIMEOUT, "Last error was %d\n", GetLastError());
9612 ok(key == 0xdeadbeef, "Key is %lu\n", key);
9613 ok(num_bytes == 0xdeadbeef, "Number of bytes transferred is %u\n", num_bytes);
9614 ok(!olp, "Overlapped structure is at %p\n", olp);
9616 /* Test IOCP without AcceptEx */
9618 src = setup_iocp_src(&bindAddress);
9620 SetLastError(0xdeadbeef);
9622 io_port = CreateIoCompletionPort((HANDLE)src, io_port, 125, 0);
9623 ok(io_port != NULL, "failed to create completion port %u\n", GetLastError());
9625 closesocket(src);
9626 src = INVALID_SOCKET;
9628 SetLastError(0xdeadbeef);
9629 key = 0xdeadbeef;
9630 num_bytes = 0xdeadbeef;
9631 olp = (WSAOVERLAPPED *)0xdeadbeef;
9632 bret = GetQueuedCompletionStatus( io_port, &num_bytes, &key, &olp, 200 );
9633 ok(bret == FALSE, "failed to get completion status %u\n", bret);
9634 ok(GetLastError() == WAIT_TIMEOUT, "Last error was %d\n", GetLastError());
9635 ok(key == 0xdeadbeef, "Key is %lu\n", key);
9636 ok(num_bytes == 0xdeadbeef, "Number of bytes transferred is %u\n", num_bytes);
9637 ok(!olp, "Overlapped structure is at %p\n", olp);
9639 /* */
9641 src = setup_iocp_src(&bindAddress);
9643 connector = socket(AF_INET, SOCK_STREAM, 0);
9644 ok(connector != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
9646 io_port = CreateIoCompletionPort((HANDLE)src, io_port, 125, 0);
9647 ok(io_port != NULL, "failed to create completion port %u\n", GetLastError());
9649 io_port = CreateIoCompletionPort((HANDLE)dest, io_port, 236, 0);
9650 ok(io_port != NULL, "failed to create completion port %u\n", GetLastError());
9652 bret = pAcceptEx(src, dest, buf, sizeof(buf) - 2*(sizeof(struct sockaddr_in) + 16),
9653 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
9654 &num_bytes, &ov);
9655 ok(bret == FALSE, "AcceptEx returned %d\n", bret);
9656 ok(GetLastError() == ERROR_IO_PENDING, "Last error was %d\n", GetLastError());
9658 iret = connect(connector, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
9659 ok(iret == 0, "connecting to accepting socket failed, error %d\n", GetLastError());
9661 closesocket(connector);
9662 connector = INVALID_SOCKET;
9664 SetLastError(0xdeadbeef);
9665 key = 0xdeadbeef;
9666 num_bytes = 0xdeadbeef;
9667 olp = (WSAOVERLAPPED *)0xdeadbeef;
9669 bret = GetQueuedCompletionStatus(io_port, &num_bytes, &key, &olp, 100);
9670 ok(bret == TRUE, "failed to get completion status %u\n", bret);
9671 ok(GetLastError() == 0xdeadbeef, "Last error was %d\n", GetLastError());
9672 ok(key == 125, "Key is %lu\n", key);
9673 ok(num_bytes == 0, "Number of bytes transferred is %u\n", num_bytes);
9674 ok(olp == &ov, "Overlapped structure is at %p\n", olp);
9675 ok(olp && (olp->Internal == (ULONG)STATUS_SUCCESS), "Internal status is %lx\n", olp ? olp->Internal : 0);
9677 SetLastError(0xdeadbeef);
9678 key = 0xdeadbeef;
9679 num_bytes = 0xdeadbeef;
9680 olp = (WSAOVERLAPPED *)0xdeadbeef;
9681 bret = GetQueuedCompletionStatus( io_port, &num_bytes, &key, &olp, 200 );
9682 ok(bret == FALSE, "failed to get completion status %u\n", bret);
9683 ok(GetLastError() == WAIT_TIMEOUT, "Last error was %d\n", GetLastError());
9684 ok(key == 0xdeadbeef, "Key is %lu\n", key);
9685 ok(num_bytes == 0xdeadbeef, "Number of bytes transferred is %u\n", num_bytes);
9686 ok(!olp, "Overlapped structure is at %p\n", olp);
9688 if (dest != INVALID_SOCKET)
9689 closesocket(dest);
9690 if (src != INVALID_SOCKET)
9691 closesocket(dest);
9693 /* */
9695 src = setup_iocp_src(&bindAddress);
9697 dest = socket(AF_INET, SOCK_STREAM, 0);
9698 ok(dest != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
9700 connector = socket(AF_INET, SOCK_STREAM, 0);
9701 ok(connector != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
9703 io_port = CreateIoCompletionPort((HANDLE)src, io_port, 125, 0);
9704 ok(io_port != NULL, "failed to create completion port %u\n", GetLastError());
9706 io_port = CreateIoCompletionPort((HANDLE)dest, io_port, 236, 0);
9707 ok(io_port != NULL, "failed to create completion port %u\n", GetLastError());
9709 bret = pAcceptEx(src, dest, buf, sizeof(buf) - 2*(sizeof(struct sockaddr_in) + 16),
9710 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
9711 &num_bytes, &ov);
9712 ok(bret == FALSE, "AcceptEx returned %d\n", bret);
9713 ok(GetLastError() == ERROR_IO_PENDING, "Last error was %d\n", GetLastError());
9715 iret = connect(connector, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
9716 ok(iret == 0, "connecting to accepting socket failed, error %d\n", GetLastError());
9718 iret = send(connector, buf, 1, 0);
9719 ok(iret == 1, "could not send 1 byte: send %d errno %d\n", iret, WSAGetLastError());
9721 Sleep(100);
9723 closesocket(dest);
9724 dest = INVALID_SOCKET;
9726 SetLastError(0xdeadbeef);
9727 key = 0xdeadbeef;
9728 num_bytes = 0xdeadbeef;
9729 olp = (WSAOVERLAPPED *)0xdeadbeef;
9731 bret = GetQueuedCompletionStatus(io_port, &num_bytes, &key, &olp, 100);
9732 ok(bret == TRUE, "failed to get completion status %u\n", bret);
9733 ok(GetLastError() == 0xdeadbeef, "Last error was %d\n", GetLastError());
9734 ok(key == 125, "Key is %lu\n", key);
9735 ok(num_bytes == 1, "Number of bytes transferred is %u\n", num_bytes);
9736 ok(olp == &ov, "Overlapped structure is at %p\n", olp);
9737 ok(olp && (olp->Internal == (ULONG)STATUS_SUCCESS), "Internal status is %lx\n", olp ? olp->Internal : 0);
9739 SetLastError(0xdeadbeef);
9740 key = 0xdeadbeef;
9741 num_bytes = 0xdeadbeef;
9742 olp = (WSAOVERLAPPED *)0xdeadbeef;
9743 bret = GetQueuedCompletionStatus( io_port, &num_bytes, &key, &olp, 200 );
9744 ok(bret == FALSE, "failed to get completion status %u\n", bret);
9745 ok(GetLastError() == WAIT_TIMEOUT, "Last error was %d\n", GetLastError());
9746 ok(key == 0xdeadbeef, "Key is %lu\n", key);
9747 ok(num_bytes == 0xdeadbeef, "Number of bytes transferred is %u\n", num_bytes);
9748 ok(!olp, "Overlapped structure is at %p\n", olp);
9750 if (src != INVALID_SOCKET)
9751 closesocket(src);
9752 if (connector != INVALID_SOCKET)
9753 closesocket(connector);
9755 /* */
9757 src = setup_iocp_src(&bindAddress);
9759 dest = socket(AF_INET, SOCK_STREAM, 0);
9760 ok(dest != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
9762 connector = socket(AF_INET, SOCK_STREAM, 0);
9763 ok(connector != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
9765 io_port = CreateIoCompletionPort((HANDLE)src, io_port, 125, 0);
9766 ok(io_port != NULL, "failed to create completion port %u\n", GetLastError());
9768 io_port = CreateIoCompletionPort((HANDLE)dest, io_port, 236, 0);
9769 ok(io_port != NULL, "failed to create completion port %u\n", GetLastError());
9771 bret = pAcceptEx(src, dest, buf, sizeof(buf) - 2*(sizeof(struct sockaddr_in) + 16),
9772 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
9773 &num_bytes, &ov);
9774 ok(bret == FALSE, "AcceptEx returned %d\n", bret);
9775 ok(GetLastError() == ERROR_IO_PENDING, "Last error was %d\n", GetLastError());
9777 iret = connect(connector, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
9778 ok(iret == 0, "connecting to accepting socket failed, error %d\n", GetLastError());
9780 closesocket(dest);
9782 SetLastError(0xdeadbeef);
9783 key = 0xdeadbeef;
9784 num_bytes = 0xdeadbeef;
9785 olp = (WSAOVERLAPPED *)0xdeadbeef;
9787 bret = GetQueuedCompletionStatus(io_port, &num_bytes, &key, &olp, 100);
9788 ok(bret == FALSE, "failed to get completion status %u\n", bret);
9789 ok(GetLastError() == ERROR_OPERATION_ABORTED
9790 || GetLastError() == ERROR_CONNECTION_ABORTED, "got error %u\n", GetLastError());
9791 ok(key == 125, "Key is %lu\n", key);
9792 ok(num_bytes == 0, "Number of bytes transferred is %u\n", num_bytes);
9793 ok(olp == &ov, "Overlapped structure is at %p\n", olp);
9794 ok((NTSTATUS)olp->Internal == STATUS_CANCELLED
9795 || (NTSTATUS)olp->Internal == STATUS_CONNECTION_ABORTED, "got status %#lx\n", olp->Internal);
9797 SetLastError(0xdeadbeef);
9798 key = 0xdeadbeef;
9799 num_bytes = 0xdeadbeef;
9800 olp = (WSAOVERLAPPED *)0xdeadbeef;
9801 bret = GetQueuedCompletionStatus( io_port, &num_bytes, &key, &olp, 200 );
9802 ok(bret == FALSE, "failed to get completion status %u\n", bret);
9803 ok(GetLastError() == WAIT_TIMEOUT, "Last error was %d\n", GetLastError());
9804 ok(key == 0xdeadbeef, "Key is %lu\n", key);
9805 ok(num_bytes == 0xdeadbeef, "Number of bytes transferred is %u\n", num_bytes);
9806 ok(!olp, "Overlapped structure is at %p\n", olp);
9808 closesocket(src);
9809 closesocket(connector);
9810 CloseHandle(io_port);
9813 static void test_connect_completion_port(void)
9815 OVERLAPPED overlapped = {0}, *overlapped_ptr;
9816 GUID connectex_guid = WSAID_CONNECTEX;
9817 SOCKET connector, listener, acceptor;
9818 struct sockaddr_in addr, destaddr;
9819 LPFN_CONNECTEX pConnectEx;
9820 int ret, addrlen;
9821 ULONG_PTR key;
9822 HANDLE port;
9823 DWORD size;
9825 overlapped.hEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
9827 listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
9828 ok(listener != -1, "failed to create socket, error %u\n", WSAGetLastError());
9830 memset(&addr, 0, sizeof(addr));
9831 addr.sin_family = AF_INET;
9832 addr.sin_addr.s_addr = inet_addr("127.0.0.1");
9833 ret = bind(listener, (struct sockaddr *)&addr, sizeof(addr));
9834 ok(!ret, "failed to bind, error %u\n", WSAGetLastError());
9835 addrlen = sizeof(destaddr);
9836 ret = getsockname(listener, (struct sockaddr *)&destaddr, &addrlen);
9837 ok(!ret, "failed to get address, error %u\n", WSAGetLastError());
9839 ret = listen(listener, 1);
9840 ok(!ret, "failed to listen, error %u\n", WSAGetLastError());
9842 connector = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
9843 ok(connector != -1, "failed to create socket, error %u\n", WSAGetLastError());
9845 ret = WSAIoctl(connector, SIO_GET_EXTENSION_FUNCTION_POINTER, &connectex_guid, sizeof(connectex_guid),
9846 &pConnectEx, sizeof(pConnectEx), &size, NULL, NULL);
9847 ok(!ret, "Failed to get ConnectEx, error %u\n", WSAGetLastError());
9849 /* connect() does not queue completion. */
9851 port = CreateIoCompletionPort((HANDLE)connector, NULL, 0, 0);
9852 ok(!!port, "failed to create port, error %u\n", GetLastError());
9854 ret = connect(connector, (struct sockaddr *)&destaddr, sizeof(destaddr));
9855 ok(!ret, "failed to connect, error %u\n", WSAGetLastError());
9856 acceptor = accept(listener, NULL, NULL);
9857 ok(acceptor != -1, "failed to accept, error %u\n", WSAGetLastError());
9858 closesocket(acceptor);
9860 ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 0);
9861 ok(!ret, "expected failure\n");
9862 ok(GetLastError() == WAIT_TIMEOUT, "got error %u\n", GetLastError());
9864 closesocket(connector);
9865 CloseHandle(port);
9867 connector = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
9868 ok(connector != -1, "failed to create socket, error %u\n", WSAGetLastError());
9869 port = CreateIoCompletionPort((HANDLE)connector, NULL, 0, 0);
9870 ok(!!port, "failed to create port, error %u\n", GetLastError());
9871 set_blocking(connector, FALSE);
9873 ret = connect(connector, (struct sockaddr *)&destaddr, sizeof(destaddr));
9874 ok(ret == -1, "expected failure\n");
9875 ok(WSAGetLastError() == WSAEWOULDBLOCK, "got error %u\n", WSAGetLastError());
9876 acceptor = accept(listener, NULL, NULL);
9877 ok(acceptor != -1, "failed to accept, error %u\n", WSAGetLastError());
9878 closesocket(acceptor);
9880 ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 0);
9881 ok(!ret, "expected failure\n");
9882 ok(GetLastError() == WAIT_TIMEOUT, "got error %u\n", GetLastError());
9884 closesocket(connector);
9885 CloseHandle(port);
9887 /* ConnectEx() queues completion. */
9889 connector = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
9890 ok(connector != -1, "failed to create socket, error %u\n", WSAGetLastError());
9891 port = CreateIoCompletionPort((HANDLE)connector, NULL, 0, 0);
9892 ok(!!port, "failed to create port, error %u\n", GetLastError());
9893 ret = bind(connector, (struct sockaddr *)&addr, sizeof(addr));
9894 ok(!ret, "failed to bind, error %u\n", WSAGetLastError());
9896 ret = pConnectEx(connector, (struct sockaddr *)&destaddr, sizeof(destaddr),
9897 NULL, 0, &size, &overlapped);
9898 ok(!ret, "expected failure\n");
9899 ok(GetLastError() == ERROR_IO_PENDING, "got error %u\n", GetLastError());
9900 ret = WaitForSingleObject(overlapped.hEvent, 1000);
9901 ok(!ret, "wait failed\n");
9902 ret = GetOverlappedResult((HANDLE)connector, &overlapped, &size, FALSE);
9903 ok(ret, "got error %u\n", GetLastError());
9904 ok(!size, "got %u bytes\n", size);
9905 acceptor = accept(listener, NULL, NULL);
9906 ok(acceptor != -1, "failed to accept, error %u\n", WSAGetLastError());
9907 closesocket(acceptor);
9909 size = 0xdeadbeef;
9910 key = 0xdeadbeef;
9911 overlapped_ptr = NULL;
9912 ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 0);
9913 ok(ret, "got error %u\n", GetLastError());
9914 ok(!key, "got key %#Ix\n", key);
9915 ok(!size, "got %u bytes\n", size);
9916 ok(overlapped_ptr == &overlapped, "got overlapped %p\n", overlapped_ptr);
9918 closesocket(connector);
9919 CloseHandle(port);
9921 /* Test ConnectEx() with a non-empty buffer. */
9923 connector = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
9924 ok(connector != -1, "failed to create socket, error %u\n", WSAGetLastError());
9925 port = CreateIoCompletionPort((HANDLE)connector, NULL, 0, 0);
9926 ok(!!port, "failed to create port, error %u\n", GetLastError());
9927 ret = bind(connector, (struct sockaddr *)&addr, sizeof(addr));
9928 ok(!ret, "failed to bind, error %u\n", WSAGetLastError());
9930 ret = pConnectEx(connector, (struct sockaddr *)&destaddr, sizeof(destaddr),
9931 (void *)"one", 3, &size, &overlapped);
9932 ok(!ret, "expected failure\n");
9933 ok(GetLastError() == ERROR_IO_PENDING, "got error %u\n", GetLastError());
9934 ret = WaitForSingleObject(overlapped.hEvent, 1000);
9935 ok(!ret, "wait failed\n");
9936 ret = GetOverlappedResult((HANDLE)connector, &overlapped, &size, FALSE);
9937 ok(ret, "got error %u\n", GetLastError());
9938 ok(size == 3, "got %u bytes\n", size);
9939 acceptor = accept(listener, NULL, NULL);
9940 ok(acceptor != -1, "failed to accept, error %u\n", WSAGetLastError());
9941 closesocket(acceptor);
9943 size = 0xdeadbeef;
9944 key = 0xdeadbeef;
9945 overlapped_ptr = NULL;
9946 ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 0);
9947 ok(ret, "got error %u\n", GetLastError());
9948 ok(!key, "got key %#Ix\n", key);
9949 ok(size == 3, "got %u bytes\n", size);
9950 ok(overlapped_ptr == &overlapped, "got overlapped %p\n", overlapped_ptr);
9952 closesocket(connector);
9953 CloseHandle(port);
9955 /* Suppress completion by setting the low bit. */
9957 connector = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
9958 ok(connector != -1, "failed to create socket, error %u\n", WSAGetLastError());
9959 port = CreateIoCompletionPort((HANDLE)connector, NULL, 0, 0);
9960 ok(!!port, "failed to create port, error %u\n", GetLastError());
9961 ret = bind(connector, (struct sockaddr *)&addr, sizeof(addr));
9962 ok(!ret, "failed to bind, error %u\n", WSAGetLastError());
9964 overlapped.hEvent = (HANDLE)((ULONG_PTR)overlapped.hEvent | 1);
9966 ret = pConnectEx(connector, (struct sockaddr *)&destaddr, sizeof(destaddr),
9967 NULL, 0, &size, &overlapped);
9968 ok(!ret, "expected failure\n");
9969 ok(GetLastError() == ERROR_IO_PENDING, "got error %u\n", GetLastError());
9970 ret = WaitForSingleObject(overlapped.hEvent, 1000);
9971 ok(!ret, "wait failed\n");
9972 ret = GetOverlappedResult((HANDLE)connector, &overlapped, &size, FALSE);
9973 ok(ret, "got error %u\n", GetLastError());
9974 ok(!size, "got %u bytes\n", size);
9975 acceptor = accept(listener, NULL, NULL);
9976 ok(acceptor != -1, "failed to accept, error %u\n", WSAGetLastError());
9977 closesocket(acceptor);
9979 ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 0);
9980 ok(!ret, "expected failure\n");
9981 ok(GetLastError() == WAIT_TIMEOUT, "got error %u\n", GetLastError());
9983 closesocket(connector);
9984 CloseHandle(port);
9986 overlapped.hEvent = (HANDLE)((ULONG_PTR)overlapped.hEvent & ~1);
9988 /* Skip completion on success. */
9990 connector = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
9991 ok(connector != -1, "failed to create socket, error %u\n", WSAGetLastError());
9992 port = CreateIoCompletionPort((HANDLE)connector, NULL, 0, 0);
9993 ok(!!port, "failed to create port, error %u\n", GetLastError());
9994 ret = SetFileCompletionNotificationModes((HANDLE)connector, FILE_SKIP_COMPLETION_PORT_ON_SUCCESS);
9995 ok(ret, "got error %u\n", GetLastError());
9996 ret = bind(connector, (struct sockaddr *)&addr, sizeof(addr));
9997 ok(!ret, "failed to bind, error %u\n", WSAGetLastError());
9999 ret = pConnectEx(connector, (struct sockaddr *)&destaddr, sizeof(destaddr),
10000 NULL, 0, &size, &overlapped);
10001 ok(!ret, "expected failure\n");
10002 ok(GetLastError() == ERROR_IO_PENDING, "got error %u\n", GetLastError());
10003 ret = WaitForSingleObject(overlapped.hEvent, 1000);
10004 ok(!ret, "wait failed\n");
10005 ret = GetOverlappedResult((HANDLE)connector, &overlapped, &size, FALSE);
10006 ok(ret, "got error %u\n", GetLastError());
10007 ok(!size, "got %u bytes\n", size);
10008 acceptor = accept(listener, NULL, NULL);
10009 ok(acceptor != -1, "failed to accept, error %u\n", WSAGetLastError());
10010 closesocket(acceptor);
10012 size = 0xdeadbeef;
10013 key = 0xdeadbeef;
10014 overlapped_ptr = NULL;
10015 ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 0);
10016 ok(ret, "got error %u\n", GetLastError());
10017 ok(!key, "got key %#Ix\n", key);
10018 ok(!size, "got %u bytes\n", size);
10019 ok(overlapped_ptr == &overlapped, "got overlapped %p\n", overlapped_ptr);
10021 closesocket(connector);
10022 CloseHandle(port);
10024 closesocket(listener);
10026 /* Connect to an invalid address. */
10028 connector = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
10029 ok(connector != -1, "failed to create socket, error %u\n", WSAGetLastError());
10030 port = CreateIoCompletionPort((HANDLE)connector, NULL, 0, 0);
10031 ok(!!port, "failed to create port, error %u\n", GetLastError());
10032 ret = SetFileCompletionNotificationModes((HANDLE)connector, FILE_SKIP_COMPLETION_PORT_ON_SUCCESS);
10033 ok(ret, "got error %u\n", GetLastError());
10034 ret = bind(connector, (struct sockaddr *)&addr, sizeof(addr));
10035 ok(!ret, "failed to bind, error %u\n", WSAGetLastError());
10037 ret = pConnectEx(connector, (struct sockaddr *)&destaddr, sizeof(destaddr),
10038 NULL, 0, &size, &overlapped);
10039 ok(!ret, "expected failure\n");
10040 ok(GetLastError() == ERROR_IO_PENDING, "got error %u\n", GetLastError());
10041 ret = WaitForSingleObject(overlapped.hEvent, 15000);
10042 ok(!ret, "wait failed\n");
10043 ret = GetOverlappedResult((HANDLE)connector, &overlapped, &size, FALSE);
10044 ok(!ret, "expected failure\n");
10045 ok(GetLastError() == ERROR_CONNECTION_REFUSED, "got error %u\n", GetLastError());
10046 ok(!size, "got %u bytes\n", size);
10048 size = 0xdeadbeef;
10049 key = 0xdeadbeef;
10050 overlapped_ptr = NULL;
10051 ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 0);
10052 ok(!ret, "expected failure\n");
10053 ok(GetLastError() == ERROR_CONNECTION_REFUSED, "got error %u\n", GetLastError());
10054 ok(!key, "got key %#Ix\n", key);
10055 ok(!size, "got %u bytes\n", size);
10056 ok(overlapped_ptr == &overlapped, "got overlapped %p\n", overlapped_ptr);
10058 closesocket(connector);
10059 CloseHandle(port);
10062 static void test_shutdown_completion_port(void)
10064 OVERLAPPED overlapped = {0}, *overlapped_ptr;
10065 GUID disconnectex_guid = WSAID_DISCONNECTEX;
10066 struct sockaddr_in addr, destaddr;
10067 LPFN_DISCONNECTEX pDisconnectEx;
10068 SOCKET listener, server, client;
10069 int ret, addrlen;
10070 ULONG_PTR key;
10071 HANDLE port;
10072 DWORD size;
10074 overlapped.hEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
10076 listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
10077 ok(listener != -1, "failed to create socket, error %u\n", WSAGetLastError());
10079 memset(&addr, 0, sizeof(addr));
10080 addr.sin_family = AF_INET;
10081 addr.sin_addr.s_addr = inet_addr("127.0.0.1");
10082 ret = bind(listener, (struct sockaddr *)&addr, sizeof(addr));
10083 ok(!ret, "failed to bind, error %u\n", WSAGetLastError());
10084 addrlen = sizeof(destaddr);
10085 ret = getsockname(listener, (struct sockaddr *)&destaddr, &addrlen);
10086 ok(!ret, "failed to get address, error %u\n", WSAGetLastError());
10088 ret = listen(listener, 1);
10089 ok(!ret, "failed to listen, error %u\n", WSAGetLastError());
10091 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
10092 ok(client != -1, "failed to create socket, error %u\n", WSAGetLastError());
10094 ret = WSAIoctl(client, SIO_GET_EXTENSION_FUNCTION_POINTER, &disconnectex_guid, sizeof(disconnectex_guid),
10095 &pDisconnectEx, sizeof(pDisconnectEx), &size, NULL, NULL);
10096 ok(!ret, "Failed to get ConnectEx, error %u\n", WSAGetLastError());
10098 /* shutdown() does not queue completion. */
10100 port = CreateIoCompletionPort((HANDLE)client, NULL, 0, 0);
10101 ok(!!port, "failed to create port, error %u\n", GetLastError());
10102 ret = connect(client, (struct sockaddr *)&destaddr, sizeof(destaddr));
10103 ok(!ret, "failed to connect, error %u\n", WSAGetLastError());
10104 server = accept(listener, NULL, NULL);
10105 ok(server != -1, "failed to accept, error %u\n", WSAGetLastError());
10107 ret = shutdown(client, SD_BOTH);
10108 ok(!ret, "failed to shutdown, error %u\n", WSAGetLastError());
10110 ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 0);
10111 ok(!ret, "expected failure\n");
10112 ok(GetLastError() == WAIT_TIMEOUT, "got error %u\n", GetLastError());
10114 closesocket(server);
10115 closesocket(client);
10116 CloseHandle(port);
10118 /* WSASendDisconnect() and WSARecvDisconnect() do not queue completion. */
10120 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
10121 ok(client != -1, "failed to create socket, error %u\n", WSAGetLastError());
10122 port = CreateIoCompletionPort((HANDLE)client, NULL, 0, 0);
10123 ok(!!port, "failed to create port, error %u\n", GetLastError());
10124 ret = connect(client, (struct sockaddr *)&destaddr, sizeof(destaddr));
10125 ok(!ret, "failed to connect, error %u\n", WSAGetLastError());
10126 server = accept(listener, NULL, NULL);
10127 ok(server != -1, "failed to accept, error %u\n", WSAGetLastError());
10129 ret = WSASendDisconnect(client, NULL);
10130 ok(!ret, "failed to shutdown, error %u\n", WSAGetLastError());
10132 ret = WSARecvDisconnect(client, NULL);
10133 ok(!ret, "failed to shutdown, error %u\n", WSAGetLastError());
10135 ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 0);
10136 ok(!ret, "expected failure\n");
10137 ok(GetLastError() == WAIT_TIMEOUT, "got error %u\n", GetLastError());
10139 closesocket(server);
10140 closesocket(client);
10141 CloseHandle(port);
10143 /* DisconnectEx() queues completion. */
10145 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
10146 ok(client != -1, "failed to create socket, error %u\n", WSAGetLastError());
10147 port = CreateIoCompletionPort((HANDLE)client, NULL, 0, 0);
10148 ok(!!port, "failed to create port, error %u\n", GetLastError());
10149 ret = SetFileCompletionNotificationModes((HANDLE)client, FILE_SKIP_COMPLETION_PORT_ON_SUCCESS);
10150 ok(ret, "got error %u\n", GetLastError());
10151 ret = connect(client, (struct sockaddr *)&destaddr, sizeof(destaddr));
10152 ok(!ret, "failed to connect, error %u\n", WSAGetLastError());
10153 server = accept(listener, NULL, NULL);
10154 ok(server != -1, "failed to accept, error %u\n", WSAGetLastError());
10156 SetLastError(0xdeadbeef);
10157 ret = pDisconnectEx(client, &overlapped, 0, 0);
10158 ok(!ret, "expected failure\n");
10159 ok(GetLastError() == ERROR_IO_PENDING, "got error %u\n", GetLastError());
10161 ret = WaitForSingleObject(overlapped.hEvent, 1000);
10162 ok(!ret, "wait failed\n");
10164 size = 0xdeadbeef;
10165 ret = GetOverlappedResult((HANDLE)client, &overlapped, &size, TRUE);
10166 ok(ret, "got error %u\n", GetLastError());
10167 ok(!size, "got %u bytes\n", size);
10169 size = 0xdeadbeef;
10170 key = 0xdeadbeef;
10171 overlapped_ptr = NULL;
10172 ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 0);
10173 todo_wine ok(ret, "got error %u\n", GetLastError());
10174 todo_wine ok(!key, "got key %#Ix\n", key);
10175 todo_wine ok(!size, "got %u bytes\n", size);
10176 todo_wine ok(overlapped_ptr == &overlapped, "got overlapped %p\n", overlapped_ptr);
10178 closesocket(server);
10179 closesocket(client);
10180 CloseHandle(port);
10182 /* Test passing a NULL overlapped structure to DisconnectEx(). */
10184 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
10185 ok(client != -1, "failed to create socket, error %u\n", WSAGetLastError());
10186 port = CreateIoCompletionPort((HANDLE)client, NULL, 0, 0);
10187 ok(!!port, "failed to create port, error %u\n", GetLastError());
10188 ret = connect(client, (struct sockaddr *)&destaddr, sizeof(destaddr));
10189 ok(!ret, "failed to connect, error %u\n", WSAGetLastError());
10190 server = accept(listener, NULL, NULL);
10191 ok(server != -1, "failed to accept, error %u\n", WSAGetLastError());
10193 SetLastError(0xdeadbeef);
10194 ret = pDisconnectEx(client, NULL, 0, 0);
10195 ok(ret, "expected success\n");
10196 ok(!GetLastError() || GetLastError() == 0xdeadbeef /* < 7 */, "got error %u\n", GetLastError());
10198 ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 0);
10199 ok(!ret, "expected failure\n");
10200 ok(GetLastError() == WAIT_TIMEOUT, "got error %u\n", GetLastError());
10202 closesocket(server);
10203 closesocket(client);
10204 CloseHandle(port);
10206 /* Suppress completion by setting the low bit. */
10208 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
10209 ok(client != -1, "failed to create socket, error %u\n", WSAGetLastError());
10210 port = CreateIoCompletionPort((HANDLE)client, NULL, 0, 0);
10211 ok(!!port, "failed to create port, error %u\n", GetLastError());
10212 ret = connect(client, (struct sockaddr *)&destaddr, sizeof(destaddr));
10213 ok(!ret, "failed to connect, error %u\n", WSAGetLastError());
10214 server = accept(listener, NULL, NULL);
10215 ok(server != -1, "failed to accept, error %u\n", WSAGetLastError());
10217 overlapped.hEvent = (HANDLE)((ULONG_PTR)overlapped.hEvent | 1);
10219 SetLastError(0xdeadbeef);
10220 ret = pDisconnectEx(client, &overlapped, 0, 0);
10221 ok(!ret, "expected failure\n");
10222 ok(GetLastError() == ERROR_IO_PENDING, "got error %u\n", GetLastError());
10224 ret = WaitForSingleObject(overlapped.hEvent, 1000);
10225 ok(!ret, "wait failed\n");
10227 size = 0xdeadbeef;
10228 ret = GetOverlappedResult((HANDLE)client, &overlapped, &size, TRUE);
10229 ok(ret, "got error %u\n", GetLastError());
10230 ok(!size, "got %u bytes\n", size);
10232 ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 0);
10233 ok(!ret, "expected failure\n");
10234 ok(GetLastError() == WAIT_TIMEOUT, "got error %u\n", GetLastError());
10236 closesocket(server);
10237 closesocket(client);
10238 CloseHandle(port);
10240 overlapped.hEvent = (HANDLE)((ULONG_PTR)overlapped.hEvent & ~1);
10242 CloseHandle(overlapped.hEvent);
10245 static void test_address_list_query(void)
10247 char buffer[1024];
10248 SOCKET_ADDRESS_LIST *address_list = (SOCKET_ADDRESS_LIST *)buffer;
10249 OVERLAPPED overlapped = {0}, *overlapped_ptr;
10250 DWORD size, expect_size;
10251 unsigned int i;
10252 ULONG_PTR key;
10253 HANDLE port;
10254 SOCKET s;
10255 int ret;
10257 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
10258 ok(s != INVALID_SOCKET, "Failed to create socket, error %d.\n", WSAGetLastError());
10259 port = CreateIoCompletionPort((HANDLE)s, NULL, 123, 0);
10261 size = 0;
10262 ret = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, NULL, 0, &size, NULL, NULL);
10263 ok(ret == SOCKET_ERROR, "Got unexpected ret %d.\n", ret);
10264 ok(WSAGetLastError() == WSAEFAULT, "Got unexpected error %d.\n", WSAGetLastError());
10265 ok(size >= FIELD_OFFSET(SOCKET_ADDRESS_LIST, Address[0]), "Got unexpected size %u.\n", size);
10266 expect_size = size;
10268 size = 0;
10269 ret = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, buffer, sizeof(buffer), &size, NULL, NULL);
10270 ok(!ret, "Got unexpected ret %d.\n", ret);
10271 ok(!WSAGetLastError(), "Got unexpected error %d.\n", WSAGetLastError());
10272 ok(size == expect_size, "Expected size %u, got %u.\n", expect_size, size);
10274 expect_size = FIELD_OFFSET(SOCKET_ADDRESS_LIST, Address[address_list->iAddressCount]);
10275 for (i = 0; i < address_list->iAddressCount; ++i)
10277 expect_size += address_list->Address[i].iSockaddrLength;
10279 ok(size == expect_size, "Expected size %u, got %u.\n", expect_size, size);
10281 ret = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, buffer, sizeof(buffer), NULL, NULL, NULL);
10282 ok(ret == SOCKET_ERROR, "Got unexpected ret %d.\n", ret);
10283 ok(WSAGetLastError() == WSAEFAULT, "Got unexpected error %d.\n", WSAGetLastError());
10285 size = 0xdeadbeef;
10286 ret = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, NULL, sizeof(buffer), &size, NULL, NULL);
10287 ok(ret == SOCKET_ERROR, "Got unexpected ret %d.\n", ret);
10288 ok(WSAGetLastError() == WSAEFAULT, "Got unexpected error %d.\n", WSAGetLastError());
10289 ok(size == expect_size, "Expected size %u, got %u.\n", expect_size, size);
10291 size = 0xdeadbeef;
10292 ret = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, buffer, 0, &size, NULL, NULL);
10293 ok(ret == SOCKET_ERROR, "Got unexpected ret %d.\n", ret);
10294 ok(WSAGetLastError() == WSAEFAULT, "Got unexpected error %d.\n", WSAGetLastError());
10295 ok(size == expect_size, "Expected size %u, got %u.\n", expect_size, size);
10297 size = 0xdeadbeef;
10298 ret = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, buffer, 1, &size, NULL, NULL);
10299 ok(ret == SOCKET_ERROR, "Got unexpected ret %d.\n", ret);
10300 ok(WSAGetLastError() == WSAEINVAL, "Got unexpected error %d.\n", WSAGetLastError());
10301 ok(!size, "Got size %u.\n", size);
10303 size = 0xdeadbeef;
10304 memset(buffer, 0xcc, sizeof(buffer));
10305 ret = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, buffer,
10306 FIELD_OFFSET(SOCKET_ADDRESS_LIST, Address[0]), &size, NULL, NULL);
10307 ok(ret == SOCKET_ERROR, "Got unexpected ret %d.\n", ret);
10308 ok(WSAGetLastError() == WSAEFAULT, "Got unexpected error %d.\n", WSAGetLastError());
10309 ok(size == expect_size, "Expected size %u, got %u.\n", expect_size, size);
10310 ok(address_list->iAddressCount == 0xcccccccc, "Got %u addresses.\n", address_list->iAddressCount);
10312 WSASetLastError(0xdeadbeef);
10313 overlapped.Internal = 0xdeadbeef;
10314 overlapped.InternalHigh = 0xdeadbeef;
10315 size = 0xdeadbeef;
10316 ret = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, buffer, 0, &size, &overlapped, NULL);
10317 ok(ret == -1, "Got unexpected ret %d.\n", ret);
10318 ok(WSAGetLastError() == WSAEFAULT, "Got unexpected error %d.\n", WSAGetLastError());
10319 ok(size == expect_size, "Expected size %u, got %u.\n", expect_size, size);
10320 ok(overlapped.Internal == 0xdeadbeef, "Got status %#x.\n", (NTSTATUS)overlapped.Internal);
10321 ok(overlapped.InternalHigh == 0xdeadbeef, "Got size %Iu.\n", overlapped.InternalHigh);
10323 overlapped.Internal = 0xdeadbeef;
10324 overlapped.InternalHigh = 0xdeadbeef;
10325 size = 0xdeadbeef;
10326 ret = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, buffer, 1, &size, &overlapped, NULL);
10327 ok(ret == -1, "Got unexpected ret %d.\n", ret);
10328 ok(WSAGetLastError() == WSAEINVAL, "Got unexpected error %d.\n", WSAGetLastError());
10329 ok(!size, "Expected size %u, got %u.\n", expect_size, size);
10330 ok(overlapped.Internal == 0xdeadbeef, "Got status %#x.\n", (NTSTATUS)overlapped.Internal);
10331 ok(overlapped.InternalHigh == 0xdeadbeef, "Got size %Iu.\n", overlapped.InternalHigh);
10333 overlapped.Internal = 0xdeadbeef;
10334 overlapped.InternalHigh = 0xdeadbeef;
10335 size = 0xdeadbeef;
10336 ret = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, buffer,
10337 FIELD_OFFSET(SOCKET_ADDRESS_LIST, Address[0]), &size, &overlapped, NULL);
10338 ok(ret == -1, "Got unexpected ret %d.\n", ret);
10339 ok(WSAGetLastError() == WSAEFAULT, "Got unexpected error %d.\n", WSAGetLastError());
10340 ok(size == expect_size, "Expected size %u, got %u.\n", expect_size, size);
10341 ok(overlapped.Internal == 0xdeadbeef, "Got status %#x.\n", (NTSTATUS)overlapped.Internal);
10342 ok(overlapped.InternalHigh == 0xdeadbeef, "Got size %Iu.\n", overlapped.InternalHigh);
10343 ok(address_list->iAddressCount == 0xcccccccc, "Got %u addresses.\n", address_list->iAddressCount);
10345 overlapped.Internal = 0xdeadbeef;
10346 overlapped.InternalHigh = 0xdeadbeef;
10347 size = 0xdeadbeef;
10348 ret = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, buffer, sizeof(buffer), &size, &overlapped, NULL);
10349 ok(!ret, "Got unexpected ret %d.\n", ret);
10350 ok(!WSAGetLastError(), "Got unexpected error %d.\n", WSAGetLastError());
10351 ok(size == expect_size, "Expected size %u, got %u.\n", expect_size, size);
10353 ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 0);
10354 ok(ret, "Got error %u.\n", GetLastError());
10355 ok(!size, "Got size %u.\n", size);
10356 ok(overlapped_ptr == &overlapped, "Got overlapped %p.\n", overlapped_ptr);
10357 ok(!overlapped.Internal, "Got status %#x.\n", (NTSTATUS)overlapped.Internal);
10358 ok(!overlapped.InternalHigh, "Got size %Iu.\n", overlapped.InternalHigh);
10360 ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 0);
10361 ok(!ret, "Expected failure.\n");
10362 ok(GetLastError() == WAIT_TIMEOUT, "Got error %u.\n", GetLastError());
10364 closesocket(s);
10365 CloseHandle(port);
10367 /* Test with an APC. */
10369 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
10371 ret = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, buffer, sizeof(buffer), NULL, &overlapped, socket_apc);
10372 ok(ret == -1, "expected failure\n");
10373 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
10375 apc_count = 0;
10376 size = 0xdeadbeef;
10377 ret = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, buffer, sizeof(buffer), &size, &overlapped, socket_apc);
10378 ok(!ret, "expected success\n");
10379 ok(size == expect_size, "got size %u\n", size);
10381 ret = SleepEx(0, TRUE);
10382 ok(ret == WAIT_IO_COMPLETION, "got %d\n", ret);
10383 ok(apc_count == 1, "APC was called %u times\n", apc_count);
10384 ok(!apc_error, "got APC error %u\n", apc_error);
10385 ok(!apc_size, "got APC size %u\n", apc_size);
10386 ok(apc_overlapped == &overlapped, "got APC overlapped %p\n", apc_overlapped);
10388 closesocket(s);
10391 static void sync_read(SOCKET src, SOCKET dst)
10393 int ret;
10394 char data[512];
10396 ret = send(dst, "Hello World!", 12, 0);
10397 ok(ret == 12, "send returned %d\n", ret);
10399 memset(data, 0, sizeof(data));
10400 ret = recv(src, data, sizeof(data), 0);
10401 ok(ret == 12, "expected 12, got %d\n", ret);
10402 ok(!memcmp(data, "Hello World!", 12), "got %u bytes (%*s)\n", ret, ret, data);
10405 static void iocp_async_read(SOCKET src, SOCKET dst)
10407 HANDLE port;
10408 WSAOVERLAPPED ovl, *ovl_iocp;
10409 WSABUF buf;
10410 int ret;
10411 char data[512];
10412 DWORD flags, bytes;
10413 ULONG_PTR key;
10415 memset(data, 0, sizeof(data));
10416 memset(&ovl, 0, sizeof(ovl));
10418 port = CreateIoCompletionPort((HANDLE)src, 0, 0x12345678, 0);
10419 ok(port != 0, "CreateIoCompletionPort error %u\n", GetLastError());
10421 buf.len = sizeof(data);
10422 buf.buf = data;
10423 bytes = 0xdeadbeef;
10424 flags = 0;
10425 SetLastError(0xdeadbeef);
10426 ret = WSARecv(src, &buf, 1, &bytes, &flags, &ovl, NULL);
10427 ok(ret == SOCKET_ERROR, "got %d\n", ret);
10428 ok(GetLastError() == ERROR_IO_PENDING, "got %u\n", GetLastError());
10429 ok(bytes == 0xdeadbeef, "got bytes %u\n", bytes);
10431 bytes = 0xdeadbeef;
10432 key = 0xdeadbeef;
10433 ovl_iocp = (void *)0xdeadbeef;
10434 SetLastError(0xdeadbeef);
10435 ret = GetQueuedCompletionStatus(port, &bytes, &key, &ovl_iocp, 100);
10436 ok(!ret, "got %d\n", ret);
10437 ok(GetLastError() == WAIT_TIMEOUT, "got %u\n", GetLastError());
10438 ok(bytes == 0xdeadbeef, "got bytes %u\n", bytes);
10439 ok(key == 0xdeadbeef, "got key %#lx\n", key);
10440 ok(!ovl_iocp, "got ovl %p\n", ovl_iocp);
10442 ret = send(dst, "Hello World!", 12, 0);
10443 ok(ret == 12, "send returned %d\n", ret);
10445 bytes = 0xdeadbeef;
10446 key = 0xdeadbeef;
10447 ovl_iocp = NULL;
10448 SetLastError(0xdeadbeef);
10449 ret = GetQueuedCompletionStatus(port, &bytes, &key, &ovl_iocp, 100);
10450 ok(ret, "got %d\n", ret);
10451 ok(bytes == 12, "got bytes %u\n", bytes);
10452 ok(key == 0x12345678, "got key %#lx\n", key);
10453 ok(ovl_iocp == &ovl, "got ovl %p\n", ovl_iocp);
10454 if (ovl_iocp)
10456 ok(ovl_iocp->InternalHigh == 12, "got %#lx\n", ovl_iocp->InternalHigh);
10457 ok(!ovl_iocp->Internal , "got %#lx\n", ovl_iocp->Internal);
10458 ok(!memcmp(data, "Hello World!", 12), "got %u bytes (%*s)\n", bytes, bytes, data);
10461 bytes = 0xdeadbeef;
10462 key = 0xdeadbeef;
10463 ovl_iocp = (void *)0xdeadbeef;
10464 SetLastError(0xdeadbeef);
10465 ret = GetQueuedCompletionStatus(port, &bytes, &key, &ovl_iocp, 100);
10466 ok(!ret, "got %d\n", ret);
10467 ok(GetLastError() == WAIT_TIMEOUT, "got %u\n", GetLastError());
10468 ok(bytes == 0xdeadbeef, "got bytes %u\n", bytes);
10469 ok(key == 0xdeadbeef, "got key %#lx\n", key);
10470 ok(!ovl_iocp, "got ovl %p\n", ovl_iocp);
10472 CloseHandle(port);
10475 static void iocp_async_read_closesocket(SOCKET src, int how_to_close)
10477 HANDLE port;
10478 WSAOVERLAPPED ovl, *ovl_iocp;
10479 WSABUF buf;
10480 int ret;
10481 char data[512];
10482 DWORD flags, bytes;
10483 ULONG_PTR key;
10484 HWND hwnd;
10485 MSG msg;
10487 hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP,
10488 0, 0, 0, 0, NULL, NULL, 0, NULL);
10489 ok(hwnd != 0, "CreateWindowEx failed\n");
10491 ret = WSAAsyncSelect(src, hwnd, WM_SOCKET, FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE);
10492 ok(!ret, "got %d\n", ret);
10494 Sleep(100);
10495 memset(&msg, 0, sizeof(msg));
10496 ret = PeekMessageA(&msg, hwnd, WM_SOCKET, WM_SOCKET, PM_REMOVE);
10497 ok(ret, "got %d\n", ret);
10498 ok(msg.hwnd == hwnd, "got %p\n", msg.hwnd);
10499 ok(msg.message == WM_SOCKET, "got %04x\n", msg.message);
10500 ok(msg.wParam == src, "got %08lx\n", msg.wParam);
10501 ok(msg.lParam == 2, "got %08lx\n", msg.lParam);
10503 memset(data, 0, sizeof(data));
10504 memset(&ovl, 0, sizeof(ovl));
10506 port = CreateIoCompletionPort((HANDLE)src, 0, 0x12345678, 0);
10507 ok(port != 0, "CreateIoCompletionPort error %u\n", GetLastError());
10509 Sleep(100);
10510 ret = PeekMessageA(&msg, hwnd, WM_SOCKET, WM_SOCKET, PM_REMOVE);
10511 ok(!ret, "got %04x,%08lx,%08lx\n", msg.message, msg.wParam, msg.lParam);
10513 buf.len = sizeof(data);
10514 buf.buf = data;
10515 bytes = 0xdeadbeef;
10516 flags = 0;
10517 SetLastError(0xdeadbeef);
10518 ret = WSARecv(src, &buf, 1, &bytes, &flags, &ovl, NULL);
10519 ok(ret == SOCKET_ERROR, "got %d\n", ret);
10520 ok(GetLastError() == ERROR_IO_PENDING, "got %u\n", GetLastError());
10521 ok(bytes == 0xdeadbeef, "got bytes %u\n", bytes);
10523 Sleep(100);
10524 ret = PeekMessageA(&msg, hwnd, WM_SOCKET, WM_SOCKET, PM_REMOVE);
10525 ok(!ret, "got %04x,%08lx,%08lx\n", msg.message, msg.wParam, msg.lParam);
10527 bytes = 0xdeadbeef;
10528 key = 0xdeadbeef;
10529 ovl_iocp = (void *)0xdeadbeef;
10530 SetLastError(0xdeadbeef);
10531 ret = GetQueuedCompletionStatus(port, &bytes, &key, &ovl_iocp, 100);
10532 ok(!ret, "got %d\n", ret);
10533 ok(GetLastError() == WAIT_TIMEOUT, "got %u\n", GetLastError());
10534 ok(bytes == 0xdeadbeef, "got bytes %u\n", bytes);
10535 ok(key == 0xdeadbeef, "got key %#lx\n", key);
10536 ok(!ovl_iocp, "got ovl %p\n", ovl_iocp);
10538 Sleep(100);
10539 ret = PeekMessageA(&msg, hwnd, WM_SOCKET, WM_SOCKET, PM_REMOVE);
10540 ok(!ret, "got %04x,%08lx,%08lx\n", msg.message, msg.wParam, msg.lParam);
10542 switch (how_to_close)
10544 case 0:
10545 closesocket(src);
10546 break;
10547 case 1:
10548 CloseHandle((HANDLE)src);
10549 break;
10550 case 2:
10551 pNtClose((HANDLE)src);
10552 break;
10553 default:
10554 ok(0, "wrong value %d\n", how_to_close);
10555 break;
10558 Sleep(200);
10559 memset(&msg, 0, sizeof(msg));
10560 ret = PeekMessageA(&msg, hwnd, WM_SOCKET, WM_SOCKET, PM_REMOVE);
10561 switch (how_to_close)
10563 case 0:
10564 ok(!ret, "got %04x,%08lx,%08lx\n", msg.message, msg.wParam, msg.lParam);
10565 break;
10566 case 1:
10567 case 2:
10568 todo_wine
10570 ok(ret, "got %d\n", ret);
10571 ok(msg.hwnd == hwnd, "got %p\n", msg.hwnd);
10572 ok(msg.message == WM_SOCKET, "got %04x\n", msg.message);
10573 ok(msg.wParam == src, "got %08lx\n", msg.wParam);
10574 ok(msg.lParam == 0x20, "got %08lx\n", msg.lParam);
10576 break;
10577 default:
10578 ok(0, "wrong value %d\n", how_to_close);
10579 break;
10582 bytes = 0xdeadbeef;
10583 key = 0xdeadbeef;
10584 ovl_iocp = NULL;
10585 SetLastError(0xdeadbeef);
10586 ret = GetQueuedCompletionStatus(port, &bytes, &key, &ovl_iocp, 100);
10587 ok(!ret, "got %d\n", ret);
10588 todo_wine
10589 ok(GetLastError() == ERROR_CONNECTION_ABORTED || GetLastError() == ERROR_NETNAME_DELETED /* XP */, "got %u\n", GetLastError());
10590 ok(!bytes, "got bytes %u\n", bytes);
10591 ok(key == 0x12345678, "got key %#lx\n", key);
10592 ok(ovl_iocp == &ovl, "got ovl %p\n", ovl_iocp);
10593 if (ovl_iocp)
10595 ok(!ovl_iocp->InternalHigh, "got %#lx\n", ovl_iocp->InternalHigh);
10596 todo_wine
10597 ok(ovl_iocp->Internal == (ULONG)STATUS_CONNECTION_ABORTED || ovl_iocp->Internal == (ULONG)STATUS_LOCAL_DISCONNECT /* XP */, "got %#lx\n", ovl_iocp->Internal);
10600 bytes = 0xdeadbeef;
10601 key = 0xdeadbeef;
10602 ovl_iocp = (void *)0xdeadbeef;
10603 SetLastError(0xdeadbeef);
10604 ret = GetQueuedCompletionStatus(port, &bytes, &key, &ovl_iocp, 100);
10605 ok(!ret, "got %d\n", ret);
10606 ok(GetLastError() == WAIT_TIMEOUT, "got %u\n", GetLastError());
10607 ok(bytes == 0xdeadbeef, "got bytes %u\n", bytes);
10608 ok(key == 0xdeadbeef, "got key %#lx\n", key);
10609 ok(!ovl_iocp, "got ovl %p\n", ovl_iocp);
10611 CloseHandle(port);
10613 DestroyWindow(hwnd);
10616 static void iocp_async_closesocket(SOCKET src)
10618 HANDLE port;
10619 WSAOVERLAPPED *ovl_iocp;
10620 int ret;
10621 DWORD bytes;
10622 ULONG_PTR key;
10623 HWND hwnd;
10624 MSG msg;
10626 hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP,
10627 0, 0, 0, 0, NULL, NULL, 0, NULL);
10628 ok(hwnd != 0, "CreateWindowEx failed\n");
10630 ret = WSAAsyncSelect(src, hwnd, WM_SOCKET, FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE);
10631 ok(!ret, "got %d\n", ret);
10633 Sleep(100);
10634 memset(&msg, 0, sizeof(msg));
10635 ret = PeekMessageA(&msg, hwnd, WM_SOCKET, WM_SOCKET, PM_REMOVE);
10636 ok(ret, "got %d\n", ret);
10637 ok(msg.hwnd == hwnd, "got %p\n", msg.hwnd);
10638 ok(msg.message == WM_SOCKET, "got %04x\n", msg.message);
10639 ok(msg.wParam == src, "got %08lx\n", msg.wParam);
10640 ok(msg.lParam == 2, "got %08lx\n", msg.lParam);
10642 port = CreateIoCompletionPort((HANDLE)src, 0, 0x12345678, 0);
10643 ok(port != 0, "CreateIoCompletionPort error %u\n", GetLastError());
10645 Sleep(100);
10646 ret = PeekMessageA(&msg, hwnd, WM_SOCKET, WM_SOCKET, PM_REMOVE);
10647 ok(!ret, "got %04x,%08lx,%08lx\n", msg.message, msg.wParam, msg.lParam);
10649 bytes = 0xdeadbeef;
10650 key = 0xdeadbeef;
10651 ovl_iocp = (void *)0xdeadbeef;
10652 SetLastError(0xdeadbeef);
10653 ret = GetQueuedCompletionStatus(port, &bytes, &key, &ovl_iocp, 100);
10654 ok(!ret, "got %d\n", ret);
10655 ok(GetLastError() == WAIT_TIMEOUT, "got %u\n", GetLastError());
10656 ok(bytes == 0xdeadbeef, "got bytes %u\n", bytes);
10657 ok(key == 0xdeadbeef, "got key %lu\n", key);
10658 ok(!ovl_iocp, "got ovl %p\n", ovl_iocp);
10660 Sleep(100);
10661 ret = PeekMessageA(&msg, hwnd, WM_SOCKET, WM_SOCKET, PM_REMOVE);
10662 ok(!ret, "got %04x,%08lx,%08lx\n", msg.message, msg.wParam, msg.lParam);
10664 closesocket(src);
10666 Sleep(100);
10667 memset(&msg, 0, sizeof(msg));
10668 ret = PeekMessageA(&msg, hwnd, WM_SOCKET, WM_SOCKET, PM_REMOVE);
10669 ok(!ret, "got %04x,%08lx,%08lx\n", msg.message, msg.wParam, msg.lParam);
10671 bytes = 0xdeadbeef;
10672 key = 0xdeadbeef;
10673 ovl_iocp = (void *)0xdeadbeef;
10674 SetLastError(0xdeadbeef);
10675 ret = GetQueuedCompletionStatus(port, &bytes, &key, &ovl_iocp, 100);
10676 ok(!ret, "got %d\n", ret);
10677 ok(GetLastError() == WAIT_TIMEOUT, "got %u\n", GetLastError());
10678 ok(bytes == 0xdeadbeef, "got bytes %u\n", bytes);
10679 ok(key == 0xdeadbeef, "got key %lu\n", key);
10680 ok(!ovl_iocp, "got ovl %p\n", ovl_iocp);
10682 CloseHandle(port);
10684 DestroyWindow(hwnd);
10687 struct wsa_async_select_info
10689 SOCKET sock;
10690 HWND hwnd;
10693 static DWORD WINAPI wsa_async_select_thread(void *param)
10695 struct wsa_async_select_info *info = param;
10696 int ret;
10698 ret = WSAAsyncSelect(info->sock, info->hwnd, WM_SOCKET, FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE);
10699 ok(!ret, "got %d\n", ret);
10701 return 0;
10704 struct wsa_recv_info
10706 SOCKET sock;
10707 WSABUF wsa_buf;
10708 WSAOVERLAPPED ovl;
10711 static DWORD WINAPI wsa_recv_thread(void *param)
10713 struct wsa_recv_info *info = param;
10714 int ret;
10715 DWORD flags, bytes;
10717 bytes = 0xdeadbeef;
10718 flags = 0;
10719 SetLastError(0xdeadbeef);
10720 ret = WSARecv(info->sock, &info->wsa_buf, 1, &bytes, &flags, &info->ovl, NULL);
10721 ok(ret == SOCKET_ERROR, "got %d\n", ret);
10722 ok(GetLastError() == ERROR_IO_PENDING, "got %u\n", GetLastError());
10723 ok(bytes == 0xdeadbeef, "got bytes %u\n", bytes);
10725 return 0;
10728 static void iocp_async_read_thread_closesocket(SOCKET src)
10730 struct wsa_async_select_info select_info;
10731 struct wsa_recv_info recv_info;
10732 HANDLE port, thread;
10733 WSAOVERLAPPED *ovl_iocp;
10734 int ret;
10735 char data[512];
10736 DWORD bytes, tid;
10737 ULONG_PTR key;
10738 HWND hwnd;
10739 MSG msg;
10741 hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP,
10742 0, 0, 0, 0, NULL, NULL, 0, NULL);
10743 ok(hwnd != 0, "CreateWindowEx failed\n");
10745 select_info.sock = src;
10746 select_info.hwnd = hwnd;
10747 thread = CreateThread(NULL, 0, wsa_async_select_thread, &select_info, 0, &tid);
10748 ok(thread != 0, "CreateThread error %u\n", GetLastError());
10749 ret = WaitForSingleObject(thread, 10000);
10750 ok(ret == WAIT_OBJECT_0, "thread failed to terminate\n");
10752 Sleep(100);
10753 memset(&msg, 0, sizeof(msg));
10754 ret = PeekMessageA(&msg, hwnd, WM_SOCKET, WM_SOCKET, PM_REMOVE);
10755 ok(ret, "got %d\n", ret);
10756 ok(msg.hwnd == hwnd, "got %p\n", msg.hwnd);
10757 ok(msg.message == WM_SOCKET, "got %04x\n", msg.message);
10758 ok(msg.wParam == src, "got %08lx\n", msg.wParam);
10759 ok(msg.lParam == 2, "got %08lx\n", msg.lParam);
10761 port = CreateIoCompletionPort((HANDLE)src, 0, 0x12345678, 0);
10762 ok(port != 0, "CreateIoCompletionPort error %u\n", GetLastError());
10764 Sleep(100);
10765 ret = PeekMessageA(&msg, hwnd, WM_SOCKET, WM_SOCKET, PM_REMOVE);
10766 ok(!ret, "got %04x,%08lx,%08lx\n", msg.message, msg.wParam, msg.lParam);
10768 memset(data, 0, sizeof(data));
10769 memset(&recv_info.ovl, 0, sizeof(recv_info.ovl));
10770 recv_info.sock = src;
10771 recv_info.wsa_buf.len = sizeof(data);
10772 recv_info.wsa_buf.buf = data;
10773 thread = CreateThread(NULL, 0, wsa_recv_thread, &recv_info, 0, &tid);
10774 ok(thread != 0, "CreateThread error %u\n", GetLastError());
10775 ret = WaitForSingleObject(thread, 10000);
10776 ok(ret == WAIT_OBJECT_0, "thread failed to terminate\n");
10778 Sleep(100);
10779 ret = PeekMessageA(&msg, hwnd, WM_SOCKET, WM_SOCKET, PM_REMOVE);
10780 ok(!ret, "got %04x,%08lx,%08lx\n", msg.message, msg.wParam, msg.lParam);
10782 bytes = 0xdeadbeef;
10783 key = 0xdeadbeef;
10784 ovl_iocp = (void *)0xdeadbeef;
10785 SetLastError(0xdeadbeef);
10786 ret = GetQueuedCompletionStatus(port, &bytes, &key, &ovl_iocp, 100);
10787 ok(!ret, "got %d\n", ret);
10788 ok(GetLastError() == WAIT_TIMEOUT || broken(GetLastError() == ERROR_OPERATION_ABORTED) /* XP */,
10789 "got %u\n", GetLastError());
10790 if (GetLastError() == WAIT_TIMEOUT)
10792 ok(bytes == 0xdeadbeef, "got bytes %u\n", bytes);
10793 ok(key == 0xdeadbeef, "got key %lx\n", key);
10794 ok(!ovl_iocp, "got ovl %p\n", ovl_iocp);
10796 else /* document XP behaviour */
10798 ok(!bytes, "got bytes %u\n", bytes);
10799 ok(key == 0x12345678, "got key %#lx\n", key);
10800 ok(ovl_iocp == &recv_info.ovl, "got ovl %p\n", ovl_iocp);
10801 if (ovl_iocp)
10803 ok(!ovl_iocp->InternalHigh, "got %#lx\n", ovl_iocp->InternalHigh);
10804 ok(ovl_iocp->Internal == STATUS_CANCELLED, "got %#lx\n", ovl_iocp->Internal);
10807 closesocket(src);
10808 goto xp_is_broken;
10811 Sleep(100);
10812 ret = PeekMessageA(&msg, hwnd, WM_SOCKET, WM_SOCKET, PM_REMOVE);
10813 ok(!ret, "got %04x,%08lx,%08lx\n", msg.message, msg.wParam, msg.lParam);
10815 closesocket(src);
10817 Sleep(100);
10818 ret = PeekMessageA(&msg, hwnd, WM_SOCKET, WM_SOCKET, PM_REMOVE);
10819 ok(!ret, "got %04x,%08lx,%08lx\n", msg.message, msg.wParam, msg.lParam);
10821 bytes = 0xdeadbeef;
10822 key = 0xdeadbeef;
10823 ovl_iocp = NULL;
10824 SetLastError(0xdeadbeef);
10825 ret = GetQueuedCompletionStatus(port, &bytes, &key, &ovl_iocp, 100);
10826 ok(!ret, "got %d\n", ret);
10827 todo_wine
10828 ok(GetLastError() == ERROR_CONNECTION_ABORTED || GetLastError() == ERROR_NETNAME_DELETED /* XP */, "got %u\n", GetLastError());
10829 ok(!bytes, "got bytes %u\n", bytes);
10830 ok(key == 0x12345678, "got key %#lx\n", key);
10831 ok(ovl_iocp == &recv_info.ovl, "got ovl %p\n", ovl_iocp);
10832 if (ovl_iocp)
10834 ok(!ovl_iocp->InternalHigh, "got %#lx\n", ovl_iocp->InternalHigh);
10835 todo_wine
10836 ok(ovl_iocp->Internal == (ULONG)STATUS_CONNECTION_ABORTED || ovl_iocp->Internal == (ULONG)STATUS_LOCAL_DISCONNECT /* XP */, "got %#lx\n", ovl_iocp->Internal);
10839 xp_is_broken:
10840 bytes = 0xdeadbeef;
10841 key = 0xdeadbeef;
10842 ovl_iocp = (void *)0xdeadbeef;
10843 SetLastError(0xdeadbeef);
10844 ret = GetQueuedCompletionStatus(port, &bytes, &key, &ovl_iocp, 100);
10845 ok(!ret, "got %d\n", ret);
10846 ok(GetLastError() == WAIT_TIMEOUT, "got %u\n", GetLastError());
10847 ok(bytes == 0xdeadbeef, "got bytes %u\n", bytes);
10848 ok(key == 0xdeadbeef, "got key %lu\n", key);
10849 ok(!ovl_iocp, "got ovl %p\n", ovl_iocp);
10851 CloseHandle(port);
10853 DestroyWindow(hwnd);
10856 static void iocp_async_read_thread(SOCKET src, SOCKET dst)
10858 struct wsa_async_select_info select_info;
10859 struct wsa_recv_info recv_info;
10860 HANDLE port, thread;
10861 WSAOVERLAPPED *ovl_iocp;
10862 int ret;
10863 char data[512];
10864 DWORD bytes, tid;
10865 ULONG_PTR key;
10866 HWND hwnd;
10867 MSG msg;
10869 hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP,
10870 0, 0, 0, 0, NULL, NULL, 0, NULL);
10871 ok(hwnd != 0, "CreateWindowEx failed\n");
10873 select_info.sock = src;
10874 select_info.hwnd = hwnd;
10875 thread = CreateThread(NULL, 0, wsa_async_select_thread, &select_info, 0, &tid);
10876 ok(thread != 0, "CreateThread error %u\n", GetLastError());
10877 ret = WaitForSingleObject(thread, 10000);
10878 ok(ret == WAIT_OBJECT_0, "thread failed to terminate\n");
10880 Sleep(100);
10881 memset(&msg, 0, sizeof(msg));
10882 ret = PeekMessageA(&msg, hwnd, WM_SOCKET, WM_SOCKET, PM_REMOVE);
10883 ok(ret, "got %d\n", ret);
10884 ok(msg.hwnd == hwnd, "got %p\n", msg.hwnd);
10885 ok(msg.message == WM_SOCKET, "got %04x\n", msg.message);
10886 ok(msg.wParam == src, "got %08lx\n", msg.wParam);
10887 ok(msg.lParam == 2, "got %08lx\n", msg.lParam);
10889 port = CreateIoCompletionPort((HANDLE)src, 0, 0x12345678, 0);
10890 ok(port != 0, "CreateIoCompletionPort error %u\n", GetLastError());
10892 Sleep(100);
10893 ret = PeekMessageA(&msg, hwnd, WM_SOCKET, WM_SOCKET, PM_REMOVE);
10894 ok(!ret, "got %04x,%08lx,%08lx\n", msg.message, msg.wParam, msg.lParam);
10896 memset(data, 0, sizeof(data));
10897 memset(&recv_info.ovl, 0, sizeof(recv_info.ovl));
10898 recv_info.sock = src;
10899 recv_info.wsa_buf.len = sizeof(data);
10900 recv_info.wsa_buf.buf = data;
10901 thread = CreateThread(NULL, 0, wsa_recv_thread, &recv_info, 0, &tid);
10902 ok(thread != 0, "CreateThread error %u\n", GetLastError());
10903 ret = WaitForSingleObject(thread, 10000);
10904 ok(ret == WAIT_OBJECT_0, "thread failed to terminate\n");
10906 Sleep(100);
10907 ret = PeekMessageA(&msg, hwnd, WM_SOCKET, WM_SOCKET, PM_REMOVE);
10908 ok(!ret, "got %04x,%08lx,%08lx\n", msg.message, msg.wParam, msg.lParam);
10910 bytes = 0xdeadbeef;
10911 key = 0xdeadbeef;
10912 ovl_iocp = (void *)0xdeadbeef;
10913 SetLastError(0xdeadbeef);
10914 ret = GetQueuedCompletionStatus(port, &bytes, &key, &ovl_iocp, 100);
10915 ok(!ret, "got %d\n", ret);
10916 ok(GetLastError() == WAIT_TIMEOUT || broken(GetLastError() == ERROR_OPERATION_ABORTED) /* XP */, "got %u\n", GetLastError());
10917 if (GetLastError() == WAIT_TIMEOUT)
10919 ok(bytes == 0xdeadbeef, "got bytes %u\n", bytes);
10920 ok(key == 0xdeadbeef, "got key %lu\n", key);
10921 ok(!ovl_iocp, "got ovl %p\n", ovl_iocp);
10923 else /* document XP behaviour */
10925 ok(bytes == 0, "got bytes %u\n", bytes);
10926 ok(key == 0x12345678, "got key %#lx\n", key);
10927 ok(ovl_iocp == &recv_info.ovl, "got ovl %p\n", ovl_iocp);
10928 if (ovl_iocp)
10930 ok(!ovl_iocp->InternalHigh, "got %#lx\n", ovl_iocp->InternalHigh);
10931 ok(ovl_iocp->Internal == STATUS_CANCELLED, "got %#lx\n", ovl_iocp->Internal);
10935 Sleep(100);
10936 memset(&msg, 0, sizeof(msg));
10937 ret = PeekMessageA(&msg, hwnd, WM_SOCKET, WM_SOCKET, PM_REMOVE);
10938 ok(!ret || broken(msg.hwnd == hwnd) /* XP */, "got %04x,%08lx,%08lx\n", msg.message, msg.wParam, msg.lParam);
10939 if (ret) /* document XP behaviour */
10941 ok(msg.message == WM_SOCKET, "got %04x\n", msg.message);
10942 ok(msg.wParam == src, "got %08lx\n", msg.wParam);
10943 ok(msg.lParam == 1, "got %08lx\n", msg.lParam);
10946 ret = send(dst, "Hello World!", 12, 0);
10947 ok(ret == 12, "send returned %d\n", ret);
10949 Sleep(100);
10950 memset(&msg, 0, sizeof(msg));
10951 ret = PeekMessageA(&msg, hwnd, WM_SOCKET, WM_SOCKET, PM_REMOVE);
10952 ok(!ret || broken(msg.hwnd == hwnd) /* XP */, "got %04x,%08lx,%08lx\n", msg.message, msg.wParam, msg.lParam);
10953 if (ret) /* document XP behaviour */
10955 ok(msg.hwnd == hwnd, "got %p\n", msg.hwnd);
10956 ok(msg.message == WM_SOCKET, "got %04x\n", msg.message);
10957 ok(msg.wParam == src, "got %08lx\n", msg.wParam);
10958 ok(msg.lParam == 1, "got %08lx\n", msg.lParam);
10961 bytes = 0xdeadbeef;
10962 key = 0xdeadbeef;
10963 ovl_iocp = (void *)0xdeadbeef;
10964 SetLastError(0xdeadbeef);
10965 ret = GetQueuedCompletionStatus(port, &bytes, &key, &ovl_iocp, 100);
10966 ok(ret || broken(GetLastError() == WAIT_TIMEOUT) /* XP */, "got %u\n", GetLastError());
10967 if (ret)
10969 ok(bytes == 12, "got bytes %u\n", bytes);
10970 ok(key == 0x12345678, "got key %#lx\n", key);
10971 ok(ovl_iocp == &recv_info.ovl, "got ovl %p\n", ovl_iocp);
10972 if (ovl_iocp)
10974 ok(ovl_iocp->InternalHigh == 12, "got %#lx\n", ovl_iocp->InternalHigh);
10975 ok(!ovl_iocp->Internal , "got %#lx\n", ovl_iocp->Internal);
10976 ok(!memcmp(data, "Hello World!", 12), "got %u bytes (%*s)\n", bytes, bytes, data);
10979 else /* document XP behaviour */
10981 ok(bytes == 0xdeadbeef, "got bytes %u\n", bytes);
10982 ok(key == 0xdeadbeef, "got key %lu\n", key);
10983 ok(!ovl_iocp, "got ovl %p\n", ovl_iocp);
10986 CloseHandle(port);
10988 DestroyWindow(hwnd);
10991 static void test_iocp(void)
10993 SOCKET src, dst;
10994 int i;
10996 tcp_socketpair(&src, &dst);
10997 sync_read(src, dst);
10998 iocp_async_read(src, dst);
10999 closesocket(src);
11000 closesocket(dst);
11002 tcp_socketpair(&src, &dst);
11003 iocp_async_read_thread(src, dst);
11004 closesocket(src);
11005 closesocket(dst);
11007 for (i = 0; i <= 2; i++)
11009 tcp_socketpair(&src, &dst);
11010 iocp_async_read_closesocket(src, i);
11011 closesocket(dst);
11014 tcp_socketpair(&src, &dst);
11015 iocp_async_closesocket(src);
11016 closesocket(dst);
11018 tcp_socketpair(&src, &dst);
11019 iocp_async_read_thread_closesocket(src);
11020 closesocket(dst);
11023 static void test_get_interface_list(void)
11025 OVERLAPPED overlapped = {0}, *overlapped_ptr;
11026 DWORD size, expect_size;
11027 unsigned int i, count;
11028 INTERFACE_INFO *info;
11029 BOOL loopback_found;
11030 char buffer[4096];
11031 ULONG_PTR key;
11032 HANDLE port;
11033 SOCKET s;
11034 int ret;
11036 s = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
11037 ok(s != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
11038 port = CreateIoCompletionPort((HANDLE)s, NULL, 123, 0);
11040 size = 0xdeadbeef;
11041 WSASetLastError(0xdeadbeef);
11042 ret = WSAIoctl(s, SIO_GET_INTERFACE_LIST, NULL, 0, buffer, sizeof(buffer), &size, NULL, NULL);
11043 ok(!ret, "Got unexpected ret %d.\n", ret);
11044 ok(!WSAGetLastError(), "Got error %u.\n", WSAGetLastError());
11045 ok(size && size != 0xdeadbeef && !(size % sizeof(INTERFACE_INFO)), "Got unexpected size %u.\n", size);
11046 expect_size = size;
11048 size = 0xdeadbeef;
11049 overlapped.Internal = 0xdeadbeef;
11050 overlapped.InternalHigh = 0xdeadbeef;
11051 ret = WSAIoctl(s, SIO_GET_INTERFACE_LIST, NULL, 0, buffer, sizeof(buffer), &size, &overlapped, NULL);
11052 ok(ret == -1, "Got unexpected ret %d.\n", ret);
11053 ok(WSAGetLastError() == ERROR_IO_PENDING, "Got error %u.\n", WSAGetLastError());
11054 ok(size == 0xdeadbeef, "Got size %u.\n", size);
11056 ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 100);
11057 ok(ret, "Got error %u.\n", GetLastError());
11058 ok(size == expect_size, "Expected size %u, got %u.\n", expect_size, size);
11059 ok(key == 123, "Got key %Iu.\n", key);
11060 ok(overlapped_ptr == &overlapped, "Got overlapped %p.\n", overlapped_ptr);
11061 ok(!overlapped.Internal, "Got status %#x.\n", (NTSTATUS)overlapped.Internal);
11062 ok(overlapped.InternalHigh == expect_size, "Expected size %u, got %Iu.\n", expect_size, overlapped.InternalHigh);
11064 info = (INTERFACE_INFO *)buffer;
11065 count = size / sizeof(INTERFACE_INFO);
11066 loopback_found = FALSE;
11067 for (i = 0; i < count; ++i)
11069 if (info[i].iiFlags & IFF_LOOPBACK)
11070 loopback_found = TRUE;
11072 ok(info[i].iiAddress.AddressIn.sin_family == AF_INET, "Got unexpected sin_family %#x.\n",
11073 info[i].iiAddress.AddressIn.sin_family);
11074 ok(info[i].iiNetmask.AddressIn.sin_family == AF_INET, "Got unexpected sin_family %#x.\n",
11075 info[i].iiNetmask.AddressIn.sin_family);
11076 ok(info[i].iiBroadcastAddress.AddressIn.sin_family
11077 == (info[i].iiFlags & IFF_BROADCAST) ? AF_INET : 0, "Got unexpected sin_family %#x.\n",
11078 info[i].iiBroadcastAddress.AddressIn.sin_family);
11079 ok(info[i].iiAddress.AddressIn.sin_addr.S_un.S_addr, "Got zero iiAddress.\n");
11080 ok(info[i].iiNetmask.AddressIn.sin_addr.S_un.S_addr, "Got zero iiNetmask.\n");
11081 ok((info[i].iiFlags & IFF_BROADCAST) ? info[i].iiBroadcastAddress.AddressIn.sin_addr.S_un.S_addr
11082 : !info[i].iiBroadcastAddress.AddressIn.sin_addr.S_un.S_addr,
11083 "Got unexpected iiBroadcastAddress %s.\n", inet_ntoa(info[i].iiBroadcastAddress.AddressIn.sin_addr));
11086 ok(loopback_found, "Loopback interface not found.\n");
11088 size = 0xdeadbeef;
11089 ret = WSAIoctl(s, SIO_GET_INTERFACE_LIST, NULL, 0, buffer, sizeof(INTERFACE_INFO) - 1, &size, NULL, NULL);
11090 ok(ret == -1, "Got unexpected ret %d.\n", ret);
11091 ok(WSAGetLastError() == WSAEFAULT, "Got unexpected error %d.\n", WSAGetLastError());
11092 ok(!size, "Got unexpected size %u.\n", size);
11094 size = 0xdeadbeef;
11095 overlapped.Internal = 0xdeadbeef;
11096 overlapped.InternalHigh = 0xdeadbeef;
11097 ret = WSAIoctl(s, SIO_GET_INTERFACE_LIST, NULL, 0, buffer, sizeof(INTERFACE_INFO) - 1, &size, &overlapped, NULL);
11098 ok(ret == -1, "Got unexpected ret %d.\n", ret);
11099 ok(WSAGetLastError() == ERROR_IO_PENDING, "Got error %u.\n", WSAGetLastError());
11100 ok(size == 0xdeadbeef, "Got size %u.\n", size);
11102 ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 100);
11103 ok(!ret, "Expected failure.\n");
11104 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Got error %u.\n", GetLastError());
11105 ok(!size, "Got size %u.\n", size);
11106 ok(key == 123, "Got key %Iu.\n", key);
11107 ok(overlapped_ptr == &overlapped, "Got overlapped %p.\n", overlapped_ptr);
11108 ok((NTSTATUS)overlapped.Internal == STATUS_BUFFER_TOO_SMALL, "Got status %#x.\n", (NTSTATUS)overlapped.Internal);
11109 ok(!overlapped.InternalHigh, "Got size %Iu.\n", overlapped.InternalHigh);
11111 ret = WSAIoctl(s, SIO_GET_INTERFACE_LIST, NULL, 0, buffer, sizeof(buffer), NULL, NULL, NULL);
11112 ok(ret == -1, "Got unexpected ret %d.\n", ret);
11113 ok(WSAGetLastError() == WSAEFAULT, "Got unexpected error %d.\n", WSAGetLastError());
11115 CloseHandle(port);
11116 closesocket(s);
11118 /* Test with an APC. */
11120 s = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
11121 ok(s != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
11123 size = 0xdeadbeef;
11124 apc_count = 0;
11125 ret = WSAIoctl(s, SIO_GET_INTERFACE_LIST, NULL, 0, buffer,
11126 sizeof(INTERFACE_INFO) - 1, &size, &overlapped, socket_apc);
11127 ok(ret == -1, "Got unexpected ret %d.\n", ret);
11128 ok(WSAGetLastError() == ERROR_IO_PENDING, "Got error %u.\n", WSAGetLastError());
11129 ok(size == 0xdeadbeef, "Got size %u.\n", size);
11131 ret = SleepEx(100, TRUE);
11132 ok(ret == WAIT_IO_COMPLETION, "got %d\n", ret);
11133 ok(apc_count == 1, "APC was called %u times\n", apc_count);
11134 ok(apc_error == WSAEFAULT, "got APC error %u\n", apc_error);
11135 ok(!apc_size, "got APC size %u\n", apc_size);
11136 ok(apc_overlapped == &overlapped, "got APC overlapped %p\n", apc_overlapped);
11138 closesocket(s);
11141 static void test_bind(void)
11143 const struct sockaddr_in invalid_addr = {.sin_family = AF_INET, .sin_addr.s_addr = inet_addr("192.0.2.0")};
11144 const struct sockaddr_in bind_addr = {.sin_family = AF_INET, .sin_addr.s_addr = htonl(INADDR_LOOPBACK)};
11145 IP_ADAPTER_ADDRESSES *adapters = NULL, *adapter;
11146 ULONG ip_addrs_size = 0;
11147 struct sockaddr addr;
11148 SOCKET s, s2;
11149 int ret, len;
11151 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
11153 WSASetLastError(0xdeadbeef);
11154 ret = bind(s, NULL, 0);
11155 ok(ret == -1, "expected failure\n");
11156 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
11158 WSASetLastError(0xdeadbeef);
11159 ret = bind(s, NULL, sizeof(addr));
11160 ok(ret == -1, "expected failure\n");
11161 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
11163 addr.sa_family = AF_INET;
11164 WSASetLastError(0xdeadbeef);
11165 ret = bind(s, &addr, 0);
11166 ok(ret == -1, "expected failure\n");
11167 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
11169 addr.sa_family = 0xdead;
11170 WSASetLastError(0xdeadbeef);
11171 ret = bind(s, &addr, sizeof(addr));
11172 ok(ret == -1, "expected failure\n");
11173 ok(WSAGetLastError() == WSAEAFNOSUPPORT, "got error %u\n", WSAGetLastError());
11175 WSASetLastError(0xdeadbeef);
11176 ret = bind(s, (const struct sockaddr *)&bind_addr, sizeof(bind_addr) - 1);
11177 ok(ret == -1, "expected failure\n");
11178 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
11180 WSASetLastError(0xdeadbeef);
11181 ret = bind(s, (const struct sockaddr *)&invalid_addr, sizeof(invalid_addr));
11182 ok(ret == -1, "expected failure\n");
11183 ok(WSAGetLastError() == WSAEADDRNOTAVAIL, "got error %u\n", WSAGetLastError());
11185 WSASetLastError(0xdeadbeef);
11186 ret = bind(s, (const struct sockaddr *)&bind_addr, sizeof(bind_addr));
11187 ok(!ret, "expected success\n");
11188 ok(!WSAGetLastError() || WSAGetLastError() == 0xdeadbeef /* win <7 */, "got error %u\n", WSAGetLastError());
11190 WSASetLastError(0xdeadbeef);
11191 ret = bind(s, (const struct sockaddr *)&bind_addr, sizeof(bind_addr));
11192 ok(ret == -1, "expected failure\n");
11193 ok(WSAGetLastError() == WSAEINVAL, "got error %u\n", WSAGetLastError());
11195 len = sizeof(addr);
11196 ret = getsockname(s, &addr, &len);
11197 ok(!ret, "got error %u\n", WSAGetLastError());
11199 s2 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
11201 WSASetLastError(0xdeadbeef);
11202 ret = bind(s2, &addr, sizeof(addr));
11203 ok(ret == -1, "expected failure\n");
11204 ok(WSAGetLastError() == WSAEADDRINUSE, "got error %u\n", WSAGetLastError());
11206 closesocket(s2);
11207 closesocket(s);
11209 s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
11211 WSASetLastError(0xdeadbeef);
11212 ret = bind(s, (const struct sockaddr *)&bind_addr, sizeof(bind_addr));
11213 ok(!ret, "expected success\n");
11214 ok(!WSAGetLastError() || WSAGetLastError() == 0xdeadbeef /* win <7 */, "got error %u\n", WSAGetLastError());
11216 closesocket(s);
11218 ret = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, adapters, &ip_addrs_size);
11219 ok(ret == ERROR_BUFFER_OVERFLOW, "got error %u\n", ret);
11220 adapters = malloc(ip_addrs_size);
11221 ret = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, adapters, &ip_addrs_size);
11222 ok(!ret, "got error %u\n", ret);
11224 for (adapter = adapters; adapter != NULL; adapter = adapter->Next)
11226 const IP_ADAPTER_UNICAST_ADDRESS *unicast_addr;
11228 for (unicast_addr = adapter->FirstUnicastAddress; unicast_addr != NULL; unicast_addr = unicast_addr->Next)
11230 short family = unicast_addr->Address.lpSockaddr->sa_family;
11232 s = socket(family, SOCK_STREAM, IPPROTO_TCP);
11233 ok(s != -1, "failed to create socket, error %u\n", WSAGetLastError());
11235 ret = bind(s, unicast_addr->Address.lpSockaddr, unicast_addr->Address.iSockaddrLength);
11236 ok(!ret, "got error %u\n", WSAGetLastError());
11238 closesocket(s);
11240 if (family == AF_INET6)
11242 struct sockaddr_in6 addr6, ret_addr6;
11244 memcpy(&addr6, unicast_addr->Address.lpSockaddr, sizeof(addr6));
11246 ok(unicast_addr->Address.iSockaddrLength == sizeof(struct sockaddr_in6),
11247 "got unexpected length %u\n", unicast_addr->Address.iSockaddrLength);
11249 s = socket(family, SOCK_STREAM, IPPROTO_TCP);
11250 ok(s != -1, "failed to create socket, error %u\n", WSAGetLastError());
11252 ret = bind(s, unicast_addr->Address.lpSockaddr, sizeof(struct sockaddr_in6_old));
11253 ok(ret == -1, "expected failure\n");
11254 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
11256 addr6.sin6_scope_id = 0xabacab;
11257 ret = bind(s, (struct sockaddr *)&addr6, sizeof(addr6));
11258 todo_wine_if (!((const struct sockaddr_in6 *)unicast_addr->Address.lpSockaddr)->sin6_scope_id)
11260 ok(ret == -1, "expected failure\n");
11261 ok(WSAGetLastError() == WSAEADDRNOTAVAIL, "got error %u\n", WSAGetLastError());
11264 addr6.sin6_scope_id = 0;
11265 ret = bind(s, (struct sockaddr *)&addr6, sizeof(addr6));
11266 todo_wine_if (!((const struct sockaddr_in6 *)unicast_addr->Address.lpSockaddr)->sin6_scope_id)
11267 ok(!ret, "got error %u\n", WSAGetLastError());
11269 memcpy(&addr6, unicast_addr->Address.lpSockaddr, sizeof(addr6));
11271 len = sizeof(struct sockaddr_in6_old);
11272 ret = getsockname(s, (struct sockaddr *)&ret_addr6, &len);
11273 ok(ret == -1, "expected failure\n");
11274 ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
11276 len = sizeof(ret_addr6);
11277 memset(&ret_addr6, 0, sizeof(ret_addr6));
11278 ret = getsockname(s, (struct sockaddr *)&ret_addr6, &len);
11279 ok(!ret, "got error %u\n", WSAGetLastError());
11280 ok(ret_addr6.sin6_family == AF_INET6, "got family %u\n", ret_addr6.sin6_family);
11281 ok(ret_addr6.sin6_port != 0, "expected nonzero port\n");
11282 ok(!memcmp(&ret_addr6.sin6_addr, &addr6.sin6_addr, sizeof(addr6.sin6_addr)), "address didn't match\n");
11283 ok(ret_addr6.sin6_scope_id == addr6.sin6_scope_id, "got scope %u\n", ret_addr6.sin6_scope_id);
11285 closesocket(s);
11290 free(adapters);
11293 /* Test calling methods on a socket which is currently connecting. */
11294 static void test_connecting_socket(void)
11296 const struct sockaddr_in bind_addr = {.sin_family = AF_INET, .sin_addr.s_addr = htonl(INADDR_ANY)};
11297 const struct sockaddr_in invalid_addr =
11299 .sin_family = AF_INET,
11300 .sin_addr.s_addr = inet_addr("192.0.2.0"),
11301 .sin_port = 255
11303 OVERLAPPED overlapped = {0}, overlapped2 = {0};
11304 GUID connectex_guid = WSAID_CONNECTEX;
11305 LPFN_CONNECTEX pConnectEx;
11306 struct sockaddr_in addr;
11307 char buffer[4];
11308 SOCKET client;
11309 int ret, len;
11310 DWORD size;
11312 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
11313 ok(client != -1, "failed to create socket, error %u\n", WSAGetLastError());
11314 set_blocking(client, FALSE);
11316 ret = bind(client, (const struct sockaddr *)&bind_addr, sizeof(bind_addr));
11317 ok(!ret, "expected success\n");
11318 ok(!WSAGetLastError(), "got %u\n", WSAGetLastError());
11320 ret = connect(client, (struct sockaddr *)&invalid_addr, sizeof(invalid_addr));
11321 ok(ret == -1, "got %d\n", ret);
11322 ok(WSAGetLastError() == WSAEWOULDBLOCK, "got %u\n", WSAGetLastError());
11324 /* Mortal Kombat 11 connects to the same address twice and expects the
11325 * second to return WSAEALREADY. */
11326 ret = connect(client, (struct sockaddr *)&invalid_addr, sizeof(invalid_addr));
11327 ok(ret == -1, "got %d\n", ret);
11328 ok(WSAGetLastError() == WSAEALREADY, "got %u\n", WSAGetLastError());
11330 ret = WSAIoctl(client, SIO_GET_EXTENSION_FUNCTION_POINTER, &connectex_guid, sizeof(connectex_guid),
11331 &pConnectEx, sizeof(pConnectEx), &size, NULL, NULL);
11332 ok(!ret, "failed to get ConnectEx, error %u\n", WSAGetLastError());
11333 overlapped.Internal = 0xdeadbeef;
11334 overlapped.InternalHigh = 0xdeadbeef;
11335 ret = pConnectEx(client, (struct sockaddr *)&invalid_addr, sizeof(invalid_addr), NULL, 0, &size, &overlapped);
11336 ok(!ret, "got %d\n", ret);
11337 ok(WSAGetLastError() == WSAEINVAL, "got %u\n", WSAGetLastError());
11338 ok((NTSTATUS)overlapped.Internal == STATUS_PENDING, "got status %#x\n", (NTSTATUS)overlapped.Internal);
11339 todo_wine ok(overlapped.InternalHigh == 0xdeadbeef, "got size %Iu\n", overlapped.InternalHigh);
11341 len = sizeof(addr);
11342 ret = getsockname(client, (struct sockaddr *)&addr, &len);
11343 ok(!ret, "got error %u\n", WSAGetLastError());
11344 ok(addr.sin_family == AF_INET, "got family %u\n", addr.sin_family);
11345 ok(addr.sin_port, "expected nonzero port\n");
11347 len = sizeof(addr);
11348 ret = getpeername(client, (struct sockaddr *)&addr, &len);
11349 todo_wine ok(!ret, "got error %u\n", WSAGetLastError());
11350 if (!ret)
11352 ok(addr.sin_family == AF_INET, "got family %u\n", addr.sin_family);
11353 ok(addr.sin_addr.s_addr == inet_addr("192.0.2.0"), "got address %#08x\n", addr.sin_addr.s_addr);
11354 ok(addr.sin_port == 255, "expected nonzero port\n");
11357 ret = recv(client, buffer, sizeof(buffer), 0);
11358 ok(ret == -1, "got %d\n", ret);
11359 todo_wine ok(WSAGetLastError() == WSAENOTCONN, "got %u\n", WSAGetLastError());
11361 ret = send(client, "data", 5, 0);
11362 ok(ret == -1, "got %d\n", ret);
11363 todo_wine ok(WSAGetLastError() == WSAENOTCONN, "got %u\n", WSAGetLastError());
11365 closesocket(client);
11367 /* Test with ConnectEx(). */
11369 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
11370 ok(client != -1, "failed to create socket, error %u\n", WSAGetLastError());
11371 set_blocking(client, FALSE);
11373 ret = bind(client, (const struct sockaddr *)&bind_addr, sizeof(bind_addr));
11374 ok(!ret, "expected success\n");
11375 ok(!WSAGetLastError(), "got %u\n", WSAGetLastError());
11377 ret = pConnectEx(client, (struct sockaddr *)&invalid_addr, sizeof(invalid_addr), NULL, 0, &size, &overlapped2);
11378 ok(!ret, "got %d\n", ret);
11379 ok(WSAGetLastError() == ERROR_IO_PENDING, "got error %u\n", WSAGetLastError());
11381 ret = connect(client, (struct sockaddr *)&invalid_addr, sizeof(invalid_addr));
11382 ok(ret == -1, "got %d\n", ret);
11383 ok(WSAGetLastError() == WSAEINVAL, "got %u\n", WSAGetLastError());
11385 overlapped.Internal = 0xdeadbeef;
11386 overlapped.InternalHigh = 0xdeadbeef;
11387 ret = pConnectEx(client, (struct sockaddr *)&invalid_addr, sizeof(invalid_addr), NULL, 0, &size, &overlapped);
11388 ok(!ret, "got %d\n", ret);
11389 ok(WSAGetLastError() == WSAEINVAL, "got %u\n", WSAGetLastError());
11390 ok((NTSTATUS)overlapped.Internal == STATUS_PENDING, "got status %#x\n", (NTSTATUS)overlapped.Internal);
11391 todo_wine ok(overlapped.InternalHigh == 0xdeadbeef, "got size %Iu\n", overlapped.InternalHigh);
11393 len = sizeof(addr);
11394 ret = getsockname(client, (struct sockaddr *)&addr, &len);
11395 ok(!ret, "got error %u\n", WSAGetLastError());
11396 ok(addr.sin_family == AF_INET, "got family %u\n", addr.sin_family);
11397 ok(addr.sin_port, "expected nonzero port\n");
11399 len = sizeof(addr);
11400 ret = getpeername(client, (struct sockaddr *)&addr, &len);
11401 ok(ret == -1, "got %d\n", ret);
11402 ok(WSAGetLastError() == WSAENOTCONN, "got %u\n", WSAGetLastError());
11404 ret = recv(client, buffer, sizeof(buffer), 0);
11405 ok(ret == -1, "got %d\n", ret);
11406 todo_wine ok(WSAGetLastError() == WSAENOTCONN, "got %u\n", WSAGetLastError());
11408 ret = send(client, "data", 5, 0);
11409 ok(ret == -1, "got %d\n", ret);
11410 todo_wine ok(WSAGetLastError() == WSAENOTCONN, "got %u\n", WSAGetLastError());
11412 closesocket(client);
11415 static DWORD map_status( NTSTATUS status )
11417 static const struct
11419 NTSTATUS status;
11420 DWORD error;
11422 errors[] =
11424 {STATUS_PENDING, ERROR_IO_INCOMPLETE},
11426 {STATUS_BUFFER_OVERFLOW, WSAEMSGSIZE},
11428 {STATUS_NOT_IMPLEMENTED, WSAEOPNOTSUPP},
11429 {STATUS_ACCESS_VIOLATION, WSAEFAULT},
11430 {STATUS_PAGEFILE_QUOTA, WSAENOBUFS},
11431 {STATUS_INVALID_HANDLE, WSAENOTSOCK},
11432 {STATUS_NO_SUCH_DEVICE, WSAENETDOWN},
11433 {STATUS_NO_SUCH_FILE, WSAENETDOWN},
11434 {STATUS_NO_MEMORY, WSAENOBUFS},
11435 {STATUS_CONFLICTING_ADDRESSES, WSAENOBUFS},
11436 {STATUS_ACCESS_DENIED, WSAEACCES},
11437 {STATUS_BUFFER_TOO_SMALL, WSAEFAULT},
11438 {STATUS_OBJECT_TYPE_MISMATCH, WSAENOTSOCK},
11439 {STATUS_OBJECT_NAME_NOT_FOUND, WSAENETDOWN},
11440 {STATUS_OBJECT_PATH_NOT_FOUND, WSAENETDOWN},
11441 {STATUS_SHARING_VIOLATION, WSAEADDRINUSE},
11442 {STATUS_QUOTA_EXCEEDED, WSAENOBUFS},
11443 {STATUS_TOO_MANY_PAGING_FILES, WSAENOBUFS},
11444 {STATUS_INSUFFICIENT_RESOURCES, WSAENOBUFS},
11445 {STATUS_WORKING_SET_QUOTA, WSAENOBUFS},
11446 {STATUS_DEVICE_NOT_READY, WSAEWOULDBLOCK},
11447 {STATUS_PIPE_DISCONNECTED, WSAESHUTDOWN},
11448 {STATUS_IO_TIMEOUT, WSAETIMEDOUT},
11449 {STATUS_NOT_SUPPORTED, WSAEOPNOTSUPP},
11450 {STATUS_REMOTE_NOT_LISTENING, WSAECONNREFUSED},
11451 {STATUS_BAD_NETWORK_PATH, WSAENETUNREACH},
11452 {STATUS_NETWORK_BUSY, WSAENETDOWN},
11453 {STATUS_INVALID_NETWORK_RESPONSE, WSAENETDOWN},
11454 {STATUS_UNEXPECTED_NETWORK_ERROR, WSAENETDOWN},
11455 {STATUS_REQUEST_NOT_ACCEPTED, WSAEWOULDBLOCK},
11456 {STATUS_CANCELLED, ERROR_OPERATION_ABORTED},
11457 {STATUS_COMMITMENT_LIMIT, WSAENOBUFS},
11458 {STATUS_LOCAL_DISCONNECT, WSAECONNABORTED},
11459 {STATUS_REMOTE_DISCONNECT, WSAECONNRESET},
11460 {STATUS_REMOTE_RESOURCES, WSAENOBUFS},
11461 {STATUS_LINK_FAILED, WSAECONNRESET},
11462 {STATUS_LINK_TIMEOUT, WSAETIMEDOUT},
11463 {STATUS_INVALID_CONNECTION, WSAENOTCONN},
11464 {STATUS_INVALID_ADDRESS, WSAEADDRNOTAVAIL},
11465 {STATUS_INVALID_BUFFER_SIZE, WSAEMSGSIZE},
11466 {STATUS_INVALID_ADDRESS_COMPONENT, WSAEADDRNOTAVAIL},
11467 {STATUS_TOO_MANY_ADDRESSES, WSAENOBUFS},
11468 {STATUS_ADDRESS_ALREADY_EXISTS, WSAEADDRINUSE},
11469 {STATUS_CONNECTION_DISCONNECTED, WSAECONNRESET},
11470 {STATUS_CONNECTION_RESET, WSAECONNRESET},
11471 {STATUS_TRANSACTION_ABORTED, WSAECONNABORTED},
11472 {STATUS_CONNECTION_REFUSED, WSAECONNREFUSED},
11473 {STATUS_GRACEFUL_DISCONNECT, WSAEDISCON},
11474 {STATUS_CONNECTION_ACTIVE, WSAEISCONN},
11475 {STATUS_NETWORK_UNREACHABLE, WSAENETUNREACH},
11476 {STATUS_HOST_UNREACHABLE, WSAEHOSTUNREACH},
11477 {STATUS_PROTOCOL_UNREACHABLE, WSAENETUNREACH},
11478 {STATUS_PORT_UNREACHABLE, WSAECONNRESET},
11479 {STATUS_REQUEST_ABORTED, WSAEINTR},
11480 {STATUS_CONNECTION_ABORTED, WSAECONNABORTED},
11481 {STATUS_DATATYPE_MISALIGNMENT_ERROR,WSAEFAULT},
11482 {STATUS_HOST_DOWN, WSAEHOSTDOWN},
11483 {0x80070000 | ERROR_IO_INCOMPLETE, ERROR_IO_INCOMPLETE},
11484 {0xc0010000 | ERROR_IO_INCOMPLETE, ERROR_IO_INCOMPLETE},
11485 {0xc0070000 | ERROR_IO_INCOMPLETE, ERROR_IO_INCOMPLETE},
11488 unsigned int i;
11490 for (i = 0; i < ARRAY_SIZE(errors); ++i)
11492 if (errors[i].status == status)
11493 return errors[i].error;
11496 return NT_SUCCESS(status) ? RtlNtStatusToDosErrorNoTeb(status) : WSAEINVAL;
11499 static void test_WSAGetOverlappedResult(void)
11501 OVERLAPPED overlapped = {0};
11502 DWORD size, flags;
11503 NTSTATUS status;
11504 unsigned int i;
11505 SOCKET s;
11506 BOOL ret;
11508 static const NTSTATUS ranges[][2] =
11510 {0x0, 0x10000},
11511 {0x40000000, 0x40001000},
11512 {0x80000000, 0x80001000},
11513 {0x80070000, 0x80080000},
11514 {0xc0000000, 0xc0001000},
11515 {0xc0070000, 0xc0080000},
11516 {0xd0000000, 0xd0001000},
11517 {0xd0070000, 0xd0080000},
11520 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
11522 for (i = 0; i < ARRAY_SIZE(ranges); ++i)
11524 for (status = ranges[i][0]; status < ranges[i][1]; ++status)
11526 BOOL expect_ret = NT_SUCCESS(status) && status != STATUS_PENDING;
11527 DWORD expect = map_status(status);
11529 overlapped.Internal = status;
11530 WSASetLastError(0xdeadbeef);
11531 ret = WSAGetOverlappedResult(s, &overlapped, &size, FALSE, &flags);
11532 ok(ret == expect_ret, "status %#x: expected %d, got %d\n", status, expect_ret, ret);
11533 if (ret)
11535 ok(WSAGetLastError() == expect /* >= win10 1809 */
11536 || !WSAGetLastError() /* < win10 1809 */
11537 || WSAGetLastError() == 0xdeadbeef, /* < win7 */
11538 "status %#x: expected error %u, got %u\n", status, expect, WSAGetLastError());
11540 else
11542 ok(WSAGetLastError() == expect
11543 || (status == (0xc0070000 | ERROR_IO_INCOMPLETE) && WSAGetLastError() == WSAEINVAL), /* < win8 */
11544 "status %#x: expected error %u, got %u\n", status, expect, WSAGetLastError());
11549 closesocket(s);
11552 struct nonblocking_async_recv_params
11554 SOCKET client;
11555 HANDLE event;
11558 static DWORD CALLBACK nonblocking_async_recv_thread(void *arg)
11560 const struct nonblocking_async_recv_params *params = arg;
11561 OVERLAPPED overlapped = {0};
11562 DWORD flags = 0, size;
11563 char buffer[5];
11564 WSABUF wsabuf;
11565 int ret;
11567 overlapped.hEvent = params->event;
11568 wsabuf.buf = buffer;
11569 wsabuf.len = sizeof(buffer);
11570 memset(buffer, 0, sizeof(buffer));
11571 ret = WSARecv(params->client, &wsabuf, 1, NULL, &flags, &overlapped, NULL);
11572 ok(!ret, "got %d\n", ret);
11573 ret = GetOverlappedResult((HANDLE)params->client, &overlapped, &size, FALSE);
11574 ok(ret, "got error %u\n", GetLastError());
11575 ok(size == 4, "got size %u\n", size);
11576 ok(!strcmp(buffer, "data"), "got %s\n", debugstr_an(buffer, size));
11578 return 0;
11581 static void test_nonblocking_async_recv(void)
11583 struct nonblocking_async_recv_params params;
11584 OVERLAPPED overlapped = {0};
11585 SOCKET client, server;
11586 DWORD flags = 0, size;
11587 HANDLE thread, event;
11588 char buffer[5];
11589 WSABUF wsabuf;
11590 int ret;
11592 event = CreateEventW(NULL, TRUE, FALSE, NULL);
11593 wsabuf.buf = buffer;
11594 wsabuf.len = sizeof(buffer);
11596 tcp_socketpair(&client, &server);
11597 set_blocking(client, FALSE);
11598 set_blocking(server, FALSE);
11600 WSASetLastError(0xdeadbeef);
11601 ret = recv(client, buffer, sizeof(buffer), 0);
11602 ok(ret == -1, "got %d\n", ret);
11603 ok(WSAGetLastError() == WSAEWOULDBLOCK, "got error %u\n", WSAGetLastError());
11605 WSASetLastError(0xdeadbeef);
11606 overlapped.Internal = 0xdeadbeef;
11607 ret = WSARecv(client, &wsabuf, 1, &size, &flags, NULL, NULL);
11608 ok(ret == -1, "got %d\n", ret);
11609 ok(WSAGetLastError() == WSAEWOULDBLOCK, "got error %u\n", WSAGetLastError());
11610 ok(overlapped.Internal == 0xdeadbeef, "got status %#x\n", (NTSTATUS)overlapped.Internal);
11612 /* Overlapped, with a NULL event. */
11614 overlapped.hEvent = NULL;
11616 memset(buffer, 0, sizeof(buffer));
11617 WSASetLastError(0xdeadbeef);
11618 ret = WSARecv(client, &wsabuf, 1, NULL, &flags, &overlapped, NULL);
11619 ok(ret == -1, "got %d\n", ret);
11620 ok(WSAGetLastError() == ERROR_IO_PENDING, "got error %u\n", WSAGetLastError());
11621 ret = WaitForSingleObject((HANDLE)client, 0);
11622 ok(ret == WAIT_TIMEOUT, "expected timeout\n");
11624 ret = send(server, "data", 4, 0);
11625 ok(ret == 4, "got %d\n", ret);
11627 ret = WaitForSingleObject((HANDLE)client, 1000);
11628 ok(!ret, "wait timed out\n");
11629 ret = GetOverlappedResult((HANDLE)client, &overlapped, &size, FALSE);
11630 ok(ret, "got error %u\n", GetLastError());
11631 ok(size == 4, "got size %u\n", size);
11632 ok(!strcmp(buffer, "data"), "got %s\n", debugstr_an(buffer, size));
11634 /* Overlapped, with a non-NULL event. */
11636 overlapped.hEvent = event;
11638 memset(buffer, 0, sizeof(buffer));
11639 WSASetLastError(0xdeadbeef);
11640 ret = WSARecv(client, &wsabuf, 1, NULL, &flags, &overlapped, NULL);
11641 ok(ret == -1, "got %d\n", ret);
11642 ok(WSAGetLastError() == ERROR_IO_PENDING, "got error %u\n", WSAGetLastError());
11643 ret = WaitForSingleObject(event, 0);
11644 ok(ret == WAIT_TIMEOUT, "expected timeout\n");
11646 ret = send(server, "data", 4, 0);
11647 ok(ret == 4, "got %d\n", ret);
11649 ret = WaitForSingleObject(event, 1000);
11650 ok(!ret, "wait timed out\n");
11651 ret = GetOverlappedResult((HANDLE)client, &overlapped, &size, FALSE);
11652 ok(ret, "got error %u\n", GetLastError());
11653 ok(size == 4, "got size %u\n", size);
11654 ok(!strcmp(buffer, "data"), "got %s\n", debugstr_an(buffer, size));
11656 /* With data already in the pipe; usually this does return 0 (but not
11657 * reliably). */
11659 ret = send(server, "data", 4, 0);
11660 ok(ret == 4, "got %d\n", ret);
11662 memset(buffer, 0, sizeof(buffer));
11663 ret = WSARecv(client, &wsabuf, 1, NULL, &flags, &overlapped, NULL);
11664 ok(!ret || WSAGetLastError() == ERROR_IO_PENDING, "got error %u\n", WSAGetLastError());
11665 ret = WaitForSingleObject(event, 1000);
11666 ok(!ret, "wait timed out\n");
11667 ret = GetOverlappedResult((HANDLE)client, &overlapped, &size, FALSE);
11668 ok(ret, "got error %u\n", GetLastError());
11669 ok(size == 4, "got size %u\n", size);
11670 ok(!strcmp(buffer, "data"), "got %s\n", debugstr_an(buffer, size));
11672 closesocket(client);
11673 closesocket(server);
11675 /* With a non-overlapped socket, WSARecv() always blocks when passed an
11676 * overlapped structure, but returns WSAEWOULDBLOCK otherwise. */
11678 tcp_socketpair_flags(&client, &server, 0);
11679 set_blocking(client, FALSE);
11680 set_blocking(server, FALSE);
11682 WSASetLastError(0xdeadbeef);
11683 ret = recv(client, buffer, sizeof(buffer), 0);
11684 ok(ret == -1, "got %d\n", ret);
11685 ok(WSAGetLastError() == WSAEWOULDBLOCK, "got error %u\n", WSAGetLastError());
11687 WSASetLastError(0xdeadbeef);
11688 overlapped.Internal = 0xdeadbeef;
11689 ret = WSARecv(client, &wsabuf, 1, &size, &flags, NULL, NULL);
11690 ok(ret == -1, "got %d\n", ret);
11691 ok(WSAGetLastError() == WSAEWOULDBLOCK, "got error %u\n", WSAGetLastError());
11692 ok(overlapped.Internal == 0xdeadbeef, "got status %#x\n", (NTSTATUS)overlapped.Internal);
11694 /* Overlapped, with a NULL event. */
11696 params.client = client;
11697 params.event = NULL;
11698 thread = CreateThread(NULL, 0, nonblocking_async_recv_thread, &params, 0, NULL);
11700 ret = WaitForSingleObject(thread, 200);
11701 ok(ret == WAIT_TIMEOUT, "expected timeout\n");
11703 ret = send(server, "data", 4, 0);
11704 ok(ret == 4, "got %d\n", ret);
11706 ret = WaitForSingleObject(thread, 200);
11707 ok(!ret, "wait timed out\n");
11708 CloseHandle(thread);
11710 /* Overlapped, with a non-NULL event. */
11712 params.client = client;
11713 params.event = event;
11714 thread = CreateThread(NULL, 0, nonblocking_async_recv_thread, &params, 0, NULL);
11716 ret = WaitForSingleObject(thread, 200);
11717 ok(ret == WAIT_TIMEOUT, "expected timeout\n");
11719 ret = send(server, "data", 4, 0);
11720 ok(ret == 4, "got %d\n", ret);
11722 ret = WaitForSingleObject(thread, 200);
11723 ok(!ret, "wait timed out\n");
11724 CloseHandle(thread);
11726 /* With data already in the pipe. */
11728 ret = send(server, "data", 4, 0);
11729 ok(ret == 4, "got %d\n", ret);
11731 memset(buffer, 0, sizeof(buffer));
11732 ret = WSARecv(client, &wsabuf, 1, NULL, &flags, &overlapped, NULL);
11733 ok(!ret, "got %d\n", ret);
11734 ret = GetOverlappedResult((HANDLE)client, &overlapped, &size, FALSE);
11735 ok(ret, "got error %u\n", GetLastError());
11736 ok(size == 4, "got size %u\n", size);
11737 ok(!strcmp(buffer, "data"), "got %s\n", debugstr_an(buffer, size));
11739 closesocket(client);
11740 closesocket(server);
11742 CloseHandle(overlapped.hEvent);
11745 static void test_simultaneous_async_recv(void)
11747 SOCKET client, server;
11748 OVERLAPPED overlappeds[2] = {{0}};
11749 HANDLE events[2];
11750 WSABUF wsabufs[2];
11751 DWORD flags[2] = {0};
11752 size_t num_io = 2, stride = 16, i;
11753 char resbuf[32] = "";
11754 static const char msgstr[32] = "-- Lorem ipsum dolor sit amet -";
11755 int ret;
11757 for (i = 0; i < num_io; i++) events[i] = CreateEventW(NULL, TRUE, FALSE, NULL);
11759 tcp_socketpair(&client, &server);
11761 for (i = 0; i < num_io; i++)
11763 wsabufs[i].buf = resbuf + i * stride;
11764 wsabufs[i].len = stride;
11765 overlappeds[i].hEvent = events[i];
11766 ret = WSARecv(client, &wsabufs[i], 1, NULL, &flags[i], &overlappeds[i], NULL);
11767 ok(ret == -1, "got %d\n", ret);
11768 ok(WSAGetLastError() == ERROR_IO_PENDING, "got error %u\n", WSAGetLastError());
11771 ret = send(server, msgstr, sizeof(msgstr), 0);
11772 ok(ret == sizeof(msgstr), "got %d\n", ret);
11774 for (i = 0; i < num_io; i++)
11776 const void *expect = msgstr + i * stride;
11777 const void *actual = resbuf + i * stride;
11778 DWORD size;
11780 ret = WaitForSingleObject(events[i], 1000);
11781 ok(!ret, "wait timed out\n");
11783 size = 0;
11784 ret = GetOverlappedResult((HANDLE)client, &overlappeds[i], &size, FALSE);
11785 ok(ret, "got error %u\n", GetLastError());
11786 ok(size == stride, "got size %u\n", size);
11787 ok(!memcmp(expect, actual, stride), "expected %s, got %s\n", debugstr_an(expect, stride), debugstr_an(actual, stride));
11790 closesocket(client);
11791 closesocket(server);
11793 for (i = 0; i < num_io; i++) CloseHandle(events[i]);
11796 static void test_empty_recv(void)
11798 OVERLAPPED overlapped = {0};
11799 SOCKET client, server;
11800 DWORD size, flags = 0;
11801 char buffer[5];
11802 WSABUF wsabuf;
11803 int ret;
11805 overlapped.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
11806 tcp_socketpair(&client, &server);
11808 WSASetLastError(0xdeadbeef);
11809 ret = WSARecv(client, NULL, 0, NULL, &flags, &overlapped, NULL);
11810 ok(ret == -1, "expected failure\n");
11811 todo_wine ok(WSAGetLastError() == WSAEINVAL, "got error %u\n", WSAGetLastError());
11813 wsabuf.buf = buffer;
11814 wsabuf.len = 0;
11815 WSASetLastError(0xdeadbeef);
11816 ret = WSARecv(client, &wsabuf, 0, NULL, &flags, &overlapped, NULL);
11817 ok(ret == -1, "expected failure\n");
11818 todo_wine ok(WSAGetLastError() == WSAEINVAL, "got error %u\n", WSAGetLastError());
11820 WSASetLastError(0xdeadbeef);
11821 ret = WSARecv(client, &wsabuf, 1, NULL, &flags, &overlapped, NULL);
11822 ok(ret == -1, "expected failure\n");
11823 ok(WSAGetLastError() == ERROR_IO_PENDING, "got error %u\n", WSAGetLastError());
11825 ret = send(server, "data", 5, 0);
11826 ok(ret == 5, "got %d\n", ret);
11828 ret = WaitForSingleObject(overlapped.hEvent, 1000);
11829 ok(!ret, "wait failed\n");
11830 ret = GetOverlappedResult((HANDLE)client, &overlapped, &size, FALSE);
11831 ok(ret, "got error %u\n", GetLastError());
11832 ok(!size, "got size %u\n", size);
11834 WSASetLastError(0xdeadbeef);
11835 ret = WSARecv(client, &wsabuf, 1, &size, &flags, &overlapped, NULL);
11836 ok(!ret, "got error %u\n", WSAGetLastError());
11837 ok(!size, "got size %u\n", size);
11839 ret = recv(client, NULL, 0, 0);
11840 ok(!ret, "got %d\n", ret);
11842 ret = recv(client, buffer, sizeof(buffer), 0);
11843 ok(ret == 5, "got %d\n", ret);
11844 ok(!strcmp(buffer, "data"), "got %s\n", debugstr_an(buffer, ret));
11846 closesocket(client);
11847 closesocket(server);
11848 CloseHandle(overlapped.hEvent);
11851 static void test_timeout(void)
11853 DWORD timeout, flags = 0, size;
11854 OVERLAPPED overlapped = {0};
11855 SOCKET client, server;
11856 WSABUF wsabuf;
11857 int ret, len;
11858 char buffer;
11860 tcp_socketpair(&client, &server);
11861 overlapped.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
11863 timeout = 0xdeadbeef;
11864 len = sizeof(timeout);
11865 WSASetLastError(0xdeadbeef);
11866 ret = getsockopt(client, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, &len);
11867 ok(!ret, "expected success\n");
11868 ok(!WSAGetLastError(), "got error %u\n", WSAGetLastError());
11869 ok(len == sizeof(timeout), "got size %u\n", len);
11870 ok(!timeout, "got timeout %u\n", timeout);
11872 timeout = 100;
11873 WSASetLastError(0xdeadbeef);
11874 ret = setsockopt(client, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout));
11875 ok(!ret, "expected success\n");
11876 ok(!WSAGetLastError(), "got error %u\n", WSAGetLastError());
11878 timeout = 0xdeadbeef;
11879 len = sizeof(timeout);
11880 WSASetLastError(0xdeadbeef);
11881 ret = getsockopt(client, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, &len);
11882 ok(!ret, "expected success\n");
11883 ok(!WSAGetLastError(), "got error %u\n", WSAGetLastError());
11884 ok(timeout == 100, "got timeout %u\n", timeout);
11886 WSASetLastError(0xdeadbeef);
11887 ret = recv(client, &buffer, 1, 0);
11888 ok(ret == -1, "got %d\n", ret);
11889 ok(WSAGetLastError() == WSAETIMEDOUT, "got error %u\n", WSAGetLastError());
11891 wsabuf.buf = &buffer;
11892 wsabuf.len = 1;
11893 WSASetLastError(0xdeadbeef);
11894 size = 0xdeadbeef;
11895 ret = WSARecv(client, &wsabuf, 1, &size, &flags, NULL, NULL);
11896 ok(ret == -1, "got %d\n", ret);
11897 ok(WSAGetLastError() == WSAETIMEDOUT, "got error %u\n", WSAGetLastError());
11898 ok(size == 0xdeadbeef, "got size %u\n", size);
11900 wsabuf.buf = &buffer;
11901 wsabuf.len = 1;
11902 WSASetLastError(0xdeadbeef);
11903 size = 0xdeadbeef;
11904 ret = WSARecv(client, &wsabuf, 1, &size, &flags, &overlapped, NULL);
11905 ok(ret == -1, "got %d\n", ret);
11906 ok(WSAGetLastError() == ERROR_IO_PENDING, "got error %u\n", WSAGetLastError());
11908 ret = WaitForSingleObject(overlapped.hEvent, 200);
11909 ok(ret == WAIT_TIMEOUT, "got %d\n", ret);
11911 ret = send(server, "a", 1, 0);
11912 ok(ret == 1, "got %d\n", ret);
11914 ret = WaitForSingleObject(overlapped.hEvent, 200);
11915 ok(!ret, "got %d\n", ret);
11916 ret = GetOverlappedResult((HANDLE)client, &overlapped, &size, FALSE);
11917 ok(ret, "got error %u\n", GetLastError());
11918 ok(size == 1, "got size %u\n", size);
11920 closesocket(client);
11921 closesocket(server);
11922 CloseHandle(overlapped.hEvent);
11925 static void test_so_debug(void)
11927 int ret, len;
11928 DWORD debug;
11929 SOCKET s;
11931 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
11933 len = sizeof(debug);
11934 WSASetLastError(0xdeadbeef);
11935 debug = 0xdeadbeef;
11936 ret = getsockopt(s, SOL_SOCKET, SO_DEBUG, (char *)&debug, &len);
11937 ok(!ret, "got %d\n", ret);
11938 ok(!WSAGetLastError(), "got error %u\n", WSAGetLastError());
11939 ok(len == sizeof(debug), "got len %u\n", len);
11940 ok(!debug, "got debug %u\n", debug);
11942 WSASetLastError(0xdeadbeef);
11943 debug = 2;
11944 ret = setsockopt(s, SOL_SOCKET, SO_DEBUG, (char *)&debug, sizeof(debug));
11945 ok(!ret, "got %d\n", ret);
11946 todo_wine ok(!WSAGetLastError(), "got error %u\n", WSAGetLastError());
11948 len = sizeof(debug);
11949 WSASetLastError(0xdeadbeef);
11950 debug = 0xdeadbeef;
11951 ret = getsockopt(s, SOL_SOCKET, SO_DEBUG, (char *)&debug, &len);
11952 ok(!ret, "got %d\n", ret);
11953 ok(!WSAGetLastError(), "got error %u\n", WSAGetLastError());
11954 ok(len == sizeof(debug), "got len %u\n", len);
11955 todo_wine ok(debug == 1, "got debug %u\n", debug);
11957 closesocket(s);
11960 struct sockopt_validity_test
11962 int opt;
11963 int get_error;
11964 int set_error;
11965 BOOL todo;
11968 static void do_sockopt_validity_tests(const char *type, SOCKET sock, int level,
11969 const struct sockopt_validity_test *tests)
11971 char value[256];
11972 int count, rc, expected_rc, i;
11974 for (i = 0; tests[i].opt; i++)
11976 winetest_push_context("%s option %i", type, tests[i].opt);
11977 memset(value, 0, sizeof(value));
11978 count = sizeof(value);
11980 WSASetLastError(0);
11981 rc = getsockopt(sock, level, tests[i].opt, value, &count);
11982 expected_rc = tests[i].get_error ? SOCKET_ERROR : 0;
11983 todo_wine_if(!tests[i].get_error && tests[i].todo)
11984 ok(rc == expected_rc || broken(rc == SOCKET_ERROR && WSAGetLastError() == WSAENOPROTOOPT),
11985 "expected getsockopt to return %i, got %i\n", expected_rc, rc);
11986 todo_wine_if(tests[i].todo)
11987 ok(WSAGetLastError() == tests[i].get_error || broken(rc == SOCKET_ERROR && WSAGetLastError() == WSAENOPROTOOPT),
11988 "expected getsockopt to set error %i, got %i\n", tests[i].get_error, WSAGetLastError());
11990 if (tests[i].get_error)
11992 winetest_pop_context();
11993 continue;
11996 WSASetLastError(0);
11997 rc = setsockopt(sock, level, tests[i].opt, value, count);
11998 expected_rc = tests[i].set_error ? SOCKET_ERROR : 0;
11999 todo_wine_if(!tests[i].set_error && tests[i].todo)
12000 ok(rc == expected_rc || broken(rc == SOCKET_ERROR && WSAGetLastError() == WSAENOPROTOOPT),
12001 "expected setsockopt to return %i, got %i\n", expected_rc, rc);
12002 todo_wine_if(tests[i].todo)
12003 ok(WSAGetLastError() == tests[i].set_error || broken(rc == SOCKET_ERROR && WSAGetLastError() == WSAENOPROTOOPT),
12004 "expected setsockopt to set error %i, got %i\n", tests[i].set_error, WSAGetLastError());
12006 winetest_pop_context();
12010 static void test_sockopt_validity(void)
12012 static const struct sockopt_validity_test ipv4_tcp_tests[] =
12014 { -1, WSAENOPROTOOPT },
12015 { IP_OPTIONS },
12016 { IP_HDRINCL, WSAEINVAL },
12017 { IP_TOS },
12018 { IP_TTL },
12019 { IP_MULTICAST_IF, WSAEINVAL },
12020 { IP_MULTICAST_TTL, WSAEINVAL },
12021 { IP_MULTICAST_LOOP, WSAEINVAL },
12022 { IP_ADD_MEMBERSHIP, WSAENOPROTOOPT },
12023 { IP_DROP_MEMBERSHIP, WSAENOPROTOOPT },
12024 { IP_DONTFRAGMENT },
12025 { IP_PKTINFO, WSAEINVAL },
12026 { IP_RECVTTL, WSAEINVAL },
12027 { IP_RECEIVE_BROADCAST, WSAEINVAL, 0, TRUE },
12028 { IP_RECVIF, WSAEINVAL, 0, TRUE },
12029 { IP_RECVDSTADDR, WSAEINVAL, 0, TRUE },
12030 { IP_IFLIST, 0, 0, TRUE },
12031 { IP_UNICAST_IF },
12032 { IP_RTHDR, 0, 0, TRUE },
12033 { IP_GET_IFLIST, WSAEINVAL, 0, TRUE },
12034 { IP_RECVRTHDR, WSAEINVAL, 0, TRUE },
12035 { IP_RECVTOS, WSAEINVAL },
12036 { IP_ORIGINAL_ARRIVAL_IF, WSAEINVAL, 0, TRUE },
12037 { IP_ECN, WSAEINVAL, 0, TRUE },
12038 { IP_PKTINFO_EX, WSAEINVAL, 0, TRUE },
12039 { IP_WFP_REDIRECT_RECORDS, WSAEINVAL, 0, TRUE },
12040 { IP_WFP_REDIRECT_CONTEXT, WSAEINVAL, 0, TRUE },
12041 { IP_MTU_DISCOVER, 0, WSAEINVAL, TRUE },
12042 { IP_MTU, WSAENOTCONN, 0, TRUE },
12043 { IP_RECVERR, WSAEINVAL, 0, TRUE },
12044 { IP_USER_MTU, 0, 0, TRUE },
12047 static const struct sockopt_validity_test ipv4_udp_tests[] =
12049 { -1, WSAENOPROTOOPT },
12050 { IP_OPTIONS },
12051 { IP_HDRINCL, WSAEINVAL },
12052 { IP_TOS },
12053 { IP_TTL },
12054 { IP_MULTICAST_IF },
12055 { IP_MULTICAST_TTL },
12056 { IP_MULTICAST_LOOP },
12057 { IP_ADD_MEMBERSHIP, WSAENOPROTOOPT },
12058 { IP_DROP_MEMBERSHIP, WSAENOPROTOOPT },
12059 { IP_DONTFRAGMENT },
12060 { IP_PKTINFO },
12061 { IP_RECVTTL },
12062 { IP_RECEIVE_BROADCAST, 0, 0, TRUE },
12063 { IP_RECVIF, 0, 0, TRUE },
12064 { IP_RECVDSTADDR, 0, 0, TRUE },
12065 { IP_IFLIST, 0, 0, TRUE },
12066 { IP_UNICAST_IF },
12067 { IP_RTHDR, 0, 0, TRUE },
12068 { IP_GET_IFLIST, WSAEINVAL, 0, TRUE },
12069 { IP_RECVRTHDR, 0, 0, TRUE },
12070 { IP_RECVTOS },
12071 { IP_ORIGINAL_ARRIVAL_IF, 0, 0, TRUE },
12072 { IP_ECN, 0, 0, TRUE },
12073 { IP_PKTINFO_EX, 0, 0, TRUE },
12074 { IP_WFP_REDIRECT_RECORDS, 0, 0, TRUE },
12075 { IP_WFP_REDIRECT_CONTEXT, 0, 0, TRUE },
12076 { IP_MTU_DISCOVER, 0, WSAEINVAL, TRUE },
12077 { IP_MTU, WSAENOTCONN, 0, TRUE },
12078 { IP_RECVERR, 0, 0, TRUE },
12079 { IP_USER_MTU, 0, 0, TRUE },
12082 static const struct sockopt_validity_test ipv4_raw_tests[] =
12084 { -1, WSAENOPROTOOPT },
12085 { IP_OPTIONS },
12086 { IP_HDRINCL, },
12087 { IP_TOS },
12088 { IP_TTL },
12089 { IP_MULTICAST_IF },
12090 { IP_MULTICAST_TTL },
12091 { IP_MULTICAST_LOOP },
12092 { IP_ADD_MEMBERSHIP, WSAENOPROTOOPT },
12093 { IP_DROP_MEMBERSHIP, WSAENOPROTOOPT },
12094 { IP_DONTFRAGMENT },
12095 { IP_PKTINFO },
12096 { IP_RECVTTL },
12097 { IP_RECEIVE_BROADCAST, 0, 0, TRUE },
12098 { IP_RECVIF, 0, 0, TRUE },
12099 { IP_RECVDSTADDR, 0, 0, TRUE },
12100 { IP_IFLIST, 0, 0, TRUE },
12101 { IP_UNICAST_IF },
12102 { IP_RTHDR, 0, 0, TRUE },
12103 { IP_GET_IFLIST, WSAEINVAL, 0, TRUE },
12104 { IP_RECVRTHDR, 0, 0, TRUE },
12105 { IP_RECVTOS },
12106 { IP_ORIGINAL_ARRIVAL_IF, 0, 0, TRUE },
12107 { IP_ECN, 0, 0, TRUE },
12108 { IP_PKTINFO_EX, 0, 0, TRUE },
12109 { IP_WFP_REDIRECT_RECORDS, 0, 0, TRUE },
12110 { IP_WFP_REDIRECT_CONTEXT, 0, 0, TRUE },
12111 { IP_MTU_DISCOVER, 0, WSAEINVAL, TRUE },
12112 { IP_MTU, WSAENOTCONN, 0, TRUE },
12113 { IP_RECVERR, WSAEINVAL, 0, TRUE },
12114 { IP_USER_MTU, 0, 0, TRUE },
12117 static const struct sockopt_validity_test ipv6_tcp_tests[] =
12119 { -1, WSAENOPROTOOPT },
12120 { IPV6_HOPOPTS, 0, 0, TRUE },
12121 { IPV6_HDRINCL, WSAEINVAL, 0, TRUE },
12122 { IPV6_UNICAST_HOPS },
12123 { IPV6_MULTICAST_IF, WSAEINVAL },
12124 { IPV6_MULTICAST_HOPS, WSAEINVAL },
12125 { IPV6_MULTICAST_LOOP, WSAEINVAL },
12126 { IPV6_ADD_MEMBERSHIP, WSAENOPROTOOPT },
12127 { IPV6_DROP_MEMBERSHIP, WSAENOPROTOOPT },
12128 { IPV6_DONTFRAG },
12129 { IPV6_PKTINFO, WSAEINVAL },
12130 { IPV6_HOPLIMIT, WSAEINVAL },
12131 { IPV6_PROTECTION_LEVEL },
12132 { IPV6_RECVIF, WSAEINVAL, 0, TRUE },
12133 { IPV6_RECVDSTADDR, WSAEINVAL, 0, TRUE },
12134 { IPV6_V6ONLY },
12135 { IPV6_IFLIST, 0, 0, TRUE },
12136 { IPV6_UNICAST_IF },
12137 { IPV6_RTHDR, 0, 0, TRUE },
12138 { IPV6_GET_IFLIST, WSAEINVAL, 0, TRUE },
12139 { IPV6_RECVRTHDR, WSAEINVAL, 0, TRUE },
12140 { IPV6_RECVTCLASS, WSAEINVAL },
12141 { IP_ORIGINAL_ARRIVAL_IF, WSAEINVAL, 0, TRUE },
12142 { IPV6_ECN, WSAEINVAL, 0, TRUE },
12143 { IPV6_PKTINFO_EX, WSAEINVAL, 0, TRUE },
12144 { IPV6_WFP_REDIRECT_RECORDS, WSAEINVAL, 0, TRUE },
12145 { IPV6_WFP_REDIRECT_CONTEXT, WSAEINVAL, 0, TRUE },
12146 { IPV6_MTU_DISCOVER, 0, WSAEINVAL, TRUE },
12147 { IPV6_MTU, WSAENOTCONN, 0, TRUE },
12148 { IPV6_RECVERR, WSAEINVAL, 0, TRUE },
12149 { IPV6_USER_MTU, 0, 0, TRUE },
12152 static const struct sockopt_validity_test ipv6_udp_tests[] =
12154 { -1, WSAENOPROTOOPT },
12155 { IPV6_HOPOPTS, 0, 0, TRUE },
12156 { IPV6_HDRINCL, WSAEINVAL, 0, TRUE },
12157 { IPV6_UNICAST_HOPS },
12158 { IPV6_MULTICAST_IF },
12159 { IPV6_MULTICAST_HOPS },
12160 { IPV6_MULTICAST_LOOP },
12161 { IPV6_ADD_MEMBERSHIP, WSAENOPROTOOPT },
12162 { IPV6_DROP_MEMBERSHIP, WSAENOPROTOOPT },
12163 { IPV6_DONTFRAG },
12164 { IPV6_PKTINFO },
12165 { IPV6_HOPLIMIT },
12166 { IPV6_PROTECTION_LEVEL },
12167 { IPV6_RECVIF, 0, 0, TRUE },
12168 { IPV6_RECVDSTADDR, 0, 0, TRUE },
12169 { IPV6_V6ONLY },
12170 { IPV6_IFLIST, 0, 0, TRUE },
12171 { IPV6_UNICAST_IF },
12172 { IPV6_RTHDR, 0, 0, TRUE },
12173 { IPV6_GET_IFLIST, WSAEINVAL, 0, TRUE },
12174 { IPV6_RECVRTHDR, 0, 0, TRUE },
12175 { IPV6_RECVTCLASS },
12176 { IP_ORIGINAL_ARRIVAL_IF, 0, 0, TRUE },
12177 { IPV6_ECN, 0, 0, TRUE },
12178 { IPV6_PKTINFO_EX, 0, 0, TRUE },
12179 { IPV6_WFP_REDIRECT_RECORDS, 0, 0, TRUE },
12180 { IPV6_WFP_REDIRECT_CONTEXT, 0, 0, TRUE },
12181 { IPV6_MTU_DISCOVER, 0, WSAEINVAL, TRUE },
12182 { IPV6_MTU, WSAENOTCONN, 0, TRUE },
12183 { IPV6_RECVERR, 0, 0, TRUE },
12184 { IPV6_USER_MTU, 0, 0, TRUE },
12187 static const struct sockopt_validity_test ipv6_raw_tests[] =
12189 { -1, WSAENOPROTOOPT },
12190 { IPV6_HOPOPTS, 0, 0, TRUE },
12191 { IPV6_HDRINCL, 0, 0, TRUE },
12192 { IPV6_UNICAST_HOPS },
12193 { IPV6_MULTICAST_IF },
12194 { IPV6_MULTICAST_HOPS },
12195 { IPV6_MULTICAST_LOOP },
12196 { IPV6_ADD_MEMBERSHIP, WSAENOPROTOOPT },
12197 { IPV6_DROP_MEMBERSHIP, WSAENOPROTOOPT },
12198 { IPV6_DONTFRAG },
12199 { IPV6_PKTINFO },
12200 { IPV6_HOPLIMIT },
12201 { IPV6_PROTECTION_LEVEL },
12202 { IPV6_RECVIF, 0, 0, TRUE },
12203 { IPV6_RECVDSTADDR, 0, 0, TRUE },
12204 { IPV6_V6ONLY },
12205 { IPV6_IFLIST, 0, 0, TRUE },
12206 { IPV6_UNICAST_IF },
12207 { IPV6_RTHDR, 0, 0, TRUE },
12208 { IPV6_GET_IFLIST, WSAEINVAL, 0, TRUE },
12209 { IPV6_RECVRTHDR, 0, 0, TRUE },
12210 { IPV6_RECVTCLASS },
12211 { IP_ORIGINAL_ARRIVAL_IF, 0, 0, TRUE },
12212 { IPV6_ECN, 0, 0, TRUE },
12213 { IPV6_PKTINFO_EX, 0, 0, TRUE },
12214 { IPV6_WFP_REDIRECT_RECORDS, 0, 0, TRUE },
12215 { IPV6_WFP_REDIRECT_CONTEXT, 0, 0, TRUE },
12216 { IPV6_MTU_DISCOVER, 0, WSAEINVAL, TRUE },
12217 { IPV6_MTU, WSAENOTCONN, 0, TRUE },
12218 { IPV6_RECVERR, WSAEINVAL, 0, TRUE },
12219 { IPV6_USER_MTU, 0, 0, TRUE },
12222 static const struct sockopt_validity_test file_handle_tests[] =
12224 { -1, WSAENOTSOCK },
12225 { SO_TYPE, WSAENOTSOCK },
12226 { SO_OPENTYPE },
12229 char path[MAX_PATH];
12230 HANDLE file;
12231 SOCKET sock;
12233 sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
12234 ok(sock != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
12235 do_sockopt_validity_tests("IPv4 TCP", sock, IPPROTO_IP, ipv4_tcp_tests);
12236 closesocket(sock);
12238 sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
12239 ok(sock != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
12240 do_sockopt_validity_tests("IPv4 UDP", sock, IPPROTO_IP, ipv4_udp_tests);
12241 closesocket(sock);
12243 sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
12244 if (sock == INVALID_SOCKET && WSAGetLastError() == WSAEACCES)
12246 skip("Raw IPv4 sockets are not available\n");
12248 else
12250 ok(sock != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
12251 do_sockopt_validity_tests("IPv4 raw", sock, IPPROTO_IP, ipv4_raw_tests);
12252 closesocket(sock);
12255 sock = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
12256 ok(sock != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
12257 do_sockopt_validity_tests("IPv6 TCP", sock, IPPROTO_IPV6, ipv6_tcp_tests);
12258 closesocket(sock);
12260 sock = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
12261 ok(sock != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
12262 do_sockopt_validity_tests("IPv6 UDP", sock, IPPROTO_IPV6, ipv6_udp_tests);
12263 closesocket(sock);
12265 sock = socket(AF_INET6, SOCK_RAW, IPPROTO_RAW);
12266 if (sock == INVALID_SOCKET && WSAGetLastError() == WSAEACCES)
12268 skip("Raw IPv6 sockets are not available\n");
12270 else
12272 ok(sock != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
12273 do_sockopt_validity_tests("IPv6 raw", sock, IPPROTO_IPV6, ipv6_raw_tests);
12274 closesocket(sock);
12277 GetSystemWindowsDirectoryA(path, ARRAY_SIZE(path));
12278 strcat(path, "\\system.ini");
12279 file = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_ALWAYS, 0x0, NULL);
12280 do_sockopt_validity_tests("file", (SOCKET)file, SOL_SOCKET, file_handle_tests);
12281 CloseHandle(file);
12284 START_TEST( sock )
12286 int i;
12288 /* Leave these tests at the beginning. They depend on WSAStartup not having been
12289 * called, which is done by Init() below. */
12290 test_WithoutWSAStartup();
12291 test_WithWSAStartup();
12293 Init();
12295 test_set_getsockopt();
12296 test_so_reuseaddr();
12297 test_ip_pktinfo();
12298 test_ipv4_cmsg();
12299 test_ipv6_cmsg();
12300 test_extendedSocketOptions();
12301 test_so_debug();
12302 test_sockopt_validity();
12304 for (i = 0; i < ARRAY_SIZE(tests); i++)
12305 do_test(&tests[i]);
12307 test_UDP();
12309 test_WSASocket();
12310 test_WSADuplicateSocket();
12311 test_WSAEnumNetworkEvents();
12313 test_errors();
12314 test_listen();
12315 test_select();
12316 test_accept();
12317 test_getpeername();
12318 test_getsockname();
12320 test_address_list_query();
12321 test_fionbio();
12322 test_fionread_siocatmark();
12323 test_get_extension_func();
12324 test_get_interface_list();
12325 test_keepalive_vals();
12326 test_sioRoutingInterfaceQuery();
12327 test_sioAddressListChange();
12328 test_base_handle();
12329 test_unsupported_ioctls();
12331 test_WSASendMsg();
12332 test_WSASendTo();
12333 test_WSARecv();
12334 test_WSAPoll();
12335 test_write_watch();
12336 test_iocp();
12338 test_events();
12340 test_ipv6only();
12341 test_TransmitFile();
12342 test_AcceptEx();
12343 test_connect();
12344 test_shutdown();
12345 test_DisconnectEx();
12347 test_completion_port();
12348 test_connect_completion_port();
12349 test_shutdown_completion_port();
12350 test_bind();
12351 test_connecting_socket();
12352 test_WSAGetOverlappedResult();
12353 test_nonblocking_async_recv();
12354 test_simultaneous_async_recv();
12355 test_empty_recv();
12356 test_timeout();
12358 /* this is an io heavy test, do it at the end so the kernel doesn't start dropping packets */
12359 test_send();
12361 Exit();