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