Assorted spelling fixes.
[wine.git] / dlls / ws2_32 / tests / sock.c
blobebde182ac22dd6b386ea8e23df18f3c57965da90
1 /*
2 * Unit test suite for winsock functions
4 * Copyright 2002 Martin Wilck
5 * Copyright 2005 Thomas Kho
6 * Copyright 2008 Jeff Zaroyko
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include <ntstatus.h>
24 #define WIN32_NO_STATUS
25 #include <winsock2.h>
26 #include <windows.h>
27 #include <ws2tcpip.h>
28 #include <mswsock.h>
29 #include <mstcpip.h>
30 #include <stdio.h>
31 #include "wine/test.h"
33 #define MAX_CLIENTS 4 /* Max number of clients */
34 #define FIRST_CHAR 'A' /* First character in transferred pattern */
35 #define BIND_SLEEP 10 /* seconds to wait between attempts to bind() */
36 #define BIND_TRIES 6 /* Number of bind() attempts */
37 #define TEST_TIMEOUT 30 /* seconds to wait before killing child threads
38 after server initialization, if something hangs */
40 #define NUM_UDP_PEERS 3 /* Number of UDP sockets to create and test > 1 */
42 #define NUM_THREADS 3 /* Number of threads to run getservbyname */
43 #define NUM_QUERIES 250 /* Number of getservbyname queries per thread */
45 #define SERVERIP "127.0.0.1" /* IP to bind to */
46 #define SERVERPORT 9374 /* Port number to bind to */
48 #define wsa_ok(op, cond, msg) \
49 do { \
50 int tmp, err = 0; \
51 tmp = op; \
52 if ( !(cond tmp) ) err = WSAGetLastError(); \
53 ok ( cond tmp, msg, GetCurrentThreadId(), err); \
54 } while (0);
56 #define make_keepalive(k, enable, time, interval) \
57 k.onoff = enable; \
58 k.keepalivetime = time; \
59 k.keepaliveinterval = interval;
61 /* Function pointers */
62 static void (WINAPI *pfreeaddrinfo)(struct addrinfo *);
63 static int (WINAPI *pgetaddrinfo)(LPCSTR,LPCSTR,const struct addrinfo *,struct addrinfo **);
64 static void (WINAPI *pFreeAddrInfoW)(PADDRINFOW);
65 static int (WINAPI *pGetAddrInfoW)(LPCWSTR,LPCWSTR,const ADDRINFOW *,PADDRINFOW *);
66 static PCSTR (WINAPI *pInetNtop)(INT,LPVOID,LPSTR,ULONG);
68 /**************** Structs and typedefs ***************/
70 typedef struct thread_info
72 HANDLE thread;
73 DWORD id;
74 } thread_info;
76 /* Information in the server about open client connections */
77 typedef struct sock_info
79 SOCKET s;
80 struct sockaddr_in addr;
81 struct sockaddr_in peer;
82 char *buf;
83 int n_recvd;
84 int n_sent;
85 } sock_info;
87 /* Test parameters for both server & client */
88 typedef struct test_params
90 int sock_type;
91 int sock_prot;
92 const char *inet_addr;
93 short inet_port;
94 int chunk_size;
95 int n_chunks;
96 int n_clients;
97 } test_params;
99 /* server-specific test parameters */
100 typedef struct server_params
102 test_params *general;
103 DWORD sock_flags;
104 int buflen;
105 } server_params;
107 /* client-specific test parameters */
108 typedef struct client_params
110 test_params *general;
111 DWORD sock_flags;
112 int buflen;
113 } client_params;
115 /* This type combines all information for setting up a test scenario */
116 typedef struct test_setup
118 test_params general;
119 LPVOID srv;
120 server_params srv_params;
121 LPVOID clt;
122 client_params clt_params;
123 } test_setup;
125 /* Thread local storage for server */
126 typedef struct server_memory
128 SOCKET s;
129 struct sockaddr_in addr;
130 sock_info sock[MAX_CLIENTS];
131 } server_memory;
133 /* Thread local storage for client */
134 typedef struct client_memory
136 SOCKET s;
137 struct sockaddr_in addr;
138 char *send_buf;
139 char *recv_buf;
140 } client_memory;
142 /* SelectReadThread thread parameters */
143 typedef struct select_thread_params
145 SOCKET s;
146 BOOL ReadKilled;
147 } select_thread_params;
149 /**************** Static variables ***************/
151 static DWORD tls; /* Thread local storage index */
152 static HANDLE thread[1+MAX_CLIENTS];
153 static DWORD thread_id[1+MAX_CLIENTS];
154 static HANDLE server_ready;
155 static HANDLE client_ready[MAX_CLIENTS];
156 static int client_id;
158 /**************** General utility functions ***************/
160 static int tcp_socketpair(SOCKET *src, SOCKET *dst)
162 SOCKET server = INVALID_SOCKET;
163 struct sockaddr_in addr;
164 int len;
165 int ret;
167 *src = INVALID_SOCKET;
168 *dst = INVALID_SOCKET;
170 *src = socket(AF_INET, SOCK_STREAM, 0);
171 if (*src == INVALID_SOCKET)
172 goto end;
174 server = socket(AF_INET, SOCK_STREAM, 0);
175 if (server == INVALID_SOCKET)
176 goto end;
178 memset(&addr, 0, sizeof(addr));
179 addr.sin_family = AF_INET;
180 addr.sin_addr.s_addr = inet_addr("127.0.0.1");
181 ret = bind(server, (struct sockaddr*)&addr, sizeof(addr));
182 if (ret != 0)
183 goto end;
185 len = sizeof(addr);
186 ret = getsockname(server, (struct sockaddr*)&addr, &len);
187 if (ret != 0)
188 goto end;
190 ret = listen(server, 1);
191 if (ret != 0)
192 goto end;
194 ret = connect(*src, (struct sockaddr*)&addr, sizeof(addr));
195 if (ret != 0)
196 goto end;
198 len = sizeof(addr);
199 *dst = accept(server, (struct sockaddr*)&addr, &len);
201 end:
202 if (server != INVALID_SOCKET)
203 closesocket(server);
204 if (*src != INVALID_SOCKET && *dst != INVALID_SOCKET)
205 return 0;
206 closesocket(*src);
207 closesocket(*dst);
208 return -1;
211 static void set_so_opentype ( BOOL overlapped )
213 int optval = !overlapped, newval, len = sizeof (int);
215 ok ( setsockopt ( INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE,
216 (LPVOID) &optval, sizeof (optval) ) == 0,
217 "setting SO_OPENTYPE failed\n" );
218 ok ( getsockopt ( INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE,
219 (LPVOID) &newval, &len ) == 0,
220 "getting SO_OPENTYPE failed\n" );
221 ok ( optval == newval, "failed to set SO_OPENTYPE\n" );
224 static int set_blocking ( SOCKET s, BOOL blocking )
226 u_long val = !blocking;
227 return ioctlsocket ( s, FIONBIO, &val );
230 static void fill_buffer ( char *buf, int chunk_size, int n_chunks )
232 char c, *p;
233 for ( c = FIRST_CHAR, p = buf; c < FIRST_CHAR + n_chunks; c++, p += chunk_size )
234 memset ( p, c, chunk_size );
237 static int test_buffer ( char *buf, int chunk_size, int n_chunks )
239 char c, *p;
240 int i;
241 for ( c = FIRST_CHAR, p = buf; c < FIRST_CHAR + n_chunks; c++, p += chunk_size )
243 for ( i = 0; i < chunk_size; i++ )
244 if ( p[i] != c ) return i;
246 return -1;
250 * This routine is called when a client / server does not expect any more data,
251 * but needs to acknowledge the closing of the connection (by reading 0 bytes).
253 static void read_zero_bytes ( SOCKET s )
255 char buf[256];
256 int tmp, n = 0;
257 while ( ( tmp = recv ( s, buf, 256, 0 ) ) > 0 )
258 n += tmp;
259 ok ( n <= 0, "garbage data received: %d bytes\n", n );
262 static int do_oob_send ( SOCKET s, char *buf, int buflen, int sendlen )
264 char* last = buf + buflen, *p;
265 int n = 1;
266 for ( p = buf; n > 0 && p < last; p += n )
267 n = send ( s, p, min ( sendlen, last - p ), MSG_OOB );
268 wsa_ok ( n, 0 <=, "do_oob_send (%x): error %d\n" );
269 return p - buf;
272 static int do_synchronous_send ( SOCKET s, char *buf, int buflen, int sendlen )
274 char* last = buf + buflen, *p;
275 int n = 1;
276 for ( p = buf; n > 0 && p < last; p += n )
277 n = send ( s, p, min ( sendlen, last - p ), 0 );
278 wsa_ok ( n, 0 <=, "do_synchronous_send (%x): error %d\n" );
279 return p - buf;
282 static int do_synchronous_recv ( SOCKET s, char *buf, int buflen, int recvlen )
284 char* last = buf + buflen, *p;
285 int n = 1;
286 for ( p = buf; n > 0 && p < last; p += n )
287 n = recv ( s, p, min ( recvlen, last - p ), 0 );
288 wsa_ok ( n, 0 <=, "do_synchronous_recv (%x): error %d:\n" );
289 return p - buf;
292 static int do_synchronous_recvfrom ( SOCKET s, char *buf, int buflen,int flags,struct sockaddr *from, int *fromlen, int recvlen )
294 char* last = buf + buflen, *p;
295 int n = 1;
296 for ( p = buf; n > 0 && p < last; p += n )
297 n = recvfrom ( s, p, min ( recvlen, last - p ), 0, from, fromlen );
298 wsa_ok ( n, 0 <=, "do_synchronous_recv (%x): error %d:\n" );
299 return p - buf;
303 * Call this routine right after thread startup.
304 * SO_OPENTYPE must by 0, regardless what the server did.
306 static void check_so_opentype (void)
308 int tmp = 1, len;
309 len = sizeof (tmp);
310 getsockopt ( INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE, (LPVOID) &tmp, &len );
311 ok ( tmp == 0, "check_so_opentype: wrong startup value of SO_OPENTYPE: %d\n", tmp );
314 /**************** Server utility functions ***************/
317 * Even if we have closed our server socket cleanly,
318 * the OS may mark the address "in use" for some time -
319 * this happens with native Linux apps, too.
321 static void do_bind ( SOCKET s, struct sockaddr* addr, int addrlen )
323 int err, wsaerr = 0, n_try = BIND_TRIES;
325 while ( ( err = bind ( s, addr, addrlen ) ) != 0 &&
326 ( wsaerr = WSAGetLastError () ) == WSAEADDRINUSE &&
327 n_try-- >= 0)
329 trace ( "address in use, waiting ...\n" );
330 Sleep ( 1000 * BIND_SLEEP );
332 ok ( err == 0, "failed to bind: %d\n", wsaerr );
335 static void server_start ( server_params *par )
337 int i;
338 test_params *gen = par->general;
339 server_memory *mem = LocalAlloc ( LPTR, sizeof ( server_memory ) );
341 TlsSetValue ( tls, mem );
342 mem->s = WSASocketA ( AF_INET, gen->sock_type, gen->sock_prot,
343 NULL, 0, par->sock_flags );
344 ok ( mem->s != INVALID_SOCKET, "Server: WSASocket failed\n" );
346 mem->addr.sin_family = AF_INET;
347 mem->addr.sin_addr.s_addr = inet_addr ( gen->inet_addr );
348 mem->addr.sin_port = htons ( gen->inet_port );
350 for (i = 0; i < MAX_CLIENTS; i++)
352 mem->sock[i].s = INVALID_SOCKET;
353 mem->sock[i].buf = LocalAlloc ( LPTR, gen->n_chunks * gen->chunk_size );
354 mem->sock[i].n_recvd = 0;
355 mem->sock[i].n_sent = 0;
358 if ( gen->sock_type == SOCK_STREAM )
359 do_bind ( mem->s, (struct sockaddr*) &mem->addr, sizeof (mem->addr) );
362 static void server_stop (void)
364 int i;
365 server_memory *mem = TlsGetValue ( tls );
367 for (i = 0; i < MAX_CLIENTS; i++ )
369 LocalFree ( mem->sock[i].buf );
370 if ( mem->sock[i].s != INVALID_SOCKET )
371 closesocket ( mem->sock[i].s );
373 ok ( closesocket ( mem->s ) == 0, "closesocket failed\n" );
374 LocalFree ( mem );
375 ExitThread ( GetCurrentThreadId () );
378 /**************** Client utilitiy functions ***************/
380 static void client_start ( client_params *par )
382 test_params *gen = par->general;
383 client_memory *mem = LocalAlloc (LPTR, sizeof (client_memory));
385 TlsSetValue ( tls, mem );
387 WaitForSingleObject ( server_ready, INFINITE );
389 mem->s = WSASocketA ( AF_INET, gen->sock_type, gen->sock_prot,
390 NULL, 0, par->sock_flags );
392 mem->addr.sin_family = AF_INET;
393 mem->addr.sin_addr.s_addr = inet_addr ( gen->inet_addr );
394 mem->addr.sin_port = htons ( gen->inet_port );
396 ok ( mem->s != INVALID_SOCKET, "Client: WSASocket failed\n" );
398 mem->send_buf = LocalAlloc ( LPTR, 2 * gen->n_chunks * gen->chunk_size );
399 mem->recv_buf = mem->send_buf + gen->n_chunks * gen->chunk_size;
400 fill_buffer ( mem->send_buf, gen->chunk_size, gen->n_chunks );
402 SetEvent ( client_ready[client_id] );
403 /* Wait for the other clients to come up */
404 WaitForMultipleObjects ( min ( gen->n_clients, MAX_CLIENTS ), client_ready, TRUE, INFINITE );
407 static void client_stop (void)
409 client_memory *mem = TlsGetValue ( tls );
410 wsa_ok ( closesocket ( mem->s ), 0 ==, "closesocket error (%x): %d\n" );
411 LocalFree ( mem->send_buf );
412 LocalFree ( mem );
413 ExitThread(0);
416 /**************** Servers ***************/
419 * simple_server: A very basic server doing synchronous IO.
421 static VOID WINAPI simple_server ( server_params *par )
423 test_params *gen = par->general;
424 server_memory *mem;
425 int pos, n_recvd, n_sent, n_expected = gen->n_chunks * gen->chunk_size, tmp, i,
426 id = GetCurrentThreadId();
428 trace ( "simple_server (%x) starting\n", id );
430 set_so_opentype ( FALSE ); /* non-overlapped */
431 server_start ( par );
432 mem = TlsGetValue ( tls );
434 wsa_ok ( set_blocking ( mem->s, TRUE ), 0 ==, "simple_server (%x): failed to set blocking mode: %d\n");
435 wsa_ok ( listen ( mem->s, SOMAXCONN ), 0 ==, "simple_server (%x): listen failed: %d\n");
437 trace ( "simple_server (%x) ready\n", id );
438 SetEvent ( server_ready ); /* notify clients */
440 for ( i = 0; i < min ( gen->n_clients, MAX_CLIENTS ); i++ )
442 trace ( "simple_server (%x): waiting for client\n", id );
444 /* accept a single connection */
445 tmp = sizeof ( mem->sock[0].peer );
446 mem->sock[0].s = accept ( mem->s, (struct sockaddr*) &mem->sock[0].peer, &tmp );
447 wsa_ok ( mem->sock[0].s, INVALID_SOCKET !=, "simple_server (%x): accept failed: %d\n" );
449 ok ( mem->sock[0].peer.sin_addr.s_addr == inet_addr ( gen->inet_addr ),
450 "simple_server (%x): strange peer address\n", id );
452 /* Receive data & check it */
453 n_recvd = do_synchronous_recv ( mem->sock[0].s, mem->sock[0].buf, n_expected, par->buflen );
454 ok ( n_recvd == n_expected,
455 "simple_server (%x): received less data than expected: %d of %d\n", id, n_recvd, n_expected );
456 pos = test_buffer ( mem->sock[0].buf, gen->chunk_size, gen->n_chunks );
457 ok ( pos == -1, "simple_server (%x): test pattern error: %d\n", id, pos);
459 /* Echo data back */
460 n_sent = do_synchronous_send ( mem->sock[0].s, mem->sock[0].buf, n_expected, par->buflen );
461 ok ( n_sent == n_expected,
462 "simple_server (%x): sent less data than expected: %d of %d\n", id, n_sent, n_expected );
464 /* cleanup */
465 read_zero_bytes ( mem->sock[0].s );
466 wsa_ok ( closesocket ( mem->sock[0].s ), 0 ==, "simple_server (%x): closesocket error: %d\n" );
467 mem->sock[0].s = INVALID_SOCKET;
470 trace ( "simple_server (%x) exiting\n", id );
471 server_stop ();
475 * oob_server: A very basic server receiving out-of-band data.
477 static VOID WINAPI oob_server ( server_params *par )
479 test_params *gen = par->general;
480 server_memory *mem;
481 u_long atmark = 0;
482 int pos, n_recvd, n_expected = gen->n_chunks * gen->chunk_size, tmp,
483 id = GetCurrentThreadId();
485 trace ( "oob_server (%x) starting\n", id );
487 set_so_opentype ( FALSE ); /* non-overlapped */
488 server_start ( par );
489 mem = TlsGetValue ( tls );
491 wsa_ok ( set_blocking ( mem->s, TRUE ), 0 ==, "oob_server (%x): failed to set blocking mode: %d\n");
492 wsa_ok ( listen ( mem->s, SOMAXCONN ), 0 ==, "oob_server (%x): listen failed: %d\n");
494 trace ( "oob_server (%x) ready\n", id );
495 SetEvent ( server_ready ); /* notify clients */
497 trace ( "oob_server (%x): waiting for client\n", id );
499 /* accept a single connection */
500 tmp = sizeof ( mem->sock[0].peer );
501 mem->sock[0].s = accept ( mem->s, (struct sockaddr*) &mem->sock[0].peer, &tmp );
502 wsa_ok ( mem->sock[0].s, INVALID_SOCKET !=, "oob_server (%x): accept failed: %d\n" );
504 ok ( mem->sock[0].peer.sin_addr.s_addr == inet_addr ( gen->inet_addr ),
505 "oob_server (%x): strange peer address\n", id );
507 /* check atmark state */
508 ioctlsocket ( mem->sock[0].s, SIOCATMARK, &atmark );
509 ok ( atmark == 1, "oob_server (%x): unexpectedly at the OOB mark: %i\n", id, atmark );
511 /* Receive normal data and check atmark state */
512 n_recvd = do_synchronous_recv ( mem->sock[0].s, mem->sock[0].buf, n_expected, par->buflen );
513 ok ( n_recvd == n_expected,
514 "simple_server (%x): received less data than expected: %d of %d\n", id, n_recvd, n_expected );
515 pos = test_buffer ( mem->sock[0].buf, gen->chunk_size, gen->n_chunks );
516 ok ( pos == -1, "simple_server (%x): test pattern error: %d\n", id, pos);
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 /* Receive a part of the out-of-band data and check atmark state */
522 n_recvd = do_synchronous_recv ( mem->sock[0].s, mem->sock[0].buf, 8, par->buflen );
523 ok ( n_recvd == 8,
524 "oob_server (%x): received less data than expected: %d of %d\n", id, n_recvd, 8 );
525 n_expected -= 8;
527 ioctlsocket ( mem->sock[0].s, SIOCATMARK, &atmark );
528 todo_wine ok ( atmark == 0, "oob_server (%x): not at the OOB mark: %i\n", id, atmark );
530 /* Receive the rest of the out-of-band data and check atmark state */
531 do_synchronous_recv ( mem->sock[0].s, mem->sock[0].buf, n_expected, par->buflen );
533 ioctlsocket ( mem->sock[0].s, SIOCATMARK, &atmark );
534 todo_wine ok ( atmark == 0, "oob_server (%x): not at the OOB mark: %i\n", id, atmark );
536 /* cleanup */
537 wsa_ok ( closesocket ( mem->sock[0].s ), 0 ==, "oob_server (%x): closesocket error: %d\n" );
538 mem->sock[0].s = INVALID_SOCKET;
540 trace ( "oob_server (%x) exiting\n", id );
541 server_stop ();
545 * select_server: A non-blocking server.
547 static VOID WINAPI select_server ( server_params *par )
549 test_params *gen = par->general;
550 server_memory *mem;
551 int n_expected = gen->n_chunks * gen->chunk_size, tmp, i,
552 id = GetCurrentThreadId(), n_connections = 0, n_sent, n_recvd,
553 n_set, delta, n_ready;
554 struct timeval timeout = {0,10}; /* wait for 10 milliseconds */
555 fd_set fds_recv, fds_send, fds_openrecv, fds_opensend;
557 trace ( "select_server (%x) starting\n", id );
559 set_so_opentype ( FALSE ); /* non-overlapped */
560 server_start ( par );
561 mem = TlsGetValue ( tls );
563 wsa_ok ( set_blocking ( mem->s, FALSE ), 0 ==, "select_server (%x): failed to set blocking mode: %d\n");
564 wsa_ok ( listen ( mem->s, SOMAXCONN ), 0 ==, "select_server (%x): listen failed: %d\n");
566 trace ( "select_server (%x) ready\n", id );
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 trace ( "select_server (%x): accepting client connection\n", id );
592 /* accept a single connection */
593 tmp = sizeof ( mem->sock[n_connections].peer );
594 mem->sock[n_connections].s = accept ( mem->s, (struct sockaddr*) &mem->sock[n_connections].peer, &tmp );
595 wsa_ok ( mem->sock[n_connections].s, INVALID_SOCKET !=, "select_server (%x): accept() failed: %d\n" );
597 ok ( mem->sock[n_connections].peer.sin_addr.s_addr == inet_addr ( gen->inet_addr ),
598 "select_server (%x): strange peer address\n", id );
600 /* add to list of open connections */
601 FD_SET ( mem->sock[n_connections].s, &fds_openrecv );
602 FD_SET ( mem->sock[n_connections].s, &fds_opensend );
604 n_connections++;
607 /* handle open requests */
609 for ( i = 0; i < n_connections; i++ )
611 if ( FD_ISSET( mem->sock[i].s, &fds_recv ) ) {
612 n_set += 1;
614 if ( mem->sock[i].n_recvd < n_expected ) {
615 /* Receive data & check it */
616 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 );
617 ok ( n_recvd != SOCKET_ERROR, "select_server (%x): error in recv(): %d\n", id, WSAGetLastError() );
618 mem->sock[i].n_recvd += n_recvd;
620 if ( mem->sock[i].n_recvd == n_expected ) {
621 int pos = test_buffer ( mem->sock[i].buf, gen->chunk_size, gen->n_chunks );
622 ok ( pos == -1, "select_server (%x): test pattern error: %d\n", id, pos );
623 FD_CLR ( mem->sock[i].s, &fds_openrecv );
626 ok ( mem->sock[i].n_recvd <= n_expected, "select_server (%x): received too many bytes: %d\n", id, mem->sock[i].n_recvd );
630 /* only echo back what we've received */
631 delta = mem->sock[i].n_recvd - mem->sock[i].n_sent;
633 if ( FD_ISSET ( mem->sock[i].s, &fds_send ) ) {
634 n_set += 1;
636 if ( ( delta > 0 ) && ( mem->sock[i].n_sent < n_expected ) ) {
637 /* Echo data back */
638 n_sent = send ( mem->sock[i].s, mem->sock[i].buf + mem->sock[i].n_sent, min ( delta, par->buflen ), 0 );
639 ok ( n_sent != SOCKET_ERROR, "select_server (%x): error in send(): %d\n", id, WSAGetLastError() );
640 mem->sock[i].n_sent += n_sent;
642 if ( mem->sock[i].n_sent == n_expected ) {
643 FD_CLR ( mem->sock[i].s, &fds_opensend );
646 ok ( mem->sock[i].n_sent <= n_expected, "select_server (%x): sent too many bytes: %d\n", id, mem->sock[i].n_sent );
651 /* check that select returned the correct number of ready sockets */
652 ok ( ( n_set == n_ready ), "select_server (%x): select() returns wrong number of ready sockets\n", id );
654 /* check if all clients are done */
655 if ( ( fds_opensend.fd_count == 0 )
656 && ( fds_openrecv.fd_count == 1 ) /* initial socket that accepts clients */
657 && ( n_connections == min ( gen->n_clients, MAX_CLIENTS ) ) ) {
658 break;
662 for ( i = 0; i < min ( gen->n_clients, MAX_CLIENTS ); i++ )
664 /* cleanup */
665 read_zero_bytes ( mem->sock[i].s );
666 wsa_ok ( closesocket ( mem->sock[i].s ), 0 ==, "select_server (%x): closesocket error: %d\n" );
667 mem->sock[i].s = INVALID_SOCKET;
670 trace ( "select_server (%x) exiting\n", id );
671 server_stop ();
674 /**************** Clients ***************/
677 * simple_client: A very basic client doing synchronous IO.
679 static VOID WINAPI simple_client ( client_params *par )
681 test_params *gen = par->general;
682 client_memory *mem;
683 int pos, n_sent, n_recvd, n_expected = gen->n_chunks * gen->chunk_size, id;
685 id = GetCurrentThreadId();
686 trace ( "simple_client (%x): starting\n", id );
687 /* wait here because we want to call set_so_opentype before creating a socket */
688 WaitForSingleObject ( server_ready, INFINITE );
689 trace ( "simple_client (%x): server ready\n", id );
691 check_so_opentype ();
692 set_so_opentype ( FALSE ); /* non-overlapped */
693 client_start ( par );
694 mem = TlsGetValue ( tls );
696 /* Connect */
697 wsa_ok ( connect ( mem->s, (struct sockaddr*) &mem->addr, sizeof ( mem->addr ) ),
698 0 ==, "simple_client (%x): connect error: %d\n" );
699 ok ( set_blocking ( mem->s, TRUE ) == 0,
700 "simple_client (%x): failed to set blocking mode\n", id );
701 trace ( "simple_client (%x) connected\n", id );
703 /* send data to server */
704 n_sent = do_synchronous_send ( mem->s, mem->send_buf, n_expected, par->buflen );
705 ok ( n_sent == n_expected,
706 "simple_client (%x): sent less data than expected: %d of %d\n", id, n_sent, n_expected );
708 /* shutdown send direction */
709 wsa_ok ( shutdown ( mem->s, SD_SEND ), 0 ==, "simple_client (%x): shutdown failed: %d\n" );
711 /* Receive data echoed back & check it */
712 n_recvd = do_synchronous_recv ( mem->s, mem->recv_buf, n_expected, par->buflen );
713 ok ( n_recvd == n_expected,
714 "simple_client (%x): received less data than expected: %d of %d\n", id, n_recvd, n_expected );
716 /* check data */
717 pos = test_buffer ( mem->recv_buf, gen->chunk_size, gen->n_chunks );
718 ok ( pos == -1, "simple_client (%x): test pattern error: %d\n", id, pos);
720 /* cleanup */
721 read_zero_bytes ( mem->s );
722 trace ( "simple_client (%x) exiting\n", id );
723 client_stop ();
727 * oob_client: A very basic client sending out-of-band data.
729 static VOID WINAPI oob_client ( client_params *par )
731 test_params *gen = par->general;
732 client_memory *mem;
733 int n_sent, n_expected = gen->n_chunks * gen->chunk_size, id;
735 id = GetCurrentThreadId();
736 trace ( "oob_client (%x): starting\n", id );
737 /* wait here because we want to call set_so_opentype before creating a socket */
738 WaitForSingleObject ( server_ready, INFINITE );
739 trace ( "oob_client (%x): server ready\n", id );
741 check_so_opentype ();
742 set_so_opentype ( FALSE ); /* non-overlapped */
743 client_start ( par );
744 mem = TlsGetValue ( tls );
746 /* Connect */
747 wsa_ok ( connect ( mem->s, (struct sockaddr*) &mem->addr, sizeof ( mem->addr ) ),
748 0 ==, "oob_client (%x): connect error: %d\n" );
749 ok ( set_blocking ( mem->s, TRUE ) == 0,
750 "oob_client (%x): failed to set blocking mode\n", id );
751 trace ( "oob_client (%x) connected\n", id );
753 /* send data to server */
754 n_sent = do_synchronous_send ( mem->s, mem->send_buf, n_expected, par->buflen );
755 ok ( n_sent == n_expected,
756 "oob_client (%x): sent less data than expected: %d of %d\n", id, n_sent, n_expected );
758 /* send out-of-band data to server */
759 n_sent = do_oob_send ( mem->s, mem->send_buf, n_expected, par->buflen );
760 ok ( n_sent == n_expected,
761 "oob_client (%x): sent less data than expected: %d of %d\n", id, n_sent, n_expected );
763 /* shutdown send direction */
764 wsa_ok ( shutdown ( mem->s, SD_SEND ), 0 ==, "simple_client (%x): shutdown failed: %d\n" );
766 /* cleanup */
767 read_zero_bytes ( mem->s );
768 trace ( "oob_client (%x) exiting\n", id );
769 client_stop ();
773 * simple_mixed_client: mixing send and recvfrom
775 static VOID WINAPI simple_mixed_client ( client_params *par )
777 test_params *gen = par->general;
778 client_memory *mem;
779 int pos, n_sent, n_recvd, n_expected = gen->n_chunks * gen->chunk_size, id;
780 int fromLen = sizeof(mem->addr);
781 struct sockaddr test;
783 id = GetCurrentThreadId();
784 trace ( "simple_client (%x): starting\n", id );
785 /* wait here because we want to call set_so_opentype before creating a socket */
786 WaitForSingleObject ( server_ready, INFINITE );
787 trace ( "simple_client (%x): server ready\n", id );
789 check_so_opentype ();
790 set_so_opentype ( FALSE ); /* non-overlapped */
791 client_start ( par );
792 mem = TlsGetValue ( tls );
794 /* Connect */
795 wsa_ok ( connect ( mem->s, (struct sockaddr*) &mem->addr, sizeof ( mem->addr ) ),
796 0 ==, "simple_client (%x): connect error: %d\n" );
797 ok ( set_blocking ( mem->s, TRUE ) == 0,
798 "simple_client (%x): failed to set blocking mode\n", id );
799 trace ( "simple_client (%x) connected\n", id );
801 /* send data to server */
802 n_sent = do_synchronous_send ( mem->s, mem->send_buf, n_expected, par->buflen );
803 ok ( n_sent == n_expected,
804 "simple_client (%x): sent less data than expected: %d of %d\n", id, n_sent, n_expected );
806 /* shutdown send direction */
807 wsa_ok ( shutdown ( mem->s, SD_SEND ), 0 ==, "simple_client (%x): shutdown failed: %d\n" );
809 /* this shouldn't change, since lpFrom, is not updated on
810 connection oriented sockets - exposed by bug 11640
812 ((struct sockaddr_in*)&test)->sin_addr.s_addr = inet_addr("0.0.0.0");
814 /* Receive data echoed back & check it */
815 n_recvd = do_synchronous_recvfrom ( mem->s,
816 mem->recv_buf,
817 n_expected,
819 (struct sockaddr *)&test,
820 &fromLen,
821 par->buflen );
822 ok ( n_recvd == n_expected,
823 "simple_client (%x): received less data than expected: %d of %d\n", id, n_recvd, n_expected );
825 /* check that lpFrom was not updated */
826 ok(0 ==
827 strcmp(
828 inet_ntoa(((struct sockaddr_in*)&test)->sin_addr),
829 "0.0.0.0"), "lpFrom shouldn't be updated on connection oriented sockets\n");
831 /* check data */
832 pos = test_buffer ( mem->recv_buf, gen->chunk_size, gen->n_chunks );
833 ok ( pos == -1, "simple_client (%x): test pattern error: %d\n", id, pos);
835 /* cleanup */
836 read_zero_bytes ( mem->s );
837 trace ( "simple_client (%x) exiting\n", id );
838 client_stop ();
842 * event_client: An event-driven client
844 static void WINAPI event_client ( client_params *par )
846 test_params *gen = par->general;
847 client_memory *mem;
848 int id = GetCurrentThreadId(), n_expected = gen->n_chunks * gen->chunk_size,
849 tmp, err, n;
850 HANDLE event;
851 WSANETWORKEVENTS wsa_events;
852 char *send_last, *recv_last, *send_p, *recv_p;
853 LONG mask = FD_READ | FD_WRITE | FD_CLOSE;
855 trace ( "event_client (%x): starting\n", id );
856 client_start ( par );
857 trace ( "event_client (%x): server ready\n", id );
859 mem = TlsGetValue ( tls );
861 /* Prepare event notification for connect, makes socket nonblocking */
862 event = WSACreateEvent ();
863 WSAEventSelect ( mem->s, event, FD_CONNECT );
864 tmp = connect ( mem->s, (struct sockaddr*) &mem->addr, sizeof ( mem->addr ) );
865 if ( tmp != 0 ) {
866 err = WSAGetLastError ();
867 ok ( err == WSAEWOULDBLOCK, "event_client (%x): connect error: %d\n", id, err );
868 tmp = WaitForSingleObject ( event, INFINITE );
869 ok ( tmp == WAIT_OBJECT_0, "event_client (%x): wait for connect event failed: %d\n", id, tmp );
870 err = WSAEnumNetworkEvents ( mem->s, event, &wsa_events );
871 ok ( err == 0, "event_client (%x): WSAEnumNetworkEvents error: %d\n", id, err );
872 err = wsa_events.iErrorCode[ FD_CONNECT_BIT ];
873 ok ( err == 0, "event_client (%x): connect error: %d\n", id, err );
874 if ( err ) goto out;
877 trace ( "event_client (%x) connected\n", id );
879 WSAEventSelect ( mem->s, event, mask );
881 recv_p = mem->recv_buf;
882 recv_last = mem->recv_buf + n_expected;
883 send_p = mem->send_buf;
884 send_last = mem->send_buf + n_expected;
886 while ( TRUE )
888 err = WaitForSingleObject ( event, INFINITE );
889 ok ( err == WAIT_OBJECT_0, "event_client (%x): wait failed\n", id );
891 err = WSAEnumNetworkEvents ( mem->s, event, &wsa_events );
892 ok( err == 0, "event_client (%x): WSAEnumNetworkEvents error: %d\n", id, err );
894 if ( wsa_events.lNetworkEvents & FD_WRITE )
896 err = wsa_events.iErrorCode[ FD_WRITE_BIT ];
897 ok ( err == 0, "event_client (%x): FD_WRITE error code: %d\n", id, err );
899 if ( err== 0 )
902 n = send ( mem->s, send_p, min ( send_last - send_p, par->buflen ), 0 );
903 if ( n < 0 )
905 err = WSAGetLastError ();
906 ok ( err == WSAEWOULDBLOCK, "event_client (%x): send error: %d\n", id, err );
908 else
909 send_p += n;
911 while ( n >= 0 && send_p < send_last );
913 if ( send_p == send_last )
915 trace ( "event_client (%x): all data sent - shutdown\n", id );
916 shutdown ( mem->s, SD_SEND );
917 mask &= ~FD_WRITE;
918 WSAEventSelect ( mem->s, event, mask );
921 if ( wsa_events.lNetworkEvents & FD_READ )
923 err = wsa_events.iErrorCode[ FD_READ_BIT ];
924 ok ( err == 0, "event_client (%x): FD_READ error code: %d\n", id, err );
925 if ( err != 0 ) break;
927 /* First read must succeed */
928 n = recv ( mem->s, recv_p, min ( recv_last - recv_p, par->buflen ), 0 );
929 wsa_ok ( n, 0 <=, "event_client (%x): recv error: %d\n" );
931 while ( n >= 0 ) {
932 recv_p += n;
933 if ( recv_p == recv_last )
935 mask &= ~FD_READ;
936 trace ( "event_client (%x): all data received\n", id );
937 WSAEventSelect ( mem->s, event, mask );
938 break;
940 n = recv ( mem->s, recv_p, min ( recv_last - recv_p, par->buflen ), 0 );
941 if ( n < 0 && ( err = WSAGetLastError()) != WSAEWOULDBLOCK )
942 ok ( 0, "event_client (%x): read error: %d\n", id, err );
946 if ( wsa_events.lNetworkEvents & FD_CLOSE )
948 trace ( "event_client (%x): close event\n", id );
949 err = wsa_events.iErrorCode[ FD_CLOSE_BIT ];
950 ok ( err == 0, "event_client (%x): FD_CLOSE error code: %d\n", id, err );
951 break;
955 n = send_p - mem->send_buf;
956 ok ( send_p == send_last,
957 "simple_client (%x): sent less data than expected: %d of %d\n", id, n, n_expected );
958 n = recv_p - mem->recv_buf;
959 ok ( recv_p == recv_last,
960 "simple_client (%x): received less data than expected: %d of %d\n", id, n, n_expected );
961 n = test_buffer ( mem->recv_buf, gen->chunk_size, gen->n_chunks );
962 ok ( n == -1, "event_client (%x): test pattern error: %d\n", id, n);
964 out:
965 WSACloseEvent ( event );
966 trace ( "event_client (%x) exiting\n", id );
967 client_stop ();
970 /* Tests for WSAStartup */
971 static void test_WithoutWSAStartup(void)
973 LPVOID ptr;
975 WSASetLastError(0xdeadbeef);
976 ptr = gethostbyname("localhost");
978 ok(ptr == NULL, "gethostbyname() succeeded unexpectedly: %d\n", WSAGetLastError());
979 ok(WSAGetLastError() == WSANOTINITIALISED, "gethostbyname() failed with unexpected error: %d\n",
980 WSAGetLastError());
983 static void test_WithWSAStartup(void)
985 WSADATA data;
986 WORD version = MAKEWORD( 2, 2 );
987 INT res;
988 LPVOID ptr;
990 res = WSAStartup( version, &data );
991 ok(res == 0, "WSAStartup() failed unexpectedly: %d\n", res);
993 ptr = gethostbyname("localhost");
994 ok(ptr != NULL, "gethostbyname() failed unexpectedly: %d\n", WSAGetLastError());
996 WSACleanup();
999 /**************** Main program utility functions ***************/
1001 static void Init (void)
1003 WORD ver = MAKEWORD (2, 2);
1004 WSADATA data;
1005 HMODULE hws2_32 = GetModuleHandle("ws2_32.dll");
1007 pfreeaddrinfo = (void *)GetProcAddress(hws2_32, "freeaddrinfo");
1008 pgetaddrinfo = (void *)GetProcAddress(hws2_32, "getaddrinfo");
1009 pFreeAddrInfoW = (void *)GetProcAddress(hws2_32, "FreeAddrInfoW");
1010 pGetAddrInfoW = (void *)GetProcAddress(hws2_32, "GetAddrInfoW");
1011 pInetNtop = (void *)GetProcAddress(hws2_32, "inet_ntop");
1013 ok ( WSAStartup ( ver, &data ) == 0, "WSAStartup failed\n" );
1014 tls = TlsAlloc();
1017 static void Exit (void)
1019 INT ret, err;
1020 TlsFree ( tls );
1021 ret = WSACleanup();
1022 err = WSAGetLastError();
1023 ok ( ret == 0, "WSACleanup failed ret = %d GetLastError is %d\n", ret, err);
1024 ret = WSACleanup();
1025 err = WSAGetLastError();
1026 ok ( (ret == SOCKET_ERROR && err == WSANOTINITIALISED) ||
1027 broken(ret == 0), /* WinME */
1028 "WSACleanup returned %d GetLastError is %d\n", ret, err);
1031 static void StartServer (LPTHREAD_START_ROUTINE routine,
1032 test_params *general, server_params *par)
1034 par->general = general;
1035 thread[0] = CreateThread ( NULL, 0, routine, par, 0, &thread_id[0] );
1036 ok ( thread[0] != NULL, "Failed to create server thread\n" );
1039 static void StartClients (LPTHREAD_START_ROUTINE routine,
1040 test_params *general, client_params *par)
1042 int i;
1043 par->general = general;
1044 for ( i = 1; i <= min ( general->n_clients, MAX_CLIENTS ); i++ )
1046 client_id = i - 1;
1047 thread[i] = CreateThread ( NULL, 0, routine, par, 0, &thread_id[i] );
1048 ok ( thread[i] != NULL, "Failed to create client thread\n" );
1049 /* Make sure the client is up and running */
1050 WaitForSingleObject ( client_ready[client_id], INFINITE );
1054 static void do_test( test_setup *test )
1056 DWORD i, n = min (test->general.n_clients, MAX_CLIENTS);
1057 DWORD wait;
1059 server_ready = CreateEventA ( NULL, TRUE, FALSE, NULL );
1060 for (i = 0; i <= n; i++)
1061 client_ready[i] = CreateEventA ( NULL, TRUE, FALSE, NULL );
1063 StartServer ( test->srv, &test->general, &test->srv_params );
1064 StartClients ( test->clt, &test->general, &test->clt_params );
1065 WaitForSingleObject ( server_ready, INFINITE );
1067 wait = WaitForMultipleObjects ( 1 + n, thread, TRUE, 1000 * TEST_TIMEOUT );
1068 ok ( wait <= WAIT_OBJECT_0 + n ,
1069 "some threads have not completed: %x\n", wait );
1071 if ( ! ( wait <= WAIT_OBJECT_0 + n ) )
1073 for (i = 0; i <= n; i++)
1075 if ( WaitForSingleObject ( thread[i], 0 ) != WAIT_OBJECT_0 )
1077 trace ("terminating thread %08x\n", thread_id[i]);
1078 TerminateThread ( thread [i], 0 );
1082 CloseHandle ( server_ready );
1083 for (i = 0; i <= n; i++)
1084 CloseHandle ( client_ready[i] );
1087 /********* some tests for getsockopt(setsockopt(X)) == X ***********/
1088 /* optname = SO_LINGER */
1089 static const LINGER linger_testvals[] = {
1090 {0,0},
1091 {0,73},
1092 {1,0},
1093 {5,189}
1096 /* optname = SO_RCVTIMEO, SOSNDTIMEO */
1097 #define SOCKTIMEOUT1 63000 /* 63 seconds. Do not test fractional part because of a
1098 bug in the linux kernel (fixed in 2.6.8) */
1099 #define SOCKTIMEOUT2 997000 /* 997 seconds */
1101 static void test_set_getsockopt(void)
1103 SOCKET s;
1104 int i, err, lasterr;
1105 int timeout;
1106 LINGER lingval;
1107 int size;
1109 s = socket(AF_INET, SOCK_STREAM, 0);
1110 ok(s!=INVALID_SOCKET, "socket() failed error: %d\n", WSAGetLastError());
1111 if( s == INVALID_SOCKET) return;
1112 /* SO_RCVTIMEO */
1113 timeout = SOCKTIMEOUT1;
1114 size = sizeof(timeout);
1115 err = setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char *) &timeout, size);
1116 if( !err)
1117 err = getsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char *) &timeout, &size);
1118 ok( !err, "get/setsockopt(SO_RCVTIMEO) failed error: %d\n", WSAGetLastError());
1119 ok( timeout == SOCKTIMEOUT1, "getsockopt(SO_RCVTIMEO) returned wrong value %d\n", timeout);
1121 timeout = 0;
1122 size = sizeof(timeout);
1123 err = setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char *) &timeout, size);
1124 if( !err)
1125 err = getsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char *) &timeout, &size);
1126 ok( !err, "get/setsockopt(SO_RCVTIMEO) failed error: %d\n", WSAGetLastError());
1127 ok( timeout == 0, "getsockopt(SO_RCVTIMEO) returned wrong value %d\n", timeout);
1129 /* SO_SNDTIMEO */
1130 timeout = SOCKTIMEOUT2; /* 997 seconds. See remark above */
1131 size = sizeof(timeout);
1132 err = setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, (char *) &timeout, size);
1133 if( !err)
1134 err = getsockopt(s, SOL_SOCKET, SO_SNDTIMEO, (char *) &timeout, &size);
1135 ok( !err, "get/setsockopt(SO_SNDTIMEO) failed error: %d\n", WSAGetLastError());
1136 ok( timeout == SOCKTIMEOUT2, "getsockopt(SO_SNDTIMEO) returned wrong value %d\n", timeout);
1137 /* SO_LINGER */
1138 for( i = 0; i < sizeof(linger_testvals)/sizeof(LINGER);i++) {
1139 size = sizeof(lingval);
1140 lingval = linger_testvals[i];
1141 err = setsockopt(s, SOL_SOCKET, SO_LINGER, (char *) &lingval, size);
1142 if( !err)
1143 err = getsockopt(s, SOL_SOCKET, SO_LINGER, (char *) &lingval, &size);
1144 ok( !err, "get/setsockopt(SO_LINGER) failed error: %d\n", WSAGetLastError());
1145 ok( !lingval.l_onoff == !linger_testvals[i].l_onoff &&
1146 (lingval.l_linger == linger_testvals[i].l_linger ||
1147 (!lingval.l_linger && !linger_testvals[i].l_onoff))
1148 , "getsockopt(SO_LINGER #%d) returned wrong value %d,%d not %d,%d\n", i,
1149 lingval.l_onoff, lingval.l_linger,
1150 linger_testvals[i].l_onoff, linger_testvals[i].l_linger);
1153 size = sizeof(lingval);
1154 err = setsockopt(s, SOL_SOCKET, SO_LINGER, NULL, size);
1155 ok(err == SOCKET_ERROR && WSAGetLastError() == WSAEFAULT,
1156 "got %d with %d (expected SOCKET_ERROR with WSAEFAULT)\n", err, WSAGetLastError());
1157 err = setsockopt(s, SOL_SOCKET, SO_LINGER, NULL, 0);
1158 ok(err == SOCKET_ERROR && WSAGetLastError() == WSAEFAULT,
1159 "got %d with %d (expected SOCKET_ERROR with WSAEFAULT)\n", err, WSAGetLastError());
1161 size = sizeof(BOOL);
1162 err = setsockopt(s, SOL_SOCKET, SO_DONTLINGER, NULL, size);
1163 ok(err == SOCKET_ERROR && WSAGetLastError() == WSAEFAULT,
1164 "got %d with %d (expected SOCKET_ERROR with WSAEFAULT)\n", err, WSAGetLastError());
1165 err = setsockopt(s, SOL_SOCKET, SO_DONTLINGER, NULL, 0);
1166 ok(err == SOCKET_ERROR && WSAGetLastError() == WSAEFAULT,
1167 "got %d with %d (expected SOCKET_ERROR with WSAEFAULT)\n", err, WSAGetLastError());
1169 /* Test for erroneously passing a value instead of a pointer as optval */
1170 size = sizeof(char);
1171 err = setsockopt(s, SOL_SOCKET, SO_DONTROUTE, (char *)1, size);
1172 ok(err == SOCKET_ERROR, "setsockopt with optval being a value passed "
1173 "instead of failing.\n");
1174 lasterr = WSAGetLastError();
1175 ok(lasterr == WSAEFAULT, "setsockopt with optval being a value "
1176 "returned 0x%08x, not WSAEFAULT(0x%08x)\n",
1177 lasterr, WSAEFAULT);
1179 /* SO_RCVTIMEO with invalid values for level */
1180 size = sizeof(timeout);
1181 timeout = SOCKTIMEOUT1;
1182 SetLastError(0xdeadbeef);
1183 err = setsockopt(s, 0xffffffff, SO_RCVTIMEO, (char *) &timeout, size);
1184 ok( (err == SOCKET_ERROR) && (WSAGetLastError() == WSAEINVAL),
1185 "got %d with %d (expected SOCKET_ERROR with WSAEINVAL)\n",
1186 err, WSAGetLastError());
1188 timeout = SOCKTIMEOUT1;
1189 SetLastError(0xdeadbeef);
1190 err = setsockopt(s, 0x00008000, SO_RCVTIMEO, (char *) &timeout, size);
1191 ok( (err == SOCKET_ERROR) && (WSAGetLastError() == WSAEINVAL),
1192 "got %d with %d (expected SOCKET_ERROR with WSAEINVAL)\n",
1193 err, WSAGetLastError());
1195 /* Test SO_ERROR set/get */
1196 SetLastError(0xdeadbeef);
1197 i = 1234;
1198 err = setsockopt(s, SOL_SOCKET, SO_ERROR, (char *) &i, size);
1199 todo_wine
1200 ok( !err && !WSAGetLastError(),
1201 "got %d with %d (expected 0 with 0)\n",
1202 err, WSAGetLastError());
1204 SetLastError(0xdeadbeef);
1205 i = 4321;
1206 err = getsockopt(s, SOL_SOCKET, SO_ERROR, (char *) &i, &size);
1207 todo_wine
1208 ok( !err && !WSAGetLastError(),
1209 "got %d with %d (expected 0 with 0)\n",
1210 err, WSAGetLastError());
1211 todo_wine
1212 ok (i == 1234, "got %d (expected 1234)\n", i);
1214 /* Test invalid optlen */
1215 SetLastError(0xdeadbeef);
1216 size = 1;
1217 err = getsockopt(s, SOL_SOCKET, SO_ERROR, (char *) &i, &size);
1218 todo_wine
1219 ok( (err == SOCKET_ERROR) && (WSAGetLastError() == WSAEFAULT),
1220 "got %d with %d (expected SOCKET_ERROR with WSAEFAULT)\n",
1221 err, WSAGetLastError());
1223 closesocket(s);
1226 static void test_so_reuseaddr(void)
1228 struct sockaddr_in saddr;
1229 SOCKET s1,s2;
1230 unsigned int rc,reuse;
1231 int size;
1233 saddr.sin_family = AF_INET;
1234 saddr.sin_port = htons(9375);
1235 saddr.sin_addr.s_addr = inet_addr("127.0.0.1");
1237 s1=socket(AF_INET, SOCK_STREAM, 0);
1238 ok(s1!=INVALID_SOCKET, "socket() failed error: %d\n", WSAGetLastError());
1239 rc = bind(s1, (struct sockaddr*)&saddr, sizeof(saddr));
1240 ok(rc!=SOCKET_ERROR, "bind(s1) failed error: %d\n", WSAGetLastError());
1242 s2=socket(AF_INET, SOCK_STREAM, 0);
1243 ok(s2!=INVALID_SOCKET, "socket() failed error: %d\n", WSAGetLastError());
1245 reuse=0x1234;
1246 size=sizeof(reuse);
1247 rc=getsockopt(s2, SOL_SOCKET, SO_REUSEADDR, (char*)&reuse, &size );
1248 ok(rc==0 && reuse==0,"wrong result in getsockopt(SO_REUSEADDR): rc=%d reuse=%d\n",rc,reuse);
1250 rc = bind(s2, (struct sockaddr*)&saddr, sizeof(saddr));
1251 ok(rc==SOCKET_ERROR, "bind() succeeded\n");
1253 reuse = 1;
1254 rc = setsockopt(s2, SOL_SOCKET, SO_REUSEADDR, (char*)&reuse, sizeof(reuse));
1255 ok(rc==0, "setsockopt() failed error: %d\n", WSAGetLastError());
1257 /* On Win2k3 and above, all SO_REUSEADDR seems to do is to allow binding to
1258 * a port immediately after closing another socket on that port, so
1259 * basically following the BSD socket semantics here. */
1260 closesocket(s1);
1261 rc = bind(s2, (struct sockaddr*)&saddr, sizeof(saddr));
1262 ok(rc==0, "bind() failed error: %d\n", WSAGetLastError());
1264 closesocket(s2);
1267 #define IP_PKTINFO_LEN (sizeof(WSACMSGHDR) + WSA_CMSG_ALIGN(sizeof(struct in_pktinfo)))
1269 static void test_ip_pktinfo(void)
1271 ULONG addresses[2] = {inet_addr("127.0.0.1"), htonl(INADDR_ANY)};
1272 char recvbuf[10], pktbuf[512], msg[] = "HELLO";
1273 struct sockaddr_in s1addr, s2addr, s3addr;
1274 GUID WSARecvMsg_GUID = WSAID_WSARECVMSG;
1275 LPFN_WSARECVMSG pWSARecvMsg = NULL;
1276 unsigned int rc, foundhdr, yes = 1;
1277 DWORD dwBytes, dwSize, dwFlags;
1278 socklen_t addrlen;
1279 WSACMSGHDR *cmsg;
1280 WSAOVERLAPPED ov;
1281 WSABUF iovec[1];
1282 SOCKET s1, s2;
1283 WSAMSG hdr;
1284 int i, err;
1286 memset(&ov, 0, sizeof(ov));
1287 ov.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
1288 if (ov.hEvent == INVALID_HANDLE_VALUE)
1290 skip("Could not create event object, some tests will be skipped. errno = %d\n", GetLastError());
1291 return;
1294 memset(&hdr, 0x00, sizeof(hdr));
1295 s1addr.sin_family = AF_INET;
1296 s1addr.sin_port = htons(0);
1297 /* Note: s1addr.sin_addr is set below */
1298 iovec[0].buf = recvbuf;
1299 iovec[0].len = sizeof(recvbuf);
1300 hdr.name = (struct sockaddr*)&s3addr;
1301 hdr.namelen = sizeof(s3addr);
1302 hdr.lpBuffers = &iovec[0];
1303 hdr.dwBufferCount = 1;
1304 hdr.Control.buf = pktbuf;
1305 /* Note: hdr.Control.len is set below */
1306 hdr.dwFlags = 0;
1308 for (i=0;i<sizeof(addresses)/sizeof(UINT32);i++)
1310 s1addr.sin_addr.s_addr = addresses[i];
1312 /* Build "server" side socket */
1313 s1=socket(AF_INET, SOCK_DGRAM, 0);
1314 if (s1 == INVALID_SOCKET)
1316 skip("socket() failed error, some tests skipped: %d\n", WSAGetLastError());
1317 goto cleanup;
1320 /* Obtain the WSARecvMsg function */
1321 WSAIoctl(s1, SIO_GET_EXTENSION_FUNCTION_POINTER, &WSARecvMsg_GUID, sizeof(WSARecvMsg_GUID),
1322 &pWSARecvMsg, sizeof(pWSARecvMsg), &dwBytes, NULL, NULL);
1323 if (!pWSARecvMsg)
1325 win_skip("WSARecvMsg is unsupported, some tests will be skipped.\n");
1326 closesocket(s1);
1327 goto cleanup;
1330 /* Setup the server side socket */
1331 rc=bind(s1, (struct sockaddr*)&s1addr, sizeof(s1addr));
1332 ok(rc != SOCKET_ERROR, "bind() failed error: %d\n", WSAGetLastError());
1333 rc=setsockopt(s1, IPPROTO_IP, IP_PKTINFO, (const char*)&yes, sizeof(yes));
1334 ok(rc == 0, "failed to set IPPROTO_IP flag IP_PKTINFO!\n");
1336 /* Build "client" side socket */
1337 addrlen = sizeof(s2addr);
1338 if (getsockname(s1, (struct sockaddr *) &s2addr, &addrlen) != 0)
1340 skip("Failed to call getsockname, some tests skipped: %d\n", WSAGetLastError());
1341 closesocket(s1);
1342 goto cleanup;
1344 s2addr.sin_addr.s_addr = addresses[0]; /* Always target the local adapter address */
1345 s2=socket(AF_INET, SOCK_DGRAM, 0);
1346 if (s2 == INVALID_SOCKET)
1348 skip("socket() failed error, some tests skipped: %d\n", WSAGetLastError());
1349 closesocket(s1);
1350 goto cleanup;
1353 /* Test an empty message header */
1354 rc=pWSARecvMsg(s1, NULL, NULL, NULL, NULL);
1355 err=WSAGetLastError();
1356 ok(rc == SOCKET_ERROR && err == WSAEFAULT, "WSARecvMsg() failed error: %d (ret = %d)\n", err, rc);
1359 * Send a packet from the client to the server and test for specifying
1360 * a short control header.
1362 rc=sendto(s2, msg, sizeof(msg), 0, (struct sockaddr*)&s2addr, sizeof(s2addr));
1363 ok(rc == sizeof(msg), "sendto() failed error: %d\n", WSAGetLastError());
1364 hdr.Control.len = 1;
1365 rc=pWSARecvMsg(s1, &hdr, &dwSize, NULL, NULL);
1366 err=WSAGetLastError();
1367 ok(rc == SOCKET_ERROR && err == WSAEMSGSIZE && (hdr.dwFlags & MSG_CTRUNC),
1368 "WSARecvMsg() failed error: %d (ret: %d, flags: %d)\n", err, rc, hdr.dwFlags);
1369 hdr.dwFlags = 0; /* Reset flags */
1371 /* Perform another short control header test, this time with an overlapped receive */
1372 hdr.Control.len = 1;
1373 rc=pWSARecvMsg(s1, &hdr, NULL, &ov, NULL);
1374 err=WSAGetLastError();
1375 ok(rc != 0 && err == WSA_IO_PENDING, "WSARecvMsg() failed error: %d\n", err);
1376 rc=sendto(s2, msg, sizeof(msg), 0, (struct sockaddr*)&s2addr, sizeof(s2addr));
1377 ok(rc == sizeof(msg), "sendto() failed error: %d\n", WSAGetLastError());
1378 if (WaitForSingleObject(ov.hEvent, 100) != WAIT_OBJECT_0)
1380 skip("Server side did not receive packet, some tests skipped.\n");
1381 closesocket(s2);
1382 closesocket(s1);
1383 continue;
1385 dwFlags = 0;
1386 WSAGetOverlappedResult(s1, &ov, NULL, FALSE, &dwFlags);
1387 ok(dwFlags == 0,
1388 "WSAGetOverlappedResult() returned unexpected flags %d!\n", dwFlags);
1389 ok(hdr.dwFlags == MSG_CTRUNC,
1390 "WSARecvMsg() overlapped operation set unexpected flags %d.\n", hdr.dwFlags);
1391 hdr.dwFlags = 0; /* Reset flags */
1394 * Setup an overlapped receive, send a packet, then wait for the packet to be retrieved
1395 * on the server end and check that the returned packet matches what was sent.
1397 hdr.Control.len = sizeof(pktbuf);
1398 rc=pWSARecvMsg(s1, &hdr, NULL, &ov, NULL);
1399 err=WSAGetLastError();
1400 ok(rc != 0 && err == WSA_IO_PENDING, "WSARecvMsg() failed error: %d\n", err);
1401 ok(hdr.Control.len == sizeof(pktbuf),
1402 "WSARecvMsg() control length mismatch (%d != sizeof pktbuf).\n", hdr.Control.len);
1403 rc=sendto(s2, msg, sizeof(msg), 0, (struct sockaddr*)&s2addr, sizeof(s2addr));
1404 ok(rc == sizeof(msg), "sendto() failed error: %d\n", WSAGetLastError());
1405 if (WaitForSingleObject(ov.hEvent, 100) != WAIT_OBJECT_0)
1407 skip("Server side did not receive packet, some tests skipped.\n");
1408 closesocket(s2);
1409 closesocket(s1);
1410 continue;
1412 dwSize = 0;
1413 WSAGetOverlappedResult(s1, &ov, &dwSize, FALSE, NULL);
1414 ok(dwSize == sizeof(msg),
1415 "WSARecvMsg() buffer length does not match transmitted data!\n");
1416 ok(strncmp(iovec[0].buf, msg, sizeof(msg)) == 0,
1417 "WSARecvMsg() buffer does not match transmitted data!\n");
1418 ok(hdr.Control.len == IP_PKTINFO_LEN,
1419 "WSARecvMsg() control length mismatch (%d).\n", hdr.Control.len);
1421 /* Test for the expected IP_PKTINFO return information. */
1422 foundhdr = FALSE;
1423 for (cmsg = WSA_CMSG_FIRSTHDR(&hdr); cmsg != NULL; cmsg = WSA_CMSG_NXTHDR(&hdr, cmsg))
1425 if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO)
1427 struct in_pktinfo *pi = (struct in_pktinfo *)WSA_CMSG_DATA(cmsg);
1429 ok(pi->ipi_addr.s_addr == s2addr.sin_addr.s_addr, "destination ip mismatch!\n");
1430 foundhdr = TRUE;
1433 ok(foundhdr, "IP_PKTINFO header information was not returned!\n");
1435 closesocket(s2);
1436 closesocket(s1);
1439 cleanup:
1440 CloseHandle(ov.hEvent);
1443 /************* Array containing the tests to run **********/
1445 #define STD_STREAM_SOCKET \
1446 SOCK_STREAM, \
1447 0, \
1448 SERVERIP, \
1449 SERVERPORT
1451 static test_setup tests [] =
1453 /* Test 0: synchronous client and server */
1456 STD_STREAM_SOCKET,
1457 2048,
1461 simple_server,
1463 NULL,
1467 simple_client,
1469 NULL,
1474 /* Test 1: event-driven client, synchronous server */
1477 STD_STREAM_SOCKET,
1478 2048,
1482 simple_server,
1484 NULL,
1488 event_client,
1490 NULL,
1491 WSA_FLAG_OVERLAPPED,
1495 /* Test 2: synchronous client, non-blocking server via select() */
1498 STD_STREAM_SOCKET,
1499 2048,
1503 select_server,
1505 NULL,
1509 simple_client,
1511 NULL,
1516 /* Test 3: OOB client, OOB server */
1519 STD_STREAM_SOCKET,
1520 128,
1524 oob_server,
1526 NULL,
1530 oob_client,
1532 NULL,
1537 /* Test 4: synchronous mixed client and server */
1540 STD_STREAM_SOCKET,
1541 2048,
1545 simple_server,
1547 NULL,
1551 simple_mixed_client,
1553 NULL,
1560 static void test_UDP(void)
1562 /* This function tests UDP sendto() and recvfrom(). UDP is unreliable, so it is
1563 possible that this test fails due to dropped packets. */
1565 /* peer 0 receives data from all other peers */
1566 struct sock_info peer[NUM_UDP_PEERS];
1567 char buf[16];
1568 int ss, i, n_recv, n_sent;
1570 memset (buf,0,sizeof(buf));
1571 for ( i = NUM_UDP_PEERS - 1; i >= 0; i-- ) {
1572 ok ( ( peer[i].s = socket ( AF_INET, SOCK_DGRAM, 0 ) ) != INVALID_SOCKET, "UDP: socket failed\n" );
1574 peer[i].addr.sin_family = AF_INET;
1575 peer[i].addr.sin_addr.s_addr = inet_addr ( SERVERIP );
1577 if ( i == 0 ) {
1578 peer[i].addr.sin_port = htons ( SERVERPORT );
1579 } else {
1580 peer[i].addr.sin_port = htons ( 0 );
1583 do_bind ( peer[i].s, (struct sockaddr *) &peer[i].addr, sizeof( peer[i].addr ) );
1585 /* test getsockname() to get peer's port */
1586 ss = sizeof ( peer[i].addr );
1587 ok ( getsockname ( peer[i].s, (struct sockaddr *) &peer[i].addr, &ss ) != SOCKET_ERROR, "UDP: could not getsockname()\n" );
1588 ok ( peer[i].addr.sin_port != htons ( 0 ), "UDP: bind() did not associate port\n" );
1591 /* test getsockname() */
1592 ok ( peer[0].addr.sin_port == htons ( SERVERPORT ), "UDP: getsockname returned incorrect peer port\n" );
1594 for ( i = 1; i < NUM_UDP_PEERS; i++ ) {
1595 /* send client's ip */
1596 memcpy( buf, &peer[i].addr.sin_port, sizeof(peer[i].addr.sin_port) );
1597 n_sent = sendto ( peer[i].s, buf, sizeof(buf), 0, (struct sockaddr*) &peer[0].addr, sizeof(peer[0].addr) );
1598 ok ( n_sent == sizeof(buf), "UDP: sendto() sent wrong amount of data or socket error: %d\n", n_sent );
1601 for ( i = 1; i < NUM_UDP_PEERS; i++ ) {
1602 n_recv = recvfrom ( peer[0].s, buf, sizeof(buf), 0,(struct sockaddr *) &peer[0].peer, &ss );
1603 ok ( n_recv == sizeof(buf), "UDP: recvfrom() received wrong amount of data or socket error: %d\n", n_recv );
1604 ok ( memcmp ( &peer[0].peer.sin_port, buf, sizeof(peer[0].addr.sin_port) ) == 0, "UDP: port numbers do not match\n" );
1608 static DWORD WINAPI do_getservbyname( void *param )
1610 struct {
1611 const char *name;
1612 const char *proto;
1613 int port;
1614 } serv[2] = { {"domain", "udp", 53}, {"telnet", "tcp", 23} };
1616 HANDLE *starttest = param;
1617 int i, j;
1618 struct servent *pserv[2];
1620 ok ( WaitForSingleObject ( *starttest, TEST_TIMEOUT * 1000 ) != WAIT_TIMEOUT, "test_getservbyname: timeout waiting for start signal\n");
1622 /* ensure that necessary buffer resizes are completed */
1623 for ( j = 0; j < 2; j++) {
1624 pserv[j] = getservbyname ( serv[j].name, serv[j].proto );
1627 for ( i = 0; i < NUM_QUERIES / 2; i++ ) {
1628 for ( j = 0; j < 2; j++ ) {
1629 pserv[j] = getservbyname ( serv[j].name, serv[j].proto );
1630 ok ( pserv[j] != NULL, "getservbyname could not retrieve information for %s: %d\n", serv[j].name, WSAGetLastError() );
1631 if ( !pserv[j] ) continue;
1632 ok ( pserv[j]->s_port == htons(serv[j].port), "getservbyname returned the wrong port for %s: %d\n", serv[j].name, ntohs(pserv[j]->s_port) );
1633 ok ( !strcmp ( pserv[j]->s_proto, serv[j].proto ), "getservbyname returned the wrong protocol for %s: %s\n", serv[j].name, pserv[j]->s_proto );
1634 ok ( !strcmp ( pserv[j]->s_name, serv[j].name ), "getservbyname returned the wrong name for %s: %s\n", serv[j].name, pserv[j]->s_name );
1637 ok ( pserv[0] == pserv[1], "getservbyname: winsock resized servent buffer when not necessary\n" );
1640 return 0;
1643 static void test_getservbyname(void)
1645 int i;
1646 HANDLE starttest, thread[NUM_THREADS];
1647 DWORD thread_id[NUM_THREADS];
1649 starttest = CreateEvent ( NULL, 1, 0, "test_getservbyname_starttest" );
1651 /* create threads */
1652 for ( i = 0; i < NUM_THREADS; i++ ) {
1653 thread[i] = CreateThread ( NULL, 0, do_getservbyname, &starttest, 0, &thread_id[i] );
1656 /* signal threads to start */
1657 SetEvent ( starttest );
1659 for ( i = 0; i < NUM_THREADS; i++) {
1660 WaitForSingleObject ( thread[i], TEST_TIMEOUT * 1000 );
1664 static void test_WSASocket(void)
1666 SOCKET sock = INVALID_SOCKET;
1667 WSAPROTOCOL_INFOA *pi;
1668 int providers[] = {6, 0};
1669 int ret, err;
1670 UINT pi_size;
1672 /* Set pi_size explicitly to a value below 2*sizeof(WSAPROTOCOL_INFOA)
1673 * to avoid a crash on win98.
1675 pi_size = 0;
1676 ret = WSAEnumProtocolsA(providers, NULL, &pi_size);
1677 ok(ret == SOCKET_ERROR, "WSAEnumProtocolsA({6,0}, NULL, 0) returned %d\n",
1678 ret);
1679 err = WSAGetLastError();
1680 ok(err == WSAENOBUFS, "WSAEnumProtocolsA error is %d, not WSAENOBUFS(%d)\n",
1681 err, WSAENOBUFS);
1683 pi = HeapAlloc(GetProcessHeap(), 0, pi_size);
1684 ok(pi != NULL, "Failed to allocate memory\n");
1685 if (pi == NULL) {
1686 skip("Can't continue without memory.\n");
1687 return;
1690 ret = WSAEnumProtocolsA(providers, pi, &pi_size);
1691 ok(ret != SOCKET_ERROR, "WSAEnumProtocolsA failed, last error is %d\n",
1692 WSAGetLastError());
1694 if (ret == 0) {
1695 skip("No protocols enumerated.\n");
1696 HeapFree(GetProcessHeap(), 0, pi);
1697 return;
1700 sock = WSASocketA(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO,
1701 FROM_PROTOCOL_INFO, &pi[0], 0, 0);
1702 ok(sock != INVALID_SOCKET, "Failed to create socket: %d\n",
1703 WSAGetLastError());
1705 closesocket(sock);
1706 HeapFree(GetProcessHeap(), 0, pi);
1709 static void test_WSAAddressToStringA(void)
1711 SOCKET v6 = INVALID_SOCKET;
1712 INT ret;
1713 DWORD len;
1714 int GLE;
1715 SOCKADDR_IN sockaddr;
1716 CHAR address[22]; /* 12 digits + 3 dots + ':' + 5 digits + '\0' */
1718 CHAR expect1[] = "0.0.0.0";
1719 CHAR expect2[] = "255.255.255.255";
1720 CHAR expect3[] = "0.0.0.0:65535";
1721 CHAR expect4[] = "255.255.255.255:65535";
1723 SOCKADDR_IN6 sockaddr6;
1724 CHAR address6[54]; /* 32 digits + 7':' + '[' + '%" + 5 digits + ']:' + 5 digits + '\0' */
1726 CHAR addr6_1[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01};
1727 CHAR addr6_2[] = {0x20,0xab,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01};
1728 CHAR addr6_3[] = {0x20,0xab,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x01};
1730 CHAR expect6_1[] = "::1";
1731 CHAR expect6_2[] = "20ab::1";
1732 CHAR expect6_3[] = "[20ab::2001]:33274";
1733 CHAR expect6_3_nt[] = "20ab::2001@33274";
1734 CHAR expect6_3_w2k[] = "20ab::2001";
1735 CHAR expect6_3_2[] = "[20ab::2001%4660]:33274";
1736 CHAR expect6_3_2_nt[] = "4660/20ab::2001@33274";
1737 CHAR expect6_3_2_w2k[] = "20ab::2001%4660";
1738 CHAR expect6_3_3[] = "20ab::2001%4660";
1739 CHAR expect6_3_3_nt[] = "4660/20ab::2001";
1741 len = 0;
1743 sockaddr.sin_family = AF_INET;
1744 sockaddr.sin_port = 0;
1745 sockaddr.sin_addr.s_addr = 0;
1747 ret = WSAAddressToStringA( (SOCKADDR*)&sockaddr, sizeof(sockaddr), NULL, address, &len );
1748 GLE = WSAGetLastError();
1749 ok( (ret == SOCKET_ERROR && GLE == WSAEFAULT) || (ret == 0),
1750 "WSAAddressToStringA() failed unexpectedly: WSAGetLastError()=%d, ret=%d\n",
1751 GLE, ret );
1753 len = sizeof(address);
1755 sockaddr.sin_family = AF_INET;
1756 sockaddr.sin_port = 0;
1757 sockaddr.sin_addr.s_addr = 0;
1759 ret = WSAAddressToStringA( (SOCKADDR*)&sockaddr, sizeof(sockaddr), NULL, address, &len );
1760 ok( !ret, "WSAAddressToStringA() failed unexpectedly: %d\n", WSAGetLastError() );
1762 ok( !strcmp( address, expect1 ), "Expected: %s, got: %s\n", expect1, address );
1763 ok( len == sizeof( expect1 ), "Got size %d\n", len);
1765 len = sizeof(address);
1767 sockaddr.sin_family = AF_INET;
1768 sockaddr.sin_port = 0;
1769 sockaddr.sin_addr.s_addr = 0xffffffff;
1771 ret = WSAAddressToStringA( (SOCKADDR*)&sockaddr, sizeof(sockaddr), NULL, address, &len );
1772 ok( !ret, "WSAAddressToStringA() failed unexpectedly: %d\n", WSAGetLastError() );
1774 ok( !strcmp( address, expect2 ), "Expected: %s, got: %s\n", expect2, address );
1776 len = sizeof(address);
1778 sockaddr.sin_family = AF_INET;
1779 sockaddr.sin_port = 0xffff;
1780 sockaddr.sin_addr.s_addr = 0;
1782 ret = WSAAddressToStringA( (SOCKADDR*)&sockaddr, sizeof(sockaddr), NULL, address, &len );
1783 ok( !ret, "WSAAddressToStringA() failed unexpectedly: %d\n", WSAGetLastError() );
1785 ok( !strcmp( address, expect3 ), "Expected: %s, got: %s\n", expect3, address );
1787 len = sizeof(address);
1789 sockaddr.sin_family = AF_INET;
1790 sockaddr.sin_port = 0xffff;
1791 sockaddr.sin_addr.s_addr = 0xffffffff;
1793 ret = WSAAddressToStringA( (SOCKADDR*)&sockaddr, sizeof(sockaddr), NULL, address, &len );
1794 ok( !ret, "WSAAddressToStringA() failed unexpectedly: %d\n", WSAGetLastError() );
1796 ok( !strcmp( address, expect4 ), "Expected: %s, got: %s\n", expect4, address );
1797 ok( len == sizeof( expect4 ), "Got size %d\n", len);
1799 /*check to see it IPv6 is available */
1800 v6 = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
1801 if (v6 == INVALID_SOCKET) {
1802 skip("Could not create IPv6 socket (LastError: %d; %d expected if IPv6 not available).\n",
1803 WSAGetLastError(), WSAEAFNOSUPPORT);
1804 goto end;
1806 /* Test a short IPv6 address */
1807 len = sizeof(address6);
1809 sockaddr6.sin6_family = AF_INET6;
1810 sockaddr6.sin6_port = 0x0000;
1811 sockaddr6.sin6_scope_id = 0;
1812 memcpy (sockaddr6.sin6_addr.s6_addr, addr6_1, sizeof(addr6_1));
1814 ret = WSAAddressToStringA( (SOCKADDR*)&sockaddr6, sizeof(sockaddr6), NULL, address6, &len );
1815 ok( !ret, "WSAAddressToStringA() failed unexpectedly: %d\n", WSAGetLastError() );
1816 ok( !strcmp( address6, expect6_1 ), "Expected: %s, got: %s\n", expect6_1, address6 );
1817 ok( len == sizeof(expect6_1), "Got size %d\n", len);
1819 /* Test a longer IPv6 address */
1820 len = sizeof(address6);
1822 sockaddr6.sin6_family = AF_INET6;
1823 sockaddr6.sin6_port = 0x0000;
1824 sockaddr6.sin6_scope_id = 0;
1825 memcpy (sockaddr6.sin6_addr.s6_addr, addr6_2, sizeof(addr6_2));
1827 ret = WSAAddressToStringA( (SOCKADDR*)&sockaddr6, sizeof(sockaddr6), NULL, address6, &len );
1828 ok( !ret, "WSAAddressToStringA() failed unexpectedly: %d\n", WSAGetLastError() );
1829 ok( !strcmp( address6, expect6_2 ), "Expected: %s, got: %s\n", expect6_2, address6 );
1830 ok( len == sizeof(expect6_2), "Got size %d\n", len);
1832 /* Test IPv6 address and port number */
1833 len = sizeof(address6);
1835 sockaddr6.sin6_family = AF_INET6;
1836 sockaddr6.sin6_port = 0xfa81;
1837 sockaddr6.sin6_scope_id = 0;
1838 memcpy (sockaddr6.sin6_addr.s6_addr, addr6_3, sizeof(addr6_3));
1840 ret = WSAAddressToStringA( (SOCKADDR*)&sockaddr6, sizeof(sockaddr6), NULL, address6, &len );
1841 ok( !ret, "WSAAddressToStringA() failed unexpectedly: %d\n", WSAGetLastError() );
1842 ok( !strcmp( address6, expect6_3 ) ||
1843 broken( !strcmp( address6, expect6_3_nt ) ) || /* NT4 */
1844 broken( !strcmp( address6, expect6_3_w2k ) ), /* Win2000 */
1845 "Expected: %s, got: %s\n", expect6_3, address6 );
1846 ok( len == sizeof(expect6_3) ||
1847 broken( len == sizeof(expect6_3_nt) ) || /* NT4 */
1848 broken( len == sizeof(expect6_3_w2k) ), /* Win2000 */
1849 "Got size %d\n", len);
1851 /* Test IPv6 address, port number and scope_id */
1852 len = sizeof(address6);
1854 sockaddr6.sin6_family = AF_INET6;
1855 sockaddr6.sin6_port = 0xfa81;
1856 sockaddr6.sin6_scope_id = 0x1234;
1857 memcpy (sockaddr6.sin6_addr.s6_addr, addr6_3, sizeof(addr6_3));
1859 ret = WSAAddressToStringA( (SOCKADDR*)&sockaddr6, sizeof(sockaddr6), NULL, address6, &len );
1860 ok( !ret, "WSAAddressToStringA() failed unexpectedly: %d\n", WSAGetLastError() );
1861 ok( !strcmp( address6, expect6_3_2 ) ||
1862 broken( !strcmp( address6, expect6_3_2_nt ) ) || /* NT4 */
1863 broken( !strcmp( address6, expect6_3_2_w2k ) ), /* Win2000 */
1864 "Expected: %s, got: %s\n", expect6_3_2, address6 );
1865 ok( len == sizeof(expect6_3_2) ||
1866 broken( len == sizeof(expect6_3_2_nt) ) || /* NT4 */
1867 broken( len == sizeof(expect6_3_2_w2k) ), /* Win2000 */
1868 "Got size %d\n", len);
1870 /* Test IPv6 address and scope_id */
1871 len = sizeof(address6);
1873 sockaddr6.sin6_family = AF_INET6;
1874 sockaddr6.sin6_port = 0x0000;
1875 sockaddr6.sin6_scope_id = 0x1234;
1876 memcpy (sockaddr6.sin6_addr.s6_addr, addr6_3, sizeof(addr6_3));
1878 ret = WSAAddressToStringA( (SOCKADDR*)&sockaddr6, sizeof(sockaddr6), NULL, address6, &len );
1879 ok( !ret, "WSAAddressToStringA() failed unexpectedly: %d\n", WSAGetLastError() );
1880 ok( !strcmp( address6, expect6_3_3 ) ||
1881 broken( !strcmp( address6, expect6_3_3_nt ) ), /* NT4 */
1882 "Expected: %s, got: %s\n", expect6_3_3, address6 );
1883 ok( len == sizeof(expect6_3_3) ||
1884 broken( len == sizeof(expect6_3_3_nt) ), /* NT4 */
1885 "Got size %d\n", len);
1887 end:
1888 if (v6 != INVALID_SOCKET)
1889 closesocket(v6);
1892 static void test_WSAAddressToStringW(void)
1894 SOCKET v6 = INVALID_SOCKET;
1895 INT ret;
1896 DWORD len;
1897 int GLE;
1898 SOCKADDR_IN sockaddr;
1899 WCHAR address[22]; /* 12 digits + 3 dots + ':' + 5 digits + '\0' */
1901 WCHAR expect1[] = { '0','.','0','.','0','.','0', 0 };
1902 WCHAR expect2[] = { '2','5','5','.','2','5','5','.','2','5','5','.','2','5','5', 0 };
1903 WCHAR expect3[] = { '0','.','0','.','0','.','0', ':', '6', '5', '5', '3', '5', 0 };
1904 WCHAR expect4[] = { '2','5','5','.','2','5','5','.','2','5','5','.','2','5','5', ':',
1905 '6', '5', '5', '3', '5', 0 };
1907 SOCKADDR_IN6 sockaddr6;
1908 WCHAR address6[54]; /* 32 digits + 7':' + '[' + '%" + 5 digits + ']:' + 5 digits + '\0' */
1910 CHAR addr6_1[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01};
1911 CHAR addr6_2[] = {0x20,0xab,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01};
1912 CHAR addr6_3[] = {0x20,0xab,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x01};
1914 WCHAR expect6_1[] = {':',':','1',0};
1915 WCHAR expect6_2[] = {'2','0','a','b',':',':','1',0};
1916 WCHAR expect6_3[] = {'[','2','0','a','b',':',':','2','0','0','1',']',':','3','3','2','7','4',0};
1917 WCHAR expect6_3_nt[] = {'2','0','a','b',':',':','2','0','0','1','@','3','3','2','7','4',0};
1918 WCHAR expect6_3_w2k[] = {'2','0','a','b',':',':','2','0','0','1',0};
1919 WCHAR expect6_3_2[] = {'[','2','0','a','b',':',':','2','0','0','1','%','4','6','6','0',']',':','3','3','2','7','4',0};
1920 WCHAR expect6_3_2_nt[] = {'4','6','6','0','/','2','0','a','b',':',':','2','0','0','1','@','3','3','2','7','4',0};
1921 WCHAR expect6_3_2_w2k[] = {'2','0','a','b',':',':','2','0','0','1','%','4','6','6','0',0};
1922 WCHAR expect6_3_3[] = {'2','0','a','b',':',':','2','0','0','1','%','6','5','5','3','4',0};
1923 WCHAR expect6_3_3_nt[] = {'6','5','5','3','4','/','2','0','a','b',':',':','2','0','0','1',0};
1925 len = 0;
1927 sockaddr.sin_family = AF_INET;
1928 sockaddr.sin_port = 0;
1929 sockaddr.sin_addr.s_addr = 0;
1931 ret = WSAAddressToStringW( (SOCKADDR*)&sockaddr, sizeof(sockaddr), NULL, address, &len );
1932 GLE = WSAGetLastError();
1933 ok( (ret == SOCKET_ERROR && GLE == WSAEFAULT) || (ret == 0),
1934 "WSAAddressToStringW() failed unexpectedly: WSAGetLastError()=%d, ret=%d\n",
1935 GLE, ret );
1937 len = sizeof(address);
1939 sockaddr.sin_family = AF_INET;
1940 sockaddr.sin_port = 0;
1941 sockaddr.sin_addr.s_addr = 0;
1943 ret = WSAAddressToStringW( (SOCKADDR*)&sockaddr, sizeof(sockaddr), NULL, address, &len );
1944 ok( !ret, "WSAAddressToStringW() failed unexpectedly: %d\n", WSAGetLastError() );
1946 ok( !lstrcmpW( address, expect1 ), "Expected different address string\n" );
1947 ok( len == sizeof( expect1 )/sizeof( WCHAR ), "Got size %d\n", len);
1949 len = sizeof(address);
1951 sockaddr.sin_family = AF_INET;
1952 sockaddr.sin_port = 0;
1953 sockaddr.sin_addr.s_addr = 0xffffffff;
1955 ret = WSAAddressToStringW( (SOCKADDR*)&sockaddr, sizeof(sockaddr), NULL, address, &len );
1956 ok( !ret, "WSAAddressToStringW() failed unexpectedly: %d\n", WSAGetLastError() );
1958 ok( !lstrcmpW( address, expect2 ), "Expected different address string\n" );
1960 len = sizeof(address);
1962 sockaddr.sin_family = AF_INET;
1963 sockaddr.sin_port = 0xffff;
1964 sockaddr.sin_addr.s_addr = 0;
1966 ret = WSAAddressToStringW( (SOCKADDR*)&sockaddr, sizeof(sockaddr), NULL, address, &len );
1967 ok( !ret, "WSAAddressToStringW() failed unexpectedly: %d\n", WSAGetLastError() );
1969 ok( !lstrcmpW( address, expect3 ), "Expected different address string\n" );
1971 len = sizeof(address);
1973 sockaddr.sin_family = AF_INET;
1974 sockaddr.sin_port = 0xffff;
1975 sockaddr.sin_addr.s_addr = 0xffffffff;
1977 ret = WSAAddressToStringW( (SOCKADDR*)&sockaddr, sizeof(sockaddr), NULL, address, &len );
1978 ok( !ret, "WSAAddressToStringW() failed unexpectedly: %d\n", WSAGetLastError() );
1980 ok( !lstrcmpW( address, expect4 ), "Expected different address string\n" );
1981 ok( len == sizeof( expect4 )/sizeof( WCHAR ), "Got %d\n", len);
1983 /*check to see it IPv6 is available */
1984 v6 = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
1985 if (v6 == INVALID_SOCKET) {
1986 skip("Could not create IPv6 socket (LastError: %d; %d expected if IPv6 not available).\n",
1987 WSAGetLastError(), WSAEAFNOSUPPORT);
1988 goto end;
1991 /* Test a short IPv6 address */
1992 len = sizeof(address6)/sizeof(WCHAR);
1994 sockaddr6.sin6_family = AF_INET6;
1995 sockaddr6.sin6_port = 0x0000;
1996 sockaddr6.sin6_scope_id = 0;
1997 memcpy (sockaddr6.sin6_addr.s6_addr, addr6_1, sizeof(addr6_1));
1999 ret = WSAAddressToStringW( (SOCKADDR*)&sockaddr6, sizeof(sockaddr6), NULL, address6, &len );
2000 ok( !ret, "WSAAddressToStringW() failed unexpectedly: %d\n", WSAGetLastError() );
2001 ok( !lstrcmpW( address6, expect6_1 ), "Wrong string returned\n" );
2002 ok( len == sizeof(expect6_1)/sizeof(WCHAR), "Got %d\n", len);
2004 /* Test a longer IPv6 address */
2005 len = sizeof(address6)/sizeof(WCHAR);
2007 sockaddr6.sin6_family = AF_INET6;
2008 sockaddr6.sin6_port = 0x0000;
2009 sockaddr6.sin6_scope_id = 0;
2010 memcpy (sockaddr6.sin6_addr.s6_addr, addr6_2, sizeof(addr6_2));
2012 ret = WSAAddressToStringW( (SOCKADDR*)&sockaddr6, sizeof(sockaddr6), NULL, address6, &len );
2013 ok( !ret, "WSAAddressToStringW() failed unexpectedly: %d\n", WSAGetLastError() );
2015 ok( !lstrcmpW( address6, expect6_2 ), "Wrong string returned\n" );
2016 ok( len == sizeof(expect6_2)/sizeof(WCHAR), "Got %d\n", len);
2018 /* Test IPv6 address and port number */
2019 len = sizeof(address6)/sizeof(WCHAR);
2021 sockaddr6.sin6_family = AF_INET6;
2022 sockaddr6.sin6_port = 0xfa81;
2023 sockaddr6.sin6_scope_id = 0;
2024 memcpy (sockaddr6.sin6_addr.s6_addr, addr6_3, sizeof(addr6_3));
2026 ret = WSAAddressToStringW( (SOCKADDR*)&sockaddr6, sizeof(sockaddr6), NULL, address6, &len );
2027 ok( !ret, "WSAAddressToStringW() failed unexpectedly: %d\n", WSAGetLastError() );
2028 ok( !lstrcmpW( address6, expect6_3 ) ||
2029 broken( !lstrcmpW( address6, expect6_3_nt ) ) || /* NT4 */
2030 broken( !lstrcmpW( address6, expect6_3_w2k ) ), /* Win2000 */
2031 "Expected: %s, got: %s\n", wine_dbgstr_w(expect6_3),
2032 wine_dbgstr_w(address6) );
2033 ok( len == sizeof(expect6_3)/sizeof(WCHAR) ||
2034 broken(len == sizeof(expect6_3_nt)/sizeof(WCHAR) ) || /* NT4 */
2035 broken(len == sizeof(expect6_3_w2k)/sizeof(WCHAR) ), /* Win2000 */
2036 "Got %d\n", len);
2038 /* Test IPv6 address, port number and scope_id */
2039 len = sizeof(address6)/sizeof(WCHAR);
2041 sockaddr6.sin6_family = AF_INET6;
2042 sockaddr6.sin6_port = 0xfa81;
2043 sockaddr6.sin6_scope_id = 0x1234;
2044 memcpy (sockaddr6.sin6_addr.s6_addr, addr6_3, sizeof(addr6_3));
2046 ret = WSAAddressToStringW( (SOCKADDR*)&sockaddr6, sizeof(sockaddr6), NULL, address6, &len );
2047 ok( !ret, "WSAAddressToStringW() failed unexpectedly: %d\n", WSAGetLastError() );
2048 ok( !lstrcmpW( address6, expect6_3_2 ) ||
2049 broken( !lstrcmpW( address6, expect6_3_2_nt ) ) || /* NT4 */
2050 broken( !lstrcmpW( address6, expect6_3_2_w2k ) ), /* Win2000 */
2051 "Expected: %s, got: %s\n", wine_dbgstr_w(expect6_3_2),
2052 wine_dbgstr_w(address6) );
2053 ok( len == sizeof(expect6_3_2)/sizeof(WCHAR) ||
2054 broken( len == sizeof(expect6_3_2_nt)/sizeof(WCHAR) ) || /* NT4 */
2055 broken( len == sizeof(expect6_3_2_w2k)/sizeof(WCHAR) ), /* Win2000 */
2056 "Got %d\n", len);
2058 /* Test IPv6 address and scope_id */
2059 len = sizeof(address6)/sizeof(WCHAR);
2061 sockaddr6.sin6_family = AF_INET6;
2062 sockaddr6.sin6_port = 0x0000;
2063 sockaddr6.sin6_scope_id = 0xfffe;
2064 memcpy (sockaddr6.sin6_addr.s6_addr, addr6_3, sizeof(addr6_3));
2066 ret = WSAAddressToStringW( (SOCKADDR*)&sockaddr6, sizeof(sockaddr6), NULL, address6, &len );
2067 ok( !ret, "WSAAddressToStringW() failed unexpectedly: %d\n", WSAGetLastError() );
2068 ok( !lstrcmpW( address6, expect6_3_3 ) ||
2069 broken( !lstrcmpW( address6, expect6_3_3_nt ) ), /* NT4 */
2070 "Expected: %s, got: %s\n", wine_dbgstr_w(expect6_3_3),
2071 wine_dbgstr_w(address6) );
2072 ok( len == sizeof(expect6_3_3)/sizeof(WCHAR) ||
2073 broken( len == sizeof(expect6_3_3_nt)/sizeof(WCHAR) ), /* NT4 */
2074 "Got %d\n", len);
2076 end:
2077 if (v6 != INVALID_SOCKET)
2078 closesocket(v6);
2081 static void test_WSAStringToAddressA(void)
2083 INT ret, len;
2084 SOCKADDR_IN sockaddr;
2085 SOCKADDR_IN6 sockaddr6;
2086 int GLE;
2088 CHAR address1[] = "0.0.0.0";
2089 CHAR address2[] = "127.127.127.127";
2090 CHAR address3[] = "255.255.255.255";
2091 CHAR address4[] = "127.127.127.127:65535";
2092 CHAR address5[] = "255.255.255.255:65535";
2093 CHAR address6[] = "::1";
2094 CHAR address7[] = "[::1]";
2095 CHAR address8[] = "[::1]:65535";
2097 len = 0;
2098 sockaddr.sin_family = AF_INET;
2100 ret = WSAStringToAddressA( address1, AF_INET, NULL, (SOCKADDR*)&sockaddr, &len );
2101 ok( ret == SOCKET_ERROR, "WSAStringToAddressA() succeeded unexpectedly: %d\n",
2102 WSAGetLastError() );
2104 len = sizeof(sockaddr);
2105 sockaddr.sin_port = 0;
2106 sockaddr.sin_addr.s_addr = 0;
2108 ret = WSAStringToAddressA( address1, AF_INET, NULL, (SOCKADDR*)&sockaddr, &len );
2109 ok( !ret && sockaddr.sin_addr.s_addr == 0,
2110 "WSAStringToAddressA() failed unexpectedly: %d\n", WSAGetLastError() );
2112 len = sizeof(sockaddr);
2113 sockaddr.sin_port = 0;
2114 sockaddr.sin_addr.s_addr = 0;
2116 ret = WSAStringToAddressA( address2, AF_INET, NULL, (SOCKADDR*)&sockaddr, &len );
2117 ok( !ret && sockaddr.sin_addr.s_addr == 0x7f7f7f7f,
2118 "WSAStringToAddressA() failed unexpectedly: %d\n", WSAGetLastError() );
2120 len = sizeof(sockaddr);
2121 sockaddr.sin_port = 0;
2122 sockaddr.sin_addr.s_addr = 0;
2124 ret = WSAStringToAddressA( address3, AF_INET, NULL, (SOCKADDR*)&sockaddr, &len );
2125 GLE = WSAGetLastError();
2126 ok( (ret == 0 && sockaddr.sin_addr.s_addr == 0xffffffff) ||
2127 (ret == SOCKET_ERROR && (GLE == ERROR_INVALID_PARAMETER || GLE == WSAEINVAL)),
2128 "WSAStringToAddressA() failed unexpectedly: %d\n", GLE );
2130 len = sizeof(sockaddr);
2131 sockaddr.sin_port = 0;
2132 sockaddr.sin_addr.s_addr = 0;
2134 ret = WSAStringToAddressA( address4, AF_INET, NULL, (SOCKADDR*)&sockaddr, &len );
2135 ok( !ret && sockaddr.sin_addr.s_addr == 0x7f7f7f7f && sockaddr.sin_port == 0xffff,
2136 "WSAStringToAddressA() failed unexpectedly: %d\n", WSAGetLastError() );
2138 len = sizeof(sockaddr);
2139 sockaddr.sin_port = 0;
2140 sockaddr.sin_addr.s_addr = 0;
2142 ret = WSAStringToAddressA( address5, AF_INET, NULL, (SOCKADDR*)&sockaddr, &len );
2143 GLE = WSAGetLastError();
2144 ok( (ret == 0 && sockaddr.sin_addr.s_addr == 0xffffffff && sockaddr.sin_port == 0xffff) ||
2145 (ret == SOCKET_ERROR && (GLE == ERROR_INVALID_PARAMETER || GLE == WSAEINVAL)),
2146 "WSAStringToAddressA() failed unexpectedly: %d\n", GLE );
2148 len = sizeof(sockaddr6);
2149 memset(&sockaddr6, 0, len);
2150 sockaddr6.sin6_family = AF_INET6;
2152 ret = WSAStringToAddressA( address6, AF_INET6, NULL, (SOCKADDR*)&sockaddr6,
2153 &len );
2154 GLE = WSAGetLastError();
2155 ok( ret == 0 || (ret == SOCKET_ERROR && GLE == WSAEINVAL),
2156 "WSAStringToAddressA() failed for IPv6 address: %d\n", GLE);
2158 len = sizeof(sockaddr6);
2159 memset(&sockaddr6, 0, len);
2160 sockaddr6.sin6_family = AF_INET6;
2162 ret = WSAStringToAddressA( address7, AF_INET6, NULL, (SOCKADDR*)&sockaddr6,
2163 &len );
2164 GLE = WSAGetLastError();
2165 ok( ret == 0 || (ret == SOCKET_ERROR && GLE == WSAEINVAL),
2166 "WSAStringToAddressA() failed for IPv6 address: %d\n", GLE);
2168 len = sizeof(sockaddr6);
2169 memset(&sockaddr6, 0, len);
2170 sockaddr6.sin6_family = AF_INET6;
2172 ret = WSAStringToAddressA( address8, AF_INET6, NULL, (SOCKADDR*)&sockaddr6,
2173 &len );
2174 GLE = WSAGetLastError();
2175 ok( (ret == 0 && sockaddr6.sin6_port == 0xffff) ||
2176 (ret == SOCKET_ERROR && GLE == WSAEINVAL),
2177 "WSAStringToAddressA() failed for IPv6 address: %d\n", GLE);
2181 static void test_WSAStringToAddressW(void)
2183 INT ret, len;
2184 SOCKADDR_IN sockaddr, *sin;
2185 SOCKADDR_IN6 sockaddr6;
2186 SOCKADDR_STORAGE sockaddr_storage;
2187 int GLE;
2189 WCHAR address1[] = { '0','.','0','.','0','.','0', 0 };
2190 WCHAR address2[] = { '1','2','7','.','1','2','7','.','1','2','7','.','1','2','7', 0 };
2191 WCHAR address3[] = { '2','5','5','.','2','5','5','.','2','5','5','.','2','5','5', 0 };
2192 WCHAR address4[] = { '1','2','7','.','1','2','7','.','1','2','7','.','1','2','7',
2193 ':', '6', '5', '5', '3', '5', 0 };
2194 WCHAR address5[] = { '2','5','5','.','2','5','5','.','2','5','5','.','2','5','5', ':',
2195 '6', '5', '5', '3', '5', 0 };
2196 WCHAR address6[] = {':',':','1','\0'};
2197 WCHAR address7[] = {'[',':',':','1',']','\0'};
2198 WCHAR address8[] = {'[',':',':','1',']',':','6','5','5','3','5','\0'};
2200 len = 0;
2201 sockaddr.sin_family = AF_INET;
2203 ret = WSAStringToAddressW( address1, AF_INET, NULL, (SOCKADDR*)&sockaddr, &len );
2204 ok( ret == SOCKET_ERROR, "WSAStringToAddressW() failed unexpectedly: %d\n",
2205 WSAGetLastError() );
2207 len = sizeof(sockaddr);
2208 sockaddr.sin_port = 0;
2209 sockaddr.sin_addr.s_addr = 0;
2211 ret = WSAStringToAddressW( address1, AF_INET, NULL, (SOCKADDR*)&sockaddr, &len );
2212 ok( !ret && sockaddr.sin_addr.s_addr == 0,
2213 "WSAStringToAddressW() failed unexpectedly: %d\n", WSAGetLastError() );
2215 len = sizeof(sockaddr);
2216 sockaddr.sin_port = 0;
2217 sockaddr.sin_addr.s_addr = 0;
2219 ret = WSAStringToAddressW( address2, AF_INET, NULL, (SOCKADDR*)&sockaddr, &len );
2220 ok( !ret && sockaddr.sin_addr.s_addr == 0x7f7f7f7f,
2221 "WSAStringToAddressW() failed unexpectedly: %d\n", WSAGetLastError() );
2223 len = sizeof(sockaddr);
2224 sockaddr.sin_port = 0;
2225 sockaddr.sin_addr.s_addr = 0;
2227 ret = WSAStringToAddressW( address3, AF_INET, NULL, (SOCKADDR*)&sockaddr, &len );
2228 GLE = WSAGetLastError();
2229 ok( (ret == 0 && sockaddr.sin_addr.s_addr == 0xffffffff) ||
2230 (ret == SOCKET_ERROR && (GLE == ERROR_INVALID_PARAMETER || GLE == WSAEINVAL)),
2231 "WSAStringToAddressW() failed unexpectedly: %d\n", GLE );
2233 len = sizeof(sockaddr);
2234 sockaddr.sin_port = 0;
2235 sockaddr.sin_addr.s_addr = 0;
2237 ret = WSAStringToAddressW( address4, AF_INET, NULL, (SOCKADDR*)&sockaddr, &len );
2238 ok( !ret && sockaddr.sin_addr.s_addr == 0x7f7f7f7f && sockaddr.sin_port == 0xffff,
2239 "WSAStringToAddressW() failed unexpectedly: %d\n", WSAGetLastError() );
2241 len = sizeof(sockaddr);
2242 sockaddr.sin_port = 0;
2243 sockaddr.sin_addr.s_addr = 0;
2245 ret = WSAStringToAddressW( address5, AF_INET, NULL, (SOCKADDR*)&sockaddr, &len );
2246 ok( (ret == 0 && sockaddr.sin_addr.s_addr == 0xffffffff && sockaddr.sin_port == 0xffff) ||
2247 (ret == SOCKET_ERROR && (GLE == ERROR_INVALID_PARAMETER || GLE == WSAEINVAL)),
2248 "WSAStringToAddressW() failed unexpectedly: %d\n", GLE );
2250 /* Test with a larger buffer than necessary */
2251 len = sizeof(sockaddr_storage);
2252 sin = (SOCKADDR_IN *)&sockaddr_storage;
2253 sin->sin_port = 0;
2254 sin->sin_addr.s_addr = 0;
2256 ret = WSAStringToAddressW( address5, AF_INET, NULL, (SOCKADDR*)sin, &len );
2257 ok( (ret == 0 && sin->sin_addr.s_addr == 0xffffffff && sin->sin_port == 0xffff) ||
2258 (ret == SOCKET_ERROR && (GLE == ERROR_INVALID_PARAMETER || GLE == WSAEINVAL)),
2259 "WSAStringToAddressW() failed unexpectedly: %d\n", GLE );
2260 ok( len == sizeof(SOCKADDR_IN) ||
2261 broken(len == sizeof(SOCKADDR_STORAGE)) /* NT4/2k */,
2262 "unexpected length %d\n", len );
2264 len = sizeof(sockaddr6);
2265 memset(&sockaddr6, 0, len);
2266 sockaddr6.sin6_family = AF_INET6;
2268 ret = WSAStringToAddressW( address6, AF_INET6, NULL, (SOCKADDR*)&sockaddr6,
2269 &len );
2270 GLE = WSAGetLastError();
2271 ok( ret == 0 || (ret == SOCKET_ERROR && GLE == WSAEINVAL),
2272 "WSAStringToAddressW() failed for IPv6 address: %d\n", GLE);
2274 len = sizeof(sockaddr6);
2275 memset(&sockaddr6, 0, len);
2276 sockaddr6.sin6_family = AF_INET6;
2278 ret = WSAStringToAddressW( address7, AF_INET6, NULL, (SOCKADDR*)&sockaddr6,
2279 &len );
2280 GLE = WSAGetLastError();
2281 ok( ret == 0 || (ret == SOCKET_ERROR && GLE == WSAEINVAL),
2282 "WSAStringToAddressW() failed for IPv6 address: %d\n", GLE);
2284 len = sizeof(sockaddr6);
2285 memset(&sockaddr6, 0, len);
2286 sockaddr6.sin6_family = AF_INET6;
2288 ret = WSAStringToAddressW( address8, AF_INET6, NULL, (SOCKADDR*)&sockaddr6,
2289 &len );
2290 GLE = WSAGetLastError();
2291 ok( (ret == 0 && sockaddr6.sin6_port == 0xffff) ||
2292 (ret == SOCKET_ERROR && GLE == WSAEINVAL),
2293 "WSAStringToAddressW() failed for IPv6 address: %d\n", GLE);
2297 static DWORD WINAPI SelectReadThread(void *param)
2299 select_thread_params *par = param;
2300 fd_set readfds;
2301 int ret;
2302 struct sockaddr_in addr;
2303 struct timeval select_timeout;
2305 FD_ZERO(&readfds);
2306 FD_SET(par->s, &readfds);
2307 select_timeout.tv_sec=5;
2308 select_timeout.tv_usec=0;
2309 addr.sin_family = AF_INET;
2310 addr.sin_addr.s_addr = inet_addr(SERVERIP);
2311 addr.sin_port = htons(SERVERPORT);
2313 do_bind(par->s, (struct sockaddr *)&addr, sizeof(addr));
2314 wsa_ok(listen(par->s, SOMAXCONN ), 0 ==, "SelectReadThread (%x): listen failed: %d\n");
2316 SetEvent(server_ready);
2317 ret = select(par->s+1, &readfds, NULL, NULL, &select_timeout);
2318 par->ReadKilled = (ret == 1);
2320 return 0;
2323 static void test_errors(void)
2325 SOCKET sock;
2326 SOCKADDR_IN SockAddr;
2327 int ret, err;
2329 WSASetLastError(NO_ERROR);
2330 sock = socket(PF_INET, SOCK_STREAM, 0);
2331 ok( (sock != INVALID_SOCKET), "socket failed unexpectedly: %d\n", WSAGetLastError() );
2332 memset(&SockAddr, 0, sizeof(SockAddr));
2333 SockAddr.sin_family = AF_INET;
2334 SockAddr.sin_port = htons(6924);
2335 SockAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
2337 ret = connect(sock, (PSOCKADDR)&SockAddr, sizeof(SockAddr));
2338 ok( (ret == SOCKET_ERROR), "expected SOCKET_ERROR, got: %d\n", ret );
2339 if (ret == SOCKET_ERROR)
2341 err = WSAGetLastError();
2342 ok( (err == WSAECONNREFUSED), "expected WSAECONNREFUSED, got: %d\n", err );
2346 TIMEVAL timeval;
2347 fd_set set = {1, {sock}};
2349 timeval.tv_sec = 0;
2350 timeval.tv_usec = 50000;
2352 ret = select(1, NULL, &set, NULL, &timeval);
2353 ok( (ret == 0), "expected 0 (timeout), got: %d\n", ret );
2356 ret = closesocket(sock);
2357 ok ( (ret == 0), "closesocket failed unexpectedly: %d\n", WSAGetLastError());
2360 static void test_select(void)
2362 SOCKET fdRead, fdWrite;
2363 fd_set readfds, writefds, exceptfds;
2364 unsigned int maxfd;
2365 int ret;
2366 char buffer;
2367 struct timeval select_timeout;
2368 select_thread_params thread_params;
2369 HANDLE thread_handle;
2370 DWORD id;
2372 fdRead = socket(AF_INET, SOCK_STREAM, 0);
2373 ok( (fdRead != INVALID_SOCKET), "socket failed unexpectedly: %d\n", WSAGetLastError() );
2374 fdWrite = socket(AF_INET, SOCK_STREAM, 0);
2375 ok( (fdWrite != INVALID_SOCKET), "socket failed unexpectedly: %d\n", WSAGetLastError() );
2377 FD_ZERO(&readfds);
2378 FD_ZERO(&writefds);
2379 FD_ZERO(&exceptfds);
2380 FD_SET(fdRead, &readfds);
2381 FD_SET(fdWrite, &writefds);
2382 FD_SET(fdRead, &exceptfds);
2383 FD_SET(fdWrite, &exceptfds);
2384 select_timeout.tv_sec=0;
2385 select_timeout.tv_usec=500;
2387 maxfd = fdRead;
2388 if (fdWrite > maxfd)
2389 maxfd = fdWrite;
2391 todo_wine {
2392 ret = select(maxfd+1, &readfds, &writefds, &exceptfds, &select_timeout);
2393 ok ( (ret == 0), "select should not return any socket handles\n");
2394 ok ( !FD_ISSET(fdRead, &readfds), "FD should not be set\n");
2396 ok ( !FD_ISSET(fdWrite, &writefds), "FD should not be set\n");
2398 ok ( !FD_ISSET(fdRead, &exceptfds), "FD should not be set\n");
2399 ok ( !FD_ISSET(fdWrite, &exceptfds), "FD should not be set\n");
2401 todo_wine {
2402 ok ((listen(fdWrite, SOMAXCONN) == SOCKET_ERROR), "listen did not fail\n");
2404 ret = closesocket(fdWrite);
2405 ok ( (ret == 0), "closesocket failed unexpectedly: %d\n", ret);
2407 thread_params.s = fdRead;
2408 thread_params.ReadKilled = FALSE;
2409 server_ready = CreateEventA(NULL, TRUE, FALSE, NULL);
2410 thread_handle = CreateThread (NULL, 0, SelectReadThread, &thread_params, 0, &id );
2411 ok ( (thread_handle != NULL), "CreateThread failed unexpectedly: %d\n", GetLastError());
2413 WaitForSingleObject (server_ready, INFINITE);
2414 Sleep(200);
2415 ret = closesocket(fdRead);
2416 ok ( (ret == 0), "closesocket failed unexpectedly: %d\n", ret);
2418 WaitForSingleObject (thread_handle, 1000);
2419 ok ( (thread_params.ReadKilled) ||
2420 broken(thread_params.ReadKilled == 0), /*Win98*/
2421 "closesocket did not wakeup select\n");
2422 ret = recv(fdRead, &buffer, 1, MSG_PEEK);
2423 ok( (ret == -1), "peek at closed socket expected -1 got %d\n", ret);
2425 /* Test selecting invalid handles */
2426 FD_ZERO(&readfds);
2427 FD_ZERO(&writefds);
2428 FD_ZERO(&exceptfds);
2430 SetLastError(0);
2431 ret = select(maxfd+1, 0, 0, 0, &select_timeout);
2432 ok ( (ret == SOCKET_ERROR), "expected SOCKET_ERROR, got %i\n", ret);
2433 ok ( WSAGetLastError() == WSAEINVAL, "expected WSAEINVAL, got %i\n", WSAGetLastError());
2435 SetLastError(0);
2436 ret = select(maxfd+1, &readfds, &writefds, &exceptfds, &select_timeout);
2437 ok ( (ret == SOCKET_ERROR), "expected SOCKET_ERROR, got %i\n", ret);
2438 ok ( WSAGetLastError() == WSAEINVAL, "expected WSAEINVAL, got %i\n", WSAGetLastError());
2440 FD_SET(INVALID_SOCKET, &readfds);
2441 SetLastError(0);
2442 ret = select(maxfd+1, &readfds, &writefds, &exceptfds, &select_timeout);
2443 ok ( (ret == SOCKET_ERROR), "expected SOCKET_ERROR, got %i\n", ret);
2444 ok ( WSAGetLastError() == WSAENOTSOCK, "expected WSAENOTSOCK, got %i\n", WSAGetLastError());
2445 ok ( !FD_ISSET(fdRead, &readfds), "FD should not be set\n");
2447 FD_ZERO(&readfds);
2448 FD_SET(INVALID_SOCKET, &writefds);
2449 SetLastError(0);
2450 ret = select(maxfd+1, &readfds, &writefds, &exceptfds, &select_timeout);
2451 ok ( (ret == SOCKET_ERROR), "expected SOCKET_ERROR, got %i\n", ret);
2452 ok ( WSAGetLastError() == WSAENOTSOCK, "expected WSAENOTSOCK, got %i\n", WSAGetLastError());
2453 ok ( !FD_ISSET(fdRead, &writefds), "FD should not be set\n");
2455 FD_ZERO(&writefds);
2456 FD_SET(INVALID_SOCKET, &exceptfds);
2457 SetLastError(0);
2458 ret = select(maxfd+1, &readfds, &writefds, &exceptfds, &select_timeout);
2459 ok ( (ret == SOCKET_ERROR), "expected SOCKET_ERROR, got %i\n", ret);
2460 ok ( WSAGetLastError() == WSAENOTSOCK, "expected WSAENOTSOCK, got %i\n", WSAGetLastError());
2461 ok ( !FD_ISSET(fdRead, &exceptfds), "FD should not be set\n");
2464 static DWORD WINAPI AcceptKillThread(void *param)
2466 select_thread_params *par = param;
2467 struct sockaddr_in address;
2468 int len = sizeof(address);
2469 SOCKET client_socket;
2471 SetEvent(server_ready);
2472 client_socket = accept(par->s, (struct sockaddr*) &address, &len);
2473 if (client_socket != INVALID_SOCKET)
2474 closesocket(client_socket);
2475 par->ReadKilled = (client_socket == INVALID_SOCKET);
2476 return 0;
2480 static int CALLBACK AlwaysDeferConditionFunc(LPWSABUF lpCallerId, LPWSABUF lpCallerData, LPQOS pQos,
2481 LPQOS lpGQOS, LPWSABUF lpCalleeId, LPWSABUF lpCalleeData,
2482 GROUP FAR * g, DWORD_PTR dwCallbackData)
2484 return CF_DEFER;
2487 static void test_accept(void)
2489 int ret;
2490 SOCKET server_socket = INVALID_SOCKET, accepted = INVALID_SOCKET, connector = INVALID_SOCKET;
2491 struct sockaddr_in address;
2492 int socklen;
2493 select_thread_params thread_params;
2494 HANDLE thread_handle = NULL;
2495 DWORD id;
2497 server_socket = socket(AF_INET, SOCK_STREAM, 0);
2498 if (server_socket == INVALID_SOCKET)
2500 trace("error creating server socket: %d\n", WSAGetLastError());
2501 goto done;
2504 memset(&address, 0, sizeof(address));
2505 address.sin_addr.s_addr = inet_addr("127.0.0.1");
2506 address.sin_family = AF_INET;
2507 ret = bind(server_socket, (struct sockaddr*) &address, sizeof(address));
2508 if (ret != 0)
2510 trace("error binding server socket: %d\n", WSAGetLastError());
2511 goto done;
2514 socklen = sizeof(address);
2515 ret = getsockname(server_socket, (struct sockaddr*)&address, &socklen);
2516 if (ret != 0) {
2517 skip("failed to lookup bind address, error %d\n", WSAGetLastError());
2518 goto done;
2521 ret = listen(server_socket, 5);
2522 if (ret != 0)
2524 trace("error making server socket listen: %d\n", WSAGetLastError());
2525 goto done;
2528 trace("Blocking accept next\n");
2530 connector = socket(AF_INET, SOCK_STREAM, 0);
2531 ok(connector != INVALID_SOCKET, "Failed to create connector socket, error %d\n", WSAGetLastError());
2533 ret = connect(connector, (struct sockaddr*)&address, sizeof(address));
2534 ok(ret == 0, "connecting to accepting socket failed, error %d\n", WSAGetLastError());
2536 accepted = WSAAccept(server_socket, NULL, NULL, AlwaysDeferConditionFunc, 0);
2537 ok(accepted == INVALID_SOCKET && WSAGetLastError() == WSATRY_AGAIN, "Failed to defer connection, %d\n", WSAGetLastError());
2539 accepted = accept(server_socket, NULL, 0);
2540 ok(accepted != INVALID_SOCKET, "Failed to accept deferred connection, error %d\n", WSAGetLastError());
2542 server_ready = CreateEventA(NULL, TRUE, FALSE, NULL);
2543 if (server_ready == INVALID_HANDLE_VALUE)
2545 trace("error creating event: %d\n", GetLastError());
2546 goto done;
2549 thread_params.s = server_socket;
2550 thread_params.ReadKilled = FALSE;
2551 thread_handle = CreateThread(NULL, 0, AcceptKillThread, &thread_params, 0, &id);
2552 if (thread_handle == NULL)
2554 trace("error creating thread: %d\n", GetLastError());
2555 goto done;
2558 WaitForSingleObject(server_ready, INFINITE);
2559 Sleep(200);
2560 ret = closesocket(server_socket);
2561 if (ret != 0)
2563 trace("closesocket failed: %d\n", WSAGetLastError());
2564 goto done;
2567 WaitForSingleObject(thread_handle, 1000);
2568 ok(thread_params.ReadKilled || broken(!thread_params.ReadKilled) /* Win98/ME, after accept */,
2569 "closesocket did not wakeup accept\n");
2571 done:
2572 if (accepted != INVALID_SOCKET)
2573 closesocket(accepted);
2574 if (connector != INVALID_SOCKET)
2575 closesocket(connector);
2576 if (thread_handle != NULL)
2577 CloseHandle(thread_handle);
2578 if (server_ready != INVALID_HANDLE_VALUE)
2579 CloseHandle(server_ready);
2580 if (server_socket != INVALID_SOCKET)
2581 closesocket(server_socket);
2584 static void test_extendedSocketOptions(void)
2586 WSADATA wsa;
2587 SOCKET sock;
2588 struct sockaddr_in sa;
2589 int sa_len = sizeof(struct sockaddr_in);
2590 int optval, optlen = sizeof(int), ret;
2591 BOOL bool_opt_val;
2592 LINGER linger_val;
2594 if(WSAStartup(MAKEWORD(2,0), &wsa)){
2595 trace("Winsock failed: %d. Aborting test\n", WSAGetLastError());
2596 return;
2599 memset(&sa, 0, sa_len);
2601 sa.sin_family = AF_INET;
2602 sa.sin_port = htons(0);
2603 sa.sin_addr.s_addr = htonl(INADDR_ANY);
2605 if((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP)) == INVALID_SOCKET) {
2606 trace("Creating the socket failed: %d\n", WSAGetLastError());
2607 WSACleanup();
2608 return;
2611 if(bind(sock, (struct sockaddr *) &sa, sa_len) < 0){
2612 trace("Failed to bind socket: %d\n", WSAGetLastError());
2613 closesocket(sock);
2614 WSACleanup();
2615 return;
2618 ret = getsockopt(sock, SOL_SOCKET, SO_MAX_MSG_SIZE, (char *)&optval, &optlen);
2620 ok(ret == 0, "getsockopt failed to query SO_MAX_MSG_SIZE, return value is 0x%08x\n", ret);
2621 ok((optval == 65507) || (optval == 65527),
2622 "SO_MAX_MSG_SIZE reported %d, expected 65507 or 65527\n", optval);
2624 /* IE 3 use 0xffffffff instead of SOL_SOCKET (0xffff) */
2625 SetLastError(0xdeadbeef);
2626 optval = 0xdeadbeef;
2627 optlen = sizeof(int);
2628 ret = getsockopt(sock, 0xffffffff, SO_MAX_MSG_SIZE, (char *)&optval, &optlen);
2629 ok( (ret == SOCKET_ERROR) && (WSAGetLastError() == WSAEINVAL),
2630 "got %d with %d and optval: 0x%x/%d (expected SOCKET_ERROR with WSAEINVAL)\n",
2631 ret, WSAGetLastError(), optval, optval);
2633 /* more invalid values for level */
2634 SetLastError(0xdeadbeef);
2635 optval = 0xdeadbeef;
2636 optlen = sizeof(int);
2637 ret = getsockopt(sock, 0x1234ffff, SO_MAX_MSG_SIZE, (char *)&optval, &optlen);
2638 ok( (ret == SOCKET_ERROR) && (WSAGetLastError() == WSAEINVAL),
2639 "got %d with %d and optval: 0x%x/%d (expected SOCKET_ERROR with WSAEINVAL)\n",
2640 ret, WSAGetLastError(), optval, optval);
2642 SetLastError(0xdeadbeef);
2643 optval = 0xdeadbeef;
2644 optlen = sizeof(int);
2645 ret = getsockopt(sock, 0x8000ffff, SO_MAX_MSG_SIZE, (char *)&optval, &optlen);
2646 ok( (ret == SOCKET_ERROR) && (WSAGetLastError() == WSAEINVAL),
2647 "got %d with %d and optval: 0x%x/%d (expected SOCKET_ERROR with WSAEINVAL)\n",
2648 ret, WSAGetLastError(), optval, optval);
2650 SetLastError(0xdeadbeef);
2651 optval = 0xdeadbeef;
2652 optlen = sizeof(int);
2653 ret = getsockopt(sock, 0x00008000, SO_MAX_MSG_SIZE, (char *)&optval, &optlen);
2654 ok( (ret == SOCKET_ERROR) && (WSAGetLastError() == WSAEINVAL),
2655 "got %d with %d and optval: 0x%x/%d (expected SOCKET_ERROR with WSAEINVAL)\n",
2656 ret, WSAGetLastError(), optval, optval);
2658 SetLastError(0xdeadbeef);
2659 optval = 0xdeadbeef;
2660 optlen = sizeof(int);
2661 ret = getsockopt(sock, 0x00000800, SO_MAX_MSG_SIZE, (char *)&optval, &optlen);
2662 ok( (ret == SOCKET_ERROR) && (WSAGetLastError() == WSAEINVAL),
2663 "got %d with %d and optval: 0x%x/%d (expected SOCKET_ERROR with WSAEINVAL)\n",
2664 ret, WSAGetLastError(), optval, optval);
2666 SetLastError(0xdeadbeef);
2667 optlen = sizeof(LINGER);
2668 ret = getsockopt(sock, SOL_SOCKET, SO_LINGER, (char *)&linger_val, &optlen);
2669 ok( (ret == SOCKET_ERROR) && (WSAGetLastError() == WSAENOPROTOOPT),
2670 "getsockopt should fail for UDP sockets setting last error to WSAENOPROTOOPT, got %d with %d\n",
2671 ret, WSAGetLastError());
2672 closesocket(sock);
2674 if((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_IP)) == INVALID_SOCKET) {
2675 trace("Creating the socket failed: %d\n", WSAGetLastError());
2676 WSACleanup();
2677 return;
2680 if(bind(sock, (struct sockaddr *) &sa, sa_len) < 0){
2681 trace("Failed to bind socket: %d\n", WSAGetLastError());
2682 closesocket(sock);
2683 WSACleanup();
2684 return;
2687 ret = getsockopt(sock, SOL_SOCKET, SO_LINGER, (char *)&linger_val, &optlen);
2688 ok(ret == 0, "getsockopt failed to query SO_LINGER, return value is 0x%08x\n", ret);
2690 optlen = sizeof(BOOL);
2691 ret = getsockopt(sock, SOL_SOCKET, SO_DONTLINGER, (char *)&bool_opt_val, &optlen);
2692 ok(ret == 0, "getsockopt failed to query SO_DONTLINGER, return value is 0x%08x\n", ret);
2693 ok((linger_val.l_onoff && !bool_opt_val) || (!linger_val.l_onoff && bool_opt_val),
2694 "Return value of SO_DONTLINGER is %d, but SO_LINGER returned l_onoff == %d.\n",
2695 bool_opt_val, linger_val.l_onoff);
2697 closesocket(sock);
2698 WSACleanup();
2701 static void test_getsockname(void)
2703 WSADATA wsa;
2704 SOCKET sock;
2705 struct sockaddr_in sa_set, sa_get;
2706 int sa_set_len = sizeof(struct sockaddr_in);
2707 int sa_get_len = sa_set_len;
2708 static const unsigned char null_padding[] = {0,0,0,0,0,0,0,0};
2709 int ret;
2711 if(WSAStartup(MAKEWORD(2,0), &wsa)){
2712 trace("Winsock failed: %d. Aborting test\n", WSAGetLastError());
2713 return;
2716 memset(&sa_set, 0, sa_set_len);
2718 sa_set.sin_family = AF_INET;
2719 sa_set.sin_port = htons(0);
2720 sa_set.sin_addr.s_addr = htonl(INADDR_ANY);
2722 if((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_IP)) == INVALID_SOCKET) {
2723 trace("Creating the socket failed: %d\n", WSAGetLastError());
2724 WSACleanup();
2725 return;
2728 sa_get = sa_set;
2729 if (getsockname(sock, (struct sockaddr*) &sa_get, &sa_get_len) == 0)
2730 ok(0, "getsockname on unbound socket should fail\n");
2731 else {
2732 ok(WSAGetLastError() == WSAEINVAL, "getsockname on unbound socket "
2733 "failed with %d, expected %d\n", WSAGetLastError(), WSAEINVAL);
2734 ok(memcmp(&sa_get, &sa_set, sizeof(sa_get)) == 0,
2735 "failed getsockname modified sockaddr when it shouldn't\n");
2738 if(bind(sock, (struct sockaddr *) &sa_set, sa_set_len) < 0){
2739 trace("Failed to bind socket: %d\n", WSAGetLastError());
2740 closesocket(sock);
2741 WSACleanup();
2742 return;
2745 if(getsockname(sock, (struct sockaddr *) &sa_get, &sa_get_len) != 0){
2746 trace("Failed to call getsockname: %d\n", WSAGetLastError());
2747 closesocket(sock);
2748 WSACleanup();
2749 return;
2752 ret = memcmp(sa_get.sin_zero, null_padding, 8);
2753 ok(ret == 0 || broken(ret != 0), /* NT4 */
2754 "getsockname did not zero the sockaddr_in structure\n");
2756 closesocket(sock);
2757 WSACleanup();
2760 static void test_dns(void)
2762 struct hostent *h;
2763 union memaddress
2765 char *chr;
2766 void *mem;
2767 } addr;
2768 char **ptr;
2769 int acount;
2771 h = gethostbyname("");
2772 ok(h != NULL, "gethostbyname(\"\") failed with %d\n", h_errno);
2774 /* Use an address with valid alias names if possible */
2775 h = gethostbyname("source.winehq.org");
2776 if(!h)
2778 skip("Can't test the hostent structure because gethostbyname failed\n");
2779 return;
2782 /* The returned struct must be allocated in a very strict way. First we need to
2783 * count how many aliases there are because they must be located right after
2784 * the struct hostent size. Knowing the amount of aliases we know the exact
2785 * location of the first IP returned. Rule valid for >= XP, for older OS's
2786 * it's somewhat the opposite. */
2787 addr.mem = h + 1;
2788 if(h->h_addr_list == addr.mem) /* <= W2K */
2790 win_skip("Skipping hostent tests since this OS is unsupported\n");
2791 return;
2794 ok(h->h_aliases == addr.mem,
2795 "hostent->h_aliases should be in %p, it is in %p\n", addr.mem, h->h_aliases);
2797 for(ptr = h->h_aliases, acount = 1; *ptr; ptr++) acount++;
2798 addr.chr += sizeof(*ptr) * acount;
2799 ok(h->h_addr_list == addr.mem,
2800 "hostent->h_addr_list should be in %p, it is in %p\n", addr.mem, h->h_addr_list);
2802 for(ptr = h->h_addr_list, acount = 1; *ptr; ptr++) acount++;
2804 addr.chr += sizeof(*ptr) * acount;
2805 ok(h->h_addr_list[0] == addr.mem,
2806 "hostent->h_addr_list[0] should be in %p, it is in %p\n", addr.mem, h->h_addr_list[0]);
2809 /* Our winsock headers don't define gethostname because it conflicts with the
2810 * definition in unistd.h. Define it here to get rid of the warning. */
2812 int WINAPI gethostname(char *name, int namelen);
2814 static void test_gethostbyname_hack(void)
2816 struct hostent *he;
2817 char name[256];
2818 static BYTE loopback[] = {127, 0, 0, 1};
2819 static BYTE magic_loopback[] = {127, 12, 34, 56};
2820 int ret;
2822 ret = gethostname(name, 256);
2823 ok(ret == 0, "gethostname() call failed: %d\n", WSAGetLastError());
2825 he = gethostbyname("localhost");
2826 ok(he != NULL, "gethostbyname(\"localhost\") failed: %d\n", h_errno);
2827 if(he)
2829 if(he->h_length != 4)
2831 skip("h_length is %d, not IPv4, skipping test.\n", he->h_length);
2832 return;
2835 ok(memcmp(he->h_addr_list[0], loopback, he->h_length) == 0,
2836 "gethostbyname(\"localhost\") returned %d.%d.%d.%d\n",
2837 he->h_addr_list[0][0], he->h_addr_list[0][1], he->h_addr_list[0][2],
2838 he->h_addr_list[0][3]);
2841 if(strcmp(name, "localhost") == 0)
2843 skip("hostname seems to be \"localhost\", skipping test.\n");
2844 return;
2847 he = NULL;
2848 he = gethostbyname(name);
2849 ok(he != NULL, "gethostbyname(\"%s\") failed: %d\n", name, h_errno);
2850 if(he)
2852 if(he->h_length != 4)
2854 skip("h_length is %d, not IPv4, skipping test.\n", he->h_length);
2855 return;
2858 if (he->h_addr_list[0][0] == 127)
2860 ok(memcmp(he->h_addr_list[0], magic_loopback, he->h_length) == 0,
2861 "gethostbyname(\"%s\") returned %d.%d.%d.%d not 127.12.34.56\n",
2862 name, he->h_addr_list[0][0], he->h_addr_list[0][1],
2863 he->h_addr_list[0][2], he->h_addr_list[0][3]);
2867 gethostbyname("nonexistent.winehq.org");
2868 /* Don't check for the return value, as some braindead ISPs will kindly
2869 * resolve nonexistent host names to addresses of the ISP's spam pages. */
2872 static void test_inet_addr(void)
2874 u_long addr;
2876 addr = inet_addr(NULL);
2877 ok(addr == INADDR_NONE, "inet_addr succeeded unexpectedly\n");
2880 static void test_addr_to_print(void)
2882 char dst[16];
2883 char dst6[64];
2884 const char * pdst;
2885 struct in_addr in;
2886 struct in6_addr in6;
2888 u_long addr0_Num = 0x00000000;
2889 PCSTR addr0_Str = "0.0.0.0";
2890 u_long addr1_Num = 0x20201015;
2891 PCSTR addr1_Str = "21.16.32.32";
2892 u_char addr2_Num[16] = {0,0,0,0,0,0,0,0,0,0,0xff,0xfe,0xcC,0x98,0xbd,0x74};
2893 PCSTR addr2_Str = "::fffe:cc98:bd74";
2894 u_char addr3_Num[16] = {0x20,0x30,0xa4,0xb1};
2895 PCSTR addr3_Str = "2030:a4b1::";
2896 u_char addr4_Num[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0xcC,0x98,0xbd,0x74};
2897 PCSTR addr4_Str = "::204.152.189.116";
2899 /* Test IPv4 addresses */
2900 in.s_addr = addr0_Num;
2902 pdst = inet_ntoa(*((struct in_addr*)&in.s_addr));
2903 ok(pdst != NULL, "inet_ntoa failed %s\n", dst);
2904 ok(!strcmp(pdst, addr0_Str),"Address %s != %s\n", pdst, addr0_Str);
2906 /* Test that inet_ntoa and inet_ntop return the same value */
2907 in.S_un.S_addr = addr1_Num;
2908 pdst = inet_ntoa(*((struct in_addr*)&in.s_addr));
2909 ok(pdst != NULL, "inet_ntoa failed %s\n", dst);
2910 ok(!strcmp(pdst, addr1_Str),"Address %s != %s\n", pdst, addr1_Str);
2912 /* InetNtop became available in Vista and Win2008 */
2913 if (!pInetNtop)
2915 win_skip("InetNtop not present, not executing tests\n");
2916 return;
2919 /* Second part of test */
2920 pdst = pInetNtop(AF_INET,(void*)&in.s_addr, dst, sizeof(dst));
2921 ok(pdst != NULL, "InetNtop failed %s\n", dst);
2922 ok(!strcmp(pdst, addr1_Str),"Address %s != %s\n", pdst, addr1_Str);
2924 /* Test invalid parm conditions */
2925 pdst = pInetNtop(1, (void*)&in.s_addr, dst, sizeof(dst));
2926 ok(pdst == NULL, "The pointer should not be returned (%p)\n", pdst);
2927 ok(WSAGetLastError() == WSAEAFNOSUPPORT, "Should be WSAEAFNOSUPPORT\n");
2929 /* Test Null destination */
2930 pdst = NULL;
2931 pdst = pInetNtop(AF_INET, (void*)&in.s_addr, NULL, sizeof(dst));
2932 ok(pdst == NULL, "The pointer should not be returned (%p)\n", pdst);
2933 ok(WSAGetLastError() == STATUS_INVALID_PARAMETER || WSAGetLastError() == WSAEINVAL /* Win7 */,
2934 "Should be STATUS_INVALID_PARAMETER or WSAEINVAL not 0x%x\n", WSAGetLastError());
2936 /* Test zero length passed */
2937 WSASetLastError(0);
2938 pdst = NULL;
2939 pdst = pInetNtop(AF_INET, (void*)&in.s_addr, dst, 0);
2940 ok(pdst == NULL, "The pointer should not be returned (%p)\n", pdst);
2941 ok(WSAGetLastError() == STATUS_INVALID_PARAMETER || WSAGetLastError() == WSAEINVAL /* Win7 */,
2942 "Should be STATUS_INVALID_PARAMETER or WSAEINVAL not 0x%x\n", WSAGetLastError());
2944 /* Test length one shorter than the address length */
2945 WSASetLastError(0);
2946 pdst = NULL;
2947 pdst = pInetNtop(AF_INET, (void*)&in.s_addr, dst, 6);
2948 ok(pdst == NULL, "The pointer should not be returned (%p)\n", pdst);
2949 ok(WSAGetLastError() == STATUS_INVALID_PARAMETER || WSAGetLastError() == WSAEINVAL /* Win7 */,
2950 "Should be STATUS_INVALID_PARAMETER or WSAEINVAL not 0x%x\n", WSAGetLastError());
2952 /* Test longer length is ok */
2953 WSASetLastError(0);
2954 pdst = NULL;
2955 pdst = pInetNtop(AF_INET, (void*)&in.s_addr, dst, sizeof(dst)+1);
2956 ok(pdst != NULL, "The pointer should be returned (%p)\n", pdst);
2957 ok(!strcmp(pdst, addr1_Str),"Address %s != %s\n", pdst, addr1_Str);
2959 /* Test the IPv6 addresses */
2961 /* Test an zero prefixed IPV6 address */
2962 memcpy(in6.u.Byte, addr2_Num, sizeof(addr2_Num));
2963 pdst = pInetNtop(AF_INET6,(void*)&in6.s6_addr, dst6, sizeof(dst6));
2964 ok(pdst != NULL, "InetNtop failed %s\n", dst6);
2965 ok(!strcmp(pdst, addr2_Str),"Address %s != %s\n", pdst, addr2_Str);
2967 /* Test an zero suffixed IPV6 address */
2968 memcpy(in6.s6_addr, addr3_Num, sizeof(addr3_Num));
2969 pdst = pInetNtop(AF_INET6,(void*)&in6.s6_addr, dst6, sizeof(dst6));
2970 ok(pdst != NULL, "InetNtop failed %s\n", dst6);
2971 ok(!strcmp(pdst, addr3_Str),"Address %s != %s\n", pdst, addr3_Str);
2973 /* Test the IPv6 address contains the IPv4 address in IPv4 notation */
2974 memcpy(in6.s6_addr, addr4_Num, sizeof(addr4_Num));
2975 pdst = pInetNtop(AF_INET6, (void*)&in6.s6_addr, dst6, sizeof(dst6));
2976 ok(pdst != NULL, "InetNtop failed %s\n", dst6);
2977 ok(!strcmp(pdst, addr4_Str),"Address %s != %s\n", pdst, addr4_Str);
2979 /* Test invalid parm conditions */
2980 memcpy(in6.u.Byte, addr2_Num, sizeof(addr2_Num));
2982 /* Test Null destination */
2983 pdst = NULL;
2984 pdst = pInetNtop(AF_INET6, (void*)&in6.s6_addr, NULL, sizeof(dst6));
2985 ok(pdst == NULL, "The pointer should not be returned (%p)\n", pdst);
2986 ok(WSAGetLastError() == STATUS_INVALID_PARAMETER || WSAGetLastError() == WSAEINVAL /* Win7 */,
2987 "Should be STATUS_INVALID_PARAMETER or WSAEINVAL not 0x%x\n", WSAGetLastError());
2989 /* Test zero length passed */
2990 WSASetLastError(0);
2991 pdst = NULL;
2992 pdst = pInetNtop(AF_INET6, (void*)&in6.s6_addr, dst6, 0);
2993 ok(pdst == NULL, "The pointer should not be returned (%p)\n", pdst);
2994 ok(WSAGetLastError() == STATUS_INVALID_PARAMETER || WSAGetLastError() == WSAEINVAL /* Win7 */,
2995 "Should be STATUS_INVALID_PARAMETER or WSAEINVAL not 0x%x\n", WSAGetLastError());
2997 /* Test length one shorter than the address length */
2998 WSASetLastError(0);
2999 pdst = NULL;
3000 pdst = pInetNtop(AF_INET6, (void*)&in6.s6_addr, dst6, 16);
3001 ok(pdst == NULL, "The pointer should not be returned (%p)\n", pdst);
3002 ok(WSAGetLastError() == STATUS_INVALID_PARAMETER || WSAGetLastError() == WSAEINVAL /* Win7 */,
3003 "Should be STATUS_INVALID_PARAMETER or WSAEINVAL not 0x%x\n", WSAGetLastError());
3005 /* Test longer length is ok */
3006 WSASetLastError(0);
3007 pdst = NULL;
3008 pdst = pInetNtop(AF_INET6, (void*)&in6.s6_addr, dst6, 18);
3009 ok(pdst != NULL, "The pointer should be returned (%p)\n", pdst);
3012 static void test_ioctlsocket(void)
3014 SOCKET sock;
3015 struct tcp_keepalive kalive;
3016 int ret, optval;
3017 static const LONG cmds[] = {FIONBIO, FIONREAD, SIOCATMARK};
3018 UINT i;
3019 u_long arg = 0;
3021 sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
3022 ok(sock != INVALID_SOCKET, "Creating the socket failed: %d\n", WSAGetLastError());
3023 if(sock == INVALID_SOCKET)
3025 skip("Can't continue without a socket.\n");
3026 return;
3029 for(i = 0; i < sizeof(cmds)/sizeof(cmds[0]); i++)
3031 /* broken apps like defcon pass the argp value directly instead of a pointer to it */
3032 ret = ioctlsocket(sock, cmds[i], (u_long *)1);
3033 ok(ret == SOCKET_ERROR, "ioctlsocket succeeded unexpectedly\n");
3034 ret = WSAGetLastError();
3035 ok(ret == WSAEFAULT, "expected WSAEFAULT, got %d instead\n", ret);
3038 /* A fresh and not connected socket has no urgent data, this test shows
3039 * that normal(not urgent) data returns a non-zero value for SIOCATMARK. */
3041 ret = ioctlsocket(sock, SIOCATMARK, &arg);
3042 ok(ret != SOCKET_ERROR, "ioctlsocket failed unexpectedly\n");
3043 ok(arg, "SIOCATMARK expected a non-zero value\n");
3045 /* when SO_OOBINLINE is set SIOCATMARK must always return TRUE */
3046 optval = 1;
3047 ret = setsockopt(sock, SOL_SOCKET, SO_OOBINLINE, (void *)&optval, sizeof(optval));
3048 ok(ret != SOCKET_ERROR, "setsockopt failed unexpectedly\n");
3049 arg = 0;
3050 ret = ioctlsocket(sock, SIOCATMARK, &arg);
3051 ok(ret != SOCKET_ERROR, "ioctlsocket failed unexpectedly\n");
3052 ok(arg, "SIOCATMARK expected a non-zero value\n");
3054 /* disable SO_OOBINLINE and get the same old behavior */
3055 optval = 0;
3056 ret = setsockopt(sock, SOL_SOCKET, SO_OOBINLINE, (void *)&optval, sizeof(optval));
3057 ok(ret != SOCKET_ERROR, "setsockopt failed unexpectedly\n");
3058 arg = 0;
3059 ret = ioctlsocket(sock, SIOCATMARK, &arg);
3060 ok(arg, "SIOCATMARK expected a non-zero value\n");
3062 ret = WSAIoctl(sock, SIO_KEEPALIVE_VALS, &arg, 0, NULL, 0, &arg, NULL, NULL);
3063 ok(ret == SOCKET_ERROR, "WSAIoctl succeeded unexpectedly\n");
3064 ret = WSAGetLastError();
3065 ok(ret == WSAEFAULT || broken(ret == WSAEINVAL), "expected WSAEFAULT, got %d instead\n", ret);
3067 ret = WSAIoctl(sock, SIO_KEEPALIVE_VALS, NULL, sizeof(struct tcp_keepalive), NULL, 0, &arg, NULL, NULL);
3068 ok(ret == SOCKET_ERROR, "WSAIoctl succeeded unexpectedly\n");
3069 ret = WSAGetLastError();
3070 ok(ret == WSAEFAULT || broken(ret == WSAEINVAL), "expected WSAEFAULT, got %d instead\n", ret);
3072 /* broken used to catch W95, W98, NT4 */
3073 make_keepalive(kalive, 0, 0, 0);
3074 ret = WSAIoctl(sock, SIO_KEEPALIVE_VALS, &kalive, sizeof(struct tcp_keepalive), NULL, 0, &arg, NULL, NULL);
3075 ok(ret == 0 || broken(ret == SOCKET_ERROR), "WSAIoctl failed unexpectedly\n");
3077 make_keepalive(kalive, 1, 0, 0);
3078 ret = WSAIoctl(sock, SIO_KEEPALIVE_VALS, &kalive, sizeof(struct tcp_keepalive), NULL, 0, &arg, NULL, NULL);
3079 ok(ret == 0 || broken(ret == SOCKET_ERROR), "WSAIoctl failed unexpectedly\n");
3081 make_keepalive(kalive, 1, 1000, 1000);
3082 ret = WSAIoctl(sock, SIO_KEEPALIVE_VALS, &kalive, sizeof(struct tcp_keepalive), NULL, 0, &arg, NULL, NULL);
3083 ok(ret == 0 || broken(ret == SOCKET_ERROR), "WSAIoctl failed unexpectedly\n");
3085 make_keepalive(kalive, 1, 10000, 10000);
3086 ret = WSAIoctl(sock, SIO_KEEPALIVE_VALS, &kalive, sizeof(struct tcp_keepalive), NULL, 0, &arg, NULL, NULL);
3087 ok(ret == 0 || broken(ret == SOCKET_ERROR), "WSAIoctl failed unexpectedly\n");
3089 make_keepalive(kalive, 1, 100, 100);
3090 ret = WSAIoctl(sock, SIO_KEEPALIVE_VALS, &kalive, sizeof(struct tcp_keepalive), NULL, 0, &arg, NULL, NULL);
3091 ok(ret == 0 || broken(ret == SOCKET_ERROR), "WSAIoctl failed unexpectedly\n");
3093 make_keepalive(kalive, 0, 100, 100);
3094 ret = WSAIoctl(sock, SIO_KEEPALIVE_VALS, &kalive, sizeof(struct tcp_keepalive), NULL, 0, &arg, NULL, NULL);
3095 ok(ret == 0 || broken(ret == SOCKET_ERROR), "WSAIoctl failed unexpectedly\n");
3097 closesocket(sock);
3100 static int drain_pause=0;
3101 static DWORD WINAPI drain_socket_thread(LPVOID arg)
3103 char buffer[1024];
3104 SOCKET sock = *(SOCKET*)arg;
3105 int ret;
3107 while ((ret = recv(sock, buffer, sizeof(buffer), 0)) != 0)
3109 if (ret < 0)
3111 if (WSAGetLastError() == WSAEWOULDBLOCK)
3113 fd_set readset;
3114 FD_ZERO(&readset);
3115 FD_SET(sock, &readset);
3116 select(sock+1, &readset, NULL, NULL, NULL);
3117 while (drain_pause)
3118 Sleep(100);
3120 else
3121 break;
3124 return 0;
3127 static void test_send(void)
3129 SOCKET src = INVALID_SOCKET;
3130 SOCKET dst = INVALID_SOCKET;
3131 HANDLE hThread = NULL;
3132 const int buflen = 1024*1024;
3133 char *buffer = NULL;
3134 int ret, i, zero = 0;
3135 WSABUF buf;
3136 OVERLAPPED ov;
3137 BOOL bret;
3138 DWORD id, bytes_sent, dwRet;
3140 memset(&ov, 0, sizeof(ov));
3142 if (tcp_socketpair(&src, &dst) != 0)
3144 ok(0, "creating socket pair failed, skipping test\n");
3145 return;
3148 set_blocking(dst, FALSE);
3149 /* force disable buffering so we can get a pending overlapped request */
3150 ret = setsockopt(dst, SOL_SOCKET, SO_SNDBUF, (char *) &zero, sizeof(zero));
3151 ok(!ret, "setsockopt SO_SNDBUF failed: %d - %d\n", ret, GetLastError());
3153 hThread = CreateThread(NULL, 0, drain_socket_thread, &dst, 0, &id);
3154 if (hThread == NULL)
3156 ok(0, "CreateThread failed, error %d\n", GetLastError());
3157 goto end;
3160 buffer = HeapAlloc(GetProcessHeap(), 0, buflen);
3161 if (buffer == NULL)
3163 ok(0, "HeapAlloc failed, error %d\n", GetLastError());
3164 goto end;
3167 /* fill the buffer with some nonsense */
3168 for (i = 0; i < buflen; ++i)
3170 buffer[i] = (char) i;
3173 ret = send(src, buffer, buflen, 0);
3174 if (ret >= 0)
3175 ok(ret == buflen, "send should have sent %d bytes, but it only sent %d\n", buflen, ret);
3176 else
3177 ok(0, "send failed, error %d\n", WSAGetLastError());
3179 buf.buf = buffer;
3180 buf.len = buflen;
3182 ov.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
3183 ok(ov.hEvent != NULL, "could not create event object, errno = %d\n", GetLastError());
3184 if (!ov.hEvent)
3185 goto end;
3187 bytes_sent = 0;
3188 WSASetLastError(12345);
3189 ret = WSASend(dst, &buf, 1, &bytes_sent, 0, &ov, NULL);
3190 ok((ret == SOCKET_ERROR && WSAGetLastError() == ERROR_IO_PENDING) || broken(bytes_sent == buflen),
3191 "Failed to start overlapped send %d - %d - %d/%d\n", ret, WSAGetLastError(), bytes_sent, buflen);
3193 /* don't check for completion yet, we may need to drain the buffer while still sending */
3194 set_blocking(src, FALSE);
3195 for (i = 0; i < buflen; ++i)
3197 int j = 0;
3199 ret = recv(src, buffer, 1, 0);
3200 while (ret == SOCKET_ERROR && GetLastError() == WSAEWOULDBLOCK && j < 100)
3202 j++;
3203 Sleep(50);
3204 ret = recv(src, buffer, 1, 0);
3207 ok(ret == 1, "Failed to receive data %d - %d (got %d/%d)\n", ret, GetLastError(), i, buflen);
3208 if (ret != 1)
3209 break;
3211 ok(buffer[0] == (char) i, "Received bad data at position %d\n", i);
3214 dwRet = WaitForSingleObject(ov.hEvent, 1000);
3215 ok(dwRet == WAIT_OBJECT_0, "Failed to wait for recv message: %d - %d\n", dwRet, GetLastError());
3216 if (dwRet == WAIT_OBJECT_0)
3218 bret = GetOverlappedResult((HANDLE)dst, &ov, &bytes_sent, FALSE);
3219 ok((bret && bytes_sent == buflen) || broken(!bret && GetLastError() == ERROR_IO_INCOMPLETE) /* win9x */,
3220 "Got %d instead of %d (%d - %d)\n", bytes_sent, buflen, bret, GetLastError());
3223 WSASetLastError(12345);
3224 ret = WSASend(INVALID_SOCKET, &buf, 1, NULL, 0, &ov, NULL);
3225 ok(ret == SOCKET_ERROR && WSAGetLastError() == WSAENOTSOCK,
3226 "WSASend failed %d - %d\n", ret, WSAGetLastError());
3228 WSASetLastError(12345);
3229 ret = WSASend(dst, &buf, 1, NULL, 0, &ov, NULL);
3230 ok(ret == SOCKET_ERROR && WSAGetLastError() == ERROR_IO_PENDING,
3231 "Failed to start overlapped send %d - %d\n", ret, WSAGetLastError());
3233 end:
3234 if (src != INVALID_SOCKET)
3235 closesocket(src);
3236 if (dst != INVALID_SOCKET)
3237 closesocket(dst);
3238 if (hThread != NULL)
3239 CloseHandle(hThread);
3240 if (ov.hEvent)
3241 CloseHandle(ov.hEvent);
3242 HeapFree(GetProcessHeap(), 0, buffer);
3245 typedef struct async_message
3247 SOCKET socket;
3248 LPARAM lparam;
3249 struct async_message *next;
3250 } async_message;
3252 static struct async_message *messages_received;
3254 #define WM_SOCKET (WM_USER+100)
3255 static LRESULT CALLBACK ws2_test_WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
3257 struct async_message *message;
3259 switch (msg)
3261 case WM_SOCKET:
3262 message = HeapAlloc(GetProcessHeap(), 0, sizeof(*message));
3263 message->socket = (SOCKET) wparam;
3264 message->lparam = lparam;
3265 message->next = NULL;
3267 if (messages_received)
3269 struct async_message *last = messages_received;
3270 while (last->next) last = last->next;
3271 last->next = message;
3273 else
3274 messages_received = message;
3275 return 0;
3278 return DefWindowProc(hwnd, msg, wparam, lparam);
3281 static void get_event_details(int event, int *bit, char *name)
3283 switch (event)
3285 case FD_ACCEPT:
3286 if (bit) *bit = FD_ACCEPT_BIT;
3287 if (name) strcpy(name, "FD_ACCEPT");
3288 break;
3289 case FD_CONNECT:
3290 if (bit) *bit = FD_CONNECT_BIT;
3291 if (name) strcpy(name, "FD_CONNECT");
3292 break;
3293 case FD_READ:
3294 if (bit) *bit = FD_READ_BIT;
3295 if (name) strcpy(name, "FD_READ");
3296 break;
3297 case FD_OOB:
3298 if (bit) *bit = FD_OOB_BIT;
3299 if (name) strcpy(name, "FD_OOB");
3300 break;
3301 case FD_WRITE:
3302 if (bit) *bit = FD_WRITE_BIT;
3303 if (name) strcpy(name, "FD_WRITE");
3304 break;
3305 case FD_CLOSE:
3306 if (bit) *bit = FD_CLOSE_BIT;
3307 if (name) strcpy(name, "FD_CLOSE");
3308 break;
3309 default:
3310 if (bit) *bit = -1;
3311 if (name) sprintf(name, "bad%x", event);
3315 static const char *dbgstr_event_seq(const LPARAM *seq)
3317 static char message[1024];
3318 char name[12];
3319 int len = 1;
3321 message[0] = '[';
3322 message[1] = 0;
3323 while (*seq)
3325 get_event_details(WSAGETSELECTEVENT(*seq), NULL, name);
3326 len += sprintf(message + len, "%s(%d) ", name, WSAGETSELECTERROR(*seq));
3327 seq++;
3329 if (len > 1) len--;
3330 strcpy( message + len, "]" );
3331 return message;
3334 static char *dbgstr_event_seq_result(SOCKET s, WSANETWORKEVENTS *netEvents)
3336 static char message[1024];
3337 struct async_message *curr = messages_received;
3338 int index, error, bit = 0;
3339 char name[12];
3340 int len = 1;
3342 message[0] = '[';
3343 message[1] = 0;
3344 while (1)
3346 if (netEvents)
3348 if (bit >= FD_MAX_EVENTS) break;
3349 if ( !(netEvents->lNetworkEvents & (1 << bit)) )
3351 bit++;
3352 continue;
3354 get_event_details(1 << bit, &index, name);
3355 error = netEvents->iErrorCode[index];
3356 bit++;
3358 else
3360 if (!curr) break;
3361 if (curr->socket != s)
3363 curr = curr->next;
3364 continue;
3366 get_event_details(WSAGETSELECTEVENT(curr->lparam), NULL, name);
3367 error = WSAGETSELECTERROR(curr->lparam);
3368 curr = curr->next;
3371 len += sprintf(message + len, "%s(%d) ", name, error);
3373 if (len > 1) len--;
3374 strcpy( message + len, "]" );
3375 return message;
3378 static void flush_events(SOCKET s, HANDLE hEvent)
3380 WSANETWORKEVENTS netEvents;
3381 struct async_message *prev = NULL, *curr = messages_received;
3382 int ret;
3383 DWORD dwRet;
3385 if (hEvent != INVALID_HANDLE_VALUE)
3387 dwRet = WaitForSingleObject(hEvent, 100);
3388 if (dwRet == WAIT_OBJECT_0)
3390 ret = WSAEnumNetworkEvents(s, hEvent, &netEvents);
3391 if (ret)
3392 ok(0, "WSAEnumNetworkEvents failed, error %d\n", ret);
3395 else
3397 while (curr)
3399 if (curr->socket == s)
3401 if (prev) prev->next = curr->next;
3402 else messages_received = curr->next;
3404 HeapFree(GetProcessHeap(), 0, curr);
3406 if (prev) curr = prev->next;
3407 else curr = messages_received;
3409 else
3411 prev = curr;
3412 curr = curr->next;
3418 static int match_event_sequence(SOCKET s, WSANETWORKEVENTS *netEvents, const LPARAM *seq)
3420 int event, index, error, events;
3421 struct async_message *curr;
3423 if (netEvents)
3425 events = netEvents->lNetworkEvents;
3426 while (*seq)
3428 event = WSAGETSELECTEVENT(*seq);
3429 error = WSAGETSELECTERROR(*seq);
3430 get_event_details(event, &index, NULL);
3432 if (!(events & event) && index != -1)
3433 return 0;
3434 if (events & event && index != -1)
3436 if (netEvents->iErrorCode[index] != error)
3437 return 0;
3439 events &= ~event;
3440 seq++;
3442 if (events)
3443 return 0;
3445 else
3447 curr = messages_received;
3448 while (curr)
3450 if (curr->socket == s)
3452 if (!*seq) return 0;
3453 if (*seq != curr->lparam) return 0;
3454 seq++;
3456 curr = curr->next;
3458 if (*seq)
3459 return 0;
3461 return 1;
3464 /* checks for a sequence of events, (order only checked if window is used) */
3465 static void ok_event_sequence(SOCKET s, HANDLE hEvent, const LPARAM *seq, const LPARAM **broken_seqs, int completelyBroken)
3467 MSG msg;
3468 WSANETWORKEVENTS events, *netEvents = NULL;
3469 int ret;
3470 DWORD dwRet;
3472 if (hEvent != INVALID_HANDLE_VALUE)
3474 netEvents = &events;
3476 dwRet = WaitForSingleObject(hEvent, 200);
3477 if (dwRet == WAIT_OBJECT_0)
3479 ret = WSAEnumNetworkEvents(s, hEvent, netEvents);
3480 if (ret)
3482 winetest_ok(0, "WSAEnumNetworkEvents failed, error %d\n", ret);
3483 return;
3486 else
3487 memset(netEvents, 0, sizeof(*netEvents));
3489 else
3491 Sleep(200);
3492 /* Run the message loop a little */
3493 while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE ))
3495 DispatchMessageA(&msg);
3499 if (match_event_sequence(s, netEvents, seq))
3501 winetest_ok(1, "Sequence matches expected: %s\n", dbgstr_event_seq(seq));
3502 flush_events(s, hEvent);
3503 return;
3506 if (broken_seqs)
3508 for (; *broken_seqs; broken_seqs++)
3510 if (match_event_sequence(s, netEvents, *broken_seqs))
3512 winetest_ok(broken(1), "Sequence matches broken: %s, expected %s\n", dbgstr_event_seq_result(s, netEvents), dbgstr_event_seq(seq));
3513 flush_events(s, hEvent);
3514 return;
3519 winetest_ok(broken(completelyBroken), "Expected event sequence %s, got %s\n", dbgstr_event_seq(seq),
3520 dbgstr_event_seq_result(s, netEvents));
3521 flush_events(s, hEvent);
3524 #define ok_event_seq (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : ok_event_sequence
3526 static void test_events(int useMessages)
3528 SOCKET server = INVALID_SOCKET;
3529 SOCKET src = INVALID_SOCKET, src2 = INVALID_SOCKET;
3530 SOCKET dst = INVALID_SOCKET, dst2 = INVALID_SOCKET;
3531 struct sockaddr_in addr;
3532 HANDLE hThread = NULL;
3533 HANDLE hEvent = INVALID_HANDLE_VALUE, hEvent2 = INVALID_HANDLE_VALUE;
3534 WNDCLASSEX wndclass;
3535 HWND hWnd = NULL;
3536 char *buffer = NULL;
3537 int bufferSize = 1024*1024;
3538 WSABUF bufs;
3539 OVERLAPPED ov, ov2;
3540 DWORD flags = 0;
3541 DWORD bytesReturned;
3542 DWORD id;
3543 int len;
3544 int ret;
3545 DWORD dwRet;
3546 BOOL bret;
3547 static char szClassName[] = "wstestclass";
3548 const LPARAM *broken_seq[3];
3549 static const LPARAM empty_seq[] = { 0 };
3550 static const LPARAM close_seq[] = { WSAMAKESELECTREPLY(FD_CLOSE, 0), 0 };
3551 static const LPARAM write_seq[] = { WSAMAKESELECTREPLY(FD_WRITE, 0), 0 };
3552 static const LPARAM read_seq[] = { WSAMAKESELECTREPLY(FD_READ, 0), 0 };
3553 static const LPARAM oob_seq[] = { WSAMAKESELECTREPLY(FD_OOB, 0), 0 };
3554 static const LPARAM connect_seq[] = { WSAMAKESELECTREPLY(FD_CONNECT, 0),
3555 WSAMAKESELECTREPLY(FD_WRITE, 0), 0 };
3556 static const LPARAM read_read_seq[] = { WSAMAKESELECTREPLY(FD_READ, 0),
3557 WSAMAKESELECTREPLY(FD_READ, 0), 0 };
3558 static const LPARAM read_write_seq[] = { WSAMAKESELECTREPLY(FD_READ, 0),
3559 WSAMAKESELECTREPLY(FD_WRITE, 0), 0 };
3560 static const LPARAM read_close_seq[] = { WSAMAKESELECTREPLY(FD_READ, 0),
3561 WSAMAKESELECTREPLY(FD_CLOSE, 0), 0 };
3563 memset(&ov, 0, sizeof(ov));
3564 memset(&ov2, 0, sizeof(ov2));
3566 /* don't use socketpair, we want connection event */
3567 src = socket(AF_INET, SOCK_STREAM, 0);
3568 if (src == INVALID_SOCKET)
3570 ok(0, "creating socket pair failed (%d), skipping test\n", GetLastError());
3571 goto end;
3574 src2 = socket(AF_INET, SOCK_STREAM, 0);
3575 if (src2 == INVALID_SOCKET)
3577 ok(0, "creating socket pair failed (%d), skipping test\n", GetLastError());
3578 goto end;
3581 len = sizeof(BOOL);
3582 if (getsockopt(src, SOL_SOCKET, SO_OOBINLINE, (void *)&bret, &len) == SOCKET_ERROR)
3584 ok(0, "failed to get oobinline status, %d\n", GetLastError());
3585 goto end;
3587 ok(bret == FALSE, "OOB not inline\n");
3589 if (useMessages)
3591 trace("Event test using messages\n");
3593 wndclass.cbSize = sizeof(wndclass);
3594 wndclass.style = CS_HREDRAW | CS_VREDRAW;
3595 wndclass.lpfnWndProc = ws2_test_WndProc;
3596 wndclass.cbClsExtra = 0;
3597 wndclass.cbWndExtra = 0;
3598 wndclass.hInstance = GetModuleHandle(NULL);
3599 wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
3600 wndclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
3601 wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
3602 wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
3603 wndclass.lpszClassName = szClassName;
3604 wndclass.lpszMenuName = NULL;
3605 RegisterClassEx(&wndclass);
3607 hWnd = CreateWindow(szClassName, "WS2Test", WS_OVERLAPPEDWINDOW, 0, 0, 500, 500, NULL, NULL, GetModuleHandle(NULL), NULL);
3608 if (!hWnd)
3610 ok(0, "failed to create window: %d\n", GetLastError());
3611 return;
3614 ret = WSAAsyncSelect(src, hWnd, WM_SOCKET, FD_CONNECT | FD_READ | FD_OOB | FD_WRITE | FD_CLOSE);
3615 if (ret)
3617 ok(0, "WSAAsyncSelect failed, error %d\n", ret);
3618 goto end;
3621 ret = WSAAsyncSelect(src2, hWnd, WM_SOCKET, FD_CONNECT | FD_READ | FD_OOB | FD_WRITE | FD_CLOSE);
3622 if (ret)
3624 ok(0, "WSAAsyncSelect failed, error %d\n", ret);
3625 goto end;
3628 else
3630 trace("Event test using events\n");
3632 hEvent = WSACreateEvent();
3633 if (hEvent == INVALID_HANDLE_VALUE)
3635 ok(0, "WSACreateEvent failed, error %d\n", GetLastError());
3636 goto end;
3639 hEvent2 = WSACreateEvent();
3640 if (hEvent2 == INVALID_HANDLE_VALUE)
3642 ok(0, "WSACreateEvent failed, error %d\n", GetLastError());
3643 goto end;
3646 ret = WSAEventSelect(src, hEvent, FD_CONNECT | FD_READ | FD_OOB | FD_WRITE | FD_CLOSE);
3647 if (ret)
3649 ok(0, "WSAEventSelect failed, error %d\n", ret);
3650 goto end;
3653 ret = WSAEventSelect(src2, hEvent2, FD_CONNECT | FD_READ | FD_OOB | FD_WRITE | FD_CLOSE);
3654 if (ret)
3656 ok(0, "WSAEventSelect failed, error %d\n", ret);
3657 goto end;
3661 server = socket(AF_INET, SOCK_STREAM, 0);
3662 if (server == INVALID_SOCKET)
3664 ok(0, "creating socket pair failed (%d), skipping test\n", GetLastError());
3665 goto end;
3668 memset(&addr, 0, sizeof(addr));
3669 addr.sin_family = AF_INET;
3670 addr.sin_addr.s_addr = inet_addr("127.0.0.1");
3671 ret = bind(server, (struct sockaddr*)&addr, sizeof(addr));
3672 if (ret != 0)
3674 ok(0, "creating socket pair failed (%d), skipping test\n", GetLastError());
3675 goto end;
3678 len = sizeof(addr);
3679 ret = getsockname(server, (struct sockaddr*)&addr, &len);
3680 if (ret != 0)
3682 ok(0, "creating socket pair failed (%d), skipping test\n", GetLastError());
3683 goto end;
3686 ret = listen(server, 2);
3687 if (ret != 0)
3689 ok(0, "creating socket pair failed (%d), skipping test\n", GetLastError());
3690 goto end;
3693 ret = connect(src, (struct sockaddr*)&addr, sizeof(addr));
3694 if (ret == SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK)
3696 ok(0, "creating socket pair failed (%d), skipping test\n", GetLastError());
3697 goto end;
3700 ret = connect(src2, (struct sockaddr*)&addr, sizeof(addr));
3701 if (ret == SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK)
3703 ok(0, "creating socket pair failed (%d), skipping test\n", GetLastError());
3704 goto end;
3707 len = sizeof(addr);
3708 dst = accept(server, (struct sockaddr*)&addr, &len);
3709 if (dst == INVALID_SOCKET)
3711 ok(0, "creating socket pair failed (%d), skipping test\n", GetLastError());
3712 goto end;
3715 len = sizeof(addr);
3716 dst2 = accept(server, (struct sockaddr*)&addr, &len);
3717 if (dst2 == INVALID_SOCKET)
3719 ok(0, "creating socket pair failed (%d), skipping test\n", GetLastError());
3720 goto end;
3723 closesocket(server);
3724 server = INVALID_SOCKET;
3726 /* On Windows it seems when a non-blocking socket sends to a
3727 blocking socket on the same host, the send() is BLOCKING,
3728 so make both sockets non-blocking. src is already non-blocking
3729 from the async select */
3731 if (set_blocking(dst, FALSE))
3733 ok(0, "ioctlsocket failed, error %d\n", WSAGetLastError());
3734 goto end;
3737 buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, bufferSize);
3738 if (buffer == NULL)
3740 ok(0, "could not allocate memory for test\n");
3741 goto end;
3744 ov.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
3745 if (ov.hEvent == NULL)
3747 ok(0, "could not create event object, errno = %d\n", GetLastError());
3748 goto end;
3751 ov2.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
3752 if (ov2.hEvent == NULL)
3754 ok(0, "could not create event object, errno = %d\n", GetLastError());
3755 goto end;
3758 /* FD_WRITE should be set initially, and allow us to send at least 1 byte */
3759 ok_event_seq(src, hEvent, connect_seq, NULL, 1);
3760 ok_event_seq(src2, hEvent2, connect_seq, NULL, 1);
3761 /* broken on all windows - FD_CONNECT error is garbage */
3763 /* Test simple send/recv */
3764 ret = send(dst, buffer, 100, 0);
3765 ok(ret == 100, "Failed to send buffer %d err %d\n", ret, GetLastError());
3766 ok_event_seq(src, hEvent, read_seq, NULL, 0);
3768 ret = recv(src, buffer, 1, MSG_PEEK);
3769 ok(ret == 1, "Failed to peek at recv buffer %d err %d\n", ret, GetLastError());
3770 ok_event_seq(src, hEvent, read_seq, NULL, 0);
3772 ret = recv(src, buffer, 50, 0);
3773 ok(ret == 50, "Failed to recv buffer %d err %d\n", ret, GetLastError());
3774 ok_event_seq(src, hEvent, read_seq, NULL, 0);
3776 ret = recv(src, buffer, 50, 0);
3777 ok(ret == 50, "Failed to recv buffer %d err %d\n", ret, GetLastError());
3778 ok_event_seq(src, hEvent, empty_seq, NULL, 0);
3780 /* fun fact - events are re-enabled even on failure, but only for messages */
3781 ret = send(dst, "1", 1, 0);
3782 ok(ret == 1, "Failed to send buffer %d err %d\n", ret, GetLastError());
3783 ok_event_seq(src, hEvent, read_seq, NULL, 0);
3785 ret = recv(src, buffer, -1, 0);
3786 ok(ret == SOCKET_ERROR && (GetLastError() == WSAEFAULT || GetLastError() == WSAENOBUFS),
3787 "Failed to recv buffer %d err %d\n", ret, GetLastError());
3788 if (useMessages)
3790 broken_seq[0] = empty_seq; /* win9x */
3791 broken_seq[1] = NULL;
3792 todo_wine ok_event_seq(src, hEvent, read_seq, broken_seq, 0);
3794 else
3795 ok_event_seq(src, hEvent, empty_seq, NULL, 0);
3797 ret = recv(src, buffer, 1, 0);
3798 ok(ret == 1, "Failed to recv buffer %d err %d\n", ret, GetLastError());
3799 ok_event_seq(src, hEvent, empty_seq, NULL, 0);
3801 /* Interaction with overlapped */
3802 bufs.len = sizeof(char);
3803 bufs.buf = buffer;
3804 ret = WSARecv(src, &bufs, 1, &bytesReturned, &flags, &ov, NULL);
3805 ok(ret == SOCKET_ERROR && GetLastError() == ERROR_IO_PENDING,
3806 "WSARecv failed - %d error %d\n", ret, GetLastError());
3808 bufs.len = sizeof(char);
3809 bufs.buf = buffer+1;
3810 ret = WSARecv(src, &bufs, 1, &bytesReturned, &flags, &ov2, NULL);
3811 ok(ret == SOCKET_ERROR && GetLastError() == ERROR_IO_PENDING,
3812 "WSARecv failed - %d error %d\n", ret, GetLastError());
3814 ret = send(dst, "12", 2, 0);
3815 ok(ret == 2, "Failed to send buffer %d err %d\n", ret, GetLastError());
3816 broken_seq[0] = read_read_seq; /* win9x */
3817 broken_seq[1] = NULL;
3818 ok_event_seq(src, hEvent, empty_seq, broken_seq, 0);
3820 dwRet = WaitForSingleObject(ov.hEvent, 100);
3821 ok(dwRet == WAIT_OBJECT_0, "Failed to wait for recv message: %d - %d\n", dwRet, GetLastError());
3822 if (dwRet == WAIT_OBJECT_0)
3824 bret = GetOverlappedResult((HANDLE)src, &ov, &bytesReturned, FALSE);
3825 ok((bret && bytesReturned == 1) || broken(!bret && GetLastError() == ERROR_IO_INCOMPLETE) /* win9x */,
3826 "Got %d instead of 1 (%d - %d)\n", bytesReturned, bret, GetLastError());
3827 ok(buffer[0] == '1', "Got %c instead of 1\n", buffer[0]);
3830 dwRet = WaitForSingleObject(ov2.hEvent, 100);
3831 ok(dwRet == WAIT_OBJECT_0, "Failed to wait for recv message: %d - %d\n", dwRet, GetLastError());
3832 if (dwRet == WAIT_OBJECT_0)
3834 bret = GetOverlappedResult((HANDLE)src, &ov2, &bytesReturned, FALSE);
3835 ok((bret && bytesReturned == 1) || broken(!bret && GetLastError() == ERROR_IO_INCOMPLETE) /* win9x */,
3836 "Got %d instead of 1 (%d - %d)\n", bytesReturned, bret, GetLastError());
3837 ok(buffer[1] == '2', "Got %c instead of 2\n", buffer[1]);
3840 ret = send(dst, "1", 1, 0);
3841 ok(ret == 1, "Failed to send buffer %d err %d\n", ret, GetLastError());
3842 ok_event_seq(src, hEvent, read_seq, NULL, 0);
3844 ret = recv(src, buffer, 1, 0);
3845 ok(ret == 1, "Failed to empty buffer: %d - %d\n", ret, GetLastError());
3846 ok_event_seq(src, hEvent, empty_seq, NULL, 0);
3848 /* Notifications are delivered as soon as possible, blocked only on
3849 * async requests on the same type */
3850 bufs.len = sizeof(char);
3851 bufs.buf = buffer;
3852 ret = WSARecv(src, &bufs, 1, &bytesReturned, &flags, &ov, NULL);
3853 ok(ret == SOCKET_ERROR && GetLastError() == ERROR_IO_PENDING,
3854 "WSARecv failed - %d error %d\n", ret, GetLastError());
3856 if (0) {
3857 ret = send(dst, "1", 1, MSG_OOB);
3858 ok(ret == 1, "Failed to send buffer %d err %d\n", ret, GetLastError());
3859 ok_event_seq(src, hEvent, oob_seq, NULL, 0);
3862 dwRet = WaitForSingleObject(ov.hEvent, 100);
3863 ok(dwRet == WAIT_TIMEOUT, "OOB message activated read?: %d - %d\n", dwRet, GetLastError());
3865 ret = send(dst, "2", 1, 0);
3866 ok(ret == 1, "Failed to send buffer %d err %d\n", ret, GetLastError());
3867 broken_seq[0] = read_seq; /* win98 */
3868 broken_seq[1] = NULL;
3869 ok_event_seq(src, hEvent, empty_seq, broken_seq, 0);
3871 dwRet = WaitForSingleObject(ov.hEvent, 100);
3872 ok(dwRet == WAIT_OBJECT_0 || broken(dwRet == WAIT_TIMEOUT),
3873 "Failed to wait for recv message: %d - %d\n", dwRet, GetLastError());
3874 if (dwRet == WAIT_OBJECT_0)
3876 bret = GetOverlappedResult((HANDLE)src, &ov, &bytesReturned, FALSE);
3877 ok((bret && bytesReturned == 1) || broken(!bret && GetLastError() == ERROR_IO_INCOMPLETE) /* win9x */,
3878 "Got %d instead of 1 (%d - %d)\n", bytesReturned, bret, GetLastError());
3879 ok(buffer[0] == '2', "Got %c instead of 2\n", buffer[0]);
3881 else if (dwRet == WAIT_TIMEOUT)
3883 /* this happens on win98. We get an FD_READ later on the next test */
3884 CancelIo((HANDLE) src);
3887 if (0) {
3888 ret = recv(src, buffer, 1, MSG_OOB);
3889 todo_wine ok(ret == 1, "Failed to empty buffer: %d - %d\n", ret, GetLastError());
3890 /* We get OOB notification, but no data on wine */
3891 ok_event_seq(src, hEvent, empty_seq, NULL, 0);
3894 /* Flood the send queue */
3895 hThread = CreateThread(NULL, 0, drain_socket_thread, &dst, 0, &id);
3896 if (hThread == NULL)
3898 ok(0, "CreateThread failed, error %d\n", GetLastError());
3899 goto end;
3902 /* Now FD_WRITE should not be set, because the socket send buffer isn't full yet */
3903 ok_event_seq(src, hEvent, empty_seq, NULL, 0);
3905 /* Now if we send a ton of data and the 'server' does not drain it fast
3906 * enough (set drain_pause to be sure), the socket send buffer will only
3907 * take some of it, and we will get a short write. This will trigger
3908 * another FD_WRITE event as soon as data is sent and more space becomes
3909 * available, but not any earlier. */
3910 drain_pause=1;
3913 ret = send(src, buffer, bufferSize, 0);
3914 } while (ret == bufferSize);
3915 drain_pause=0;
3916 if (ret >= 0 || WSAGetLastError() == WSAEWOULDBLOCK)
3918 Sleep(400); /* win9x */
3919 broken_seq[0] = read_write_seq;
3920 broken_seq[1] = NULL;
3921 ok_event_seq(src, hEvent, write_seq, broken_seq, 0);
3923 else
3925 ok(0, "sending a lot of data failed with error %d\n", WSAGetLastError());
3928 /* Test how FD_CLOSE is handled */
3929 ret = send(dst, "12", 2, 0);
3930 ok(ret == 2, "Failed to send buffer %d err %d\n", ret, GetLastError());
3932 /* Wait a little and let the send complete */
3933 Sleep(100);
3934 closesocket(dst);
3935 dst = INVALID_SOCKET;
3936 Sleep(100);
3938 /* We can never implement this in wine, best we can hope for is
3939 sending FD_CLOSE after the reads complete */
3940 broken_seq[0] = read_seq; /* win9x */
3941 broken_seq[1] = NULL;
3942 todo_wine ok_event_seq(src, hEvent, read_close_seq, broken_seq, 0);
3944 ret = recv(src, buffer, 1, 0);
3945 ok(ret == 1, "Failed to empty buffer: %d - %d\n", ret, GetLastError());
3946 ok_event_seq(src, hEvent, read_seq, NULL, 0);
3948 ret = recv(src, buffer, 1, 0);
3949 ok(ret == 1, "Failed to empty buffer: %d - %d\n", ret, GetLastError());
3950 /* want it? it's here, but you can't have it */
3951 broken_seq[0] = close_seq; /* win9x */
3952 broken_seq[1] = NULL;
3953 todo_wine ok_event_seq(src, hEvent, empty_seq, /* wine sends FD_CLOSE here */
3954 broken_seq, 0);
3956 /* Test how FD_CLOSE is handled */
3957 ret = send(dst2, "12", 2, 0);
3958 ok(ret == 2, "Failed to send buffer %d err %d\n", ret, GetLastError());
3960 Sleep(200);
3961 shutdown(dst2, SD_SEND);
3962 Sleep(200);
3964 /* Some of the below are technically todo_wine, but our event sequence is still valid, so to prevent
3965 regressions, don't mark them as todo_wine, and mark windows as broken */
3966 broken_seq[0] = read_close_seq;
3967 broken_seq[1] = close_seq;
3968 broken_seq[2] = NULL;
3969 ok_event_seq(src2, hEvent2, read_seq, broken_seq, 0);
3971 ret = recv(src2, buffer, 1, 0);
3972 ok(ret == 1 || broken(!ret), "Failed to empty buffer: %d - %d\n", ret, GetLastError());
3973 broken_seq[0] = close_seq; /* win98 */
3974 broken_seq[1] = NULL;
3975 ok_event_seq(src2, hEvent2, read_seq, broken_seq, 0);
3977 ret = recv(src2, buffer, 1, 0);
3978 ok(ret == 1 || broken(!ret), "Failed to empty buffer: %d - %d\n", ret, GetLastError());
3979 broken_seq[0] = empty_seq;
3980 broken_seq[1] = NULL;
3981 ok_event_seq(src2, hEvent2, close_seq, broken_seq, 0);
3983 ret = send(src2, "1", 1, 0);
3984 ok(ret == 1, "Sending to half-closed socket failed %d err %d\n", ret, GetLastError());
3985 ok_event_seq(src2, hEvent2, empty_seq, NULL, 0);
3987 ret = send(src2, "1", 1, 0);
3988 ok(ret == 1, "Sending to half-closed socket failed %d err %d\n", ret, GetLastError());
3989 ok_event_seq(src2, hEvent2, empty_seq, NULL, 0);
3991 end:
3992 if (src != INVALID_SOCKET)
3994 flush_events(src, hEvent);
3995 closesocket(src);
3997 if (src2 != INVALID_SOCKET)
3999 flush_events(src2, hEvent2);
4000 closesocket(src2);
4002 HeapFree(GetProcessHeap(), 0, buffer);
4003 if (server != INVALID_SOCKET)
4004 closesocket(server);
4005 if (dst != INVALID_SOCKET)
4006 closesocket(dst);
4007 if (dst2 != INVALID_SOCKET)
4008 closesocket(dst2);
4009 if (hThread != NULL)
4010 CloseHandle(hThread);
4011 if (hWnd != NULL)
4012 DestroyWindow(hWnd);
4013 if (hEvent != NULL)
4014 CloseHandle(hEvent);
4015 if (hEvent2 != NULL)
4016 CloseHandle(hEvent2);
4017 if (ov.hEvent != NULL)
4018 CloseHandle(ov.hEvent);
4019 if (ov2.hEvent != NULL)
4020 CloseHandle(ov2.hEvent);
4023 static void test_ipv6only(void)
4025 SOCKET v4 = INVALID_SOCKET,
4026 v6 = INVALID_SOCKET;
4027 struct sockaddr_in sin4;
4028 struct sockaddr_in6 sin6;
4029 int ret;
4031 memset(&sin4, 0, sizeof(sin4));
4032 sin4.sin_family = AF_INET;
4033 sin4.sin_port = htons(SERVERPORT);
4035 memset(&sin6, 0, sizeof(sin6));
4036 sin6.sin6_family = AF_INET6;
4037 sin6.sin6_port = htons(SERVERPORT);
4039 v6 = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
4040 if (v6 == INVALID_SOCKET) {
4041 skip("Could not create IPv6 socket (LastError: %d; %d expected if IPv6 not available).\n",
4042 WSAGetLastError(), WSAEAFNOSUPPORT);
4043 goto end;
4045 ret = bind(v6, (struct sockaddr*)&sin6, sizeof(sin6));
4046 if (ret) {
4047 skip("Could not bind IPv6 address (LastError: %d).\n",
4048 WSAGetLastError());
4049 goto end;
4052 v4 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
4053 if (v4 == INVALID_SOCKET) {
4054 skip("Could not create IPv4 socket (LastError: %d).\n",
4055 WSAGetLastError());
4056 goto end;
4058 ret = bind(v4, (struct sockaddr*)&sin4, sizeof(sin4));
4059 ok(!ret, "Could not bind IPv4 address (LastError: %d; %d expected if IPv6 binds to IPv4 as well).\n",
4060 WSAGetLastError(), WSAEADDRINUSE);
4062 end:
4063 if (v4 != INVALID_SOCKET)
4064 closesocket(v4);
4065 if (v6 != INVALID_SOCKET)
4066 closesocket(v6);
4069 static void test_WSASendTo(void)
4071 SOCKET s;
4072 struct sockaddr_in addr;
4073 char buf[12] = "hello world";
4074 WSABUF data_buf;
4075 DWORD bytesSent;
4076 int ret;
4078 addr.sin_family = AF_INET;
4079 addr.sin_port = htons(139);
4080 addr.sin_addr.s_addr = inet_addr("127.0.0.1");
4081 data_buf.len = sizeof(buf);
4082 data_buf.buf = buf;
4084 if( (s = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET) {
4085 ok(0, "socket() failed error: %d\n", WSAGetLastError());
4086 return;
4089 WSASetLastError(12345);
4090 ret = WSASendTo(INVALID_SOCKET, &data_buf, 1, NULL, 0, (struct sockaddr*)&addr, sizeof(addr), NULL, NULL);
4091 ok(ret == SOCKET_ERROR && WSAGetLastError() == WSAENOTSOCK,
4092 "WSASendTo() failed: %d/%d\n", ret, WSAGetLastError());
4094 WSASetLastError(12345);
4095 ret = WSASendTo(s, &data_buf, 1, NULL, 0, (struct sockaddr*)&addr, sizeof(addr), NULL, NULL);
4096 ok(ret == SOCKET_ERROR && WSAGetLastError() == WSAEFAULT,
4097 "WSASendTo() failed: %d/%d\n", ret, WSAGetLastError());
4099 WSASetLastError(12345);
4100 if(WSASendTo(s, &data_buf, 1, &bytesSent, 0, (struct sockaddr*)&addr, sizeof(addr), NULL, NULL)) {
4101 ok(0, "WSASendTo() failed error: %d\n", WSAGetLastError());
4102 return;
4104 ok(!WSAGetLastError(), "WSAGetLastError() should return zero after "
4105 "a successful call to WSASendTo()\n");
4108 static DWORD WINAPI recv_thread(LPVOID arg)
4110 SOCKET sock = *(SOCKET *)arg;
4111 char buffer[32];
4112 WSABUF wsa;
4113 WSAOVERLAPPED ov;
4114 DWORD flags = 0;
4116 wsa.buf = buffer;
4117 wsa.len = sizeof(buffer);
4118 ov.hEvent = WSACreateEvent();
4119 WSARecv(sock, &wsa, 1, NULL, &flags, &ov, NULL);
4121 WaitForSingleObject(ov.hEvent, 1000);
4122 WSACloseEvent(ov.hEvent);
4123 return 0;
4126 static void test_WSARecv(void)
4128 SOCKET src, dest, server = INVALID_SOCKET;
4129 char buf[20];
4130 WSABUF bufs;
4131 WSAOVERLAPPED ov;
4132 DWORD bytesReturned, flags, id;
4133 struct linger ling;
4134 struct sockaddr_in addr;
4135 int iret, len;
4136 DWORD dwret;
4137 BOOL bret;
4138 HANDLE thread;
4140 memset(&ov, 0, sizeof(ov));
4142 tcp_socketpair(&src, &dest);
4143 if (src == INVALID_SOCKET || dest == INVALID_SOCKET)
4145 skip("failed to create sockets\n");
4146 goto end;
4149 bufs.len = sizeof(buf);
4150 bufs.buf = buf;
4151 flags = 0;
4153 ov.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
4154 ok(ov.hEvent != NULL, "could not create event object, errno = %d\n", GetLastError());
4155 if (!ov.hEvent)
4156 goto end;
4158 ling.l_onoff = 1;
4159 ling.l_linger = 0;
4160 iret = setsockopt (src, SOL_SOCKET, SO_LINGER, (char *) &ling, sizeof(ling));
4161 ok(!iret, "Failed to set linger %d\n", GetLastError());
4163 iret = WSARecv(dest, &bufs, 1, NULL, &flags, &ov, NULL);
4164 ok(iret == SOCKET_ERROR && GetLastError() == ERROR_IO_PENDING, "WSARecv failed - %d error %d\n", iret, GetLastError());
4166 iret = WSARecv(dest, &bufs, 1, &bytesReturned, &flags, &ov, NULL);
4167 ok(iret == SOCKET_ERROR && GetLastError() == ERROR_IO_PENDING, "WSARecv failed - %d error %d\n", iret, GetLastError());
4169 closesocket(src);
4170 src = INVALID_SOCKET;
4172 dwret = WaitForSingleObject(ov.hEvent, 1000);
4173 ok(dwret == WAIT_OBJECT_0, "Waiting for disconnect event failed with %d + errno %d\n", dwret, GetLastError());
4175 bret = GetOverlappedResult((HANDLE)dest, &ov, &bytesReturned, FALSE);
4176 todo_wine ok(!bret && (GetLastError() == ERROR_NETNAME_DELETED || broken(GetLastError() == ERROR_IO_INCOMPLETE) /* win9x */),
4177 "Did not get disconnect event: %d, error %d\n", bret, GetLastError());
4178 ok(bytesReturned == 0, "Bytes received is %d\n", bytesReturned);
4180 src = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0);
4181 ok(src != INVALID_SOCKET, "failed to create socket %d\n", WSAGetLastError());
4182 if (src == INVALID_SOCKET) goto end;
4184 server = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
4185 ok(server != INVALID_SOCKET, "failed to create socket %d\n", WSAGetLastError());
4186 if (server == INVALID_SOCKET) goto end;
4188 memset(&addr, 0, sizeof(addr));
4189 addr.sin_family = AF_INET;
4190 addr.sin_addr.s_addr = inet_addr("127.0.0.1");
4191 iret = bind(server, (struct sockaddr *)&addr, sizeof(addr));
4192 if (iret) goto end;
4194 len = sizeof(addr);
4195 iret = getsockname(server, (struct sockaddr *)&addr, &len);
4196 if (iret) goto end;
4198 iret = listen(server, 1);
4199 if (iret) goto end;
4201 iret = connect(src, (struct sockaddr *)&addr, sizeof(addr));
4202 if (iret) goto end;
4204 len = sizeof(addr);
4205 dest = accept(server, (struct sockaddr *)&addr, &len);
4206 ok(dest != INVALID_SOCKET, "failed to create socket %d\n", WSAGetLastError());
4207 if (dest == INVALID_SOCKET) goto end;
4209 send(src, "test message", sizeof("test message"), 0);
4210 thread = CreateThread(NULL, 0, recv_thread, &dest, 0, &id);
4211 CloseHandle(thread);
4213 end:
4214 if (server != INVALID_SOCKET)
4215 closesocket(server);
4216 if (dest != INVALID_SOCKET)
4217 closesocket(dest);
4218 if (src != INVALID_SOCKET)
4219 closesocket(src);
4220 if (ov.hEvent)
4221 WSACloseEvent(ov.hEvent);
4224 static void test_GetAddrInfoW(void)
4226 static const WCHAR port[] = {'8','0',0};
4227 static const WCHAR empty[] = {0};
4228 static const WCHAR localhost[] = {'l','o','c','a','l','h','o','s','t',0};
4229 static const WCHAR zero[] = {'0',0};
4230 int ret;
4231 ADDRINFOW *result, hint;
4233 if (!pGetAddrInfoW || !pFreeAddrInfoW)
4235 win_skip("GetAddrInfoW and/or FreeAddrInfoW not present\n");
4236 return;
4238 memset(&hint, 0, sizeof(ADDRINFOW));
4240 ret = pGetAddrInfoW(NULL, NULL, NULL, &result);
4241 ok(ret == WSAHOST_NOT_FOUND, "got %d expected WSAHOST_NOT_FOUND\n", ret);
4243 result = NULL;
4244 ret = pGetAddrInfoW(empty, NULL, NULL, &result);
4245 ok(!ret, "GetAddrInfoW failed with %d\n", WSAGetLastError());
4246 ok(result != NULL, "GetAddrInfoW failed\n");
4247 pFreeAddrInfoW(result);
4249 result = NULL;
4250 ret = pGetAddrInfoW(NULL, zero, NULL, &result);
4251 ok(!ret, "GetAddrInfoW failed with %d\n", WSAGetLastError());
4252 ok(result != NULL, "GetAddrInfoW failed\n");
4253 pFreeAddrInfoW(result);
4255 result = NULL;
4256 ret = pGetAddrInfoW(empty, zero, NULL, &result);
4257 ok(!ret, "GetAddrInfoW failed with %d\n", WSAGetLastError());
4258 ok(result != NULL, "GetAddrInfoW failed\n");
4259 pFreeAddrInfoW(result);
4261 result = NULL;
4262 ret = pGetAddrInfoW(localhost, NULL, NULL, &result);
4263 ok(!ret, "GetAddrInfoW failed with %d\n", WSAGetLastError());
4264 pFreeAddrInfoW(result);
4266 result = NULL;
4267 ret = pGetAddrInfoW(localhost, empty, NULL, &result);
4268 ok(!ret, "GetAddrInfoW failed with %d\n", WSAGetLastError());
4269 pFreeAddrInfoW(result);
4271 result = NULL;
4272 ret = pGetAddrInfoW(localhost, zero, NULL, &result);
4273 ok(!ret, "GetAddrInfoW failed with %d\n", WSAGetLastError());
4274 pFreeAddrInfoW(result);
4276 result = NULL;
4277 ret = pGetAddrInfoW(localhost, port, NULL, &result);
4278 ok(!ret, "GetAddrInfoW failed with %d\n", WSAGetLastError());
4279 pFreeAddrInfoW(result);
4281 result = NULL;
4282 ret = pGetAddrInfoW(localhost, port, &hint, &result);
4283 ok(!ret, "GetAddrInfoW failed with %d\n", WSAGetLastError());
4284 pFreeAddrInfoW(result);
4287 static void test_getaddrinfo(void)
4289 int ret;
4290 ADDRINFOA *result, hint;
4292 if (!pgetaddrinfo || !pfreeaddrinfo)
4294 win_skip("getaddrinfo and/or freeaddrinfo not present\n");
4295 return;
4297 memset(&hint, 0, sizeof(ADDRINFOA));
4299 ret = pgetaddrinfo(NULL, NULL, NULL, &result);
4300 ok(ret == WSAHOST_NOT_FOUND, "got %d expected WSAHOST_NOT_FOUND\n", ret);
4302 result = NULL;
4303 ret = pgetaddrinfo("", NULL, NULL, &result);
4304 ok(!ret, "getaddrinfo failed with %d\n", WSAGetLastError());
4305 ok(result != NULL, "getaddrinfo failed\n");
4306 pfreeaddrinfo(result);
4308 result = NULL;
4309 ret = pgetaddrinfo(NULL, "0", NULL, &result);
4310 ok(!ret, "getaddrinfo failed with %d\n", WSAGetLastError());
4311 ok(result != NULL, "getaddrinfo failed\n");
4312 pfreeaddrinfo(result);
4314 result = NULL;
4315 ret = pgetaddrinfo("", "0", NULL, &result);
4316 ok(!ret, "getaddrinfo failed with %d\n", WSAGetLastError());
4317 ok(result != NULL, "getaddrinfo failed\n");
4318 pfreeaddrinfo(result);
4320 result = NULL;
4321 ret = pgetaddrinfo("localhost", NULL, NULL, &result);
4322 ok(!ret, "getaddrinfo failed with %d\n", WSAGetLastError());
4323 pfreeaddrinfo(result);
4325 result = NULL;
4326 ret = pgetaddrinfo("localhost", "", NULL, &result);
4327 ok(!ret, "getaddrinfo failed with %d\n", WSAGetLastError());
4328 pfreeaddrinfo(result);
4330 result = NULL;
4331 ret = pgetaddrinfo("localhost", "0", NULL, &result);
4332 ok(!ret, "getaddrinfo failed with %d\n", WSAGetLastError());
4333 pfreeaddrinfo(result);
4335 result = NULL;
4336 ret = pgetaddrinfo("localhost", "80", NULL, &result);
4337 ok(!ret, "getaddrinfo failed with %d\n", WSAGetLastError());
4338 pfreeaddrinfo(result);
4340 result = NULL;
4341 ret = pgetaddrinfo("localhost", "80", &hint, &result);
4342 ok(!ret, "getaddrinfo failed with %d\n", WSAGetLastError());
4343 pfreeaddrinfo(result);
4346 static void test_ConnectEx(void)
4348 SOCKET listener = INVALID_SOCKET;
4349 SOCKET acceptor = INVALID_SOCKET;
4350 SOCKET connector = INVALID_SOCKET;
4351 struct sockaddr_in address, conaddress;
4352 int addrlen;
4353 OVERLAPPED overlapped;
4354 LPFN_CONNECTEX pConnectEx;
4355 GUID connectExGuid = WSAID_CONNECTEX;
4356 DWORD bytesReturned;
4357 char buffer[1024];
4358 BOOL bret;
4359 DWORD dwret;
4360 int iret;
4362 memset(&overlapped, 0, sizeof(overlapped));
4364 listener = socket(AF_INET, SOCK_STREAM, 0);
4365 if (listener == INVALID_SOCKET) {
4366 skip("could not create listener socket, error %d\n", WSAGetLastError());
4367 goto end;
4370 connector = socket(AF_INET, SOCK_STREAM, 0);
4371 if (connector == INVALID_SOCKET) {
4372 skip("could not create connector socket, error %d\n", WSAGetLastError());
4373 goto end;
4376 memset(&address, 0, sizeof(address));
4377 address.sin_family = AF_INET;
4378 address.sin_addr.s_addr = inet_addr("127.0.0.1");
4379 iret = bind(listener, (struct sockaddr*)&address, sizeof(address));
4380 if (iret != 0) {
4381 skip("failed to bind, error %d\n", WSAGetLastError());
4382 goto end;
4385 addrlen = sizeof(address);
4386 iret = getsockname(listener, (struct sockaddr*)&address, &addrlen);
4387 if (iret != 0) {
4388 skip("failed to lookup bind address, error %d\n", WSAGetLastError());
4389 goto end;
4392 if (set_blocking(listener, TRUE)) {
4393 skip("couldn't make socket non-blocking, error %d\n", WSAGetLastError());
4394 goto end;
4397 iret = WSAIoctl(connector, SIO_GET_EXTENSION_FUNCTION_POINTER, &connectExGuid, sizeof(connectExGuid),
4398 &pConnectEx, sizeof(pConnectEx), &bytesReturned, NULL, NULL);
4399 if (iret) {
4400 win_skip("WSAIoctl failed to get ConnectEx with ret %d + errno %d\n", iret, WSAGetLastError());
4401 goto end;
4404 bret = pConnectEx(INVALID_SOCKET, (struct sockaddr*)&address, addrlen, NULL, 0, &bytesReturned, &overlapped);
4405 ok(bret == FALSE && WSAGetLastError() == WSAENOTSOCK, "ConnectEx on invalid socket "
4406 "returned %d + errno %d\n", bret, WSAGetLastError());
4408 bret = pConnectEx(connector, (struct sockaddr*)&address, addrlen, NULL, 0, &bytesReturned, &overlapped);
4409 todo_wine ok(bret == FALSE && WSAGetLastError() == WSAEINVAL, "ConnectEx on a unbound socket "
4410 "returned %d + errno %d\n", bret, WSAGetLastError());
4411 if (bret == TRUE || WSAGetLastError() != WSAEINVAL)
4413 acceptor = accept(listener, NULL, NULL);
4414 if (acceptor != INVALID_SOCKET) {
4415 closesocket(acceptor);
4416 acceptor = INVALID_SOCKET;
4419 closesocket(connector);
4420 connector = socket(AF_INET, SOCK_STREAM, 0);
4421 if (connector == INVALID_SOCKET) {
4422 skip("could not create connector socket, error %d\n", WSAGetLastError());
4423 goto end;
4427 /* ConnectEx needs a bound socket */
4428 memset(&conaddress, 0, sizeof(conaddress));
4429 conaddress.sin_family = AF_INET;
4430 conaddress.sin_addr.s_addr = inet_addr("127.0.0.1");
4431 iret = bind(connector, (struct sockaddr*)&conaddress, sizeof(conaddress));
4432 if (iret != 0) {
4433 skip("failed to bind, error %d\n", WSAGetLastError());
4434 goto end;
4437 bret = pConnectEx(connector, (struct sockaddr*)&address, addrlen, NULL, 0, &bytesReturned, NULL);
4438 ok(bret == FALSE && WSAGetLastError() == ERROR_INVALID_PARAMETER, "ConnectEx on a NULL overlapped "
4439 "returned %d + errno %d\n", bret, WSAGetLastError());
4441 overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
4442 if (overlapped.hEvent == NULL) {
4443 skip("could not create event object, errno = %d\n", GetLastError());
4444 goto end;
4447 iret = listen(listener, 1);
4448 if (iret != 0) {
4449 skip("listening failed, errno = %d\n", WSAGetLastError());
4450 goto end;
4453 bret = pConnectEx(connector, (struct sockaddr*)&address, addrlen, NULL, 0, &bytesReturned, &overlapped);
4454 ok(bret == FALSE && WSAGetLastError() == ERROR_IO_PENDING, "ConnectEx failed: "
4455 "returned %d + errno %d\n", bret, WSAGetLastError());
4456 dwret = WaitForSingleObject(overlapped.hEvent, 15000);
4457 ok(dwret == WAIT_OBJECT_0, "Waiting for connect event failed with %d + errno %d\n", dwret, GetLastError());
4459 bret = GetOverlappedResult((HANDLE)connector, &overlapped, &bytesReturned, FALSE);
4460 ok(bret, "Connecting failed, error %d\n", GetLastError());
4461 ok(bytesReturned == 0, "Bytes sent is %d\n", bytesReturned);
4463 closesocket(connector);
4464 connector = socket(AF_INET, SOCK_STREAM, 0);
4465 if (connector == INVALID_SOCKET) {
4466 skip("could not create connector socket, error %d\n", WSAGetLastError());
4467 goto end;
4469 /* ConnectEx needs a bound socket */
4470 memset(&conaddress, 0, sizeof(conaddress));
4471 conaddress.sin_family = AF_INET;
4472 conaddress.sin_addr.s_addr = inet_addr("127.0.0.1");
4473 iret = bind(connector, (struct sockaddr*)&conaddress, sizeof(conaddress));
4474 if (iret != 0) {
4475 skip("failed to bind, error %d\n", WSAGetLastError());
4476 goto end;
4479 acceptor = accept(listener, NULL, NULL);
4480 if (acceptor != INVALID_SOCKET) {
4481 closesocket(acceptor);
4484 buffer[0] = '1';
4485 buffer[1] = '2';
4486 buffer[2] = '3';
4487 bret = pConnectEx(connector, (struct sockaddr*)&address, addrlen, buffer, 3, &bytesReturned, &overlapped);
4488 ok(bret == FALSE && WSAGetLastError() == ERROR_IO_PENDING, "ConnectEx failed: "
4489 "returned %d + errno %d\n", bret, WSAGetLastError());
4490 dwret = WaitForSingleObject(overlapped.hEvent, 15000);
4491 ok(dwret == WAIT_OBJECT_0, "Waiting for connect event failed with %d + errno %d\n", dwret, GetLastError());
4493 bret = GetOverlappedResult((HANDLE)connector, &overlapped, &bytesReturned, FALSE);
4494 ok(bret, "Connecting failed, error %d\n", GetLastError());
4495 ok(bytesReturned == 3, "Bytes sent is %d\n", bytesReturned);
4497 acceptor = accept(listener, NULL, NULL);
4498 ok(acceptor != INVALID_SOCKET, "could not accept socket error %d\n", WSAGetLastError());
4500 bytesReturned = recv(acceptor, buffer, 3, 0);
4501 buffer[4] = 0;
4502 ok(bytesReturned == 3, "Didn't get all sent data, got only %d\n", bytesReturned);
4503 ok(buffer[0] == '1' && buffer[1] == '2' && buffer[2] == '3',
4504 "Failed to get the right data, expected '123', got '%s'\n", buffer);
4506 closesocket(connector);
4507 connector = socket(AF_INET, SOCK_STREAM, 0);
4508 if (connector == INVALID_SOCKET) {
4509 skip("could not create connector socket, error %d\n", WSAGetLastError());
4510 goto end;
4512 /* ConnectEx needs a bound socket */
4513 memset(&conaddress, 0, sizeof(conaddress));
4514 conaddress.sin_family = AF_INET;
4515 conaddress.sin_addr.s_addr = inet_addr("127.0.0.1");
4516 iret = bind(connector, (struct sockaddr*)&conaddress, sizeof(conaddress));
4517 if (iret != 0) {
4518 skip("failed to bind, error %d\n", WSAGetLastError());
4519 goto end;
4522 if (acceptor != INVALID_SOCKET) {
4523 closesocket(acceptor);
4524 acceptor = INVALID_SOCKET;
4527 /* Connect with error */
4528 closesocket(listener);
4529 listener = INVALID_SOCKET;
4531 address.sin_port = htons(1);
4533 bret = pConnectEx(connector, (struct sockaddr*)&address, addrlen, NULL, 0, &bytesReturned, &overlapped);
4534 ok(bret == FALSE && GetLastError(), "ConnectEx to bad destination failed: "
4535 "returned %d + errno %d\n", bret, GetLastError());
4537 if (GetLastError() == ERROR_IO_PENDING)
4539 dwret = WaitForSingleObject(overlapped.hEvent, 15000);
4540 ok(dwret == WAIT_OBJECT_0, "Waiting for connect event failed with %d + errno %d\n", dwret, GetLastError());
4542 bret = GetOverlappedResult((HANDLE)connector, &overlapped, &bytesReturned, FALSE);
4543 ok(bret == FALSE && GetLastError() == ERROR_CONNECTION_REFUSED,
4544 "Connecting to a disconnected host returned error %d - %d\n", bret, WSAGetLastError());
4546 else {
4547 ok(GetLastError() == WSAECONNREFUSED,
4548 "Connecting to a disconnected host returned error %d - %d\n", bret, WSAGetLastError());
4551 end:
4552 if (overlapped.hEvent)
4553 WSACloseEvent(overlapped.hEvent);
4554 if (listener != INVALID_SOCKET)
4555 closesocket(listener);
4556 if (acceptor != INVALID_SOCKET)
4557 closesocket(acceptor);
4558 if (connector != INVALID_SOCKET)
4559 closesocket(connector);
4562 static void test_AcceptEx(void)
4564 SOCKET listener = INVALID_SOCKET;
4565 SOCKET acceptor = INVALID_SOCKET;
4566 SOCKET connector = INVALID_SOCKET;
4567 SOCKET connector2 = INVALID_SOCKET;
4568 struct sockaddr_in bindAddress, peerAddress, *readBindAddress, *readRemoteAddress;
4569 int socklen, optlen;
4570 GUID acceptExGuid = WSAID_ACCEPTEX, getAcceptExGuid = WSAID_GETACCEPTEXSOCKADDRS;
4571 LPFN_ACCEPTEX pAcceptEx = NULL;
4572 LPFN_GETACCEPTEXSOCKADDRS pGetAcceptExSockaddrs = NULL;
4573 fd_set fds_accept, fds_send;
4574 struct timeval timeout = {0,10}; /* wait for 10 milliseconds */
4575 int got, conn1, i;
4576 DWORD bytesReturned, connect_time;
4577 char buffer[1024], ipbuffer[32];
4578 OVERLAPPED overlapped;
4579 int iret, localSize = sizeof(struct sockaddr_in), remoteSize = localSize;
4580 BOOL bret;
4581 DWORD dwret;
4583 memset(&overlapped, 0, sizeof(overlapped));
4585 listener = socket(AF_INET, SOCK_STREAM, 0);
4586 if (listener == INVALID_SOCKET) {
4587 skip("could not create listener socket, error %d\n", WSAGetLastError());
4588 goto end;
4591 acceptor = socket(AF_INET, SOCK_STREAM, 0);
4592 if (acceptor == INVALID_SOCKET) {
4593 skip("could not create acceptor socket, error %d\n", WSAGetLastError());
4594 goto end;
4597 connector = socket(AF_INET, SOCK_STREAM, 0);
4598 if (connector == INVALID_SOCKET) {
4599 skip("could not create connector socket, error %d\n", WSAGetLastError());
4600 goto end;
4603 memset(&bindAddress, 0, sizeof(bindAddress));
4604 bindAddress.sin_family = AF_INET;
4605 bindAddress.sin_addr.s_addr = inet_addr("127.0.0.1");
4606 iret = bind(listener, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
4607 if (iret != 0) {
4608 skip("failed to bind, error %d\n", WSAGetLastError());
4609 goto end;
4612 socklen = sizeof(bindAddress);
4613 iret = getsockname(listener, (struct sockaddr*)&bindAddress, &socklen);
4614 if (iret != 0) {
4615 skip("failed to lookup bind address, error %d\n", WSAGetLastError());
4616 goto end;
4619 if (set_blocking(listener, FALSE)) {
4620 skip("couldn't make socket non-blocking, error %d\n", WSAGetLastError());
4621 goto end;
4624 iret = WSAIoctl(listener, SIO_GET_EXTENSION_FUNCTION_POINTER, &acceptExGuid, sizeof(acceptExGuid),
4625 &pAcceptEx, sizeof(pAcceptEx), &bytesReturned, NULL, NULL);
4626 if (iret) {
4627 skip("WSAIoctl failed to get AcceptEx with ret %d + errno %d\n", iret, WSAGetLastError());
4628 goto end;
4631 iret = WSAIoctl(listener, SIO_GET_EXTENSION_FUNCTION_POINTER, &getAcceptExGuid, sizeof(getAcceptExGuid),
4632 &pGetAcceptExSockaddrs, sizeof(pGetAcceptExSockaddrs), &bytesReturned, NULL, NULL);
4633 if (iret) {
4634 skip("WSAIoctl failed to get GetAcceptExSockaddrs with ret %d + errno %d\n", iret, WSAGetLastError());
4635 goto end;
4638 bret = pAcceptEx(INVALID_SOCKET, acceptor, buffer, sizeof(buffer) - 2*(sizeof(struct sockaddr_in) + 16),
4639 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
4640 &bytesReturned, &overlapped);
4641 ok(bret == FALSE && WSAGetLastError() == WSAENOTSOCK, "AcceptEx on invalid listening socket "
4642 "returned %d + errno %d\n", bret, WSAGetLastError());
4644 bret = pAcceptEx(listener, INVALID_SOCKET, buffer, sizeof(buffer) - 2*(sizeof(struct sockaddr_in) + 16),
4645 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
4646 &bytesReturned, &overlapped);
4647 ok(bret == FALSE && WSAGetLastError() == WSAEINVAL, "AcceptEx on invalid accepting socket "
4648 "returned %d + errno %d\n", bret, WSAGetLastError());
4650 bret = pAcceptEx(listener, acceptor, NULL, sizeof(buffer) - 2*(sizeof(struct sockaddr_in) + 16),
4651 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
4652 &bytesReturned, &overlapped);
4653 ok(bret == FALSE &&
4654 (WSAGetLastError() == WSAEINVAL ||
4655 broken(WSAGetLastError() == WSAEFAULT)), /* NT4 */
4656 "AcceptEx on NULL buffer returned %d + errno %d\n", bret, WSAGetLastError());
4658 bret = pAcceptEx(listener, acceptor, buffer, 0, 0, sizeof(struct sockaddr_in) + 16,
4659 &bytesReturned, &overlapped);
4660 todo_wine ok(bret == FALSE && WSAGetLastError() == WSAEINVAL, "AcceptEx on too small local address size "
4661 "returned %d + errno %d\n", bret, WSAGetLastError());
4663 bret = pAcceptEx(listener, acceptor, buffer, 0, sizeof(struct sockaddr_in) + 16, 0,
4664 &bytesReturned, &overlapped);
4665 todo_wine ok(bret == FALSE && WSAGetLastError() == WSAEINVAL, "AcceptEx on too small remote address size "
4666 "returned %d + errno %d\n", bret, WSAGetLastError());
4668 bret = pAcceptEx(listener, acceptor, buffer, 0,
4669 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
4670 &bytesReturned, NULL);
4671 ok(bret == FALSE && WSAGetLastError() == ERROR_INVALID_PARAMETER, "AcceptEx on a NULL overlapped "
4672 "returned %d + errno %d\n", bret, WSAGetLastError());
4674 bret = pAcceptEx(listener, acceptor, buffer, sizeof(buffer) - 2*(sizeof(struct sockaddr_in) + 16),
4675 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
4676 &bytesReturned, &overlapped);
4677 todo_wine ok(bret == FALSE && WSAGetLastError() == WSAEINVAL, "AcceptEx on a non-listening socket "
4678 "returned %d + errno %d\n", bret, WSAGetLastError());
4680 iret = listen(listener, 5);
4681 if (iret != 0) {
4682 skip("listening failed, errno = %d\n", WSAGetLastError());
4683 goto end;
4686 overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
4687 if (overlapped.hEvent == NULL) {
4688 skip("could not create event object, errno = %d\n", GetLastError());
4689 goto end;
4692 bret = pAcceptEx(listener, acceptor, buffer, 0,
4693 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
4694 &bytesReturned, &overlapped);
4695 ok(bret == FALSE && WSAGetLastError() == ERROR_IO_PENDING, "AcceptEx returned %d + errno %d\n", bret, WSAGetLastError());
4697 bret = pAcceptEx(listener, acceptor, buffer, 0,
4698 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
4699 &bytesReturned, &overlapped);
4700 todo_wine ok((bret == FALSE && WSAGetLastError() == WSAEINVAL) || broken(bret == FALSE && WSAGetLastError() == ERROR_IO_PENDING) /* NT4 */,
4701 "AcceptEx on already pending socket returned %d + errno %d\n", bret, WSAGetLastError());
4702 if (bret == FALSE && WSAGetLastError() == ERROR_IO_PENDING) {
4703 /* We need to cancel this call, otherwise things fail */
4704 bret = CancelIo((HANDLE) listener);
4705 ok(bret, "Failed to cancel failed test. Bailing...\n");
4706 if (!bret) return;
4707 WaitForSingleObject(overlapped.hEvent, 0);
4709 bret = pAcceptEx(listener, acceptor, buffer, 0,
4710 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
4711 &bytesReturned, &overlapped);
4712 ok(bret == FALSE && WSAGetLastError() == ERROR_IO_PENDING, "AcceptEx returned %d + errno %d\n", bret, WSAGetLastError());
4715 iret = connect(acceptor, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
4716 todo_wine ok((iret == SOCKET_ERROR && WSAGetLastError() == WSAEINVAL) || broken(!iret) /* NT4 */,
4717 "connecting to acceptex acceptor succeeded? return %d + errno %d\n", iret, WSAGetLastError());
4718 if (!iret || (iret == SOCKET_ERROR && WSAGetLastError() == WSAEWOULDBLOCK)) {
4719 /* We need to cancel this call, otherwise things fail */
4720 closesocket(acceptor);
4721 acceptor = socket(AF_INET, SOCK_STREAM, 0);
4722 if (acceptor == INVALID_SOCKET) {
4723 skip("could not create acceptor socket, error %d\n", WSAGetLastError());
4724 goto end;
4727 bret = CancelIo((HANDLE) listener);
4728 ok(bret, "Failed to cancel failed test. Bailing...\n");
4729 if (!bret) return;
4731 bret = pAcceptEx(listener, acceptor, buffer, 0,
4732 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
4733 &bytesReturned, &overlapped);
4734 ok(bret == FALSE && WSAGetLastError() == ERROR_IO_PENDING, "AcceptEx returned %d + errno %d\n", bret, WSAGetLastError());
4737 iret = connect(connector, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
4738 ok(iret == 0, "connecting to accepting socket failed, error %d\n", WSAGetLastError());
4740 dwret = WaitForSingleObject(overlapped.hEvent, INFINITE);
4741 ok(dwret == WAIT_OBJECT_0, "Waiting for accept event failed with %d + errno %d\n", dwret, GetLastError());
4743 bret = GetOverlappedResult((HANDLE)listener, &overlapped, &bytesReturned, FALSE);
4744 ok(bret, "GetOverlappedResult failed, error %d\n", GetLastError());
4745 ok(bytesReturned == 0, "bytesReturned isn't supposed to be %d\n", bytesReturned);
4747 closesocket(connector);
4748 connector = INVALID_SOCKET;
4749 closesocket(acceptor);
4751 /* Test short reads */
4753 acceptor = socket(AF_INET, SOCK_STREAM, 0);
4754 if (acceptor == INVALID_SOCKET) {
4755 skip("could not create acceptor socket, error %d\n", WSAGetLastError());
4756 goto end;
4758 connector = socket(AF_INET, SOCK_STREAM, 0);
4759 if (connector == INVALID_SOCKET) {
4760 skip("could not create connector socket, error %d\n", WSAGetLastError());
4761 goto end;
4763 bret = pAcceptEx(listener, acceptor, buffer, 2,
4764 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
4765 &bytesReturned, &overlapped);
4766 ok(bret == FALSE && WSAGetLastError() == ERROR_IO_PENDING, "AcceptEx returned %d + errno %d\n", bret, WSAGetLastError());
4768 connect_time = 0xdeadbeef;
4769 optlen = sizeof(connect_time);
4770 iret = getsockopt(connector, SOL_SOCKET, SO_CONNECT_TIME, (char *)&connect_time, &optlen);
4771 ok(!iret, "getsockopt failed %d\n", WSAGetLastError());
4772 ok(connect_time == ~0u, "unexpected connect time %u\n", connect_time);
4774 iret = connect(connector, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
4775 ok(iret == 0, "connecting to accepting socket failed, error %d\n", WSAGetLastError());
4777 connect_time = 0xdeadbeef;
4778 optlen = sizeof(connect_time);
4779 iret = getsockopt(connector, SOL_SOCKET, SO_CONNECT_TIME, (char *)&connect_time, &optlen);
4780 ok(!iret, "getsockopt failed %d\n", WSAGetLastError());
4781 ok(connect_time < 0xdeadbeef, "unexpected connect time %u\n", connect_time);
4783 dwret = WaitForSingleObject(overlapped.hEvent, 0);
4784 ok(dwret == WAIT_TIMEOUT, "Waiting for accept event timeout failed with %d + errno %d\n", dwret, GetLastError());
4786 iret = getsockname( connector, (struct sockaddr *)&peerAddress, &remoteSize);
4787 ok( !iret, "getsockname failed.\n");
4789 /* Check if the buffer from AcceptEx is decoded correctly */
4790 pGetAcceptExSockaddrs(buffer, 2, sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
4791 (struct sockaddr **)&readBindAddress, &localSize,
4792 (struct sockaddr **)&readRemoteAddress, &remoteSize);
4793 strcpy( ipbuffer, inet_ntoa(readBindAddress->sin_addr));
4794 ok( readBindAddress->sin_addr.s_addr == bindAddress.sin_addr.s_addr,
4795 "Local socket address is different %s != %s\n",
4796 ipbuffer, inet_ntoa(bindAddress.sin_addr));
4797 ok( readBindAddress->sin_port == bindAddress.sin_port,
4798 "Local socket port is different: %d != %d\n",
4799 readBindAddress->sin_port, bindAddress.sin_port);
4800 strcpy( ipbuffer, inet_ntoa(readRemoteAddress->sin_addr));
4801 ok( readRemoteAddress->sin_addr.s_addr == peerAddress.sin_addr.s_addr,
4802 "Remote socket address is different %s != %s\n",
4803 ipbuffer, inet_ntoa(peerAddress.sin_addr));
4804 ok( readRemoteAddress->sin_port == peerAddress.sin_port,
4805 "Remote socket port is different: %d != %d\n",
4806 readRemoteAddress->sin_port, peerAddress.sin_port);
4808 iret = send(connector, buffer, 1, 0);
4809 ok(iret == 1, "could not send 1 byte: send %d errno %d\n", iret, WSAGetLastError());
4811 dwret = WaitForSingleObject(overlapped.hEvent, 1000);
4812 ok(dwret == WAIT_OBJECT_0, "Waiting for accept event failed with %d + errno %d\n", dwret, GetLastError());
4814 bret = GetOverlappedResult((HANDLE)listener, &overlapped, &bytesReturned, FALSE);
4815 ok(bret, "GetOverlappedResult failed, error %d\n", GetLastError());
4816 ok(bytesReturned == 1, "bytesReturned isn't supposed to be %d\n", bytesReturned);
4818 closesocket(connector);
4819 connector = INVALID_SOCKET;
4820 closesocket(acceptor);
4822 /* Test CF_DEFER & AcceptEx interaction */
4824 acceptor = socket(AF_INET, SOCK_STREAM, 0);
4825 if (acceptor == INVALID_SOCKET) {
4826 skip("could not create acceptor socket, error %d\n", WSAGetLastError());
4827 goto end;
4829 connector = socket(AF_INET, SOCK_STREAM, 0);
4830 if (connector == INVALID_SOCKET) {
4831 skip("could not create connector socket, error %d\n", WSAGetLastError());
4832 goto end;
4834 connector2 = socket(AF_INET, SOCK_STREAM, 0);
4835 if (connector == INVALID_SOCKET) {
4836 skip("could not create connector socket, error %d\n", WSAGetLastError());
4837 goto end;
4840 if (set_blocking(connector, FALSE)) {
4841 skip("couldn't make socket non-blocking, error %d\n", WSAGetLastError());
4842 goto end;
4845 if (set_blocking(connector2, FALSE)) {
4846 skip("couldn't make socket non-blocking, error %d\n", WSAGetLastError());
4847 goto end;
4850 /* Connect socket #1 */
4851 iret = connect(connector, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
4852 ok(iret == SOCKET_ERROR && WSAGetLastError() == WSAEWOULDBLOCK, "connecting to accepting socket failed, error %d\n", WSAGetLastError());
4854 FD_ZERO ( &fds_accept );
4855 FD_ZERO ( &fds_send );
4857 FD_SET ( listener, &fds_accept );
4858 FD_SET ( connector, &fds_send );
4860 buffer[0] = '0';
4861 got = 0;
4862 conn1 = 0;
4864 for (i = 0; i < 4000; ++i)
4866 fd_set fds_openaccept = fds_accept, fds_opensend = fds_send;
4868 wsa_ok ( ( select ( 0, &fds_openaccept, &fds_opensend, NULL, &timeout ) ), SOCKET_ERROR !=,
4869 "acceptex test(%d): could not select on socket, errno %d\n" );
4871 /* check for incoming requests */
4872 if ( FD_ISSET ( listener, &fds_openaccept ) ) {
4873 got++;
4874 if (got == 1) {
4875 SOCKET tmp = WSAAccept(listener, NULL, NULL, (LPCONDITIONPROC) AlwaysDeferConditionFunc, 0);
4876 ok(tmp == INVALID_SOCKET && WSAGetLastError() == WSATRY_AGAIN, "Failed to defer connection, %d\n", WSAGetLastError());
4877 bret = pAcceptEx(listener, acceptor, buffer, 0,
4878 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
4879 &bytesReturned, &overlapped);
4880 ok(bret == FALSE && WSAGetLastError() == ERROR_IO_PENDING, "AcceptEx returned %d + errno %d\n", bret, WSAGetLastError());
4882 else if (got == 2) {
4883 /* this should be socket #2 */
4884 SOCKET tmp = accept(listener, NULL, NULL);
4885 ok(tmp != INVALID_SOCKET, "accept failed %d\n", WSAGetLastError());
4886 closesocket(tmp);
4888 else {
4889 ok(FALSE, "Got more than 2 connections?\n");
4892 if ( conn1 && FD_ISSET ( connector2, &fds_opensend ) ) {
4893 /* Send data on second socket, and stop */
4894 send(connector2, "2", 1, 0);
4895 FD_CLR ( connector2, &fds_send );
4897 break;
4899 if ( FD_ISSET ( connector, &fds_opensend ) ) {
4900 /* Once #1 is connected, allow #2 to connect */
4901 conn1 = 1;
4903 send(connector, "1", 1, 0);
4904 FD_CLR ( connector, &fds_send );
4906 iret = connect(connector2, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
4907 ok(iret == SOCKET_ERROR && WSAGetLastError() == WSAEWOULDBLOCK, "connecting to accepting socket failed, error %d\n", WSAGetLastError());
4908 FD_SET ( connector2, &fds_send );
4912 ok (got == 2 || broken(got == 1) /* NT4 */,
4913 "Did not get both connections, got %d\n", got);
4915 dwret = WaitForSingleObject(overlapped.hEvent, 0);
4916 ok(dwret == WAIT_OBJECT_0, "Waiting for accept event failed with %d + errno %d\n", dwret, GetLastError());
4918 bret = GetOverlappedResult((HANDLE)listener, &overlapped, &bytesReturned, FALSE);
4919 ok(bret, "GetOverlappedResult failed, error %d\n", GetLastError());
4920 ok(bytesReturned == 0, "bytesReturned isn't supposed to be %d\n", bytesReturned);
4922 set_blocking(acceptor, TRUE);
4923 iret = recv( acceptor, buffer, 2, 0);
4924 ok(iret == 1, "Failed to get data, %d, errno: %d\n", iret, WSAGetLastError());
4926 ok(buffer[0] == '1', "The wrong first client was accepted by acceptex: %c != 1\n", buffer[0]);
4928 closesocket(connector);
4929 connector = INVALID_SOCKET;
4930 closesocket(acceptor);
4932 /* clean up in case of failures */
4933 while ((acceptor = accept(listener, NULL, NULL)) != INVALID_SOCKET)
4934 closesocket(acceptor);
4936 /* Disconnect during receive? */
4938 acceptor = socket(AF_INET, SOCK_STREAM, 0);
4939 if (acceptor == INVALID_SOCKET) {
4940 skip("could not create acceptor socket, error %d\n", WSAGetLastError());
4941 goto end;
4943 connector = socket(AF_INET, SOCK_STREAM, 0);
4944 if (connector == INVALID_SOCKET) {
4945 skip("could not create connector socket, error %d\n", WSAGetLastError());
4946 goto end;
4948 bret = pAcceptEx(listener, acceptor, buffer, sizeof(buffer) - 2*(sizeof(struct sockaddr_in) + 16),
4949 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
4950 &bytesReturned, &overlapped);
4951 ok(bret == FALSE && WSAGetLastError() == ERROR_IO_PENDING, "AcceptEx returned %d + errno %d\n", bret, WSAGetLastError());
4953 iret = connect(connector, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
4954 ok(iret == 0, "connecting to accepting socket failed, error %d\n", WSAGetLastError());
4956 closesocket(connector);
4957 connector = INVALID_SOCKET;
4959 dwret = WaitForSingleObject(overlapped.hEvent, 1000);
4960 ok(dwret == WAIT_OBJECT_0, "Waiting for accept event failed with %d + errno %d\n", dwret, GetLastError());
4962 bret = GetOverlappedResult((HANDLE)listener, &overlapped, &bytesReturned, FALSE);
4963 ok(bret, "GetOverlappedResult failed, error %d\n", GetLastError());
4964 ok(bytesReturned == 0, "bytesReturned isn't supposed to be %d\n", bytesReturned);
4966 closesocket(acceptor);
4968 /* Test closing with pending requests */
4970 acceptor = socket(AF_INET, SOCK_STREAM, 0);
4971 if (acceptor == INVALID_SOCKET) {
4972 skip("could not create acceptor socket, error %d\n", WSAGetLastError());
4973 goto end;
4975 bret = pAcceptEx(listener, acceptor, buffer, sizeof(buffer) - 2*(sizeof(struct sockaddr_in) + 16),
4976 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
4977 &bytesReturned, &overlapped);
4978 ok(bret == FALSE && WSAGetLastError() == ERROR_IO_PENDING, "AcceptEx returned %d + errno %d\n", bret, WSAGetLastError());
4980 closesocket(acceptor);
4982 dwret = WaitForSingleObject(overlapped.hEvent, 1000);
4983 todo_wine ok(dwret == WAIT_OBJECT_0 || broken(dwret == WAIT_TIMEOUT) /* NT4/2000 */,
4984 "Waiting for accept event failed with %d + errno %d\n", dwret, GetLastError());
4986 if (dwret != WAIT_TIMEOUT) {
4987 bret = GetOverlappedResult((HANDLE)listener, &overlapped, &bytesReturned, FALSE);
4988 ok(!bret && GetLastError() == ERROR_OPERATION_ABORTED, "GetOverlappedResult failed, error %d\n", GetLastError());
4990 else {
4991 bret = CancelIo((HANDLE) listener);
4992 ok(bret, "Failed to cancel failed test. Bailing...\n");
4993 if (!bret) return;
4994 WaitForSingleObject(overlapped.hEvent, 0);
4997 acceptor = socket(AF_INET, SOCK_STREAM, 0);
4998 if (acceptor == INVALID_SOCKET) {
4999 skip("could not create acceptor socket, error %d\n", WSAGetLastError());
5000 goto end;
5002 bret = pAcceptEx(listener, acceptor, buffer, sizeof(buffer) - 2*(sizeof(struct sockaddr_in) + 16),
5003 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
5004 &bytesReturned, &overlapped);
5005 ok(bret == FALSE && WSAGetLastError() == ERROR_IO_PENDING, "AcceptEx returned %d + errno %d\n", bret, WSAGetLastError());
5007 CancelIo((HANDLE) acceptor);
5009 dwret = WaitForSingleObject(overlapped.hEvent, 1000);
5010 ok(dwret == WAIT_TIMEOUT, "Waiting for timeout failed with %d + errno %d\n", dwret, GetLastError());
5012 closesocket(acceptor);
5014 acceptor = socket(AF_INET, SOCK_STREAM, 0);
5015 if (acceptor == INVALID_SOCKET) {
5016 skip("could not create acceptor socket, error %d\n", WSAGetLastError());
5017 goto end;
5019 bret = pAcceptEx(listener, acceptor, buffer, sizeof(buffer) - 2*(sizeof(struct sockaddr_in) + 16),
5020 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
5021 &bytesReturned, &overlapped);
5022 ok(bret == FALSE && WSAGetLastError() == ERROR_IO_PENDING, "AcceptEx returned %d + errno %d\n", bret, WSAGetLastError());
5024 closesocket(listener);
5025 listener = INVALID_SOCKET;
5027 dwret = WaitForSingleObject(overlapped.hEvent, 1000);
5028 ok(dwret == WAIT_OBJECT_0, "Waiting for accept event failed with %d + errno %d\n", dwret, GetLastError());
5030 bret = GetOverlappedResult((HANDLE)listener, &overlapped, &bytesReturned, FALSE);
5031 ok(!bret && GetLastError() == ERROR_OPERATION_ABORTED, "GetOverlappedResult failed, error %d\n", GetLastError());
5033 end:
5034 if (overlapped.hEvent)
5035 WSACloseEvent(overlapped.hEvent);
5036 if (listener != INVALID_SOCKET)
5037 closesocket(listener);
5038 if (acceptor != INVALID_SOCKET)
5039 closesocket(acceptor);
5040 if (connector != INVALID_SOCKET)
5041 closesocket(connector);
5042 if (connector2 != INVALID_SOCKET)
5043 closesocket(connector2);
5046 static void test_getpeername(void)
5048 SOCKET sock;
5049 struct sockaddr_in sa, sa_out;
5050 int sa_len;
5051 const char buf[] = "hello world";
5052 int ret;
5054 /* Test the parameter validation order. */
5055 ret = getpeername(INVALID_SOCKET, NULL, NULL);
5056 ok(ret == SOCKET_ERROR, "Expected getpeername to return SOCKET_ERROR, got %d\n", ret);
5057 ok(WSAGetLastError() == WSAENOTSOCK,
5058 "Expected WSAGetLastError() to return WSAENOTSOCK, got %d\n", WSAGetLastError());
5060 sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
5061 ok(sock != INVALID_SOCKET, "Expected socket to return a valid socket\n");
5062 if (sock == INVALID_SOCKET)
5064 skip("Socket creation failed with %d\n", WSAGetLastError());
5065 return;
5068 ret = getpeername(sock, NULL, NULL);
5069 ok(ret == SOCKET_ERROR, "Expected getpeername to return SOCKET_ERROR, got %d\n", ret);
5070 ok(WSAGetLastError() == WSAENOTCONN ||
5071 broken(WSAGetLastError() == WSAEFAULT), /* Win9x and WinMe */
5072 "Expected WSAGetLastError() to return WSAENOTCONN, got %d\n", WSAGetLastError());
5074 memset(&sa, 0, sizeof(sa));
5075 sa.sin_family = AF_INET;
5076 sa.sin_port = htons(139);
5077 sa.sin_addr.s_addr = inet_addr("127.0.0.1");
5079 /* sendto does not change a socket's connection state. */
5080 ret = sendto(sock, buf, sizeof(buf), 0, (struct sockaddr*)&sa, sizeof(sa));
5081 ok(ret != SOCKET_ERROR,
5082 "Expected sendto to succeed, WSAGetLastError() = %d\n", WSAGetLastError());
5084 ret = getpeername(sock, NULL, NULL);
5085 ok(ret == SOCKET_ERROR, "Expected getpeername to return SOCKET_ERROR, got %d\n", ret);
5086 ok(WSAGetLastError() == WSAENOTCONN ||
5087 broken(WSAGetLastError() == WSAEFAULT), /* Win9x and WinMe */
5088 "Expected WSAGetLastError() to return WSAENOTCONN, got %d\n", WSAGetLastError());
5090 ret = connect(sock, (struct sockaddr*)&sa, sizeof(sa));
5091 ok(ret == 0,
5092 "Expected connect to succeed, WSAGetLastError() = %d\n", WSAGetLastError());
5094 ret = getpeername(sock, NULL, NULL);
5095 ok(ret == SOCKET_ERROR, "Expected getpeername to return SOCKET_ERROR, got %d\n", ret);
5096 ok(WSAGetLastError() == WSAEFAULT,
5097 "Expected WSAGetLastError() to return WSAEFAULT, got %d\n", WSAGetLastError());
5099 /* Test crashes on Wine. */
5100 if (0)
5102 ret = getpeername(sock, (void*)0xdeadbeef, (void*)0xcafebabe);
5103 ok(ret == SOCKET_ERROR, "Expected getpeername to return SOCKET_ERROR, got %d\n", ret);
5104 ok(WSAGetLastError() == WSAEFAULT,
5105 "Expected WSAGetLastError() to return WSAEFAULT, got %d\n", WSAGetLastError());
5108 sa_len = 0;
5109 ret = getpeername(sock, (struct sockaddr*)&sa_out, &sa_len);
5110 ok(ret == SOCKET_ERROR, "Expected getpeername to return 0, got %d\n", ret);
5111 ok(WSAGetLastError() == WSAEFAULT,
5112 "Expected WSAGetLastError() to return WSAEFAULT, got %d\n", WSAGetLastError());
5114 sa_len = sizeof(sa_out);
5115 ret = getpeername(sock, (struct sockaddr*)&sa_out, &sa_len);
5116 ok(ret == 0, "Expected getpeername to return 0, got %d\n", ret);
5117 ok(!memcmp(&sa, &sa_out, sizeof(sa)),
5118 "Expected the returned structure to be identical to the connect structure\n");
5120 closesocket(sock);
5123 static void test_sioRoutingInterfaceQuery(void)
5125 int ret;
5126 SOCKET sock;
5127 SOCKADDR_IN sin = { 0 }, sout = { 0 };
5128 DWORD bytesReturned;
5130 sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
5131 ok(sock != INVALID_SOCKET, "Expected socket to return a valid socket\n");
5132 if (sock == INVALID_SOCKET)
5134 skip("Socket creation failed with %d\n", WSAGetLastError());
5135 return;
5137 ret = WSAIoctl(sock, SIO_ROUTING_INTERFACE_QUERY, NULL, 0, NULL, 0, NULL,
5138 NULL, NULL);
5139 ok(ret == SOCKET_ERROR && WSAGetLastError() == WSAEFAULT,
5140 "expected WSAEFAULT, got %d\n", WSAGetLastError());
5141 ret = WSAIoctl(sock, SIO_ROUTING_INTERFACE_QUERY, &sin, sizeof(sin),
5142 NULL, 0, NULL, NULL, NULL);
5143 ok(ret == SOCKET_ERROR && WSAGetLastError() == WSAEFAULT,
5144 "expected WSAEFAULT, got %d\n", WSAGetLastError());
5145 ret = WSAIoctl(sock, SIO_ROUTING_INTERFACE_QUERY, &sin, sizeof(sin),
5146 NULL, 0, &bytesReturned, NULL, NULL);
5147 ok(ret == SOCKET_ERROR &&
5148 (WSAGetLastError() == WSAEFAULT /* Win98 */ ||
5149 WSAGetLastError() == WSAEINVAL /* NT4 */||
5150 WSAGetLastError() == WSAEAFNOSUPPORT),
5151 "expected WSAEFAULT or WSAEINVAL or WSAEAFNOSUPPORT, got %d\n",
5152 WSAGetLastError());
5153 sin.sin_family = AF_INET;
5154 ret = WSAIoctl(sock, SIO_ROUTING_INTERFACE_QUERY, &sin, sizeof(sin),
5155 NULL, 0, &bytesReturned, NULL, NULL);
5156 ok(ret == SOCKET_ERROR &&
5157 (WSAGetLastError() == WSAEFAULT /* Win98 */ ||
5158 WSAGetLastError() == WSAEINVAL),
5159 "expected WSAEFAULT or WSAEINVAL, got %d\n", WSAGetLastError());
5160 sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
5161 ret = WSAIoctl(sock, SIO_ROUTING_INTERFACE_QUERY, &sin, sizeof(sin),
5162 NULL, 0, &bytesReturned, NULL, NULL);
5163 ok(ret == SOCKET_ERROR &&
5164 (WSAGetLastError() == WSAEINVAL /* NT4 */ ||
5165 WSAGetLastError() == WSAEFAULT),
5166 "expected WSAEINVAL or WSAEFAULT, got %d\n", WSAGetLastError());
5167 ret = WSAIoctl(sock, SIO_ROUTING_INTERFACE_QUERY, &sin, sizeof(sin),
5168 &sout, sizeof(sout), &bytesReturned, NULL, NULL);
5169 ok(!ret || broken(WSAGetLastError() == WSAEINVAL /* NT4 */),
5170 "WSAIoctl failed: %d\n", WSAGetLastError());
5171 if (!ret)
5173 ok(sout.sin_family == AF_INET, "expected AF_INET, got %d\n",
5174 sout.sin_family);
5175 /* We expect the source address to be INADDR_LOOPBACK as well, but
5176 * there's no guarantee that a route to the loopback address exists,
5177 * so rather than introduce spurious test failures we do not test the
5178 * source address.
5181 closesocket(sock);
5184 static void test_synchronous_WSAIoctl(void)
5186 HANDLE previous_port, io_port;
5187 WSAOVERLAPPED overlapped, *olp;
5188 SOCKET socket;
5189 ULONG on;
5190 ULONG_PTR key;
5191 DWORD num_bytes;
5192 BOOL ret;
5193 int res;
5195 previous_port = CreateIoCompletionPort( INVALID_HANDLE_VALUE, NULL, 0, 0 );
5196 ok( previous_port != NULL, "failed to create completion port %u\n", GetLastError() );
5198 socket = WSASocketW( AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED );
5199 ok( socket != INVALID_SOCKET, "failed to create socket %d\n", WSAGetLastError() );
5201 io_port = CreateIoCompletionPort( (HANDLE)socket, previous_port, 0, 0 );
5202 ok( io_port != NULL, "failed to create completion port %u\n", GetLastError() );
5204 on = 1;
5205 memset( &overlapped, 0, sizeof(overlapped) );
5206 res = WSAIoctl( socket, FIONBIO, &on, sizeof(on), NULL, 0, &num_bytes, &overlapped, NULL );
5207 ok( !res, "WSAIoctl failed %d\n", WSAGetLastError() );
5209 ret = GetQueuedCompletionStatus( io_port, &num_bytes, &key, &olp, 10000 );
5210 ok( ret, "failed to get completion status %u\n", GetLastError() );
5212 CloseHandle( io_port );
5213 closesocket( socket );
5214 CloseHandle( previous_port );
5217 #define WM_ASYNCCOMPLETE (WM_USER + 100)
5218 static HWND create_async_message_window(void)
5220 static const char class_name[] = "ws2_32 async message window class";
5222 WNDCLASSEXA wndclass;
5223 HWND hWnd;
5225 wndclass.cbSize = sizeof(wndclass);
5226 wndclass.style = CS_HREDRAW | CS_VREDRAW;
5227 wndclass.lpfnWndProc = DefWindowProcA;
5228 wndclass.cbClsExtra = 0;
5229 wndclass.cbWndExtra = 0;
5230 wndclass.hInstance = GetModuleHandleA(NULL);
5231 wndclass.hIcon = LoadIconA(NULL, IDI_APPLICATION);
5232 wndclass.hIconSm = LoadIconA(NULL, IDI_APPLICATION);
5233 wndclass.hCursor = LoadCursorA(NULL, IDC_ARROW);
5234 wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
5235 wndclass.lpszClassName = class_name;
5236 wndclass.lpszMenuName = NULL;
5238 RegisterClassExA(&wndclass);
5240 hWnd = CreateWindow(class_name, "ws2_32 async message window", WS_OVERLAPPEDWINDOW,
5241 0, 0, 500, 500, NULL, NULL, GetModuleHandleA(NULL), NULL);
5242 if (!hWnd)
5244 ok(0, "failed to create window: %u\n", GetLastError());
5245 return NULL;
5248 return hWnd;
5251 static void test_WSAAsyncGetServByPort(void)
5253 HWND hwnd = create_async_message_window();
5254 HANDLE ret;
5255 char buffer[MAXGETHOSTSTRUCT];
5257 if (!hwnd)
5258 return;
5260 /* FIXME: The asynchronous window messages should be tested. */
5262 /* Parameters are not checked when initiating the asynchronous operation. */
5263 ret = WSAAsyncGetServByPort(NULL, 0, 0, NULL, NULL, 0);
5264 ok(ret != NULL, "WSAAsyncGetServByPort returned NULL\n");
5266 ret = WSAAsyncGetServByPort(hwnd, WM_ASYNCCOMPLETE, 0, NULL, NULL, 0);
5267 ok(ret != NULL, "WSAAsyncGetServByPort returned NULL\n");
5269 ret = WSAAsyncGetServByPort(hwnd, WM_ASYNCCOMPLETE, htons(80), NULL, NULL, 0);
5270 ok(ret != NULL, "WSAAsyncGetServByPort returned NULL\n");
5272 ret = WSAAsyncGetServByPort(hwnd, WM_ASYNCCOMPLETE, htons(80), NULL, buffer, MAXGETHOSTSTRUCT);
5273 ok(ret != NULL, "WSAAsyncGetServByPort returned NULL\n");
5275 DestroyWindow(hwnd);
5278 static void test_WSAAsyncGetServByName(void)
5280 HWND hwnd = create_async_message_window();
5281 HANDLE ret;
5282 char buffer[MAXGETHOSTSTRUCT];
5284 if (!hwnd)
5285 return;
5287 /* FIXME: The asynchronous window messages should be tested. */
5289 /* Parameters are not checked when initiating the asynchronous operation. */
5290 ret = WSAAsyncGetServByName(hwnd, WM_ASYNCCOMPLETE, "", NULL, NULL, 0);
5291 ok(ret != NULL, "WSAAsyncGetServByName returned NULL\n");
5293 ret = WSAAsyncGetServByName(hwnd, WM_ASYNCCOMPLETE, "", "", buffer, MAXGETHOSTSTRUCT);
5294 ok(ret != NULL, "WSAAsyncGetServByName returned NULL\n");
5296 ret = WSAAsyncGetServByName(hwnd, WM_ASYNCCOMPLETE, "http", NULL, NULL, 0);
5297 ok(ret != NULL, "WSAAsyncGetServByName returned NULL\n");
5299 ret = WSAAsyncGetServByName(hwnd, WM_ASYNCCOMPLETE, "http", "tcp", buffer, MAXGETHOSTSTRUCT);
5300 ok(ret != NULL, "WSAAsyncGetServByName returned NULL\n");
5302 DestroyWindow(hwnd);
5306 * Provide consistent initialization for the AcceptEx IOCP tests.
5308 static SOCKET setup_iocp_src(struct sockaddr_in *bindAddress)
5310 SOCKET src, ret = INVALID_SOCKET;
5311 int iret, socklen;
5313 src = socket(AF_INET, SOCK_STREAM, 0);
5314 if (src == INVALID_SOCKET)
5316 skip("could not create listener socket, error %d\n", WSAGetLastError());
5317 goto end;
5320 memset(bindAddress, 0, sizeof(*bindAddress));
5321 bindAddress->sin_family = AF_INET;
5322 bindAddress->sin_addr.s_addr = inet_addr("127.0.0.1");
5323 iret = bind(src, (struct sockaddr*)bindAddress, sizeof(*bindAddress));
5324 if (iret != 0)
5326 skip("failed to bind, error %d\n", WSAGetLastError());
5327 goto end;
5330 socklen = sizeof(*bindAddress);
5331 iret = getsockname(src, (struct sockaddr*)bindAddress, &socklen);
5332 if (iret != 0) {
5333 skip("failed to lookup bind address, error %d\n", WSAGetLastError());
5334 goto end;
5337 if (set_blocking(src, FALSE))
5339 skip("couldn't make socket non-blocking, error %d\n", WSAGetLastError());
5340 goto end;
5343 iret = listen(src, 5);
5344 if (iret != 0)
5346 skip("listening failed, errno = %d\n", WSAGetLastError());
5347 goto end;
5350 ret = src;
5351 end:
5352 if (src != ret && ret == INVALID_SOCKET)
5353 closesocket(src);
5354 return ret;
5357 static void test_completion_port(void)
5359 HANDLE previous_port, io_port;
5360 WSAOVERLAPPED ov, *olp;
5361 SOCKET src, dest, dup, connector = INVALID_SOCKET;
5362 WSAPROTOCOL_INFOA info;
5363 char buf[1024];
5364 WSABUF bufs;
5365 DWORD num_bytes, flags;
5366 struct linger ling;
5367 int iret;
5368 BOOL bret;
5369 ULONG_PTR key;
5370 struct sockaddr_in bindAddress;
5371 GUID acceptExGuid = WSAID_ACCEPTEX;
5372 LPFN_ACCEPTEX pAcceptEx = NULL;
5374 previous_port = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
5375 ok( previous_port != NULL, "Failed to create completion port %u\n", GetLastError());
5377 memset(&ov, 0, sizeof(ov));
5379 tcp_socketpair(&src, &dest);
5380 if (src == INVALID_SOCKET || dest == INVALID_SOCKET)
5382 skip("failed to create sockets\n");
5383 goto end;
5386 bufs.len = sizeof(buf);
5387 bufs.buf = buf;
5388 flags = 0;
5390 ling.l_onoff = 1;
5391 ling.l_linger = 0;
5392 iret = setsockopt (src, SOL_SOCKET, SO_LINGER, (char *) &ling, sizeof(ling));
5393 ok(!iret, "Failed to set linger %d\n", GetLastError());
5395 io_port = CreateIoCompletionPort( (HANDLE)dest, previous_port, 125, 0 );
5396 ok(io_port != NULL, "Failed to create completion port %u\n", GetLastError());
5398 SetLastError(0xdeadbeef);
5400 iret = WSARecv(dest, &bufs, 1, &num_bytes, &flags, &ov, NULL);
5401 ok(iret == SOCKET_ERROR, "WSARecv returned %d\n", iret);
5402 ok(GetLastError() == ERROR_IO_PENDING, "Last error was %d\n", GetLastError());
5404 closesocket(src);
5405 src = INVALID_SOCKET;
5407 SetLastError(0xdeadbeef);
5408 key = 0xdeadbeef;
5409 num_bytes = 0xdeadbeef;
5410 olp = (WSAOVERLAPPED *)0xdeadbeef;
5412 bret = GetQueuedCompletionStatus(io_port, &num_bytes, &key, &olp, 100);
5413 todo_wine ok(bret == FALSE, "GetQueuedCompletionStatus returned %d\n", bret);
5414 todo_wine ok(GetLastError() == ERROR_NETNAME_DELETED, "Last error was %d\n", GetLastError());
5415 ok(key == 125, "Key is %lu\n", key);
5416 ok(num_bytes == 0, "Number of bytes received is %u\n", num_bytes);
5417 ok(olp == &ov, "Overlapped structure is at %p\n", olp);
5419 SetLastError(0xdeadbeef);
5420 key = 0xdeadbeef;
5421 num_bytes = 0xdeadbeef;
5422 olp = (WSAOVERLAPPED *)0xdeadbeef;
5424 bret = GetQueuedCompletionStatus(io_port, &num_bytes, &key, &olp, 100);
5425 ok(bret == FALSE, "GetQueuedCompletionStatus returned %d\n", bret );
5426 ok(GetLastError() == WAIT_TIMEOUT, "Last error was %d\n", GetLastError());
5427 ok(key == 0xdeadbeef, "Key is %lu\n", key);
5428 ok(num_bytes == 0xdeadbeef, "Number of bytes transferred is %u\n", num_bytes);
5429 ok(!olp, "Overlapped structure is at %p\n", olp);
5431 if (dest != INVALID_SOCKET)
5432 closesocket(dest);
5434 memset(&ov, 0, sizeof(ov));
5436 tcp_socketpair(&src, &dest);
5437 if (src == INVALID_SOCKET || dest == INVALID_SOCKET)
5439 skip("failed to create sockets\n");
5440 goto end;
5443 bufs.len = sizeof(buf);
5444 bufs.buf = buf;
5445 flags = 0;
5447 ling.l_onoff = 1;
5448 ling.l_linger = 0;
5449 iret = setsockopt (src, SOL_SOCKET, SO_LINGER, (char *) &ling, sizeof(ling));
5450 ok(!iret, "Failed to set linger %d\n", GetLastError());
5452 io_port = CreateIoCompletionPort((HANDLE)dest, previous_port, 125, 0);
5453 ok(io_port != NULL, "failed to create completion port %u\n", GetLastError());
5455 set_blocking(dest, FALSE);
5457 closesocket(src);
5458 src = INVALID_SOCKET;
5459 num_bytes = 0xdeadbeef;
5460 SetLastError(0xdeadbeef);
5462 iret = WSASend(dest, &bufs, 1, &num_bytes, 0, &ov, NULL);
5463 ok(iret == SOCKET_ERROR, "WSASend failed - %d\n", iret);
5464 ok(GetLastError() == WSAECONNRESET, "Last error was %d\n", GetLastError());
5465 ok(num_bytes == 0xdeadbeef, "Managed to send %d\n", num_bytes);
5467 SetLastError(0xdeadbeef);
5468 key = 0xdeadbeef;
5469 num_bytes = 0xdeadbeef;
5470 olp = (WSAOVERLAPPED *)0xdeadbeef;
5472 bret = GetQueuedCompletionStatus( io_port, &num_bytes, &key, &olp, 200 );
5473 ok(bret == FALSE, "GetQueuedCompletionStatus returned %u\n", bret );
5474 ok(GetLastError() == WAIT_TIMEOUT, "Last error was %d\n", GetLastError());
5475 ok(key == 0xdeadbeef, "Key is %lu\n", key);
5476 ok(num_bytes == 0xdeadbeef, "Number of bytes transferred is %u\n", num_bytes);
5477 ok(!olp, "Overlapped structure is at %p\n", olp);
5479 if (dest != INVALID_SOCKET)
5480 closesocket(dest);
5482 dest = socket(AF_INET, SOCK_STREAM, 0);
5483 if (dest == INVALID_SOCKET)
5485 skip("could not create acceptor socket, error %d\n", WSAGetLastError());
5486 goto end;
5489 iret = WSAIoctl(dest, SIO_GET_EXTENSION_FUNCTION_POINTER, &acceptExGuid, sizeof(acceptExGuid),
5490 &pAcceptEx, sizeof(pAcceptEx), &num_bytes, NULL, NULL);
5491 if (iret)
5493 skip("WSAIoctl failed to get AcceptEx with ret %d + errno %d\n", iret, WSAGetLastError());
5494 goto end;
5497 /* Test IOCP response on socket close (IOCP created after AcceptEx) */
5499 if ((src = setup_iocp_src(&bindAddress)) == INVALID_SOCKET)
5500 goto end;
5502 SetLastError(0xdeadbeef);
5504 bret = pAcceptEx(src, dest, buf, sizeof(buf) - 2*(sizeof(struct sockaddr_in) + 16),
5505 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
5506 &num_bytes, &ov);
5507 ok(bret == FALSE, "AcceptEx returned %d\n", bret);
5508 ok(GetLastError() == ERROR_IO_PENDING, "Last error was %d\n", GetLastError());
5510 io_port = CreateIoCompletionPort((HANDLE)src, previous_port, 125, 0);
5511 ok(io_port != NULL, "failed to create completion port %u\n", GetLastError());
5513 closesocket(src);
5514 src = INVALID_SOCKET;
5516 SetLastError(0xdeadbeef);
5517 key = 0xdeadbeef;
5518 num_bytes = 0xdeadbeef;
5519 olp = (WSAOVERLAPPED *)0xdeadbeef;
5521 bret = GetQueuedCompletionStatus(io_port, &num_bytes, &key, &olp, 100);
5522 ok(bret == FALSE, "failed to get completion status %u\n", bret);
5523 ok(GetLastError() == ERROR_OPERATION_ABORTED, "Last error was %d\n", GetLastError());
5524 ok(key == 125, "Key is %lu\n", key);
5525 ok(num_bytes == 0, "Number of bytes transferred is %u\n", num_bytes);
5526 ok(olp == &ov, "Overlapped structure is at %p\n", olp);
5527 ok(olp && (olp->Internal == (ULONG)STATUS_CANCELLED), "Internal status is %lx\n", olp ? olp->Internal : 0);
5529 SetLastError(0xdeadbeef);
5530 key = 0xdeadbeef;
5531 num_bytes = 0xdeadbeef;
5532 olp = (WSAOVERLAPPED *)0xdeadbeef;
5533 bret = GetQueuedCompletionStatus( io_port, &num_bytes, &key, &olp, 200 );
5534 ok(bret == FALSE, "failed to get completion status %u\n", bret);
5535 ok(GetLastError() == WAIT_TIMEOUT, "Last error was %d\n", GetLastError());
5536 ok(key == 0xdeadbeef, "Key is %lu\n", key);
5537 ok(num_bytes == 0xdeadbeef, "Number of bytes transferred is %u\n", num_bytes);
5538 ok(!olp, "Overlapped structure is at %p\n", olp);
5540 /* Test IOCP response on socket close (IOCP created before AcceptEx) */
5542 if ((src = setup_iocp_src(&bindAddress)) == INVALID_SOCKET)
5543 goto end;
5545 SetLastError(0xdeadbeef);
5547 io_port = CreateIoCompletionPort((HANDLE)src, previous_port, 125, 0);
5548 ok(io_port != NULL, "failed to create completion port %u\n", GetLastError());
5550 bret = pAcceptEx(src, dest, buf, sizeof(buf) - 2*(sizeof(struct sockaddr_in) + 16),
5551 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
5552 &num_bytes, &ov);
5553 ok(bret == FALSE, "AcceptEx returned %d\n", bret);
5554 ok(GetLastError() == ERROR_IO_PENDING, "Last error was %d\n", GetLastError());
5556 closesocket(src);
5557 src = INVALID_SOCKET;
5559 SetLastError(0xdeadbeef);
5560 key = 0xdeadbeef;
5561 num_bytes = 0xdeadbeef;
5562 olp = (WSAOVERLAPPED *)0xdeadbeef;
5564 bret = GetQueuedCompletionStatus(io_port, &num_bytes, &key, &olp, 100);
5565 ok(bret == FALSE, "failed to get completion status %u\n", bret);
5566 ok(GetLastError() == ERROR_OPERATION_ABORTED, "Last error was %d\n", GetLastError());
5567 ok(key == 125, "Key is %lu\n", key);
5568 ok(num_bytes == 0, "Number of bytes transferred is %u\n", num_bytes);
5569 ok(olp == &ov, "Overlapped structure is at %p\n", olp);
5570 ok(olp && (olp->Internal == (ULONG)STATUS_CANCELLED), "Internal status is %lx\n", olp ? olp->Internal : 0);
5572 SetLastError(0xdeadbeef);
5573 key = 0xdeadbeef;
5574 num_bytes = 0xdeadbeef;
5575 olp = (WSAOVERLAPPED *)0xdeadbeef;
5576 bret = GetQueuedCompletionStatus( io_port, &num_bytes, &key, &olp, 200 );
5577 ok(bret == FALSE, "failed to get completion status %u\n", bret);
5578 ok(GetLastError() == WAIT_TIMEOUT, "Last error was %d\n", GetLastError());
5579 ok(key == 0xdeadbeef, "Key is %lu\n", key);
5580 ok(num_bytes == 0xdeadbeef, "Number of bytes transferred is %u\n", num_bytes);
5581 ok(!olp, "Overlapped structure is at %p\n", olp);
5583 /* Test IOCP with duplicated handle */
5585 if ((src = setup_iocp_src(&bindAddress)) == INVALID_SOCKET)
5586 goto end;
5588 SetLastError(0xdeadbeef);
5590 io_port = CreateIoCompletionPort((HANDLE)src, previous_port, 125, 0);
5591 ok(io_port != NULL, "failed to create completion port %u\n", GetLastError());
5593 WSADuplicateSocket( src, GetCurrentProcessId(), &info );
5594 dup = WSASocket(AF_INET, SOCK_STREAM, 0, &info, 0, WSA_FLAG_OVERLAPPED);
5595 ok(dup != INVALID_SOCKET, "failed to duplicate socket!\n");
5597 bret = pAcceptEx(dup, dest, buf, sizeof(buf) - 2*(sizeof(struct sockaddr_in) + 16),
5598 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
5599 &num_bytes, &ov);
5600 ok(bret == FALSE, "AcceptEx returned %d\n", bret);
5601 ok(GetLastError() == ERROR_IO_PENDING, "Last error was %d\n", GetLastError());
5603 SetLastError(0xdeadbeef);
5604 key = 0xdeadbeef;
5605 num_bytes = 0xdeadbeef;
5606 olp = (WSAOVERLAPPED *)0xdeadbeef;
5607 bret = GetQueuedCompletionStatus( io_port, &num_bytes, &key, &olp, 200 );
5608 ok(bret == FALSE, "failed to get completion status %u\n", bret);
5609 ok(GetLastError() == WAIT_TIMEOUT, "Last error was %d\n", GetLastError());
5610 ok(key == 0xdeadbeef, "Key is %lu\n", key);
5611 ok(num_bytes == 0xdeadbeef, "Number of bytes transferred is %u\n", num_bytes);
5612 ok(!olp, "Overlapped structure is at %p\n", olp);
5614 closesocket(src);
5615 src = INVALID_SOCKET;
5616 closesocket(dup);
5617 dup = INVALID_SOCKET;
5619 SetLastError(0xdeadbeef);
5620 key = 0xdeadbeef;
5621 num_bytes = 0xdeadbeef;
5622 olp = (WSAOVERLAPPED *)0xdeadbeef;
5623 bret = GetQueuedCompletionStatus(io_port, &num_bytes, &key, &olp, 100);
5624 ok(bret == FALSE, "failed to get completion status %u\n", bret);
5625 ok(GetLastError() == ERROR_OPERATION_ABORTED, "Last error was %d\n", GetLastError());
5626 ok(key == 125, "Key is %lu\n", key);
5627 ok(num_bytes == 0, "Number of bytes transferred is %u\n", num_bytes);
5628 ok(olp == &ov, "Overlapped structure is at %p\n", olp);
5629 ok(olp && olp->Internal == (ULONG)STATUS_CANCELLED, "Internal status is %lx\n", olp ? olp->Internal : 0);
5631 SetLastError(0xdeadbeef);
5632 key = 0xdeadbeef;
5633 num_bytes = 0xdeadbeef;
5634 olp = (WSAOVERLAPPED *)0xdeadbeef;
5635 bret = GetQueuedCompletionStatus( io_port, &num_bytes, &key, &olp, 200 );
5636 ok(bret == FALSE, "failed to get completion status %u\n", bret);
5637 ok(GetLastError() == WAIT_TIMEOUT, "Last error was %d\n", GetLastError());
5638 ok(key == 0xdeadbeef, "Key is %lu\n", key);
5639 ok(num_bytes == 0xdeadbeef, "Number of bytes transferred is %u\n", num_bytes);
5640 ok(!olp, "Overlapped structure is at %p\n", olp);
5642 /* Test IOCP with duplicated handle (closing duplicated handle) */
5644 if ((src = setup_iocp_src(&bindAddress)) == INVALID_SOCKET)
5645 goto end;
5647 SetLastError(0xdeadbeef);
5649 io_port = CreateIoCompletionPort((HANDLE)src, previous_port, 125, 0);
5650 ok(io_port != NULL, "failed to create completion port %u\n", GetLastError());
5652 WSADuplicateSocket( src, GetCurrentProcessId(), &info );
5653 dup = WSASocket(AF_INET, SOCK_STREAM, 0, &info, 0, WSA_FLAG_OVERLAPPED);
5654 ok(dup != INVALID_SOCKET, "failed to duplicate socket!\n");
5656 bret = pAcceptEx(dup, dest, buf, sizeof(buf) - 2*(sizeof(struct sockaddr_in) + 16),
5657 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
5658 &num_bytes, &ov);
5659 ok(bret == FALSE, "AcceptEx returned %d\n", bret);
5660 ok(GetLastError() == ERROR_IO_PENDING, "Last error was %d\n", GetLastError());
5662 closesocket(dup);
5663 dup = INVALID_SOCKET;
5665 SetLastError(0xdeadbeef);
5666 key = 0xdeadbeef;
5667 num_bytes = 0xdeadbeef;
5668 olp = (WSAOVERLAPPED *)0xdeadbeef;
5669 bret = GetQueuedCompletionStatus( io_port, &num_bytes, &key, &olp, 200 );
5670 ok(bret == FALSE, "failed to get completion status %u\n", bret);
5671 ok(GetLastError() == WAIT_TIMEOUT, "Last error was %d\n", GetLastError());
5672 ok(key == 0xdeadbeef, "Key is %lu\n", key);
5673 ok(num_bytes == 0xdeadbeef, "Number of bytes transferred is %u\n", num_bytes);
5674 ok(!olp, "Overlapped structure is at %p\n", olp);
5676 SetLastError(0xdeadbeef);
5677 key = 0xdeadbeef;
5678 num_bytes = 0xdeadbeef;
5679 olp = (WSAOVERLAPPED *)0xdeadbeef;
5680 bret = GetQueuedCompletionStatus( io_port, &num_bytes, &key, &olp, 200 );
5681 ok(bret == FALSE, "failed to get completion status %u\n", bret);
5682 ok(GetLastError() == WAIT_TIMEOUT, "Last error was %d\n", GetLastError());
5683 ok(key == 0xdeadbeef, "Key is %lu\n", key);
5684 ok(num_bytes == 0xdeadbeef, "Number of bytes transferred is %u\n", num_bytes);
5685 ok(!olp, "Overlapped structure is at %p\n", olp);
5687 closesocket(src);
5688 src = INVALID_SOCKET;
5690 bret = GetQueuedCompletionStatus(io_port, &num_bytes, &key, &olp, 100);
5691 ok(bret == FALSE, "failed to get completion status %u\n", bret);
5692 ok(GetLastError() == ERROR_OPERATION_ABORTED, "Last error was %d\n", GetLastError());
5693 ok(key == 125, "Key is %lu\n", key);
5694 ok(num_bytes == 0, "Number of bytes transferred is %u\n", num_bytes);
5695 ok(olp == &ov, "Overlapped structure is at %p\n", olp);
5696 ok(olp && (olp->Internal == (ULONG)STATUS_CANCELLED), "Internal status is %lx\n", olp ? olp->Internal : 0);
5698 SetLastError(0xdeadbeef);
5699 key = 0xdeadbeef;
5700 num_bytes = 0xdeadbeef;
5701 olp = (WSAOVERLAPPED *)0xdeadbeef;
5702 bret = GetQueuedCompletionStatus( io_port, &num_bytes, &key, &olp, 200 );
5703 ok(bret == FALSE, "failed to get completion status %u\n", bret);
5704 ok(GetLastError() == WAIT_TIMEOUT, "Last error was %d\n", GetLastError());
5705 ok(key == 0xdeadbeef, "Key is %lu\n", key);
5706 ok(num_bytes == 0xdeadbeef, "Number of bytes transferred is %u\n", num_bytes);
5707 ok(!olp, "Overlapped structure is at %p\n", olp);
5709 /* Test IOCP with duplicated handle (closing original handle) */
5711 if ((src = setup_iocp_src(&bindAddress)) == INVALID_SOCKET)
5712 goto end;
5714 SetLastError(0xdeadbeef);
5716 io_port = CreateIoCompletionPort((HANDLE)src, previous_port, 125, 0);
5717 ok(io_port != NULL, "failed to create completion port %u\n", GetLastError());
5719 WSADuplicateSocket( src, GetCurrentProcessId(), &info );
5720 dup = WSASocket(AF_INET, SOCK_STREAM, 0, &info, 0, WSA_FLAG_OVERLAPPED);
5721 ok(dup != INVALID_SOCKET, "failed to duplicate socket!\n");
5723 bret = pAcceptEx(dup, dest, buf, sizeof(buf) - 2*(sizeof(struct sockaddr_in) + 16),
5724 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
5725 &num_bytes, &ov);
5726 ok(bret == FALSE, "AcceptEx returned %d\n", bret);
5727 ok(GetLastError() == ERROR_IO_PENDING, "Last error was %d\n", GetLastError());
5729 closesocket(src);
5730 src = INVALID_SOCKET;
5732 SetLastError(0xdeadbeef);
5733 key = 0xdeadbeef;
5734 num_bytes = 0xdeadbeef;
5735 olp = (WSAOVERLAPPED *)0xdeadbeef;
5736 bret = GetQueuedCompletionStatus( io_port, &num_bytes, &key, &olp, 200 );
5737 ok(bret == FALSE, "failed to get completion status %u\n", bret);
5738 ok(GetLastError() == WAIT_TIMEOUT, "Last error was %d\n", GetLastError());
5739 ok(key == 0xdeadbeef, "Key is %lu\n", key);
5740 ok(num_bytes == 0xdeadbeef, "Number of bytes transferred is %u\n", num_bytes);
5741 ok(!olp, "Overlapped structure is at %p\n", olp);
5743 closesocket(dup);
5744 dup = INVALID_SOCKET;
5746 bret = GetQueuedCompletionStatus(io_port, &num_bytes, &key, &olp, 100);
5747 ok(bret == FALSE, "failed to get completion status %u\n", bret);
5748 ok(GetLastError() == ERROR_OPERATION_ABORTED, "Last error was %d\n", GetLastError());
5749 ok(key == 125, "Key is %lu\n", key);
5750 ok(num_bytes == 0, "Number of bytes transferred is %u\n", num_bytes);
5751 ok(olp == &ov, "Overlapped structure is at %p\n", olp);
5752 ok(olp && (olp->Internal == (ULONG)STATUS_CANCELLED), "Internal status is %lx\n", olp ? olp->Internal : 0);
5754 SetLastError(0xdeadbeef);
5755 key = 0xdeadbeef;
5756 num_bytes = 0xdeadbeef;
5757 olp = (WSAOVERLAPPED *)0xdeadbeef;
5758 bret = GetQueuedCompletionStatus( io_port, &num_bytes, &key, &olp, 200 );
5759 ok(bret == FALSE, "failed to get completion status %u\n", bret);
5760 ok(GetLastError() == WAIT_TIMEOUT, "Last error was %d\n", GetLastError());
5761 ok(key == 0xdeadbeef, "Key is %lu\n", key);
5762 ok(num_bytes == 0xdeadbeef, "Number of bytes transferred is %u\n", num_bytes);
5763 ok(!olp, "Overlapped structure is at %p\n", olp);
5765 /* Test IOCP without AcceptEx */
5767 if ((src = setup_iocp_src(&bindAddress)) == INVALID_SOCKET)
5768 goto end;
5770 SetLastError(0xdeadbeef);
5772 io_port = CreateIoCompletionPort((HANDLE)src, previous_port, 125, 0);
5773 ok(io_port != NULL, "failed to create completion port %u\n", GetLastError());
5775 closesocket(src);
5776 src = INVALID_SOCKET;
5778 SetLastError(0xdeadbeef);
5779 key = 0xdeadbeef;
5780 num_bytes = 0xdeadbeef;
5781 olp = (WSAOVERLAPPED *)0xdeadbeef;
5782 bret = GetQueuedCompletionStatus( io_port, &num_bytes, &key, &olp, 200 );
5783 ok(bret == FALSE, "failed to get completion status %u\n", bret);
5784 ok(GetLastError() == WAIT_TIMEOUT, "Last error was %d\n", GetLastError());
5785 ok(key == 0xdeadbeef, "Key is %lu\n", key);
5786 ok(num_bytes == 0xdeadbeef, "Number of bytes transferred is %u\n", num_bytes);
5787 ok(!olp, "Overlapped structure is at %p\n", olp);
5789 /* */
5791 if ((src = setup_iocp_src(&bindAddress)) == INVALID_SOCKET)
5792 goto end;
5794 connector = socket(AF_INET, SOCK_STREAM, 0);
5795 if (connector == INVALID_SOCKET) {
5796 skip("could not create connector socket, error %d\n", WSAGetLastError());
5797 goto end;
5800 io_port = CreateIoCompletionPort((HANDLE)src, previous_port, 125, 0);
5801 ok(io_port != NULL, "failed to create completion port %u\n", GetLastError());
5803 io_port = CreateIoCompletionPort((HANDLE)dest, previous_port, 236, 0);
5804 ok(io_port != NULL, "failed to create completion port %u\n", GetLastError());
5806 bret = pAcceptEx(src, dest, buf, sizeof(buf) - 2*(sizeof(struct sockaddr_in) + 16),
5807 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
5808 &num_bytes, &ov);
5809 ok(bret == FALSE, "AcceptEx returned %d\n", bret);
5810 ok(GetLastError() == ERROR_IO_PENDING, "Last error was %d\n", GetLastError());
5812 iret = connect(connector, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
5813 ok(iret == 0, "connecting to accepting socket failed, error %d\n", GetLastError());
5815 closesocket(connector);
5816 connector = INVALID_SOCKET;
5818 SetLastError(0xdeadbeef);
5819 key = 0xdeadbeef;
5820 num_bytes = 0xdeadbeef;
5821 olp = (WSAOVERLAPPED *)0xdeadbeef;
5823 bret = GetQueuedCompletionStatus(io_port, &num_bytes, &key, &olp, 100);
5824 ok(bret == TRUE, "failed to get completion status %u\n", bret);
5825 ok(GetLastError() == 0xdeadbeef, "Last error was %d\n", GetLastError());
5826 ok(key == 125, "Key is %lu\n", key);
5827 ok(num_bytes == 0, "Number of bytes transferred is %u\n", num_bytes);
5828 ok(olp == &ov, "Overlapped structure is at %p\n", olp);
5829 ok(olp && (olp->Internal == (ULONG)STATUS_SUCCESS), "Internal status is %lx\n", olp ? olp->Internal : 0);
5831 SetLastError(0xdeadbeef);
5832 key = 0xdeadbeef;
5833 num_bytes = 0xdeadbeef;
5834 olp = (WSAOVERLAPPED *)0xdeadbeef;
5835 bret = GetQueuedCompletionStatus( io_port, &num_bytes, &key, &olp, 200 );
5836 ok(bret == FALSE, "failed to get completion status %u\n", bret);
5837 ok(GetLastError() == WAIT_TIMEOUT, "Last error was %d\n", GetLastError());
5838 ok(key == 0xdeadbeef, "Key is %lu\n", key);
5839 ok(num_bytes == 0xdeadbeef, "Number of bytes transferred is %u\n", num_bytes);
5840 ok(!olp, "Overlapped structure is at %p\n", olp);
5842 if (dest != INVALID_SOCKET)
5843 closesocket(dest);
5844 if (src != INVALID_SOCKET)
5845 closesocket(dest);
5847 /* */
5849 if ((src = setup_iocp_src(&bindAddress)) == INVALID_SOCKET)
5850 goto end;
5852 dest = socket(AF_INET, SOCK_STREAM, 0);
5853 if (dest == INVALID_SOCKET)
5855 skip("could not create acceptor socket, error %d\n", WSAGetLastError());
5856 goto end;
5859 connector = socket(AF_INET, SOCK_STREAM, 0);
5860 if (connector == INVALID_SOCKET) {
5861 skip("could not create connector socket, error %d\n", WSAGetLastError());
5862 goto end;
5865 io_port = CreateIoCompletionPort((HANDLE)src, previous_port, 125, 0);
5866 ok(io_port != NULL, "failed to create completion port %u\n", GetLastError());
5868 io_port = CreateIoCompletionPort((HANDLE)dest, previous_port, 236, 0);
5869 ok(io_port != NULL, "failed to create completion port %u\n", GetLastError());
5871 bret = pAcceptEx(src, dest, buf, sizeof(buf) - 2*(sizeof(struct sockaddr_in) + 16),
5872 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
5873 &num_bytes, &ov);
5874 ok(bret == FALSE, "AcceptEx returned %d\n", bret);
5875 ok(GetLastError() == ERROR_IO_PENDING, "Last error was %d\n", GetLastError());
5877 iret = connect(connector, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
5878 ok(iret == 0, "connecting to accepting socket failed, error %d\n", GetLastError());
5880 iret = send(connector, buf, 1, 0);
5881 ok(iret == 1, "could not send 1 byte: send %d errno %d\n", iret, WSAGetLastError());
5883 closesocket(dest);
5884 dest = INVALID_SOCKET;
5886 SetLastError(0xdeadbeef);
5887 key = 0xdeadbeef;
5888 num_bytes = 0xdeadbeef;
5889 olp = (WSAOVERLAPPED *)0xdeadbeef;
5891 bret = GetQueuedCompletionStatus(io_port, &num_bytes, &key, &olp, 100);
5892 ok(bret == TRUE, "failed to get completion status %u\n", bret);
5893 ok(GetLastError() == 0xdeadbeef, "Last error was %d\n", GetLastError());
5894 ok(key == 125, "Key is %lu\n", key);
5895 ok(num_bytes == 1, "Number of bytes transferred is %u\n", num_bytes);
5896 ok(olp == &ov, "Overlapped structure is at %p\n", olp);
5897 ok(olp && (olp->Internal == (ULONG)STATUS_SUCCESS), "Internal status is %lx\n", olp ? olp->Internal : 0);
5899 SetLastError(0xdeadbeef);
5900 key = 0xdeadbeef;
5901 num_bytes = 0xdeadbeef;
5902 olp = (WSAOVERLAPPED *)0xdeadbeef;
5903 bret = GetQueuedCompletionStatus( io_port, &num_bytes, &key, &olp, 200 );
5904 ok(bret == FALSE, "failed to get completion status %u\n", bret);
5905 ok(GetLastError() == WAIT_TIMEOUT, "Last error was %d\n", GetLastError());
5906 ok(key == 0xdeadbeef, "Key is %lu\n", key);
5907 ok(num_bytes == 0xdeadbeef, "Number of bytes transferred is %u\n", num_bytes);
5908 ok(!olp, "Overlapped structure is at %p\n", olp);
5910 if (src != INVALID_SOCKET)
5911 closesocket(src);
5912 if (connector != INVALID_SOCKET)
5913 closesocket(connector);
5915 /* */
5917 if ((src = setup_iocp_src(&bindAddress)) == INVALID_SOCKET)
5918 goto end;
5920 dest = socket(AF_INET, SOCK_STREAM, 0);
5921 if (dest == INVALID_SOCKET)
5923 skip("could not create acceptor socket, error %d\n", WSAGetLastError());
5924 goto end;
5927 connector = socket(AF_INET, SOCK_STREAM, 0);
5928 if (connector == INVALID_SOCKET) {
5929 skip("could not create connector socket, error %d\n", WSAGetLastError());
5930 goto end;
5933 io_port = CreateIoCompletionPort((HANDLE)src, previous_port, 125, 0);
5934 ok(io_port != NULL, "failed to create completion port %u\n", GetLastError());
5936 io_port = CreateIoCompletionPort((HANDLE)dest, previous_port, 236, 0);
5937 ok(io_port != NULL, "failed to create completion port %u\n", GetLastError());
5939 bret = pAcceptEx(src, dest, buf, sizeof(buf) - 2*(sizeof(struct sockaddr_in) + 16),
5940 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
5941 &num_bytes, &ov);
5942 ok(bret == FALSE, "AcceptEx returned %d\n", bret);
5943 ok(GetLastError() == ERROR_IO_PENDING, "Last error was %d\n", GetLastError());
5945 iret = connect(connector, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
5946 ok(iret == 0, "connecting to accepting socket failed, error %d\n", GetLastError());
5948 closesocket(dest);
5949 dest = INVALID_SOCKET;
5951 SetLastError(0xdeadbeef);
5952 key = 0xdeadbeef;
5953 num_bytes = 0xdeadbeef;
5954 olp = (WSAOVERLAPPED *)0xdeadbeef;
5956 bret = GetQueuedCompletionStatus(io_port, &num_bytes, &key, &olp, 100);
5957 ok(bret == FALSE, "failed to get completion status %u\n", bret);
5958 todo_wine ok((GetLastError() == ERROR_NETNAME_DELETED) || (GetLastError() == ERROR_CONNECTION_ABORTED), "Last error was %d\n", GetLastError());
5959 ok(key == 125, "Key is %lu\n", key);
5960 ok(num_bytes == 0, "Number of bytes transferred is %u\n", num_bytes);
5961 ok(olp == &ov, "Overlapped structure is at %p\n", olp);
5962 todo_wine ok(olp && ((olp->Internal == (ULONG)STATUS_LOCAL_DISCONNECT)
5963 || (olp->Internal == (ULONG)STATUS_CONNECTION_ABORTED)), "Internal status is %lx\n", olp ? olp->Internal : 0);
5965 SetLastError(0xdeadbeef);
5966 key = 0xdeadbeef;
5967 num_bytes = 0xdeadbeef;
5968 olp = (WSAOVERLAPPED *)0xdeadbeef;
5969 bret = GetQueuedCompletionStatus( io_port, &num_bytes, &key, &olp, 200 );
5970 ok(bret == FALSE, "failed to get completion status %u\n", bret);
5971 ok(GetLastError() == WAIT_TIMEOUT, "Last error was %d\n", GetLastError());
5972 ok(key == 0xdeadbeef, "Key is %lu\n", key);
5973 ok(num_bytes == 0xdeadbeef, "Number of bytes transferred is %u\n", num_bytes);
5974 ok(!olp, "Overlapped structure is at %p\n", olp);
5977 end:
5978 if (dest != INVALID_SOCKET)
5979 closesocket(dest);
5980 if (src != INVALID_SOCKET)
5981 closesocket(src);
5982 if (connector != INVALID_SOCKET)
5983 closesocket(connector);
5984 CloseHandle(previous_port);
5987 /**************** Main program ***************/
5989 START_TEST( sock )
5991 int i;
5993 /* Leave these tests at the beginning. They depend on WSAStartup not having been
5994 * called, which is done by Init() below. */
5995 test_WithoutWSAStartup();
5996 test_WithWSAStartup();
5998 Init();
6000 test_set_getsockopt();
6001 test_so_reuseaddr();
6002 test_ip_pktinfo();
6003 test_extendedSocketOptions();
6005 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
6007 trace ( " **** STARTING TEST %d ****\n", i );
6008 do_test ( &tests[i] );
6009 trace ( " **** TEST %d COMPLETE ****\n", i );
6012 test_UDP();
6014 test_getservbyname();
6015 test_WSASocket();
6017 test_WSAAddressToStringA();
6018 test_WSAAddressToStringW();
6020 test_WSAStringToAddressA();
6021 test_WSAStringToAddressW();
6023 test_errors();
6024 test_select();
6025 test_accept();
6026 test_getpeername();
6027 test_getsockname();
6028 test_inet_addr();
6029 test_addr_to_print();
6030 test_ioctlsocket();
6031 test_dns();
6032 test_gethostbyname_hack();
6034 test_WSASendTo();
6035 test_WSARecv();
6037 test_events(0);
6038 test_events(1);
6040 test_ipv6only();
6041 test_GetAddrInfoW();
6042 test_getaddrinfo();
6043 test_AcceptEx();
6044 test_ConnectEx();
6046 test_sioRoutingInterfaceQuery();
6048 test_WSAAsyncGetServByPort();
6049 test_WSAAsyncGetServByName();
6051 test_completion_port();
6053 /* this is a io heavy test, do it at the end so the kernel doesn't start dropping packets */
6054 test_send();
6055 test_synchronous_WSAIoctl();
6057 Exit();