Clear struct sockaddr_ipx directly instead of just the sipx_zero
[wine] / dlls / winsock / socket.c
1 /*
2  * based on Windows Sockets 1.1 specs
3  * (ftp.microsoft.com:/Advsys/winsock/spec11/WINSOCK.TXT)
4  *
5  * Copyright (C) 1993,1994,1996,1997 John Brezak, Erik Bos, Alex Korobka.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  *
21  * NOTE: If you make any changes to fix a particular app, make sure
22  * they don't break something else like Netscape or telnet and ftp
23  * clients and servers (www.winsite.com got a lot of those).
24  */
25
26 #include "config.h"
27 #include "wine/port.h"
28
29 #include <stdarg.h>
30 #include <stdio.h>
31 #include <string.h>
32 #include <sys/types.h>
33 #ifdef HAVE_SYS_IPC_H
34 # include <sys/ipc.h>
35 #endif
36 #ifdef HAVE_SYS_IOCTL_H
37 # include <sys/ioctl.h>
38 #endif
39 #ifdef HAVE_SYS_FILIO_H
40 # include <sys/filio.h>
41 #endif
42 #ifdef HAVE_SYS_SOCKIO_H
43 # include <sys/sockio.h>
44 #endif
45
46 #if defined(__EMX__)
47 # include <sys/so_ioctl.h>
48 #endif
49
50 #ifdef HAVE_SYS_PARAM_H
51 # include <sys/param.h>
52 #endif
53
54 #ifdef HAVE_SYS_MSG_H
55 # include <sys/msg.h>
56 #endif
57 #ifdef HAVE_SYS_WAIT_H
58 # include <sys/wait.h>
59 #endif
60 #ifdef HAVE_SYS_UIO_H
61 # include <sys/uio.h>
62 #endif
63 #ifdef HAVE_SYS_SOCKET_H
64 #include <sys/socket.h>
65 #endif
66 #ifdef HAVE_NETINET_IN_H
67 # include <netinet/in.h>
68 #endif
69 #ifdef HAVE_NETINET_TCP_H
70 # include <netinet/tcp.h>
71 #endif
72 #ifdef HAVE_ARPA_INET_H
73 # include <arpa/inet.h>
74 #endif
75 #include <ctype.h>
76 #include <fcntl.h>
77 #include <errno.h>
78 #ifdef HAVE_SYS_ERRNO_H
79 #include <sys/errno.h>
80 #endif
81 #ifdef HAVE_NETDB_H
82 #include <netdb.h>
83 #endif
84 #ifdef HAVE_UNISTD_H
85 # include <unistd.h>
86 #endif
87 #include <stdlib.h>
88 #ifdef HAVE_ARPA_NAMESER_H
89 # include <arpa/nameser.h>
90 #endif
91 #ifdef HAVE_RESOLV_H
92 # include <resolv.h>
93 #endif
94 #ifdef HAVE_NET_IF_H
95 # include <net/if.h>
96 #endif
97 #ifdef HAVE_IPX_GNU
98 # include <netipx/ipx.h>
99 # define HAVE_IPX
100 #endif
101 #ifdef HAVE_IPX_LINUX
102 # include <asm/types.h>
103 # include <linux/ipx.h>
104 # define HAVE_IPX
105 #endif
106
107 #ifdef HAVE_SYS_POLL_H
108 # include <sys/poll.h>
109 #endif
110 #ifdef HAVE_SYS_TIME_H
111 # include <sys/time.h>
112 #endif
113
114 #define NONAMELESSUNION
115 #define NONAMELESSSTRUCT
116 #include "windef.h"
117 #include "winbase.h"
118 #include "wingdi.h"
119 #include "winuser.h"
120 #include "winerror.h"
121 #include "winsock2.h"
122 #include "ws2tcpip.h"
123 #include "wsipx.h"
124 #include "winnt.h"
125 #include "iphlpapi.h"
126 #include "thread.h"
127 #include "wine/server.h"
128 #include "wine/debug.h"
129
130 #ifdef __FreeBSD__
131 # define sipx_network    sipx_addr.x_net
132 # define sipx_node       sipx_addr.x_host.c_host
133 #endif  /* __FreeBSD__ */
134
135 WINE_DEFAULT_DEBUG_CHANNEL(winsock);
136
137 /* critical section to protect some non-rentrant net function */
138 extern CRITICAL_SECTION csWSgetXXXbyYYY;
139
140 inline static const char *debugstr_sockaddr( const struct WS_sockaddr *a )
141 {
142     if (!a) return "(nil)";
143     return wine_dbg_sprintf("{ family %d, address %s, port %d }",
144                             ((struct sockaddr_in *)a)->sin_family,
145                             inet_ntoa(((struct sockaddr_in *)a)->sin_addr),
146                             ntohs(((struct sockaddr_in *)a)->sin_port));
147 }
148
149 /* HANDLE<->SOCKET conversion (SOCKET is UINT_PTR). */
150 #define SOCKET2HANDLE(s) ((HANDLE)(s))
151 #define HANDLE2SOCKET(h) ((SOCKET)(h))
152
153 /****************************************************************
154  * Async IO declarations
155  ****************************************************************/
156 #include "async.h"
157
158 static DWORD ws2_async_get_count  (const struct async_private *ovp);
159 static void CALLBACK ws2_async_call_completion (ULONG_PTR data);
160 static void ws2_async_cleanup ( struct async_private *ovp );
161
162 static struct async_ops ws2_async_ops =
163 {
164     ws2_async_get_count,
165     ws2_async_call_completion,
166     ws2_async_cleanup
167 };
168
169 static struct async_ops ws2_nocomp_async_ops =
170 {
171     ws2_async_get_count,
172     NULL,                     /* call_completion */
173     ws2_async_cleanup
174 };
175
176 typedef struct ws2_async
177 {
178     async_private                       async;
179     LPWSAOVERLAPPED                     user_overlapped;
180     LPWSAOVERLAPPED_COMPLETION_ROUTINE  completion_func;
181     struct iovec                        *iovec;
182     int                                 n_iovecs;
183     struct WS_sockaddr                  *addr;
184     union {
185         int val;     /* for send operations */
186         int *ptr;    /* for recv operations */
187     }                                   addrlen;
188     DWORD                               flags;
189 } ws2_async;
190
191 /****************************************************************/
192
193 /* ----------------------------------- internal data */
194
195 /* ws_... struct conversion flags */
196
197 typedef struct          /* WSAAsyncSelect() control struct */
198 {
199   HANDLE      service, event, sock;
200   HWND        hWnd;
201   UINT        uMsg;
202   LONG        lEvent;
203 } ws_select_info;
204
205 #define WS_MAX_SOCKETS_PER_PROCESS      128     /* reasonable guess */
206 #define WS_MAX_UDP_DATAGRAM             1024
207 static INT WINAPI WSA_DefaultBlockingHook( FARPROC x );
208
209 static struct WS_hostent *he_buffer;          /* typecast for Win32 ws_hostent */
210 static struct WS_servent *se_buffer;          /* typecast for Win32 ws_servent */
211 static struct WS_protoent *pe_buffer;          /* typecast for Win32 ws_protoent */
212 static INT num_startup;          /* reference counter */
213 static FARPROC blocking_hook = WSA_DefaultBlockingHook;
214
215 /* function prototypes */
216 static struct WS_hostent *WS_dup_he(const struct hostent* p_he);
217 static struct WS_protoent *WS_dup_pe(const struct protoent* p_pe);
218 static struct WS_servent *WS_dup_se(const struct servent* p_se);
219
220 int WSAIOCTL_GetInterfaceCount(void);
221 int WSAIOCTL_GetInterfaceName(int intNumber, char *intName);
222
223 UINT wsaErrno(void);
224 UINT wsaHerrno(int errnr);
225
226 #define MAP_OPTION(opt) { WS_##opt, opt }
227
228 static const int ws_sock_map[][2] =
229 {
230     MAP_OPTION( SO_DEBUG ),
231     MAP_OPTION( SO_REUSEADDR ),
232     MAP_OPTION( SO_KEEPALIVE ),
233     MAP_OPTION( SO_DONTROUTE ),
234     MAP_OPTION( SO_BROADCAST ),
235     MAP_OPTION( SO_LINGER ),
236     MAP_OPTION( SO_OOBINLINE ),
237     MAP_OPTION( SO_SNDBUF ),
238     MAP_OPTION( SO_RCVBUF ),
239     MAP_OPTION( SO_ERROR ),
240     MAP_OPTION( SO_TYPE ),
241 #ifdef SO_RCVTIMEO
242     MAP_OPTION( SO_RCVTIMEO ),
243 #endif
244 #ifdef SO_SNDTIMEO
245     MAP_OPTION( SO_SNDTIMEO ),
246 #endif
247     { 0, 0 }
248 };
249
250 static const int ws_tcp_map[][2] =
251 {
252 #ifdef TCP_NODELAY
253     MAP_OPTION( TCP_NODELAY ),
254 #endif
255     { 0, 0 }
256 };
257
258 static const int ws_ip_map[][2] =
259 {
260     MAP_OPTION( IP_MULTICAST_IF ),
261     MAP_OPTION( IP_MULTICAST_TTL ),
262     MAP_OPTION( IP_MULTICAST_LOOP ),
263     MAP_OPTION( IP_ADD_MEMBERSHIP ),
264     MAP_OPTION( IP_DROP_MEMBERSHIP ),
265     MAP_OPTION( IP_OPTIONS ),
266 #ifdef IP_HDRINCL
267     MAP_OPTION( IP_HDRINCL ),
268 #endif
269     MAP_OPTION( IP_TOS ),
270     MAP_OPTION( IP_TTL ),
271     { 0, 0 }
272 };
273
274 static DWORD opentype_tls_index = TLS_OUT_OF_INDEXES;  /* TLS index for SO_OPENTYPE flag */
275
276 inline static DWORD NtStatusToWSAError ( const DWORD status )
277 {
278     /* We only need to cover the status codes set by server async request handling */
279     DWORD wserr;
280     switch ( status )
281     {
282     case STATUS_SUCCESS:              wserr = 0;                     break;
283     case STATUS_PENDING:              wserr = WSA_IO_PENDING;        break;
284     case STATUS_INVALID_HANDLE:       wserr = WSAENOTSOCK;           break;  /* WSAEBADF ? */
285     case STATUS_INVALID_PARAMETER:    wserr = WSAEINVAL;             break;
286     case STATUS_PIPE_DISCONNECTED:    wserr = WSAESHUTDOWN;          break;
287     case STATUS_CANCELLED:            wserr = WSA_OPERATION_ABORTED; break;
288     case STATUS_TIMEOUT:              wserr = WSAETIMEDOUT;          break;
289     case STATUS_NO_MEMORY:            wserr = WSAEFAULT;             break;
290     default:
291         if ( status >= WSABASEERR && status <= WSABASEERR+1004 )
292             /* It is not a NT status code but a winsock error */
293             wserr = status;
294         else
295         {
296             wserr = RtlNtStatusToDosError( status );
297             FIXME ( "Status code %08lx converted to DOS error code %lx\n", status, wserr );
298         }
299     }
300     return wserr;
301 }
302
303 /* set last error code from NT status without mapping WSA errors */
304 inline static unsigned int set_error( unsigned int err )
305 {
306     if (err)
307     {
308         err = NtStatusToWSAError ( err );
309         SetLastError( err );
310     }
311     return err;
312 }
313
314 inline static int get_sock_fd( SOCKET s, DWORD access, int *flags )
315 {
316     int fd;
317     if (set_error( wine_server_handle_to_fd( SOCKET2HANDLE(s), access, &fd, NULL, flags ) ))
318         return -1;
319     return fd;
320 }
321
322 inline static void release_sock_fd( SOCKET s, int fd )
323 {
324     wine_server_release_fd( SOCKET2HANDLE(s), fd );
325 }
326
327 static void _enable_event( HANDLE s, unsigned int event,
328                            unsigned int sstate, unsigned int cstate )
329 {
330     SERVER_START_REQ( enable_socket_event )
331     {
332         req->handle = s;
333         req->mask   = event;
334         req->sstate = sstate;
335         req->cstate = cstate;
336         wine_server_call( req );
337     }
338     SERVER_END_REQ;
339 }
340
341 static int _is_blocking(SOCKET s)
342 {
343     int ret;
344     SERVER_START_REQ( get_socket_event )
345     {
346         req->handle  = SOCKET2HANDLE(s);
347         req->service = FALSE;
348         req->c_event = 0;
349         wine_server_call( req );
350         ret = (reply->state & FD_WINE_NONBLOCKING) == 0;
351     }
352     SERVER_END_REQ;
353     return ret;
354 }
355
356 static unsigned int _get_sock_mask(SOCKET s)
357 {
358     unsigned int ret;
359     SERVER_START_REQ( get_socket_event )
360     {
361         req->handle  = SOCKET2HANDLE(s);
362         req->service = FALSE;
363         req->c_event = 0;
364         wine_server_call( req );
365         ret = reply->mask;
366     }
367     SERVER_END_REQ;
368     return ret;
369 }
370
371 static void _sync_sock_state(SOCKET s)
372 {
373     /* do a dummy wineserver request in order to let
374        the wineserver run through its select loop once */
375     (void)_is_blocking(s);
376 }
377
378 static int _get_sock_error(SOCKET s, unsigned int bit)
379 {
380     int events[FD_MAX_EVENTS];
381
382     SERVER_START_REQ( get_socket_event )
383     {
384         req->handle  = SOCKET2HANDLE(s);
385         req->service = FALSE;
386         req->c_event = 0;
387         wine_server_set_reply( req, events, sizeof(events) );
388         wine_server_call( req );
389     }
390     SERVER_END_REQ;
391     return events[bit];
392 }
393
394 static void WINSOCK_DeleteIData(void)
395 {
396     /* delete scratch buffers */
397
398     if (he_buffer) HeapFree( GetProcessHeap(), 0, he_buffer );
399     if (se_buffer) HeapFree( GetProcessHeap(), 0, se_buffer );
400     if (pe_buffer) HeapFree( GetProcessHeap(), 0, pe_buffer );
401     he_buffer = NULL;
402     se_buffer = NULL;
403     pe_buffer = NULL;
404     num_startup = 0;
405 }
406
407 /***********************************************************************
408  *              DllMain (WS2_32.init)
409  */
410 BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID fImpLoad)
411 {
412     TRACE("%p 0x%lx %p\n", hInstDLL, fdwReason, fImpLoad);
413     switch (fdwReason) {
414     case DLL_PROCESS_ATTACH:
415         DisableThreadLibraryCalls(hInstDLL);
416         opentype_tls_index = TlsAlloc();
417         break;
418     case DLL_PROCESS_DETACH:
419         TlsFree( opentype_tls_index );
420         WINSOCK_DeleteIData();
421         break;
422     }
423     return TRUE;
424 }
425
426 /***********************************************************************
427  *          convert_sockopt()
428  *
429  * Converts socket flags from Windows format.
430  * Return 1 if converted, 0 if not (error).
431  */
432 static int convert_sockopt(INT *level, INT *optname)
433 {
434   int i;
435   switch (*level)
436   {
437      case WS_SOL_SOCKET:
438         *level = SOL_SOCKET;
439         for(i=0; ws_sock_map[i][0]; i++)
440         {
441             if( ws_sock_map[i][0] == *optname )
442             {
443                 *optname = ws_sock_map[i][1];
444                 return 1;
445             }
446         }
447         FIXME("Unknown SOL_SOCKET optname 0x%x\n", *optname);
448         break;
449      case WS_IPPROTO_TCP:
450         *level = IPPROTO_TCP;
451         for(i=0; ws_tcp_map[i][0]; i++)
452         {
453             if ( ws_tcp_map[i][0] == *optname )
454             {
455                 *optname = ws_tcp_map[i][1];
456                 return 1;
457             }
458         }
459         FIXME("Unknown IPPROTO_TCP optname 0x%x\n", *optname);
460         break;
461      case WS_IPPROTO_IP:
462         *level = IPPROTO_IP;
463         for(i=0; ws_ip_map[i][0]; i++)
464         {
465             if (ws_ip_map[i][0] == *optname )
466             {
467                 *optname = ws_ip_map[i][1];
468                 return 1;
469             }
470         }
471         FIXME("Unknown IPPROTO_IP optname 0x%x\n", *optname);
472         break;
473      default: FIXME("Unimplemented or unknown socket level\n");
474   }
475   return 0;
476 }
477
478 static inline BOOL is_timeout_option( int optname )
479 {
480 #ifdef SO_RCVTIMEO
481     if (optname == SO_RCVTIMEO) return TRUE;
482 #endif
483 #ifdef SO_SNDTIMEO
484     if (optname == SO_SNDTIMEO) return TRUE;
485 #endif
486     return FALSE;
487 }
488
489 /* ----------------------------------- Per-thread info (or per-process?) */
490
491 static char *strdup_lower(const char *str)
492 {
493     int i;
494     char *ret = HeapAlloc( GetProcessHeap(), 0, strlen(str) + 1 );
495
496     if (ret)
497     {
498         for (i = 0; str[i]; i++) ret[i] = tolower(str[i]);
499         ret[i] = 0;
500     }
501     else SetLastError(WSAENOBUFS);
502     return ret;
503 }
504
505 static fd_set* fd_set_import( fd_set* fds, const WS_fd_set* wsfds, int access, int* highfd, int lfd[] )
506 {
507     /* translate Winsock fd set into local fd set */
508     if( wsfds )
509     {
510         int i;
511
512         FD_ZERO(fds);
513         for( i = 0; i < wsfds->fd_count; i++ )
514         {
515             int s = wsfds->fd_array[i];
516             int fd = get_sock_fd( s, access, NULL );
517             if (fd != -1)
518             {
519                 lfd[ i ] = fd;
520                 if( fd > *highfd ) *highfd = fd;
521                 FD_SET(fd, fds);
522             }
523             else lfd[ i ] = -1;
524         }
525         return fds;
526     }
527     return NULL;
528 }
529
530 inline static int sock_error_p(int s)
531 {
532     unsigned int optval, optlen;
533
534     optlen = sizeof(optval);
535     getsockopt(s, SOL_SOCKET, SO_ERROR, (void *) &optval, &optlen);
536     if (optval) WARN("\t[%i] error: %d\n", s, optval);
537     return optval != 0;
538 }
539
540 static int fd_set_export( const fd_set* fds, fd_set* exceptfds, WS_fd_set* wsfds, int lfd[] )
541 {
542     int num_err = 0;
543
544     /* translate local fd set into Winsock fd set, adding
545      * errors to exceptfds (only if app requested it) */
546
547     if( wsfds )
548     {
549         int i, j, count = wsfds->fd_count;
550
551         for( i = 0, j = 0; i < count; i++ )
552         {
553             int fd = lfd[i];
554             SOCKET s = wsfds->fd_array[i];
555             if (fd == -1) continue;
556             if( FD_ISSET(fd, fds) )
557             {
558                 if ( exceptfds && sock_error_p(fd) )
559                 {
560                     FD_SET(fd, exceptfds);
561                     num_err++;
562                 }
563                 else wsfds->fd_array[j++] = s;
564             }
565             release_sock_fd( s, fd );
566         }
567         wsfds->fd_count = j;
568     }
569     return num_err;
570 }
571
572 static void fd_set_unimport( WS_fd_set* wsfds, int lfd[] )
573 {
574     if ( wsfds )
575     {
576         int i;
577
578         for( i = 0; i < wsfds->fd_count; i++ )
579             if ( lfd[i] >= 0 ) release_sock_fd( wsfds->fd_array[i], lfd[i] );
580         wsfds->fd_count = 0;
581     }
582 }
583
584 /* utility: given an fd, will block until one of the events occurs */
585 static inline int do_block( int fd, int events )
586 {
587   struct pollfd pfd;
588
589   pfd.fd = fd;
590   pfd.events = events;
591   poll(&pfd, 1, -1);
592   return pfd.revents;
593 }
594
595
596 /* ----------------------------------- API -----
597  *
598  * Init / cleanup / error checking.
599  */
600
601 /***********************************************************************
602  *      WSAStartup              (WS2_32.115)
603  */
604 int WINAPI WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData)
605 {
606     TRACE("verReq=%x\n", wVersionRequested);
607
608     if (LOBYTE(wVersionRequested) < 1)
609         return WSAVERNOTSUPPORTED;
610
611     if (!lpWSAData) return WSAEINVAL;
612
613     num_startup++;
614
615     /* that's the whole of the negotiation for now */
616     lpWSAData->wVersion = wVersionRequested;
617     /* return winsock information */
618     lpWSAData->wHighVersion = 0x0202;
619     strcpy(lpWSAData->szDescription, "WinSock 2.0" );
620     strcpy(lpWSAData->szSystemStatus, "Running" );
621     lpWSAData->iMaxSockets = WS_MAX_SOCKETS_PER_PROCESS;
622     lpWSAData->iMaxUdpDg = WS_MAX_UDP_DATAGRAM;
623     /* don't do anything with lpWSAData->lpVendorInfo */
624     /* (some apps don't allocate the space for this field) */
625
626     TRACE("succeeded\n");
627     return 0;
628 }
629
630
631 /***********************************************************************
632  *      WSACleanup                      (WS2_32.116)
633  */
634 INT WINAPI WSACleanup(void)
635 {
636     if (num_startup)
637     {
638         if (--num_startup > 0) return 0;
639         WINSOCK_DeleteIData();
640         return 0;
641     }
642     SetLastError(WSANOTINITIALISED);
643     return SOCKET_ERROR;
644 }
645
646
647 /***********************************************************************
648  *      WSAGetLastError         (WINSOCK.111)
649  *      WSAGetLastError         (WS2_32.111)
650  */
651 INT WINAPI WSAGetLastError(void)
652 {
653         return GetLastError();
654 }
655
656 /***********************************************************************
657  *      WSASetLastError         (WS2_32.112)
658  */
659 void WINAPI WSASetLastError(INT iError) {
660     SetLastError(iError);
661 }
662
663 static struct WS_hostent *check_buffer_he(int size)
664 {
665     static int he_len;
666     if (he_buffer)
667     {
668         if (he_len >= size ) return he_buffer;
669         HeapFree( GetProcessHeap(), 0, he_buffer );
670     }
671     he_buffer = HeapAlloc( GetProcessHeap(), 0, (he_len = size) );
672     if (!he_buffer) SetLastError(WSAENOBUFS);
673     return he_buffer;
674 }
675
676 static struct WS_servent *check_buffer_se(int size)
677 {
678     static int se_len;
679     if (se_buffer)
680     {
681         if (se_len >= size ) return se_buffer;
682         HeapFree( GetProcessHeap(), 0, se_buffer );
683     }
684     se_buffer = HeapAlloc( GetProcessHeap(), 0, (se_len = size) );
685     if (!se_buffer) SetLastError(WSAENOBUFS);
686     return se_buffer;
687 }
688
689 static struct WS_protoent *check_buffer_pe(int size)
690 {
691     static int pe_len;
692     if (pe_buffer)
693     {
694         if (pe_len >= size ) return pe_buffer;
695         HeapFree( GetProcessHeap(), 0, pe_buffer );
696     }
697     pe_buffer = HeapAlloc( GetProcessHeap(), 0, (pe_len = size) );
698     if (!pe_buffer) SetLastError(WSAENOBUFS);
699     return pe_buffer;
700 }
701
702 /* ----------------------------------- i/o APIs */
703
704 #ifdef HAVE_IPX
705 #define SUPPORTED_PF(pf) ((pf)==WS_AF_INET || (pf)== WS_AF_IPX)
706 #else
707 #define SUPPORTED_PF(pf) ((pf)==WS_AF_INET)
708 #endif
709
710
711 /**********************************************************************/
712
713 /* Returns the converted address if successful, NULL if it was too small to
714  * start with. Note that the returned pointer may be the original pointer
715  * if no conversion is necessary.
716  */
717 static const struct sockaddr* ws_sockaddr_ws2u(const struct WS_sockaddr* wsaddr, int wsaddrlen, int *uaddrlen)
718 {
719     switch (wsaddr->sa_family)
720     {
721 #ifdef HAVE_IPX
722     case WS_AF_IPX:
723         {
724             struct WS_sockaddr_ipx* wsipx=(struct WS_sockaddr_ipx*)wsaddr;
725             struct sockaddr_ipx* uipx;
726
727             if (wsaddrlen<sizeof(struct WS_sockaddr_ipx))
728                 return NULL;
729
730             *uaddrlen=sizeof(struct sockaddr_ipx);
731             uipx=malloc(*uaddrlen);
732             memset(&uipx,0,sizeof(uipx));
733             uipx->sipx_family=AF_IPX;
734             uipx->sipx_port=wsipx->sa_socket;
735             /* copy sa_netnum and sa_nodenum to sipx_network and sipx_node
736              * in one go
737              */
738             memcpy(&uipx->sipx_network,wsipx->sa_netnum,sizeof(uipx->sipx_network)+sizeof(uipx->sipx_node));
739 #ifdef IPX_FRAME_NONE
740             uipx->sipx_type=IPX_FRAME_NONE;
741 #endif
742             return (const struct sockaddr*)uipx;
743         }
744 #endif
745
746     default:
747         if (wsaddrlen<sizeof(struct WS_sockaddr))
748             return NULL;
749
750         /* No conversion needed, just return the original address */
751         *uaddrlen=wsaddrlen;
752         return (const struct sockaddr*)wsaddr;
753     }
754     return NULL;
755 }
756
757 /* Allocates a Unix sockaddr structure to receive the data */
758 inline struct sockaddr* ws_sockaddr_alloc(const struct WS_sockaddr* wsaddr, int* wsaddrlen, int* uaddrlen)
759 {
760     if (wsaddr==NULL)
761     {
762       ERR( "WINE shouldn't pass a NULL wsaddr! Attempting to continue\n" );
763
764       /* This is not strictly the right thing to do. Hope it works however */
765       *uaddrlen=0;
766
767       return NULL;
768     }
769
770     if (*wsaddrlen==0)
771         *uaddrlen=0;
772     else
773         *uaddrlen=max(sizeof(struct sockaddr),*wsaddrlen);
774
775     return malloc(*uaddrlen);
776 }
777
778 /* Returns 0 if successful, -1 if the buffer is too small */
779 static int ws_sockaddr_u2ws(const struct sockaddr* uaddr, int uaddrlen, struct WS_sockaddr* wsaddr, int* wsaddrlen)
780 {
781     int res;
782
783     switch(uaddr->sa_family)
784     {
785 #ifdef HAVE_IPX
786     case AF_IPX:
787         {
788             struct sockaddr_ipx* uipx=(struct sockaddr_ipx*)uaddr;
789             struct WS_sockaddr_ipx* wsipx=(struct WS_sockaddr_ipx*)wsaddr;
790
791             res=-1;
792             switch (*wsaddrlen) /* how much can we copy? */
793             {
794             default:
795                 res=0; /* enough */
796                 *wsaddrlen=uaddrlen;
797                 wsipx->sa_socket=uipx->sipx_port;
798                 /* fall through */
799             case 13:
800             case 12:
801                 memcpy(wsipx->sa_nodenum,uipx->sipx_node,sizeof(wsipx->sa_nodenum));
802                 /* fall through */
803             case 11:
804             case 10:
805             case 9:
806             case 8:
807             case 7:
808             case 6:
809                 memcpy(wsipx->sa_netnum,&uipx->sipx_network,sizeof(wsipx->sa_netnum));
810                 /* fall through */
811             case 5:
812             case 4:
813             case 3:
814             case 2:
815                 wsipx->sa_family=WS_AF_IPX;
816                 /* fall through */
817             case 1:
818             case 0:
819                 /* way too small */
820                 break;
821             }
822         }
823         break;
824 #endif
825
826     default:
827         /* No conversion needed */
828         memcpy(wsaddr,uaddr,*wsaddrlen);
829         if (*wsaddrlen<uaddrlen) {
830             res=-1;
831         } else {
832             *wsaddrlen=uaddrlen;
833             res=0;
834         }
835     }
836     return res;
837 }
838
839 /* to be called to free the memory allocated by ws_sockaddr_ws2u or
840  * ws_sockaddr_alloc
841  */
842 inline void ws_sockaddr_free(const struct sockaddr* uaddr, const struct WS_sockaddr* wsaddr)
843 {
844     if (uaddr!=NULL && uaddr!=(const struct sockaddr*)wsaddr)
845         free((void*)uaddr);
846 }
847
848 /**************************************************************************
849  * Functions for handling overlapped I/O
850  **************************************************************************/
851
852 static DWORD ws2_async_get_count (const struct async_private *ovp)
853 {
854     return ovp->iosb->Information;
855 }
856
857 static void ws2_async_cleanup ( struct async_private *ap )
858 {
859     struct ws2_async *as = (struct ws2_async*) ap;
860
861     TRACE ( "as: %p uovl %p ovl %p\n", as, as->user_overlapped, as->async.iosb );
862     if ( !as->user_overlapped )
863     {
864 #if 0
865         /* FIXME: I don't think this is really used */
866         if ( as->overlapped->hEvent != INVALID_HANDLE_VALUE )
867             WSACloseEvent ( as->overlapped->hEvent  );
868 #endif
869         HeapFree ( GetProcessHeap(), 0, as->async.iosb );
870     }
871
872     if ( as->iovec )
873         HeapFree ( GetProcessHeap(), 0, as->iovec );
874
875     HeapFree ( GetProcessHeap(), 0, as );
876 }
877
878 static void CALLBACK ws2_async_call_completion (ULONG_PTR data)
879 {
880     ws2_async* as = (ws2_async*) data;
881
882     TRACE ("data: %p\n", as);
883
884     as->completion_func ( NtStatusToWSAError (as->async.iosb->u.Status),
885                           as->async.iosb->Information,
886                           as->user_overlapped,
887                           as->flags );
888     ws2_async_cleanup ( &as->async );
889 }
890
891 /***********************************************************************
892  *              WS2_make_async          (INTERNAL)
893  */
894
895 static void WS2_async_recv (async_private *as);
896 static void WS2_async_send (async_private *as);
897
898 inline static struct ws2_async*
899 WS2_make_async (SOCKET s, int fd, int type, struct iovec *iovec, DWORD dwBufferCount,
900                 LPDWORD lpFlags, struct WS_sockaddr *addr,
901                 LPINT addrlen, LPWSAOVERLAPPED lpOverlapped,
902                 LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
903 {
904     struct ws2_async *wsa = HeapAlloc ( GetProcessHeap(), 0, sizeof ( ws2_async ) );
905
906     TRACE ( "wsa %p\n", wsa );
907
908     if (!wsa)
909         return NULL;
910
911     wsa->async.ops = ( lpCompletionRoutine ? &ws2_async_ops : &ws2_nocomp_async_ops );
912     wsa->async.handle = (HANDLE) s;
913     wsa->async.fd = fd;
914     wsa->async.type = type;
915     switch (type)
916     {
917     case ASYNC_TYPE_READ:
918         wsa->flags = *lpFlags;
919         wsa->async.func = WS2_async_recv;
920         wsa->addrlen.ptr = addrlen;
921         break;
922     case ASYNC_TYPE_WRITE:
923         wsa->flags = 0;
924         wsa->async.func = WS2_async_send;
925         wsa->addrlen.val = *addrlen;
926         break;
927     default:
928         ERR ("Invalid async type: %d\n", type);
929     }
930     wsa->user_overlapped = lpOverlapped;
931     wsa->completion_func = lpCompletionRoutine;
932     wsa->iovec = iovec;
933     wsa->n_iovecs = dwBufferCount;
934     wsa->addr = addr;
935
936     if ( lpOverlapped )
937     {
938         wsa->async.iosb = (IO_STATUS_BLOCK*)lpOverlapped;
939         wsa->async.event = ( lpCompletionRoutine ? INVALID_HANDLE_VALUE : lpOverlapped->hEvent );
940     }
941     else
942     {
943         wsa->async.iosb = HeapAlloc ( GetProcessHeap(), 0,
944                                       sizeof (IO_STATUS_BLOCK) );
945         if ( !wsa->async.iosb )
946             goto error;
947         wsa->async.event = INVALID_HANDLE_VALUE;
948     }
949
950     wsa->async.iosb->Information = 0;
951     TRACE ( "wsa %p, ops %p, h %p, ev %p, fd %d, func %p, iosb %p, uov %p, cfunc %p\n",
952             wsa, wsa->async.ops, wsa->async.handle, wsa->async.event, wsa->async.fd, wsa->async.func,
953             wsa->async.iosb, wsa->user_overlapped, wsa->completion_func );
954
955     return wsa;
956
957 error:
958     TRACE ("Error\n");
959     HeapFree ( GetProcessHeap(), 0, wsa );
960     return NULL;
961 }
962
963 /***********************************************************************
964  *              WS2_recv                (INTERNAL)
965  *
966  * Work horse for both synchronous and asynchronous recv() operations.
967  */
968 static int WS2_recv ( int fd, struct iovec* iov, int count,
969                       struct WS_sockaddr *lpFrom, LPINT lpFromlen,
970                       LPDWORD lpFlags )
971 {
972     struct msghdr hdr;
973     int n;
974     TRACE ( "fd %d, iovec %p, count %d addr %s, len %p, flags %lx\n",
975             fd, iov, count, debugstr_sockaddr(lpFrom), lpFromlen, *lpFlags);
976
977     hdr.msg_name = NULL;
978
979     if ( lpFrom )
980     {
981         hdr.msg_namelen = *lpFromlen;
982         hdr.msg_name = ws_sockaddr_alloc ( lpFrom, lpFromlen, &hdr.msg_namelen );
983         if ( !hdr.msg_name )
984         {
985             WSASetLastError ( WSAEFAULT );
986             n = -1;
987             goto out;
988         }
989     }
990     else
991         hdr.msg_namelen = 0;
992
993     hdr.msg_iov = iov;
994     hdr.msg_iovlen = count;
995 #ifdef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
996     hdr.msg_accrights = NULL;
997     hdr.msg_accrightslen = 0;
998 #else
999     hdr.msg_control = NULL;
1000     hdr.msg_controllen = 0;
1001     hdr.msg_flags = 0;
1002 #endif
1003
1004     if ( (n = recvmsg (fd, &hdr, *lpFlags)) == -1 )
1005     {
1006         TRACE ( "recvmsg error %d\n", errno);
1007         goto out;
1008     }
1009
1010     if ( lpFrom &&
1011          ws_sockaddr_u2ws ( hdr.msg_name, hdr.msg_namelen,
1012                             lpFrom, lpFromlen ) != 0 )
1013     {
1014         /* The from buffer was too small, but we read the data
1015          * anyway. Is that really bad?
1016          */
1017         WSASetLastError ( WSAEFAULT );
1018         WARN ( "Address buffer too small\n" );
1019     }
1020
1021 out:
1022
1023     ws_sockaddr_free ( hdr.msg_name, lpFrom );
1024     TRACE ("-> %d\n", n);
1025     return n;
1026 }
1027
1028 /***********************************************************************
1029  *              WS2_async_recv          (INTERNAL)
1030  *
1031  * Handler for overlapped recv() operations.
1032  */
1033 static void WS2_async_recv ( async_private *as )
1034 {
1035     ws2_async* wsa = (ws2_async*) as;
1036     int result, err;
1037
1038     TRACE ( "async %p\n", wsa );
1039
1040     if ( wsa->async.iosb->u.Status != STATUS_PENDING )
1041     {
1042         TRACE ( "status: %ld\n", wsa->async.iosb->u.Status );
1043         return;
1044     }
1045
1046     result = WS2_recv ( wsa->async.fd, wsa->iovec, wsa->n_iovecs,
1047                         wsa->addr, wsa->addrlen.ptr, &wsa->flags );
1048
1049     if (result >= 0)
1050     {
1051         wsa->async.iosb->u.Status = STATUS_SUCCESS;
1052         wsa->async.iosb->Information = result;
1053         TRACE ( "received %d bytes\n", result );
1054         _enable_event ( wsa->async.handle, FD_READ, 0, 0 );
1055         return;
1056     }
1057
1058     err = wsaErrno ();
1059     if ( err == WSAEINTR || err == WSAEWOULDBLOCK )  /* errno: EINTR / EAGAIN */
1060     {
1061         wsa->async.iosb->u.Status = STATUS_PENDING;
1062         _enable_event ( wsa->async.handle, FD_READ, 0, 0 );
1063         TRACE ( "still pending\n" );
1064     }
1065     else
1066     {
1067         wsa->async.iosb->u.Status = err;
1068         TRACE ( "Error: %x\n", err );
1069     }
1070 }
1071
1072 /***********************************************************************
1073  *              WS2_send                (INTERNAL)
1074  *
1075  * Work horse for both synchronous and asynchronous send() operations.
1076  */
1077 static int WS2_send ( int fd, struct iovec* iov, int count,
1078                       const struct WS_sockaddr *to, INT tolen, DWORD dwFlags )
1079 {
1080     struct msghdr hdr;
1081     int n = -1;
1082     TRACE ( "fd %d, iovec %p, count %d addr %s, len %d, flags %lx\n",
1083             fd, iov, count, debugstr_sockaddr(to), tolen, dwFlags);
1084
1085     hdr.msg_name = NULL;
1086
1087     if ( to )
1088     {
1089         hdr.msg_name = (struct sockaddr*) ws_sockaddr_ws2u ( to, tolen, &hdr.msg_namelen );
1090         if ( !hdr.msg_name )
1091         {
1092             WSASetLastError ( WSAEFAULT );
1093             goto out;
1094         }
1095     }
1096     else
1097         hdr.msg_namelen = 0;
1098
1099     hdr.msg_iov = iov;
1100     hdr.msg_iovlen = count;
1101 #ifdef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
1102     hdr.msg_accrights = NULL;
1103     hdr.msg_accrightslen = 0;
1104 #else
1105     hdr.msg_control = NULL;
1106     hdr.msg_controllen = 0;
1107     hdr.msg_flags = 0;
1108 #endif
1109
1110     n = sendmsg (fd, &hdr, dwFlags);
1111
1112 out:
1113     ws_sockaddr_free ( hdr.msg_name, to );
1114     return n;
1115 }
1116
1117 /***********************************************************************
1118  *              WS2_async_send          (INTERNAL)
1119  *
1120  * Handler for overlapped send() operations.
1121  */
1122 static void WS2_async_send ( async_private *as )
1123 {
1124     ws2_async* wsa = (ws2_async*) as;
1125     int result, err;
1126
1127     TRACE ( "async %p\n", wsa );
1128
1129     if ( wsa->async.iosb->u.Status != STATUS_PENDING )
1130     {
1131         TRACE ( "status: %ld\n", wsa->async.iosb->u.Status );
1132         return;
1133     }
1134
1135     result = WS2_send ( wsa->async.fd, wsa->iovec, wsa->n_iovecs,
1136                         wsa->addr, wsa->addrlen.val, wsa->flags );
1137
1138     if (result >= 0)
1139     {
1140         wsa->async.iosb->u.Status = STATUS_SUCCESS;
1141         wsa->async.iosb->Information = result;
1142         TRACE ( "sent %d bytes\n", result );
1143         _enable_event ( wsa->async.handle, FD_WRITE, 0, 0 );
1144         return;
1145     }
1146
1147     err = wsaErrno ();
1148     if ( err == WSAEINTR )
1149     {
1150         wsa->async.iosb->u.Status = STATUS_PENDING;
1151         _enable_event ( wsa->async.handle, FD_WRITE, 0, 0 );
1152         TRACE ( "still pending\n" );
1153     }
1154     else
1155     {
1156         /* We set the status to a winsock error code and check for that
1157            later in NtStatusToWSAError () */
1158         wsa->async.iosb->u.Status = err;
1159         TRACE ( "Error: %x\n", err );
1160     }
1161 }
1162
1163 /***********************************************************************
1164  *              WS2_async_shutdown      (INTERNAL)
1165  *
1166  * Handler for shutdown() operations on overlapped sockets.
1167  */
1168 static void WS2_async_shutdown ( async_private *as )
1169 {
1170     ws2_async* wsa = (ws2_async*) as;
1171     int err = 1;
1172
1173     TRACE ( "async %p %d\n", wsa, wsa->async.type );
1174     switch ( wsa->async.type )
1175     {
1176     case ASYNC_TYPE_READ:
1177         err = shutdown ( wsa->async.fd, 0 );
1178         break;
1179     case ASYNC_TYPE_WRITE:
1180         err = shutdown ( wsa->async.fd, 1 );
1181         break;
1182     default:
1183         ERR ("invalid type: %d\n", wsa->async.type );
1184     }
1185
1186     if ( err )
1187         wsa->async.iosb->u.Status = wsaErrno ();
1188     else
1189         wsa->async.iosb->u.Status = STATUS_SUCCESS;
1190 }
1191
1192 /***********************************************************************
1193  *  WS2_register_async_shutdown         (INTERNAL)
1194  *
1195  * Helper function for WS_shutdown() on overlapped sockets.
1196  */
1197 static int WS2_register_async_shutdown ( SOCKET s, int fd, int type )
1198 {
1199     struct ws2_async *wsa;
1200     int ret, err = WSAEFAULT;
1201     DWORD dwflags = 0;
1202     int len = 0;
1203     LPWSAOVERLAPPED ovl = HeapAlloc (GetProcessHeap(), 0, sizeof ( WSAOVERLAPPED ));
1204
1205     TRACE ("s %d fd %d type %d\n", s, fd, type);
1206     if (!ovl)
1207         goto out;
1208
1209     ovl->hEvent = WSACreateEvent ();
1210     if ( ovl->hEvent == WSA_INVALID_EVENT  )
1211         goto out_free;
1212
1213     wsa = WS2_make_async ( s, fd, type, NULL, 0,
1214                            &dwflags, NULL, &len, ovl, NULL );
1215     if ( !wsa )
1216         goto out_close;
1217
1218     /* Hack: this will cause ws2_async_cleanup() to free the overlapped structure */
1219     wsa->user_overlapped = NULL;
1220     wsa->async.func = WS2_async_shutdown;
1221     if ( (ret = register_new_async ( &wsa->async )) )
1222     {
1223         err = NtStatusToWSAError ( ret );
1224         goto out;
1225     }
1226     /* Try immediate completion */
1227     while ( WaitForSingleObjectEx ( ovl->hEvent, 0, TRUE ) == STATUS_USER_APC );
1228     return 0;
1229
1230 out_close:
1231     WSACloseEvent ( ovl->hEvent );
1232 out_free:
1233     HeapFree ( GetProcessHeap(), 0, ovl );
1234 out:
1235     return err;
1236 }
1237
1238 /***********************************************************************
1239  *              accept          (WS2_32.1)
1240  */
1241 SOCKET WINAPI WS_accept(SOCKET s, struct WS_sockaddr *addr,
1242                                  int *addrlen32)
1243 {
1244     SOCKET as;
1245
1246     TRACE("socket %04x\n", s );
1247     if (_is_blocking(s))
1248     {
1249         int fd = get_sock_fd( s, GENERIC_READ, NULL );
1250         if (fd == -1) return INVALID_SOCKET;
1251         /* block here */
1252         do_block(fd, POLLIN);
1253         _sync_sock_state(s); /* let wineserver notice connection */
1254         release_sock_fd( s, fd );
1255         /* retrieve any error codes from it */
1256         SetLastError(_get_sock_error(s, FD_ACCEPT_BIT));
1257         /* FIXME: care about the error? */
1258     }
1259     SERVER_START_REQ( accept_socket )
1260     {
1261         req->lhandle = SOCKET2HANDLE(s);
1262         req->access  = GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE;
1263         req->inherit = TRUE;
1264         set_error( wine_server_call( req ) );
1265         as = HANDLE2SOCKET( reply->handle );
1266     }
1267     SERVER_END_REQ;
1268     if (as)
1269     {
1270         if (addr) WS_getpeername(as, addr, addrlen32);
1271         return as;
1272     }
1273     return INVALID_SOCKET;
1274 }
1275
1276 /***********************************************************************
1277  *              bind                    (WS2_32.2)
1278  */
1279 int WINAPI WS_bind(SOCKET s, const struct WS_sockaddr* name, int namelen)
1280 {
1281     int fd = get_sock_fd( s, 0, NULL );
1282     int res = SOCKET_ERROR;
1283
1284     TRACE("socket %04x, ptr %p %s, length %d\n", s, name, debugstr_sockaddr(name), namelen);
1285
1286     if (fd != -1)
1287     {
1288         if (!name || !SUPPORTED_PF(name->sa_family))
1289         {
1290             SetLastError(WSAEAFNOSUPPORT);
1291         }
1292         else
1293         {
1294             const struct sockaddr* uaddr;
1295             int uaddrlen;
1296
1297             uaddr=ws_sockaddr_ws2u(name,namelen,&uaddrlen);
1298             if (uaddr == NULL)
1299             {
1300                 SetLastError(WSAEFAULT);
1301             }
1302             else
1303             {
1304                 int on = 1;
1305                 /* The game GrandPrixLegends binds more than one time, but does
1306                  * not do a SO_REUSEADDR - Stevens says this is ok */
1307                 TRACE( "Setting WS_SO_REUSEADDR on socket before we bind it\n");
1308                 WS_setsockopt( s, WS_SOL_SOCKET, WS_SO_REUSEADDR, (char*)&on, sizeof(on) );
1309
1310                 if (bind(fd, uaddr, uaddrlen) < 0)
1311                 {
1312                     int loc_errno = errno;
1313                     WARN("\tfailure - errno = %i\n", errno);
1314                     errno = loc_errno;
1315                     switch (errno)
1316                     {
1317                     case EBADF:
1318                         SetLastError(WSAENOTSOCK);
1319                         break;
1320                     case EADDRNOTAVAIL:
1321                         SetLastError(WSAEINVAL);
1322                         break;
1323                     default:
1324                         SetLastError(wsaErrno());
1325                         break;
1326                     }
1327                 }
1328                 else
1329                 {
1330                     res=0; /* success */
1331                 }
1332                 ws_sockaddr_free(uaddr,name);
1333             }
1334         }
1335         release_sock_fd( s, fd );
1336     }
1337     return res;
1338 }
1339
1340 /***********************************************************************
1341  *              closesocket             (WS2_32.3)
1342  */
1343 int WINAPI WS_closesocket(SOCKET s)
1344 {
1345     TRACE("socket %08x\n", s);
1346     if (CloseHandle(SOCKET2HANDLE(s))) return 0;
1347     return SOCKET_ERROR;
1348 }
1349
1350 /***********************************************************************
1351  *              connect         (WS2_32.4)
1352  */
1353 int WINAPI WS_connect(SOCKET s, const struct WS_sockaddr* name, int namelen)
1354 {
1355     int fd = get_sock_fd( s, GENERIC_READ, NULL );
1356
1357     TRACE("socket %04x, ptr %p %s, length %d\n", s, name, debugstr_sockaddr(name), namelen);
1358
1359     if (fd != -1)
1360     {
1361         const struct sockaddr* uaddr;
1362         int uaddrlen;
1363
1364         uaddr=ws_sockaddr_ws2u(name,namelen,&uaddrlen);
1365         if (uaddr == NULL)
1366         {
1367             SetLastError(WSAEFAULT);
1368         }
1369         else
1370         {
1371             int rc;
1372
1373             rc=connect(fd, uaddr, uaddrlen);
1374             ws_sockaddr_free(uaddr,name);
1375             if (rc == 0)
1376                 goto connect_success;
1377         }
1378
1379         if (errno == EINPROGRESS)
1380         {
1381             /* tell wineserver that a connection is in progress */
1382             _enable_event(SOCKET2HANDLE(s), FD_CONNECT|FD_READ|FD_WRITE,
1383                           FD_CONNECT|FD_READ|FD_WRITE,
1384                           FD_WINE_CONNECTED|FD_WINE_LISTENING);
1385             if (_is_blocking(s))
1386             {
1387                 int result;
1388                 /* block here */
1389                 do_block(fd, POLLIN | POLLOUT );
1390                 _sync_sock_state(s); /* let wineserver notice connection */
1391                 /* retrieve any error codes from it */
1392                 result = _get_sock_error(s, FD_CONNECT_BIT);
1393                 if (result)
1394                     SetLastError(result);
1395                 else
1396                 {
1397                     goto connect_success;
1398                 }
1399             }
1400             else
1401             {
1402                 SetLastError(WSAEWOULDBLOCK);
1403             }
1404         }
1405         else
1406         {
1407             SetLastError(wsaErrno());
1408         }
1409         release_sock_fd( s, fd );
1410     }
1411     return SOCKET_ERROR;
1412
1413 connect_success:
1414     release_sock_fd( s, fd );
1415     _enable_event(SOCKET2HANDLE(s), FD_CONNECT|FD_READ|FD_WRITE,
1416                   FD_WINE_CONNECTED|FD_READ|FD_WRITE,
1417                   FD_CONNECT|FD_WINE_LISTENING);
1418     return 0;
1419 }
1420
1421 /***********************************************************************
1422  *              WSAConnect             (WS2_32.30)
1423  */
1424 int WINAPI WSAConnect ( SOCKET s, const struct WS_sockaddr* name, int namelen,
1425                         LPWSABUF lpCallerData, LPWSABUF lpCalleeData,
1426                         LPQOS lpSQOS, LPQOS lpGQOS )
1427 {
1428     if ( lpCallerData || lpCalleeData || lpSQOS || lpGQOS )
1429         FIXME ("unsupported parameters!\n");
1430     return WS_connect ( s, name, namelen );
1431 }
1432
1433
1434 /***********************************************************************
1435  *              getpeername             (WS2_32.5)
1436  */
1437 int WINAPI WS_getpeername(SOCKET s, struct WS_sockaddr *name, int *namelen)
1438 {
1439     int fd;
1440     int res;
1441
1442     TRACE("socket: %04x, ptr %p, len %8x\n", s, name, *namelen);
1443
1444     /* Check if what we've received is valid. Should we use IsBadReadPtr? */
1445     if( (name == NULL) || (namelen == NULL) )
1446     {
1447         SetLastError( WSAEFAULT );
1448         return SOCKET_ERROR;
1449     }
1450
1451     fd = get_sock_fd( s, 0, NULL );
1452     res = SOCKET_ERROR;
1453
1454     if (fd != -1)
1455     {
1456         struct sockaddr* uaddr;
1457         int uaddrlen;
1458
1459         uaddr=ws_sockaddr_alloc(name,namelen,&uaddrlen);
1460         if (getpeername(fd, uaddr, &uaddrlen) != 0)
1461         {
1462             SetLastError(wsaErrno());
1463         }
1464         else if (ws_sockaddr_u2ws(uaddr,uaddrlen,name,namelen) != 0)
1465         {
1466             /* The buffer was too small */
1467             SetLastError(WSAEFAULT);
1468         }
1469         else
1470         {
1471             res=0;
1472         }
1473         ws_sockaddr_free(uaddr,name);
1474         release_sock_fd( s, fd );
1475     }
1476     return res;
1477 }
1478
1479 /***********************************************************************
1480  *              getsockname             (WS2_32.6)
1481  */
1482 int WINAPI WS_getsockname(SOCKET s, struct WS_sockaddr *name, int *namelen)
1483 {
1484     int fd;
1485     int res;
1486
1487     TRACE("socket: %04x, ptr %p, len %8x\n", s, name, *namelen);
1488
1489     /* Check if what we've received is valid. Should we use IsBadReadPtr? */
1490     if( (name == NULL) || (namelen == NULL) )
1491     {
1492         SetLastError( WSAEFAULT );
1493         return SOCKET_ERROR;
1494     }
1495
1496     fd = get_sock_fd( s, 0, NULL );
1497     res = SOCKET_ERROR;
1498
1499     if (fd != -1)
1500     {
1501         struct sockaddr* uaddr;
1502         int uaddrlen;
1503
1504         uaddr=ws_sockaddr_alloc(name,namelen,&uaddrlen);
1505         if (getsockname(fd, uaddr, &uaddrlen) != 0)
1506         {
1507             SetLastError(wsaErrno());
1508         }
1509         else if (ws_sockaddr_u2ws(uaddr,uaddrlen,name,namelen) != 0)
1510         {
1511             /* The buffer was too small */
1512             SetLastError(WSAEFAULT);
1513         }
1514         else
1515         {
1516             res=0;
1517         }
1518         release_sock_fd( s, fd );
1519     }
1520     return res;
1521 }
1522
1523 /***********************************************************************
1524  *              getsockopt              (WS2_32.7)
1525  */
1526 INT WINAPI WS_getsockopt(SOCKET s, INT level,
1527                                   INT optname, char *optval, INT *optlen)
1528 {
1529     int fd;
1530
1531     TRACE("socket: %04x, level 0x%x, name 0x%x, ptr %8x, len %d\n", s, level,
1532           (int) optname, (int) optval, (int) *optlen);
1533     /* SO_OPENTYPE does not require a valid socket handle. */
1534     if (level == WS_SOL_SOCKET && optname == WS_SO_OPENTYPE)
1535     {
1536         if (!optlen || *optlen < sizeof(int) || !optval)
1537         {
1538             SetLastError(WSAEFAULT);
1539             return SOCKET_ERROR;
1540         }
1541         *(int *)optval = (int)TlsGetValue( opentype_tls_index );
1542         *optlen = sizeof(int);
1543         TRACE("getting global SO_OPENTYPE = 0x%x\n", *((int*)optval) );
1544         return 0;
1545     }
1546
1547     fd = get_sock_fd( s, 0, NULL );
1548     if (fd != -1)
1549     {
1550         if (!convert_sockopt(&level, &optname)) {
1551             SetLastError(WSAENOPROTOOPT);       /* Unknown option */
1552         } else {
1553             if (getsockopt(fd, (int) level, optname, optval, optlen) == 0 )
1554             {
1555                 release_sock_fd( s, fd );
1556                 return 0;
1557             }
1558             SetLastError((errno == EBADF) ? WSAENOTSOCK : wsaErrno());
1559         }
1560         release_sock_fd( s, fd );
1561     }
1562     return SOCKET_ERROR;
1563 }
1564
1565
1566 /***********************************************************************
1567  *              htonl                   (WINSOCK.8)
1568  *              htonl                   (WS2_32.8)
1569  */
1570 u_long WINAPI WS_htonl(u_long hostlong)
1571 {
1572     return htonl(hostlong);
1573 }
1574
1575
1576 /***********************************************************************
1577  *              htons                   (WINSOCK.9)
1578  *              htons                   (WS2_32.9)
1579  */
1580 u_short WINAPI WS_htons(u_short hostshort)
1581 {
1582     return htons(hostshort);
1583 }
1584
1585 /***********************************************************************
1586  *              WSAHtonl                (WS2_32.46)
1587  */
1588 int WINAPI WSAHtonl(SOCKET s, u_long hostlong, u_long *lpnetlong)
1589 {
1590     FIXME("stub.\n");
1591     return INVALID_SOCKET;
1592 }
1593
1594 /***********************************************************************
1595  *              WSAHtons                (WS2_32.47)
1596  */
1597 int WINAPI WSAHtons(SOCKET s, u_short hostshort, u_short *lpnetshort)
1598 {
1599     FIXME("stub.\n");
1600     return INVALID_SOCKET;
1601 }
1602
1603
1604 /***********************************************************************
1605  *              inet_addr               (WINSOCK.10)
1606  *              inet_addr               (WS2_32.11)
1607  */
1608 u_long WINAPI WS_inet_addr(const char *cp)
1609 {
1610     return inet_addr(cp);
1611 }
1612
1613
1614 /***********************************************************************
1615  *              ntohl                   (WINSOCK.14)
1616  *              ntohl                   (WS2_32.14)
1617  */
1618 u_long WINAPI WS_ntohl(u_long netlong)
1619 {
1620     return ntohl(netlong);
1621 }
1622
1623
1624 /***********************************************************************
1625  *              ntohs                   (WINSOCK.15)
1626  *              ntohs                   (WS2_32.15)
1627  */
1628 u_short WINAPI WS_ntohs(u_short netshort)
1629 {
1630     return ntohs(netshort);
1631 }
1632
1633
1634 /***********************************************************************
1635  *              inet_ntoa               (WS2_32.12)
1636  */
1637 char* WINAPI WS_inet_ntoa(struct WS_in_addr in)
1638 {
1639   /* use "buffer for dummies" here because some applications have
1640    * propensity to decode addresses in ws_hostent structure without
1641    * saving them first...
1642    */
1643     static char dbuffer[16]; /* Yes, 16: 4*3 digits + 3 '.' + 1 '\0' */
1644
1645     char* s = inet_ntoa(*((struct in_addr*)&in));
1646     if( s )
1647     {
1648         strcpy(dbuffer, s);
1649         return dbuffer;
1650     }
1651     SetLastError(wsaErrno());
1652     return NULL;
1653 }
1654
1655 /**********************************************************************
1656  *              WSAIoctl                (WS2_32.50)
1657  *
1658  *
1659  *   FIXME:  Only SIO_GET_INTERFACE_LIST option implemented.
1660  */
1661 INT WINAPI WSAIoctl (SOCKET s,
1662                      DWORD   dwIoControlCode,
1663                      LPVOID  lpvInBuffer,
1664                      DWORD   cbInBuffer,
1665                      LPVOID  lpbOutBuffer,
1666                      DWORD   cbOutBuffer,
1667                      LPDWORD lpcbBytesReturned,
1668                      LPWSAOVERLAPPED lpOverlapped,
1669                      LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
1670 {
1671    int fd = get_sock_fd( s, 0, NULL );
1672
1673    if (fd == -1) return SOCKET_ERROR;
1674
1675    switch( dwIoControlCode )
1676    {
1677    case SIO_GET_INTERFACE_LIST:
1678        {
1679            INTERFACE_INFO* intArray = (INTERFACE_INFO*)lpbOutBuffer;
1680            DWORD size, numInt, apiReturn;
1681
1682            TRACE ("-> SIO_GET_INTERFACE_LIST request\n");
1683
1684            if (!lpbOutBuffer)
1685            {
1686                release_sock_fd( s, fd );
1687                WSASetLastError(WSAEFAULT);
1688                return SOCKET_ERROR;
1689            }
1690            if (!lpcbBytesReturned)
1691            {
1692                release_sock_fd( s, fd );
1693                WSASetLastError(WSAEFAULT);
1694                return SOCKET_ERROR;
1695            }
1696
1697            apiReturn = GetAdaptersInfo(NULL, &size);
1698            if (apiReturn == ERROR_NO_DATA)
1699            {
1700                numInt = 0;
1701            }
1702            else if (apiReturn == ERROR_BUFFER_OVERFLOW)
1703            {
1704                PIP_ADAPTER_INFO table = (PIP_ADAPTER_INFO)HeapAlloc(GetProcessHeap(),0,size);
1705
1706                if (table)
1707                {
1708                   if (GetAdaptersInfo(table, &size) == NO_ERROR)
1709                   {
1710                      PIP_ADAPTER_INFO ptr;
1711
1712                      if (size > cbOutBuffer)
1713                      {
1714                         HeapFree(GetProcessHeap(),0,table);
1715                         release_sock_fd( s, fd );
1716                         WSASetLastError(WSAEFAULT);
1717                         return (SOCKET_ERROR);
1718                      }
1719                      for (ptr = table, numInt = 0; ptr;
1720                       ptr = ptr->Next, intArray++, numInt++)
1721                      {
1722                         unsigned int addr, mask, bcast;
1723                         struct ifreq ifInfo;
1724
1725                         /* Socket Status Flags */
1726                         strncpy(ifInfo.ifr_name, ptr->AdapterName, IFNAMSIZ);
1727                         ifInfo.ifr_name[IFNAMSIZ-1] = '\0';
1728                         if (ioctl(fd, SIOCGIFFLAGS, &ifInfo) < 0)
1729                         {
1730                            ERR ("Error obtaining status flags for socket!\n");
1731                            HeapFree(GetProcessHeap(),0,table);
1732                            release_sock_fd( s, fd );
1733                            WSASetLastError(WSAEINVAL);
1734                            return (SOCKET_ERROR);
1735                         }
1736                         else
1737                         {
1738                            /* set flags; the values of IFF_* are not the same
1739                               under Linux and Windows, therefore must generate
1740                               new flags */
1741                            intArray->iiFlags = 0;
1742                            if (ifInfo.ifr_flags & IFF_BROADCAST)
1743                               intArray->iiFlags |= WS_IFF_BROADCAST;
1744 #ifdef IFF_POINTOPOINT
1745                            if (ifInfo.ifr_flags & IFF_POINTOPOINT)
1746                               intArray->iiFlags |= WS_IFF_POINTTOPOINT;
1747 #endif
1748                            if (ifInfo.ifr_flags & IFF_LOOPBACK)
1749                               intArray->iiFlags |= WS_IFF_LOOPBACK;
1750                            if (ifInfo.ifr_flags & IFF_UP)
1751                               intArray->iiFlags |= WS_IFF_UP;
1752                         }
1753
1754                         addr = inet_addr(ptr->IpAddressList.IpAddress.String);
1755                         mask = inet_addr(ptr->IpAddressList.IpMask.String);
1756                         bcast = addr | (addr & !mask);
1757                         intArray->iiAddress.AddressIn.sin_family = AF_INET;
1758                         intArray->iiAddress.AddressIn.sin_port = 0;
1759                         intArray->iiAddress.AddressIn.sin_addr.WS_s_addr =
1760                          addr;
1761                         intArray->iiNetmask.AddressIn.sin_family = AF_INET;
1762                         intArray->iiNetmask.AddressIn.sin_port = 0;
1763                         intArray->iiNetmask.AddressIn.sin_addr.WS_s_addr =
1764                          mask;
1765                         intArray->iiBroadcastAddress.AddressIn.sin_family =
1766                          AF_INET;
1767                         intArray->iiBroadcastAddress.AddressIn.sin_port = 0;
1768                         intArray->iiBroadcastAddress.AddressIn.sin_addr.
1769                          WS_s_addr = bcast;
1770                      }
1771                   }
1772                   else
1773                   {
1774                      ERR ("Unable to get interface table!\n");
1775                      release_sock_fd( s, fd );
1776                      HeapFree(GetProcessHeap(),0,table);
1777                      WSASetLastError(WSAEINVAL);
1778                      return (SOCKET_ERROR);
1779                   }
1780                   HeapFree(GetProcessHeap(),0,table);
1781                }
1782                else
1783                {
1784                   release_sock_fd( s, fd );
1785                   WSASetLastError(WSAEINVAL);
1786                   return (SOCKET_ERROR);
1787                }
1788            }
1789            else
1790            {
1791                ERR ("Unable to get interface table!\n");
1792                release_sock_fd( s, fd );
1793                WSASetLastError(WSAEINVAL);
1794                return (SOCKET_ERROR);
1795            }
1796            /* Calculate the size of the array being returned */
1797            *lpcbBytesReturned = sizeof(INTERFACE_INFO) * numInt;
1798            break;
1799        }
1800
1801    default:
1802        WARN("\tunsupported WS_IOCTL cmd (%08lx)\n", dwIoControlCode);
1803        release_sock_fd( s, fd );
1804        WSASetLastError(WSAEOPNOTSUPP);
1805        return (SOCKET_ERROR);
1806    }
1807
1808    /* Function executed with no errors */
1809    release_sock_fd( s, fd );
1810    return (0);
1811 }
1812
1813
1814 /***********************************************************************
1815  *              ioctlsocket             (WS2_32.10)
1816  */
1817 int WINAPI WS_ioctlsocket(SOCKET s, long cmd, u_long *argp)
1818 {
1819     int fd;
1820     long newcmd  = cmd;
1821
1822     TRACE("socket %04x, cmd %08lx, ptr %p\n", s, cmd, argp);
1823
1824     switch( cmd )
1825     {
1826     case WS_FIONREAD:
1827         newcmd=FIONREAD;
1828         break;
1829
1830     case WS_FIONBIO:
1831         newcmd=FIONBIO;
1832         if( _get_sock_mask(s) )
1833         {
1834             /* AsyncSelect()'ed sockets are always nonblocking */
1835             if (*argp) return 0;
1836             SetLastError(WSAEINVAL);
1837             return SOCKET_ERROR;
1838         }
1839         if (*argp)
1840             _enable_event(SOCKET2HANDLE(s), 0, FD_WINE_NONBLOCKING, 0);
1841         else
1842             _enable_event(SOCKET2HANDLE(s), 0, 0, FD_WINE_NONBLOCKING);
1843         return 0;
1844
1845     case WS_SIOCATMARK:
1846         newcmd=SIOCATMARK;
1847         break;
1848
1849     case WS__IOW('f',125,u_long):
1850         WARN("Warning: WS1.1 shouldn't be using async I/O\n");
1851         SetLastError(WSAEINVAL);
1852         return SOCKET_ERROR;
1853
1854     case SIOCGIFBRDADDR:
1855     case SIOCGIFNETMASK:
1856     case SIOCGIFADDR:
1857         /* These don't need any special handling.  They are used by
1858            WsControl, and are here to suppress an unecessary warning. */
1859         break;
1860
1861     default:
1862         /* Netscape tries hard to use bogus ioctl 0x667e */
1863         WARN("\tunknown WS_IOCTL cmd (%08lx)\n", cmd);
1864         break;
1865     }
1866
1867     fd = get_sock_fd( s, 0, NULL );
1868     if (fd != -1)
1869     {
1870         if( ioctl(fd, newcmd, (char*)argp ) == 0 )
1871         {
1872             release_sock_fd( s, fd );
1873             return 0;
1874         }
1875         SetLastError((errno == EBADF) ? WSAENOTSOCK : wsaErrno());
1876         release_sock_fd( s, fd );
1877     }
1878     return SOCKET_ERROR;
1879 }
1880
1881 /***********************************************************************
1882  *              listen          (WS2_32.13)
1883  */
1884 int WINAPI WS_listen(SOCKET s, int backlog)
1885 {
1886     int fd = get_sock_fd( s, GENERIC_READ, NULL );
1887
1888     TRACE("socket %04x, backlog %d\n", s, backlog);
1889     if (fd != -1)
1890     {
1891         if (listen(fd, backlog) == 0)
1892         {
1893             release_sock_fd( s, fd );
1894             _enable_event(SOCKET2HANDLE(s), FD_ACCEPT,
1895                           FD_WINE_LISTENING,
1896                           FD_CONNECT|FD_WINE_CONNECTED);
1897             return 0;
1898         }
1899         SetLastError(wsaErrno());
1900         release_sock_fd( s, fd );
1901     }
1902     return SOCKET_ERROR;
1903 }
1904
1905 /***********************************************************************
1906  *              recv                    (WS2_32.16)
1907  */
1908 int WINAPI WS_recv(SOCKET s, char *buf, int len, int flags)
1909 {
1910     DWORD n, dwFlags = flags;
1911     WSABUF wsabuf;
1912
1913     wsabuf.len = len;
1914     wsabuf.buf = buf;
1915
1916     if ( WSARecvFrom (s, &wsabuf, 1, &n, &dwFlags, NULL, NULL, NULL, NULL) == SOCKET_ERROR )
1917         return SOCKET_ERROR;
1918     else
1919         return n;
1920 }
1921
1922 /***********************************************************************
1923  *              recvfrom                (WS2_32.17)
1924  */
1925 int WINAPI WS_recvfrom(SOCKET s, char *buf, INT len, int flags,
1926                                 struct WS_sockaddr *from, int *fromlen)
1927 {
1928     DWORD n, dwFlags = flags;
1929     WSABUF wsabuf;
1930
1931     wsabuf.len = len;
1932     wsabuf.buf = buf;
1933
1934     if ( WSARecvFrom (s, &wsabuf, 1, &n, &dwFlags, from, fromlen, NULL, NULL) == SOCKET_ERROR )
1935         return SOCKET_ERROR;
1936     else
1937         return n;
1938 }
1939
1940 /***********************************************************************
1941  *              select                  (WS2_32.18)
1942  */
1943 int WINAPI WS_select(int nfds, WS_fd_set *ws_readfds,
1944                      WS_fd_set *ws_writefds, WS_fd_set *ws_exceptfds,
1945                      const struct WS_timeval* ws_timeout)
1946 {
1947     int         highfd = 0;
1948     fd_set      readfds, writefds, exceptfds;
1949     fd_set     *p_read, *p_write, *p_except;
1950     int         readfd[FD_SETSIZE], writefd[FD_SETSIZE], exceptfd[FD_SETSIZE];
1951     struct timeval timeout, *timeoutaddr = NULL;
1952
1953     TRACE("read %p, write %p, excp %p timeout %p\n",
1954           ws_readfds, ws_writefds, ws_exceptfds, ws_timeout);
1955
1956     p_read = fd_set_import(&readfds, ws_readfds, GENERIC_READ, &highfd, readfd);
1957     p_write = fd_set_import(&writefds, ws_writefds, GENERIC_WRITE, &highfd, writefd);
1958     p_except = fd_set_import(&exceptfds, ws_exceptfds, 0, &highfd, exceptfd);
1959     if (ws_timeout)
1960     {
1961         timeoutaddr = &timeout;
1962         timeout.tv_sec=ws_timeout->tv_sec;
1963         timeout.tv_usec=ws_timeout->tv_usec;
1964     }
1965
1966     if( (highfd = select(highfd + 1, p_read, p_write, p_except, timeoutaddr)) > 0 )
1967     {
1968         fd_set_export(&readfds, p_except, ws_readfds, readfd);
1969         fd_set_export(&writefds, p_except, ws_writefds, writefd);
1970
1971         if (p_except && ws_exceptfds)
1972         {
1973             int i, j;
1974
1975             for (i = j = 0; i < ws_exceptfds->fd_count; i++)
1976             {
1977                 int fd = exceptfd[i];
1978                 SOCKET s = ws_exceptfds->fd_array[i];
1979                 if (fd == -1) continue;
1980                 if (FD_ISSET(fd, &exceptfds)) ws_exceptfds->fd_array[j++] = s;
1981                 release_sock_fd( s, fd );
1982             }
1983             ws_exceptfds->fd_count = j;
1984         }
1985         return highfd;
1986     }
1987     fd_set_unimport(ws_readfds, readfd);
1988     fd_set_unimport(ws_writefds, writefd);
1989     fd_set_unimport(ws_exceptfds, exceptfd);
1990
1991     if( highfd == 0 ) return 0;
1992     SetLastError(wsaErrno());
1993     return SOCKET_ERROR;
1994 }
1995
1996
1997 /***********************************************************************
1998  *              send                    (WS2_32.19)
1999  */
2000 int WINAPI WS_send(SOCKET s, const char *buf, int len, int flags)
2001 {
2002     DWORD n;
2003     WSABUF wsabuf;
2004
2005     wsabuf.len = len;
2006     wsabuf.buf = (char*) buf;
2007
2008     if ( WSASendTo ( s, &wsabuf, 1, &n, flags, NULL, 0, NULL, NULL) == SOCKET_ERROR )
2009         return SOCKET_ERROR;
2010     else
2011         return n;
2012 }
2013
2014 /***********************************************************************
2015  *              WSASend                 (WS2_32.72)
2016  */
2017 INT WINAPI WSASend( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
2018                     LPDWORD lpNumberOfBytesSent, DWORD dwFlags,
2019                     LPWSAOVERLAPPED lpOverlapped,
2020                     LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine )
2021 {
2022     return WSASendTo ( s, lpBuffers, dwBufferCount, lpNumberOfBytesSent, dwFlags,
2023                        NULL, 0, lpOverlapped, lpCompletionRoutine );
2024 }
2025
2026 /***********************************************************************
2027  *              WSASendDisconnect       (WS2_32.73)
2028  */
2029 INT WINAPI WSASendDisconnect( SOCKET s, LPWSABUF lpBuffers )
2030 {
2031     return WS_shutdown ( s, SD_SEND );
2032 }
2033
2034
2035 /***********************************************************************
2036  *              WSASendTo               (WS2_32.74)
2037  */
2038 INT WINAPI WSASendTo( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
2039                       LPDWORD lpNumberOfBytesSent, DWORD dwFlags,
2040                       const struct WS_sockaddr *to, int tolen,
2041                       LPWSAOVERLAPPED lpOverlapped,
2042                       LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine )
2043 {
2044     int i, n, fd, err = WSAENOTSOCK, flags, ret;
2045     struct iovec* iovec;
2046     struct ws2_async *wsa;
2047
2048     TRACE ("socket %04x, wsabuf %p, nbufs %ld, flags %ld, to %p, tolen %d, ovl %p, func %p\n",
2049            s, lpBuffers, dwBufferCount, dwFlags,
2050            to, tolen, lpOverlapped, lpCompletionRoutine);
2051
2052     fd = get_sock_fd( s, GENERIC_WRITE, &flags );
2053     TRACE ( "fd=%d, flags=%x\n", fd, flags );
2054
2055     if ( fd == -1 ) return SOCKET_ERROR;
2056
2057     if (flags & FD_FLAG_SEND_SHUTDOWN)
2058     {
2059         WSASetLastError ( WSAESHUTDOWN );
2060         goto err_close;
2061     }
2062
2063     if ( !lpNumberOfBytesSent )
2064     {
2065         err = WSAEFAULT;
2066         goto err_close;
2067     }
2068
2069     iovec = HeapAlloc (GetProcessHeap(), 0, dwBufferCount * sizeof (struct iovec) );
2070
2071     if ( !iovec )
2072     {
2073         err = WSAEFAULT;
2074         goto err_close;
2075     }
2076
2077     for ( i = 0; i < dwBufferCount; i++ )
2078     {
2079         iovec[i].iov_base = lpBuffers[i].buf;
2080         iovec[i].iov_len  = lpBuffers[i].len;
2081     }
2082
2083     if ( (lpOverlapped || lpCompletionRoutine) && flags & FD_FLAG_OVERLAPPED )
2084     {
2085         wsa = WS2_make_async ( s, fd, ASYNC_TYPE_WRITE, iovec, dwBufferCount,
2086                                &dwFlags, (struct WS_sockaddr*) to, &tolen,
2087                                lpOverlapped, lpCompletionRoutine );
2088         if ( !wsa )
2089         {
2090             err = WSAEFAULT;
2091             goto err_free;
2092         }
2093
2094         if ( ( ret = register_new_async ( &wsa->async )) )
2095         {
2096             err = NtStatusToWSAError ( ret );
2097
2098             if ( !lpOverlapped )
2099                 HeapFree ( GetProcessHeap(), 0, wsa->async.iosb );
2100             HeapFree ( GetProcessHeap(), 0, wsa );
2101             goto err_free;
2102         }
2103
2104         /* Try immediate completion */
2105         if ( lpOverlapped && !NtResetEvent( lpOverlapped->hEvent, NULL ) )
2106         {
2107             if  ( WSAGetOverlappedResult ( s, lpOverlapped,
2108                                            lpNumberOfBytesSent, FALSE, &dwFlags) )
2109                 return 0;
2110
2111             if ( (err = WSAGetLastError ()) != WSA_IO_INCOMPLETE )
2112                 goto error;
2113         }
2114
2115         WSASetLastError ( WSA_IO_PENDING );
2116         return SOCKET_ERROR;
2117     }
2118
2119     if (_is_blocking(s))
2120     {
2121         /* FIXME: exceptfds? */
2122         do_block(fd, POLLOUT);
2123     }
2124
2125     n = WS2_send ( fd, iovec, dwBufferCount, to, tolen, dwFlags );
2126     if ( n == -1 )
2127     {
2128         err = wsaErrno();
2129         if ( err == WSAEWOULDBLOCK )
2130             _enable_event (SOCKET2HANDLE(s), FD_WRITE, 0, 0);
2131         goto err_free;
2132     }
2133
2134     TRACE(" -> %i bytes\n", n);
2135     *lpNumberOfBytesSent = n;
2136
2137     HeapFree ( GetProcessHeap(), 0, iovec );
2138     release_sock_fd( s, fd );
2139     return 0;
2140
2141 err_free:
2142     HeapFree ( GetProcessHeap(), 0, iovec );
2143
2144 err_close:
2145     release_sock_fd( s, fd );
2146
2147 error:
2148     WARN (" -> ERROR %d\n", err);
2149     WSASetLastError (err);
2150     return SOCKET_ERROR;
2151 }
2152
2153 /***********************************************************************
2154  *              sendto          (WS2_32.20)
2155  */
2156 int WINAPI WS_sendto(SOCKET s, const char *buf, int len, int flags,
2157                               const struct WS_sockaddr *to, int tolen)
2158 {
2159     DWORD n;
2160     WSABUF wsabuf;
2161
2162     wsabuf.len = len;
2163     wsabuf.buf = (char*) buf;
2164
2165     if ( WSASendTo (s, &wsabuf, 1, &n, flags, to, tolen, NULL, NULL) == SOCKET_ERROR )
2166         return SOCKET_ERROR;
2167     else
2168         return n;
2169 }
2170
2171 /***********************************************************************
2172  *              setsockopt              (WS2_32.21)
2173  */
2174 int WINAPI WS_setsockopt(SOCKET s, int level, int optname,
2175                                   const char *optval, int optlen)
2176 {
2177     int fd;
2178     int woptval;
2179     struct linger linger;
2180     struct timeval tval;
2181
2182     TRACE("socket: %04x, level %d, name %d, ptr %p, len %d\n",
2183           s, level, optname, optval, optlen);
2184
2185     /* SO_OPENTYPE does not require a valid socket handle. */
2186     if (level == WS_SOL_SOCKET && optname == WS_SO_OPENTYPE)
2187     {
2188         if (optlen < sizeof(int) || !optval)
2189         {
2190             SetLastError(WSAEFAULT);
2191             return SOCKET_ERROR;
2192         }
2193         TlsSetValue( opentype_tls_index, (LPVOID)*(int *)optval );
2194         TRACE("setting global SO_OPENTYPE to 0x%x\n", *(int *)optval );
2195         return 0;
2196     }
2197
2198     /* For some reason the game GrandPrixLegends does set SO_DONTROUTE on its
2199      * socket. This will either not happen under windows or it is ignored in
2200      * windows (but it works in linux and therefor prevents the game to find
2201      * games outsite the current network) */
2202     if ( level==WS_SOL_SOCKET && optname==WS_SO_DONTROUTE ) 
2203     {
2204         FIXME("Does windows ignore SO_DONTROUTE?\n");
2205         return 0;
2206     }
2207
2208     /* Is a privileged and useless operation, so we don't. */
2209     if ((optname == WS_SO_DEBUG) && (level == WS_SOL_SOCKET))
2210     {
2211         FIXME("(%d,SOL_SOCKET,SO_DEBUG,%p(%ld)) attempted (is privileged). Ignoring.\n",s,optval,*(DWORD*)optval);
2212         return 0;
2213     }
2214
2215     if(optname == WS_SO_DONTLINGER && level == WS_SOL_SOCKET) {
2216         /* This is unique to WinSock and takes special conversion */
2217         linger.l_onoff  = *((int*)optval) ? 0: 1;
2218         linger.l_linger = 0;
2219         optname=SO_LINGER;
2220         optval = (char*)&linger;
2221         optlen = sizeof(struct linger);
2222         level = SOL_SOCKET;
2223     }
2224     else
2225     {
2226         if (!convert_sockopt(&level, &optname)) {
2227             ERR("Invalid level (%d) or optname (%d)\n", level, optname);
2228             SetLastError(WSAENOPROTOOPT);
2229             return SOCKET_ERROR;
2230         }
2231         if (optname == SO_LINGER && optval) {
2232             /* yes, uses unsigned short in both win16/win32 */
2233             linger.l_onoff  = ((UINT16*)optval)[0];
2234             linger.l_linger = ((UINT16*)optval)[1];
2235             /* FIXME: what is documented behavior if SO_LINGER optval
2236                is null?? */
2237             optval = (char*)&linger;
2238             optlen = sizeof(struct linger);
2239         }
2240         else if (optval && optlen < sizeof(int))
2241         {
2242             woptval= *((INT16 *) optval);
2243             optval= (char*) &woptval;
2244             optlen=sizeof(int);
2245         }
2246         if (level == SOL_SOCKET && is_timeout_option(optname))
2247         {
2248             if (optlen == sizeof(UINT32)) {
2249                 /* WinSock passes miliseconds instead of struct timeval */
2250                 tval.tv_usec = *(PUINT32)optval % 1000;
2251                 tval.tv_sec = *(PUINT32)optval / 1000;
2252                 /* min of 500 milisec */
2253                 if (tval.tv_sec == 0 && tval.tv_usec < 500) tval.tv_usec = 500;
2254                 optlen = sizeof(struct timeval);
2255                 optval = (char*)&tval;
2256             } else if (optlen == sizeof(struct timeval)) {
2257                 WARN("SO_SND/RCVTIMEO for %d bytes: assuming unixism\n", optlen);
2258             } else {
2259                 WARN("SO_SND/RCVTIMEO for %d bytes is weird: ignored\n", optlen);
2260                 return 0;
2261             }
2262         }
2263         if (level == SOL_SOCKET && optname == SO_RCVBUF && *(int*)optval < 2048)
2264         {
2265             WARN("SO_RCVBF for %d bytes is too small: ignored\n", *(int*)optval );
2266             return 0;
2267         }
2268     }
2269
2270
2271     fd = get_sock_fd( s, 0, NULL );
2272     if (fd == -1) return SOCKET_ERROR;
2273
2274     if (setsockopt(fd, level, optname, optval, optlen) == 0)
2275     {
2276         release_sock_fd( s, fd );
2277         return 0;
2278     }
2279     TRACE("Setting socket error, %d\n", wsaErrno());
2280     SetLastError(wsaErrno());
2281     release_sock_fd( s, fd );
2282     return SOCKET_ERROR;
2283 }
2284
2285 /***********************************************************************
2286  *              shutdown                (WS2_32.22)
2287  */
2288 int WINAPI WS_shutdown(SOCKET s, int how)
2289 {
2290     int fd, fd0 = -1, fd1 = -1, flags, err = WSAENOTSOCK;
2291     unsigned int clear_flags = 0;
2292
2293     fd = get_sock_fd( s, 0, &flags );
2294     TRACE("socket %04x, how %i %x\n", s, how, flags );
2295
2296     if (fd == -1)
2297         return SOCKET_ERROR;
2298
2299     switch( how )
2300     {
2301     case 0: /* drop receives */
2302         clear_flags |= FD_READ;
2303         break;
2304     case 1: /* drop sends */
2305         clear_flags |= FD_WRITE;
2306         break;
2307     case 2: /* drop all */
2308         clear_flags |= FD_READ|FD_WRITE;
2309     default:
2310         clear_flags |= FD_WINE_LISTENING;
2311     }
2312
2313     if ( flags & FD_FLAG_OVERLAPPED ) {
2314
2315         switch ( how )
2316         {
2317         case SD_RECEIVE:
2318             fd0 = fd;
2319             break;
2320         case SD_SEND:
2321             fd1 = fd;
2322             break;
2323         case SD_BOTH:
2324         default:
2325             fd0 = fd;
2326             fd1 = get_sock_fd ( s, 0, NULL );
2327             break;
2328         }
2329
2330         if ( fd0 != -1 )
2331         {
2332             err = WS2_register_async_shutdown ( s, fd0, ASYNC_TYPE_READ );
2333             if ( err )
2334             {
2335                 release_sock_fd( s, fd0 );
2336                 goto error;
2337             }
2338         }
2339         if ( fd1 != -1 )
2340         {
2341             err = WS2_register_async_shutdown ( s, fd1, ASYNC_TYPE_WRITE );
2342             if ( err )
2343             {
2344                 release_sock_fd( s, fd1 );
2345                 goto error;
2346             }
2347         }
2348     }
2349     else /* non-overlapped mode */
2350     {
2351         if ( shutdown( fd, how ) )
2352         {
2353             err = wsaErrno ();
2354             release_sock_fd( s, fd );
2355             goto error;
2356         }
2357         release_sock_fd( s, fd );
2358     }
2359
2360     _enable_event( SOCKET2HANDLE(s), 0, 0, clear_flags );
2361     if ( how > 1) WSAAsyncSelect( s, 0, 0, 0 );
2362     return 0;
2363
2364 error:
2365     _enable_event( SOCKET2HANDLE(s), 0, 0, clear_flags );
2366     WSASetLastError ( err );
2367     return SOCKET_ERROR;
2368 }
2369
2370 /***********************************************************************
2371  *              socket          (WS2_32.23)
2372  */
2373 SOCKET WINAPI WS_socket(int af, int type, int protocol)
2374 {
2375     TRACE("af=%d type=%d protocol=%d\n", af, type, protocol);
2376
2377     return WSASocketA ( af, type, protocol, NULL, 0,
2378                         (TlsGetValue(opentype_tls_index) ? 0 : WSA_FLAG_OVERLAPPED) );
2379 }
2380
2381
2382 /***********************************************************************
2383  *              gethostbyaddr           (WS2_32.51)
2384  */
2385 struct WS_hostent* WINAPI WS_gethostbyaddr(const char *addr, int len, int type)
2386 {
2387     struct WS_hostent *retval = NULL;
2388     struct hostent* host;
2389
2390 #ifdef HAVE_LINUX_GETHOSTBYNAME_R_6
2391     char *extrabuf;
2392     int ebufsize=1024;
2393     struct hostent hostentry;
2394     int locerr=ENOBUFS;
2395     host = NULL;
2396     extrabuf=HeapAlloc(GetProcessHeap(),0,ebufsize) ;
2397     while(extrabuf) {
2398         int res = gethostbyaddr_r(addr, len, type,
2399                                   &hostentry, extrabuf, ebufsize, &host, &locerr);
2400         if( res != ERANGE) break;
2401         ebufsize *=2;
2402         extrabuf=HeapReAlloc(GetProcessHeap(),0,extrabuf,ebufsize) ;
2403     }
2404     if (!host) SetLastError((locerr < 0) ? wsaErrno() : wsaHerrno(locerr));
2405 #else
2406     EnterCriticalSection( &csWSgetXXXbyYYY );
2407     host = gethostbyaddr(addr, len, type);
2408     if (!host) SetLastError((h_errno < 0) ? wsaErrno() : wsaHerrno(h_errno));
2409 #endif
2410     if( host != NULL ) retval = WS_dup_he(host);
2411 #ifdef  HAVE_LINUX_GETHOSTBYNAME_R_6
2412     HeapFree(GetProcessHeap(),0,extrabuf);
2413 #else
2414     LeaveCriticalSection( &csWSgetXXXbyYYY );
2415 #endif
2416     TRACE("ptr %p, len %d, type %d ret %p\n", addr, len, type, retval);
2417     return retval;
2418 }
2419
2420 /***********************************************************************
2421  *              gethostbyname           (WS2_32.52)
2422  */
2423 struct WS_hostent* WINAPI WS_gethostbyname(const char* name)
2424 {
2425     struct WS_hostent *retval = NULL;
2426     struct hostent*     host;
2427 #ifdef  HAVE_LINUX_GETHOSTBYNAME_R_6
2428     char *extrabuf;
2429     int ebufsize=1024;
2430     struct hostent hostentry;
2431     int locerr = ENOBUFS;
2432 #endif
2433     char buf[100];
2434     if( !name) {
2435         name = buf;
2436         if( gethostname( buf, 100) == -1) {
2437             SetLastError( WSAENOBUFS); /* appropriate ? */
2438             return retval;
2439         }
2440     }
2441 #ifdef  HAVE_LINUX_GETHOSTBYNAME_R_6
2442     host = NULL;
2443     extrabuf=HeapAlloc(GetProcessHeap(),0,ebufsize) ;
2444     while(extrabuf) {
2445         int res = gethostbyname_r(name, &hostentry, extrabuf, ebufsize, &host, &locerr);
2446         if( res != ERANGE) break;
2447         ebufsize *=2;
2448         extrabuf=HeapReAlloc(GetProcessHeap(),0,extrabuf,ebufsize) ;
2449     }
2450     if (!host) SetLastError((locerr < 0) ? wsaErrno() : wsaHerrno(locerr));
2451 #else
2452     EnterCriticalSection( &csWSgetXXXbyYYY );
2453     host = gethostbyname(name);
2454     if (!host) SetLastError((h_errno < 0) ? wsaErrno() : wsaHerrno(h_errno));
2455 #endif
2456     if (host) retval = WS_dup_he(host);
2457 #ifdef  HAVE_LINUX_GETHOSTBYNAME_R_6
2458     HeapFree(GetProcessHeap(),0,extrabuf);
2459 #else
2460     LeaveCriticalSection( &csWSgetXXXbyYYY );
2461 #endif
2462     TRACE( "%s ret %p\n", debugstr_a(name), retval );
2463     return retval;
2464 }
2465
2466
2467 /***********************************************************************
2468  *              getprotobyname          (WS2_32.53)
2469  */
2470 struct WS_protoent* WINAPI WS_getprotobyname(const char* name)
2471 {
2472     struct WS_protoent* retval = NULL;
2473 #ifdef HAVE_GETPROTOBYNAME
2474     struct protoent*     proto;
2475     EnterCriticalSection( &csWSgetXXXbyYYY );
2476     if( (proto = getprotobyname(name)) != NULL )
2477     {
2478         retval = WS_dup_pe(proto);
2479     }
2480     else {
2481         MESSAGE("protocol %s not found; You might want to add "
2482                 "this to /etc/protocols\n", debugstr_a(name) );
2483         SetLastError(WSANO_DATA);
2484     }
2485     LeaveCriticalSection( &csWSgetXXXbyYYY );
2486 #endif
2487     TRACE( "%s ret %p\n", debugstr_a(name), retval );
2488     return retval;
2489 }
2490
2491
2492 /***********************************************************************
2493  *              getprotobynumber        (WS2_32.54)
2494  */
2495 struct WS_protoent* WINAPI WS_getprotobynumber(int number)
2496 {
2497     struct WS_protoent* retval = NULL;
2498 #ifdef HAVE_GETPROTOBYNUMBER
2499     struct protoent*     proto;
2500     EnterCriticalSection( &csWSgetXXXbyYYY );
2501     if( (proto = getprotobynumber(number)) != NULL )
2502     {
2503         retval = WS_dup_pe(proto);
2504     }
2505     else {
2506         MESSAGE("protocol number %d not found; You might want to add "
2507                 "this to /etc/protocols\n", number );
2508         SetLastError(WSANO_DATA);
2509     }
2510     LeaveCriticalSection( &csWSgetXXXbyYYY );
2511 #endif
2512     TRACE("%i ret %p\n", number, retval);
2513     return retval;
2514 }
2515
2516
2517 /***********************************************************************
2518  *              getservbyname           (WS2_32.55)
2519  */
2520 struct WS_servent* WINAPI WS_getservbyname(const char *name, const char *proto)
2521 {
2522     struct WS_servent* retval = NULL;
2523     struct servent*     serv;
2524     char *name_str;
2525     char *proto_str = NULL;
2526
2527     if (!(name_str = strdup_lower(name))) return NULL;
2528
2529     if (proto && *proto)
2530     {
2531         if (!(proto_str = strdup_lower(proto)))
2532         {
2533             HeapFree( GetProcessHeap(), 0, name_str );
2534             return NULL;
2535         }
2536     }
2537
2538     EnterCriticalSection( &csWSgetXXXbyYYY );
2539     serv = getservbyname(name_str, proto_str);
2540     if( serv != NULL )
2541     {
2542         retval = WS_dup_se(serv);
2543     }
2544     else SetLastError(WSANO_DATA);
2545     LeaveCriticalSection( &csWSgetXXXbyYYY );
2546     if (proto_str) HeapFree( GetProcessHeap(), 0, proto_str );
2547     HeapFree( GetProcessHeap(), 0, name_str );
2548     TRACE( "%s, %s ret %p\n", debugstr_a(name), debugstr_a(proto), retval );
2549     return retval;
2550 }
2551
2552
2553 /***********************************************************************
2554  *              getservbyport           (WS2_32.56)
2555  */
2556 struct WS_servent* WINAPI WS_getservbyport(int port, const char *proto)
2557 {
2558     struct WS_servent* retval = NULL;
2559 #ifdef HAVE_GETSERVBYPORT
2560     struct servent*     serv;
2561     char *proto_str = NULL;
2562
2563     if (proto && *proto)
2564     {
2565         if (!(proto_str = strdup_lower(proto))) return NULL;
2566     }
2567     EnterCriticalSection( &csWSgetXXXbyYYY );
2568     if( (serv = getservbyport(port, proto_str)) != NULL ) {
2569         retval = WS_dup_se(serv);
2570     }
2571     else SetLastError(WSANO_DATA);
2572     LeaveCriticalSection( &csWSgetXXXbyYYY );
2573     if (proto_str) HeapFree( GetProcessHeap(), 0, proto_str );
2574 #endif
2575     TRACE("%d (i.e. port %d), %s ret %p\n", port, (int)ntohl(port), debugstr_a(proto), retval);
2576     return retval;
2577 }
2578
2579
2580 /***********************************************************************
2581  *              gethostname           (WS2_32.57)
2582  */
2583 int WINAPI WS_gethostname(char *name, int namelen)
2584 {
2585     TRACE("name %p, len %d\n", name, namelen);
2586
2587     if (gethostname(name, namelen) == 0)
2588     {
2589         TRACE("<- '%s'\n", name);
2590         return 0;
2591     }
2592     SetLastError((errno == EINVAL) ? WSAEFAULT : wsaErrno());
2593     TRACE("<- ERROR !\n");
2594     return SOCKET_ERROR;
2595 }
2596
2597
2598 /* ------------------------------------- Windows sockets extensions -- *
2599  *                                                                     *
2600  * ------------------------------------------------------------------- */
2601
2602 /***********************************************************************
2603  *              WSAEnumNetworkEvents (WS2_32.36)
2604  */
2605 int WINAPI WSAEnumNetworkEvents(SOCKET s, WSAEVENT hEvent, LPWSANETWORKEVENTS lpEvent)
2606 {
2607     int ret;
2608
2609     TRACE("%08x, hEvent %p, lpEvent %08x\n", s, hEvent, (unsigned)lpEvent );
2610
2611     SERVER_START_REQ( get_socket_event )
2612     {
2613         req->handle  = SOCKET2HANDLE(s);
2614         req->service = TRUE;
2615         req->c_event = hEvent;
2616         wine_server_set_reply( req, lpEvent->iErrorCode, sizeof(lpEvent->iErrorCode) );
2617         if (!(ret = wine_server_call(req))) lpEvent->lNetworkEvents = reply->pmask & reply->mask;
2618     }
2619     SERVER_END_REQ;
2620     if (!ret) return 0;
2621     SetLastError(WSAEINVAL);
2622     return SOCKET_ERROR;
2623 }
2624
2625 /***********************************************************************
2626  *              WSAEventSelect (WS2_32.39)
2627  */
2628 int WINAPI WSAEventSelect(SOCKET s, WSAEVENT hEvent, LONG lEvent)
2629 {
2630     int ret;
2631
2632     TRACE("%08x, hEvent %p, event %08x\n", s, hEvent, (unsigned)lEvent );
2633
2634     SERVER_START_REQ( set_socket_event )
2635     {
2636         req->handle = SOCKET2HANDLE(s);
2637         req->mask   = lEvent;
2638         req->event  = hEvent;
2639         req->window = 0;
2640         req->msg    = 0;
2641         ret = wine_server_call( req );
2642     }
2643     SERVER_END_REQ;
2644     if (!ret) return 0;
2645     SetLastError(WSAEINVAL);
2646     return SOCKET_ERROR;
2647 }
2648
2649 /**********************************************************************
2650  *      WSAGetOverlappedResult (WS2_32.40)
2651  */
2652 BOOL WINAPI WSAGetOverlappedResult ( SOCKET s, LPWSAOVERLAPPED lpOverlapped,
2653                                      LPDWORD lpcbTransfer, BOOL fWait,
2654                                      LPDWORD lpdwFlags )
2655 {
2656     DWORD r;
2657
2658     TRACE ( "socket %d ovl %p trans %p, wait %d flags %p\n",
2659             s, lpOverlapped, lpcbTransfer, fWait, lpdwFlags );
2660
2661     if ( !(lpOverlapped && lpOverlapped->hEvent) )
2662     {
2663         ERR ( "Invalid pointer\n" );
2664         WSASetLastError (WSA_INVALID_PARAMETER);
2665         return FALSE;
2666     }
2667
2668     if ( fWait )
2669     {
2670         while ( WaitForSingleObjectEx (lpOverlapped->hEvent, INFINITE, TRUE) == STATUS_USER_APC );
2671     }
2672     else if ( lpOverlapped->Internal == STATUS_PENDING )
2673     {
2674         /* Wait in order to give APCs a chance to run. */
2675         /* This is cheating, so we must set the event again in case of success -
2676            it may be a non-manual reset event. */
2677         while ( (r = WaitForSingleObjectEx (lpOverlapped->hEvent, 0, TRUE)) == STATUS_USER_APC );
2678         if ( r == WAIT_OBJECT_0 )
2679             NtSetEvent ( lpOverlapped->hEvent, NULL );
2680     }
2681
2682     if ( lpcbTransfer )
2683         *lpcbTransfer = lpOverlapped->InternalHigh;
2684
2685     if ( lpdwFlags )
2686         *lpdwFlags = lpOverlapped->Offset;
2687
2688     switch ( lpOverlapped->Internal )
2689     {
2690     case STATUS_SUCCESS:
2691         return TRUE;
2692     case STATUS_PENDING:
2693         WSASetLastError ( WSA_IO_INCOMPLETE );
2694         if (fWait) ERR ("PENDING status after waiting!\n");
2695         return FALSE;
2696     default:
2697         WSASetLastError ( NtStatusToWSAError ( lpOverlapped->Internal ));
2698         return FALSE;
2699     }
2700 }
2701
2702
2703 /***********************************************************************
2704  *      WSAAsyncSelect                  (WS2_32.101)
2705  */
2706 INT WINAPI WSAAsyncSelect(SOCKET s, HWND hWnd, UINT uMsg, LONG lEvent)
2707 {
2708     int ret;
2709
2710     TRACE("%x, hWnd %p, uMsg %08x, event %08lx\n", s, hWnd, uMsg, lEvent );
2711
2712     SERVER_START_REQ( set_socket_event )
2713     {
2714         req->handle = SOCKET2HANDLE(s);
2715         req->mask   = lEvent;
2716         req->event  = 0;
2717         req->window = hWnd;
2718         req->msg    = uMsg;
2719         ret = wine_server_call( req );
2720     }
2721     SERVER_END_REQ;
2722     if (!ret) return 0;
2723     SetLastError(WSAEINVAL);
2724     return SOCKET_ERROR;
2725 }
2726
2727 /***********************************************************************
2728  *      WSACreateEvent          (WS2_32.31)
2729  *
2730  */
2731 WSAEVENT WINAPI WSACreateEvent(void)
2732 {
2733     /* Create a manual-reset event, with initial state: unsignealed */
2734     TRACE("\n");
2735
2736     return CreateEventA(NULL, TRUE, FALSE, NULL);
2737 }
2738
2739 /***********************************************************************
2740  *      WSACloseEvent          (WS2_32.29)
2741  *
2742  */
2743 BOOL WINAPI WSACloseEvent(WSAEVENT event)
2744 {
2745     TRACE ("event=%p\n", event);
2746
2747     return CloseHandle(event);
2748 }
2749
2750 /***********************************************************************
2751  *      WSASocketA          (WS2_32.78)
2752  *
2753  */
2754 SOCKET WINAPI WSASocketA(int af, int type, int protocol,
2755                          LPWSAPROTOCOL_INFOA lpProtocolInfo,
2756                          GROUP g, DWORD dwFlags)
2757 {
2758     SOCKET ret;
2759
2760    /*
2761       FIXME: The "advanced" parameters of WSASocketA (lpProtocolInfo,
2762       g, dwFlags except WSA_FLAG_OVERLAPPED) are ignored.
2763    */
2764
2765    TRACE("af=%d type=%d protocol=%d protocol_info=%p group=%d flags=0x%lx\n",
2766          af, type, protocol, lpProtocolInfo, g, dwFlags );
2767
2768     /* hack for WSADuplicateSocket */
2769     if (lpProtocolInfo && lpProtocolInfo->dwServiceFlags4 == 0xff00ff00) {
2770       ret = lpProtocolInfo->dwCatalogEntryId;
2771       TRACE("\tgot duplicate %04x\n", ret);
2772       return ret;
2773     }
2774
2775     /* check the socket family */
2776     switch(af)
2777     {
2778 #ifdef HAVE_IPX
2779         case WS_AF_IPX: af = AF_IPX;
2780 #endif
2781         case AF_INET:
2782         case AF_UNSPEC:
2783             break;
2784         default:
2785             SetLastError(WSAEAFNOSUPPORT);
2786             return INVALID_SOCKET;
2787     }
2788
2789     /* check the socket type */
2790     switch(type)
2791     {
2792         case WS_SOCK_STREAM:
2793             type=SOCK_STREAM;
2794             break;
2795         case WS_SOCK_DGRAM:
2796             type=SOCK_DGRAM;
2797             break;
2798         case WS_SOCK_RAW:
2799             type=SOCK_RAW;
2800             break;
2801         default:
2802             SetLastError(WSAESOCKTNOSUPPORT);
2803             return INVALID_SOCKET;
2804     }
2805
2806     /* check the protocol type */
2807     if ( protocol < 0 )  /* don't support negative values */
2808     {
2809         SetLastError(WSAEPROTONOSUPPORT);
2810         return INVALID_SOCKET;
2811     }
2812
2813     if ( af == AF_UNSPEC)  /* did they not specify the address family? */
2814         switch(protocol)
2815         {
2816           case IPPROTO_TCP:
2817              if (type == SOCK_STREAM) { af = AF_INET; break; }
2818           case IPPROTO_UDP:
2819              if (type == SOCK_DGRAM)  { af = AF_INET; break; }
2820           default: SetLastError(WSAEPROTOTYPE); return INVALID_SOCKET;
2821         }
2822
2823     SERVER_START_REQ( create_socket )
2824     {
2825         req->family   = af;
2826         req->type     = type;
2827         req->protocol = protocol;
2828         req->access   = GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE;
2829         req->flags    = dwFlags;
2830         req->inherit  = TRUE;
2831         set_error( wine_server_call( req ) );
2832         ret = HANDLE2SOCKET( reply->handle );
2833     }
2834     SERVER_END_REQ;
2835     if (ret)
2836     {
2837         TRACE("\tcreated %04x\n", ret );
2838         return ret;
2839     }
2840
2841     if (GetLastError() == WSAEACCES) /* raw socket denied */
2842     {
2843         if (type == SOCK_RAW)
2844             MESSAGE("WARNING: Trying to create a socket of type SOCK_RAW, will fail unless running as root\n");
2845         else
2846             MESSAGE("WS_SOCKET: not enough privileges to create socket, try running as root\n");
2847         SetLastError(WSAESOCKTNOSUPPORT);
2848     }
2849
2850     WARN("\t\tfailed!\n");
2851     return INVALID_SOCKET;
2852 }
2853
2854 /***********************************************************************
2855  *      WSAJoinLeaf          (WS2_32.58)
2856  *
2857  */
2858 SOCKET WINAPI WSAJoinLeaf(
2859         SOCKET s,
2860         const struct WS_sockaddr *addr,
2861         int addrlen,
2862         LPWSABUF lpCallerData,
2863         LPWSABUF lpCalleeData,
2864         LPQOS lpSQOS,
2865         LPQOS lpGQOS,
2866         DWORD dwFlags)
2867 {
2868     FIXME("stub.\n");
2869     return INVALID_SOCKET;
2870 }
2871
2872 /***********************************************************************
2873  *      __WSAFDIsSet                    (WS2_32.151)
2874  */
2875 int WINAPI __WSAFDIsSet(SOCKET s, WS_fd_set *set)
2876 {
2877   int i = set->fd_count;
2878
2879   TRACE("(%d,%8lx(%i))\n", s,(unsigned long)set, i);
2880
2881   while (i--)
2882       if (set->fd_array[i] == s) return 1;
2883   return 0;
2884 }
2885
2886 /***********************************************************************
2887  *      WSAIsBlocking                   (WINSOCK.114)
2888  *      WSAIsBlocking                   (WS2_32.114)
2889  */
2890 BOOL WINAPI WSAIsBlocking(void)
2891 {
2892   /* By default WinSock should set all its sockets to non-blocking mode
2893    * and poll in PeekMessage loop when processing "blocking" ones. This
2894    * function is supposed to tell if the program is in this loop. Our
2895    * blocking calls are truly blocking so we always return FALSE.
2896    *
2897    * Note: It is allowed to call this function without prior WSAStartup().
2898    */
2899
2900   TRACE("\n");
2901   return FALSE;
2902 }
2903
2904 /***********************************************************************
2905  *      WSACancelBlockingCall           (WINSOCK.113)
2906  *      WSACancelBlockingCall           (WS2_32.113)
2907  */
2908 INT WINAPI WSACancelBlockingCall(void)
2909 {
2910     TRACE("\n");
2911     return 0;
2912 }
2913
2914 static INT WINAPI WSA_DefaultBlockingHook( FARPROC x )
2915 {
2916     FIXME("How was this called?\n");
2917     return x();
2918 }
2919
2920
2921 /***********************************************************************
2922  *      WSASetBlockingHook (WS2_32.109)
2923  */
2924 FARPROC WINAPI WSASetBlockingHook(FARPROC lpBlockFunc)
2925 {
2926   FARPROC prev = blocking_hook;
2927   blocking_hook = lpBlockFunc;
2928   TRACE("hook %p\n", lpBlockFunc);
2929   return prev;
2930 }
2931
2932
2933 /***********************************************************************
2934  *      WSAUnhookBlockingHook (WS2_32.110)
2935  */
2936 INT WINAPI WSAUnhookBlockingHook(void)
2937 {
2938     blocking_hook = WSA_DefaultBlockingHook;
2939     return 0;
2940 }
2941
2942
2943 /* ----------------------------------- end of API stuff */
2944
2945 /* ----------------------------------- helper functions -
2946  *
2947  * TODO: Merge WS_dup_..() stuff into one function that
2948  * would operate with a generic structure containing internal
2949  * pointers (via a template of some kind).
2950  */
2951
2952 static int list_size(char** l, int item_size)
2953 {
2954   int i,j = 0;
2955   if(l)
2956   { for(i=0;l[i];i++)
2957         j += (item_size) ? item_size : strlen(l[i]) + 1;
2958     j += (i + 1) * sizeof(char*); }
2959   return j;
2960 }
2961
2962 static int list_dup(char** l_src, char** l_to, int item_size)
2963 {
2964    char *p;
2965    int i;
2966
2967    for (i = 0; l_src[i]; i++) ;
2968    p = (char *)(l_to + i + 1);
2969    for (i = 0; l_src[i]; i++)
2970    {
2971        int count = ( item_size ) ? item_size : strlen(l_src[i]) + 1;
2972        memcpy(p, l_src[i], count);
2973        l_to[i] = p;
2974        p += count;
2975    }
2976    l_to[i] = NULL;
2977    return (p - (char *)l_to);
2978 }
2979
2980 /* ----- hostent */
2981
2982 /* duplicate hostent entry
2983  * and handle all Win16/Win32 dependent things (struct size, ...) *correctly*.
2984  * Dito for protoent and servent.
2985  */
2986 static struct WS_hostent *WS_dup_he(const struct hostent* p_he)
2987 {
2988     char *p;
2989     struct WS_hostent *p_to;
2990
2991     int size = (sizeof(*p_he) +
2992                 strlen(p_he->h_name) + 1 +
2993                 list_size(p_he->h_aliases, 0) +
2994                 list_size(p_he->h_addr_list, p_he->h_length));
2995
2996     if (!(p_to = check_buffer_he(size))) return NULL;
2997     p_to->h_addrtype = p_he->h_addrtype;
2998     p_to->h_length = p_he->h_length;
2999
3000     p = (char *)(p_to + 1);
3001     p_to->h_name = p;
3002     strcpy(p, p_he->h_name);
3003     p += strlen(p) + 1;
3004
3005     p_to->h_aliases = (char **)p;
3006     p += list_dup(p_he->h_aliases, p_to->h_aliases, 0);
3007
3008     p_to->h_addr_list = (char **)p;
3009     list_dup(p_he->h_addr_list, p_to->h_addr_list, p_he->h_length);
3010     return p_to;
3011 }
3012
3013 /* ----- protoent */
3014
3015 static struct WS_protoent *WS_dup_pe(const struct protoent* p_pe)
3016 {
3017     char *p;
3018     struct WS_protoent *p_to;
3019
3020     int size = (sizeof(*p_pe) +
3021                 strlen(p_pe->p_name) + 1 +
3022                 list_size(p_pe->p_aliases, 0));
3023
3024     if (!(p_to = check_buffer_pe(size))) return NULL;
3025     p_to->p_proto = p_pe->p_proto;
3026
3027     p = (char *)(p_to + 1);
3028     p_to->p_name = p;
3029     strcpy(p, p_pe->p_name);
3030     p += strlen(p) + 1;
3031
3032     p_to->p_aliases = (char **)p;
3033     list_dup(p_pe->p_aliases, p_to->p_aliases, 0);
3034     return p_to;
3035 }
3036
3037 /* ----- servent */
3038
3039 static struct WS_servent *WS_dup_se(const struct servent* p_se)
3040 {
3041     char *p;
3042     struct WS_servent *p_to;
3043
3044     int size = (sizeof(*p_se) +
3045                 strlen(p_se->s_proto) + 1 +
3046                 strlen(p_se->s_name) + 1 +
3047                 list_size(p_se->s_aliases, 0));
3048
3049     if (!(p_to = check_buffer_se(size))) return NULL;
3050     p_to->s_port = p_se->s_port;
3051
3052     p = (char *)(p_to + 1);
3053     p_to->s_name = p;
3054     strcpy(p, p_se->s_name);
3055     p += strlen(p) + 1;
3056
3057     p_to->s_proto = p;
3058     strcpy(p, p_se->s_proto);
3059     p += strlen(p) + 1;
3060
3061     p_to->s_aliases = (char **)p;
3062     list_dup(p_se->s_aliases, p_to->s_aliases, 0);
3063     return p_to;
3064 }
3065
3066 /* ----------------------------------- error handling */
3067
3068 UINT wsaErrno(void)
3069 {
3070     int loc_errno = errno;
3071     WARN("errno %d, (%s).\n", loc_errno, strerror(loc_errno));
3072
3073     switch(loc_errno)
3074     {
3075         case EINTR:             return WSAEINTR;
3076         case EBADF:             return WSAEBADF;
3077         case EPERM:
3078         case EACCES:            return WSAEACCES;
3079         case EFAULT:            return WSAEFAULT;
3080         case EINVAL:            return WSAEINVAL;
3081         case EMFILE:            return WSAEMFILE;
3082         case EWOULDBLOCK:       return WSAEWOULDBLOCK;
3083         case EINPROGRESS:       return WSAEINPROGRESS;
3084         case EALREADY:          return WSAEALREADY;
3085         case ENOTSOCK:          return WSAENOTSOCK;
3086         case EDESTADDRREQ:      return WSAEDESTADDRREQ;
3087         case EMSGSIZE:          return WSAEMSGSIZE;
3088         case EPROTOTYPE:        return WSAEPROTOTYPE;
3089         case ENOPROTOOPT:       return WSAENOPROTOOPT;
3090         case EPROTONOSUPPORT:   return WSAEPROTONOSUPPORT;
3091         case ESOCKTNOSUPPORT:   return WSAESOCKTNOSUPPORT;
3092         case EOPNOTSUPP:        return WSAEOPNOTSUPP;
3093         case EPFNOSUPPORT:      return WSAEPFNOSUPPORT;
3094         case EAFNOSUPPORT:      return WSAEAFNOSUPPORT;
3095         case EADDRINUSE:        return WSAEADDRINUSE;
3096         case EADDRNOTAVAIL:     return WSAEADDRNOTAVAIL;
3097         case ENETDOWN:          return WSAENETDOWN;
3098         case ENETUNREACH:       return WSAENETUNREACH;
3099         case ENETRESET:         return WSAENETRESET;
3100         case ECONNABORTED:      return WSAECONNABORTED;
3101         case EPIPE:
3102         case ECONNRESET:        return WSAECONNRESET;
3103         case ENOBUFS:           return WSAENOBUFS;
3104         case EISCONN:           return WSAEISCONN;
3105         case ENOTCONN:          return WSAENOTCONN;
3106         case ESHUTDOWN:         return WSAESHUTDOWN;
3107         case ETOOMANYREFS:      return WSAETOOMANYREFS;
3108         case ETIMEDOUT:         return WSAETIMEDOUT;
3109         case ECONNREFUSED:      return WSAECONNREFUSED;
3110         case ELOOP:             return WSAELOOP;
3111         case ENAMETOOLONG:      return WSAENAMETOOLONG;
3112         case EHOSTDOWN:         return WSAEHOSTDOWN;
3113         case EHOSTUNREACH:      return WSAEHOSTUNREACH;
3114         case ENOTEMPTY:         return WSAENOTEMPTY;
3115 #ifdef EPROCLIM
3116         case EPROCLIM:          return WSAEPROCLIM;
3117 #endif
3118 #ifdef EUSERS
3119         case EUSERS:            return WSAEUSERS;
3120 #endif
3121 #ifdef EDQUOT
3122         case EDQUOT:            return WSAEDQUOT;
3123 #endif
3124 #ifdef ESTALE
3125         case ESTALE:            return WSAESTALE;
3126 #endif
3127 #ifdef EREMOTE
3128         case EREMOTE:           return WSAEREMOTE;
3129 #endif
3130
3131        /* just in case we ever get here and there are no problems */
3132         case 0:                 return 0;
3133         default:
3134                 WARN("Unknown errno %d!\n", loc_errno);
3135                 return WSAEOPNOTSUPP;
3136     }
3137 }
3138
3139 UINT wsaHerrno(int loc_errno)
3140 {
3141
3142     WARN("h_errno %d.\n", loc_errno);
3143
3144     switch(loc_errno)
3145     {
3146         case HOST_NOT_FOUND:    return WSAHOST_NOT_FOUND;
3147         case TRY_AGAIN:         return WSATRY_AGAIN;
3148         case NO_RECOVERY:       return WSANO_RECOVERY;
3149         case NO_DATA:           return WSANO_DATA;
3150         case ENOBUFS:           return WSAENOBUFS;
3151
3152         case 0:                 return 0;
3153         default:
3154                 WARN("Unknown h_errno %d!\n", loc_errno);
3155                 return WSAEOPNOTSUPP;
3156     }
3157 }
3158
3159
3160 /***********************************************************************
3161  *              WSARecv                 (WS2_32.67)
3162  */
3163 int WINAPI WSARecv (SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
3164                     LPDWORD NumberOfBytesReceived, LPDWORD lpFlags,
3165                     LPWSAOVERLAPPED lpOverlapped,
3166                     LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
3167 {
3168     return WSARecvFrom (s, lpBuffers, dwBufferCount, NumberOfBytesReceived, lpFlags,
3169                         NULL, NULL, lpOverlapped, lpCompletionRoutine);
3170 }
3171
3172 /***********************************************************************
3173  *              WSARecvFrom             (WS2_32.69)
3174  */
3175 INT WINAPI WSARecvFrom( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
3176                         LPDWORD lpNumberOfBytesRecvd, LPDWORD lpFlags, struct WS_sockaddr *lpFrom,
3177                         LPINT lpFromlen, LPWSAOVERLAPPED lpOverlapped,
3178                         LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine )
3179
3180 {
3181     int i, n, fd, err = WSAENOTSOCK, flags, ret;
3182     struct iovec* iovec;
3183     struct ws2_async *wsa;
3184
3185     TRACE("socket %04x, wsabuf %p, nbufs %ld, flags %ld, from %p, fromlen %ld, ovl %p, func %p\n",
3186           s, lpBuffers, dwBufferCount, *lpFlags, lpFrom,
3187           (lpFromlen ? *lpFromlen : -1L),
3188           lpOverlapped, lpCompletionRoutine);
3189
3190     fd = get_sock_fd( s, GENERIC_READ, &flags );
3191     TRACE ( "fd=%d, flags=%x\n", fd, flags );
3192
3193     if (fd == -1) return SOCKET_ERROR;
3194
3195     if (flags & FD_FLAG_RECV_SHUTDOWN)
3196     {
3197         WSASetLastError ( WSAESHUTDOWN );
3198         goto err_close;
3199     }
3200
3201     iovec = HeapAlloc ( GetProcessHeap(), 0, dwBufferCount * sizeof (struct iovec) );
3202     if ( !iovec )
3203     {
3204         err = WSAEFAULT;
3205         goto err_close;
3206     }
3207
3208     for (i = 0; i < dwBufferCount; i++)
3209     {
3210         iovec[i].iov_base = lpBuffers[i].buf;
3211         iovec[i].iov_len  = lpBuffers[i].len;
3212     }
3213
3214     if ( (lpOverlapped || lpCompletionRoutine) && flags & FD_FLAG_OVERLAPPED )
3215     {
3216         wsa = WS2_make_async ( s, fd, ASYNC_TYPE_READ, iovec, dwBufferCount,
3217                                lpFlags, lpFrom, lpFromlen,
3218                                lpOverlapped, lpCompletionRoutine );
3219
3220         if ( !wsa )
3221         {
3222             err = WSAEFAULT;
3223             goto err_free;
3224         }
3225
3226         if ( ( ret = register_new_async ( &wsa->async )) )
3227         {
3228             err = NtStatusToWSAError ( ret );
3229
3230             if ( !lpOverlapped )
3231                 HeapFree ( GetProcessHeap(), 0, wsa->async.iosb );
3232             HeapFree ( GetProcessHeap(), 0, wsa );
3233             goto err_free;
3234         }
3235
3236         /* Try immediate completion */
3237         if ( lpOverlapped && !NtResetEvent( lpOverlapped->hEvent, NULL ) )
3238         {
3239             if  ( WSAGetOverlappedResult ( s, lpOverlapped,
3240                                            lpNumberOfBytesRecvd, FALSE, lpFlags) )
3241                 return 0;
3242
3243             if ( (err = WSAGetLastError ()) != WSA_IO_INCOMPLETE )
3244                 goto error;
3245         }
3246
3247         WSASetLastError ( WSA_IO_PENDING );
3248         return SOCKET_ERROR;
3249     }
3250
3251     if ( _is_blocking(s) )
3252     {
3253         /* block here */
3254         /* FIXME: OOB and exceptfds? */
3255         do_block(fd, POLLIN);
3256     }
3257
3258     n = WS2_recv ( fd, iovec, dwBufferCount, lpFrom, lpFromlen, lpFlags );
3259     if ( n == -1 )
3260     {
3261         err = wsaErrno();
3262         goto err_free;
3263     }
3264
3265     TRACE(" -> %i bytes\n", n);
3266     *lpNumberOfBytesRecvd = n;
3267
3268     HeapFree (GetProcessHeap(), 0, iovec);
3269     release_sock_fd( s, fd );
3270     _enable_event(SOCKET2HANDLE(s), FD_READ, 0, 0);
3271
3272     return 0;
3273
3274 err_free:
3275     HeapFree (GetProcessHeap(), 0, iovec);
3276
3277 err_close:
3278     release_sock_fd( s, fd );
3279
3280 error:
3281     WARN(" -> ERROR %d\n", err);
3282     WSASetLastError ( err );
3283     return SOCKET_ERROR;
3284 }
3285
3286 /***********************************************************************
3287  *              WSCInstallProvider             (WS2_32.88)
3288  */
3289 INT WINAPI WSCInstallProvider( const LPGUID lpProviderId,
3290                                LPCWSTR lpszProviderDllPath,
3291                                const LPWSAPROTOCOL_INFOW lpProtocolInfoList,
3292                                DWORD dwNumberOfEntries,
3293                                LPINT lpErrno )
3294 {
3295     FIXME("(%s, %s, %p, %ld, %p): stub !\n", debugstr_guid(lpProviderId),
3296           debugstr_w(lpszProviderDllPath), lpProtocolInfoList,
3297           dwNumberOfEntries, lpErrno);
3298     *lpErrno = 0;
3299     return 0;
3300 }
3301
3302
3303 /***********************************************************************
3304  *              WSCDeinstallProvider             (WS2_32.83)
3305  */
3306 INT WINAPI WSCDeinstallProvider(LPGUID lpProviderId, LPINT lpErrno)
3307 {
3308     FIXME("(%s, %p): stub !\n", debugstr_guid(lpProviderId), lpErrno);
3309     *lpErrno = 0;
3310     return 0;
3311 }
3312
3313
3314 /***********************************************************************
3315  *              WSAAccept                        (WS2_32.26)
3316  */
3317 SOCKET WINAPI WSAAccept( SOCKET s, struct WS_sockaddr *addr, LPINT addrlen,
3318                LPCONDITIONPROC lpfnCondition, DWORD dwCallbackData)
3319 {
3320
3321        int ret = 0, size = 0;
3322        WSABUF CallerId, CallerData, CalleeId, CalleeData;
3323        /*        QOS SQOS, GQOS; */
3324        GROUP g;
3325        SOCKET cs;
3326        SOCKADDR src_addr, dst_addr;
3327
3328        TRACE("Socket  %u, sockaddr %p, addrlen %p, fnCondition %p, dwCallbackData %ld\n",
3329                s, addr, addrlen, lpfnCondition, dwCallbackData);
3330
3331
3332        size = sizeof(src_addr);
3333        cs = WS_accept(s, &src_addr, &size);
3334
3335        if (cs == SOCKET_ERROR) return SOCKET_ERROR;
3336
3337        CallerId.buf = (char *)&src_addr;
3338        CallerId.len = sizeof(src_addr);
3339
3340        CallerData.buf = NULL;
3341        CallerData.len = (ULONG)NULL;
3342
3343        WS_getsockname(cs, &dst_addr, &size);
3344
3345        CalleeId.buf = (char *)&dst_addr;
3346        CalleeId.len = sizeof(dst_addr);
3347
3348
3349        ret = (*lpfnCondition)(&CallerId, &CallerData, NULL, NULL,
3350                        &CalleeId, &CalleeData, &g, dwCallbackData);
3351
3352        switch (ret)
3353        {
3354                case CF_ACCEPT:
3355                        if (addr && addrlen)
3356                                addr = memcpy(addr, &src_addr, (*addrlen > size) ?  size : *addrlen );
3357                        return cs;
3358                case CF_DEFER:
3359                        SERVER_START_REQ ( set_socket_deferred )
3360                        {
3361                            req->handle = SOCKET2HANDLE (s);
3362                            req->deferred = SOCKET2HANDLE (cs);
3363                            if ( !wine_server_call_err ( req ) )
3364                            {
3365                                SetLastError ( WSATRY_AGAIN );
3366                                WS_closesocket ( cs );
3367                            }
3368                        }
3369                        SERVER_END_REQ;
3370                        return SOCKET_ERROR;
3371                case CF_REJECT:
3372                        WS_closesocket(cs);
3373                        SetLastError(WSAECONNREFUSED);
3374                        return SOCKET_ERROR;
3375                default:
3376                        FIXME("Unknown return type from Condition function\n");
3377                        SetLastError(WSAENOTSOCK);
3378                        return SOCKET_ERROR;
3379                }
3380 }
3381
3382 /***********************************************************************
3383  *              WSAEnumProtocolsA                        (WS2_32.37)
3384  */
3385 int WINAPI WSAEnumProtocolsA(LPINT lpiProtocols, LPWSAPROTOCOL_INFOA lpProtocolBuffer, LPDWORD lpdwBufferLength)
3386 {
3387     FIXME("(%p,%p,%p): stub\n", lpiProtocols,lpProtocolBuffer, lpdwBufferLength);
3388     return 0;
3389 }
3390
3391 /***********************************************************************
3392  *              WSAEnumProtocolsW                        (WS2_32.38)
3393  */
3394 int WINAPI WSAEnumProtocolsW(LPINT lpiProtocols, LPWSAPROTOCOL_INFOW lpProtocolBuffer, LPDWORD lpdwBufferLength)
3395 {
3396     FIXME("(%p,%p,%p): stub\n", lpiProtocols,lpProtocolBuffer, lpdwBufferLength);
3397     return 0;
3398 }
3399
3400 /***********************************************************************
3401  *              WSADuplicateSocketA                      (WS2_32.32)
3402  */
3403 int WINAPI WSADuplicateSocketA( SOCKET s, DWORD dwProcessId, LPWSAPROTOCOL_INFOA lpProtocolInfo )
3404 {
3405    HANDLE hProcess;
3406
3407    TRACE("(%d,%lx,%p)\n", s, dwProcessId, lpProtocolInfo);
3408    memset(lpProtocolInfo, 0, sizeof(*lpProtocolInfo));
3409    /* FIXME: WS_getsockopt(s, WS_SOL_SOCKET, SO_PROTOCOL_INFO, lpProtocolInfo, sizeof(*lpProtocolInfo)); */
3410    /* I don't know what the real Windoze does next, this is a hack */
3411    /* ...we could duplicate and then use ConvertToGlobalHandle on the duplicate, then let
3412     * the target use the global duplicate, or we could copy a reference to us to the structure
3413     * and let the target duplicate it from us, but let's do it as simple as possible */
3414    hProcess = OpenProcess(PROCESS_DUP_HANDLE, FALSE, dwProcessId);
3415    DuplicateHandle(GetCurrentProcess(), SOCKET2HANDLE(s),
3416                    hProcess, (LPHANDLE)&lpProtocolInfo->dwCatalogEntryId,
3417                    0, FALSE, DUPLICATE_SAME_ACCESS);
3418    CloseHandle(hProcess);
3419    lpProtocolInfo->dwServiceFlags4 = 0xff00ff00; /* magic */
3420    return 0;
3421 }
3422
3423 /***********************************************************************
3424  *              WSAInstallServiceClassA                  (WS2_32.48)
3425  */
3426 int WINAPI WSAInstallServiceClassA(LPWSASERVICECLASSINFOA info)
3427 {
3428     FIXME("Request to install service %s\n",debugstr_a(info->lpszServiceClassName));
3429     WSASetLastError(WSAEACCES);
3430     return SOCKET_ERROR;
3431 }
3432
3433 /***********************************************************************
3434  *              WSAInstallServiceClassW                  (WS2_32.49)
3435  */
3436 int WINAPI WSAInstallServiceClassW(LPWSASERVICECLASSINFOW info)
3437 {
3438     FIXME("Request to install service %s\n",debugstr_w(info->lpszServiceClassName));
3439     WSASetLastError(WSAEACCES);
3440     return SOCKET_ERROR;
3441 }
3442
3443 /***********************************************************************
3444  *              WSARemoveServiceClass                    (WS2_32.70)
3445  */
3446 int WINAPI WSARemoveServiceClass(LPGUID info)
3447 {
3448     FIXME("Request to remove service %p\n",info);
3449     WSASetLastError(WSATYPE_NOT_FOUND);
3450     return SOCKET_ERROR;
3451 }