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