fltlib: Add a stub dll.
[wine] / dlls / ws2_32 / socket.c
1 /*
2  * based on Windows Sockets 1.1 specs
3  *
4  * Copyright (C) 1993,1994,1996,1997 John Brezak, Erik Bos, Alex Korobka.
5  * Copyright (C) 2005 Marcus Meissner
6  * Copyright (C) 2006-2008 Kai Blin
7  *
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.
12  *
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.
17  *
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
21  *
22  * NOTE: If you make any changes to fix a particular app, make sure
23  * they don't break something else like Netscape or telnet and ftp
24  * clients and servers (www.winsite.com got a lot of those).
25  */
26
27 #include "config.h"
28 #include "wine/port.h"
29
30 #include <stdarg.h>
31 #include <stdio.h>
32 #include <string.h>
33 #include <sys/types.h>
34 #ifdef HAVE_SYS_IPC_H
35 # include <sys/ipc.h>
36 #endif
37 #ifdef HAVE_SYS_IOCTL_H
38 # include <sys/ioctl.h>
39 #endif
40 #ifdef HAVE_SYS_FILIO_H
41 # include <sys/filio.h>
42 #endif
43 #ifdef HAVE_SYS_SOCKIO_H
44 # include <sys/sockio.h>
45 #endif
46
47 #if defined(__EMX__)
48 # include <sys/so_ioctl.h>
49 #endif
50
51 #ifdef HAVE_SYS_PARAM_H
52 # include <sys/param.h>
53 #endif
54
55 #ifdef HAVE_SYS_MSG_H
56 # include <sys/msg.h>
57 #endif
58 #ifdef HAVE_SYS_WAIT_H
59 # include <sys/wait.h>
60 #endif
61 #ifdef HAVE_SYS_UIO_H
62 # include <sys/uio.h>
63 #endif
64 #ifdef HAVE_SYS_SOCKET_H
65 #include <sys/socket.h>
66 #endif
67 #ifdef HAVE_NETINET_IN_H
68 # include <netinet/in.h>
69 #endif
70 #ifdef HAVE_NETINET_TCP_H
71 # include <netinet/tcp.h>
72 #endif
73 #ifdef HAVE_ARPA_INET_H
74 # include <arpa/inet.h>
75 #endif
76 #include <ctype.h>
77 #include <fcntl.h>
78 #include <errno.h>
79 #ifdef HAVE_SYS_ERRNO_H
80 #include <sys/errno.h>
81 #endif
82 #ifdef HAVE_NETDB_H
83 #include <netdb.h>
84 #endif
85 #ifdef HAVE_UNISTD_H
86 # include <unistd.h>
87 #endif
88 #include <stdlib.h>
89 #ifdef HAVE_ARPA_NAMESER_H
90 # include <arpa/nameser.h>
91 #endif
92 #ifdef HAVE_RESOLV_H
93 # include <resolv.h>
94 #endif
95 #ifdef HAVE_NET_IF_H
96 # include <net/if.h>
97 #endif
98
99 #ifdef HAVE_NETIPX_IPX_H
100 # include <netipx/ipx.h>
101 # define HAVE_IPX
102 #elif defined(HAVE_LINUX_IPX_H)
103 # ifdef HAVE_ASM_TYPES_H
104 #  include <asm/types.h>
105 # endif
106 # ifdef HAVE_LINUX_TYPES_H
107 #  include <linux/types.h>
108 # endif
109 # include <linux/ipx.h>
110 # define HAVE_IPX
111 #endif
112
113 #ifdef HAVE_LINUX_IRDA_H
114 # ifdef HAVE_LINUX_TYPES_H
115 #  include <linux/types.h>
116 # endif
117 # include <linux/irda.h>
118 # define HAVE_IRDA
119 #endif
120
121 #ifdef HAVE_POLL_H
122 #include <poll.h>
123 #endif
124 #ifdef HAVE_SYS_POLL_H
125 # include <sys/poll.h>
126 #endif
127 #ifdef HAVE_SYS_TIME_H
128 # include <sys/time.h>
129 #endif
130
131 #define NONAMELESSUNION
132 #define NONAMELESSSTRUCT
133 #include "ntstatus.h"
134 #define WIN32_NO_STATUS
135 #include "windef.h"
136 #include "winbase.h"
137 #include "wingdi.h"
138 #include "winuser.h"
139 #include "winerror.h"
140 #include "winnls.h"
141 #include "winsock2.h"
142 #include "mswsock.h"
143 #include "ws2tcpip.h"
144 #include "ws2spi.h"
145 #include "wsipx.h"
146 #include "mstcpip.h"
147 #include "af_irda.h"
148 #include "winnt.h"
149 #include "iphlpapi.h"
150 #include "wine/server.h"
151 #include "wine/debug.h"
152 #include "wine/unicode.h"
153
154 #ifdef HAVE_IPX
155 # include "wsnwlink.h"
156 #endif
157
158
159 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
160 # define sipx_network    sipx_addr.x_net
161 # define sipx_node       sipx_addr.x_host.c_host
162 #endif  /* __FreeBSD__ */
163
164 #ifndef INADDR_NONE
165 #define INADDR_NONE ~0UL
166 #endif
167
168 WINE_DEFAULT_DEBUG_CHANNEL(winsock);
169
170 /* critical section to protect some non-reentrant net function */
171 static CRITICAL_SECTION csWSgetXXXbyYYY;
172 static CRITICAL_SECTION_DEBUG critsect_debug =
173 {
174     0, 0, &csWSgetXXXbyYYY,
175     { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
176       0, 0, { (DWORD_PTR)(__FILE__ ": csWSgetXXXbyYYY") }
177 };
178 static CRITICAL_SECTION csWSgetXXXbyYYY = { &critsect_debug, -1, 0, 0, 0, 0 };
179
180 union generic_unix_sockaddr
181 {
182     struct sockaddr addr;
183     char data[128];  /* should be big enough for all families */
184 };
185
186 static inline const char *debugstr_sockaddr( const struct WS_sockaddr *a )
187 {
188     if (!a) return "(nil)";
189     switch (a->sa_family)
190     {
191     case WS_AF_INET:
192         return wine_dbg_sprintf("{ family AF_INET, address %s, port %d }",
193                                 inet_ntoa(((const struct sockaddr_in *)a)->sin_addr),
194                                 ntohs(((const struct sockaddr_in *)a)->sin_port));
195     case WS_AF_INET6:
196     {
197         char buf[46];
198         const char *p;
199         struct WS_sockaddr_in6 *sin = (struct WS_sockaddr_in6 *)a;
200
201         p = WS_inet_ntop( WS_AF_INET6, &sin->sin6_addr, buf, sizeof(buf) );
202         if (!p)
203             p = "(unknown IPv6 address)";
204         return wine_dbg_sprintf("{ family AF_INET6, address %s, port %d }",
205                                 p, ntohs(sin->sin6_port));
206     }
207     case WS_AF_IRDA:
208     {
209         DWORD addr;
210
211         memcpy( &addr, ((const SOCKADDR_IRDA *)a)->irdaDeviceID, sizeof(addr) );
212         addr = ntohl( addr );
213         return wine_dbg_sprintf("{ family AF_IRDA, addr %08x, name %s }",
214                                 addr,
215                                 ((const SOCKADDR_IRDA *)a)->irdaServiceName);
216     }
217     default:
218         return wine_dbg_sprintf("{ family %d }", a->sa_family);
219     }
220 }
221
222 /* HANDLE<->SOCKET conversion (SOCKET is UINT_PTR). */
223 #define SOCKET2HANDLE(s) ((HANDLE)(s))
224 #define HANDLE2SOCKET(h) ((SOCKET)(h))
225
226 /****************************************************************
227  * Async IO declarations
228  ****************************************************************/
229
230 typedef struct ws2_async
231 {
232     HANDLE                              hSocket;
233     int                                 type;
234     LPWSAOVERLAPPED                     user_overlapped;
235     LPWSAOVERLAPPED_COMPLETION_ROUTINE  completion_func;
236     IO_STATUS_BLOCK                     local_iosb;
237     struct WS_sockaddr                  *addr;
238     union
239     {
240         int val;     /* for send operations */
241         int *ptr;    /* for recv operations */
242     }                                   addrlen;
243     DWORD                               flags;
244     unsigned int                        n_iovecs;
245     unsigned int                        first_iovec;
246     struct iovec                        iovec[1];
247 } ws2_async;
248
249 /****************************************************************/
250
251 /* ----------------------------------- internal data */
252
253 /* ws_... struct conversion flags */
254
255 typedef struct          /* WSAAsyncSelect() control struct */
256 {
257   HANDLE      service, event, sock;
258   HWND        hWnd;
259   UINT        uMsg;
260   LONG        lEvent;
261 } ws_select_info;
262
263 #define WS_MAX_SOCKETS_PER_PROCESS      128     /* reasonable guess */
264 #define WS_MAX_UDP_DATAGRAM             1024
265 static INT WINAPI WSA_DefaultBlockingHook( FARPROC x );
266
267 /* hostent's, servent's and protent's are stored in one buffer per thread,
268  * as documented on MSDN for the functions that return any of the buffers */
269 struct per_thread_data
270 {
271     int opentype;
272     struct WS_hostent *he_buffer;
273     struct WS_servent *se_buffer;
274     struct WS_protoent *pe_buffer;
275     int he_len;
276     int se_len;
277     int pe_len;
278 };
279
280 static INT num_startup;          /* reference counter */
281 static FARPROC blocking_hook = (FARPROC)WSA_DefaultBlockingHook;
282
283 /* function prototypes */
284 static struct WS_hostent *WS_dup_he(const struct hostent* p_he);
285 static struct WS_protoent *WS_dup_pe(const struct protoent* p_pe);
286 static struct WS_servent *WS_dup_se(const struct servent* p_se);
287
288 int WSAIOCTL_GetInterfaceCount(void);
289 int WSAIOCTL_GetInterfaceName(int intNumber, char *intName);
290
291 UINT wsaErrno(void);
292 UINT wsaHerrno(int errnr);
293
294 #define MAP_OPTION(opt) { WS_##opt, opt }
295
296 static const int ws_sock_map[][2] =
297 {
298     MAP_OPTION( SO_DEBUG ),
299     MAP_OPTION( SO_ACCEPTCONN ),
300     MAP_OPTION( SO_REUSEADDR ),
301     MAP_OPTION( SO_KEEPALIVE ),
302     MAP_OPTION( SO_DONTROUTE ),
303     MAP_OPTION( SO_BROADCAST ),
304     MAP_OPTION( SO_LINGER ),
305     MAP_OPTION( SO_OOBINLINE ),
306     MAP_OPTION( SO_SNDBUF ),
307     MAP_OPTION( SO_RCVBUF ),
308     MAP_OPTION( SO_ERROR ),
309     MAP_OPTION( SO_TYPE ),
310 #ifdef SO_RCVTIMEO
311     MAP_OPTION( SO_RCVTIMEO ),
312 #endif
313 #ifdef SO_SNDTIMEO
314     MAP_OPTION( SO_SNDTIMEO ),
315 #endif
316 };
317
318 static const int ws_tcp_map[][2] =
319 {
320 #ifdef TCP_NODELAY
321     MAP_OPTION( TCP_NODELAY ),
322 #endif
323 };
324
325 static const int ws_ip_map[][2] =
326 {
327     MAP_OPTION( IP_MULTICAST_IF ),
328     MAP_OPTION( IP_MULTICAST_TTL ),
329     MAP_OPTION( IP_MULTICAST_LOOP ),
330     MAP_OPTION( IP_ADD_MEMBERSHIP ),
331     MAP_OPTION( IP_DROP_MEMBERSHIP ),
332     MAP_OPTION( IP_OPTIONS ),
333 #ifdef IP_HDRINCL
334     MAP_OPTION( IP_HDRINCL ),
335 #endif
336     MAP_OPTION( IP_TOS ),
337     MAP_OPTION( IP_TTL ),
338 };
339
340 static const int ws_af_map[][2] =
341 {
342     MAP_OPTION( AF_UNSPEC ),
343     MAP_OPTION( AF_INET ),
344     MAP_OPTION( AF_INET6 ),
345 #ifdef HAVE_IPX
346     MAP_OPTION( AF_IPX ),
347 #endif
348 #ifdef AF_IRDA
349     MAP_OPTION( AF_IRDA ),
350 #endif
351     {FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO},
352 };
353
354 static const int ws_socktype_map[][2] =
355 {
356     MAP_OPTION( SOCK_DGRAM ),
357     MAP_OPTION( SOCK_STREAM ),
358     MAP_OPTION( SOCK_RAW ),
359     {FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO},
360 };
361
362 static const int ws_proto_map[][2] =
363 {
364     MAP_OPTION( IPPROTO_IP ),
365     MAP_OPTION( IPPROTO_TCP ),
366     MAP_OPTION( IPPROTO_UDP ),
367     MAP_OPTION( IPPROTO_ICMP ),
368     MAP_OPTION( IPPROTO_IGMP ),
369     MAP_OPTION( IPPROTO_RAW ),
370     {FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO},
371 };
372
373 static const int ws_aiflag_map[][2] =
374 {
375     MAP_OPTION( AI_PASSIVE ),
376     MAP_OPTION( AI_CANONNAME ),
377     MAP_OPTION( AI_NUMERICHOST ),
378     /* Linux/UNIX knows a lot more. But Windows only
379      * has 3 as far as I could see. -Marcus
380      */
381 };
382
383 static const int ws_niflag_map[][2] =
384 {
385     MAP_OPTION( NI_NOFQDN ),
386     MAP_OPTION( NI_NUMERICHOST ),
387     MAP_OPTION( NI_NAMEREQD ),
388     MAP_OPTION( NI_NUMERICSERV ),
389     MAP_OPTION( NI_DGRAM ),
390 };
391
392 static const int ws_eai_map[][2] =
393 {
394     MAP_OPTION( EAI_AGAIN ),
395     MAP_OPTION( EAI_BADFLAGS ),
396     MAP_OPTION( EAI_FAIL ),
397     MAP_OPTION( EAI_FAMILY ),
398     MAP_OPTION( EAI_MEMORY ),
399 /* Note: EAI_NODATA is deprecated, but still 
400  * used by Windows and Linux... We map the newer
401  * EAI_NONAME to EAI_NODATA for now until Windows
402  * changes too.
403  */
404 #ifdef EAI_NODATA
405     MAP_OPTION( EAI_NODATA ),
406 #endif
407 #ifdef EAI_NONAME
408     { WS_EAI_NODATA, EAI_NONAME },
409 #endif
410
411     MAP_OPTION( EAI_SERVICE ),
412     MAP_OPTION( EAI_SOCKTYPE ),
413     { 0, 0 }
414 };
415
416 static const char magic_loopback_addr[] = {127, 12, 34, 56};
417
418 static inline DWORD NtStatusToWSAError( const DWORD status )
419 {
420     /* We only need to cover the status codes set by server async request handling */
421     DWORD wserr;
422     switch ( status )
423     {
424     case STATUS_SUCCESS:              wserr = 0;                     break;
425     case STATUS_PENDING:              wserr = WSA_IO_PENDING;        break;
426     case STATUS_OBJECT_TYPE_MISMATCH: wserr = WSAENOTSOCK;           break;
427     case STATUS_INVALID_HANDLE:       wserr = WSAEBADF;              break;
428     case STATUS_INVALID_PARAMETER:    wserr = WSAEINVAL;             break;
429     case STATUS_PIPE_DISCONNECTED:    wserr = WSAESHUTDOWN;          break;
430     case STATUS_CANCELLED:            wserr = WSA_OPERATION_ABORTED; break;
431     case STATUS_TIMEOUT:              wserr = WSAETIMEDOUT;          break;
432     case STATUS_NO_MEMORY:            wserr = WSAEFAULT;             break;
433     default:
434         if ( status >= WSABASEERR && status <= WSABASEERR+1004 )
435             /* It is not an NT status code but a winsock error */
436             wserr = status;
437         else
438         {
439             wserr = RtlNtStatusToDosError( status );
440             FIXME( "Status code %08x converted to DOS error code %x\n", status, wserr );
441         }
442     }
443     return wserr;
444 }
445
446 /* set last error code from NT status without mapping WSA errors */
447 static inline unsigned int set_error( unsigned int err )
448 {
449     if (err)
450     {
451         err = NtStatusToWSAError( err );
452         SetLastError( err );
453     }
454     return err;
455 }
456
457 static inline int get_sock_fd( SOCKET s, DWORD access, unsigned int *options )
458 {
459     int fd;
460     if (set_error( wine_server_handle_to_fd( SOCKET2HANDLE(s), access, &fd, options ) ))
461         return -1;
462     return fd;
463 }
464
465 static inline void release_sock_fd( SOCKET s, int fd )
466 {
467     wine_server_release_fd( SOCKET2HANDLE(s), fd );
468 }
469
470 static void _enable_event( HANDLE s, unsigned int event,
471                            unsigned int sstate, unsigned int cstate )
472 {
473     SERVER_START_REQ( enable_socket_event )
474     {
475         req->handle = wine_server_obj_handle( s );
476         req->mask   = event;
477         req->sstate = sstate;
478         req->cstate = cstate;
479         wine_server_call( req );
480     }
481     SERVER_END_REQ;
482 }
483
484 static int _is_blocking(SOCKET s)
485 {
486     int ret;
487     SERVER_START_REQ( get_socket_event )
488     {
489         req->handle  = wine_server_obj_handle( SOCKET2HANDLE(s) );
490         req->service = FALSE;
491         req->c_event = 0;
492         wine_server_call( req );
493         ret = (reply->state & FD_WINE_NONBLOCKING) == 0;
494     }
495     SERVER_END_REQ;
496     return ret;
497 }
498
499 static unsigned int _get_sock_mask(SOCKET s)
500 {
501     unsigned int ret;
502     SERVER_START_REQ( get_socket_event )
503     {
504         req->handle  = wine_server_obj_handle( SOCKET2HANDLE(s) );
505         req->service = FALSE;
506         req->c_event = 0;
507         wine_server_call( req );
508         ret = reply->mask;
509     }
510     SERVER_END_REQ;
511     return ret;
512 }
513
514 static void _sync_sock_state(SOCKET s)
515 {
516     /* do a dummy wineserver request in order to let
517        the wineserver run through its select loop once */
518     (void)_is_blocking(s);
519 }
520
521 static int _get_sock_error(SOCKET s, unsigned int bit)
522 {
523     int events[FD_MAX_EVENTS];
524
525     SERVER_START_REQ( get_socket_event )
526     {
527         req->handle  = wine_server_obj_handle( SOCKET2HANDLE(s) );
528         req->service = FALSE;
529         req->c_event = 0;
530         wine_server_set_reply( req, events, sizeof(events) );
531         wine_server_call( req );
532     }
533     SERVER_END_REQ;
534     return events[bit];
535 }
536
537 static struct per_thread_data *get_per_thread_data(void)
538 {
539     struct per_thread_data * ptb = NtCurrentTeb()->WinSockData;
540     /* lazy initialization */
541     if (!ptb)
542     {
543         ptb = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ptb) );
544         NtCurrentTeb()->WinSockData = ptb;
545     }
546     return ptb;
547 }
548
549 static void free_per_thread_data(void)
550 {
551     struct per_thread_data * ptb = NtCurrentTeb()->WinSockData;
552
553     if (!ptb) return;
554
555     /* delete scratch buffers */
556     HeapFree( GetProcessHeap(), 0, ptb->he_buffer );
557     HeapFree( GetProcessHeap(), 0, ptb->se_buffer );
558     HeapFree( GetProcessHeap(), 0, ptb->pe_buffer );
559     ptb->he_buffer = NULL;
560     ptb->se_buffer = NULL;
561     ptb->pe_buffer = NULL;
562
563     HeapFree( GetProcessHeap(), 0, ptb );
564     NtCurrentTeb()->WinSockData = NULL;
565 }
566
567 /***********************************************************************
568  *              DllMain (WS2_32.init)
569  */
570 BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID fImpLoad)
571 {
572     TRACE("%p 0x%x %p\n", hInstDLL, fdwReason, fImpLoad);
573     switch (fdwReason) {
574     case DLL_PROCESS_ATTACH:
575         break;
576     case DLL_PROCESS_DETACH:
577         free_per_thread_data();
578         num_startup = 0;
579         break;
580     case DLL_THREAD_DETACH:
581         free_per_thread_data();
582         break;
583     }
584     return TRUE;
585 }
586
587 /***********************************************************************
588  *          convert_sockopt()
589  *
590  * Converts socket flags from Windows format.
591  * Return 1 if converted, 0 if not (error).
592  */
593 static int convert_sockopt(INT *level, INT *optname)
594 {
595   unsigned int i;
596   switch (*level)
597   {
598      case WS_SOL_SOCKET:
599         *level = SOL_SOCKET;
600         for(i=0; i<sizeof(ws_sock_map)/sizeof(ws_sock_map[0]); i++) {
601             if( ws_sock_map[i][0] == *optname )
602             {
603                 *optname = ws_sock_map[i][1];
604                 return 1;
605             }
606         }
607         FIXME("Unknown SOL_SOCKET optname 0x%x\n", *optname);
608         break;
609      case WS_IPPROTO_TCP:
610         *level = IPPROTO_TCP;
611         for(i=0; i<sizeof(ws_tcp_map)/sizeof(ws_tcp_map[0]); i++) {
612             if ( ws_tcp_map[i][0] == *optname )
613             {
614                 *optname = ws_tcp_map[i][1];
615                 return 1;
616             }
617         }
618         FIXME("Unknown IPPROTO_TCP optname 0x%x\n", *optname);
619         break;
620      case WS_IPPROTO_IP:
621         *level = IPPROTO_IP;
622         for(i=0; i<sizeof(ws_ip_map)/sizeof(ws_ip_map[0]); i++) {
623             if (ws_ip_map[i][0] == *optname )
624             {
625                 *optname = ws_ip_map[i][1];
626                 return 1;
627             }
628         }
629         FIXME("Unknown IPPROTO_IP optname 0x%x\n", *optname);
630         break;
631      default: FIXME("Unimplemented or unknown socket level\n");
632   }
633   return 0;
634 }
635
636 /* ----------------------------------- Per-thread info (or per-process?) */
637
638 static char *strdup_lower(const char *str)
639 {
640     int i;
641     char *ret = HeapAlloc( GetProcessHeap(), 0, strlen(str) + 1 );
642
643     if (ret)
644     {
645         for (i = 0; str[i]; i++) ret[i] = tolower(str[i]);
646         ret[i] = 0;
647     }
648     else SetLastError(WSAENOBUFS);
649     return ret;
650 }
651
652 static inline int sock_error_p(int s)
653 {
654     unsigned int optval, optlen;
655
656     optlen = sizeof(optval);
657     getsockopt(s, SOL_SOCKET, SO_ERROR, (void *) &optval, &optlen);
658     if (optval) WARN("\t[%i] error: %d\n", s, optval);
659     return optval != 0;
660 }
661
662 /* Utility: get the SO_RCVTIMEO or SO_SNDTIMEO socket option
663  * from an fd and return the value converted to milli seconds
664  * or -1 if there is an infinite time out */
665 static inline int get_rcvsnd_timeo( int fd, int optname)
666 {
667   struct timeval tv;
668   unsigned int len = sizeof(tv);
669   int ret = getsockopt(fd, SOL_SOCKET, optname, &tv, &len);
670   if( ret >= 0)
671       ret = tv.tv_sec * 1000 + tv.tv_usec / 1000;
672   if( ret <= 0 ) /* tv == {0,0} means infinite time out */
673       return -1;
674   return ret;
675 }
676
677 /* macro wrappers for portability */
678 #ifdef SO_RCVTIMEO
679 #define GET_RCVTIMEO(fd) get_rcvsnd_timeo( (fd), SO_RCVTIMEO)
680 #else
681 #define GET_RCVTIMEO(fd) (-1)
682 #endif
683
684 #ifdef SO_SNDTIMEO
685 #define GET_SNDTIMEO(fd) get_rcvsnd_timeo( (fd), SO_SNDTIMEO)
686 #else
687 #define GET_SNDTIMEO(fd) (-1)
688 #endif
689
690 /* utility: given an fd, will block until one of the events occurs */
691 static inline int do_block( int fd, int events, int timeout )
692 {
693   struct pollfd pfd;
694   int ret;
695
696   pfd.fd = fd;
697   pfd.events = events;
698
699   while ((ret = poll(&pfd, 1, timeout)) < 0)
700   {
701       if (errno != EINTR)
702           return -1;
703   }
704   if( ret == 0 )
705       return 0;
706   return pfd.revents;
707 }
708
709 static int
710 convert_af_w2u(int windowsaf) {
711     unsigned int i;
712
713     for (i=0;i<sizeof(ws_af_map)/sizeof(ws_af_map[0]);i++)
714         if (ws_af_map[i][0] == windowsaf)
715             return ws_af_map[i][1];
716     FIXME("unhandled Windows address family %d\n", windowsaf);
717     return -1;
718 }
719
720 static int
721 convert_af_u2w(int unixaf) {
722     unsigned int i;
723
724     for (i=0;i<sizeof(ws_af_map)/sizeof(ws_af_map[0]);i++)
725         if (ws_af_map[i][1] == unixaf)
726             return ws_af_map[i][0];
727     FIXME("unhandled UNIX address family %d\n", unixaf);
728     return -1;
729 }
730
731 static int
732 convert_proto_w2u(int windowsproto) {
733     unsigned int i;
734
735     for (i=0;i<sizeof(ws_proto_map)/sizeof(ws_proto_map[0]);i++)
736         if (ws_proto_map[i][0] == windowsproto)
737             return ws_proto_map[i][1];
738     FIXME("unhandled Windows socket protocol %d\n", windowsproto);
739     return -1;
740 }
741
742 static int
743 convert_proto_u2w(int unixproto) {
744     unsigned int i;
745
746     for (i=0;i<sizeof(ws_proto_map)/sizeof(ws_proto_map[0]);i++)
747         if (ws_proto_map[i][1] == unixproto)
748             return ws_proto_map[i][0];
749     FIXME("unhandled UNIX socket protocol %d\n", unixproto);
750     return -1;
751 }
752
753 static int
754 convert_socktype_w2u(int windowssocktype) {
755     unsigned int i;
756
757     for (i=0;i<sizeof(ws_socktype_map)/sizeof(ws_socktype_map[0]);i++)
758         if (ws_socktype_map[i][0] == windowssocktype)
759             return ws_socktype_map[i][1];
760     FIXME("unhandled Windows socket type %d\n", windowssocktype);
761     return -1;
762 }
763
764 static int
765 convert_socktype_u2w(int unixsocktype) {
766     unsigned int i;
767
768     for (i=0;i<sizeof(ws_socktype_map)/sizeof(ws_socktype_map[0]);i++)
769         if (ws_socktype_map[i][1] == unixsocktype)
770             return ws_socktype_map[i][0];
771     FIXME("unhandled UNIX socket type %d\n", unixsocktype);
772     return -1;
773 }
774
775 /* ----------------------------------- API -----
776  *
777  * Init / cleanup / error checking.
778  */
779
780 /***********************************************************************
781  *      WSAStartup              (WS2_32.115)
782  */
783 int WINAPI WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData)
784 {
785     TRACE("verReq=%x\n", wVersionRequested);
786
787     if (LOBYTE(wVersionRequested) < 1)
788         return WSAVERNOTSUPPORTED;
789
790     if (!lpWSAData) return WSAEINVAL;
791
792     num_startup++;
793
794     /* that's the whole of the negotiation for now */
795     lpWSAData->wVersion = wVersionRequested;
796     /* return winsock information */
797     lpWSAData->wHighVersion = 0x0202;
798     strcpy(lpWSAData->szDescription, "WinSock 2.0" );
799     strcpy(lpWSAData->szSystemStatus, "Running" );
800     lpWSAData->iMaxSockets = WS_MAX_SOCKETS_PER_PROCESS;
801     lpWSAData->iMaxUdpDg = WS_MAX_UDP_DATAGRAM;
802     /* don't do anything with lpWSAData->lpVendorInfo */
803     /* (some apps don't allocate the space for this field) */
804
805     TRACE("succeeded\n");
806     return 0;
807 }
808
809
810 /***********************************************************************
811  *      WSACleanup                      (WS2_32.116)
812  */
813 INT WINAPI WSACleanup(void)
814 {
815     if (num_startup) {
816         num_startup--;
817         return 0;
818     }
819     SetLastError(WSANOTINITIALISED);
820     return SOCKET_ERROR;
821 }
822
823
824 /***********************************************************************
825  *      WSAGetLastError         (WS2_32.111)
826  */
827 INT WINAPI WSAGetLastError(void)
828 {
829         return GetLastError();
830 }
831
832 /***********************************************************************
833  *      WSASetLastError         (WS2_32.112)
834  */
835 void WINAPI WSASetLastError(INT iError) {
836     SetLastError(iError);
837 }
838
839 static struct WS_hostent *check_buffer_he(int size)
840 {
841     struct per_thread_data * ptb = get_per_thread_data();
842     if (ptb->he_buffer)
843     {
844         if (ptb->he_len >= size ) return ptb->he_buffer;
845         HeapFree( GetProcessHeap(), 0, ptb->he_buffer );
846     }
847     ptb->he_buffer = HeapAlloc( GetProcessHeap(), 0, (ptb->he_len = size) );
848     if (!ptb->he_buffer) SetLastError(WSAENOBUFS);
849     return ptb->he_buffer;
850 }
851
852 static struct WS_servent *check_buffer_se(int size)
853 {
854     struct per_thread_data * ptb = get_per_thread_data();
855     if (ptb->se_buffer)
856     {
857         if (ptb->se_len >= size ) return ptb->se_buffer;
858         HeapFree( GetProcessHeap(), 0, ptb->se_buffer );
859     }
860     ptb->se_buffer = HeapAlloc( GetProcessHeap(), 0, (ptb->se_len = size) );
861     if (!ptb->se_buffer) SetLastError(WSAENOBUFS);
862     return ptb->se_buffer;
863 }
864
865 static struct WS_protoent *check_buffer_pe(int size)
866 {
867     struct per_thread_data * ptb = get_per_thread_data();
868     if (ptb->pe_buffer)
869     {
870         if (ptb->pe_len >= size ) return ptb->pe_buffer;
871         HeapFree( GetProcessHeap(), 0, ptb->pe_buffer );
872     }
873     ptb->pe_buffer = HeapAlloc( GetProcessHeap(), 0, (ptb->pe_len = size) );
874     if (!ptb->pe_buffer) SetLastError(WSAENOBUFS);
875     return ptb->pe_buffer;
876 }
877
878 /* ----------------------------------- i/o APIs */
879
880 static inline BOOL supported_pf(int pf)
881 {
882     switch (pf)
883     {
884     case WS_AF_INET:
885     case WS_AF_INET6:
886         return TRUE;
887 #ifdef HAVE_IPX
888     case WS_AF_IPX:
889         return TRUE;
890 #endif
891 #ifdef HAVE_IRDA
892     case WS_AF_IRDA:
893         return TRUE;
894 #endif
895     default:
896         return FALSE;
897     }
898 }
899
900
901 /**********************************************************************/
902
903 /* Returns the length of the converted address if successful, 0 if it was too small to
904  * start with.
905  */
906 static unsigned int ws_sockaddr_ws2u(const struct WS_sockaddr* wsaddr, int wsaddrlen,
907                                      union generic_unix_sockaddr *uaddr)
908 {
909     unsigned int uaddrlen = 0;
910
911     switch (wsaddr->sa_family)
912     {
913 #ifdef HAVE_IPX
914     case WS_AF_IPX:
915         {
916             const struct WS_sockaddr_ipx* wsipx=(const struct WS_sockaddr_ipx*)wsaddr;
917             struct sockaddr_ipx* uipx = (struct sockaddr_ipx *)uaddr;
918
919             if (wsaddrlen<sizeof(struct WS_sockaddr_ipx))
920                 return 0;
921
922             uaddrlen = sizeof(struct sockaddr_ipx);
923             memset( uaddr, 0, uaddrlen );
924             uipx->sipx_family=AF_IPX;
925             uipx->sipx_port=wsipx->sa_socket;
926             /* copy sa_netnum and sa_nodenum to sipx_network and sipx_node
927              * in one go
928              */
929             memcpy(&uipx->sipx_network,wsipx->sa_netnum,sizeof(uipx->sipx_network)+sizeof(uipx->sipx_node));
930 #ifdef IPX_FRAME_NONE
931             uipx->sipx_type=IPX_FRAME_NONE;
932 #endif
933             break;
934         }
935 #endif
936     case WS_AF_INET6: {
937         struct sockaddr_in6* uin6 = (struct sockaddr_in6 *)uaddr;
938         const struct WS_sockaddr_in6* win6 = (const struct WS_sockaddr_in6*)wsaddr;
939
940         /* Note: Windows has 2 versions of the sockaddr_in6 struct, one with
941          * scope_id, one without.
942          */
943         if (wsaddrlen >= sizeof(struct WS_sockaddr_in6_old)) {
944             uaddrlen = sizeof(struct sockaddr_in6);
945             memset( uaddr, 0, uaddrlen );
946             uin6->sin6_family   = AF_INET6;
947             uin6->sin6_port     = win6->sin6_port;
948             uin6->sin6_flowinfo = win6->sin6_flowinfo;
949 #ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID
950             if (wsaddrlen >= sizeof(struct WS_sockaddr_in6)) uin6->sin6_scope_id = win6->sin6_scope_id;
951 #endif
952             memcpy(&uin6->sin6_addr,&win6->sin6_addr,16); /* 16 bytes = 128 address bits */
953             break;
954         }
955         FIXME("bad size %d for WS_sockaddr_in6\n",wsaddrlen);
956         return 0;
957     }
958     case WS_AF_INET: {
959         struct sockaddr_in* uin = (struct sockaddr_in *)uaddr;
960         const struct WS_sockaddr_in* win = (const struct WS_sockaddr_in*)wsaddr;
961
962         if (wsaddrlen<sizeof(struct WS_sockaddr_in))
963             return 0;
964         uaddrlen = sizeof(struct sockaddr_in);
965         memset( uaddr, 0, uaddrlen );
966         uin->sin_family = AF_INET;
967         uin->sin_port   = win->sin_port;
968         memcpy(&uin->sin_addr,&win->sin_addr,4); /* 4 bytes = 32 address bits */
969         break;
970     }
971 #ifdef HAVE_IRDA
972     case WS_AF_IRDA: {
973         struct sockaddr_irda *uin = (struct sockaddr_irda *)uaddr;
974         const SOCKADDR_IRDA *win = (const SOCKADDR_IRDA *)wsaddr;
975
976         if (wsaddrlen < sizeof(SOCKADDR_IRDA))
977             return 0;
978         uaddrlen = sizeof(struct sockaddr_irda);
979         memset( uaddr, 0, uaddrlen );
980         uin->sir_family = AF_IRDA;
981         if (!strncmp( win->irdaServiceName, "LSAP-SEL", strlen( "LSAP-SEL" ) ))
982         {
983             unsigned int lsap_sel;
984
985             sscanf( win->irdaServiceName, "LSAP-SEL%u", &lsap_sel );
986             uin->sir_lsap_sel = lsap_sel;
987         }
988         else
989         {
990             uin->sir_lsap_sel = LSAP_ANY;
991             memcpy( uin->sir_name, win->irdaServiceName, 25 );
992         }
993         memcpy( &uin->sir_addr, win->irdaDeviceID, sizeof(uin->sir_addr) );
994         break;
995     }
996 #endif
997     case WS_AF_UNSPEC: {
998         /* Try to determine the needed space by the passed windows sockaddr space */
999         switch (wsaddrlen) {
1000         default: /* likely a ipv4 address */
1001         case sizeof(struct WS_sockaddr_in):
1002             uaddrlen = sizeof(struct sockaddr_in);
1003             break;
1004 #ifdef HAVE_IPX
1005         case sizeof(struct WS_sockaddr_ipx):
1006             uaddrlen = sizeof(struct sockaddr_ipx);
1007             break;
1008 #endif
1009 #ifdef HAVE_IRDA
1010         case sizeof(SOCKADDR_IRDA):
1011             uaddrlen = sizeof(struct sockaddr_irda);
1012             break;
1013 #endif
1014         case sizeof(struct WS_sockaddr_in6):
1015         case sizeof(struct WS_sockaddr_in6_old):
1016             uaddrlen = sizeof(struct sockaddr_in6);
1017             break;
1018         }
1019         memset( uaddr, 0, uaddrlen );
1020         break;
1021     }
1022     default:
1023         FIXME("Unknown address family %d, return NULL.\n", wsaddr->sa_family);
1024         return 0;
1025     }
1026     return uaddrlen;
1027 }
1028
1029 static BOOL is_sockaddr_bound(const struct sockaddr *uaddr, int uaddrlen)
1030 {
1031     switch (uaddr->sa_family)
1032     {
1033 #ifdef HAVE_IPX
1034         case AF_IPX:
1035             FIXME("don't know how to tell if IPX socket is bound, assuming it is!\n");
1036             return TRUE;
1037 #endif
1038         case AF_INET6:
1039         {
1040             static const struct sockaddr_in6 emptyAddr;
1041             const struct sockaddr_in6 *in6 = (const struct sockaddr_in6*) uaddr;
1042             return in6->sin6_port || memcmp(&in6->sin6_addr, &emptyAddr.sin6_addr, sizeof(struct in6_addr));
1043         }
1044         case AF_INET:
1045         {
1046             static const struct sockaddr_in emptyAddr;
1047             const struct sockaddr_in *in = (const struct sockaddr_in*) uaddr;
1048             return in->sin_port || memcmp(&in->sin_addr, &emptyAddr.sin_addr, sizeof(struct in_addr));
1049         }
1050         case AF_UNSPEC:
1051             return FALSE;
1052         default:
1053             FIXME("unknown address family %d\n", uaddr->sa_family);
1054             return TRUE;
1055     }
1056 }
1057
1058 /* Returns 0 if successful, -1 if the buffer is too small */
1059 static int ws_sockaddr_u2ws(const struct sockaddr* uaddr, struct WS_sockaddr* wsaddr, int* wsaddrlen)
1060 {
1061     int res;
1062
1063     switch(uaddr->sa_family)
1064     {
1065 #ifdef HAVE_IPX
1066     case AF_IPX:
1067         {
1068             const struct sockaddr_ipx* uipx=(const struct sockaddr_ipx*)uaddr;
1069             struct WS_sockaddr_ipx* wsipx=(struct WS_sockaddr_ipx*)wsaddr;
1070
1071             res=-1;
1072             switch (*wsaddrlen) /* how much can we copy? */
1073             {
1074             default:
1075                 res=0; /* enough */
1076                 *wsaddrlen = sizeof(*wsipx);
1077                 wsipx->sa_socket=uipx->sipx_port;
1078                 /* fall through */
1079             case 13:
1080             case 12:
1081                 memcpy(wsipx->sa_nodenum,uipx->sipx_node,sizeof(wsipx->sa_nodenum));
1082                 /* fall through */
1083             case 11:
1084             case 10:
1085             case 9:
1086             case 8:
1087             case 7:
1088             case 6:
1089                 memcpy(wsipx->sa_netnum,&uipx->sipx_network,sizeof(wsipx->sa_netnum));
1090                 /* fall through */
1091             case 5:
1092             case 4:
1093             case 3:
1094             case 2:
1095                 wsipx->sa_family=WS_AF_IPX;
1096                 /* fall through */
1097             case 1:
1098             case 0:
1099                 /* way too small */
1100                 break;
1101             }
1102         }
1103         break;
1104 #endif
1105 #ifdef HAVE_IRDA
1106     case AF_IRDA: {
1107         const struct sockaddr_irda *uin = (const struct sockaddr_irda *)uaddr;
1108         SOCKADDR_IRDA *win = (SOCKADDR_IRDA *)wsaddr;
1109
1110         if (*wsaddrlen < sizeof(SOCKADDR_IRDA))
1111             return -1;
1112         win->irdaAddressFamily = WS_AF_IRDA;
1113         memcpy( win->irdaDeviceID, &uin->sir_addr, sizeof(win->irdaDeviceID) );
1114         if (uin->sir_lsap_sel != LSAP_ANY)
1115             sprintf( win->irdaServiceName, "LSAP-SEL%u", uin->sir_lsap_sel );
1116         else
1117             memcpy( win->irdaServiceName, uin->sir_name,
1118                     sizeof(win->irdaServiceName) );
1119         return 0;
1120     }
1121 #endif
1122     case AF_INET6: {
1123         const struct sockaddr_in6* uin6 = (const struct sockaddr_in6*)uaddr;
1124         struct WS_sockaddr_in6_old* win6old = (struct WS_sockaddr_in6_old*)wsaddr;
1125
1126         if (*wsaddrlen < sizeof(struct WS_sockaddr_in6_old))
1127             return -1;
1128         win6old->sin6_family   = WS_AF_INET6;
1129         win6old->sin6_port     = uin6->sin6_port;
1130         win6old->sin6_flowinfo = uin6->sin6_flowinfo;
1131         memcpy(&win6old->sin6_addr,&uin6->sin6_addr,16); /* 16 bytes = 128 address bits */
1132         *wsaddrlen = sizeof(struct WS_sockaddr_in6_old);
1133 #ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID
1134         if (*wsaddrlen >= sizeof(struct WS_sockaddr_in6)) {
1135             struct WS_sockaddr_in6* win6 = (struct WS_sockaddr_in6*)wsaddr;
1136             win6->sin6_scope_id = uin6->sin6_scope_id;
1137             *wsaddrlen = sizeof(struct WS_sockaddr_in6);
1138         }
1139 #endif
1140         return 0;
1141     }
1142     case AF_INET: {
1143         const struct sockaddr_in* uin = (const struct sockaddr_in*)uaddr;
1144         struct WS_sockaddr_in* win = (struct WS_sockaddr_in*)wsaddr;
1145
1146         if (*wsaddrlen < sizeof(struct WS_sockaddr_in))
1147             return -1;
1148         win->sin_family = WS_AF_INET;
1149         win->sin_port   = uin->sin_port;
1150         memcpy(&win->sin_addr,&uin->sin_addr,4); /* 4 bytes = 32 address bits */
1151         memset(win->sin_zero, 0, 8); /* Make sure the null padding is null */
1152         *wsaddrlen = sizeof(struct WS_sockaddr_in);
1153         return 0;
1154     }
1155     case AF_UNSPEC: {
1156         memset(wsaddr,0,*wsaddrlen);
1157         return 0;
1158     }
1159     default:
1160         FIXME("Unknown address family %d\n", uaddr->sa_family);
1161         return -1;
1162     }
1163     return res;
1164 }
1165
1166 /**************************************************************************
1167  * Functions for handling overlapped I/O
1168  **************************************************************************/
1169
1170 /* user APC called upon async completion */
1171 static void WINAPI ws2_async_apc( void *arg, IO_STATUS_BLOCK *iosb, ULONG reserved )
1172 {
1173     ws2_async *wsa = arg;
1174
1175     if (wsa->completion_func) wsa->completion_func( NtStatusToWSAError(iosb->u.Status),
1176                                                     iosb->Information, wsa->user_overlapped,
1177                                                     wsa->flags );
1178     HeapFree( GetProcessHeap(), 0, wsa );
1179 }
1180
1181 /***********************************************************************
1182  *              WS2_recv                (INTERNAL)
1183  *
1184  * Workhorse for both synchronous and asynchronous recv() operations.
1185  */
1186 static int WS2_recv( int fd, struct ws2_async *wsa )
1187 {
1188     struct msghdr hdr;
1189     union generic_unix_sockaddr unix_sockaddr;
1190     int n;
1191
1192     hdr.msg_name = NULL;
1193
1194     if (wsa->addr)
1195     {
1196         hdr.msg_namelen = sizeof(unix_sockaddr);
1197         hdr.msg_name = &unix_sockaddr;
1198     }
1199     else
1200         hdr.msg_namelen = 0;
1201
1202     hdr.msg_iov = wsa->iovec + wsa->first_iovec;
1203     hdr.msg_iovlen = wsa->n_iovecs - wsa->first_iovec;
1204 #ifdef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
1205     hdr.msg_accrights = NULL;
1206     hdr.msg_accrightslen = 0;
1207 #else
1208     hdr.msg_control = NULL;
1209     hdr.msg_controllen = 0;
1210     hdr.msg_flags = 0;
1211 #endif
1212
1213     if ( (n = recvmsg(fd, &hdr, wsa->flags)) == -1 )
1214         return -1;
1215
1216     /* if this socket is connected and lpFrom is not NULL, Linux doesn't give us
1217      * msg_name and msg_namelen from recvmsg, but it does set msg_namelen to zero.
1218      *
1219      * quoting linux 2.6 net/ipv4/tcp.c:
1220      *  "According to UNIX98, msg_name/msg_namelen are ignored
1221      *  on connected socket. I was just happy when found this 8) --ANK"
1222      *
1223      * likewise MSDN says that lpFrom and lpFromlen are ignored for
1224      * connection-oriented sockets, so don't try to update lpFrom.
1225      */
1226     if (wsa->addr && hdr.msg_namelen)
1227         ws_sockaddr_u2ws( &unix_sockaddr.addr, wsa->addr, wsa->addrlen.ptr );
1228
1229     return n;
1230 }
1231
1232 /***********************************************************************
1233  *              WS2_async_recv          (INTERNAL)
1234  *
1235  * Handler for overlapped recv() operations.
1236  */
1237 static NTSTATUS WS2_async_recv( void* user, IO_STATUS_BLOCK* iosb, NTSTATUS status, void **apc)
1238 {
1239     ws2_async* wsa = user;
1240     int result = 0, fd;
1241
1242     switch (status)
1243     {
1244     case STATUS_ALERTED:
1245         if ((status = wine_server_handle_to_fd( wsa->hSocket, FILE_READ_DATA, &fd, NULL ) ))
1246             break;
1247
1248         result = WS2_recv( fd, wsa );
1249         wine_server_release_fd( wsa->hSocket, fd );
1250         if (result >= 0)
1251         {
1252             status = STATUS_SUCCESS;
1253             _enable_event( wsa->hSocket, FD_READ, 0, 0 );
1254         }
1255         else
1256         {
1257             if (errno == EINTR || errno == EAGAIN)
1258             {
1259                 status = STATUS_PENDING;
1260                 _enable_event( wsa->hSocket, FD_READ, 0, 0 );
1261             }
1262             else
1263             {
1264                 result = 0;
1265                 status = wsaErrno(); /* FIXME: is this correct ???? */
1266             }
1267         }
1268         break;
1269     }
1270     if (status != STATUS_PENDING)
1271     {
1272         iosb->u.Status = status;
1273         iosb->Information = result;
1274         *apc = ws2_async_apc;
1275     }
1276     return status;
1277 }
1278
1279 /***********************************************************************
1280  *              WS2_send                (INTERNAL)
1281  *
1282  * Workhorse for both synchronous and asynchronous send() operations.
1283  */
1284 static int WS2_send( int fd, struct ws2_async *wsa )
1285 {
1286     struct msghdr hdr;
1287     union generic_unix_sockaddr unix_addr;
1288
1289     hdr.msg_name = NULL;
1290     hdr.msg_namelen = 0;
1291
1292     if (wsa->addr)
1293     {
1294         hdr.msg_name = &unix_addr;
1295         hdr.msg_namelen = ws_sockaddr_ws2u( wsa->addr, wsa->addrlen.val, &unix_addr );
1296         if ( !hdr.msg_namelen )
1297         {
1298             errno = EFAULT;
1299             return -1;
1300         }
1301
1302 #if defined(HAVE_IPX) && defined(SOL_IPX)
1303         if(wsa->addr->sa_family == WS_AF_IPX)
1304         {
1305             struct sockaddr_ipx* uipx = (struct sockaddr_ipx*)hdr.msg_name;
1306             int val=0;
1307             unsigned int len=sizeof(int);
1308
1309             /* The packet type is stored at the ipx socket level; At least the linux kernel seems
1310              *  to do something with it in case hdr.msg_name is NULL. Nonetheless can we use it to store
1311              *  the packet type and then we can retrieve it using getsockopt. After that we can set the
1312              *  ipx type in the sockaddr_opx structure with the stored value.
1313              */
1314             if(getsockopt(fd, SOL_IPX, IPX_TYPE, &val, &len) != -1)
1315                 uipx->sipx_type = val;
1316         }
1317 #endif
1318     }
1319
1320     hdr.msg_iov = wsa->iovec + wsa->first_iovec;
1321     hdr.msg_iovlen = wsa->n_iovecs - wsa->first_iovec;
1322 #ifdef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
1323     hdr.msg_accrights = NULL;
1324     hdr.msg_accrightslen = 0;
1325 #else
1326     hdr.msg_control = NULL;
1327     hdr.msg_controllen = 0;
1328     hdr.msg_flags = 0;
1329 #endif
1330
1331     return sendmsg(fd, &hdr, wsa->flags);
1332 }
1333
1334 /***********************************************************************
1335  *              WS2_async_send          (INTERNAL)
1336  *
1337  * Handler for overlapped send() operations.
1338  */
1339 static NTSTATUS WS2_async_send(void* user, IO_STATUS_BLOCK* iosb, NTSTATUS status, void **apc)
1340 {
1341     ws2_async* wsa = user;
1342     int result = 0, fd;
1343
1344     switch (status)
1345     {
1346     case STATUS_ALERTED:
1347         if ((status = wine_server_handle_to_fd( wsa->hSocket, FILE_WRITE_DATA, &fd, NULL ) ))
1348             break;
1349
1350         /* check to see if the data is ready (non-blocking) */
1351         result = WS2_send( fd, wsa );
1352         wine_server_release_fd( wsa->hSocket, fd );
1353
1354         if (result >= 0)
1355         {
1356             int totalLength = 0;
1357             unsigned int i;
1358             status = STATUS_SUCCESS;
1359             for (i = 0; i < wsa->n_iovecs; i++)
1360                 totalLength += wsa->iovec[i].iov_len;
1361             if (result < totalLength)
1362                 _enable_event( wsa->hSocket, FD_WRITE, 0, 0 );
1363         }
1364         else
1365         {
1366             if (errno == EINTR || errno == EAGAIN)
1367             {
1368                 status = STATUS_PENDING;
1369                 _enable_event( wsa->hSocket, FD_WRITE, 0, 0 );
1370             }
1371             else
1372             {
1373                 /* We set the status to a winsock error code and check for that
1374                    later in NtStatusToWSAError () */
1375                 status = wsaErrno();
1376                 result = 0;
1377             }
1378         }
1379         break;
1380     }
1381     if (status != STATUS_PENDING)
1382     {
1383         iosb->u.Status = status;
1384         iosb->Information = result;
1385         *apc = ws2_async_apc;
1386     }
1387     return status;
1388 }
1389
1390 /***********************************************************************
1391  *              WS2_async_shutdown      (INTERNAL)
1392  *
1393  * Handler for shutdown() operations on overlapped sockets.
1394  */
1395 static NTSTATUS WS2_async_shutdown( void* user, PIO_STATUS_BLOCK iosb, NTSTATUS status, void **apc )
1396 {
1397     ws2_async* wsa = user;
1398     int fd, err = 1;
1399
1400     switch (status)
1401     {
1402     case STATUS_ALERTED:
1403         if ((status = wine_server_handle_to_fd( wsa->hSocket, 0, &fd, NULL ) ))
1404             break;
1405
1406         switch ( wsa->type )
1407         {
1408         case ASYNC_TYPE_READ:   err = shutdown( fd, 0 );  break;
1409         case ASYNC_TYPE_WRITE:  err = shutdown( fd, 1 );  break;
1410         }
1411         wine_server_release_fd( wsa->hSocket, fd );
1412         status = err ? wsaErrno() : STATUS_SUCCESS;
1413         break;
1414     }
1415     iosb->u.Status = status;
1416     *apc = ws2_async_apc;
1417     return status;
1418 }
1419
1420 /***********************************************************************
1421  *  WS2_register_async_shutdown         (INTERNAL)
1422  *
1423  * Helper function for WS_shutdown() on overlapped sockets.
1424  */
1425 static int WS2_register_async_shutdown( SOCKET s, int type )
1426 {
1427     struct ws2_async *wsa;
1428     NTSTATUS status;
1429
1430     TRACE("s %ld type %d\n", s, type);
1431
1432     wsa = HeapAlloc( GetProcessHeap(), 0, sizeof(*wsa) );
1433     if ( !wsa )
1434         return WSAEFAULT;
1435
1436     wsa->hSocket         = SOCKET2HANDLE(s);
1437     wsa->type            = type;
1438     wsa->completion_func = NULL;
1439
1440     SERVER_START_REQ( register_async )
1441     {
1442         req->type   = type;
1443         req->async.handle   = wine_server_obj_handle( wsa->hSocket );
1444         req->async.callback = wine_server_client_ptr( WS2_async_shutdown );
1445         req->async.iosb     = wine_server_client_ptr( &wsa->local_iosb );
1446         req->async.arg      = wine_server_client_ptr( wsa );
1447         req->async.cvalue   = 0;
1448         status = wine_server_call( req );
1449     }
1450     SERVER_END_REQ;
1451
1452     if (status != STATUS_PENDING)
1453     {
1454         HeapFree( GetProcessHeap(), 0, wsa );
1455         return NtStatusToWSAError( status );
1456     }
1457     return 0;
1458 }
1459
1460 /***********************************************************************
1461  *              accept          (WS2_32.1)
1462  */
1463 SOCKET WINAPI WS_accept(SOCKET s, struct WS_sockaddr *addr,
1464                                  int *addrlen32)
1465 {
1466     NTSTATUS status;
1467     SOCKET as;
1468     BOOL is_blocking;
1469
1470     TRACE("socket %04lx\n", s );
1471     is_blocking = _is_blocking(s);
1472
1473     do {
1474         /* try accepting first (if there is a deferred connection) */
1475         SERVER_START_REQ( accept_socket )
1476         {
1477             req->lhandle    = wine_server_obj_handle( SOCKET2HANDLE(s) );
1478             req->access     = GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE;
1479             req->attributes = OBJ_INHERIT;
1480             status = wine_server_call( req );
1481             as = HANDLE2SOCKET( wine_server_ptr_handle( reply->handle ));
1482         }
1483         SERVER_END_REQ;
1484         if (!status)
1485         {
1486             if (addr) WS_getpeername(as, addr, addrlen32);
1487             return as;
1488         }
1489         if (is_blocking && status == WSAEWOULDBLOCK)
1490         {
1491             int fd = get_sock_fd( s, FILE_READ_DATA, NULL );
1492             /* block here */
1493             do_block(fd, POLLIN, -1);
1494             _sync_sock_state(s); /* let wineserver notice connection */
1495             release_sock_fd( s, fd );
1496         }
1497     } while (is_blocking && status == WSAEWOULDBLOCK);
1498
1499     set_error(status);
1500     return INVALID_SOCKET;
1501 }
1502
1503 /***********************************************************************
1504  *              bind                    (WS2_32.2)
1505  */
1506 int WINAPI WS_bind(SOCKET s, const struct WS_sockaddr* name, int namelen)
1507 {
1508     int fd = get_sock_fd( s, 0, NULL );
1509     int res = SOCKET_ERROR;
1510
1511     TRACE("socket %04lx, ptr %p %s, length %d\n", s, name, debugstr_sockaddr(name), namelen);
1512
1513     if (fd != -1)
1514     {
1515         if (!name || (name->sa_family && !supported_pf(name->sa_family)))
1516         {
1517             SetLastError(WSAEAFNOSUPPORT);
1518         }
1519         else
1520         {
1521             union generic_unix_sockaddr uaddr;
1522             unsigned int uaddrlen = ws_sockaddr_ws2u(name, namelen, &uaddr);
1523             if (!uaddrlen)
1524             {
1525                 SetLastError(WSAEFAULT);
1526             }
1527             else
1528             {
1529 #ifdef IPV6_V6ONLY
1530                 const struct sockaddr_in6 *in6 = (const struct sockaddr_in6*) &uaddr;
1531                 if (name->sa_family == WS_AF_INET6 &&
1532                     !memcmp(&in6->sin6_addr, &in6addr_any, sizeof(struct in6_addr)))
1533                 {
1534                     int enable = 1;
1535                     if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &enable, sizeof(enable)) == -1)
1536                     {
1537                         release_sock_fd( s, fd );
1538                         SetLastError(WSAEAFNOSUPPORT);
1539                         return SOCKET_ERROR;
1540                     }
1541                 }
1542 #endif
1543                 if (name->sa_family == WS_AF_INET)
1544                 {
1545                     struct sockaddr_in *in4 = (struct sockaddr_in*) &uaddr;
1546                     if (memcmp(&in4->sin_addr, magic_loopback_addr, 4) == 0)
1547                     {
1548                         /* Trying to bind to the default host interface, using
1549                          * INADDR_ANY instead*/
1550                         WARN("Trying to bind to magic IP address, using "
1551                              "INADDR_ANY instead.\n");
1552                         in4->sin_addr.s_addr = htonl(WS_INADDR_ANY);
1553                     }
1554                 }
1555                 if (bind(fd, &uaddr.addr, uaddrlen) < 0)
1556                 {
1557                     int loc_errno = errno;
1558                     WARN("\tfailure - errno = %i\n", errno);
1559                     errno = loc_errno;
1560                     switch (errno)
1561                     {
1562                     case EBADF:
1563                         SetLastError(WSAENOTSOCK);
1564                         break;
1565                     case EADDRNOTAVAIL:
1566                         SetLastError(WSAEINVAL);
1567                         break;
1568                     default:
1569                         SetLastError(wsaErrno());
1570                         break;
1571                     }
1572                 }
1573                 else
1574                 {
1575                     res=0; /* success */
1576                 }
1577             }
1578         }
1579         release_sock_fd( s, fd );
1580     }
1581     return res;
1582 }
1583
1584 /***********************************************************************
1585  *              closesocket             (WS2_32.3)
1586  */
1587 int WINAPI WS_closesocket(SOCKET s)
1588 {
1589     TRACE("socket %04lx\n", s);
1590     if (CloseHandle(SOCKET2HANDLE(s))) return 0;
1591     return SOCKET_ERROR;
1592 }
1593
1594 /***********************************************************************
1595  *              connect         (WS2_32.4)
1596  */
1597 int WINAPI WS_connect(SOCKET s, const struct WS_sockaddr* name, int namelen)
1598 {
1599     int fd = get_sock_fd( s, FILE_READ_DATA, NULL );
1600
1601     TRACE("socket %04lx, ptr %p %s, length %d\n", s, name, debugstr_sockaddr(name), namelen);
1602
1603     if (fd != -1)
1604     {
1605         union generic_unix_sockaddr uaddr;
1606         unsigned int uaddrlen = ws_sockaddr_ws2u(name, namelen, &uaddr);
1607
1608         if (!uaddrlen)
1609         {
1610             SetLastError(WSAEFAULT);
1611         }
1612         else
1613         {
1614             if (name->sa_family == WS_AF_INET)
1615             {
1616                 struct sockaddr_in *in4 = (struct sockaddr_in*) &uaddr;
1617                 if (memcmp(&in4->sin_addr, magic_loopback_addr, 4) == 0)
1618                 {
1619                     /* Trying to connect to magic replace-loopback address,
1620                      * assuming we really want to connect to localhost */
1621                     TRACE("Trying to connect to magic IP address, using "
1622                          "INADDR_LOOPBACK instead.\n");
1623                     in4->sin_addr.s_addr = htonl(WS_INADDR_LOOPBACK);
1624                 }
1625             }
1626
1627             if (connect(fd, &uaddr.addr, uaddrlen) == 0)
1628                 goto connect_success;
1629         }
1630
1631         if (errno == EINPROGRESS)
1632         {
1633             /* tell wineserver that a connection is in progress */
1634             _enable_event(SOCKET2HANDLE(s), FD_CONNECT|FD_READ|FD_WRITE,
1635                           FD_CONNECT|FD_READ|FD_WRITE,
1636                           FD_WINE_CONNECTED|FD_WINE_LISTENING);
1637             if (_is_blocking(s))
1638             {
1639                 int result;
1640                 /* block here */
1641                 do_block(fd, POLLIN | POLLOUT, -1);
1642                 _sync_sock_state(s); /* let wineserver notice connection */
1643                 /* retrieve any error codes from it */
1644                 result = _get_sock_error(s, FD_CONNECT_BIT);
1645                 if (result)
1646                     SetLastError(result);
1647                 else
1648                 {
1649                     goto connect_success;
1650                 }
1651             }
1652             else
1653             {
1654                 SetLastError(WSAEWOULDBLOCK);
1655             }
1656         }
1657         else
1658         {
1659             SetLastError(wsaErrno());
1660         }
1661         release_sock_fd( s, fd );
1662     }
1663     return SOCKET_ERROR;
1664
1665 connect_success:
1666     release_sock_fd( s, fd );
1667     _enable_event(SOCKET2HANDLE(s), FD_CONNECT|FD_READ|FD_WRITE,
1668                   FD_WINE_CONNECTED|FD_READ|FD_WRITE,
1669                   FD_CONNECT|FD_WINE_LISTENING);
1670     return 0;
1671 }
1672
1673 /***********************************************************************
1674  *              WSAConnect             (WS2_32.30)
1675  */
1676 int WINAPI WSAConnect( SOCKET s, const struct WS_sockaddr* name, int namelen,
1677                        LPWSABUF lpCallerData, LPWSABUF lpCalleeData,
1678                        LPQOS lpSQOS, LPQOS lpGQOS )
1679 {
1680     if ( lpCallerData || lpCalleeData || lpSQOS || lpGQOS )
1681         FIXME("unsupported parameters!\n");
1682     return WS_connect( s, name, namelen );
1683 }
1684
1685
1686 /***********************************************************************
1687  *              getpeername             (WS2_32.5)
1688  */
1689 int WINAPI WS_getpeername(SOCKET s, struct WS_sockaddr *name, int *namelen)
1690 {
1691     int fd;
1692     int res;
1693
1694     TRACE("socket: %04lx, ptr %p, len %08x\n", s, name, *namelen);
1695
1696     /* Check if what we've received is valid. Should we use IsBadReadPtr? */
1697     if( (name == NULL) || (namelen == NULL) )
1698     {
1699         SetLastError( WSAEFAULT );
1700         return SOCKET_ERROR;
1701     }
1702
1703     fd = get_sock_fd( s, 0, NULL );
1704     res = SOCKET_ERROR;
1705
1706     if (fd != -1)
1707     {
1708         union generic_unix_sockaddr uaddr;
1709         unsigned int uaddrlen = sizeof(uaddr);
1710
1711         if (getpeername(fd, &uaddr.addr, &uaddrlen) != 0)
1712         {
1713             SetLastError(wsaErrno());
1714         }
1715         else if (ws_sockaddr_u2ws(&uaddr.addr, name, namelen) != 0)
1716         {
1717             /* The buffer was too small */
1718             SetLastError(WSAEFAULT);
1719         }
1720         else
1721         {
1722             res=0;
1723         }
1724         release_sock_fd( s, fd );
1725     }
1726     return res;
1727 }
1728
1729 /***********************************************************************
1730  *              getsockname             (WS2_32.6)
1731  */
1732 int WINAPI WS_getsockname(SOCKET s, struct WS_sockaddr *name, int *namelen)
1733 {
1734     int fd;
1735     int res;
1736
1737     TRACE("socket: %04lx, ptr %p, len %8x\n", s, name, *namelen);
1738
1739     /* Check if what we've received is valid. Should we use IsBadReadPtr? */
1740     if( (name == NULL) || (namelen == NULL) )
1741     {
1742         SetLastError( WSAEFAULT );
1743         return SOCKET_ERROR;
1744     }
1745
1746     fd = get_sock_fd( s, 0, NULL );
1747     res = SOCKET_ERROR;
1748
1749     if (fd != -1)
1750     {
1751         union generic_unix_sockaddr uaddr;
1752         unsigned int uaddrlen = sizeof(uaddr);
1753
1754         if (getsockname(fd, &uaddr.addr, &uaddrlen) != 0)
1755         {
1756             SetLastError(wsaErrno());
1757         }
1758         else if (!is_sockaddr_bound(&uaddr.addr, uaddrlen))
1759         {
1760             SetLastError(WSAEINVAL);
1761         }
1762         else if (ws_sockaddr_u2ws(&uaddr.addr, name, namelen) != 0)
1763         {
1764             /* The buffer was too small */
1765             SetLastError(WSAEFAULT);
1766         }
1767         else
1768         {
1769             res=0;
1770         }
1771         release_sock_fd( s, fd );
1772     }
1773     return res;
1774 }
1775
1776 /***********************************************************************
1777  *              getsockopt              (WS2_32.7)
1778  */
1779 INT WINAPI WS_getsockopt(SOCKET s, INT level,
1780                                   INT optname, char *optval, INT *optlen)
1781 {
1782     int fd;
1783     INT ret = 0;
1784
1785     TRACE("socket: %04lx, level 0x%x, name 0x%x, ptr %p, len %d\n",
1786           s, level, optname, optval, *optlen);
1787
1788     switch(level)
1789     {
1790     case WS_SOL_SOCKET:
1791     {
1792         switch(optname)
1793         {
1794         /* Handle common cases. The special cases are below, sorted
1795          * alphabetically */
1796         case WS_SO_ACCEPTCONN:
1797         case WS_SO_BROADCAST:
1798         case WS_SO_DEBUG:
1799         case WS_SO_ERROR:
1800         case WS_SO_KEEPALIVE:
1801         case WS_SO_OOBINLINE:
1802         case WS_SO_RCVBUF:
1803         case WS_SO_REUSEADDR:
1804         case WS_SO_SNDBUF:
1805         case WS_SO_TYPE:
1806             if ( (fd = get_sock_fd( s, 0, NULL )) == -1)
1807                 return SOCKET_ERROR;
1808             convert_sockopt(&level, &optname);
1809             if (getsockopt(fd, level, optname, optval, (unsigned int *)optlen) != 0 )
1810             {
1811                 SetLastError((errno == EBADF) ? WSAENOTSOCK : wsaErrno());
1812                 ret = SOCKET_ERROR;
1813             }
1814             release_sock_fd( s, fd );
1815             return ret;
1816
1817         case WS_SO_DONTLINGER:
1818         {
1819             struct linger lingval;
1820             unsigned int len = sizeof(struct linger);
1821
1822             if (!optlen || *optlen < sizeof(BOOL)|| !optval)
1823             {
1824                 SetLastError(WSAEFAULT);
1825                 return SOCKET_ERROR;
1826             }
1827             if ( (fd = get_sock_fd( s, 0, NULL )) == -1)
1828                 return SOCKET_ERROR;
1829
1830             if (getsockopt(fd, SOL_SOCKET, SO_LINGER, &lingval, &len) != 0 )
1831             {
1832                 SetLastError((errno == EBADF) ? WSAENOTSOCK : wsaErrno());
1833                 ret = SOCKET_ERROR;
1834             }
1835             else
1836             {
1837                 *(BOOL *)optval = (lingval.l_onoff) ? FALSE : TRUE;
1838                 *optlen = sizeof(BOOL);
1839             }
1840
1841             release_sock_fd( s, fd );
1842             return ret;
1843         }
1844
1845         /* As mentioned in setsockopt, Windows ignores this, so we
1846          * always return true here */
1847         case WS_SO_DONTROUTE:
1848             if (!optlen || *optlen < sizeof(BOOL) || !optval)
1849             {
1850                 SetLastError(WSAEFAULT);
1851                 return SOCKET_ERROR;
1852             }
1853             *(BOOL *)optval = TRUE;
1854             *optlen = sizeof(BOOL);
1855             return 0;
1856
1857         case WS_SO_LINGER:
1858         {
1859             struct linger lingval;
1860             unsigned int len = sizeof(struct linger);
1861
1862             /* struct linger and LINGER have different sizes */
1863             if (!optlen || *optlen < sizeof(LINGER) || !optval)
1864             {
1865                 SetLastError(WSAEFAULT);
1866                 return SOCKET_ERROR;
1867             }
1868             if ( (fd = get_sock_fd( s, 0, NULL )) == -1)
1869                 return SOCKET_ERROR;
1870
1871             if (getsockopt(fd, SOL_SOCKET, SO_LINGER, &lingval, &len) != 0 )
1872             {
1873                 SetLastError((errno == EBADF) ? WSAENOTSOCK : wsaErrno());
1874                 ret = SOCKET_ERROR;
1875             }
1876             else
1877             {
1878                 ((LINGER *)optval)->l_onoff = lingval.l_onoff;
1879                 ((LINGER *)optval)->l_linger = lingval.l_linger;
1880                 *optlen = sizeof(struct linger);
1881             }
1882
1883             release_sock_fd( s, fd );
1884             return ret;
1885         }
1886
1887         case WS_SO_MAX_MSG_SIZE:
1888             if (!optlen || *optlen < sizeof(int) || !optval)
1889             {
1890                 SetLastError(WSAEFAULT);
1891                 return SOCKET_ERROR;
1892             }
1893             TRACE("getting global SO_MAX_MSG_SIZE = 65507\n");
1894             *(int *)optval = 65507;
1895             *optlen = sizeof(int);
1896             return 0;
1897
1898         /* SO_OPENTYPE does not require a valid socket handle. */
1899         case WS_SO_OPENTYPE:
1900             if (!optlen || *optlen < sizeof(int) || !optval)
1901             {
1902                 SetLastError(WSAEFAULT);
1903                 return SOCKET_ERROR;
1904             }
1905             *(int *)optval = get_per_thread_data()->opentype;
1906             *optlen = sizeof(int);
1907             TRACE("getting global SO_OPENTYPE = 0x%x\n", *((int*)optval) );
1908             return 0;
1909
1910 #ifdef SO_RCVTIMEO
1911         case WS_SO_RCVTIMEO:
1912 #endif
1913 #ifdef SO_SNDTIMEO
1914         case WS_SO_SNDTIMEO:
1915 #endif
1916 #if defined(SO_RCVTIMEO) || defined(SO_SNDTIMEO)
1917         {
1918             struct timeval tv;
1919             unsigned int len = sizeof(struct timeval);
1920
1921             if (!optlen || *optlen < sizeof(int)|| !optval)
1922             {
1923                 SetLastError(WSAEFAULT);
1924                 return SOCKET_ERROR;
1925             }
1926             if ( (fd = get_sock_fd( s, 0, NULL )) == -1)
1927                 return SOCKET_ERROR;
1928
1929             convert_sockopt(&level, &optname);
1930             if (getsockopt(fd, level, optname, &tv, &len) != 0 )
1931             {
1932                 SetLastError((errno == EBADF) ? WSAENOTSOCK : wsaErrno());
1933                 ret = SOCKET_ERROR;
1934             }
1935             else
1936             {
1937                 *(int *)optval = tv.tv_sec * 1000 + tv.tv_usec / 1000;
1938                 *optlen = sizeof(int);
1939             }
1940
1941             release_sock_fd( s, fd );
1942             return ret;
1943         }
1944 #endif
1945         default:
1946             TRACE("Unknown SOL_SOCKET optname: 0x%08x\n", optname);
1947             SetLastError(WSAENOPROTOOPT);
1948             return SOCKET_ERROR;
1949         } /* end switch(optname) */
1950     }/* end case WS_SOL_SOCKET */
1951 #ifdef HAVE_IPX
1952     case NSPROTO_IPX:
1953     {
1954         struct WS_sockaddr_ipx addr;
1955         IPX_ADDRESS_DATA *data;
1956         int namelen;
1957         switch(optname)
1958         {
1959         case IPX_PTYPE:
1960             if ((fd = get_sock_fd( s, 0, NULL )) == -1) return SOCKET_ERROR;
1961 #ifdef SOL_IPX
1962             if(getsockopt(fd, SOL_IPX, IPX_TYPE, optval, (unsigned int*)optlen) == -1)
1963             {
1964                 ret = SOCKET_ERROR;
1965             }
1966 #else
1967             {
1968                 struct ipx val;
1969                 socklen_t len=sizeof(struct ipx);
1970                 if(getsockopt(fd, 0, SO_DEFAULT_HEADERS, &val, &len) == -1 )
1971                     ret = SOCKET_ERROR;
1972                 else
1973                     *optval = (int)val.ipx_pt;
1974             }
1975 #endif
1976             TRACE("ptype: %d (fd: %d)\n", *(int*)optval, fd);
1977             release_sock_fd( s, fd );
1978             return ret;
1979
1980         case IPX_ADDRESS:
1981             /*
1982             *  On a Win2000 system with one network card there are usually
1983             *  three ipx devices one with a speed of 28.8kbps, 10Mbps and 100Mbps.
1984             *  Using this call you can then retrieve info about this all.
1985             *  In case of Linux it is a bit different. Usually you have
1986             *  only "one" device active and further it is not possible to
1987             *  query things like the linkspeed.
1988             */
1989             FIXME("IPX_ADDRESS\n");
1990             namelen = sizeof(struct WS_sockaddr_ipx);
1991             memset(&addr, 0, sizeof(struct WS_sockaddr_ipx));
1992             WS_getsockname(s, (struct WS_sockaddr*)&addr, &namelen);
1993
1994             data = (IPX_ADDRESS_DATA*)optval;
1995                     memcpy(data->nodenum,addr.sa_nodenum,sizeof(data->nodenum));
1996                     memcpy(data->netnum,addr.sa_netnum,sizeof(data->netnum));
1997             data->adapternum = 0;
1998             data->wan = FALSE; /* We are not on a wan for now .. */
1999             data->status = FALSE; /* Since we are not on a wan, the wan link isn't up */
2000             data->maxpkt = 1467; /* This value is the default one, at least on Win2k/WinXP */
2001             data->linkspeed = 100000; /* Set the line speed in 100bit/s to 10 Mbit;
2002                                        * note 1MB = 1000kB in this case */
2003             return 0;
2004
2005         case IPX_MAX_ADAPTER_NUM:
2006             FIXME("IPX_MAX_ADAPTER_NUM\n");
2007             *(int*)optval = 1; /* As noted under IPX_ADDRESS we have just one card. */
2008             return 0;
2009
2010         default:
2011             FIXME("IPX optname:%x\n", optname);
2012             return SOCKET_ERROR;
2013         }/* end switch(optname) */
2014     } /* end case NSPROTO_IPX */
2015 #endif
2016
2017 #ifdef HAVE_IRDA
2018     case WS_SOL_IRLMP:
2019         switch(optname)
2020         {
2021         case WS_IRLMP_ENUMDEVICES:
2022         {
2023             static const int MAX_IRDA_DEVICES = 10;
2024             char buf[sizeof(struct irda_device_list) +
2025                      (MAX_IRDA_DEVICES - 1) * sizeof(struct irda_device_info)];
2026             int fd, res;
2027             socklen_t len = sizeof(buf);
2028
2029             if ( (fd = get_sock_fd( s, 0, NULL )) == -1)
2030                 return SOCKET_ERROR;
2031             res = getsockopt( fd, SOL_IRLMP, IRLMP_ENUMDEVICES, buf, &len );
2032             if (res < 0)
2033             {
2034                 SetLastError(wsaErrno());
2035                 return SOCKET_ERROR;
2036             }
2037             else
2038             {
2039                 struct irda_device_list *src = (struct irda_device_list *)buf;
2040                 DEVICELIST *dst = (DEVICELIST *)optval;
2041                 INT needed = sizeof(DEVICELIST), i;
2042
2043                 if (src->len > 0)
2044                     needed += (src->len - 1) * sizeof(IRDA_DEVICE_INFO);
2045                 if (*optlen < needed)
2046                 {
2047                     SetLastError(WSAEFAULT);
2048                     return SOCKET_ERROR;
2049                 }
2050                 *optlen = needed;
2051                 TRACE("IRLMP_ENUMDEVICES: %d devices found:\n", src->len);
2052                 dst->numDevice = src->len;
2053                 for (i = 0; i < src->len; i++)
2054                 {
2055                     TRACE("saddr = %08x, daddr = %08x, info = %s, hints = %02x%02x\n",
2056                           src->dev[i].saddr, src->dev[i].daddr,
2057                           src->dev[i].info, src->dev[i].hints[0],
2058                           src->dev[i].hints[1]);
2059                     memcpy( dst->Device[i].irdaDeviceID,
2060                             &src->dev[i].daddr,
2061                             sizeof(dst->Device[i].irdaDeviceID) ) ;
2062                     memcpy( dst->Device[i].irdaDeviceName,
2063                             &src->dev[i].info,
2064                             sizeof(dst->Device[i].irdaDeviceName) ) ;
2065                     memcpy( &dst->Device[i].irdaDeviceHints1,
2066                             &src->dev[i].hints[0],
2067                             sizeof(dst->Device[i].irdaDeviceHints1) ) ;
2068                     memcpy( &dst->Device[i].irdaDeviceHints2,
2069                             &src->dev[i].hints[1],
2070                             sizeof(dst->Device[i].irdaDeviceHints2) ) ;
2071                     dst->Device[i].irdaCharSet = src->dev[i].charset;
2072                 }
2073                 return 0;
2074             }
2075         }
2076         default:
2077             FIXME("IrDA optname:0x%x\n", optname);
2078             return SOCKET_ERROR;
2079         }
2080         break; /* case WS_SOL_IRLMP */
2081 #endif
2082
2083     /* Levels WS_IPPROTO_TCP and WS_IPPROTO_IP convert directly */
2084     case WS_IPPROTO_TCP:
2085         switch(optname)
2086         {
2087         case WS_TCP_NODELAY:
2088             if ( (fd = get_sock_fd( s, 0, NULL )) == -1)
2089                 return SOCKET_ERROR;
2090             convert_sockopt(&level, &optname);
2091             if (getsockopt(fd, level, optname, optval, (unsigned int *)optlen) != 0 )
2092             {
2093                 SetLastError((errno == EBADF) ? WSAENOTSOCK : wsaErrno());
2094                 ret = SOCKET_ERROR;
2095             }
2096             release_sock_fd( s, fd );
2097             return ret;
2098         }
2099         FIXME("Unknown IPPROTO_TCP optname 0x%08x\n", optname);
2100         return SOCKET_ERROR;
2101
2102     case WS_IPPROTO_IP:
2103         switch(optname)
2104         {
2105         case WS_IP_ADD_MEMBERSHIP:
2106         case WS_IP_DROP_MEMBERSHIP:
2107 #ifdef IP_HDRINCL
2108         case WS_IP_HDRINCL:
2109 #endif
2110         case WS_IP_MULTICAST_IF:
2111         case WS_IP_MULTICAST_LOOP:
2112         case WS_IP_MULTICAST_TTL:
2113         case WS_IP_OPTIONS:
2114         case WS_IP_TOS:
2115         case WS_IP_TTL:
2116             if ( (fd = get_sock_fd( s, 0, NULL )) == -1)
2117                 return SOCKET_ERROR;
2118             convert_sockopt(&level, &optname);
2119             if (getsockopt(fd, level, optname, optval, (unsigned int *)optlen) != 0 )
2120             {
2121                 SetLastError((errno == EBADF) ? WSAENOTSOCK : wsaErrno());
2122                 ret = SOCKET_ERROR;
2123             }
2124             release_sock_fd( s, fd );
2125             return ret;
2126         case WS_IP_DONTFRAGMENT:
2127             FIXME("WS_IP_DONTFRAGMENT is always false!\n");
2128             *(BOOL*)optval = FALSE;
2129             return 0;
2130         }
2131         FIXME("Unknown IPPROTO_IP optname 0x%08x\n", optname);
2132         return SOCKET_ERROR;
2133
2134     case WS_IPPROTO_IPV6:
2135         FIXME("IPPROTO_IPV6 unimplemented (optname 0x%08x)\n", optname);
2136         return SOCKET_ERROR;
2137
2138     default:
2139         WARN("Unknown level: 0x%08x\n", level);
2140         SetLastError(WSAEINVAL);
2141         return SOCKET_ERROR;
2142     } /* end switch(level) */
2143 }
2144
2145 /***********************************************************************
2146  *              htonl                   (WS2_32.8)
2147  */
2148 WS_u_long WINAPI WS_htonl(WS_u_long hostlong)
2149 {
2150     return htonl(hostlong);
2151 }
2152
2153
2154 /***********************************************************************
2155  *              htons                   (WS2_32.9)
2156  */
2157 WS_u_short WINAPI WS_htons(WS_u_short hostshort)
2158 {
2159     return htons(hostshort);
2160 }
2161
2162 /***********************************************************************
2163  *              WSAHtonl                (WS2_32.46)
2164  *  From MSDN description of error codes, this function should also
2165  *  check if WinSock has been initialized and the socket is a valid
2166  *  socket. But why? This function only translates a host byte order
2167  *  u_long into a network byte order u_long...
2168  */
2169 int WINAPI WSAHtonl(SOCKET s, WS_u_long hostlong, WS_u_long *lpnetlong)
2170 {
2171     if (lpnetlong)
2172     {
2173         *lpnetlong = htonl(hostlong);
2174         return 0;
2175     }
2176     WSASetLastError(WSAEFAULT);
2177     return SOCKET_ERROR;
2178 }
2179
2180 /***********************************************************************
2181  *              WSAHtons                (WS2_32.47)
2182  *  From MSDN description of error codes, this function should also
2183  *  check if WinSock has been initialized and the socket is a valid
2184  *  socket. But why? This function only translates a host byte order
2185  *  u_short into a network byte order u_short...
2186  */
2187 int WINAPI WSAHtons(SOCKET s, WS_u_short hostshort, WS_u_short *lpnetshort)
2188 {
2189
2190     if (lpnetshort)
2191     {
2192         *lpnetshort = htons(hostshort);
2193         return 0;
2194     }
2195     WSASetLastError(WSAEFAULT);
2196     return SOCKET_ERROR;
2197 }
2198
2199
2200 /***********************************************************************
2201  *              inet_addr               (WS2_32.11)
2202  */
2203 WS_u_long WINAPI WS_inet_addr(const char *cp)
2204 {
2205     if (!cp) return INADDR_NONE;
2206     return inet_addr(cp);
2207 }
2208
2209
2210 /***********************************************************************
2211  *              ntohl                   (WS2_32.14)
2212  */
2213 WS_u_long WINAPI WS_ntohl(WS_u_long netlong)
2214 {
2215     return ntohl(netlong);
2216 }
2217
2218
2219 /***********************************************************************
2220  *              ntohs                   (WS2_32.15)
2221  */
2222 WS_u_short WINAPI WS_ntohs(WS_u_short netshort)
2223 {
2224     return ntohs(netshort);
2225 }
2226
2227
2228 /***********************************************************************
2229  *              inet_ntoa               (WS2_32.12)
2230  */
2231 char* WINAPI WS_inet_ntoa(struct WS_in_addr in)
2232 {
2233   /* use "buffer for dummies" here because some applications have a
2234    * propensity to decode addresses in ws_hostent structure without
2235    * saving them first...
2236    */
2237     static char dbuffer[16]; /* Yes, 16: 4*3 digits + 3 '.' + 1 '\0' */
2238
2239     char* s = inet_ntoa(*((struct in_addr*)&in));
2240     if( s )
2241     {
2242         strcpy(dbuffer, s);
2243         return dbuffer;
2244     }
2245     SetLastError(wsaErrno());
2246     return NULL;
2247 }
2248
2249 /**********************************************************************
2250  *              WSAIoctl                (WS2_32.50)
2251  *
2252  */
2253 INT WINAPI WSAIoctl(SOCKET s,
2254                     DWORD   dwIoControlCode,
2255                     LPVOID  lpvInBuffer,
2256                     DWORD   cbInBuffer,
2257                     LPVOID  lpbOutBuffer,
2258                     DWORD   cbOutBuffer,
2259                     LPDWORD lpcbBytesReturned,
2260                     LPWSAOVERLAPPED lpOverlapped,
2261                     LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
2262 {
2263    TRACE("%ld, 0x%08x, %p, %d, %p, %d, %p, %p, %p\n",
2264        s, dwIoControlCode, lpvInBuffer, cbInBuffer, lpbOutBuffer,
2265        cbOutBuffer, lpcbBytesReturned, lpOverlapped, lpCompletionRoutine);
2266
2267    switch( dwIoControlCode )
2268    {
2269    case WS_FIONBIO:
2270         if (cbInBuffer != sizeof(WS_u_long)) {
2271             WSASetLastError(WSAEFAULT);
2272             return SOCKET_ERROR;
2273         }
2274         return WS_ioctlsocket( s, WS_FIONBIO, lpvInBuffer);
2275
2276    case WS_FIONREAD:
2277         if (cbOutBuffer != sizeof(WS_u_long)) {
2278             WSASetLastError(WSAEFAULT);
2279             return SOCKET_ERROR;
2280         }
2281         return WS_ioctlsocket( s, WS_FIONREAD, lpbOutBuffer);
2282
2283    case WS_SIO_GET_INTERFACE_LIST:
2284        {
2285            INTERFACE_INFO* intArray = (INTERFACE_INFO*)lpbOutBuffer;
2286            DWORD size, numInt, apiReturn;
2287            int fd;
2288
2289            TRACE("-> SIO_GET_INTERFACE_LIST request\n");
2290
2291            if (!lpbOutBuffer)
2292            {
2293                WSASetLastError(WSAEFAULT);
2294                return SOCKET_ERROR;
2295            }
2296            if (!lpcbBytesReturned)
2297            {
2298                WSASetLastError(WSAEFAULT);
2299                return SOCKET_ERROR;
2300            }
2301
2302            fd = get_sock_fd( s, 0, NULL );
2303            if (fd == -1) return SOCKET_ERROR;
2304
2305            apiReturn = GetAdaptersInfo(NULL, &size);
2306            if (apiReturn == ERROR_NO_DATA)
2307            {
2308                numInt = 0;
2309            }
2310            else if (apiReturn == ERROR_BUFFER_OVERFLOW)
2311            {
2312                PIP_ADAPTER_INFO table = HeapAlloc(GetProcessHeap(),0,size);
2313
2314                if (table)
2315                {
2316                   if (GetAdaptersInfo(table, &size) == NO_ERROR)
2317                   {
2318                      PIP_ADAPTER_INFO ptr;
2319
2320                      if (size*sizeof(INTERFACE_INFO)/sizeof(IP_ADAPTER_INFO) > cbOutBuffer)
2321                      {
2322                         WARN("Buffer too small = %u, cbOutBuffer = %u\n", size, cbOutBuffer);
2323                         HeapFree(GetProcessHeap(),0,table);
2324                         release_sock_fd( s, fd );
2325                         WSASetLastError(WSAEFAULT);
2326                         return SOCKET_ERROR;
2327                      }
2328                      for (ptr = table, numInt = 0; ptr;
2329                       ptr = ptr->Next, intArray++, numInt++)
2330                      {
2331                         unsigned int addr, mask, bcast;
2332                         struct ifreq ifInfo;
2333
2334                         /* Socket Status Flags */
2335                         lstrcpynA(ifInfo.ifr_name, ptr->AdapterName, IFNAMSIZ);
2336                         if (ioctl(fd, SIOCGIFFLAGS, &ifInfo) < 0)
2337                         {
2338                            ERR("Error obtaining status flags for socket!\n");
2339                            HeapFree(GetProcessHeap(),0,table);
2340                            release_sock_fd( s, fd );
2341                            WSASetLastError(WSAEINVAL);
2342                            return SOCKET_ERROR;
2343                         }
2344                         else
2345                         {
2346                            /* set flags; the values of IFF_* are not the same
2347                               under Linux and Windows, therefore must generate
2348                               new flags */
2349                            intArray->iiFlags = 0;
2350                            if (ifInfo.ifr_flags & IFF_BROADCAST)
2351                               intArray->iiFlags |= WS_IFF_BROADCAST;
2352 #ifdef IFF_POINTOPOINT
2353                            if (ifInfo.ifr_flags & IFF_POINTOPOINT)
2354                               intArray->iiFlags |= WS_IFF_POINTTOPOINT;
2355 #endif
2356                            if (ifInfo.ifr_flags & IFF_LOOPBACK)
2357                               intArray->iiFlags |= WS_IFF_LOOPBACK;
2358                            if (ifInfo.ifr_flags & IFF_UP)
2359                               intArray->iiFlags |= WS_IFF_UP;
2360                            if (ifInfo.ifr_flags & IFF_MULTICAST)
2361                               intArray->iiFlags |= WS_IFF_MULTICAST;
2362                         }
2363
2364                         addr = inet_addr(ptr->IpAddressList.IpAddress.String);
2365                         mask = inet_addr(ptr->IpAddressList.IpMask.String);
2366                         bcast = addr | ~mask;
2367                         intArray->iiAddress.AddressIn.sin_family = AF_INET;
2368                         intArray->iiAddress.AddressIn.sin_port = 0;
2369                         intArray->iiAddress.AddressIn.sin_addr.WS_s_addr =
2370                          addr;
2371                         intArray->iiNetmask.AddressIn.sin_family = AF_INET;
2372                         intArray->iiNetmask.AddressIn.sin_port = 0;
2373                         intArray->iiNetmask.AddressIn.sin_addr.WS_s_addr =
2374                          mask;
2375                         intArray->iiBroadcastAddress.AddressIn.sin_family =
2376                          AF_INET;
2377                         intArray->iiBroadcastAddress.AddressIn.sin_port = 0;
2378                         intArray->iiBroadcastAddress.AddressIn.sin_addr.
2379                          WS_s_addr = bcast;
2380                      }
2381                   }
2382                   else
2383                   {
2384                      ERR("Unable to get interface table!\n");
2385                      release_sock_fd( s, fd );
2386                      HeapFree(GetProcessHeap(),0,table);
2387                      WSASetLastError(WSAEINVAL);
2388                      return SOCKET_ERROR;
2389                   }
2390                   HeapFree(GetProcessHeap(),0,table);
2391                }
2392                else
2393                {
2394                   release_sock_fd( s, fd );
2395                   WSASetLastError(WSAEINVAL);
2396                   return SOCKET_ERROR;
2397                }
2398            }
2399            else
2400            {
2401                ERR("Unable to get interface table!\n");
2402                release_sock_fd( s, fd );
2403                WSASetLastError(WSAEINVAL);
2404                return SOCKET_ERROR;
2405            }
2406            /* Calculate the size of the array being returned */
2407            *lpcbBytesReturned = sizeof(INTERFACE_INFO) * numInt;
2408            release_sock_fd( s, fd );
2409            break;
2410        }
2411
2412    case WS_SIO_ADDRESS_LIST_CHANGE:
2413        FIXME("-> SIO_ADDRESS_LIST_CHANGE request: stub\n");
2414        /* FIXME: error and return code depend on whether socket was created
2415         * with WSA_FLAG_OVERLAPPED, but there is no easy way to get this */
2416        break;
2417
2418    case WS_SIO_ADDRESS_LIST_QUERY:
2419    {
2420         DWORD size;
2421
2422         TRACE("-> SIO_ADDRESS_LIST_QUERY request\n");
2423
2424         if (!lpcbBytesReturned)
2425         {
2426             WSASetLastError(WSAEFAULT);
2427             return SOCKET_ERROR;
2428         }
2429
2430         if (GetAdaptersInfo(NULL, &size) == ERROR_BUFFER_OVERFLOW)
2431         {
2432             IP_ADAPTER_INFO *p, *table = HeapAlloc(GetProcessHeap(), 0, size);
2433             DWORD need, num;
2434
2435             if (!table || GetAdaptersInfo(table, &size))
2436             {
2437                 HeapFree(GetProcessHeap(), 0, table);
2438                 WSASetLastError(WSAEINVAL);
2439                 return SOCKET_ERROR;
2440             }
2441
2442             for (p = table, num = 0; p; p = p->Next)
2443                 if (p->IpAddressList.IpAddress.String[0]) num++;
2444
2445             need = sizeof(SOCKET_ADDRESS_LIST) + sizeof(SOCKET_ADDRESS) * (num - 1);
2446             need += sizeof(SOCKADDR) * num;
2447             *lpcbBytesReturned = need;
2448
2449             if (need > cbOutBuffer)
2450             {
2451                 HeapFree(GetProcessHeap(), 0, table);
2452                 WSASetLastError(WSAEFAULT);
2453                 return SOCKET_ERROR;
2454             }
2455
2456             if (lpbOutBuffer)
2457             {
2458                 unsigned int i;
2459                 SOCKET_ADDRESS *sa;
2460                 SOCKET_ADDRESS_LIST *sa_list = (SOCKET_ADDRESS_LIST *)lpbOutBuffer;
2461                 SOCKADDR_IN *sockaddr;
2462
2463                 sa = sa_list->Address;
2464                 sockaddr = (SOCKADDR_IN *)((char *)sa + num * sizeof(SOCKET_ADDRESS));
2465                 sa_list->iAddressCount = num;
2466
2467                 for (p = table, i = 0; p; p = p->Next)
2468                 {
2469                     if (!p->IpAddressList.IpAddress.String[0]) continue;
2470
2471                     sa[i].lpSockaddr = (SOCKADDR *)&sockaddr[i];
2472                     sa[i].iSockaddrLength = sizeof(SOCKADDR);
2473
2474                     sockaddr[i].sin_family = AF_INET;
2475                     sockaddr[i].sin_port = 0;
2476                     sockaddr[i].sin_addr.WS_s_addr = inet_addr(p->IpAddressList.IpAddress.String);
2477                     i++;
2478                 }
2479             }
2480
2481             HeapFree(GetProcessHeap(), 0, table);
2482             return 0;
2483         }
2484         else
2485         {
2486             WARN("unable to get IP address list\n");
2487             WSASetLastError(WSAEINVAL);
2488             return SOCKET_ERROR;
2489         }
2490    }
2491    case WS_SIO_FLUSH:
2492         FIXME("SIO_FLUSH: stub.\n");
2493         break;
2494
2495    case WS_SIO_GET_EXTENSION_FUNCTION_POINTER:
2496        FIXME("SIO_GET_EXTENSION_FUNCTION_POINTER %s: stub\n", debugstr_guid(lpvInBuffer));
2497        WSASetLastError(WSAEOPNOTSUPP);
2498        return SOCKET_ERROR;
2499
2500    case WS_SIO_KEEPALIVE_VALS:
2501    {
2502         int fd;
2503         struct tcp_keepalive *k = lpvInBuffer;
2504         int keepalive = k->onoff ? 1 : 0;
2505         int keepidle = k->keepalivetime / 1000;
2506         int keepintvl = k->keepaliveinterval / 1000;
2507
2508         if (!lpvInBuffer)
2509         {
2510             WSASetLastError(WSAEINVAL);
2511             return SOCKET_ERROR;
2512         }
2513
2514         TRACE("onoff: %d, keepalivetime: %d, keepaliveinterval: %d\n", keepalive, keepidle, keepintvl);
2515
2516         fd = get_sock_fd(s, 0, NULL);
2517         if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepalive, sizeof(int)) == -1)
2518         {
2519             release_sock_fd(s, fd);
2520             WSASetLastError(WSAEINVAL);
2521             return SOCKET_ERROR;
2522         }
2523 #if defined(TCP_KEEPIDLE) && defined(TCP_KEEPINTVL)
2524         if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, (void *)&keepidle, sizeof(int)) == -1)
2525         {
2526             release_sock_fd(s, fd);
2527             WSASetLastError(WSAEINVAL);
2528             return SOCKET_ERROR;
2529         }
2530         if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, (void *)&keepintvl, sizeof(int)) == -1)
2531         {
2532             release_sock_fd(s, fd);
2533             WSASetLastError(WSAEINVAL);
2534             return SOCKET_ERROR;
2535         }
2536 #else
2537         FIXME("ignoring keepalive interval and timeout\n");
2538 #endif
2539
2540         release_sock_fd(s, fd);
2541         break;
2542    }
2543    default:
2544        FIXME("unsupported WS_IOCTL cmd (%08x)\n", dwIoControlCode);
2545        WSASetLastError(WSAEOPNOTSUPP);
2546        return SOCKET_ERROR;
2547    }
2548
2549    return 0;
2550 }
2551
2552
2553 /***********************************************************************
2554  *              ioctlsocket             (WS2_32.10)
2555  */
2556 int WINAPI WS_ioctlsocket(SOCKET s, LONG cmd, WS_u_long *argp)
2557 {
2558     int fd;
2559     LONG newcmd  = cmd;
2560
2561     TRACE("socket %04lx, cmd %08x, ptr %p\n", s, cmd, argp);
2562     /* broken apps like defcon pass the argp value directly instead of a pointer to it */
2563     if(IS_INTRESOURCE(argp))
2564     {
2565        SetLastError(WSAEFAULT);
2566        return SOCKET_ERROR;
2567     }
2568
2569     switch( cmd )
2570     {
2571     case WS_FIONREAD:
2572         newcmd=FIONREAD;
2573         break;
2574
2575     case WS_FIONBIO:
2576         if( _get_sock_mask(s) )
2577         {
2578             /* AsyncSelect()'ed sockets are always nonblocking */
2579             if (*argp) return 0;
2580             SetLastError(WSAEINVAL);
2581             return SOCKET_ERROR;
2582         }
2583         if (*argp)
2584             _enable_event(SOCKET2HANDLE(s), 0, FD_WINE_NONBLOCKING, 0);
2585         else
2586             _enable_event(SOCKET2HANDLE(s), 0, 0, FD_WINE_NONBLOCKING);
2587         return 0;
2588
2589     case WS_SIOCATMARK:
2590         newcmd=SIOCATMARK;
2591         break;
2592
2593     case WS_FIOASYNC:
2594         WARN("Warning: WS1.1 shouldn't be using async I/O\n");
2595         SetLastError(WSAEINVAL);
2596         return SOCKET_ERROR;
2597
2598     case SIOCGIFBRDADDR:
2599     case SIOCGIFNETMASK:
2600     case SIOCGIFADDR:
2601         /* These don't need any special handling.  They are used by
2602            WsControl, and are here to suppress an unnecessary warning. */
2603         break;
2604
2605     default:
2606         /* Netscape tries hard to use bogus ioctl 0x667e */
2607         /* FIXME: 0x667e above is ('f' << 8) | 126, and is a low word of
2608          * FIONBIO (_IOW('f', 126, u_long)), how that should be handled?
2609          */
2610         WARN("\tunknown WS_IOCTL cmd (%08x)\n", cmd);
2611         break;
2612     }
2613
2614     fd = get_sock_fd( s, 0, NULL );
2615     if (fd != -1)
2616     {
2617         if( ioctl(fd, newcmd, (char*)argp ) == 0 )
2618         {
2619             release_sock_fd( s, fd );
2620             return 0;
2621         }
2622         SetLastError((errno == EBADF) ? WSAENOTSOCK : wsaErrno());
2623         release_sock_fd( s, fd );
2624     }
2625     return SOCKET_ERROR;
2626 }
2627
2628 /***********************************************************************
2629  *              listen          (WS2_32.13)
2630  */
2631 int WINAPI WS_listen(SOCKET s, int backlog)
2632 {
2633     int fd = get_sock_fd( s, FILE_READ_DATA, NULL );
2634
2635     TRACE("socket %04lx, backlog %d\n", s, backlog);
2636     if (fd != -1)
2637     {
2638         if (listen(fd, backlog) == 0)
2639         {
2640             release_sock_fd( s, fd );
2641             _enable_event(SOCKET2HANDLE(s), FD_ACCEPT,
2642                           FD_WINE_LISTENING,
2643                           FD_CONNECT|FD_WINE_CONNECTED);
2644             return 0;
2645         }
2646         SetLastError(wsaErrno());
2647         release_sock_fd( s, fd );
2648     }
2649     return SOCKET_ERROR;
2650 }
2651
2652 /***********************************************************************
2653  *              recv                    (WS2_32.16)
2654  */
2655 int WINAPI WS_recv(SOCKET s, char *buf, int len, int flags)
2656 {
2657     DWORD n, dwFlags = flags;
2658     WSABUF wsabuf;
2659
2660     wsabuf.len = len;
2661     wsabuf.buf = buf;
2662
2663     if ( WSARecvFrom(s, &wsabuf, 1, &n, &dwFlags, NULL, NULL, NULL, NULL) == SOCKET_ERROR )
2664         return SOCKET_ERROR;
2665     else
2666         return n;
2667 }
2668
2669 /***********************************************************************
2670  *              recvfrom                (WS2_32.17)
2671  */
2672 int WINAPI WS_recvfrom(SOCKET s, char *buf, INT len, int flags,
2673                        struct WS_sockaddr *from, int *fromlen)
2674 {
2675     DWORD n, dwFlags = flags;
2676     WSABUF wsabuf;
2677
2678     wsabuf.len = len;
2679     wsabuf.buf = buf;
2680
2681     if ( WSARecvFrom(s, &wsabuf, 1, &n, &dwFlags, from, fromlen, NULL, NULL) == SOCKET_ERROR )
2682         return SOCKET_ERROR;
2683     else
2684         return n;
2685 }
2686
2687 /* allocate a poll array for the corresponding fd sets */
2688 static struct pollfd *fd_sets_to_poll( const WS_fd_set *readfds, const WS_fd_set *writefds,
2689                                        const WS_fd_set *exceptfds, int *count_ptr )
2690 {
2691     unsigned int i, j = 0, count = 0;
2692     struct pollfd *fds;
2693
2694     if (readfds) count += readfds->fd_count;
2695     if (writefds) count += writefds->fd_count;
2696     if (exceptfds) count += exceptfds->fd_count;
2697     *count_ptr = count;
2698     if (!count) return NULL;
2699     if (!(fds = HeapAlloc( GetProcessHeap(), 0, count * sizeof(fds[0])))) return NULL;
2700     if (readfds)
2701         for (i = 0; i < readfds->fd_count; i++, j++)
2702         {
2703             fds[j].fd = get_sock_fd( readfds->fd_array[i], FILE_READ_DATA, NULL );
2704             fds[j].events = POLLIN;
2705             fds[j].revents = 0;
2706         }
2707     if (writefds)
2708         for (i = 0; i < writefds->fd_count; i++, j++)
2709         {
2710             fds[j].fd = get_sock_fd( writefds->fd_array[i], FILE_WRITE_DATA, NULL );
2711             fds[j].events = POLLOUT;
2712             fds[j].revents = 0;
2713         }
2714     if (exceptfds)
2715         for (i = 0; i < exceptfds->fd_count; i++, j++)
2716         {
2717             fds[j].fd = get_sock_fd( exceptfds->fd_array[i], 0, NULL );
2718             fds[j].events = POLLHUP;
2719             fds[j].revents = 0;
2720         }
2721     return fds;
2722 }
2723
2724 /* release the file descriptor obtained in fd_sets_to_poll */
2725 /* must be called with the original fd_set arrays, before calling get_poll_results */
2726 static void release_poll_fds( const WS_fd_set *readfds, const WS_fd_set *writefds,
2727                               const WS_fd_set *exceptfds, struct pollfd *fds )
2728 {
2729     unsigned int i, j = 0;
2730
2731     if (readfds)
2732     {
2733         for (i = 0; i < readfds->fd_count; i++, j++)
2734             if (fds[j].fd != -1) release_sock_fd( readfds->fd_array[i], fds[j].fd );
2735     }
2736     if (writefds)
2737     {
2738         for (i = 0; i < writefds->fd_count; i++, j++)
2739             if (fds[j].fd != -1) release_sock_fd( writefds->fd_array[i], fds[j].fd );
2740     }
2741     if (exceptfds)
2742     {
2743         for (i = 0; i < exceptfds->fd_count; i++, j++)
2744             if (fds[j].fd != -1)
2745             {
2746                 /* make sure we have a real error before releasing the fd */
2747                 if (!sock_error_p( fds[j].fd )) fds[j].revents = 0;
2748                 release_sock_fd( exceptfds->fd_array[i], fds[j].fd );
2749             }
2750     }
2751 }
2752
2753 /* map the poll results back into the Windows fd sets */
2754 static int get_poll_results( WS_fd_set *readfds, WS_fd_set *writefds, WS_fd_set *exceptfds,
2755                              const struct pollfd *fds )
2756 {
2757     unsigned int i, j = 0, k, total = 0;
2758
2759     if (readfds)
2760     {
2761         for (i = k = 0; i < readfds->fd_count; i++, j++)
2762             if (fds[j].revents) readfds->fd_array[k++] = readfds->fd_array[i];
2763         readfds->fd_count = k;
2764         total += k;
2765     }
2766     if (writefds)
2767     {
2768         for (i = k = 0; i < writefds->fd_count; i++, j++)
2769             if (fds[j].revents) writefds->fd_array[k++] = writefds->fd_array[i];
2770         writefds->fd_count = k;
2771         total += k;
2772     }
2773     if (exceptfds)
2774     {
2775         for (i = k = 0; i < exceptfds->fd_count; i++, j++)
2776             if (fds[j].revents) exceptfds->fd_array[k++] = exceptfds->fd_array[i];
2777         exceptfds->fd_count = k;
2778         total += k;
2779     }
2780     return total;
2781 }
2782
2783
2784 /***********************************************************************
2785  *              select                  (WS2_32.18)
2786  */
2787 int WINAPI WS_select(int nfds, WS_fd_set *ws_readfds,
2788                      WS_fd_set *ws_writefds, WS_fd_set *ws_exceptfds,
2789                      const struct WS_timeval* ws_timeout)
2790 {
2791     struct pollfd *pollfds;
2792     int count, ret, timeout = -1;
2793
2794     TRACE("read %p, write %p, excp %p timeout %p\n",
2795           ws_readfds, ws_writefds, ws_exceptfds, ws_timeout);
2796
2797     if (!(pollfds = fd_sets_to_poll( ws_readfds, ws_writefds, ws_exceptfds, &count )) && count)
2798     {
2799         SetLastError( ERROR_NOT_ENOUGH_MEMORY );
2800         return SOCKET_ERROR;
2801     }
2802
2803     if (ws_timeout) timeout = (ws_timeout->tv_sec * 1000) + (ws_timeout->tv_usec + 999) / 1000;
2804
2805     ret = poll( pollfds, count, timeout );
2806     release_poll_fds( ws_readfds, ws_writefds, ws_exceptfds, pollfds );
2807
2808     if (ret == -1) SetLastError(wsaErrno());
2809     else ret = get_poll_results( ws_readfds, ws_writefds, ws_exceptfds, pollfds );
2810     HeapFree( GetProcessHeap(), 0, pollfds );
2811     return ret;
2812 }
2813
2814 /* helper to send completion messages for client-only i/o operation case */
2815 static void WS_AddCompletion( SOCKET sock, ULONG_PTR CompletionValue, NTSTATUS CompletionStatus,
2816                               ULONG Information )
2817 {
2818     NTSTATUS status;
2819
2820     SERVER_START_REQ( add_fd_completion )
2821     {
2822         req->handle      = wine_server_obj_handle( SOCKET2HANDLE(sock) );
2823         req->cvalue      = CompletionValue;
2824         req->status      = CompletionStatus;
2825         req->information = Information;
2826         status = wine_server_call( req );
2827     }
2828     SERVER_END_REQ;
2829 }
2830
2831
2832 /***********************************************************************
2833  *              send                    (WS2_32.19)
2834  */
2835 int WINAPI WS_send(SOCKET s, const char *buf, int len, int flags)
2836 {
2837     DWORD n;
2838     WSABUF wsabuf;
2839
2840     wsabuf.len = len;
2841     wsabuf.buf = (char*) buf;
2842
2843     if ( WSASendTo( s, &wsabuf, 1, &n, flags, NULL, 0, NULL, NULL) == SOCKET_ERROR )
2844         return SOCKET_ERROR;
2845     else
2846         return n;
2847 }
2848
2849 /***********************************************************************
2850  *              WSASend                 (WS2_32.72)
2851  */
2852 INT WINAPI WSASend( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
2853                     LPDWORD lpNumberOfBytesSent, DWORD dwFlags,
2854                     LPWSAOVERLAPPED lpOverlapped,
2855                     LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine )
2856 {
2857     return WSASendTo( s, lpBuffers, dwBufferCount, lpNumberOfBytesSent, dwFlags,
2858                       NULL, 0, lpOverlapped, lpCompletionRoutine );
2859 }
2860
2861 /***********************************************************************
2862  *              WSASendDisconnect       (WS2_32.73)
2863  */
2864 INT WINAPI WSASendDisconnect( SOCKET s, LPWSABUF lpBuffers )
2865 {
2866     return WS_shutdown( s, SD_SEND );
2867 }
2868
2869
2870 /***********************************************************************
2871  *              WSASendTo               (WS2_32.74)
2872  */
2873 INT WINAPI WSASendTo( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
2874                       LPDWORD lpNumberOfBytesSent, DWORD dwFlags,
2875                       const struct WS_sockaddr *to, int tolen,
2876                       LPWSAOVERLAPPED lpOverlapped,
2877                       LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine )
2878 {
2879     unsigned int i, options;
2880     int n, fd, err;
2881     struct ws2_async *wsa;
2882     int totalLength = 0;
2883     ULONG_PTR cvalue = (lpOverlapped && ((ULONG_PTR)lpOverlapped->hEvent & 1) == 0) ? (ULONG_PTR)lpOverlapped : 0;
2884
2885     TRACE("socket %04lx, wsabuf %p, nbufs %d, flags %d, to %p, tolen %d, ovl %p, func %p\n",
2886           s, lpBuffers, dwBufferCount, dwFlags,
2887           to, tolen, lpOverlapped, lpCompletionRoutine);
2888
2889     fd = get_sock_fd( s, FILE_WRITE_DATA, &options );
2890     TRACE( "fd=%d, options=%x\n", fd, options );
2891
2892     if ( fd == -1 ) return SOCKET_ERROR;
2893
2894     if (!(wsa = HeapAlloc( GetProcessHeap(), 0, FIELD_OFFSET(struct ws2_async, iovec[dwBufferCount]) )))
2895     {
2896         err = WSAEFAULT;
2897         goto error;
2898     }
2899
2900     wsa->hSocket     = SOCKET2HANDLE(s);
2901     wsa->addr        = (struct WS_sockaddr *)to;
2902     wsa->addrlen.val = tolen;
2903     wsa->flags       = dwFlags;
2904     wsa->n_iovecs    = dwBufferCount;
2905     wsa->first_iovec = 0;
2906     for ( i = 0; i < dwBufferCount; i++ )
2907     {
2908         wsa->iovec[i].iov_base = lpBuffers[i].buf;
2909         wsa->iovec[i].iov_len  = lpBuffers[i].len;
2910         totalLength += lpBuffers[i].len;
2911     }
2912
2913     if (!lpNumberOfBytesSent)
2914     {
2915         err = WSAEFAULT;
2916         goto error;
2917     }
2918
2919     for (;;)
2920     {
2921         n = WS2_send( fd, wsa );
2922         if (n != -1 || errno != EINTR) break;
2923     }
2924     if (n == -1 && errno != EAGAIN)
2925     {
2926         err = wsaErrno();
2927         if (cvalue) WS_AddCompletion( s, cvalue, err, 0 );
2928         goto error;
2929     }
2930
2931     if ((lpOverlapped || lpCompletionRoutine) &&
2932         !(options & (FILE_SYNCHRONOUS_IO_ALERT | FILE_SYNCHRONOUS_IO_NONALERT)))
2933     {
2934         IO_STATUS_BLOCK *iosb = lpOverlapped ? (IO_STATUS_BLOCK *)lpOverlapped : &wsa->local_iosb;
2935
2936         wsa->user_overlapped = lpOverlapped;
2937         wsa->completion_func = lpCompletionRoutine;
2938         release_sock_fd( s, fd );
2939
2940         if (n == -1)
2941         {
2942             iosb->u.Status = STATUS_PENDING;
2943             iosb->Information = 0;
2944
2945             SERVER_START_REQ( register_async )
2946             {
2947                 req->type           = ASYNC_TYPE_WRITE;
2948                 req->async.handle   = wine_server_obj_handle( wsa->hSocket );
2949                 req->async.callback = wine_server_client_ptr( WS2_async_send );
2950                 req->async.iosb     = wine_server_client_ptr( iosb );
2951                 req->async.arg      = wine_server_client_ptr( wsa );
2952                 req->async.event    = wine_server_obj_handle( lpCompletionRoutine ? 0 : lpOverlapped->hEvent );
2953                 req->async.cvalue   = cvalue;
2954                 err = wine_server_call( req );
2955             }
2956             SERVER_END_REQ;
2957
2958             if (err != STATUS_PENDING) HeapFree( GetProcessHeap(), 0, wsa );
2959             WSASetLastError( NtStatusToWSAError( err ));
2960             return SOCKET_ERROR;
2961         }
2962
2963         iosb->u.Status = STATUS_SUCCESS;
2964         iosb->Information = n;
2965         *lpNumberOfBytesSent = n;
2966         if (!wsa->completion_func)
2967         {
2968             if (cvalue) WS_AddCompletion( s, cvalue, STATUS_SUCCESS, n );
2969             if (lpOverlapped->hEvent) SetEvent( lpOverlapped->hEvent );
2970             HeapFree( GetProcessHeap(), 0, wsa );
2971         }
2972         else NtQueueApcThread( GetCurrentThread(), (PNTAPCFUNC)ws2_async_apc,
2973                                (ULONG_PTR)wsa, (ULONG_PTR)iosb, 0 );
2974         WSASetLastError(0);
2975         return 0;
2976     }
2977
2978     if ( _is_blocking(s) )
2979     {
2980         /* On a blocking non-overlapped stream socket,
2981          * sending blocks until the entire buffer is sent. */
2982         DWORD timeout_start = GetTickCount();
2983
2984         *lpNumberOfBytesSent = 0;
2985
2986         while (wsa->first_iovec < dwBufferCount)
2987         {
2988             struct pollfd pfd;
2989             int timeout = GET_SNDTIMEO(fd);
2990
2991             if (n >= 0)
2992             {
2993                 *lpNumberOfBytesSent += n;
2994                 while (wsa->first_iovec < dwBufferCount && wsa->iovec[wsa->first_iovec].iov_len <= n)
2995                     n -= wsa->iovec[wsa->first_iovec++].iov_len;
2996                 if (wsa->first_iovec >= dwBufferCount) break;
2997                 wsa->iovec[wsa->first_iovec].iov_base = (char*)wsa->iovec[wsa->first_iovec].iov_base + n;
2998                 wsa->iovec[wsa->first_iovec].iov_len -= n;
2999             }
3000
3001             if (timeout != -1)
3002             {
3003                 timeout -= GetTickCount() - timeout_start;
3004                 if (timeout < 0) timeout = 0;
3005             }
3006
3007             pfd.fd = fd;
3008             pfd.events = POLLOUT;
3009
3010             if (!timeout || !poll( &pfd, 1, timeout ))
3011             {
3012                 err = WSAETIMEDOUT;
3013                 goto error; /* msdn says a timeout in send is fatal */
3014             }
3015
3016             n = WS2_send( fd, wsa );
3017             if (n == -1 && errno != EAGAIN && errno != EINTR)
3018             {
3019                 err = wsaErrno();
3020                 goto error;
3021             }
3022         }
3023     }
3024     else  /* non-blocking */
3025     {
3026         if (n < totalLength)
3027             _enable_event(SOCKET2HANDLE(s), FD_WRITE, 0, 0);
3028         if (n == -1)
3029         {
3030             err = WSAEWOULDBLOCK;
3031             goto error;
3032         }
3033         *lpNumberOfBytesSent = n;
3034     }
3035
3036     TRACE(" -> %i bytes\n", *lpNumberOfBytesSent);
3037
3038     HeapFree( GetProcessHeap(), 0, wsa );
3039     release_sock_fd( s, fd );
3040     WSASetLastError(0);
3041     return 0;
3042
3043 error:
3044     HeapFree( GetProcessHeap(), 0, wsa );
3045     release_sock_fd( s, fd );
3046     WARN(" -> ERROR %d\n", err);
3047     WSASetLastError(err);
3048     return SOCKET_ERROR;
3049 }
3050
3051 /***********************************************************************
3052  *              sendto          (WS2_32.20)
3053  */
3054 int WINAPI WS_sendto(SOCKET s, const char *buf, int len, int flags,
3055                               const struct WS_sockaddr *to, int tolen)
3056 {
3057     DWORD n;
3058     WSABUF wsabuf;
3059
3060     wsabuf.len = len;
3061     wsabuf.buf = (char*) buf;
3062
3063     if ( WSASendTo(s, &wsabuf, 1, &n, flags, to, tolen, NULL, NULL) == SOCKET_ERROR )
3064         return SOCKET_ERROR;
3065     else
3066         return n;
3067 }
3068
3069 /***********************************************************************
3070  *              setsockopt              (WS2_32.21)
3071  */
3072 int WINAPI WS_setsockopt(SOCKET s, int level, int optname,
3073                                   const char *optval, int optlen)
3074 {
3075     int fd;
3076     int woptval;
3077     struct linger linger;
3078     struct timeval tval;
3079
3080     TRACE("socket: %04lx, level 0x%x, name 0x%x, ptr %p, len %d\n",
3081           s, level, optname, optval, optlen);
3082
3083     /* some broken apps pass the value directly instead of a pointer to it */
3084     if(IS_INTRESOURCE(optval))
3085     {
3086         SetLastError(WSAEFAULT);
3087         return SOCKET_ERROR;
3088     }
3089
3090     switch(level)
3091     {
3092     case WS_SOL_SOCKET:
3093         switch(optname)
3094         {
3095         /* Some options need some conversion before they can be sent to
3096          * setsockopt. The conversions are done here, then they will fall though
3097          * to the general case. Special options that are not passed to
3098          * setsockopt follow below that.*/
3099
3100         case WS_SO_DONTLINGER:
3101             linger.l_onoff  = *((const int*)optval) ? 0: 1;
3102             linger.l_linger = 0;
3103             level = SOL_SOCKET;
3104             optname = SO_LINGER;
3105             optval = (char*)&linger;
3106             optlen = sizeof(struct linger);
3107             break;
3108
3109         case WS_SO_LINGER:
3110             linger.l_onoff  = ((LINGER*)optval)->l_onoff;
3111             linger.l_linger  = ((LINGER*)optval)->l_linger;
3112             /* FIXME: what is documented behavior if SO_LINGER optval
3113                is null?? */
3114             level = SOL_SOCKET;
3115             optname = SO_LINGER;
3116             optval = (char*)&linger;
3117             optlen = sizeof(struct linger);
3118             break;
3119
3120         case WS_SO_RCVBUF:
3121             if (*(const int*)optval < 2048)
3122             {
3123                 WARN("SO_RCVBF for %d bytes is too small: ignored\n", *(const int*)optval );
3124                 return 0;
3125             }
3126             /* Fall through */
3127
3128         /* The options listed here don't need any special handling. Thanks to
3129          * the conversion happening above, options from there will fall through
3130          * to this, too.*/
3131         case WS_SO_ACCEPTCONN:
3132         case WS_SO_BROADCAST:
3133         case WS_SO_ERROR:
3134         case WS_SO_KEEPALIVE:
3135         case WS_SO_OOBINLINE:
3136         /* BSD socket SO_REUSEADDR is not 100% compatible to winsock semantics.
3137          * however, using it the BSD way fixes bug 8513 and seems to be what
3138          * most programmers assume, anyway */
3139         case WS_SO_REUSEADDR:
3140         case WS_SO_SNDBUF:
3141         case WS_SO_TYPE:
3142             convert_sockopt(&level, &optname);
3143             break;
3144
3145         /* SO_DEBUG is a privileged operation, ignore it. */
3146         case WS_SO_DEBUG:
3147             TRACE("Ignoring SO_DEBUG\n");
3148             return 0;
3149
3150         /* For some reason the game GrandPrixLegends does set SO_DONTROUTE on its
3151          * socket. According to MSDN, this option is silently ignored.*/
3152         case WS_SO_DONTROUTE:
3153             TRACE("Ignoring SO_DONTROUTE\n");
3154             return 0;
3155
3156         /* Stops two sockets from being bound to the same port. Always happens
3157          * on unix systems, so just drop it. */
3158         case WS_SO_EXCLUSIVEADDRUSE:
3159             TRACE("Ignoring SO_EXCLUSIVEADDRUSE, is always set.\n");
3160             return 0;
3161
3162         /* SO_OPENTYPE does not require a valid socket handle. */
3163         case WS_SO_OPENTYPE:
3164             if (!optlen || optlen < sizeof(int) || !optval)
3165             {
3166                 SetLastError(WSAEFAULT);
3167                 return SOCKET_ERROR;
3168             }
3169             get_per_thread_data()->opentype = *(const int *)optval;
3170             TRACE("setting global SO_OPENTYPE = 0x%x\n", *((int*)optval) );
3171             return 0;
3172
3173 #ifdef SO_RCVTIMEO
3174         case WS_SO_RCVTIMEO:
3175 #endif
3176 #ifdef SO_SNDTIMEO
3177         case WS_SO_SNDTIMEO:
3178 #endif
3179 #if defined(SO_RCVTIMEO) || defined(SO_SNDTIMEO)
3180             if (optval && optlen == sizeof(UINT32)) {
3181                 /* WinSock passes milliseconds instead of struct timeval */
3182                 tval.tv_usec = (*(const UINT32*)optval % 1000) * 1000;
3183                 tval.tv_sec = *(const UINT32*)optval / 1000;
3184                 /* min of 500 milliseconds */
3185                 if (tval.tv_sec == 0 && tval.tv_usec < 500000)
3186                     tval.tv_usec = 500000;
3187                 optlen = sizeof(struct timeval);
3188                 optval = (char*)&tval;
3189             } else if (optlen == sizeof(struct timeval)) {
3190                 WARN("SO_SND/RCVTIMEO for %d bytes: assuming unixism\n", optlen);
3191             } else {
3192                 WARN("SO_SND/RCVTIMEO for %d bytes is weird: ignored\n", optlen);
3193                 return 0;
3194             }
3195             convert_sockopt(&level, &optname);
3196             break;
3197 #endif
3198
3199         default:
3200             TRACE("Unknown SOL_SOCKET optname: 0x%08x\n", optname);
3201             SetLastError(WSAENOPROTOOPT);
3202             return SOCKET_ERROR;
3203         }
3204         break; /* case WS_SOL_SOCKET */
3205
3206 #ifdef HAVE_IPX
3207     case NSPROTO_IPX:
3208         switch(optname)
3209         {
3210         case IPX_PTYPE:
3211             fd = get_sock_fd( s, 0, NULL );
3212             TRACE("trying to set IPX_PTYPE: %d (fd: %d)\n", *(const int*)optval, fd);
3213
3214             /* We try to set the ipx type on ipx socket level. */
3215 #ifdef SOL_IPX
3216             if(setsockopt(fd, SOL_IPX, IPX_TYPE, optval, optlen) == -1)
3217             {
3218                 ERR("IPX: could not set ipx option type; expect weird behaviour\n");
3219                 release_sock_fd( s, fd );
3220                 return SOCKET_ERROR;
3221             }
3222 #else
3223             {
3224                 struct ipx val;
3225                 /* Should we retrieve val using a getsockopt call and then
3226                  * set the modified one? */
3227                 val.ipx_pt = *optval;
3228                 setsockopt(fd, 0, SO_DEFAULT_HEADERS, &val, sizeof(struct ipx));
3229             }
3230 #endif
3231             release_sock_fd( s, fd );
3232             return 0;
3233
3234         case IPX_FILTERPTYPE:
3235             /* Sets the receive filter packet type, at the moment we don't support it */
3236             FIXME("IPX_FILTERPTYPE: %x\n", *optval);
3237             /* Returning 0 is better for now than returning a SOCKET_ERROR */
3238             return 0;
3239
3240         default:
3241             FIXME("opt_name:%x\n", optname);
3242             return SOCKET_ERROR;
3243         }
3244         break; /* case NSPROTO_IPX */
3245 #endif
3246
3247     /* Levels WS_IPPROTO_TCP and WS_IPPROTO_IP convert directly */
3248     case WS_IPPROTO_TCP:
3249         switch(optname)
3250         {
3251         case WS_TCP_NODELAY:
3252             convert_sockopt(&level, &optname);
3253             break;
3254         default:
3255             FIXME("Unknown IPPROTO_TCP optname 0x%08x\n", optname);
3256             return SOCKET_ERROR;
3257         }
3258         break;
3259
3260     case WS_IPPROTO_IP:
3261         switch(optname)
3262         {
3263         case WS_IP_ADD_MEMBERSHIP:
3264         case WS_IP_DROP_MEMBERSHIP:
3265 #ifdef IP_HDRINCL
3266         case WS_IP_HDRINCL:
3267 #endif
3268         case WS_IP_MULTICAST_IF:
3269         case WS_IP_MULTICAST_LOOP:
3270         case WS_IP_MULTICAST_TTL:
3271         case WS_IP_OPTIONS:
3272         case WS_IP_TOS:
3273         case WS_IP_TTL:
3274             convert_sockopt(&level, &optname);
3275             break;
3276         case WS_IP_DONTFRAGMENT:
3277             FIXME("IP_DONTFRAGMENT is silently ignored!\n");
3278             return 0;
3279         default:
3280             FIXME("Unknown IPPROTO_IP optname 0x%08x\n", optname);
3281             return SOCKET_ERROR;
3282         }
3283         break;
3284
3285     default:
3286         WARN("Unknown level: 0x%08x\n", level);
3287         SetLastError(WSAEINVAL);
3288         return SOCKET_ERROR;
3289     } /* end switch(level) */
3290
3291     /* avoid endianness issues if argument is a 16-bit int */
3292     if (optval && optlen < sizeof(int))
3293     {
3294         woptval= *((const INT16 *) optval);
3295         optval= (char*) &woptval;
3296         optlen=sizeof(int);
3297     }
3298     fd = get_sock_fd( s, 0, NULL );
3299     if (fd == -1) return SOCKET_ERROR;
3300
3301     if (setsockopt(fd, level, optname, optval, optlen) == 0)
3302     {
3303         release_sock_fd( s, fd );
3304         return 0;
3305     }
3306     TRACE("Setting socket error, %d\n", wsaErrno());
3307     SetLastError(wsaErrno());
3308     release_sock_fd( s, fd );
3309
3310     return SOCKET_ERROR;
3311 }
3312
3313 /***********************************************************************
3314  *              shutdown                (WS2_32.22)
3315  */
3316 int WINAPI WS_shutdown(SOCKET s, int how)
3317 {
3318     int fd, err = WSAENOTSOCK;
3319     unsigned int options, clear_flags = 0;
3320
3321     fd = get_sock_fd( s, 0, &options );
3322     TRACE("socket %04lx, how %i %x\n", s, how, options );
3323
3324     if (fd == -1)
3325         return SOCKET_ERROR;
3326
3327     switch( how )
3328     {
3329     case 0: /* drop receives */
3330         clear_flags |= FD_READ;
3331         break;
3332     case 1: /* drop sends */
3333         clear_flags |= FD_WRITE;
3334         break;
3335     case 2: /* drop all */
3336         clear_flags |= FD_READ|FD_WRITE;
3337     default:
3338         clear_flags |= FD_WINE_LISTENING;
3339     }
3340
3341     if (!(options & (FILE_SYNCHRONOUS_IO_ALERT | FILE_SYNCHRONOUS_IO_NONALERT)))
3342     {
3343         switch ( how )
3344         {
3345         case SD_RECEIVE:
3346             err = WS2_register_async_shutdown( s, ASYNC_TYPE_READ );
3347             break;
3348         case SD_SEND:
3349             err = WS2_register_async_shutdown( s, ASYNC_TYPE_WRITE );
3350             break;
3351         case SD_BOTH:
3352         default:
3353             err = WS2_register_async_shutdown( s, ASYNC_TYPE_READ );
3354             if (!err) err = WS2_register_async_shutdown( s, ASYNC_TYPE_WRITE );
3355             break;
3356         }
3357         if (err) goto error;
3358     }
3359     else /* non-overlapped mode */
3360     {
3361         if ( shutdown( fd, how ) )
3362         {
3363             err = wsaErrno();
3364             goto error;
3365         }
3366     }
3367
3368     release_sock_fd( s, fd );
3369     _enable_event( SOCKET2HANDLE(s), 0, 0, clear_flags );
3370     if ( how > 1) WSAAsyncSelect( s, 0, 0, 0 );
3371     return 0;
3372
3373 error:
3374     release_sock_fd( s, fd );
3375     _enable_event( SOCKET2HANDLE(s), 0, 0, clear_flags );
3376     WSASetLastError( err );
3377     return SOCKET_ERROR;
3378 }
3379
3380 /***********************************************************************
3381  *              socket          (WS2_32.23)
3382  */
3383 SOCKET WINAPI WS_socket(int af, int type, int protocol)
3384 {
3385     TRACE("af=%d type=%d protocol=%d\n", af, type, protocol);
3386
3387     return WSASocketA( af, type, protocol, NULL, 0,
3388                        get_per_thread_data()->opentype ? 0 : WSA_FLAG_OVERLAPPED );
3389 }
3390
3391
3392 /***********************************************************************
3393  *              gethostbyaddr           (WS2_32.51)
3394  */
3395 struct WS_hostent* WINAPI WS_gethostbyaddr(const char *addr, int len, int type)
3396 {
3397     struct WS_hostent *retval = NULL;
3398     struct hostent* host;
3399
3400 #ifdef HAVE_LINUX_GETHOSTBYNAME_R_6
3401     char *extrabuf;
3402     int ebufsize=1024;
3403     struct hostent hostentry;
3404     int locerr=ENOBUFS;
3405     host = NULL;
3406     extrabuf=HeapAlloc(GetProcessHeap(),0,ebufsize) ;
3407     while(extrabuf) {
3408         int res = gethostbyaddr_r(addr, len, type,
3409                                   &hostentry, extrabuf, ebufsize, &host, &locerr);
3410         if( res != ERANGE) break;
3411         ebufsize *=2;
3412         extrabuf=HeapReAlloc(GetProcessHeap(),0,extrabuf,ebufsize) ;
3413     }
3414     if (!host) SetLastError((locerr < 0) ? wsaErrno() : wsaHerrno(locerr));
3415 #else
3416     EnterCriticalSection( &csWSgetXXXbyYYY );
3417     host = gethostbyaddr(addr, len, type);
3418     if (!host) SetLastError((h_errno < 0) ? wsaErrno() : wsaHerrno(h_errno));
3419 #endif
3420     if( host != NULL ) retval = WS_dup_he(host);
3421 #ifdef  HAVE_LINUX_GETHOSTBYNAME_R_6
3422     HeapFree(GetProcessHeap(),0,extrabuf);
3423 #else
3424     LeaveCriticalSection( &csWSgetXXXbyYYY );
3425 #endif
3426     TRACE("ptr %p, len %d, type %d ret %p\n", addr, len, type, retval);
3427     return retval;
3428 }
3429
3430 /***********************************************************************
3431  *              gethostbyname           (WS2_32.52)
3432  */
3433 struct WS_hostent* WINAPI WS_gethostbyname(const char* name)
3434 {
3435     struct WS_hostent *retval = NULL;
3436     struct hostent*     host;
3437 #ifdef  HAVE_LINUX_GETHOSTBYNAME_R_6
3438     char *extrabuf;
3439     int ebufsize=1024;
3440     struct hostent hostentry;
3441     int locerr = ENOBUFS;
3442 #endif
3443     char buf[100];
3444     if( !name || !name[0]) {
3445         name = buf;
3446         if( gethostname( buf, 100) == -1) {
3447             SetLastError( WSAENOBUFS); /* appropriate ? */
3448             return retval;
3449         }
3450     }
3451 #ifdef  HAVE_LINUX_GETHOSTBYNAME_R_6
3452     host = NULL;
3453     extrabuf=HeapAlloc(GetProcessHeap(),0,ebufsize) ;
3454     while(extrabuf) {
3455         int res = gethostbyname_r(name, &hostentry, extrabuf, ebufsize, &host, &locerr);
3456         if( res != ERANGE) break;
3457         ebufsize *=2;
3458         extrabuf=HeapReAlloc(GetProcessHeap(),0,extrabuf,ebufsize) ;
3459     }
3460     if (!host) SetLastError((locerr < 0) ? wsaErrno() : wsaHerrno(locerr));
3461 #else
3462     EnterCriticalSection( &csWSgetXXXbyYYY );
3463     host = gethostbyname(name);
3464     if (!host) SetLastError((h_errno < 0) ? wsaErrno() : wsaHerrno(h_errno));
3465 #endif
3466     if (host) retval = WS_dup_he(host);
3467 #ifdef  HAVE_LINUX_GETHOSTBYNAME_R_6
3468     HeapFree(GetProcessHeap(),0,extrabuf);
3469 #else
3470     LeaveCriticalSection( &csWSgetXXXbyYYY );
3471 #endif
3472     if (retval && retval->h_addr_list[0][0] == 127 &&
3473         strcmp(name, "localhost") != 0)
3474     {
3475         /* hostname != "localhost" but has loopback address. replace by our
3476          * special address.*/
3477         memcpy(retval->h_addr_list[0], magic_loopback_addr, 4);
3478     }
3479     TRACE( "%s ret %p\n", debugstr_a(name), retval );
3480     return retval;
3481 }
3482
3483
3484 /***********************************************************************
3485  *              getprotobyname          (WS2_32.53)
3486  */
3487 struct WS_protoent* WINAPI WS_getprotobyname(const char* name)
3488 {
3489     struct WS_protoent* retval = NULL;
3490 #ifdef HAVE_GETPROTOBYNAME
3491     struct protoent*     proto;
3492     EnterCriticalSection( &csWSgetXXXbyYYY );
3493     if( (proto = getprotobyname(name)) != NULL )
3494     {
3495         retval = WS_dup_pe(proto);
3496     }
3497     else {
3498         MESSAGE("protocol %s not found; You might want to add "
3499                 "this to /etc/protocols\n", debugstr_a(name) );
3500         SetLastError(WSANO_DATA);
3501     }
3502     LeaveCriticalSection( &csWSgetXXXbyYYY );
3503 #endif
3504     TRACE( "%s ret %p\n", debugstr_a(name), retval );
3505     return retval;
3506 }
3507
3508
3509 /***********************************************************************
3510  *              getprotobynumber        (WS2_32.54)
3511  */
3512 struct WS_protoent* WINAPI WS_getprotobynumber(int number)
3513 {
3514     struct WS_protoent* retval = NULL;
3515 #ifdef HAVE_GETPROTOBYNUMBER
3516     struct protoent*     proto;
3517     EnterCriticalSection( &csWSgetXXXbyYYY );
3518     if( (proto = getprotobynumber(number)) != NULL )
3519     {
3520         retval = WS_dup_pe(proto);
3521     }
3522     else {
3523         MESSAGE("protocol number %d not found; You might want to add "
3524                 "this to /etc/protocols\n", number );
3525         SetLastError(WSANO_DATA);
3526     }
3527     LeaveCriticalSection( &csWSgetXXXbyYYY );
3528 #endif
3529     TRACE("%i ret %p\n", number, retval);
3530     return retval;
3531 }
3532
3533
3534 /***********************************************************************
3535  *              getservbyname           (WS2_32.55)
3536  */
3537 struct WS_servent* WINAPI WS_getservbyname(const char *name, const char *proto)
3538 {
3539     struct WS_servent* retval = NULL;
3540     struct servent*     serv;
3541     char *name_str;
3542     char *proto_str = NULL;
3543
3544     if (!(name_str = strdup_lower(name))) return NULL;
3545
3546     if (proto && *proto)
3547     {
3548         if (!(proto_str = strdup_lower(proto)))
3549         {
3550             HeapFree( GetProcessHeap(), 0, name_str );
3551             return NULL;
3552         }
3553     }
3554
3555     EnterCriticalSection( &csWSgetXXXbyYYY );
3556     serv = getservbyname(name_str, proto_str);
3557     if( serv != NULL )
3558     {
3559         retval = WS_dup_se(serv);
3560     }
3561     else SetLastError(WSANO_DATA);
3562     LeaveCriticalSection( &csWSgetXXXbyYYY );
3563     HeapFree( GetProcessHeap(), 0, proto_str );
3564     HeapFree( GetProcessHeap(), 0, name_str );
3565     TRACE( "%s, %s ret %p\n", debugstr_a(name), debugstr_a(proto), retval );
3566     return retval;
3567 }
3568
3569 /***********************************************************************
3570  *              freeaddrinfo            (WS2_32.@)
3571  */
3572 void WINAPI WS_freeaddrinfo(struct WS_addrinfo *res)
3573 {
3574     while (res) {
3575         struct WS_addrinfo *next;
3576
3577         HeapFree(GetProcessHeap(),0,res->ai_canonname);
3578         HeapFree(GetProcessHeap(),0,res->ai_addr);
3579         next = res->ai_next;
3580         HeapFree(GetProcessHeap(),0,res);
3581         res = next;
3582     }
3583 }
3584
3585 /* helper functions for getaddrinfo()/getnameinfo() */
3586 static int convert_aiflag_w2u(int winflags) {
3587     unsigned int i;
3588     int unixflags = 0;
3589
3590     for (i=0;i<sizeof(ws_aiflag_map)/sizeof(ws_aiflag_map[0]);i++)
3591         if (ws_aiflag_map[i][0] & winflags) {
3592             unixflags |= ws_aiflag_map[i][1];
3593             winflags &= ~ws_aiflag_map[i][0];
3594         }
3595     if (winflags)
3596         FIXME("Unhandled windows AI_xxx flags %x\n", winflags);
3597     return unixflags;
3598 }
3599
3600 static int convert_niflag_w2u(int winflags) {
3601     unsigned int i;
3602     int unixflags = 0;
3603
3604     for (i=0;i<sizeof(ws_niflag_map)/sizeof(ws_niflag_map[0]);i++)
3605         if (ws_niflag_map[i][0] & winflags) {
3606             unixflags |= ws_niflag_map[i][1];
3607             winflags &= ~ws_niflag_map[i][0];
3608         }
3609     if (winflags)
3610         FIXME("Unhandled windows NI_xxx flags %x\n", winflags);
3611     return unixflags;
3612 }
3613
3614 static int convert_aiflag_u2w(int unixflags) {
3615     unsigned int i;
3616     int winflags = 0;
3617
3618     for (i=0;i<sizeof(ws_aiflag_map)/sizeof(ws_aiflag_map[0]);i++)
3619         if (ws_aiflag_map[i][1] & unixflags) {
3620             winflags |= ws_aiflag_map[i][0];
3621             unixflags &= ~ws_aiflag_map[i][1];
3622         }
3623     if (unixflags) /* will warn usually */
3624         WARN("Unhandled UNIX AI_xxx flags %x\n", unixflags);
3625     return winflags;
3626 }
3627
3628 static int convert_eai_u2w(int unixret) {
3629     int i;
3630
3631     for (i=0;ws_eai_map[i][0];i++)
3632         if (ws_eai_map[i][1] == unixret)
3633             return ws_eai_map[i][0];
3634     return unixret;
3635 }
3636
3637 /***********************************************************************
3638  *              getaddrinfo             (WS2_32.@)
3639  */
3640 int WINAPI WS_getaddrinfo(LPCSTR nodename, LPCSTR servname, const struct WS_addrinfo *hints, struct WS_addrinfo **res)
3641 {
3642 #ifdef HAVE_GETADDRINFO
3643     struct addrinfo *unixaires = NULL;
3644     int   result;
3645     struct addrinfo unixhints, *punixhints = NULL;
3646     CHAR *node = NULL, *serv = NULL;
3647
3648     if (nodename)
3649         if (!(node = strdup_lower(nodename))) return WSA_NOT_ENOUGH_MEMORY;
3650
3651     if (servname) {
3652         if (!(serv = strdup_lower(servname))) {
3653             HeapFree(GetProcessHeap(), 0, node);
3654             return WSA_NOT_ENOUGH_MEMORY;
3655         }
3656     }
3657
3658     if (hints) {
3659         punixhints = &unixhints;
3660
3661         memset(&unixhints, 0, sizeof(unixhints));
3662         punixhints->ai_flags    = convert_aiflag_w2u(hints->ai_flags);
3663         if (hints->ai_family == 0) /* wildcard, specific to getaddrinfo() */
3664             punixhints->ai_family = 0;
3665         else
3666             punixhints->ai_family = convert_af_w2u(hints->ai_family);
3667         if (hints->ai_socktype == 0) /* wildcard, specific to getaddrinfo() */
3668             punixhints->ai_socktype = 0;
3669         else
3670             punixhints->ai_socktype = convert_socktype_w2u(hints->ai_socktype);
3671         if (hints->ai_protocol == 0) /* wildcard, specific to getaddrinfo() */
3672             punixhints->ai_protocol = 0;
3673         else
3674             punixhints->ai_protocol = convert_proto_w2u(hints->ai_protocol);
3675     }
3676
3677     /* getaddrinfo(3) is thread safe, no need to wrap in CS */
3678     result = getaddrinfo(nodename, servname, punixhints, &unixaires);
3679
3680     TRACE("%s, %s %p -> %p %d\n", debugstr_a(nodename), debugstr_a(servname), hints, res, result);
3681
3682     HeapFree(GetProcessHeap(), 0, node);
3683     HeapFree(GetProcessHeap(), 0, serv);
3684
3685     if (!result) {
3686         struct addrinfo *xuai = unixaires;
3687         struct WS_addrinfo **xai = res;
3688
3689         *xai = NULL;
3690         while (xuai) {
3691             struct WS_addrinfo *ai = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, sizeof(struct WS_addrinfo));
3692             int len;
3693
3694             if (!ai)
3695                 goto outofmem;
3696
3697             *xai = ai;xai = &ai->ai_next;
3698             ai->ai_flags    = convert_aiflag_u2w(xuai->ai_flags);
3699             ai->ai_family   = convert_af_u2w(xuai->ai_family);
3700             ai->ai_socktype = convert_socktype_u2w(xuai->ai_socktype);
3701             ai->ai_protocol = convert_proto_u2w(xuai->ai_protocol);
3702             if (xuai->ai_canonname) {
3703                 TRACE("canon name - %s\n",debugstr_a(xuai->ai_canonname));
3704                 ai->ai_canonname = HeapAlloc(GetProcessHeap(),0,strlen(xuai->ai_canonname)+1);
3705                 if (!ai->ai_canonname)
3706                     goto outofmem;
3707                 strcpy(ai->ai_canonname,xuai->ai_canonname);
3708             }
3709             len = xuai->ai_addrlen;
3710             ai->ai_addr = HeapAlloc(GetProcessHeap(),0,len);
3711             if (!ai->ai_addr)
3712                 goto outofmem;
3713             ai->ai_addrlen = len;
3714             do {
3715                 int winlen = ai->ai_addrlen;
3716
3717                 if (!ws_sockaddr_u2ws(xuai->ai_addr, ai->ai_addr, &winlen)) {
3718                     ai->ai_addrlen = winlen;
3719                     break;
3720                 }
3721                 len = 2*len;
3722                 ai->ai_addr = HeapReAlloc(GetProcessHeap(),0,ai->ai_addr,len);
3723                 if (!ai->ai_addr)
3724                     goto outofmem;
3725                 ai->ai_addrlen = len;
3726             } while (1);
3727             xuai = xuai->ai_next;
3728         }
3729         freeaddrinfo(unixaires);
3730     } else {
3731         result = convert_eai_u2w(result);
3732         *res = NULL;
3733     }
3734     return result;
3735
3736 outofmem:
3737     if (*res) WS_freeaddrinfo(*res);
3738     if (unixaires) freeaddrinfo(unixaires);
3739     *res = NULL;
3740     return WSA_NOT_ENOUGH_MEMORY;
3741 #else
3742     FIXME("getaddrinfo() failed, not found during buildtime.\n");
3743     return EAI_FAIL;
3744 #endif
3745 }
3746
3747 static struct WS_addrinfoW *addrinfo_AtoW(const struct WS_addrinfo *ai)
3748 {
3749     struct WS_addrinfoW *ret;
3750
3751     if (!(ret = HeapAlloc(GetProcessHeap(), 0, sizeof(struct WS_addrinfoW)))) return NULL;
3752     ret->ai_flags     = ai->ai_flags;
3753     ret->ai_family    = ai->ai_family;
3754     ret->ai_socktype  = ai->ai_socktype;
3755     ret->ai_protocol  = ai->ai_protocol;
3756     ret->ai_addrlen   = ai->ai_addrlen;
3757     ret->ai_canonname = NULL;
3758     ret->ai_addr      = NULL;
3759     ret->ai_next      = NULL;
3760     if (ai->ai_canonname)
3761     {
3762         int len = MultiByteToWideChar(CP_ACP, 0, ai->ai_canonname, -1, NULL, 0);
3763         if (!(ret->ai_canonname = HeapAlloc(GetProcessHeap(), 0, len)))
3764         {
3765             HeapFree(GetProcessHeap(), 0, ret);
3766             return NULL;
3767         }
3768         MultiByteToWideChar(CP_ACP, 0, ai->ai_canonname, -1, ret->ai_canonname, len);
3769     }
3770     if (ai->ai_addr)
3771     {
3772         if (!(ret->ai_addr = HeapAlloc(GetProcessHeap(), 0, sizeof(struct WS_sockaddr))))
3773         {
3774             HeapFree(GetProcessHeap(), 0, ret->ai_canonname);
3775             HeapFree(GetProcessHeap(), 0, ret);
3776             return NULL;
3777         }
3778         memcpy(ret->ai_addr, ai->ai_addr, sizeof(struct WS_sockaddr));
3779     }
3780     return ret;
3781 }
3782
3783 static struct WS_addrinfoW *addrinfo_list_AtoW(const struct WS_addrinfo *info)
3784 {
3785     struct WS_addrinfoW *ret, *infoW;
3786
3787     if (!(ret = infoW = addrinfo_AtoW(info))) return NULL;
3788     while (info->ai_next)
3789     {
3790         if (!(infoW->ai_next = addrinfo_AtoW(info->ai_next)))
3791         {
3792             FreeAddrInfoW(ret);
3793             return NULL;
3794         }
3795         infoW = infoW->ai_next;
3796         info = info->ai_next;
3797     }
3798     return ret;
3799 }
3800
3801 static struct WS_addrinfo *addrinfo_WtoA(const struct WS_addrinfoW *ai)
3802 {
3803     struct WS_addrinfo *ret;
3804
3805     if (!(ret = HeapAlloc(GetProcessHeap(), 0, sizeof(struct WS_addrinfo)))) return NULL;
3806     ret->ai_flags     = ai->ai_flags;
3807     ret->ai_family    = ai->ai_family;
3808     ret->ai_socktype  = ai->ai_socktype;
3809     ret->ai_protocol  = ai->ai_protocol;
3810     ret->ai_addrlen   = ai->ai_addrlen;
3811     ret->ai_canonname = NULL;
3812     ret->ai_addr      = NULL;
3813     ret->ai_next      = NULL;
3814     if (ai->ai_canonname)
3815     {
3816         int len = WideCharToMultiByte(CP_ACP, 0, ai->ai_canonname, -1, NULL, 0, NULL, NULL);
3817         if (!(ret->ai_canonname = HeapAlloc(GetProcessHeap(), 0, len)))
3818         {
3819             HeapFree(GetProcessHeap(), 0, ret);
3820             return NULL;
3821         }
3822         WideCharToMultiByte(CP_ACP, 0, ai->ai_canonname, -1, ret->ai_canonname, len, NULL, NULL);
3823     }
3824     if (ai->ai_addr)
3825     {
3826         if (!(ret->ai_addr = HeapAlloc(GetProcessHeap(), 0, sizeof(struct WS_sockaddr))))
3827         {
3828             HeapFree(GetProcessHeap(), 0, ret->ai_canonname);
3829             HeapFree(GetProcessHeap(), 0, ret);
3830             return NULL;
3831         }
3832         memcpy(ret->ai_addr, ai->ai_addr, sizeof(struct WS_sockaddr));
3833     }
3834     return ret;
3835 }
3836
3837 /***********************************************************************
3838  *              GetAddrInfoW            (WS2_32.@)
3839  */
3840 int WINAPI GetAddrInfoW(LPCWSTR nodename, LPCWSTR servname, const ADDRINFOW *hints, PADDRINFOW *res)
3841 {
3842     int ret, len;
3843     char *nodenameA, *servnameA = NULL;
3844     struct WS_addrinfo *resA, *hintsA = NULL;
3845
3846     len = WideCharToMultiByte(CP_ACP, 0, nodename, -1, NULL, 0, NULL, NULL);
3847     if (!(nodenameA = HeapAlloc(GetProcessHeap(), 0, len))) return EAI_MEMORY;
3848     WideCharToMultiByte(CP_ACP, 0, nodename, -1, nodenameA, len, NULL, NULL);
3849
3850     if (servname)
3851     {
3852         len = WideCharToMultiByte(CP_ACP, 0, servname, -1, NULL, 0, NULL, NULL);
3853         if (!(servnameA = HeapAlloc(GetProcessHeap(), 0, len)))
3854         {
3855             HeapFree(GetProcessHeap(), 0, nodenameA);
3856             return EAI_MEMORY;
3857         }
3858         WideCharToMultiByte(CP_ACP, 0, servname, -1, servnameA, len, NULL, NULL);
3859     }
3860
3861     if (hints) hintsA = addrinfo_WtoA(hints);
3862     ret = WS_getaddrinfo(nodenameA, servnameA, hintsA, &resA);
3863     WS_freeaddrinfo(hintsA);
3864
3865     if (!ret)
3866     {
3867         *res = addrinfo_list_AtoW(resA);
3868         WS_freeaddrinfo(resA);
3869     }
3870
3871     HeapFree(GetProcessHeap(), 0, nodenameA);
3872     HeapFree(GetProcessHeap(), 0, servnameA);
3873     return ret;
3874 }
3875
3876 /***********************************************************************
3877  *      FreeAddrInfoW        (WS2_32.@)
3878  */
3879 void WINAPI FreeAddrInfoW(PADDRINFOW ai)
3880 {
3881     while (ai)
3882     {
3883         ADDRINFOW *next;
3884         HeapFree(GetProcessHeap(), 0, ai->ai_canonname);
3885         HeapFree(GetProcessHeap(), 0, ai->ai_addr);
3886         next = ai->ai_next;
3887         HeapFree(GetProcessHeap(), 0, ai);
3888         ai = next;
3889     }
3890 }
3891
3892 int WINAPI WS_getnameinfo(const SOCKADDR *sa, WS_socklen_t salen, PCHAR host,
3893                           DWORD hostlen, PCHAR serv, DWORD servlen, INT flags)
3894 {
3895 #ifdef HAVE_GETNAMEINFO
3896     int ret;
3897     union generic_unix_sockaddr sa_u;
3898     unsigned int size;
3899
3900     TRACE("%s %d %p %d %p %d %d\n", debugstr_sockaddr(sa), salen, host, hostlen,
3901           serv, servlen, flags);
3902
3903     size = ws_sockaddr_ws2u(sa, salen, &sa_u);
3904     if (!size)
3905     {
3906         WSASetLastError(WSAEFAULT);
3907         return WSA_NOT_ENOUGH_MEMORY;
3908     }
3909     ret = getnameinfo(&sa_u.addr, size, host, hostlen, serv, servlen, convert_niflag_w2u(flags));
3910     return convert_eai_u2w(ret);
3911 #else
3912     FIXME("getnameinfo() failed, not found during buildtime.\n");
3913     return EAI_FAIL;
3914 #endif
3915 }
3916
3917 /***********************************************************************
3918  *              getservbyport           (WS2_32.56)
3919  */
3920 struct WS_servent* WINAPI WS_getservbyport(int port, const char *proto)
3921 {
3922     struct WS_servent* retval = NULL;
3923 #ifdef HAVE_GETSERVBYPORT
3924     struct servent*     serv;
3925     char *proto_str = NULL;
3926
3927     if (proto && *proto)
3928     {
3929         if (!(proto_str = strdup_lower(proto))) return NULL;
3930     }
3931     EnterCriticalSection( &csWSgetXXXbyYYY );
3932     if( (serv = getservbyport(port, proto_str)) != NULL ) {
3933         retval = WS_dup_se(serv);
3934     }
3935     else SetLastError(WSANO_DATA);
3936     LeaveCriticalSection( &csWSgetXXXbyYYY );
3937     HeapFree( GetProcessHeap(), 0, proto_str );
3938 #endif
3939     TRACE("%d (i.e. port %d), %s ret %p\n", port, (int)ntohl(port), debugstr_a(proto), retval);
3940     return retval;
3941 }
3942
3943
3944 /***********************************************************************
3945  *              gethostname           (WS2_32.57)
3946  */
3947 int WINAPI WS_gethostname(char *name, int namelen)
3948 {
3949     TRACE("name %p, len %d\n", name, namelen);
3950
3951     if (gethostname(name, namelen) == 0)
3952     {
3953         TRACE("<- '%s'\n", name);
3954         return 0;
3955     }
3956     SetLastError((errno == EINVAL) ? WSAEFAULT : wsaErrno());
3957     TRACE("<- ERROR !\n");
3958     return SOCKET_ERROR;
3959 }
3960
3961
3962 /* ------------------------------------- Windows sockets extensions -- *
3963  *                                                                     *
3964  * ------------------------------------------------------------------- */
3965
3966 /***********************************************************************
3967  *              WSAEnumNetworkEvents (WS2_32.36)
3968  */
3969 int WINAPI WSAEnumNetworkEvents(SOCKET s, WSAEVENT hEvent, LPWSANETWORKEVENTS lpEvent)
3970 {
3971     int ret;
3972
3973     TRACE("%08lx, hEvent %p, lpEvent %p\n", s, hEvent, lpEvent );
3974
3975     SERVER_START_REQ( get_socket_event )
3976     {
3977         req->handle  = wine_server_obj_handle( SOCKET2HANDLE(s) );
3978         req->service = TRUE;
3979         req->c_event = wine_server_obj_handle( hEvent );
3980         wine_server_set_reply( req, lpEvent->iErrorCode, sizeof(lpEvent->iErrorCode) );
3981         if (!(ret = wine_server_call(req))) lpEvent->lNetworkEvents = reply->pmask & reply->mask;
3982     }
3983     SERVER_END_REQ;
3984     if (!ret) return 0;
3985     SetLastError(WSAEINVAL);
3986     return SOCKET_ERROR;
3987 }
3988
3989 /***********************************************************************
3990  *              WSAEventSelect (WS2_32.39)
3991  */
3992 int WINAPI WSAEventSelect(SOCKET s, WSAEVENT hEvent, LONG lEvent)
3993 {
3994     int ret;
3995
3996     TRACE("%08lx, hEvent %p, event %08x\n", s, hEvent, lEvent);
3997
3998     SERVER_START_REQ( set_socket_event )
3999     {
4000         req->handle = wine_server_obj_handle( SOCKET2HANDLE(s) );
4001         req->mask   = lEvent;
4002         req->event  = wine_server_obj_handle( hEvent );
4003         req->window = 0;
4004         req->msg    = 0;
4005         ret = wine_server_call( req );
4006     }
4007     SERVER_END_REQ;
4008     if (!ret) return 0;
4009     SetLastError(WSAEINVAL);
4010     return SOCKET_ERROR;
4011 }
4012
4013 /**********************************************************************
4014  *      WSAGetOverlappedResult (WS2_32.40)
4015  */
4016 BOOL WINAPI WSAGetOverlappedResult( SOCKET s, LPWSAOVERLAPPED lpOverlapped,
4017                                     LPDWORD lpcbTransfer, BOOL fWait,
4018                                     LPDWORD lpdwFlags )
4019 {
4020     NTSTATUS status;
4021
4022     TRACE( "socket %04lx ovl %p trans %p, wait %d flags %p\n",
4023            s, lpOverlapped, lpcbTransfer, fWait, lpdwFlags );
4024
4025     if ( lpOverlapped == NULL )
4026     {
4027         ERR( "Invalid pointer\n" );
4028         WSASetLastError(WSA_INVALID_PARAMETER);
4029         return FALSE;
4030     }
4031
4032     status = lpOverlapped->Internal;
4033     if (status == STATUS_PENDING)
4034     {
4035         if (!fWait)
4036         {
4037             SetLastError( WSA_IO_INCOMPLETE );
4038             return FALSE;
4039         }
4040
4041         if (WaitForSingleObject( lpOverlapped->hEvent ? lpOverlapped->hEvent : SOCKET2HANDLE(s),
4042                                  INFINITE ) == WAIT_FAILED)
4043             return FALSE;
4044         status = lpOverlapped->Internal;
4045     }
4046
4047     if ( lpcbTransfer )
4048         *lpcbTransfer = lpOverlapped->InternalHigh;
4049
4050     if ( lpdwFlags )
4051         *lpdwFlags = lpOverlapped->u.s.Offset;
4052
4053     if (status) SetLastError( RtlNtStatusToDosError(status) );
4054     return !status;
4055 }
4056
4057
4058 /***********************************************************************
4059  *      WSAAsyncSelect                  (WS2_32.101)
4060  */
4061 INT WINAPI WSAAsyncSelect(SOCKET s, HWND hWnd, UINT uMsg, LONG lEvent)
4062 {
4063     int ret;
4064
4065     TRACE("%lx, hWnd %p, uMsg %08x, event %08x\n", s, hWnd, uMsg, lEvent);
4066
4067     SERVER_START_REQ( set_socket_event )
4068     {
4069         req->handle = wine_server_obj_handle( SOCKET2HANDLE(s) );
4070         req->mask   = lEvent;
4071         req->event  = 0;
4072         req->window = wine_server_user_handle( hWnd );
4073         req->msg    = uMsg;
4074         ret = wine_server_call( req );
4075     }
4076     SERVER_END_REQ;
4077     if (!ret) return 0;
4078     SetLastError(WSAEINVAL);
4079     return SOCKET_ERROR;
4080 }
4081
4082 /***********************************************************************
4083  *      WSACreateEvent          (WS2_32.31)
4084  *
4085  */
4086 WSAEVENT WINAPI WSACreateEvent(void)
4087 {
4088     /* Create a manual-reset event, with initial state: unsignaled */
4089     TRACE("\n");
4090
4091     return CreateEventW(NULL, TRUE, FALSE, NULL);
4092 }
4093
4094 /***********************************************************************
4095  *      WSACloseEvent          (WS2_32.29)
4096  *
4097  */
4098 BOOL WINAPI WSACloseEvent(WSAEVENT event)
4099 {
4100     TRACE ("event=%p\n", event);
4101
4102     return CloseHandle(event);
4103 }
4104
4105 /***********************************************************************
4106  *      WSASocketA          (WS2_32.78)
4107  *
4108  */
4109 SOCKET WINAPI WSASocketA(int af, int type, int protocol,
4110                          LPWSAPROTOCOL_INFOA lpProtocolInfo,
4111                          GROUP g, DWORD dwFlags)
4112 {
4113     INT len;
4114     WSAPROTOCOL_INFOW info;
4115
4116     TRACE("af=%d type=%d protocol=%d protocol_info=%p group=%d flags=0x%x\n",
4117           af, type, protocol, lpProtocolInfo, g, dwFlags);
4118
4119     if (!lpProtocolInfo) return WSASocketW(af, type, protocol, NULL, g, dwFlags);
4120
4121     memcpy(&info, lpProtocolInfo, FIELD_OFFSET(WSAPROTOCOL_INFOW, szProtocol));
4122     len = MultiByteToWideChar(CP_ACP, 0, lpProtocolInfo->szProtocol, -1,
4123                               info.szProtocol, WSAPROTOCOL_LEN + 1);
4124
4125     if (!len)
4126     {
4127         WSASetLastError( WSAEINVAL);
4128         return SOCKET_ERROR;
4129     }
4130
4131     return WSASocketW(af, type, protocol, &info, g, dwFlags);
4132 }
4133
4134 /***********************************************************************
4135  *      WSASocketW          (WS2_32.79)
4136  *
4137  */
4138 SOCKET WINAPI WSASocketW(int af, int type, int protocol,
4139                          LPWSAPROTOCOL_INFOW lpProtocolInfo,
4140                          GROUP g, DWORD dwFlags)
4141 {
4142     SOCKET ret;
4143
4144    /*
4145       FIXME: The "advanced" parameters of WSASocketW (lpProtocolInfo,
4146       g, dwFlags except WSA_FLAG_OVERLAPPED) are ignored.
4147    */
4148
4149    TRACE("af=%d type=%d protocol=%d protocol_info=%p group=%d flags=0x%x\n",
4150          af, type, protocol, lpProtocolInfo, g, dwFlags );
4151
4152     /* hack for WSADuplicateSocket */
4153     if (lpProtocolInfo && lpProtocolInfo->dwServiceFlags4 == 0xff00ff00) {
4154       ret = lpProtocolInfo->dwCatalogEntryId;
4155       TRACE("\tgot duplicate %04lx\n", ret);
4156       return ret;
4157     }
4158
4159     /* convert the socket family and type */
4160     af = convert_af_w2u(af);
4161     type = convert_socktype_w2u(type);
4162
4163     if (lpProtocolInfo)
4164     {
4165         if (af == FROM_PROTOCOL_INFO)
4166             af = lpProtocolInfo->iAddressFamily;
4167         if (type == FROM_PROTOCOL_INFO)
4168             type = lpProtocolInfo->iSocketType;
4169         if (protocol == FROM_PROTOCOL_INFO)
4170             protocol = lpProtocolInfo->iProtocol;
4171     }
4172
4173     if ( af == AF_UNSPEC)  /* did they not specify the address family? */
4174         switch(protocol)
4175         {
4176           case IPPROTO_TCP:
4177              if (type == SOCK_STREAM) { af = AF_INET; break; }
4178           case IPPROTO_UDP:
4179              if (type == SOCK_DGRAM)  { af = AF_INET; break; }
4180           default: SetLastError(WSAEPROTOTYPE); return INVALID_SOCKET;
4181         }
4182
4183     SERVER_START_REQ( create_socket )
4184     {
4185         req->family     = af;
4186         req->type       = type;
4187         req->protocol   = protocol;
4188         req->access     = GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE;
4189         req->attributes = OBJ_INHERIT;
4190         req->flags      = dwFlags;
4191         set_error( wine_server_call( req ) );
4192         ret = HANDLE2SOCKET( wine_server_ptr_handle( reply->handle ));
4193     }
4194     SERVER_END_REQ;
4195     if (ret)
4196     {
4197         TRACE("\tcreated %04lx\n", ret );
4198         return ret;
4199     }
4200
4201     if (GetLastError() == WSAEACCES) /* raw socket denied */
4202     {
4203         if (type == SOCK_RAW)
4204             MESSAGE("WARNING: Trying to create a socket of type SOCK_RAW, this"
4205                     " will fail unless you have special permissions.\n");
4206         else
4207             MESSAGE("WS_SOCKET: Failed to create socket, this requires"
4208                     " special permissions.\n");
4209         SetLastError(WSAESOCKTNOSUPPORT);
4210     }
4211
4212     WARN("\t\tfailed!\n");
4213     return INVALID_SOCKET;
4214 }
4215
4216 /***********************************************************************
4217  *      WSAJoinLeaf          (WS2_32.58)
4218  *
4219  */
4220 SOCKET WINAPI WSAJoinLeaf(
4221         SOCKET s,
4222         const struct WS_sockaddr *addr,
4223         int addrlen,
4224         LPWSABUF lpCallerData,
4225         LPWSABUF lpCalleeData,
4226         LPQOS lpSQOS,
4227         LPQOS lpGQOS,
4228         DWORD dwFlags)
4229 {
4230     FIXME("stub.\n");
4231     return INVALID_SOCKET;
4232 }
4233
4234 /***********************************************************************
4235  *      __WSAFDIsSet                    (WS2_32.151)
4236  */
4237 int WINAPI __WSAFDIsSet(SOCKET s, WS_fd_set *set)
4238 {
4239   int i = set->fd_count;
4240
4241   TRACE("(%ld,%p(%i))\n", s, set, i);
4242
4243   while (i--)
4244       if (set->fd_array[i] == s) return 1;
4245   return 0;
4246 }
4247
4248 /***********************************************************************
4249  *      WSAIsBlocking                   (WS2_32.114)
4250  */
4251 BOOL WINAPI WSAIsBlocking(void)
4252 {
4253   /* By default WinSock should set all its sockets to non-blocking mode
4254    * and poll in PeekMessage loop when processing "blocking" ones. This
4255    * function is supposed to tell if the program is in this loop. Our
4256    * blocking calls are truly blocking so we always return FALSE.
4257    *
4258    * Note: It is allowed to call this function without prior WSAStartup().
4259    */
4260
4261   TRACE("\n");
4262   return FALSE;
4263 }
4264
4265 /***********************************************************************
4266  *      WSACancelBlockingCall           (WS2_32.113)
4267  */
4268 INT WINAPI WSACancelBlockingCall(void)
4269 {
4270     TRACE("\n");
4271     return 0;
4272 }
4273
4274 static INT WINAPI WSA_DefaultBlockingHook( FARPROC x )
4275 {
4276     FIXME("How was this called?\n");
4277     return x();
4278 }
4279
4280
4281 /***********************************************************************
4282  *      WSASetBlockingHook (WS2_32.109)
4283  */
4284 FARPROC WINAPI WSASetBlockingHook(FARPROC lpBlockFunc)
4285 {
4286   FARPROC prev = blocking_hook;
4287   blocking_hook = lpBlockFunc;
4288   TRACE("hook %p\n", lpBlockFunc);
4289   return prev;
4290 }
4291
4292
4293 /***********************************************************************
4294  *      WSAUnhookBlockingHook (WS2_32.110)
4295  */
4296 INT WINAPI WSAUnhookBlockingHook(void)
4297 {
4298     blocking_hook = (FARPROC)WSA_DefaultBlockingHook;
4299     return 0;
4300 }
4301
4302
4303 /* ----------------------------------- end of API stuff */
4304
4305 /* ----------------------------------- helper functions -
4306  *
4307  * TODO: Merge WS_dup_..() stuff into one function that
4308  * would operate with a generic structure containing internal
4309  * pointers (via a template of some kind).
4310  */
4311
4312 static int list_size(char** l, int item_size)
4313 {
4314   int i,j = 0;
4315   if(l)
4316   { for(i=0;l[i];i++)
4317         j += (item_size) ? item_size : strlen(l[i]) + 1;
4318     j += (i + 1) * sizeof(char*); }
4319   return j;
4320 }
4321
4322 static int list_dup(char** l_src, char** l_to, int item_size)
4323 {
4324    char *p;
4325    int i;
4326
4327    for (i = 0; l_src[i]; i++) ;
4328    p = (char *)(l_to + i + 1);
4329    for (i = 0; l_src[i]; i++)
4330    {
4331        int count = ( item_size ) ? item_size : strlen(l_src[i]) + 1;
4332        memcpy(p, l_src[i], count);
4333        l_to[i] = p;
4334        p += count;
4335    }
4336    l_to[i] = NULL;
4337    return p - (char *)l_to;
4338 }
4339
4340 /* ----- hostent */
4341
4342 /* duplicate hostent entry
4343  * and handle all Win16/Win32 dependent things (struct size, ...) *correctly*.
4344  * Ditto for protoent and servent.
4345  */
4346 static struct WS_hostent *WS_dup_he(const struct hostent* p_he)
4347 {
4348     char *p;
4349     struct WS_hostent *p_to;
4350
4351     int size = (sizeof(*p_he) +
4352                 strlen(p_he->h_name) + 1 +
4353                 list_size(p_he->h_aliases, 0) +
4354                 list_size(p_he->h_addr_list, p_he->h_length));
4355
4356     if (!(p_to = check_buffer_he(size))) return NULL;
4357     p_to->h_addrtype = p_he->h_addrtype;
4358     p_to->h_length = p_he->h_length;
4359
4360     p = (char *)(p_to + 1);
4361     p_to->h_name = p;
4362     strcpy(p, p_he->h_name);
4363     p += strlen(p) + 1;
4364
4365     p_to->h_aliases = (char **)p;
4366     p += list_dup(p_he->h_aliases, p_to->h_aliases, 0);
4367
4368     p_to->h_addr_list = (char **)p;
4369     list_dup(p_he->h_addr_list, p_to->h_addr_list, p_he->h_length);
4370     return p_to;
4371 }
4372
4373 /* ----- protoent */
4374
4375 static struct WS_protoent *WS_dup_pe(const struct protoent* p_pe)
4376 {
4377     char *p;
4378     struct WS_protoent *p_to;
4379
4380     int size = (sizeof(*p_pe) +
4381                 strlen(p_pe->p_name) + 1 +
4382                 list_size(p_pe->p_aliases, 0));
4383
4384     if (!(p_to = check_buffer_pe(size))) return NULL;
4385     p_to->p_proto = p_pe->p_proto;
4386
4387     p = (char *)(p_to + 1);
4388     p_to->p_name = p;
4389     strcpy(p, p_pe->p_name);
4390     p += strlen(p) + 1;
4391
4392     p_to->p_aliases = (char **)p;
4393     list_dup(p_pe->p_aliases, p_to->p_aliases, 0);
4394     return p_to;
4395 }
4396
4397 /* ----- servent */
4398
4399 static struct WS_servent *WS_dup_se(const struct servent* p_se)
4400 {
4401     char *p;
4402     struct WS_servent *p_to;
4403
4404     int size = (sizeof(*p_se) +
4405                 strlen(p_se->s_proto) + 1 +
4406                 strlen(p_se->s_name) + 1 +
4407                 list_size(p_se->s_aliases, 0));
4408
4409     if (!(p_to = check_buffer_se(size))) return NULL;
4410     p_to->s_port = p_se->s_port;
4411
4412     p = (char *)(p_to + 1);
4413     p_to->s_name = p;
4414     strcpy(p, p_se->s_name);
4415     p += strlen(p) + 1;
4416
4417     p_to->s_proto = p;
4418     strcpy(p, p_se->s_proto);
4419     p += strlen(p) + 1;
4420
4421     p_to->s_aliases = (char **)p;
4422     list_dup(p_se->s_aliases, p_to->s_aliases, 0);
4423     return p_to;
4424 }
4425
4426 /* ----------------------------------- error handling */
4427
4428 UINT wsaErrno(void)
4429 {
4430     int loc_errno = errno;
4431     WARN("errno %d, (%s).\n", loc_errno, strerror(loc_errno));
4432
4433     switch(loc_errno)
4434     {
4435         case EINTR:             return WSAEINTR;
4436         case EBADF:             return WSAEBADF;
4437         case EPERM:
4438         case EACCES:            return WSAEACCES;
4439         case EFAULT:            return WSAEFAULT;
4440         case EINVAL:            return WSAEINVAL;
4441         case EMFILE:            return WSAEMFILE;
4442         case EWOULDBLOCK:       return WSAEWOULDBLOCK;
4443         case EINPROGRESS:       return WSAEINPROGRESS;
4444         case EALREADY:          return WSAEALREADY;
4445         case ENOTSOCK:          return WSAENOTSOCK;
4446         case EDESTADDRREQ:      return WSAEDESTADDRREQ;
4447         case EMSGSIZE:          return WSAEMSGSIZE;
4448         case EPROTOTYPE:        return WSAEPROTOTYPE;
4449         case ENOPROTOOPT:       return WSAENOPROTOOPT;
4450         case EPROTONOSUPPORT:   return WSAEPROTONOSUPPORT;
4451         case ESOCKTNOSUPPORT:   return WSAESOCKTNOSUPPORT;
4452         case EOPNOTSUPP:        return WSAEOPNOTSUPP;
4453         case EPFNOSUPPORT:      return WSAEPFNOSUPPORT;
4454         case EAFNOSUPPORT:      return WSAEAFNOSUPPORT;
4455         case EADDRINUSE:        return WSAEADDRINUSE;
4456         case EADDRNOTAVAIL:     return WSAEADDRNOTAVAIL;
4457         case ENETDOWN:          return WSAENETDOWN;
4458         case ENETUNREACH:       return WSAENETUNREACH;
4459         case ENETRESET:         return WSAENETRESET;
4460         case ECONNABORTED:      return WSAECONNABORTED;
4461         case EPIPE:
4462         case ECONNRESET:        return WSAECONNRESET;
4463         case ENOBUFS:           return WSAENOBUFS;
4464         case EISCONN:           return WSAEISCONN;
4465         case ENOTCONN:          return WSAENOTCONN;
4466         case ESHUTDOWN:         return WSAESHUTDOWN;
4467         case ETOOMANYREFS:      return WSAETOOMANYREFS;
4468         case ETIMEDOUT:         return WSAETIMEDOUT;
4469         case ECONNREFUSED:      return WSAECONNREFUSED;
4470         case ELOOP:             return WSAELOOP;
4471         case ENAMETOOLONG:      return WSAENAMETOOLONG;
4472         case EHOSTDOWN:         return WSAEHOSTDOWN;
4473         case EHOSTUNREACH:      return WSAEHOSTUNREACH;
4474         case ENOTEMPTY:         return WSAENOTEMPTY;
4475 #ifdef EPROCLIM
4476         case EPROCLIM:          return WSAEPROCLIM;
4477 #endif
4478 #ifdef EUSERS
4479         case EUSERS:            return WSAEUSERS;
4480 #endif
4481 #ifdef EDQUOT
4482         case EDQUOT:            return WSAEDQUOT;
4483 #endif
4484 #ifdef ESTALE
4485         case ESTALE:            return WSAESTALE;
4486 #endif
4487 #ifdef EREMOTE
4488         case EREMOTE:           return WSAEREMOTE;
4489 #endif
4490
4491        /* just in case we ever get here and there are no problems */
4492         case 0:                 return 0;
4493         default:
4494                 WARN("Unknown errno %d!\n", loc_errno);
4495                 return WSAEOPNOTSUPP;
4496     }
4497 }
4498
4499 UINT wsaHerrno(int loc_errno)
4500 {
4501
4502     WARN("h_errno %d.\n", loc_errno);
4503
4504     switch(loc_errno)
4505     {
4506         case HOST_NOT_FOUND:    return WSAHOST_NOT_FOUND;
4507         case TRY_AGAIN:         return WSATRY_AGAIN;
4508         case NO_RECOVERY:       return WSANO_RECOVERY;
4509         case NO_DATA:           return WSANO_DATA;
4510         case ENOBUFS:           return WSAENOBUFS;
4511
4512         case 0:                 return 0;
4513         default:
4514                 WARN("Unknown h_errno %d!\n", loc_errno);
4515                 return WSAEOPNOTSUPP;
4516     }
4517 }
4518
4519
4520 /***********************************************************************
4521  *              WSARecv                 (WS2_32.67)
4522  */
4523 int WINAPI WSARecv(SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
4524                    LPDWORD NumberOfBytesReceived, LPDWORD lpFlags,
4525                    LPWSAOVERLAPPED lpOverlapped,
4526                    LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
4527 {
4528     return WSARecvFrom(s, lpBuffers, dwBufferCount, NumberOfBytesReceived, lpFlags,
4529                        NULL, NULL, lpOverlapped, lpCompletionRoutine);
4530 }
4531
4532 /***********************************************************************
4533  *              WSARecvFrom             (WS2_32.69)
4534  */
4535 INT WINAPI WSARecvFrom( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
4536                         LPDWORD lpNumberOfBytesRecvd, LPDWORD lpFlags, struct WS_sockaddr *lpFrom,
4537                         LPINT lpFromlen, LPWSAOVERLAPPED lpOverlapped,
4538                         LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine )
4539
4540 {
4541     unsigned int i, options;
4542     int n, fd, err;
4543     struct ws2_async *wsa;
4544     DWORD timeout_start = GetTickCount();
4545     ULONG_PTR cvalue = (lpOverlapped && ((ULONG_PTR)lpOverlapped->hEvent & 1) == 0) ? (ULONG_PTR)lpOverlapped : 0;
4546
4547     TRACE("socket %04lx, wsabuf %p, nbufs %d, flags %d, from %p, fromlen %d, ovl %p, func %p\n",
4548           s, lpBuffers, dwBufferCount, *lpFlags, lpFrom,
4549           (lpFromlen ? *lpFromlen : -1),
4550           lpOverlapped, lpCompletionRoutine);
4551
4552     fd = get_sock_fd( s, FILE_READ_DATA, &options );
4553     TRACE( "fd=%d, options=%x\n", fd, options );
4554
4555     if (fd == -1) return SOCKET_ERROR;
4556
4557     if (!(wsa = HeapAlloc( GetProcessHeap(), 0, FIELD_OFFSET(struct ws2_async, iovec[dwBufferCount]) )))
4558     {
4559         err = WSAEFAULT;
4560         goto error;
4561     }
4562
4563     wsa->hSocket     = SOCKET2HANDLE(s);
4564     wsa->flags       = *lpFlags;
4565     wsa->addr        = lpFrom;
4566     wsa->addrlen.ptr = lpFromlen;
4567     wsa->n_iovecs    = dwBufferCount;
4568     wsa->first_iovec = 0;
4569     for (i = 0; i < dwBufferCount; i++)
4570     {
4571         /* check buffer first to trigger write watches */
4572         if (IsBadWritePtr( lpBuffers[i].buf, lpBuffers[i].len ))
4573         {
4574             err = WSAEFAULT;
4575             goto error;
4576         }
4577         wsa->iovec[i].iov_base = lpBuffers[i].buf;
4578         wsa->iovec[i].iov_len  = lpBuffers[i].len;
4579     }
4580
4581     for (;;)
4582     {
4583         n = WS2_recv( fd, wsa );
4584         if (n == -1)
4585         {
4586             if (errno == EINTR) continue;
4587             if (errno != EAGAIN)
4588             {
4589                 err = wsaErrno();
4590                 if (cvalue) WS_AddCompletion( s, cvalue, err, 0 );
4591                 goto error;
4592             }
4593         }
4594         else
4595             *lpNumberOfBytesRecvd = n;
4596
4597         if ((lpOverlapped || lpCompletionRoutine) &&
4598              !(options & (FILE_SYNCHRONOUS_IO_ALERT | FILE_SYNCHRONOUS_IO_NONALERT)))
4599         {
4600             IO_STATUS_BLOCK *iosb = lpOverlapped ? (IO_STATUS_BLOCK *)lpOverlapped : &wsa->local_iosb;
4601
4602             wsa->user_overlapped = lpOverlapped;
4603             wsa->completion_func = lpCompletionRoutine;
4604             release_sock_fd( s, fd );
4605
4606             if (n == -1)
4607             {
4608                 iosb->u.Status = STATUS_PENDING;
4609                 iosb->Information = 0;
4610
4611                 SERVER_START_REQ( register_async )
4612                 {
4613                     req->type           = ASYNC_TYPE_READ;
4614                     req->async.handle   = wine_server_obj_handle( wsa->hSocket );
4615                     req->async.callback = wine_server_client_ptr( WS2_async_recv );
4616                     req->async.iosb     = wine_server_client_ptr( iosb );
4617                     req->async.arg      = wine_server_client_ptr( wsa );
4618                     req->async.event    = wine_server_obj_handle( lpCompletionRoutine ? 0 : lpOverlapped->hEvent );
4619                     req->async.cvalue   = cvalue;
4620                     err = wine_server_call( req );
4621                 }
4622                 SERVER_END_REQ;
4623
4624                 if (err != STATUS_PENDING) HeapFree( GetProcessHeap(), 0, wsa );
4625                 WSASetLastError( NtStatusToWSAError( err ));
4626                 return SOCKET_ERROR;
4627             }
4628
4629             iosb->u.Status = STATUS_SUCCESS;
4630             iosb->Information = n;
4631             if (!wsa->completion_func)
4632             {
4633                 if (cvalue) WS_AddCompletion( s, cvalue, STATUS_SUCCESS, n );
4634                 if (lpOverlapped->hEvent) SetEvent( lpOverlapped->hEvent );
4635                 HeapFree( GetProcessHeap(), 0, wsa );
4636             }
4637             else NtQueueApcThread( GetCurrentThread(), (PNTAPCFUNC)ws2_async_apc,
4638                                    (ULONG_PTR)wsa, (ULONG_PTR)iosb, 0 );
4639             _enable_event(SOCKET2HANDLE(s), FD_READ, 0, 0);
4640             return 0;
4641         }
4642
4643         if (n != -1) break;
4644
4645         if ( _is_blocking(s) )
4646         {
4647             struct pollfd pfd;
4648             int timeout = GET_RCVTIMEO(fd);
4649             if (timeout != -1)
4650             {
4651                 timeout -= GetTickCount() - timeout_start;
4652                 if (timeout < 0) timeout = 0;
4653             }
4654
4655             pfd.fd = fd;
4656             pfd.events = POLLIN;
4657             if (*lpFlags & WS_MSG_OOB) pfd.events |= POLLPRI;
4658
4659             if (!timeout || !poll( &pfd, 1, timeout ))
4660             {
4661                 err = WSAETIMEDOUT;
4662                 /* a timeout is not fatal */
4663                 _enable_event(SOCKET2HANDLE(s), FD_READ, 0, 0);
4664                 goto error;
4665             }
4666         }
4667         else
4668         {
4669             _enable_event(SOCKET2HANDLE(s), FD_READ, 0, 0);
4670             err = WSAEWOULDBLOCK;
4671             goto error;
4672         }
4673     }
4674
4675     TRACE(" -> %i bytes\n", n);
4676     HeapFree( GetProcessHeap(), 0, wsa );
4677     release_sock_fd( s, fd );
4678     _enable_event(SOCKET2HANDLE(s), FD_READ, 0, 0);
4679
4680     return 0;
4681
4682 error:
4683     HeapFree( GetProcessHeap(), 0, wsa );
4684     release_sock_fd( s, fd );
4685     WARN(" -> ERROR %d\n", err);
4686     WSASetLastError( err );
4687     return SOCKET_ERROR;
4688 }
4689
4690 /***********************************************************************
4691  *              WSCInstallProvider             (WS2_32.88)
4692  */
4693 INT WINAPI WSCInstallProvider( const LPGUID lpProviderId,
4694                                LPCWSTR lpszProviderDllPath,
4695                                const LPWSAPROTOCOL_INFOW lpProtocolInfoList,
4696                                DWORD dwNumberOfEntries,
4697                                LPINT lpErrno )
4698 {
4699     FIXME("(%s, %s, %p, %d, %p): stub !\n", debugstr_guid(lpProviderId),
4700           debugstr_w(lpszProviderDllPath), lpProtocolInfoList,
4701           dwNumberOfEntries, lpErrno);
4702     *lpErrno = 0;
4703     return 0;
4704 }
4705
4706
4707 /***********************************************************************
4708  *              WSCDeinstallProvider             (WS2_32.83)
4709  */
4710 INT WINAPI WSCDeinstallProvider(LPGUID lpProviderId, LPINT lpErrno)
4711 {
4712     FIXME("(%s, %p): stub !\n", debugstr_guid(lpProviderId), lpErrno);
4713     *lpErrno = 0;
4714     return 0;
4715 }
4716
4717
4718 /***********************************************************************
4719  *              WSAAccept                        (WS2_32.26)
4720  */
4721 SOCKET WINAPI WSAAccept( SOCKET s, struct WS_sockaddr *addr, LPINT addrlen,
4722                LPCONDITIONPROC lpfnCondition, DWORD dwCallbackData)
4723 {
4724
4725        int ret = 0, size = 0;
4726        WSABUF CallerId, CallerData, CalleeId, CalleeData;
4727        /*        QOS SQOS, GQOS; */
4728        GROUP g;
4729        SOCKET cs;
4730        SOCKADDR src_addr, dst_addr;
4731
4732        TRACE("Socket %04lx, sockaddr %p, addrlen %p, fnCondition %p, dwCallbackData %d\n",
4733                s, addr, addrlen, lpfnCondition, dwCallbackData);
4734
4735
4736        size = sizeof(src_addr);
4737        cs = WS_accept(s, &src_addr, &size);
4738
4739        if (cs == SOCKET_ERROR) return SOCKET_ERROR;
4740
4741        if (!lpfnCondition) return cs;
4742
4743        CallerId.buf = (char *)&src_addr;
4744        CallerId.len = sizeof(src_addr);
4745
4746        CallerData.buf = NULL;
4747        CallerData.len = 0;
4748
4749        WS_getsockname(cs, &dst_addr, &size);
4750
4751        CalleeId.buf = (char *)&dst_addr;
4752        CalleeId.len = sizeof(dst_addr);
4753
4754
4755        ret = (*lpfnCondition)(&CallerId, &CallerData, NULL, NULL,
4756                        &CalleeId, &CalleeData, &g, dwCallbackData);
4757
4758        switch (ret)
4759        {
4760                case CF_ACCEPT:
4761                        if (addr && addrlen)
4762                                addr = memcpy(addr, &src_addr, (*addrlen > size) ?  size : *addrlen );
4763                        return cs;
4764                case CF_DEFER:
4765                        SERVER_START_REQ( set_socket_deferred )
4766                        {
4767                            req->handle = wine_server_obj_handle( SOCKET2HANDLE(s) );
4768                            req->deferred = wine_server_obj_handle( SOCKET2HANDLE(cs) );
4769                            if ( !wine_server_call_err ( req ) )
4770                            {
4771                                SetLastError( WSATRY_AGAIN );
4772                                WS_closesocket( cs );
4773                            }
4774                        }
4775                        SERVER_END_REQ;
4776                        return SOCKET_ERROR;
4777                case CF_REJECT:
4778                        WS_closesocket(cs);
4779                        SetLastError(WSAECONNREFUSED);
4780                        return SOCKET_ERROR;
4781                default:
4782                        FIXME("Unknown return type from Condition function\n");
4783                        SetLastError(WSAENOTSOCK);
4784                        return SOCKET_ERROR;
4785        }
4786 }
4787
4788 /***********************************************************************
4789  *              WSADuplicateSocketA                      (WS2_32.32)
4790  */
4791 int WINAPI WSADuplicateSocketA( SOCKET s, DWORD dwProcessId, LPWSAPROTOCOL_INFOA lpProtocolInfo )
4792 {
4793    HANDLE hProcess;
4794
4795    TRACE("(%ld,%x,%p)\n", s, dwProcessId, lpProtocolInfo);
4796    memset(lpProtocolInfo, 0, sizeof(*lpProtocolInfo));
4797    /* FIXME: WS_getsockopt(s, WS_SOL_SOCKET, SO_PROTOCOL_INFO, lpProtocolInfo, sizeof(*lpProtocolInfo)); */
4798    /* I don't know what the real Windoze does next, this is a hack */
4799    /* ...we could duplicate and then use ConvertToGlobalHandle on the duplicate, then let
4800     * the target use the global duplicate, or we could copy a reference to us to the structure
4801     * and let the target duplicate it from us, but let's do it as simple as possible */
4802    hProcess = OpenProcess(PROCESS_DUP_HANDLE, FALSE, dwProcessId);
4803    DuplicateHandle(GetCurrentProcess(), SOCKET2HANDLE(s),
4804                    hProcess, (LPHANDLE)&lpProtocolInfo->dwCatalogEntryId,
4805                    0, FALSE, DUPLICATE_SAME_ACCESS);
4806    CloseHandle(hProcess);
4807    lpProtocolInfo->dwServiceFlags4 = 0xff00ff00; /* magic */
4808    return 0;
4809 }
4810
4811 /***********************************************************************
4812  *              WSADuplicateSocketW                      (WS2_32.33)
4813  */
4814 int WINAPI WSADuplicateSocketW( SOCKET s, DWORD dwProcessId, LPWSAPROTOCOL_INFOW lpProtocolInfo )
4815 {
4816    HANDLE hProcess;
4817
4818    TRACE("(%ld,%x,%p)\n", s, dwProcessId, lpProtocolInfo);
4819
4820    memset(lpProtocolInfo, 0, sizeof(*lpProtocolInfo));
4821    hProcess = OpenProcess(PROCESS_DUP_HANDLE, FALSE, dwProcessId);
4822    DuplicateHandle(GetCurrentProcess(), SOCKET2HANDLE(s),
4823                    hProcess, (LPHANDLE)&lpProtocolInfo->dwCatalogEntryId,
4824                    0, FALSE, DUPLICATE_SAME_ACCESS);
4825    CloseHandle(hProcess);
4826    lpProtocolInfo->dwServiceFlags4 = 0xff00ff00; /* magic */
4827    return 0;
4828 }
4829
4830 /***********************************************************************
4831  *              WSAInstallServiceClassA                  (WS2_32.48)
4832  */
4833 int WINAPI WSAInstallServiceClassA(LPWSASERVICECLASSINFOA info)
4834 {
4835     FIXME("Request to install service %s\n",debugstr_a(info->lpszServiceClassName));
4836     WSASetLastError(WSAEACCES);
4837     return SOCKET_ERROR;
4838 }
4839
4840 /***********************************************************************
4841  *              WSAInstallServiceClassW                  (WS2_32.49)
4842  */
4843 int WINAPI WSAInstallServiceClassW(LPWSASERVICECLASSINFOW info)
4844 {
4845     FIXME("Request to install service %s\n",debugstr_w(info->lpszServiceClassName));
4846     WSASetLastError(WSAEACCES);
4847     return SOCKET_ERROR;
4848 }
4849
4850 /***********************************************************************
4851  *              WSARemoveServiceClass                    (WS2_32.70)
4852  */
4853 int WINAPI WSARemoveServiceClass(LPGUID info)
4854 {
4855     FIXME("Request to remove service %p\n",info);
4856     WSASetLastError(WSATYPE_NOT_FOUND);
4857     return SOCKET_ERROR;
4858 }
4859
4860 /***********************************************************************
4861  *              inet_ntop                      (WS2_32.@)
4862  */
4863 PCSTR WINAPI WS_inet_ntop( INT family, PVOID addr, PSTR buffer, SIZE_T len )
4864 {
4865 #ifdef HAVE_INET_NTOP
4866     struct WS_in6_addr *in6;
4867     struct WS_in_addr  *in;
4868     PCSTR pdst;
4869
4870     TRACE("family %d, addr (%p), buffer (%p), len %ld\n", family, addr, buffer, len);
4871     if (!buffer)
4872     {
4873         WSASetLastError( STATUS_INVALID_PARAMETER );
4874         return NULL;
4875     }
4876
4877     switch (family)
4878     {
4879     case WS_AF_INET:
4880     {
4881         in = addr;
4882         pdst = inet_ntop( AF_INET, &in->WS_s_addr, buffer, len );
4883         break;
4884     }
4885     case WS_AF_INET6:
4886     {
4887         in6 = addr;
4888         pdst = inet_ntop( AF_INET6, in6->WS_s6_addr, buffer, len );
4889         break;
4890     }
4891     default:
4892         WSASetLastError( WSAEAFNOSUPPORT );
4893         return NULL;
4894     }
4895
4896     if (!pdst) WSASetLastError( STATUS_INVALID_PARAMETER );
4897     return pdst;
4898 #else
4899     FIXME( "not supported on this platform\n" );
4900     WSASetLastError( WSAEAFNOSUPPORT );
4901     return NULL;
4902 #endif
4903 }
4904
4905 /***********************************************************************
4906  *              WSAStringToAddressA                      (WS2_32.80)
4907  */
4908 INT WINAPI WSAStringToAddressA(LPSTR AddressString,
4909                                INT AddressFamily,
4910                                LPWSAPROTOCOL_INFOA lpProtocolInfo,
4911                                LPSOCKADDR lpAddress,
4912                                LPINT lpAddressLength)
4913 {
4914     INT res=0;
4915     LPSTR workBuffer=NULL,ptrPort;
4916
4917     TRACE( "(%s, %x, %p, %p, %p)\n", debugstr_a(AddressString), AddressFamily,
4918            lpProtocolInfo, lpAddress, lpAddressLength );
4919
4920     if (!lpAddressLength || !lpAddress) return SOCKET_ERROR;
4921
4922     if (!AddressString)
4923     {
4924         WSASetLastError(WSAEINVAL);
4925         return SOCKET_ERROR;
4926     }
4927
4928     if (lpProtocolInfo)
4929         FIXME("ProtocolInfo not implemented.\n");
4930
4931     workBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
4932                             strlen(AddressString) + 1);
4933     if (!workBuffer)
4934     {
4935         WSASetLastError(WSA_NOT_ENOUGH_MEMORY);
4936         return SOCKET_ERROR;
4937     }
4938
4939     strcpy(workBuffer, AddressString);
4940
4941     switch(AddressFamily)
4942     {
4943     case WS_AF_INET:
4944     {
4945         struct in_addr inetaddr;
4946
4947         /* If lpAddressLength is too small, tell caller the size we need */
4948         if (*lpAddressLength < sizeof(SOCKADDR_IN))
4949         {
4950             *lpAddressLength = sizeof(SOCKADDR_IN);
4951             res = WSAEFAULT;
4952             break;
4953         }
4954         memset(lpAddress, 0, sizeof(SOCKADDR_IN));
4955
4956         ((LPSOCKADDR_IN)lpAddress)->sin_family = AF_INET;
4957
4958         ptrPort = strchr(workBuffer, ':');
4959         if(ptrPort)
4960         {
4961             ((LPSOCKADDR_IN)lpAddress)->sin_port = htons(atoi(ptrPort+1));
4962             *ptrPort = '\0';
4963         }
4964         else
4965         {
4966             ((LPSOCKADDR_IN)lpAddress)->sin_port = 0;
4967         }
4968
4969         if(inet_aton(workBuffer, &inetaddr) > 0)
4970         {
4971             ((LPSOCKADDR_IN)lpAddress)->sin_addr.WS_s_addr = inetaddr.s_addr;
4972             res = 0;
4973         }
4974         else
4975             res = WSAEINVAL;
4976
4977         break;
4978
4979     }
4980     case WS_AF_INET6:
4981     {
4982         struct in6_addr inetaddr;
4983         /* If lpAddressLength is too small, tell caller the size we need */
4984         if (*lpAddressLength < sizeof(SOCKADDR_IN6))
4985         {
4986             *lpAddressLength = sizeof(SOCKADDR_IN6);
4987             res = WSAEFAULT;
4988             break;
4989         }
4990 #ifdef HAVE_INET_PTON
4991         memset(lpAddress, 0, sizeof(SOCKADDR_IN6));
4992
4993         ((LPSOCKADDR_IN6)lpAddress)->sin6_family = WS_AF_INET6;
4994
4995         /* This one is a bit tricky. An IPv6 address contains colons, so the
4996          * check from IPv4 doesn't work like that. However, IPv6 addresses that
4997          * contain a port are written with braces like [fd12:3456:7890::1]:12345
4998          * so what we will do is to look for ']', check if the next char is a
4999          * colon, and if it is, parse the port as in IPv4. */
5000
5001         ptrPort = strchr(workBuffer, ']');
5002         if(ptrPort && *(++ptrPort) == ':')
5003         {
5004             ((LPSOCKADDR_IN6)lpAddress)->sin6_port = htons(atoi(ptrPort+1));
5005             *ptrPort = '\0';
5006         }
5007         else
5008         {
5009             ((LPSOCKADDR_IN6)lpAddress)->sin6_port = 0;
5010         }
5011
5012         if(inet_pton(AF_INET6, workBuffer, &inetaddr) > 0)
5013         {
5014             memcpy(&((LPSOCKADDR_IN6)lpAddress)->sin6_addr, &inetaddr,
5015                     sizeof(struct in6_addr));
5016             res = 0;
5017         }
5018         else
5019 #endif /* HAVE_INET_PTON */
5020             res = WSAEINVAL;
5021
5022         break;
5023     }
5024     default:
5025         /* According to MSDN, only AF_INET and AF_INET6 are supported. */
5026         TRACE("Unsupported address family specified: %d.\n", AddressFamily);
5027         res = WSAEINVAL;
5028     }
5029
5030     HeapFree(GetProcessHeap(), 0, workBuffer);
5031
5032     if (!res) return 0;
5033     WSASetLastError(res);
5034     return SOCKET_ERROR;
5035 }
5036
5037 /***********************************************************************
5038  *              WSAStringToAddressW                      (WS2_32.81)
5039  *
5040  * Does anybody know if this functions allows to use hebrew/arabic/chinese... digits?
5041  * If this should be the case, it would be required to map these digits
5042  * to Unicode digits (0-9) using FoldString first.
5043  */
5044 INT WINAPI WSAStringToAddressW(LPWSTR AddressString,
5045                                INT AddressFamily,
5046                                LPWSAPROTOCOL_INFOW lpProtocolInfo,
5047                                LPSOCKADDR lpAddress,
5048                                LPINT lpAddressLength)
5049 {
5050     INT sBuffer,res=0;
5051     LPSTR workBuffer=NULL;
5052     WSAPROTOCOL_INFOA infoA;
5053     LPWSAPROTOCOL_INFOA lpProtoInfoA = NULL;
5054
5055     TRACE( "(%s, %x, %p, %p, %p)\n", debugstr_w(AddressString), AddressFamily, lpProtocolInfo,
5056            lpAddress, lpAddressLength );
5057
5058     if (!lpAddressLength || !lpAddress) return SOCKET_ERROR;
5059
5060     /* if ProtocolInfo is available - convert to ANSI variant */
5061     if (lpProtocolInfo)
5062     {
5063         lpProtoInfoA = &infoA;
5064         memcpy( lpProtoInfoA, lpProtocolInfo, FIELD_OFFSET( WSAPROTOCOL_INFOA, szProtocol ) );
5065
5066         if (!WideCharToMultiByte( CP_ACP, 0, lpProtocolInfo->szProtocol, -1,
5067                                   lpProtoInfoA->szProtocol, WSAPROTOCOL_LEN+1, NULL, NULL ))
5068         {
5069             WSASetLastError( WSAEINVAL);
5070             return SOCKET_ERROR;
5071         }
5072     }
5073
5074     if (AddressString)
5075     {
5076         /* Translate AddressString to ANSI code page - assumes that only
5077            standard digits 0-9 are used with this API call */
5078         sBuffer = WideCharToMultiByte( CP_ACP, 0, AddressString, -1, NULL, 0, NULL, NULL );
5079         workBuffer = HeapAlloc( GetProcessHeap(), 0, sBuffer );
5080
5081         if (workBuffer)
5082         {
5083             WideCharToMultiByte( CP_ACP, 0, AddressString, -1, workBuffer, sBuffer, NULL, NULL );
5084             res = WSAStringToAddressA(workBuffer,AddressFamily,lpProtoInfoA,
5085                                       lpAddress,lpAddressLength);
5086             HeapFree( GetProcessHeap(), 0, workBuffer );
5087             return res;
5088         }
5089         else
5090             res = WSA_NOT_ENOUGH_MEMORY;
5091     }
5092     else
5093         res = WSAEINVAL;
5094
5095     WSASetLastError(res);
5096     return SOCKET_ERROR;
5097 }
5098
5099 /***********************************************************************
5100  *              WSAAddressToStringA                      (WS2_32.27)
5101  *
5102  *  See WSAAddressToStringW
5103  */
5104 INT WINAPI WSAAddressToStringA( LPSOCKADDR sockaddr, DWORD len,
5105                                 LPWSAPROTOCOL_INFOA info, LPSTR string,
5106                                 LPDWORD lenstr )
5107 {
5108     DWORD size;
5109     CHAR buffer[54]; /* 32 digits + 7':' + '[' + '%" + 5 digits + ']:' + 5 digits + '\0' */
5110     CHAR *p;
5111
5112     TRACE( "(%p, %d, %p, %p, %p)\n", sockaddr, len, info, string, lenstr );
5113
5114     if (!sockaddr) return SOCKET_ERROR;
5115     if (!string || !lenstr) return SOCKET_ERROR;
5116
5117     switch(sockaddr->sa_family)
5118     {
5119     case WS_AF_INET:
5120         if (len < sizeof(SOCKADDR_IN)) return SOCKET_ERROR;
5121         sprintf( buffer, "%u.%u.%u.%u:%u",
5122                (unsigned int)(ntohl( ((SOCKADDR_IN *)sockaddr)->sin_addr.WS_s_addr ) >> 24 & 0xff),
5123                (unsigned int)(ntohl( ((SOCKADDR_IN *)sockaddr)->sin_addr.WS_s_addr ) >> 16 & 0xff),
5124                (unsigned int)(ntohl( ((SOCKADDR_IN *)sockaddr)->sin_addr.WS_s_addr ) >> 8 & 0xff),
5125                (unsigned int)(ntohl( ((SOCKADDR_IN *)sockaddr)->sin_addr.WS_s_addr ) & 0xff),
5126                ntohs( ((SOCKADDR_IN *)sockaddr)->sin_port ) );
5127
5128         p = strchr( buffer, ':' );
5129         if (!((SOCKADDR_IN *)sockaddr)->sin_port) *p = 0;
5130         break;
5131
5132     case WS_AF_INET6:
5133     {
5134         struct WS_sockaddr_in6 *sockaddr6 = (LPSOCKADDR_IN6) sockaddr;
5135
5136         buffer[0] = 0;
5137         if (len < sizeof(SOCKADDR_IN6)) return SOCKET_ERROR;
5138         if ((sockaddr6->sin6_port))
5139             strcpy(buffer, "[");
5140         if (!WS_inet_ntop(WS_AF_INET6, &sockaddr6->sin6_addr, buffer+strlen(buffer), sizeof(buffer)))
5141         {
5142             WSASetLastError(WSAEINVAL);
5143             return SOCKET_ERROR;
5144         }
5145         if ((sockaddr6->sin6_scope_id))
5146             sprintf(buffer+strlen(buffer), "%%%u", sockaddr6->sin6_scope_id);
5147         if ((sockaddr6->sin6_port))
5148             sprintf(buffer+strlen(buffer), "]:%u", ntohs(sockaddr6->sin6_port));
5149         break;
5150     }
5151
5152     default:
5153         WSASetLastError(WSAEINVAL);
5154         return SOCKET_ERROR;
5155     }
5156
5157     size = strlen( buffer ) + 1;
5158
5159     if (*lenstr <  size)
5160     {
5161         *lenstr = size;
5162         WSASetLastError(WSAEFAULT);
5163         return SOCKET_ERROR;
5164     }
5165
5166     *lenstr = size;
5167     strcpy( string, buffer );
5168     return 0;
5169 }
5170
5171 /***********************************************************************
5172  *              WSAAddressToStringW                      (WS2_32.28)
5173  *
5174  * Convert a sockaddr address into a readable address string. 
5175  *
5176  * PARAMS
5177  *  sockaddr [I]    Pointer to a sockaddr structure.
5178  *  len      [I]    Size of the sockaddr structure.
5179  *  info     [I]    Pointer to a WSAPROTOCOL_INFOW structure (optional).
5180  *  string   [I/O]  Pointer to a buffer to receive the address string.
5181  *  lenstr   [I/O]  Size of the receive buffer in WCHARs.
5182  *
5183  * RETURNS
5184  *  Success: 0
5185  *  Failure: SOCKET_ERROR
5186  *
5187  * NOTES
5188  *  The 'info' parameter is ignored.
5189  */
5190 INT WINAPI WSAAddressToStringW( LPSOCKADDR sockaddr, DWORD len,
5191                                 LPWSAPROTOCOL_INFOW info, LPWSTR string,
5192                                 LPDWORD lenstr )
5193 {
5194     INT   ret;
5195     DWORD size;
5196     WCHAR buffer[54]; /* 32 digits + 7':' + '[' + '%" + 5 digits + ']:' + 5 digits + '\0' */
5197     CHAR bufAddr[54];
5198
5199     TRACE( "(%p, %d, %p, %p, %p)\n", sockaddr, len, info, string, lenstr );
5200
5201     size = *lenstr;
5202     ret = WSAAddressToStringA(sockaddr, len, NULL, bufAddr, &size);
5203
5204     if (ret) return ret;
5205
5206     MultiByteToWideChar( CP_ACP, 0, bufAddr, size, buffer, sizeof( buffer )/sizeof(WCHAR));
5207
5208     if (*lenstr <  size)
5209     {
5210         *lenstr = size;
5211         WSASetLastError(WSAEFAULT);
5212         return SOCKET_ERROR;
5213     }
5214
5215     *lenstr = size;
5216     lstrcpyW( string, buffer );
5217     return 0;
5218 }
5219
5220 /***********************************************************************
5221  *              WSAEnumNameSpaceProvidersA                  (WS2_32.34)
5222  */
5223 INT WINAPI WSAEnumNameSpaceProvidersA( LPDWORD len, LPWSANAMESPACE_INFOA buffer )
5224 {
5225     FIXME( "(%p %p) Stub!\n", len, buffer );
5226     return 0;
5227 }
5228
5229 /***********************************************************************
5230  *              WSAEnumNameSpaceProvidersW                  (WS2_32.35)
5231  */
5232 INT WINAPI WSAEnumNameSpaceProvidersW( LPDWORD len, LPWSANAMESPACE_INFOW buffer )
5233 {
5234     FIXME( "(%p %p) Stub!\n", len, buffer );
5235     return 0;
5236 }
5237
5238 /***********************************************************************
5239  *              WSAGetQOSByName                             (WS2_32.41)
5240  */
5241 BOOL WINAPI WSAGetQOSByName( SOCKET s, LPWSABUF lpQOSName, LPQOS lpQOS )
5242 {
5243     FIXME( "(0x%04lx %p %p) Stub!\n", s, lpQOSName, lpQOS );
5244     return FALSE;
5245 }
5246
5247 /***********************************************************************
5248  *              WSAGetServiceClassInfoA                     (WS2_32.42)
5249  */
5250 INT WINAPI WSAGetServiceClassInfoA( LPGUID provider, LPGUID service, LPDWORD len,
5251                                     LPWSASERVICECLASSINFOA info )
5252 {
5253     FIXME( "(%s %s %p %p) Stub!\n", debugstr_guid(provider), debugstr_guid(service),
5254            len, info );
5255     WSASetLastError(WSA_NOT_ENOUGH_MEMORY);
5256     return SOCKET_ERROR; 
5257 }
5258
5259 /***********************************************************************
5260  *              WSAGetServiceClassInfoW                     (WS2_32.43)
5261  */
5262 INT WINAPI WSAGetServiceClassInfoW( LPGUID provider, LPGUID service, LPDWORD len,
5263                                     LPWSASERVICECLASSINFOW info )
5264 {
5265     FIXME( "(%s %s %p %p) Stub!\n", debugstr_guid(provider), debugstr_guid(service),
5266            len, info );
5267     WSASetLastError(WSA_NOT_ENOUGH_MEMORY);
5268     return SOCKET_ERROR;
5269 }
5270
5271 /***********************************************************************
5272  *              WSAGetServiceClassNameByClassIdA            (WS2_32.44)
5273  */
5274 INT WINAPI WSAGetServiceClassNameByClassIdA( LPGUID class, LPSTR service, LPDWORD len )
5275 {
5276     FIXME( "(%s %p %p) Stub!\n", debugstr_guid(class), service, len );
5277     WSASetLastError(WSA_NOT_ENOUGH_MEMORY);
5278     return SOCKET_ERROR;
5279 }
5280
5281 /***********************************************************************
5282  *              WSAGetServiceClassNameByClassIdW            (WS2_32.45)
5283  */
5284 INT WINAPI WSAGetServiceClassNameByClassIdW( LPGUID class, LPWSTR service, LPDWORD len )
5285 {
5286     FIXME( "(%s %p %p) Stub!\n", debugstr_guid(class), service, len );
5287     WSASetLastError(WSA_NOT_ENOUGH_MEMORY);
5288     return SOCKET_ERROR;
5289 }
5290
5291 /***********************************************************************
5292  *              WSALookupServiceBeginA                       (WS2_32.59)
5293  */
5294 INT WINAPI WSALookupServiceBeginA( LPWSAQUERYSETA lpqsRestrictions,
5295                                    DWORD dwControlFlags,
5296                                    LPHANDLE lphLookup)
5297 {
5298     FIXME("(%p 0x%08x %p) Stub!\n", lpqsRestrictions, dwControlFlags,
5299             lphLookup);
5300     WSASetLastError(WSA_NOT_ENOUGH_MEMORY);
5301     return SOCKET_ERROR;
5302 }
5303
5304 /***********************************************************************
5305  *              WSALookupServiceBeginW                       (WS2_32.60)
5306  */
5307 INT WINAPI WSALookupServiceBeginW( LPWSAQUERYSETW lpqsRestrictions,
5308                                    DWORD dwControlFlags,
5309                                    LPHANDLE lphLookup)
5310 {
5311     FIXME("(%p 0x%08x %p) Stub!\n", lpqsRestrictions, dwControlFlags,
5312             lphLookup);
5313     WSASetLastError(WSA_NOT_ENOUGH_MEMORY);
5314     return SOCKET_ERROR;
5315 }
5316
5317 /***********************************************************************
5318  *              WSALookupServiceBeginW                       (WS2_32.61)
5319  */
5320 INT WINAPI WSALookupServiceEnd( HANDLE lookup )
5321 {
5322     FIXME("(%p) Stub!\n", lookup );
5323     return 0;
5324 }
5325
5326 /***********************************************************************
5327  *              WSALookupServiceNextA                       (WS2_32.62)
5328  */
5329 INT WINAPI WSALookupServiceNextA( HANDLE lookup, DWORD flags, LPDWORD len, LPWSAQUERYSETA results )
5330 {
5331     FIXME( "(%p 0x%08x %p %p) Stub!\n", lookup, flags, len, results );
5332     return 0;
5333 }
5334
5335 /***********************************************************************
5336  *              WSALookupServiceNextW                       (WS2_32.63)
5337  */
5338 INT WINAPI WSALookupServiceNextW( HANDLE lookup, DWORD flags, LPDWORD len, LPWSAQUERYSETW results )
5339 {
5340     FIXME( "(%p 0x%08x %p %p) Stub!\n", lookup, flags, len, results );
5341     return 0;
5342 }
5343
5344 /***********************************************************************
5345  *              WSANtohl                                   (WS2_32.64)
5346  */
5347 INT WINAPI WSANtohl( SOCKET s, WS_u_long netlong, WS_u_long* lphostlong )
5348 {
5349     TRACE( "(0x%04lx 0x%08x %p)\n", s, netlong, lphostlong );
5350
5351     if (!lphostlong) return WSAEFAULT;
5352
5353     *lphostlong = ntohl( netlong );
5354     return 0;
5355 }
5356
5357 /***********************************************************************
5358  *              WSANtohs                                   (WS2_32.65)
5359  */
5360 INT WINAPI WSANtohs( SOCKET s, WS_u_short netshort, WS_u_short* lphostshort )
5361 {
5362     TRACE( "(0x%04lx 0x%08x %p)\n", s, netshort, lphostshort );
5363
5364     if (!lphostshort) return WSAEFAULT;
5365
5366     *lphostshort = ntohs( netshort );
5367     return 0;
5368 }
5369
5370 /***********************************************************************
5371  *              WSAProviderConfigChange                     (WS2_32.66)
5372  */
5373 INT WINAPI WSAProviderConfigChange( LPHANDLE handle, LPWSAOVERLAPPED overlapped,
5374                                     LPWSAOVERLAPPED_COMPLETION_ROUTINE completion )
5375 {
5376     FIXME( "(%p %p %p) Stub!\n", handle, overlapped, completion );
5377     return SOCKET_ERROR;
5378 }
5379
5380 /***********************************************************************
5381  *              WSARecvDisconnect                           (WS2_32.68)
5382  */
5383 INT WINAPI WSARecvDisconnect( SOCKET s, LPWSABUF disconnectdata )
5384 {
5385     TRACE( "(0x%04lx %p)\n", s, disconnectdata );
5386
5387     return WS_shutdown( s, 0 );
5388 }
5389
5390 /***********************************************************************
5391  *              WSASetServiceA                              (WS2_32.76)
5392  */
5393 INT WINAPI WSASetServiceA( LPWSAQUERYSETA query, WSAESETSERVICEOP operation, DWORD flags )
5394 {
5395     FIXME( "(%p 0x%08x 0x%08x) Stub!\n", query, operation, flags );
5396     return 0;
5397 }
5398
5399 /***********************************************************************
5400  *              WSASetServiceW                              (WS2_32.77)
5401  */
5402 INT WINAPI WSASetServiceW( LPWSAQUERYSETW query, WSAESETSERVICEOP operation, DWORD flags )
5403 {
5404     FIXME( "(%p 0x%08x 0x%08x) Stub!\n", query, operation, flags );
5405     return 0;
5406 }
5407
5408 /***********************************************************************
5409  *              WSCEnableNSProvider                         (WS2_32.84)
5410  */
5411 INT WINAPI WSCEnableNSProvider( LPGUID provider, BOOL enable )
5412 {
5413     FIXME( "(%s 0x%08x) Stub!\n", debugstr_guid(provider), enable );
5414     return 0;
5415 }
5416
5417 /***********************************************************************
5418  *              WSCGetProviderPath                          (WS2_32.86)
5419  */
5420 INT WINAPI WSCGetProviderPath( LPGUID provider, LPWSTR path, LPINT len, LPINT errcode )
5421 {
5422     FIXME( "(%s %p %p %p) Stub!\n", debugstr_guid(provider), path, len, errcode );
5423
5424     if (!errcode || !provider || !len) return WSAEFAULT;
5425
5426     *errcode = WSAEINVAL;
5427     return SOCKET_ERROR;
5428 }
5429
5430 /***********************************************************************
5431  *              WSCInstallNameSpace                         (WS2_32.87)
5432  */
5433 INT WINAPI WSCInstallNameSpace( LPWSTR identifier, LPWSTR path, DWORD namespace,
5434                                 DWORD version, LPGUID provider )
5435 {
5436     FIXME( "(%s %s 0x%08x 0x%08x %s) Stub!\n", debugstr_w(identifier), debugstr_w(path),
5437            namespace, version, debugstr_guid(provider) );
5438     return 0;
5439 }
5440
5441 /***********************************************************************
5442  *              WSCUnInstallNameSpace                       (WS2_32.89)
5443  */
5444 INT WINAPI WSCUnInstallNameSpace( LPGUID lpProviderId )
5445 {
5446     FIXME("(%p) Stub!\n", lpProviderId);
5447     return NO_ERROR;
5448 }
5449
5450 /***********************************************************************
5451  *              WSCWriteProviderOrder                       (WS2_32.91)
5452  */
5453 INT WINAPI WSCWriteProviderOrder( LPDWORD entry, DWORD number )
5454 {
5455     FIXME("(%p 0x%08x) Stub!\n", entry, number);
5456     return 0;
5457 }