Accept VT_BOOL mixed with another type as valid combination in
[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                 if (bind(fd, uaddr, uaddrlen) < 0)
1305                 {
1306                     int loc_errno = errno;
1307                     WARN("\tfailure - errno = %i\n", errno);
1308                     errno = loc_errno;
1309                     switch (errno)
1310                     {
1311                     case EBADF:
1312                         SetLastError(WSAENOTSOCK);
1313                         break;
1314                     case EADDRNOTAVAIL:
1315                         SetLastError(WSAEINVAL);
1316                         break;
1317                     default:
1318                         SetLastError(wsaErrno());
1319                         break;
1320                     }
1321                 }
1322                 else
1323                 {
1324                     res=0; /* success */
1325                 }
1326                 ws_sockaddr_free(uaddr,name);
1327             }
1328         }
1329         release_sock_fd( s, fd );
1330     }
1331     return res;
1332 }
1333
1334 /***********************************************************************
1335  *              closesocket             (WS2_32.3)
1336  */
1337 int WINAPI WS_closesocket(SOCKET s)
1338 {
1339     TRACE("socket %08x\n", s);
1340     if (CloseHandle(SOCKET2HANDLE(s))) return 0;
1341     return SOCKET_ERROR;
1342 }
1343
1344 /***********************************************************************
1345  *              connect         (WS2_32.4)
1346  */
1347 int WINAPI WS_connect(SOCKET s, const struct WS_sockaddr* name, int namelen)
1348 {
1349     int fd = get_sock_fd( s, GENERIC_READ, NULL );
1350
1351     TRACE("socket %04x, ptr %p %s, length %d\n", s, name, debugstr_sockaddr(name), namelen);
1352
1353     if (fd != -1)
1354     {
1355         const struct sockaddr* uaddr;
1356         int uaddrlen;
1357
1358         uaddr=ws_sockaddr_ws2u(name,namelen,&uaddrlen);
1359         if (uaddr == NULL)
1360         {
1361             SetLastError(WSAEFAULT);
1362         }
1363         else
1364         {
1365             int rc;
1366
1367             rc=connect(fd, uaddr, uaddrlen);
1368             ws_sockaddr_free(uaddr,name);
1369             if (rc == 0)
1370                 goto connect_success;
1371         }
1372
1373         if (errno == EINPROGRESS)
1374         {
1375             /* tell wineserver that a connection is in progress */
1376             _enable_event(SOCKET2HANDLE(s), FD_CONNECT|FD_READ|FD_WRITE,
1377                           FD_CONNECT|FD_READ|FD_WRITE,
1378                           FD_WINE_CONNECTED|FD_WINE_LISTENING);
1379             if (_is_blocking(s))
1380             {
1381                 int result;
1382                 /* block here */
1383                 do_block(fd, POLLIN | POLLOUT );
1384                 _sync_sock_state(s); /* let wineserver notice connection */
1385                 /* retrieve any error codes from it */
1386                 result = _get_sock_error(s, FD_CONNECT_BIT);
1387                 if (result)
1388                     SetLastError(result);
1389                 else
1390                 {
1391                     goto connect_success;
1392                 }
1393             }
1394             else
1395             {
1396                 SetLastError(WSAEWOULDBLOCK);
1397             }
1398         }
1399         else
1400         {
1401             SetLastError(wsaErrno());
1402         }
1403         release_sock_fd( s, fd );
1404     }
1405     return SOCKET_ERROR;
1406
1407 connect_success:
1408     release_sock_fd( s, fd );
1409     _enable_event(SOCKET2HANDLE(s), FD_CONNECT|FD_READ|FD_WRITE,
1410                   FD_WINE_CONNECTED|FD_READ|FD_WRITE,
1411                   FD_CONNECT|FD_WINE_LISTENING);
1412     return 0;
1413 }
1414
1415 /***********************************************************************
1416  *              WSAConnect             (WS2_32.30)
1417  */
1418 int WINAPI WSAConnect ( SOCKET s, const struct WS_sockaddr* name, int namelen,
1419                         LPWSABUF lpCallerData, LPWSABUF lpCalleeData,
1420                         LPQOS lpSQOS, LPQOS lpGQOS )
1421 {
1422     if ( lpCallerData || lpCalleeData || lpSQOS || lpGQOS )
1423         FIXME ("unsupported parameters!\n");
1424     return WS_connect ( s, name, namelen );
1425 }
1426
1427
1428 /***********************************************************************
1429  *              getpeername             (WS2_32.5)
1430  */
1431 int WINAPI WS_getpeername(SOCKET s, struct WS_sockaddr *name, int *namelen)
1432 {
1433     int fd;
1434     int res;
1435
1436     TRACE("socket: %04x, ptr %p, len %8x\n", s, name, *namelen);
1437
1438     /* Check if what we've received is valid. Should we use IsBadReadPtr? */
1439     if( (name == NULL) || (namelen == NULL) )
1440     {
1441         SetLastError( WSAEFAULT );
1442         return SOCKET_ERROR;
1443     }
1444
1445     fd = get_sock_fd( s, 0, NULL );
1446     res = SOCKET_ERROR;
1447
1448     if (fd != -1)
1449     {
1450         struct sockaddr* uaddr;
1451         int uaddrlen;
1452
1453         uaddr=ws_sockaddr_alloc(name,namelen,&uaddrlen);
1454         if (getpeername(fd, uaddr, &uaddrlen) != 0)
1455         {
1456             SetLastError(wsaErrno());
1457         }
1458         else if (ws_sockaddr_u2ws(uaddr,uaddrlen,name,namelen) != 0)
1459         {
1460             /* The buffer was too small */
1461             SetLastError(WSAEFAULT);
1462         }
1463         else
1464         {
1465             res=0;
1466         }
1467         ws_sockaddr_free(uaddr,name);
1468         release_sock_fd( s, fd );
1469     }
1470     return res;
1471 }
1472
1473 /***********************************************************************
1474  *              getsockname             (WS2_32.6)
1475  */
1476 int WINAPI WS_getsockname(SOCKET s, struct WS_sockaddr *name, int *namelen)
1477 {
1478     int fd;
1479     int res;
1480
1481     TRACE("socket: %04x, ptr %p, len %8x\n", s, name, *namelen);
1482
1483     /* Check if what we've received is valid. Should we use IsBadReadPtr? */
1484     if( (name == NULL) || (namelen == NULL) )
1485     {
1486         SetLastError( WSAEFAULT );
1487         return SOCKET_ERROR;
1488     }
1489
1490     fd = get_sock_fd( s, 0, NULL );
1491     res = SOCKET_ERROR;
1492
1493     if (fd != -1)
1494     {
1495         struct sockaddr* uaddr;
1496         int uaddrlen;
1497
1498         uaddr=ws_sockaddr_alloc(name,namelen,&uaddrlen);
1499         if (getsockname(fd, uaddr, &uaddrlen) != 0)
1500         {
1501             SetLastError(wsaErrno());
1502         }
1503         else if (ws_sockaddr_u2ws(uaddr,uaddrlen,name,namelen) != 0)
1504         {
1505             /* The buffer was too small */
1506             SetLastError(WSAEFAULT);
1507         }
1508         else
1509         {
1510             res=0;
1511         }
1512         release_sock_fd( s, fd );
1513     }
1514     return res;
1515 }
1516
1517 /***********************************************************************
1518  *              getsockopt              (WS2_32.7)
1519  */
1520 INT WINAPI WS_getsockopt(SOCKET s, INT level,
1521                                   INT optname, char *optval, INT *optlen)
1522 {
1523     int fd;
1524
1525     TRACE("socket: %04x, level 0x%x, name 0x%x, ptr %8x, len %d\n", s, level,
1526           (int) optname, (int) optval, (int) *optlen);
1527     /* SO_OPENTYPE does not require a valid socket handle. */
1528     if (level == WS_SOL_SOCKET && optname == WS_SO_OPENTYPE)
1529     {
1530         if (!optlen || *optlen < sizeof(int) || !optval)
1531         {
1532             SetLastError(WSAEFAULT);
1533             return SOCKET_ERROR;
1534         }
1535         *(int *)optval = (int)TlsGetValue( opentype_tls_index );
1536         *optlen = sizeof(int);
1537         TRACE("getting global SO_OPENTYPE = 0x%x\n", *((int*)optval) );
1538         return 0;
1539     }
1540
1541     fd = get_sock_fd( s, 0, NULL );
1542     if (fd != -1)
1543     {
1544         if (!convert_sockopt(&level, &optname)) {
1545             SetLastError(WSAENOPROTOOPT);       /* Unknown option */
1546         } else {
1547             if (getsockopt(fd, (int) level, optname, optval, optlen) == 0 )
1548             {
1549                 release_sock_fd( s, fd );
1550                 return 0;
1551             }
1552             SetLastError((errno == EBADF) ? WSAENOTSOCK : wsaErrno());
1553         }
1554         release_sock_fd( s, fd );
1555     }
1556     return SOCKET_ERROR;
1557 }
1558
1559
1560 /***********************************************************************
1561  *              htonl                   (WINSOCK.8)
1562  *              htonl                   (WS2_32.8)
1563  */
1564 u_long WINAPI WS_htonl(u_long hostlong)
1565 {
1566     return htonl(hostlong);
1567 }
1568
1569
1570 /***********************************************************************
1571  *              htons                   (WINSOCK.9)
1572  *              htons                   (WS2_32.9)
1573  */
1574 u_short WINAPI WS_htons(u_short hostshort)
1575 {
1576     return htons(hostshort);
1577 }
1578
1579 /***********************************************************************
1580  *              WSAHtonl                (WS2_32.46)
1581  */
1582 int WINAPI WSAHtonl(SOCKET s, u_long hostlong, u_long *lpnetlong)
1583 {
1584     FIXME("stub.\n");
1585     return INVALID_SOCKET;
1586 }
1587
1588 /***********************************************************************
1589  *              WSAHtons                (WS2_32.47)
1590  */
1591 int WINAPI WSAHtons(SOCKET s, u_short hostshort, u_short *lpnetshort)
1592 {
1593     FIXME("stub.\n");
1594     return INVALID_SOCKET;
1595 }
1596
1597
1598 /***********************************************************************
1599  *              inet_addr               (WINSOCK.10)
1600  *              inet_addr               (WS2_32.11)
1601  */
1602 u_long WINAPI WS_inet_addr(const char *cp)
1603 {
1604     return inet_addr(cp);
1605 }
1606
1607
1608 /***********************************************************************
1609  *              ntohl                   (WINSOCK.14)
1610  *              ntohl                   (WS2_32.14)
1611  */
1612 u_long WINAPI WS_ntohl(u_long netlong)
1613 {
1614     return ntohl(netlong);
1615 }
1616
1617
1618 /***********************************************************************
1619  *              ntohs                   (WINSOCK.15)
1620  *              ntohs                   (WS2_32.15)
1621  */
1622 u_short WINAPI WS_ntohs(u_short netshort)
1623 {
1624     return ntohs(netshort);
1625 }
1626
1627
1628 /***********************************************************************
1629  *              inet_ntoa               (WS2_32.12)
1630  */
1631 char* WINAPI WS_inet_ntoa(struct WS_in_addr in)
1632 {
1633   /* use "buffer for dummies" here because some applications have
1634    * propensity to decode addresses in ws_hostent structure without
1635    * saving them first...
1636    */
1637     static char dbuffer[16]; /* Yes, 16: 4*3 digits + 3 '.' + 1 '\0' */
1638
1639     char* s = inet_ntoa(*((struct in_addr*)&in));
1640     if( s )
1641     {
1642         strcpy(dbuffer, s);
1643         return dbuffer;
1644     }
1645     SetLastError(wsaErrno());
1646     return NULL;
1647 }
1648
1649 /**********************************************************************
1650  *              WSAIoctl                (WS2_32.50)
1651  *
1652  *
1653  *   FIXME:  Only SIO_GET_INTERFACE_LIST option implemented.
1654  */
1655 INT WINAPI WSAIoctl (SOCKET s,
1656                      DWORD   dwIoControlCode,
1657                      LPVOID  lpvInBuffer,
1658                      DWORD   cbInBuffer,
1659                      LPVOID  lpbOutBuffer,
1660                      DWORD   cbOutBuffer,
1661                      LPDWORD lpcbBytesReturned,
1662                      LPWSAOVERLAPPED lpOverlapped,
1663                      LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
1664 {
1665    int fd = get_sock_fd( s, 0, NULL );
1666
1667    if (fd == -1) return SOCKET_ERROR;
1668
1669    switch( dwIoControlCode )
1670    {
1671    case SIO_GET_INTERFACE_LIST:
1672        {
1673            INTERFACE_INFO* intArray = (INTERFACE_INFO*)lpbOutBuffer;
1674            DWORD size, numInt, apiReturn;
1675
1676            TRACE ("-> SIO_GET_INTERFACE_LIST request\n");
1677
1678            if (!lpbOutBuffer)
1679            {
1680                release_sock_fd( s, fd );
1681                WSASetLastError(WSAEFAULT);
1682                return SOCKET_ERROR;
1683            }
1684            if (!lpcbBytesReturned)
1685            {
1686                release_sock_fd( s, fd );
1687                WSASetLastError(WSAEFAULT);
1688                return SOCKET_ERROR;
1689            }
1690
1691            apiReturn = GetAdaptersInfo(NULL, &size);
1692            if (apiReturn == ERROR_NO_DATA)
1693            {
1694                numInt = 0;
1695            }
1696            else if (apiReturn == ERROR_BUFFER_OVERFLOW)
1697            {
1698                PIP_ADAPTER_INFO table = (PIP_ADAPTER_INFO)HeapAlloc(GetProcessHeap(),0,size);
1699
1700                if (table)
1701                {
1702                   if (GetAdaptersInfo(table, &size) == NO_ERROR)
1703                   {
1704                      PIP_ADAPTER_INFO ptr;
1705
1706                      if (size > cbOutBuffer)
1707                      {
1708                         HeapFree(GetProcessHeap(),0,table);
1709                         release_sock_fd( s, fd );
1710                         WSASetLastError(WSAEFAULT);
1711                         return (SOCKET_ERROR);
1712                      }
1713                      for (ptr = table, numInt = 0; ptr;
1714                       ptr = ptr->Next, intArray++, numInt++)
1715                      {
1716                         unsigned int addr, mask, bcast;
1717                         struct ifreq ifInfo;
1718
1719                         /* Socket Status Flags */
1720                         strncpy(ifInfo.ifr_name, ptr->AdapterName, IFNAMSIZ);
1721                         ifInfo.ifr_name[IFNAMSIZ-1] = '\0';
1722                         if (ioctl(fd, SIOCGIFFLAGS, &ifInfo) < 0)
1723                         {
1724                            ERR ("Error obtaining status flags for socket!\n");
1725                            HeapFree(GetProcessHeap(),0,table);
1726                            release_sock_fd( s, fd );
1727                            WSASetLastError(WSAEINVAL);
1728                            return (SOCKET_ERROR);
1729                         }
1730                         else
1731                         {
1732                            /* set flags; the values of IFF_* are not the same
1733                               under Linux and Windows, therefore must generate
1734                               new flags */
1735                            intArray->iiFlags = 0;
1736                            if (ifInfo.ifr_flags & IFF_BROADCAST)
1737                               intArray->iiFlags |= WS_IFF_BROADCAST;
1738 #ifdef IFF_POINTOPOINT
1739                            if (ifInfo.ifr_flags & IFF_POINTOPOINT)
1740                               intArray->iiFlags |= WS_IFF_POINTTOPOINT;
1741 #endif
1742                            if (ifInfo.ifr_flags & IFF_LOOPBACK)
1743                               intArray->iiFlags |= WS_IFF_LOOPBACK;
1744                            if (ifInfo.ifr_flags & IFF_UP)
1745                               intArray->iiFlags |= WS_IFF_UP;
1746                         }
1747
1748                         addr = inet_addr(ptr->IpAddressList.IpAddress.String);
1749                         mask = inet_addr(ptr->IpAddressList.IpMask.String);
1750                         bcast = addr | (addr & !mask);
1751                         intArray->iiAddress.AddressIn.sin_family = AF_INET;
1752                         intArray->iiAddress.AddressIn.sin_port = 0;
1753                         intArray->iiAddress.AddressIn.sin_addr.WS_s_addr =
1754                          addr;
1755                         intArray->iiNetmask.AddressIn.sin_family = AF_INET;
1756                         intArray->iiNetmask.AddressIn.sin_port = 0;
1757                         intArray->iiNetmask.AddressIn.sin_addr.WS_s_addr =
1758                          mask;
1759                         intArray->iiBroadcastAddress.AddressIn.sin_family =
1760                          AF_INET;
1761                         intArray->iiBroadcastAddress.AddressIn.sin_port = 0;
1762                         intArray->iiBroadcastAddress.AddressIn.sin_addr.
1763                          WS_s_addr = bcast;
1764                      }
1765                   }
1766                   else
1767                   {
1768                      ERR ("Unable to get interface table!\n");
1769                      release_sock_fd( s, fd );
1770                      HeapFree(GetProcessHeap(),0,table);
1771                      WSASetLastError(WSAEINVAL);
1772                      return (SOCKET_ERROR);
1773                   }
1774                   HeapFree(GetProcessHeap(),0,table);
1775                }
1776                else
1777                {
1778                   release_sock_fd( s, fd );
1779                   WSASetLastError(WSAEINVAL);
1780                   return (SOCKET_ERROR);
1781                }
1782            }
1783            else
1784            {
1785                ERR ("Unable to get interface table!\n");
1786                release_sock_fd( s, fd );
1787                WSASetLastError(WSAEINVAL);
1788                return (SOCKET_ERROR);
1789            }
1790            /* Calculate the size of the array being returned */
1791            *lpcbBytesReturned = sizeof(INTERFACE_INFO) * numInt;
1792            break;
1793        }
1794
1795    default:
1796        WARN("\tunsupported WS_IOCTL cmd (%08lx)\n", dwIoControlCode);
1797        release_sock_fd( s, fd );
1798        WSASetLastError(WSAEOPNOTSUPP);
1799        return (SOCKET_ERROR);
1800    }
1801
1802    /* Function executed with no errors */
1803    release_sock_fd( s, fd );
1804    return (0);
1805 }
1806
1807
1808 /***********************************************************************
1809  *              ioctlsocket             (WS2_32.10)
1810  */
1811 int WINAPI WS_ioctlsocket(SOCKET s, long cmd, u_long *argp)
1812 {
1813     int fd;
1814     long newcmd  = cmd;
1815
1816     TRACE("socket %04x, cmd %08lx, ptr %p\n", s, cmd, argp);
1817
1818     switch( cmd )
1819     {
1820     case WS_FIONREAD:
1821         newcmd=FIONREAD;
1822         break;
1823
1824     case WS_FIONBIO:
1825         newcmd=FIONBIO;
1826         if( _get_sock_mask(s) )
1827         {
1828             /* AsyncSelect()'ed sockets are always nonblocking */
1829             if (*argp) return 0;
1830             SetLastError(WSAEINVAL);
1831             return SOCKET_ERROR;
1832         }
1833         if (*argp)
1834             _enable_event(SOCKET2HANDLE(s), 0, FD_WINE_NONBLOCKING, 0);
1835         else
1836             _enable_event(SOCKET2HANDLE(s), 0, 0, FD_WINE_NONBLOCKING);
1837         return 0;
1838
1839     case WS_SIOCATMARK:
1840         newcmd=SIOCATMARK;
1841         break;
1842
1843     case WS__IOW('f',125,u_long):
1844         WARN("Warning: WS1.1 shouldn't be using async I/O\n");
1845         SetLastError(WSAEINVAL);
1846         return SOCKET_ERROR;
1847
1848     case SIOCGIFBRDADDR:
1849     case SIOCGIFNETMASK:
1850     case SIOCGIFADDR:
1851         /* These don't need any special handling.  They are used by
1852            WsControl, and are here to suppress an unecessary warning. */
1853         break;
1854
1855     default:
1856         /* Netscape tries hard to use bogus ioctl 0x667e */
1857         WARN("\tunknown WS_IOCTL cmd (%08lx)\n", cmd);
1858         break;
1859     }
1860
1861     fd = get_sock_fd( s, 0, NULL );
1862     if (fd != -1)
1863     {
1864         if( ioctl(fd, newcmd, (char*)argp ) == 0 )
1865         {
1866             release_sock_fd( s, fd );
1867             return 0;
1868         }
1869         SetLastError((errno == EBADF) ? WSAENOTSOCK : wsaErrno());
1870         release_sock_fd( s, fd );
1871     }
1872     return SOCKET_ERROR;
1873 }
1874
1875 /***********************************************************************
1876  *              listen          (WS2_32.13)
1877  */
1878 int WINAPI WS_listen(SOCKET s, int backlog)
1879 {
1880     int fd = get_sock_fd( s, GENERIC_READ, NULL );
1881
1882     TRACE("socket %04x, backlog %d\n", s, backlog);
1883     if (fd != -1)
1884     {
1885         if (listen(fd, backlog) == 0)
1886         {
1887             release_sock_fd( s, fd );
1888             _enable_event(SOCKET2HANDLE(s), FD_ACCEPT,
1889                           FD_WINE_LISTENING,
1890                           FD_CONNECT|FD_WINE_CONNECTED);
1891             return 0;
1892         }
1893         SetLastError(wsaErrno());
1894         release_sock_fd( s, fd );
1895     }
1896     return SOCKET_ERROR;
1897 }
1898
1899 /***********************************************************************
1900  *              recv                    (WS2_32.16)
1901  */
1902 int WINAPI WS_recv(SOCKET s, char *buf, int len, int flags)
1903 {
1904     DWORD n, dwFlags = flags;
1905     WSABUF wsabuf;
1906
1907     wsabuf.len = len;
1908     wsabuf.buf = buf;
1909
1910     if ( WSARecvFrom (s, &wsabuf, 1, &n, &dwFlags, NULL, NULL, NULL, NULL) == SOCKET_ERROR )
1911         return SOCKET_ERROR;
1912     else
1913         return n;
1914 }
1915
1916 /***********************************************************************
1917  *              recvfrom                (WS2_32.17)
1918  */
1919 int WINAPI WS_recvfrom(SOCKET s, char *buf, INT len, int flags,
1920                                 struct WS_sockaddr *from, int *fromlen)
1921 {
1922     DWORD n, dwFlags = flags;
1923     WSABUF wsabuf;
1924
1925     wsabuf.len = len;
1926     wsabuf.buf = buf;
1927
1928     if ( WSARecvFrom (s, &wsabuf, 1, &n, &dwFlags, from, fromlen, NULL, NULL) == SOCKET_ERROR )
1929         return SOCKET_ERROR;
1930     else
1931         return n;
1932 }
1933
1934 /***********************************************************************
1935  *              select                  (WS2_32.18)
1936  */
1937 int WINAPI WS_select(int nfds, WS_fd_set *ws_readfds,
1938                      WS_fd_set *ws_writefds, WS_fd_set *ws_exceptfds,
1939                      const struct WS_timeval* ws_timeout)
1940 {
1941     int         highfd = 0;
1942     fd_set      readfds, writefds, exceptfds;
1943     fd_set     *p_read, *p_write, *p_except;
1944     int         readfd[FD_SETSIZE], writefd[FD_SETSIZE], exceptfd[FD_SETSIZE];
1945     struct timeval timeout, *timeoutaddr = NULL;
1946
1947     TRACE("read %p, write %p, excp %p timeout %p\n",
1948           ws_readfds, ws_writefds, ws_exceptfds, ws_timeout);
1949
1950     p_read = fd_set_import(&readfds, ws_readfds, GENERIC_READ, &highfd, readfd);
1951     p_write = fd_set_import(&writefds, ws_writefds, GENERIC_WRITE, &highfd, writefd);
1952     p_except = fd_set_import(&exceptfds, ws_exceptfds, 0, &highfd, exceptfd);
1953     if (ws_timeout)
1954     {
1955         timeoutaddr = &timeout;
1956         timeout.tv_sec=ws_timeout->tv_sec;
1957         timeout.tv_usec=ws_timeout->tv_usec;
1958     }
1959
1960     if( (highfd = select(highfd + 1, p_read, p_write, p_except, timeoutaddr)) > 0 )
1961     {
1962         fd_set_export(&readfds, p_except, ws_readfds, readfd);
1963         fd_set_export(&writefds, p_except, ws_writefds, writefd);
1964
1965         if (p_except && ws_exceptfds)
1966         {
1967             int i, j;
1968
1969             for (i = j = 0; i < ws_exceptfds->fd_count; i++)
1970             {
1971                 int fd = exceptfd[i];
1972                 SOCKET s = ws_exceptfds->fd_array[i];
1973                 if (fd == -1) continue;
1974                 if (FD_ISSET(fd, &exceptfds)) ws_exceptfds->fd_array[j++] = s;
1975                 release_sock_fd( s, fd );
1976             }
1977             ws_exceptfds->fd_count = j;
1978         }
1979         return highfd;
1980     }
1981     fd_set_unimport(ws_readfds, readfd);
1982     fd_set_unimport(ws_writefds, writefd);
1983     fd_set_unimport(ws_exceptfds, exceptfd);
1984
1985     if( highfd == 0 ) return 0;
1986     SetLastError(wsaErrno());
1987     return SOCKET_ERROR;
1988 }
1989
1990
1991 /***********************************************************************
1992  *              send                    (WS2_32.19)
1993  */
1994 int WINAPI WS_send(SOCKET s, const char *buf, int len, int flags)
1995 {
1996     DWORD n;
1997     WSABUF wsabuf;
1998
1999     wsabuf.len = len;
2000     wsabuf.buf = (char*) buf;
2001
2002     if ( WSASendTo ( s, &wsabuf, 1, &n, flags, NULL, 0, NULL, NULL) == SOCKET_ERROR )
2003         return SOCKET_ERROR;
2004     else
2005         return n;
2006 }
2007
2008 /***********************************************************************
2009  *              WSASend                 (WS2_32.72)
2010  */
2011 INT WINAPI WSASend( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
2012                     LPDWORD lpNumberOfBytesSent, DWORD dwFlags,
2013                     LPWSAOVERLAPPED lpOverlapped,
2014                     LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine )
2015 {
2016     return WSASendTo ( s, lpBuffers, dwBufferCount, lpNumberOfBytesSent, dwFlags,
2017                        NULL, 0, lpOverlapped, lpCompletionRoutine );
2018 }
2019
2020 /***********************************************************************
2021  *              WSASendDisconnect       (WS2_32.73)
2022  */
2023 INT WINAPI WSASendDisconnect( SOCKET s, LPWSABUF lpBuffers )
2024 {
2025     return WS_shutdown ( s, SD_SEND );
2026 }
2027
2028
2029 /***********************************************************************
2030  *              WSASendTo               (WS2_32.74)
2031  */
2032 INT WINAPI WSASendTo( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
2033                       LPDWORD lpNumberOfBytesSent, DWORD dwFlags,
2034                       const struct WS_sockaddr *to, int tolen,
2035                       LPWSAOVERLAPPED lpOverlapped,
2036                       LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine )
2037 {
2038     int i, n, fd, err = WSAENOTSOCK, flags, ret;
2039     struct iovec* iovec;
2040     struct ws2_async *wsa;
2041
2042     TRACE ("socket %04x, wsabuf %p, nbufs %ld, flags %ld, to %p, tolen %d, ovl %p, func %p\n",
2043            s, lpBuffers, dwBufferCount, dwFlags,
2044            to, tolen, lpOverlapped, lpCompletionRoutine);
2045
2046     fd = get_sock_fd( s, GENERIC_WRITE, &flags );
2047     TRACE ( "fd=%d, flags=%x\n", fd, flags );
2048
2049     if ( fd == -1 ) return SOCKET_ERROR;
2050
2051     if (flags & FD_FLAG_SEND_SHUTDOWN)
2052     {
2053         WSASetLastError ( WSAESHUTDOWN );
2054         goto err_close;
2055     }
2056
2057     if ( !lpNumberOfBytesSent )
2058     {
2059         err = WSAEFAULT;
2060         goto err_close;
2061     }
2062
2063     iovec = HeapAlloc (GetProcessHeap(), 0, dwBufferCount * sizeof (struct iovec) );
2064
2065     if ( !iovec )
2066     {
2067         err = WSAEFAULT;
2068         goto err_close;
2069     }
2070
2071     for ( i = 0; i < dwBufferCount; i++ )
2072     {
2073         iovec[i].iov_base = lpBuffers[i].buf;
2074         iovec[i].iov_len  = lpBuffers[i].len;
2075     }
2076
2077     if ( (lpOverlapped || lpCompletionRoutine) && flags & FD_FLAG_OVERLAPPED )
2078     {
2079         wsa = WS2_make_async ( s, fd, ASYNC_TYPE_WRITE, iovec, dwBufferCount,
2080                                &dwFlags, (struct WS_sockaddr*) to, &tolen,
2081                                lpOverlapped, lpCompletionRoutine );
2082         if ( !wsa )
2083         {
2084             err = WSAEFAULT;
2085             goto err_free;
2086         }
2087
2088         if ( ( ret = register_new_async ( &wsa->async )) )
2089         {
2090             err = NtStatusToWSAError ( ret );
2091
2092             if ( !lpOverlapped )
2093                 HeapFree ( GetProcessHeap(), 0, wsa->async.iosb );
2094             HeapFree ( GetProcessHeap(), 0, wsa );
2095             goto err_free;
2096         }
2097
2098         /* Try immediate completion */
2099         if ( lpOverlapped && !NtResetEvent( lpOverlapped->hEvent, NULL ) )
2100         {
2101             if  ( WSAGetOverlappedResult ( s, lpOverlapped,
2102                                            lpNumberOfBytesSent, FALSE, &dwFlags) )
2103                 return 0;
2104
2105             if ( (err = WSAGetLastError ()) != WSA_IO_INCOMPLETE )
2106                 goto error;
2107         }
2108
2109         WSASetLastError ( WSA_IO_PENDING );
2110         return SOCKET_ERROR;
2111     }
2112
2113     if (_is_blocking(s))
2114     {
2115         /* FIXME: exceptfds? */
2116         do_block(fd, POLLOUT);
2117     }
2118
2119     n = WS2_send ( fd, iovec, dwBufferCount, to, tolen, dwFlags );
2120     if ( n == -1 )
2121     {
2122         err = wsaErrno();
2123         if ( err == WSAEWOULDBLOCK )
2124             _enable_event (SOCKET2HANDLE(s), FD_WRITE, 0, 0);
2125         goto err_free;
2126     }
2127
2128     TRACE(" -> %i bytes\n", n);
2129     *lpNumberOfBytesSent = n;
2130
2131     HeapFree ( GetProcessHeap(), 0, iovec );
2132     release_sock_fd( s, fd );
2133     return 0;
2134
2135 err_free:
2136     HeapFree ( GetProcessHeap(), 0, iovec );
2137
2138 err_close:
2139     release_sock_fd( s, fd );
2140
2141 error:
2142     WARN (" -> ERROR %d\n", err);
2143     WSASetLastError (err);
2144     return SOCKET_ERROR;
2145 }
2146
2147 /***********************************************************************
2148  *              sendto          (WS2_32.20)
2149  */
2150 int WINAPI WS_sendto(SOCKET s, const char *buf, int len, int flags,
2151                               const struct WS_sockaddr *to, int tolen)
2152 {
2153     DWORD n;
2154     WSABUF wsabuf;
2155
2156     wsabuf.len = len;
2157     wsabuf.buf = (char*) buf;
2158
2159     if ( WSASendTo (s, &wsabuf, 1, &n, flags, to, tolen, NULL, NULL) == SOCKET_ERROR )
2160         return SOCKET_ERROR;
2161     else
2162         return n;
2163 }
2164
2165 /***********************************************************************
2166  *              setsockopt              (WS2_32.21)
2167  */
2168 int WINAPI WS_setsockopt(SOCKET s, int level, int optname,
2169                                   const char *optval, int optlen)
2170 {
2171     int fd;
2172     int woptval;
2173     struct linger linger;
2174     struct timeval tval;
2175
2176     TRACE("socket: %04x, level %d, name %d, ptr %p, len %d\n",
2177           s, level, optname, optval, optlen);
2178
2179     /* SO_OPENTYPE does not require a valid socket handle. */
2180     if (level == WS_SOL_SOCKET && optname == WS_SO_OPENTYPE)
2181     {
2182         if (optlen < sizeof(int) || !optval)
2183         {
2184             SetLastError(WSAEFAULT);
2185             return SOCKET_ERROR;
2186         }
2187         TlsSetValue( opentype_tls_index, (LPVOID)*(int *)optval );
2188         TRACE("setting global SO_OPENTYPE to 0x%x\n", *(int *)optval );
2189         return 0;
2190     }
2191
2192     /* For some reason the game GrandPrixLegends does set SO_DONTROUTE on its
2193      * socket. This will either not happen under windows or it is ignored in
2194      * windows (but it works in linux and therefor prevents the game to find
2195      * games outsite the current network) */
2196     if ( level==WS_SOL_SOCKET && optname==WS_SO_DONTROUTE ) 
2197     {
2198         FIXME("Does windows ignore SO_DONTROUTE?\n");
2199         return 0;
2200     }
2201
2202     /* Is a privileged and useless operation, so we don't. */
2203     if ((optname == WS_SO_DEBUG) && (level == WS_SOL_SOCKET))
2204     {
2205         FIXME("(%d,SOL_SOCKET,SO_DEBUG,%p(%ld)) attempted (is privileged). Ignoring.\n",s,optval,*(DWORD*)optval);
2206         return 0;
2207     }
2208
2209     if(optname == WS_SO_DONTLINGER && level == WS_SOL_SOCKET) {
2210         /* This is unique to WinSock and takes special conversion */
2211         linger.l_onoff  = *((int*)optval) ? 0: 1;
2212         linger.l_linger = 0;
2213         optname=SO_LINGER;
2214         optval = (char*)&linger;
2215         optlen = sizeof(struct linger);
2216         level = SOL_SOCKET;
2217     }
2218     else
2219     {
2220         if (!convert_sockopt(&level, &optname)) {
2221             ERR("Invalid level (%d) or optname (%d)\n", level, optname);
2222             SetLastError(WSAENOPROTOOPT);
2223             return SOCKET_ERROR;
2224         }
2225         if (optname == SO_LINGER && optval) {
2226             /* yes, uses unsigned short in both win16/win32 */
2227             linger.l_onoff  = ((UINT16*)optval)[0];
2228             linger.l_linger = ((UINT16*)optval)[1];
2229             /* FIXME: what is documented behavior if SO_LINGER optval
2230                is null?? */
2231             optval = (char*)&linger;
2232             optlen = sizeof(struct linger);
2233         }
2234         else if (optval && optlen < sizeof(int))
2235         {
2236             woptval= *((INT16 *) optval);
2237             optval= (char*) &woptval;
2238             optlen=sizeof(int);
2239         }
2240         if (level == SOL_SOCKET && is_timeout_option(optname))
2241         {
2242             if (optlen == sizeof(UINT32)) {
2243                 /* WinSock passes miliseconds instead of struct timeval */
2244                 tval.tv_usec = *(PUINT32)optval % 1000;
2245                 tval.tv_sec = *(PUINT32)optval / 1000;
2246                 /* min of 500 milisec */
2247                 if (tval.tv_sec == 0 && tval.tv_usec < 500) tval.tv_usec = 500;
2248                 optlen = sizeof(struct timeval);
2249                 optval = (char*)&tval;
2250             } else if (optlen == sizeof(struct timeval)) {
2251                 WARN("SO_SND/RCVTIMEO for %d bytes: assuming unixism\n", optlen);
2252             } else {
2253                 WARN("SO_SND/RCVTIMEO for %d bytes is weird: ignored\n", optlen);
2254                 return 0;
2255             }
2256         }
2257         if (level == SOL_SOCKET && optname == SO_RCVBUF && *(int*)optval < 2048)
2258         {
2259             WARN("SO_RCVBF for %d bytes is too small: ignored\n", *(int*)optval );
2260             return 0;
2261         }
2262     }
2263
2264
2265     fd = get_sock_fd( s, 0, NULL );
2266     if (fd == -1) return SOCKET_ERROR;
2267
2268     if (setsockopt(fd, level, optname, optval, optlen) == 0)
2269     {
2270         release_sock_fd( s, fd );
2271         return 0;
2272     }
2273     TRACE("Setting socket error, %d\n", wsaErrno());
2274     SetLastError(wsaErrno());
2275     release_sock_fd( s, fd );
2276     return SOCKET_ERROR;
2277 }
2278
2279 /***********************************************************************
2280  *              shutdown                (WS2_32.22)
2281  */
2282 int WINAPI WS_shutdown(SOCKET s, int how)
2283 {
2284     int fd, fd0 = -1, fd1 = -1, flags, err = WSAENOTSOCK;
2285     unsigned int clear_flags = 0;
2286
2287     fd = get_sock_fd( s, 0, &flags );
2288     TRACE("socket %04x, how %i %x\n", s, how, flags );
2289
2290     if (fd == -1)
2291         return SOCKET_ERROR;
2292
2293     switch( how )
2294     {
2295     case 0: /* drop receives */
2296         clear_flags |= FD_READ;
2297         break;
2298     case 1: /* drop sends */
2299         clear_flags |= FD_WRITE;
2300         break;
2301     case 2: /* drop all */
2302         clear_flags |= FD_READ|FD_WRITE;
2303     default:
2304         clear_flags |= FD_WINE_LISTENING;
2305     }
2306
2307     if ( flags & FD_FLAG_OVERLAPPED ) {
2308
2309         switch ( how )
2310         {
2311         case SD_RECEIVE:
2312             fd0 = fd;
2313             break;
2314         case SD_SEND:
2315             fd1 = fd;
2316             break;
2317         case SD_BOTH:
2318         default:
2319             fd0 = fd;
2320             fd1 = get_sock_fd ( s, 0, NULL );
2321             break;
2322         }
2323
2324         if ( fd0 != -1 )
2325         {
2326             err = WS2_register_async_shutdown ( s, fd0, ASYNC_TYPE_READ );
2327             if ( err )
2328             {
2329                 release_sock_fd( s, fd0 );
2330                 goto error;
2331             }
2332         }
2333         if ( fd1 != -1 )
2334         {
2335             err = WS2_register_async_shutdown ( s, fd1, ASYNC_TYPE_WRITE );
2336             if ( err )
2337             {
2338                 release_sock_fd( s, fd1 );
2339                 goto error;
2340             }
2341         }
2342     }
2343     else /* non-overlapped mode */
2344     {
2345         if ( shutdown( fd, how ) )
2346         {
2347             err = wsaErrno ();
2348             release_sock_fd( s, fd );
2349             goto error;
2350         }
2351         release_sock_fd( s, fd );
2352     }
2353
2354     _enable_event( SOCKET2HANDLE(s), 0, 0, clear_flags );
2355     if ( how > 1) WSAAsyncSelect( s, 0, 0, 0 );
2356     return 0;
2357
2358 error:
2359     _enable_event( SOCKET2HANDLE(s), 0, 0, clear_flags );
2360     WSASetLastError ( err );
2361     return SOCKET_ERROR;
2362 }
2363
2364 /***********************************************************************
2365  *              socket          (WS2_32.23)
2366  */
2367 SOCKET WINAPI WS_socket(int af, int type, int protocol)
2368 {
2369     TRACE("af=%d type=%d protocol=%d\n", af, type, protocol);
2370
2371     return WSASocketA ( af, type, protocol, NULL, 0,
2372                         (TlsGetValue(opentype_tls_index) ? 0 : WSA_FLAG_OVERLAPPED) );
2373 }
2374
2375
2376 /***********************************************************************
2377  *              gethostbyaddr           (WS2_32.51)
2378  */
2379 struct WS_hostent* WINAPI WS_gethostbyaddr(const char *addr, int len, int type)
2380 {
2381     struct WS_hostent *retval = NULL;
2382     struct hostent* host;
2383
2384 #ifdef HAVE_LINUX_GETHOSTBYNAME_R_6
2385     char *extrabuf;
2386     int ebufsize=1024;
2387     struct hostent hostentry;
2388     int locerr=ENOBUFS;
2389     host = NULL;
2390     extrabuf=HeapAlloc(GetProcessHeap(),0,ebufsize) ;
2391     while(extrabuf) {
2392         int res = gethostbyaddr_r(addr, len, type,
2393                                   &hostentry, extrabuf, ebufsize, &host, &locerr);
2394         if( res != ERANGE) break;
2395         ebufsize *=2;
2396         extrabuf=HeapReAlloc(GetProcessHeap(),0,extrabuf,ebufsize) ;
2397     }
2398     if (!host) SetLastError((locerr < 0) ? wsaErrno() : wsaHerrno(locerr));
2399 #else
2400     EnterCriticalSection( &csWSgetXXXbyYYY );
2401     host = gethostbyaddr(addr, len, type);
2402     if (!host) SetLastError((h_errno < 0) ? wsaErrno() : wsaHerrno(h_errno));
2403 #endif
2404     if( host != NULL ) retval = WS_dup_he(host);
2405 #ifdef  HAVE_LINUX_GETHOSTBYNAME_R_6
2406     HeapFree(GetProcessHeap(),0,extrabuf);
2407 #else
2408     LeaveCriticalSection( &csWSgetXXXbyYYY );
2409 #endif
2410     TRACE("ptr %p, len %d, type %d ret %p\n", addr, len, type, retval);
2411     return retval;
2412 }
2413
2414 /***********************************************************************
2415  *              gethostbyname           (WS2_32.52)
2416  */
2417 struct WS_hostent* WINAPI WS_gethostbyname(const char* name)
2418 {
2419     struct WS_hostent *retval = NULL;
2420     struct hostent*     host;
2421 #ifdef  HAVE_LINUX_GETHOSTBYNAME_R_6
2422     char *extrabuf;
2423     int ebufsize=1024;
2424     struct hostent hostentry;
2425     int locerr = ENOBUFS;
2426 #endif
2427     char buf[100];
2428     if( !name) {
2429         name = buf;
2430         if( gethostname( buf, 100) == -1) {
2431             SetLastError( WSAENOBUFS); /* appropriate ? */
2432             return retval;
2433         }
2434     }
2435 #ifdef  HAVE_LINUX_GETHOSTBYNAME_R_6
2436     host = NULL;
2437     extrabuf=HeapAlloc(GetProcessHeap(),0,ebufsize) ;
2438     while(extrabuf) {
2439         int res = gethostbyname_r(name, &hostentry, extrabuf, ebufsize, &host, &locerr);
2440         if( res != ERANGE) break;
2441         ebufsize *=2;
2442         extrabuf=HeapReAlloc(GetProcessHeap(),0,extrabuf,ebufsize) ;
2443     }
2444     if (!host) SetLastError((locerr < 0) ? wsaErrno() : wsaHerrno(locerr));
2445 #else
2446     EnterCriticalSection( &csWSgetXXXbyYYY );
2447     host = gethostbyname(name);
2448     if (!host) SetLastError((h_errno < 0) ? wsaErrno() : wsaHerrno(h_errno));
2449 #endif
2450     if (host) retval = WS_dup_he(host);
2451 #ifdef  HAVE_LINUX_GETHOSTBYNAME_R_6
2452     HeapFree(GetProcessHeap(),0,extrabuf);
2453 #else
2454     LeaveCriticalSection( &csWSgetXXXbyYYY );
2455 #endif
2456     TRACE( "%s ret %p\n", debugstr_a(name), retval );
2457     return retval;
2458 }
2459
2460
2461 /***********************************************************************
2462  *              getprotobyname          (WS2_32.53)
2463  */
2464 struct WS_protoent* WINAPI WS_getprotobyname(const char* name)
2465 {
2466     struct WS_protoent* retval = NULL;
2467 #ifdef HAVE_GETPROTOBYNAME
2468     struct protoent*     proto;
2469     EnterCriticalSection( &csWSgetXXXbyYYY );
2470     if( (proto = getprotobyname(name)) != NULL )
2471     {
2472         retval = WS_dup_pe(proto);
2473     }
2474     else {
2475         MESSAGE("protocol %s not found; You might want to add "
2476                 "this to /etc/protocols\n", debugstr_a(name) );
2477         SetLastError(WSANO_DATA);
2478     }
2479     LeaveCriticalSection( &csWSgetXXXbyYYY );
2480 #endif
2481     TRACE( "%s ret %p\n", debugstr_a(name), retval );
2482     return retval;
2483 }
2484
2485
2486 /***********************************************************************
2487  *              getprotobynumber        (WS2_32.54)
2488  */
2489 struct WS_protoent* WINAPI WS_getprotobynumber(int number)
2490 {
2491     struct WS_protoent* retval = NULL;
2492 #ifdef HAVE_GETPROTOBYNUMBER
2493     struct protoent*     proto;
2494     EnterCriticalSection( &csWSgetXXXbyYYY );
2495     if( (proto = getprotobynumber(number)) != NULL )
2496     {
2497         retval = WS_dup_pe(proto);
2498     }
2499     else {
2500         MESSAGE("protocol number %d not found; You might want to add "
2501                 "this to /etc/protocols\n", number );
2502         SetLastError(WSANO_DATA);
2503     }
2504     LeaveCriticalSection( &csWSgetXXXbyYYY );
2505 #endif
2506     TRACE("%i ret %p\n", number, retval);
2507     return retval;
2508 }
2509
2510
2511 /***********************************************************************
2512  *              getservbyname           (WS2_32.55)
2513  */
2514 struct WS_servent* WINAPI WS_getservbyname(const char *name, const char *proto)
2515 {
2516     struct WS_servent* retval = NULL;
2517     struct servent*     serv;
2518     char *name_str;
2519     char *proto_str = NULL;
2520
2521     if (!(name_str = strdup_lower(name))) return NULL;
2522
2523     if (proto && *proto)
2524     {
2525         if (!(proto_str = strdup_lower(proto)))
2526         {
2527             HeapFree( GetProcessHeap(), 0, name_str );
2528             return NULL;
2529         }
2530     }
2531
2532     EnterCriticalSection( &csWSgetXXXbyYYY );
2533     serv = getservbyname(name_str, proto_str);
2534     if( serv != NULL )
2535     {
2536         retval = WS_dup_se(serv);
2537     }
2538     else SetLastError(WSANO_DATA);
2539     LeaveCriticalSection( &csWSgetXXXbyYYY );
2540     if (proto_str) HeapFree( GetProcessHeap(), 0, proto_str );
2541     HeapFree( GetProcessHeap(), 0, name_str );
2542     TRACE( "%s, %s ret %p\n", debugstr_a(name), debugstr_a(proto), retval );
2543     return retval;
2544 }
2545
2546
2547 /***********************************************************************
2548  *              getservbyport           (WS2_32.56)
2549  */
2550 struct WS_servent* WINAPI WS_getservbyport(int port, const char *proto)
2551 {
2552     struct WS_servent* retval = NULL;
2553 #ifdef HAVE_GETSERVBYPORT
2554     struct servent*     serv;
2555     char *proto_str = NULL;
2556
2557     if (proto && *proto)
2558     {
2559         if (!(proto_str = strdup_lower(proto))) return NULL;
2560     }
2561     EnterCriticalSection( &csWSgetXXXbyYYY );
2562     if( (serv = getservbyport(port, proto_str)) != NULL ) {
2563         retval = WS_dup_se(serv);
2564     }
2565     else SetLastError(WSANO_DATA);
2566     LeaveCriticalSection( &csWSgetXXXbyYYY );
2567     if (proto_str) HeapFree( GetProcessHeap(), 0, proto_str );
2568 #endif
2569     TRACE("%d (i.e. port %d), %s ret %p\n", port, (int)ntohl(port), debugstr_a(proto), retval);
2570     return retval;
2571 }
2572
2573
2574 /***********************************************************************
2575  *              gethostname           (WS2_32.57)
2576  */
2577 int WINAPI WS_gethostname(char *name, int namelen)
2578 {
2579     TRACE("name %p, len %d\n", name, namelen);
2580
2581     if (gethostname(name, namelen) == 0)
2582     {
2583         TRACE("<- '%s'\n", name);
2584         return 0;
2585     }
2586     SetLastError((errno == EINVAL) ? WSAEFAULT : wsaErrno());
2587     TRACE("<- ERROR !\n");
2588     return SOCKET_ERROR;
2589 }
2590
2591
2592 /* ------------------------------------- Windows sockets extensions -- *
2593  *                                                                     *
2594  * ------------------------------------------------------------------- */
2595
2596 /***********************************************************************
2597  *              WSAEnumNetworkEvents (WS2_32.36)
2598  */
2599 int WINAPI WSAEnumNetworkEvents(SOCKET s, WSAEVENT hEvent, LPWSANETWORKEVENTS lpEvent)
2600 {
2601     int ret;
2602
2603     TRACE("%08x, hEvent %p, lpEvent %08x\n", s, hEvent, (unsigned)lpEvent );
2604
2605     SERVER_START_REQ( get_socket_event )
2606     {
2607         req->handle  = SOCKET2HANDLE(s);
2608         req->service = TRUE;
2609         req->c_event = hEvent;
2610         wine_server_set_reply( req, lpEvent->iErrorCode, sizeof(lpEvent->iErrorCode) );
2611         if (!(ret = wine_server_call(req))) lpEvent->lNetworkEvents = reply->pmask & reply->mask;
2612     }
2613     SERVER_END_REQ;
2614     if (!ret) return 0;
2615     SetLastError(WSAEINVAL);
2616     return SOCKET_ERROR;
2617 }
2618
2619 /***********************************************************************
2620  *              WSAEventSelect (WS2_32.39)
2621  */
2622 int WINAPI WSAEventSelect(SOCKET s, WSAEVENT hEvent, LONG lEvent)
2623 {
2624     int ret;
2625
2626     TRACE("%08x, hEvent %p, event %08x\n", s, hEvent, (unsigned)lEvent );
2627
2628     SERVER_START_REQ( set_socket_event )
2629     {
2630         req->handle = SOCKET2HANDLE(s);
2631         req->mask   = lEvent;
2632         req->event  = hEvent;
2633         req->window = 0;
2634         req->msg    = 0;
2635         ret = wine_server_call( req );
2636     }
2637     SERVER_END_REQ;
2638     if (!ret) return 0;
2639     SetLastError(WSAEINVAL);
2640     return SOCKET_ERROR;
2641 }
2642
2643 /**********************************************************************
2644  *      WSAGetOverlappedResult (WS2_32.40)
2645  */
2646 BOOL WINAPI WSAGetOverlappedResult ( SOCKET s, LPWSAOVERLAPPED lpOverlapped,
2647                                      LPDWORD lpcbTransfer, BOOL fWait,
2648                                      LPDWORD lpdwFlags )
2649 {
2650     DWORD r;
2651
2652     TRACE ( "socket %d ovl %p trans %p, wait %d flags %p\n",
2653             s, lpOverlapped, lpcbTransfer, fWait, lpdwFlags );
2654
2655     if ( !(lpOverlapped && lpOverlapped->hEvent) )
2656     {
2657         ERR ( "Invalid pointer\n" );
2658         WSASetLastError (WSA_INVALID_PARAMETER);
2659         return FALSE;
2660     }
2661
2662     if ( fWait )
2663     {
2664         while ( WaitForSingleObjectEx (lpOverlapped->hEvent, INFINITE, TRUE) == STATUS_USER_APC );
2665     }
2666     else if ( lpOverlapped->Internal == STATUS_PENDING )
2667     {
2668         /* Wait in order to give APCs a chance to run. */
2669         /* This is cheating, so we must set the event again in case of success -
2670            it may be a non-manual reset event. */
2671         while ( (r = WaitForSingleObjectEx (lpOverlapped->hEvent, 0, TRUE)) == STATUS_USER_APC );
2672         if ( r == WAIT_OBJECT_0 )
2673             NtSetEvent ( lpOverlapped->hEvent, NULL );
2674     }
2675
2676     if ( lpcbTransfer )
2677         *lpcbTransfer = lpOverlapped->InternalHigh;
2678
2679     if ( lpdwFlags )
2680         *lpdwFlags = lpOverlapped->Offset;
2681
2682     switch ( lpOverlapped->Internal )
2683     {
2684     case STATUS_SUCCESS:
2685         return TRUE;
2686     case STATUS_PENDING:
2687         WSASetLastError ( WSA_IO_INCOMPLETE );
2688         if (fWait) ERR ("PENDING status after waiting!\n");
2689         return FALSE;
2690     default:
2691         WSASetLastError ( NtStatusToWSAError ( lpOverlapped->Internal ));
2692         return FALSE;
2693     }
2694 }
2695
2696
2697 /***********************************************************************
2698  *      WSAAsyncSelect                  (WS2_32.101)
2699  */
2700 INT WINAPI WSAAsyncSelect(SOCKET s, HWND hWnd, UINT uMsg, LONG lEvent)
2701 {
2702     int ret;
2703
2704     TRACE("%x, hWnd %p, uMsg %08x, event %08lx\n", s, hWnd, uMsg, lEvent );
2705
2706     SERVER_START_REQ( set_socket_event )
2707     {
2708         req->handle = SOCKET2HANDLE(s);
2709         req->mask   = lEvent;
2710         req->event  = 0;
2711         req->window = hWnd;
2712         req->msg    = uMsg;
2713         ret = wine_server_call( req );
2714     }
2715     SERVER_END_REQ;
2716     if (!ret) return 0;
2717     SetLastError(WSAEINVAL);
2718     return SOCKET_ERROR;
2719 }
2720
2721 /***********************************************************************
2722  *      WSACreateEvent          (WS2_32.31)
2723  *
2724  */
2725 WSAEVENT WINAPI WSACreateEvent(void)
2726 {
2727     /* Create a manual-reset event, with initial state: unsignealed */
2728     TRACE("\n");
2729
2730     return CreateEventA(NULL, TRUE, FALSE, NULL);
2731 }
2732
2733 /***********************************************************************
2734  *      WSACloseEvent          (WS2_32.29)
2735  *
2736  */
2737 BOOL WINAPI WSACloseEvent(WSAEVENT event)
2738 {
2739     TRACE ("event=%p\n", event);
2740
2741     return CloseHandle(event);
2742 }
2743
2744 /***********************************************************************
2745  *      WSASocketA          (WS2_32.78)
2746  *
2747  */
2748 SOCKET WINAPI WSASocketA(int af, int type, int protocol,
2749                          LPWSAPROTOCOL_INFOA lpProtocolInfo,
2750                          GROUP g, DWORD dwFlags)
2751 {
2752     SOCKET ret;
2753
2754    /*
2755       FIXME: The "advanced" parameters of WSASocketA (lpProtocolInfo,
2756       g, dwFlags except WSA_FLAG_OVERLAPPED) are ignored.
2757    */
2758
2759    TRACE("af=%d type=%d protocol=%d protocol_info=%p group=%d flags=0x%lx\n",
2760          af, type, protocol, lpProtocolInfo, g, dwFlags );
2761
2762     /* hack for WSADuplicateSocket */
2763     if (lpProtocolInfo && lpProtocolInfo->dwServiceFlags4 == 0xff00ff00) {
2764       ret = lpProtocolInfo->dwCatalogEntryId;
2765       TRACE("\tgot duplicate %04x\n", ret);
2766       return ret;
2767     }
2768
2769     /* check the socket family */
2770     switch(af)
2771     {
2772 #ifdef HAVE_IPX
2773         case WS_AF_IPX: af = AF_IPX;
2774 #endif
2775         case AF_INET:
2776         case AF_UNSPEC:
2777             break;
2778         default:
2779             SetLastError(WSAEAFNOSUPPORT);
2780             return INVALID_SOCKET;
2781     }
2782
2783     /* check the socket type */
2784     switch(type)
2785     {
2786         case WS_SOCK_STREAM:
2787             type=SOCK_STREAM;
2788             break;
2789         case WS_SOCK_DGRAM:
2790             type=SOCK_DGRAM;
2791             break;
2792         case WS_SOCK_RAW:
2793             type=SOCK_RAW;
2794             break;
2795         default:
2796             SetLastError(WSAESOCKTNOSUPPORT);
2797             return INVALID_SOCKET;
2798     }
2799
2800     /* check the protocol type */
2801     if ( protocol < 0 )  /* don't support negative values */
2802     {
2803         SetLastError(WSAEPROTONOSUPPORT);
2804         return INVALID_SOCKET;
2805     }
2806
2807     if ( af == AF_UNSPEC)  /* did they not specify the address family? */
2808         switch(protocol)
2809         {
2810           case IPPROTO_TCP:
2811              if (type == SOCK_STREAM) { af = AF_INET; break; }
2812           case IPPROTO_UDP:
2813              if (type == SOCK_DGRAM)  { af = AF_INET; break; }
2814           default: SetLastError(WSAEPROTOTYPE); return INVALID_SOCKET;
2815         }
2816
2817     SERVER_START_REQ( create_socket )
2818     {
2819         req->family   = af;
2820         req->type     = type;
2821         req->protocol = protocol;
2822         req->access   = GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE;
2823         req->flags    = dwFlags;
2824         req->inherit  = TRUE;
2825         set_error( wine_server_call( req ) );
2826         ret = HANDLE2SOCKET( reply->handle );
2827     }
2828     SERVER_END_REQ;
2829     if (ret)
2830     {
2831         TRACE("\tcreated %04x\n", ret );
2832         return ret;
2833     }
2834
2835     if (GetLastError() == WSAEACCES) /* raw socket denied */
2836     {
2837         if (type == SOCK_RAW)
2838             MESSAGE("WARNING: Trying to create a socket of type SOCK_RAW, will fail unless running as root\n");
2839         else
2840             MESSAGE("WS_SOCKET: not enough privileges to create socket, try running as root\n");
2841         SetLastError(WSAESOCKTNOSUPPORT);
2842     }
2843
2844     WARN("\t\tfailed!\n");
2845     return INVALID_SOCKET;
2846 }
2847
2848 /***********************************************************************
2849  *      WSAJoinLeaf          (WS2_32.58)
2850  *
2851  */
2852 SOCKET WINAPI WSAJoinLeaf(
2853         SOCKET s,
2854         const struct WS_sockaddr *addr,
2855         int addrlen,
2856         LPWSABUF lpCallerData,
2857         LPWSABUF lpCalleeData,
2858         LPQOS lpSQOS,
2859         LPQOS lpGQOS,
2860         DWORD dwFlags)
2861 {
2862     FIXME("stub.\n");
2863     return INVALID_SOCKET;
2864 }
2865
2866 /***********************************************************************
2867  *      __WSAFDIsSet                    (WS2_32.151)
2868  */
2869 int WINAPI __WSAFDIsSet(SOCKET s, WS_fd_set *set)
2870 {
2871   int i = set->fd_count;
2872
2873   TRACE("(%d,%8lx(%i))\n", s,(unsigned long)set, i);
2874
2875   while (i--)
2876       if (set->fd_array[i] == s) return 1;
2877   return 0;
2878 }
2879
2880 /***********************************************************************
2881  *      WSAIsBlocking                   (WINSOCK.114)
2882  *      WSAIsBlocking                   (WS2_32.114)
2883  */
2884 BOOL WINAPI WSAIsBlocking(void)
2885 {
2886   /* By default WinSock should set all its sockets to non-blocking mode
2887    * and poll in PeekMessage loop when processing "blocking" ones. This
2888    * function is supposed to tell if the program is in this loop. Our
2889    * blocking calls are truly blocking so we always return FALSE.
2890    *
2891    * Note: It is allowed to call this function without prior WSAStartup().
2892    */
2893
2894   TRACE("\n");
2895   return FALSE;
2896 }
2897
2898 /***********************************************************************
2899  *      WSACancelBlockingCall           (WINSOCK.113)
2900  *      WSACancelBlockingCall           (WS2_32.113)
2901  */
2902 INT WINAPI WSACancelBlockingCall(void)
2903 {
2904     TRACE("\n");
2905     return 0;
2906 }
2907
2908 static INT WINAPI WSA_DefaultBlockingHook( FARPROC x )
2909 {
2910     FIXME("How was this called?\n");
2911     return x();
2912 }
2913
2914
2915 /***********************************************************************
2916  *      WSASetBlockingHook (WS2_32.109)
2917  */
2918 FARPROC WINAPI WSASetBlockingHook(FARPROC lpBlockFunc)
2919 {
2920   FARPROC prev = blocking_hook;
2921   blocking_hook = lpBlockFunc;
2922   TRACE("hook %p\n", lpBlockFunc);
2923   return prev;
2924 }
2925
2926
2927 /***********************************************************************
2928  *      WSAUnhookBlockingHook (WS2_32.110)
2929  */
2930 INT WINAPI WSAUnhookBlockingHook(void)
2931 {
2932     blocking_hook = WSA_DefaultBlockingHook;
2933     return 0;
2934 }
2935
2936
2937 /* ----------------------------------- end of API stuff */
2938
2939 /* ----------------------------------- helper functions -
2940  *
2941  * TODO: Merge WS_dup_..() stuff into one function that
2942  * would operate with a generic structure containing internal
2943  * pointers (via a template of some kind).
2944  */
2945
2946 static int list_size(char** l, int item_size)
2947 {
2948   int i,j = 0;
2949   if(l)
2950   { for(i=0;l[i];i++)
2951         j += (item_size) ? item_size : strlen(l[i]) + 1;
2952     j += (i + 1) * sizeof(char*); }
2953   return j;
2954 }
2955
2956 static int list_dup(char** l_src, char** l_to, int item_size)
2957 {
2958    char *p;
2959    int i;
2960
2961    for (i = 0; l_src[i]; i++) ;
2962    p = (char *)(l_to + i + 1);
2963    for (i = 0; l_src[i]; i++)
2964    {
2965        int count = ( item_size ) ? item_size : strlen(l_src[i]) + 1;
2966        memcpy(p, l_src[i], count);
2967        l_to[i] = p;
2968        p += count;
2969    }
2970    l_to[i] = NULL;
2971    return (p - (char *)l_to);
2972 }
2973
2974 /* ----- hostent */
2975
2976 /* duplicate hostent entry
2977  * and handle all Win16/Win32 dependent things (struct size, ...) *correctly*.
2978  * Dito for protoent and servent.
2979  */
2980 static struct WS_hostent *WS_dup_he(const struct hostent* p_he)
2981 {
2982     char *p;
2983     struct WS_hostent *p_to;
2984
2985     int size = (sizeof(*p_he) +
2986                 strlen(p_he->h_name) + 1 +
2987                 list_size(p_he->h_aliases, 0) +
2988                 list_size(p_he->h_addr_list, p_he->h_length));
2989
2990     if (!(p_to = check_buffer_he(size))) return NULL;
2991     p_to->h_addrtype = p_he->h_addrtype;
2992     p_to->h_length = p_he->h_length;
2993
2994     p = (char *)(p_to + 1);
2995     p_to->h_name = p;
2996     strcpy(p, p_he->h_name);
2997     p += strlen(p) + 1;
2998
2999     p_to->h_aliases = (char **)p;
3000     p += list_dup(p_he->h_aliases, p_to->h_aliases, 0);
3001
3002     p_to->h_addr_list = (char **)p;
3003     list_dup(p_he->h_addr_list, p_to->h_addr_list, p_he->h_length);
3004     return p_to;
3005 }
3006
3007 /* ----- protoent */
3008
3009 static struct WS_protoent *WS_dup_pe(const struct protoent* p_pe)
3010 {
3011     char *p;
3012     struct WS_protoent *p_to;
3013
3014     int size = (sizeof(*p_pe) +
3015                 strlen(p_pe->p_name) + 1 +
3016                 list_size(p_pe->p_aliases, 0));
3017
3018     if (!(p_to = check_buffer_pe(size))) return NULL;
3019     p_to->p_proto = p_pe->p_proto;
3020
3021     p = (char *)(p_to + 1);
3022     p_to->p_name = p;
3023     strcpy(p, p_pe->p_name);
3024     p += strlen(p) + 1;
3025
3026     p_to->p_aliases = (char **)p;
3027     list_dup(p_pe->p_aliases, p_to->p_aliases, 0);
3028     return p_to;
3029 }
3030
3031 /* ----- servent */
3032
3033 static struct WS_servent *WS_dup_se(const struct servent* p_se)
3034 {
3035     char *p;
3036     struct WS_servent *p_to;
3037
3038     int size = (sizeof(*p_se) +
3039                 strlen(p_se->s_proto) + 1 +
3040                 strlen(p_se->s_name) + 1 +
3041                 list_size(p_se->s_aliases, 0));
3042
3043     if (!(p_to = check_buffer_se(size))) return NULL;
3044     p_to->s_port = p_se->s_port;
3045
3046     p = (char *)(p_to + 1);
3047     p_to->s_name = p;
3048     strcpy(p, p_se->s_name);
3049     p += strlen(p) + 1;
3050
3051     p_to->s_proto = p;
3052     strcpy(p, p_se->s_proto);
3053     p += strlen(p) + 1;
3054
3055     p_to->s_aliases = (char **)p;
3056     list_dup(p_se->s_aliases, p_to->s_aliases, 0);
3057     return p_to;
3058 }
3059
3060 /* ----------------------------------- error handling */
3061
3062 UINT wsaErrno(void)
3063 {
3064     int loc_errno = errno;
3065     WARN("errno %d, (%s).\n", loc_errno, strerror(loc_errno));
3066
3067     switch(loc_errno)
3068     {
3069         case EINTR:             return WSAEINTR;
3070         case EBADF:             return WSAEBADF;
3071         case EPERM:
3072         case EACCES:            return WSAEACCES;
3073         case EFAULT:            return WSAEFAULT;
3074         case EINVAL:            return WSAEINVAL;
3075         case EMFILE:            return WSAEMFILE;
3076         case EWOULDBLOCK:       return WSAEWOULDBLOCK;
3077         case EINPROGRESS:       return WSAEINPROGRESS;
3078         case EALREADY:          return WSAEALREADY;
3079         case ENOTSOCK:          return WSAENOTSOCK;
3080         case EDESTADDRREQ:      return WSAEDESTADDRREQ;
3081         case EMSGSIZE:          return WSAEMSGSIZE;
3082         case EPROTOTYPE:        return WSAEPROTOTYPE;
3083         case ENOPROTOOPT:       return WSAENOPROTOOPT;
3084         case EPROTONOSUPPORT:   return WSAEPROTONOSUPPORT;
3085         case ESOCKTNOSUPPORT:   return WSAESOCKTNOSUPPORT;
3086         case EOPNOTSUPP:        return WSAEOPNOTSUPP;
3087         case EPFNOSUPPORT:      return WSAEPFNOSUPPORT;
3088         case EAFNOSUPPORT:      return WSAEAFNOSUPPORT;
3089         case EADDRINUSE:        return WSAEADDRINUSE;
3090         case EADDRNOTAVAIL:     return WSAEADDRNOTAVAIL;
3091         case ENETDOWN:          return WSAENETDOWN;
3092         case ENETUNREACH:       return WSAENETUNREACH;
3093         case ENETRESET:         return WSAENETRESET;
3094         case ECONNABORTED:      return WSAECONNABORTED;
3095         case EPIPE:
3096         case ECONNRESET:        return WSAECONNRESET;
3097         case ENOBUFS:           return WSAENOBUFS;
3098         case EISCONN:           return WSAEISCONN;
3099         case ENOTCONN:          return WSAENOTCONN;
3100         case ESHUTDOWN:         return WSAESHUTDOWN;
3101         case ETOOMANYREFS:      return WSAETOOMANYREFS;
3102         case ETIMEDOUT:         return WSAETIMEDOUT;
3103         case ECONNREFUSED:      return WSAECONNREFUSED;
3104         case ELOOP:             return WSAELOOP;
3105         case ENAMETOOLONG:      return WSAENAMETOOLONG;
3106         case EHOSTDOWN:         return WSAEHOSTDOWN;
3107         case EHOSTUNREACH:      return WSAEHOSTUNREACH;
3108         case ENOTEMPTY:         return WSAENOTEMPTY;
3109 #ifdef EPROCLIM
3110         case EPROCLIM:          return WSAEPROCLIM;
3111 #endif
3112 #ifdef EUSERS
3113         case EUSERS:            return WSAEUSERS;
3114 #endif
3115 #ifdef EDQUOT
3116         case EDQUOT:            return WSAEDQUOT;
3117 #endif
3118 #ifdef ESTALE
3119         case ESTALE:            return WSAESTALE;
3120 #endif
3121 #ifdef EREMOTE
3122         case EREMOTE:           return WSAEREMOTE;
3123 #endif
3124
3125        /* just in case we ever get here and there are no problems */
3126         case 0:                 return 0;
3127         default:
3128                 WARN("Unknown errno %d!\n", loc_errno);
3129                 return WSAEOPNOTSUPP;
3130     }
3131 }
3132
3133 UINT wsaHerrno(int loc_errno)
3134 {
3135
3136     WARN("h_errno %d.\n", loc_errno);
3137
3138     switch(loc_errno)
3139     {
3140         case HOST_NOT_FOUND:    return WSAHOST_NOT_FOUND;
3141         case TRY_AGAIN:         return WSATRY_AGAIN;
3142         case NO_RECOVERY:       return WSANO_RECOVERY;
3143         case NO_DATA:           return WSANO_DATA;
3144         case ENOBUFS:           return WSAENOBUFS;
3145
3146         case 0:                 return 0;
3147         default:
3148                 WARN("Unknown h_errno %d!\n", loc_errno);
3149                 return WSAEOPNOTSUPP;
3150     }
3151 }
3152
3153
3154 /***********************************************************************
3155  *              WSARecv                 (WS2_32.67)
3156  */
3157 int WINAPI WSARecv (SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
3158                     LPDWORD NumberOfBytesReceived, LPDWORD lpFlags,
3159                     LPWSAOVERLAPPED lpOverlapped,
3160                     LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
3161 {
3162     return WSARecvFrom (s, lpBuffers, dwBufferCount, NumberOfBytesReceived, lpFlags,
3163                         NULL, NULL, lpOverlapped, lpCompletionRoutine);
3164 }
3165
3166 /***********************************************************************
3167  *              WSARecvFrom             (WS2_32.69)
3168  */
3169 INT WINAPI WSARecvFrom( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
3170                         LPDWORD lpNumberOfBytesRecvd, LPDWORD lpFlags, struct WS_sockaddr *lpFrom,
3171                         LPINT lpFromlen, LPWSAOVERLAPPED lpOverlapped,
3172                         LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine )
3173
3174 {
3175     int i, n, fd, err = WSAENOTSOCK, flags, ret;
3176     struct iovec* iovec;
3177     struct ws2_async *wsa;
3178
3179     TRACE("socket %04x, wsabuf %p, nbufs %ld, flags %ld, from %p, fromlen %ld, ovl %p, func %p\n",
3180           s, lpBuffers, dwBufferCount, *lpFlags, lpFrom,
3181           (lpFromlen ? *lpFromlen : -1L),
3182           lpOverlapped, lpCompletionRoutine);
3183
3184     fd = get_sock_fd( s, GENERIC_READ, &flags );
3185     TRACE ( "fd=%d, flags=%x\n", fd, flags );
3186
3187     if (fd == -1) return SOCKET_ERROR;
3188
3189     if (flags & FD_FLAG_RECV_SHUTDOWN)
3190     {
3191         WSASetLastError ( WSAESHUTDOWN );
3192         goto err_close;
3193     }
3194
3195     iovec = HeapAlloc ( GetProcessHeap(), 0, dwBufferCount * sizeof (struct iovec) );
3196     if ( !iovec )
3197     {
3198         err = WSAEFAULT;
3199         goto err_close;
3200     }
3201
3202     for (i = 0; i < dwBufferCount; i++)
3203     {
3204         iovec[i].iov_base = lpBuffers[i].buf;
3205         iovec[i].iov_len  = lpBuffers[i].len;
3206     }
3207
3208     if ( (lpOverlapped || lpCompletionRoutine) && flags & FD_FLAG_OVERLAPPED )
3209     {
3210         wsa = WS2_make_async ( s, fd, ASYNC_TYPE_READ, iovec, dwBufferCount,
3211                                lpFlags, lpFrom, lpFromlen,
3212                                lpOverlapped, lpCompletionRoutine );
3213
3214         if ( !wsa )
3215         {
3216             err = WSAEFAULT;
3217             goto err_free;
3218         }
3219
3220         if ( ( ret = register_new_async ( &wsa->async )) )
3221         {
3222             err = NtStatusToWSAError ( ret );
3223
3224             if ( !lpOverlapped )
3225                 HeapFree ( GetProcessHeap(), 0, wsa->async.iosb );
3226             HeapFree ( GetProcessHeap(), 0, wsa );
3227             goto err_free;
3228         }
3229
3230         /* Try immediate completion */
3231         if ( lpOverlapped && !NtResetEvent( lpOverlapped->hEvent, NULL ) )
3232         {
3233             if  ( WSAGetOverlappedResult ( s, lpOverlapped,
3234                                            lpNumberOfBytesRecvd, FALSE, lpFlags) )
3235                 return 0;
3236
3237             if ( (err = WSAGetLastError ()) != WSA_IO_INCOMPLETE )
3238                 goto error;
3239         }
3240
3241         WSASetLastError ( WSA_IO_PENDING );
3242         return SOCKET_ERROR;
3243     }
3244
3245     if ( _is_blocking(s) )
3246     {
3247         /* block here */
3248         /* FIXME: OOB and exceptfds? */
3249         do_block(fd, POLLIN);
3250     }
3251
3252     n = WS2_recv ( fd, iovec, dwBufferCount, lpFrom, lpFromlen, lpFlags );
3253     if ( n == -1 )
3254     {
3255         err = wsaErrno();
3256         goto err_free;
3257     }
3258
3259     TRACE(" -> %i bytes\n", n);
3260     *lpNumberOfBytesRecvd = n;
3261
3262     HeapFree (GetProcessHeap(), 0, iovec);
3263     release_sock_fd( s, fd );
3264     _enable_event(SOCKET2HANDLE(s), FD_READ, 0, 0);
3265
3266     return 0;
3267
3268 err_free:
3269     HeapFree (GetProcessHeap(), 0, iovec);
3270
3271 err_close:
3272     release_sock_fd( s, fd );
3273
3274 error:
3275     WARN(" -> ERROR %d\n", err);
3276     WSASetLastError ( err );
3277     return SOCKET_ERROR;
3278 }
3279
3280 /***********************************************************************
3281  *              WSCInstallProvider             (WS2_32.88)
3282  */
3283 INT WINAPI WSCInstallProvider( const LPGUID lpProviderId,
3284                                LPCWSTR lpszProviderDllPath,
3285                                const LPWSAPROTOCOL_INFOW lpProtocolInfoList,
3286                                DWORD dwNumberOfEntries,
3287                                LPINT lpErrno )
3288 {
3289     FIXME("(%s, %s, %p, %ld, %p): stub !\n", debugstr_guid(lpProviderId),
3290           debugstr_w(lpszProviderDllPath), lpProtocolInfoList,
3291           dwNumberOfEntries, lpErrno);
3292     *lpErrno = 0;
3293     return 0;
3294 }
3295
3296
3297 /***********************************************************************
3298  *              WSCDeinstallProvider             (WS2_32.83)
3299  */
3300 INT WINAPI WSCDeinstallProvider(LPGUID lpProviderId, LPINT lpErrno)
3301 {
3302     FIXME("(%s, %p): stub !\n", debugstr_guid(lpProviderId), lpErrno);
3303     *lpErrno = 0;
3304     return 0;
3305 }
3306
3307
3308 /***********************************************************************
3309  *              WSAAccept                        (WS2_32.26)
3310  */
3311 SOCKET WINAPI WSAAccept( SOCKET s, struct WS_sockaddr *addr, LPINT addrlen,
3312                LPCONDITIONPROC lpfnCondition, DWORD dwCallbackData)
3313 {
3314
3315        int ret = 0, size = 0;
3316        WSABUF CallerId, CallerData, CalleeId, CalleeData;
3317        /*        QOS SQOS, GQOS; */
3318        GROUP g;
3319        SOCKET cs;
3320        SOCKADDR src_addr, dst_addr;
3321
3322        TRACE("Socket  %u, sockaddr %p, addrlen %p, fnCondition %p, dwCallbackData %ld\n",
3323                s, addr, addrlen, lpfnCondition, dwCallbackData);
3324
3325
3326        size = sizeof(src_addr);
3327        cs = WS_accept(s, &src_addr, &size);
3328
3329        if (cs == SOCKET_ERROR) return SOCKET_ERROR;
3330
3331        CallerId.buf = (char *)&src_addr;
3332        CallerId.len = sizeof(src_addr);
3333
3334        CallerData.buf = NULL;
3335        CallerData.len = (ULONG)NULL;
3336
3337        WS_getsockname(cs, &dst_addr, &size);
3338
3339        CalleeId.buf = (char *)&dst_addr;
3340        CalleeId.len = sizeof(dst_addr);
3341
3342
3343        ret = (*lpfnCondition)(&CallerId, &CallerData, NULL, NULL,
3344                        &CalleeId, &CalleeData, &g, dwCallbackData);
3345
3346        switch (ret)
3347        {
3348                case CF_ACCEPT:
3349                        if (addr && addrlen)
3350                                addr = memcpy(addr, &src_addr, (*addrlen > size) ?  size : *addrlen );
3351                        return cs;
3352                case CF_DEFER:
3353                        SERVER_START_REQ ( set_socket_deferred )
3354                        {
3355                            req->handle = SOCKET2HANDLE (s);
3356                            req->deferred = SOCKET2HANDLE (cs);
3357                            if ( !wine_server_call_err ( req ) )
3358                            {
3359                                SetLastError ( WSATRY_AGAIN );
3360                                WS_closesocket ( cs );
3361                            }
3362                        }
3363                        SERVER_END_REQ;
3364                        return SOCKET_ERROR;
3365                case CF_REJECT:
3366                        WS_closesocket(cs);
3367                        SetLastError(WSAECONNREFUSED);
3368                        return SOCKET_ERROR;
3369                default:
3370                        FIXME("Unknown return type from Condition function\n");
3371                        SetLastError(WSAENOTSOCK);
3372                        return SOCKET_ERROR;
3373                }
3374 }
3375
3376 /***********************************************************************
3377  *              WSAEnumProtocolsA                        (WS2_32.37)
3378  */
3379 int WINAPI WSAEnumProtocolsA(LPINT lpiProtocols, LPWSAPROTOCOL_INFOA lpProtocolBuffer, LPDWORD lpdwBufferLength)
3380 {
3381     FIXME("(%p,%p,%p): stub\n", lpiProtocols,lpProtocolBuffer, lpdwBufferLength);
3382     return 0;
3383 }
3384
3385 /***********************************************************************
3386  *              WSAEnumProtocolsW                        (WS2_32.38)
3387  */
3388 int WINAPI WSAEnumProtocolsW(LPINT lpiProtocols, LPWSAPROTOCOL_INFOW lpProtocolBuffer, LPDWORD lpdwBufferLength)
3389 {
3390     FIXME("(%p,%p,%p): stub\n", lpiProtocols,lpProtocolBuffer, lpdwBufferLength);
3391     return 0;
3392 }
3393
3394 /***********************************************************************
3395  *              WSADuplicateSocketA                      (WS2_32.32)
3396  */
3397 int WINAPI WSADuplicateSocketA( SOCKET s, DWORD dwProcessId, LPWSAPROTOCOL_INFOA lpProtocolInfo )
3398 {
3399    HANDLE hProcess;
3400
3401    TRACE("(%d,%lx,%p)\n", s, dwProcessId, lpProtocolInfo);
3402    memset(lpProtocolInfo, 0, sizeof(*lpProtocolInfo));
3403    /* FIXME: WS_getsockopt(s, WS_SOL_SOCKET, SO_PROTOCOL_INFO, lpProtocolInfo, sizeof(*lpProtocolInfo)); */
3404    /* I don't know what the real Windoze does next, this is a hack */
3405    /* ...we could duplicate and then use ConvertToGlobalHandle on the duplicate, then let
3406     * the target use the global duplicate, or we could copy a reference to us to the structure
3407     * and let the target duplicate it from us, but let's do it as simple as possible */
3408    hProcess = OpenProcess(PROCESS_DUP_HANDLE, FALSE, dwProcessId);
3409    DuplicateHandle(GetCurrentProcess(), SOCKET2HANDLE(s),
3410                    hProcess, (LPHANDLE)&lpProtocolInfo->dwCatalogEntryId,
3411                    0, FALSE, DUPLICATE_SAME_ACCESS);
3412    CloseHandle(hProcess);
3413    lpProtocolInfo->dwServiceFlags4 = 0xff00ff00; /* magic */
3414    return 0;
3415 }
3416
3417 /***********************************************************************
3418  *              WSAInstallServiceClassA                  (WS2_32.48)
3419  */
3420 int WINAPI WSAInstallServiceClassA(LPWSASERVICECLASSINFOA info)
3421 {
3422     FIXME("Request to install service %s\n",debugstr_a(info->lpszServiceClassName));
3423     WSASetLastError(WSAEACCES);
3424     return SOCKET_ERROR;
3425 }
3426
3427 /***********************************************************************
3428  *              WSAInstallServiceClassW                  (WS2_32.49)
3429  */
3430 int WINAPI WSAInstallServiceClassW(LPWSASERVICECLASSINFOW info)
3431 {
3432     FIXME("Request to install service %s\n",debugstr_w(info->lpszServiceClassName));
3433     WSASetLastError(WSAEACCES);
3434     return SOCKET_ERROR;
3435 }
3436
3437 /***********************************************************************
3438  *              WSARemoveServiceClass                    (WS2_32.70)
3439  */
3440 int WINAPI WSARemoveServiceClass(LPGUID info)
3441 {
3442     FIXME("Request to remove service %p\n",info);
3443     WSASetLastError(WSATYPE_NOT_FOUND);
3444     return SOCKET_ERROR;
3445 }
3446
3447 /***********************************************************************
3448  *              WSAStringToAddressA                      (WS2_32.80)
3449  */
3450 INT WINAPI WSAStringToAddressA(LPSTR AddressString,
3451                                INT AddressFamily,
3452                                LPWSAPROTOCOL_INFOA lpProtocolInfo, 
3453                                LPSOCKADDR lpAddress,
3454                                LPINT lpAddressLength)
3455 {
3456     FIXME("(%s, %x, %p, %p, %p) Stub!\n", AddressString, AddressFamily, lpProtocolInfo, lpAddress, lpAddressLength);
3457     return 0;
3458 }