Release 960928
[wine/multimedia.git] / misc / winsocket.c
blob5cdae3d054c2ffc524dbb17b0231d22136574673
1 /*
2 * based on Windows Sockets 1.1 specs
3 * (ftp.microsoft.com:/Advsys/winsock/spec11/WINSOCK.TXT)
4 *
5 * (C) 1993,1994 John Brezak, Erik Bos.
6 */
8 #include <stdio.h>
9 #include <string.h>
10 #include <signal.h>
11 #include <sys/types.h>
12 #include <sys/ipc.h>
13 #include <sys/ioctl.h>
14 #if defined(__svr4__)
15 #include <sys/filio.h>
16 #include <sys/ioccom.h>
17 #endif
18 #include <sys/msg.h>
19 #include <sys/socket.h>
20 #include <netinet/in.h>
21 #include <arpa/inet.h>
22 #include <fcntl.h>
23 #include <errno.h>
24 #include <netdb.h>
25 #include <unistd.h>
27 #include "winsock.h"
28 #include "global.h"
29 #include "stddebug.h"
30 #include "debug.h"
32 #ifdef _SCO_DS
33 #define _IOR _IOSR
34 #define _IOW _IOSW
35 #endif
37 static WORD wsa_errno;
38 static int wsa_initted;
39 static key_t wine_key = 0;
40 static FARPROC16 BlockFunction;
41 static fd_set fd_in_use;
43 extern int h_errno;
45 struct ipc_packet {
46 long mtype;
47 HANDLE handle;
48 HWND hWnd;
49 WORD wMsg;
50 LONG lParam;
53 #ifndef WINELIB
54 #pragma pack(1)
55 #endif
57 #define WINSOCK_MAX_SOCKETS 256
58 #define WINSOCK_MAX_UDPDG 1024
60 /* we are out by two with the following, is it due to byte alignment?
61 * #define IPC_PACKET_SIZE (sizeof(struct ipc_packet) - sizeof(long))
63 #define IPC_PACKET_SIZE (sizeof(struct ipc_packet) - sizeof(long) - 2)
64 /*#define MTYPE 0xb0b0eb05*/
65 #define MTYPE 0x30b0eb05
67 /* These structures are Win16 only */
69 struct WIN_hostent {
70 SEGPTR h_name WINE_PACKED; /* official name of host */
71 SEGPTR h_aliases WINE_PACKED; /* alias list */
72 INT h_addrtype WINE_PACKED; /* host address type */
73 INT h_length WINE_PACKED; /* length of address */
74 char **h_addr_list WINE_PACKED; /* list of addresses from name server */
75 char *names[2];
76 char hostname[200];
79 struct WIN_protoent {
80 SEGPTR p_name WINE_PACKED; /* official protocol name */
81 SEGPTR p_aliases WINE_PACKED; /* alias list */
82 INT p_proto WINE_PACKED; /* protocol # */
85 struct WIN_servent {
86 SEGPTR s_name WINE_PACKED; /* official service name */
87 SEGPTR s_aliases WINE_PACKED; /* alias list */
88 INT s_port WINE_PACKED; /* port # */
89 SEGPTR s_proto WINE_PACKED; /* protocol to use */
92 typedef struct WinSock_fd_set {
93 u_short fd_count; /* how many are SET? */
94 SOCKET fd_array[FD_SETSIZE]; /* an array of SOCKETs */
95 } WinSock_fd_set;
97 struct WinSockHeap {
98 char ntoa_buffer[32];
100 struct WIN_hostent hostent_addr;
101 struct WIN_hostent hostent_name;
102 struct WIN_protoent protoent_name;
103 struct WIN_protoent protoent_number;
104 struct WIN_servent servent_name;
105 struct WIN_servent servent_port;
107 struct WIN_hostent WSAhostent_addr;
108 struct WIN_hostent WSAhostent_name;
109 struct WIN_protoent WSAprotoent_name;
110 struct WIN_protoent WSAprotoent_number;
111 struct WIN_servent WSAservent_name;
112 struct WIN_servent WSAservent_port;
113 /* 8K scratch buffer for aliases and friends are hopefully enough */
114 char scratch[8192];
116 static struct WinSockHeap *Heap;
117 static HANDLE HeapHandle;
118 #ifndef WINELIB32
119 static int ScratchPtr;
120 #endif
122 #ifndef WINELIB
123 #define GET_SEG_PTR(x) MAKELONG((int)((char*)(x)-(char*)Heap), \
124 GlobalHandleToSel(HeapHandle))
125 #else
126 #define GET_SEG_PTR(x) ((SEGPTR)x)
127 #endif
129 #ifndef WINELIB
130 #pragma pack(4)
131 #endif
133 #define dump_sockaddr(a) \
134 fprintf(stderr, "sockaddr_in: family %d, address %s, port %d\n", \
135 ((struct sockaddr_in *)a)->sin_family, \
136 inet_ntoa(((struct sockaddr_in *)a)->sin_addr), \
137 ntohs(((struct sockaddr_in *)a)->sin_port))
139 #ifndef WINELIB32
140 static void ResetScratch()
142 ScratchPtr=0;
145 static void *scratch_alloc(int size)
147 char *ret;
148 if(ScratchPtr+size > sizeof(Heap->scratch))
149 return 0;
150 ret = Heap->scratch + ScratchPtr;
151 ScratchPtr += size;
152 return ret;
155 static SEGPTR scratch_strdup(char * s)
157 char *ret=scratch_alloc(strlen(s)+1);
158 strcpy(ret,s);
159 return GET_SEG_PTR(ret);
161 #endif
163 static WORD wsaerrno(void)
165 #ifdef DEBUG_WINSOCK
166 #ifndef sun
167 #if defined(__FreeBSD__)
168 fprintf(stderr, "winsock: errno %d, (%s).\n",
169 errno, sys_errlist[errno]);
170 #else
171 fprintf(stderr, "winsock: errno %d\n", errno);
172 #endif
173 #else
174 fprintf(stderr, "winsock: errno %d\n", errno);
175 #endif
176 #endif
178 switch(errno)
180 case EINTR: return WSAEINTR;
181 case EBADF: return WSAEBADF;
182 case EACCES: return WSAEACCES;
183 case EFAULT: return WSAEFAULT;
184 case EINVAL: return WSAEINVAL;
185 case EMFILE: return WSAEMFILE;
186 case EWOULDBLOCK: return WSAEWOULDBLOCK;
187 case EINPROGRESS: return WSAEINPROGRESS;
188 case EALREADY: return WSAEALREADY;
189 case ENOTSOCK: return WSAENOTSOCK;
190 case EDESTADDRREQ: return WSAEDESTADDRREQ;
191 case EMSGSIZE: return WSAEMSGSIZE;
192 case EPROTOTYPE: return WSAEPROTOTYPE;
193 case ENOPROTOOPT: return WSAENOPROTOOPT;
194 case EPROTONOSUPPORT: return WSAEPROTONOSUPPORT;
195 case ESOCKTNOSUPPORT: return WSAESOCKTNOSUPPORT;
196 case EOPNOTSUPP: return WSAEOPNOTSUPP;
197 case EPFNOSUPPORT: return WSAEPFNOSUPPORT;
198 case EAFNOSUPPORT: return WSAEAFNOSUPPORT;
199 case EADDRINUSE: return WSAEADDRINUSE;
200 case EADDRNOTAVAIL: return WSAEADDRNOTAVAIL;
201 case ENETDOWN: return WSAENETDOWN;
202 case ENETUNREACH: return WSAENETUNREACH;
203 case ENETRESET: return WSAENETRESET;
204 case ECONNABORTED: return WSAECONNABORTED;
205 case ECONNRESET: return WSAECONNRESET;
206 case ENOBUFS: return WSAENOBUFS;
207 case EISCONN: return WSAEISCONN;
208 case ENOTCONN: return WSAENOTCONN;
209 case ESHUTDOWN: return WSAESHUTDOWN;
210 case ETOOMANYREFS: return WSAETOOMANYREFS;
211 case ETIMEDOUT: return WSAETIMEDOUT;
212 case ECONNREFUSED: return WSAECONNREFUSED;
213 case ELOOP: return WSAELOOP;
214 case ENAMETOOLONG: return WSAENAMETOOLONG;
215 case EHOSTDOWN: return WSAEHOSTDOWN;
216 case EHOSTUNREACH: return WSAEHOSTUNREACH;
217 case ENOTEMPTY: return WSAENOTEMPTY;
218 #ifdef EPROCLIM
219 case EPROCLIM: return WSAEPROCLIM;
220 #endif
221 #ifdef EUSERS
222 case EUSERS: return WSAEUSERS;
223 #endif
224 #ifdef EDQUOT
225 case EDQUOT: return WSAEDQUOT;
226 #endif
227 case ESTALE: return WSAESTALE;
228 case EREMOTE: return WSAEREMOTE;
229 /* just in case we ever get here and there are no problems */
230 case 0: return 0;
232 default:
233 fprintf(stderr, "winsock: unknown errorno %d!\n", errno);
234 return WSAEOPNOTSUPP;
238 static void errno_to_wsaerrno(void)
240 wsa_errno = wsaerrno();
244 static WORD wsaherrno(void)
246 #if DEBUG_WINSOCK
247 #ifndef sun
248 #if defined(__FreeBSD__)
249 fprintf(stderr, "winsock: h_errno %d, (%s).\n",
250 h_errno, sys_errlist[h_errno]);
251 #else
252 fprintf(stderr, "winsock: h_errno %d.\n", h_errno);
253 herror("wine: winsock: wsaherrno");
254 #endif
255 #else
256 fprintf(stderr, "winsock: h_errno %d\n", h_errno);
257 #endif
258 #endif
260 switch(h_errno)
262 case HOST_NOT_FOUND: return WSAHOST_NOT_FOUND;
263 case TRY_AGAIN: return WSATRY_AGAIN;
264 case NO_RECOVERY: return WSANO_RECOVERY;
265 case NO_DATA: return WSANO_DATA;
266 /* just in case we ever get here and there are no problems */
267 case 0: return 0;
270 default:
271 fprintf(stderr, "winsock: unknown h_errorno %d!\n", h_errno);
272 return WSAEOPNOTSUPP;
277 static void herrno_to_wsaerrno(void)
279 wsa_errno = wsaherrno();
283 static void convert_sockopt(INT *level, INT *optname)
285 /* $%#%!#! why couldn't they use the same values for both winsock and unix ? */
287 switch (*level) {
288 case -1:
289 *level = SOL_SOCKET;
290 switch (*optname) {
291 case 0x01: *optname = SO_DEBUG;
292 break;
293 case 0x04: *optname = SO_REUSEADDR;
294 break;
295 case 0x08: *optname = SO_KEEPALIVE;
296 break;
297 case 0x10: *optname = SO_DONTROUTE;
298 break;
299 case 0x20: *optname = SO_BROADCAST;
300 break;
301 case 0x80: *optname = SO_LINGER;
302 break;
303 case 0x100: *optname = SO_OOBINLINE;
304 break;
305 case 0x1001: *optname = SO_SNDBUF;
306 break;
307 case 0x1002: *optname = SO_RCVBUF;
308 break;
309 case 0x1007: *optname = SO_ERROR;
310 break;
311 case 0x1008: *optname = SO_TYPE;
312 break;
313 default:
314 fprintf(stderr, "convert_sockopt() unknown optname %d\n", *optname);
315 break;
317 break;
318 case 6: *optname = IPPROTO_TCP;
322 #ifndef WINELIB
323 static SEGPTR copy_stringlist(char **list)
325 SEGPTR *s_list;
326 int i;
327 for(i=0;list[i];i++)
329 s_list = scratch_alloc(sizeof(SEGPTR)*(i+1));
330 for(i=0;list[i];i++)
332 void *copy = scratch_alloc(strlen(list[i])+1);
333 strcpy(copy,list[i]);
334 s_list[i]=GET_SEG_PTR(copy);
336 s_list[i]=0;
337 return GET_SEG_PTR(s_list);
341 static void CONVERT_HOSTENT(struct WIN_hostent *heapent, struct hostent *host)
343 SEGPTR *addr_list;
344 int i;
345 ResetScratch();
346 strcpy(heapent->hostname,host->h_name);
347 heapent->h_name = GET_SEG_PTR(heapent->hostname);
348 /* Convert aliases. Have to create array with FAR pointers */
349 if(!host->h_aliases)
350 heapent->h_aliases = 0;
351 else
352 heapent->h_aliases = copy_stringlist(host->h_aliases);
354 heapent->h_addrtype = host->h_addrtype;
355 heapent->h_length = host->h_length;
356 for(i=0;host->h_addr_list[i];i++)
358 addr_list=scratch_alloc(sizeof(SEGPTR)*(i+1));
359 heapent->h_addr_list = (char**)GET_SEG_PTR(addr_list);
360 for(i=0;host->h_addr_list[i];i++)
362 void *addr=scratch_alloc(host->h_length);
363 memcpy(addr,host->h_addr_list[i],host->h_length);
364 addr_list[i]=GET_SEG_PTR(addr);
366 addr_list[i]=0;
369 static void CONVERT_PROTOENT(struct WIN_protoent *heapent,
370 struct protoent *proto)
372 ResetScratch();
373 heapent->p_name= scratch_strdup(proto->p_name);
374 heapent->p_aliases=proto->p_aliases ?
375 copy_stringlist(proto->p_aliases) : 0;
376 heapent->p_proto = proto->p_proto;
379 static void CONVERT_SERVENT(struct WIN_servent *heapent, struct servent *serv)
381 ResetScratch();
382 heapent->s_name = scratch_strdup(serv->s_name);
383 heapent->s_aliases = serv->s_aliases ?
384 copy_stringlist(serv->s_aliases) : 0;
385 heapent->s_port = serv->s_port;
386 heapent->s_proto = scratch_strdup(serv->s_proto);
388 #else
389 #define CONVERT_HOSTENT(a,b) memcpy(a, &b, sizeof(a))
390 #define CONVERT_PROTOENT(a,b) memcpy(a, &b, sizeof(a))
391 #define CONVERT_SERVENT(a,b) memcpy(a, &b, sizeof(a))
392 #endif
394 SOCKET WINSOCK_accept(SOCKET s, struct sockaddr *addr, INT *addrlen)
396 int sock;
398 dprintf_winsock(stddeb, "WSA_accept: socket %d, ptr %8x, length %d\n", s, (int) addr, *addrlen);
400 if (!wsa_initted) {
401 WSASetLastError(WSANOTINITIALISED);
402 return INVALID_SOCKET;
405 if ((sock = accept(s, addr, (int *) addrlen)) < 0) {
406 errno_to_wsaerrno();
407 return INVALID_SOCKET;
409 return sock;
412 INT WINSOCK_bind(SOCKET s, struct sockaddr *name, INT namelen)
415 dprintf_winsock(stddeb, "WSA_bind: socket %d, ptr %8x, length %d\n", s, (int) name, namelen);
416 dump_sockaddr(name);
418 if (!wsa_initted) {
419 WSASetLastError(WSANOTINITIALISED);
420 return SOCKET_ERROR;
423 if (namelen < sizeof(*name)) {
424 WSASetLastError(WSAEFAULT);
425 return SOCKET_ERROR;
428 /* check the socket family */
429 if ( ((struct sockaddr_in *)name)->sin_family != AF_INET ) {
430 WSASetLastError(WSAEAFNOSUPPORT);
431 return SOCKET_ERROR;
434 if (bind(s, name, namelen) < 0) {
435 switch(errno) {
436 case EBADF:
437 WSASetLastError(WSAENOTSOCK);
438 break;
439 case EADDRNOTAVAIL:
440 WSASetLastError(WSAEINVAL);
441 break;
442 default:
443 errno_to_wsaerrno();
444 break;
446 return SOCKET_ERROR;
448 return 0;
451 INT WINSOCK_closesocket(SOCKET s)
453 dprintf_winsock(stddeb, "WSA_closesocket: socket %d\n", s);
455 if (!wsa_initted) {
456 WSASetLastError(WSANOTINITIALISED);
457 return SOCKET_ERROR;
460 FD_CLR(s, &fd_in_use);
462 if (close(s) < 0) {
463 if (errno == EBADF)
464 WSASetLastError(WSAENOTSOCK);
465 else
466 errno_to_wsaerrno();
467 return SOCKET_ERROR;
469 return 0;
472 INT WINSOCK_connect(SOCKET s, struct sockaddr *name, INT namelen)
474 dprintf_winsock(stddeb, "WSA_connect: socket %d, ptr %8x, length %d\n", s, (int) name, namelen);
475 dump_sockaddr(name);
477 if (!wsa_initted) {
478 WSASetLastError(WSANOTINITIALISED);
479 return SOCKET_ERROR;
482 if (connect(s, name, namelen) < 0) {
483 errno_to_wsaerrno();
484 return SOCKET_ERROR;
486 return 0;
489 INT WINSOCK_getpeername(SOCKET s, struct sockaddr *name, INT *namelen)
491 dprintf_winsock(stddeb, "WSA_getpeername: socket: %d, ptr %8x, ptr %8x\n", s, (int) name, *namelen);
492 dump_sockaddr(name);
494 if (!wsa_initted) {
495 WSASetLastError(WSANOTINITIALISED);
496 return SOCKET_ERROR;
499 if (getpeername(s, name, (int *) namelen) < 0) {
500 if (h_errno < 0) {
501 errno_to_wsaerrno();
502 } else {
503 herrno_to_wsaerrno();
505 return SOCKET_ERROR;
507 return 0;
510 INT WINSOCK_getsockname(SOCKET s, struct sockaddr *name, INT *namelen)
512 dprintf_winsock(stddeb, "WSA_getsockname: socket: %d, ptr %8x, ptr %8x\n", s, (int) name, (int) *namelen);
514 if (!wsa_initted) {
515 WSASetLastError(WSANOTINITIALISED);
516 return SOCKET_ERROR;
519 if (getsockname(s, name, (int *) namelen) < 0) {
520 if (h_errno < 0) {
521 errno_to_wsaerrno();
522 } else {
523 herrno_to_wsaerrno();
525 return SOCKET_ERROR;
527 return 0;
531 WINSOCK_getsockopt(SOCKET s, INT level, INT optname, char *optval, INT *optlen)
533 dprintf_winsock(stddeb, "WSA_getsockopt: socket: %d, opt %d, ptr %8x, ptr %8x\n", s, level, (int) optval, (int) *optlen);
535 if (!wsa_initted) {
536 WSASetLastError(WSANOTINITIALISED);
537 return SOCKET_ERROR;
540 convert_sockopt(&level, &optname);
542 if (getsockopt(s, (int) level, optname, optval, (int *) optlen) < 0) {
543 if (errno == EBADF)
544 WSASetLastError(WSAENOTSOCK);
545 else
546 errno_to_wsaerrno();
547 return SOCKET_ERROR;
549 return 0;
552 u_long WINSOCK_htonl(u_long hostlong)
554 return( htonl(hostlong) );
557 u_short WINSOCK_htons(u_short hostshort)
559 return( htons(hostshort) );
562 u_long WINSOCK_inet_addr(char *cp)
564 return( inet_addr(cp) );
567 char *WINSOCK_inet_ntoa(struct in_addr in)
569 char *s;
571 /* dprintf_winsock(stddeb, "WSA_inet_ntoa: %8lx\n", (int) in);*/
573 if ((s = inet_ntoa(in)) == NULL) {
574 errno_to_wsaerrno();
575 return NULL;
578 strncpy(Heap->ntoa_buffer, s, sizeof(Heap->ntoa_buffer) );
580 return (char *) GET_SEG_PTR(&Heap->ntoa_buffer);
583 INT WINSOCK_ioctlsocket(SOCKET s, u_long cmd, u_long *argp)
585 long newcmd;
586 u_long *newargp;
587 char *ctlname;
588 dprintf_winsock(stddeb, "WSA_ioctl: socket %d, cmd %lX, ptr %8x\n", s, cmd, (int) argp);
590 if (!wsa_initted) {
591 WSASetLastError(WSANOTINITIALISED);
592 return SOCKET_ERROR;
595 /* Why can't they all use the same ioctl numbers */
596 newcmd=cmd;
597 newargp=argp;
598 ctlname=0;
599 if(cmd == _IOR('f',127,u_long))
601 ctlname="FIONREAD";
602 newcmd=FIONREAD;
603 }else
604 if(cmd == _IOW('f',126,u_long) || cmd == _IOR('f',126,u_long))
606 ctlname="FIONBIO";
607 newcmd=FIONBIO;
608 }else
609 if(cmd == _IOW('f',125,u_long))
611 ctlname="FIOASYNC";
612 newcmd=FIOASYNC;
615 if(!ctlname)
616 fprintf(stderr,"Unknown winsock ioctl. Trying anyway\n");
617 else
618 dprintf_winsock(stddeb,"Recognized as %s\n", ctlname);
621 if (ioctl(s, newcmd, newargp) < 0) {
622 if (errno == EBADF)
623 WSASetLastError(WSAENOTSOCK);
624 else
625 errno_to_wsaerrno();
626 return SOCKET_ERROR;
628 return 0;
631 INT WINSOCK_listen(SOCKET s, INT backlog)
633 dprintf_winsock(stddeb, "WSA_listen: socket %d, backlog %d\n", s, backlog);
635 if (!wsa_initted) {
636 WSASetLastError(WSANOTINITIALISED);
637 return SOCKET_ERROR;
640 if (listen(s, backlog) < 0) {
641 errno_to_wsaerrno();
642 return SOCKET_ERROR;
644 return 0;
647 u_long WINSOCK_ntohl(u_long netlong)
649 return( ntohl(netlong) );
652 u_short WINSOCK_ntohs(u_short netshort)
654 return( ntohs(netshort) );
657 INT WINSOCK_recv(SOCKET s, char *buf, INT len, INT flags)
659 int length;
661 dprintf_winsock(stddeb, "WSA_recv: socket %d, ptr %8x, length %d, flags %d\n", s, (int) buf, len, flags);
663 if (!wsa_initted) {
664 WSASetLastError(WSANOTINITIALISED);
665 return SOCKET_ERROR;
668 if ((length = recv(s, buf, len, flags)) < 0) {
669 errno_to_wsaerrno();
670 return SOCKET_ERROR;
672 return length;
675 INT WINSOCK_recvfrom(SOCKET s, char *buf, INT len, INT flags,
676 struct sockaddr *from, int *fromlen)
678 int length;
680 dprintf_winsock(stddeb, "WSA_recvfrom: socket %d, ptr %8lx, length %d, flags %d\n", s, (unsigned long)buf, len, flags);
682 if (!wsa_initted) {
683 WSASetLastError(WSANOTINITIALISED);
684 return SOCKET_ERROR;
687 if ((length = recvfrom(s, buf, len, flags, from, fromlen)) < 0) {
688 errno_to_wsaerrno();
689 return SOCKET_ERROR;
691 return length;
694 INT WINSOCK_select(INT nfds, WinSock_fd_set *ws_readfds,
695 WinSock_fd_set *ws_writefds, WinSock_fd_set *ws_exceptfds,
696 struct timeval *timeout)
698 int ret;
699 int i;
700 int count;
701 int highfd;
702 fd_set readfds,writefds,exceptfds;
703 FD_ZERO(&readfds);
704 FD_ZERO(&writefds);
705 FD_ZERO(&exceptfds);
707 dprintf_winsock(stddeb, "WSA_select called: nfds %d (ignored), ptr %8lx, ptr %8lx, ptr %8lx\n", nfds, (unsigned long) ws_readfds, (unsigned long) ws_writefds, (unsigned long) ws_exceptfds);
709 if (!wsa_initted) {
710 WSASetLastError(WSANOTINITIALISED);
711 dprintf_winsock(stddeb, "WSA_select: returning error WSANOTINITIALISED\n");
712 return SOCKET_ERROR;
715 /* In some sort of attempt to be BSD-compatible, MS-Winsock accepts and
716 discards the nfds parameter. However, the format of windoze's fd_sets
717 is totally different from the BSD standard. So much for compatibility.
718 Hence, we must convert the winsock array-of-ints fd_set to the UNIX
719 bitmapped format. */
721 if(ws_readfds!=NULL) {
722 dprintf_winsock(stddeb, "readfds: (%d) ",ws_readfds->fd_count);
723 for(i=0;i<(ws_readfds->fd_count);i++) {
724 dprintf_winsock(stddeb, " %d",( (SOCKET *)&(((char *)ws_readfds)[2]) )[i]);
725 /*FD_SET(((SOCKET *)&(((char *)ws_readfds)[2]))[i], &readfds);*/
726 FD_SET(ws_readfds->fd_array[i], &readfds);
728 dprintf_winsock(stddeb, "\n");
729 } else {
730 dprintf_winsock(stddeb, "readfds: (null)\n");
732 if(ws_writefds!=NULL) {
733 dprintf_winsock(stddeb, "writefds: (%d) ",ws_writefds->fd_count);
734 for(i=0;i<(ws_writefds->fd_count);i++) {
735 dprintf_winsock(stddeb, " %d",( (SOCKET *)&(((char *)ws_writefds)[2]) )[i]);
736 /*FD_SET(((SOCKET *)&(((char *)ws_writefds)[2]))[i], &writefds);*/
737 FD_SET(ws_writefds->fd_array[i], &writefds);
739 dprintf_winsock(stddeb, "\n");
740 } else {
741 dprintf_winsock(stddeb, "writefds: (null)\n");
743 if(ws_exceptfds!=NULL) {
744 dprintf_winsock(stddeb, "exceptfds: (%d) ",ws_exceptfds->fd_count);
745 for(i=0;i<(ws_exceptfds->fd_count);i++) {
746 dprintf_winsock(stddeb, " %d",( (SOCKET *)&(((char *)ws_exceptfds)[2]) )[i]);
747 /*FD_SET(((SOCKET *)&(((char *)ws_exceptfds)[2]))[i], &exceptfds);*/
748 FD_SET(ws_exceptfds->fd_array[i], &exceptfds);
750 dprintf_winsock(stddeb, "\n");
751 } else {
752 dprintf_winsock(stddeb, "exceptfds: (null)\n");
755 /* Make the select() call */
756 dprintf_winsock(stddeb, "WSA_select: calling select()\n");
757 highfd=256; /* We should count them, but this works */
758 ret=select(highfd, &readfds, &writefds, &exceptfds, timeout);
759 dprintf_winsock(stddeb, "WSA_select: select() returned %d\n",ret);
760 if(ret<0) {
761 errno_to_wsaerrno();
762 dprintf_winsock(stddeb, "WSA_select returning: Error %d\n",SOCKET_ERROR);
763 return SOCKET_ERROR;
766 /* update the winsock fd sets */
767 if(ws_readfds!=NULL) {
768 dprintf_winsock(stddeb, "readfds: ");
769 count=0;
770 for(i=0;i<highfd;i++) {
771 if(FD_ISSET(i,&readfds)) {
772 dprintf_winsock(stddeb, " %d",i);
773 ws_readfds->fd_array[count++]=i;
776 dprintf_winsock(stddeb, " (%d)\n",count);
777 ws_readfds->fd_count=count;
778 } else {
779 dprintf_winsock(stddeb, "readfds: (null)\n");
781 if(ws_writefds!=NULL) {
782 dprintf_winsock(stddeb, "writefds: ");
783 count=0;
784 for(i=0;i<highfd;i++) {
785 if(FD_ISSET(i,&writefds)) {
786 dprintf_winsock(stddeb, " %d",i);
787 ws_writefds->fd_array[count++]=i;
790 dprintf_winsock(stddeb, " (%d)\n",count);
791 ws_writefds->fd_count=count;
792 } else {
793 dprintf_winsock(stddeb, "writefds: (null)\n");
795 if(ws_exceptfds!=NULL) {
796 dprintf_winsock(stddeb, "exceptfds: ");
797 count=0;
798 for(i=0;i<highfd;i++) {
799 if(FD_ISSET(i,&exceptfds)) {
800 dprintf_winsock(stddeb, " %d",i);
801 ws_exceptfds->fd_array[count++]=i;
804 dprintf_winsock(stddeb, " (%d)\n",count);
805 ws_exceptfds->fd_count=count;
806 } else {
807 dprintf_winsock(stddeb, "exceptfds: (null)\n");
810 dprintf_winsock(stddeb, "WSA_select returning: %d\n",ret);
811 return(ret);
814 INT WINSOCK_send(SOCKET s, char *buf, INT len, INT flags)
816 int length;
818 dprintf_winsock(stddeb, "WSA_send: socket %d, ptr %8lx, length %d, flags %d\n", s, (unsigned long) buf, len, flags);
820 if (!wsa_initted) {
821 WSASetLastError(WSANOTINITIALISED);
822 return SOCKET_ERROR;
825 if ((length = send(s, buf, len, flags)) < 0) {
826 errno_to_wsaerrno();
827 return SOCKET_ERROR;
829 return length;
832 INT WINSOCK_sendto(SOCKET s, char *buf, INT len, INT flags,
833 struct sockaddr *to, INT tolen)
835 int length;
837 dprintf_winsock(stddeb, "WSA_sendto: socket %d, ptr %8lx, length %d, flags %d\n", s, (unsigned long) buf, len, flags);
839 if (!wsa_initted) {
840 WSASetLastError(WSANOTINITIALISED);
841 return SOCKET_ERROR;
844 if ((length = sendto(s, buf, len, flags, to, tolen)) < 0) {
845 errno_to_wsaerrno();
846 return SOCKET_ERROR;
848 return length;
851 INT WINSOCK_setsockopt(SOCKET s, INT level, INT optname, const char *optval,
852 INT optlen)
854 dprintf_winsock(stddeb, "WSA_setsockopt: socket %d, level %d, opt %d, ptr %8x, len %d\n", s, level, optname, (int) optval, optlen);
855 convert_sockopt(&level, &optname);
857 if (!wsa_initted) {
858 WSASetLastError(WSANOTINITIALISED);
859 return SOCKET_ERROR;
862 if (setsockopt(s, level, optname, optval, optlen) < 0) {
863 errno_to_wsaerrno();
864 return SOCKET_ERROR;
866 return 0;
869 INT WINSOCK_shutdown(SOCKET s, INT how)
871 dprintf_winsock(stddeb, "WSA_shutdown: socket s %d, how %d\n", s, how);
873 if (!wsa_initted) {
874 WSASetLastError(WSANOTINITIALISED);
875 return SOCKET_ERROR;
878 if (shutdown(s, how) < 0) {
879 errno_to_wsaerrno();
880 return SOCKET_ERROR;
882 return 0;
885 SOCKET WINSOCK_socket(INT af, INT type, INT protocol)
887 int sock;
889 dprintf_winsock(stddeb, "WSA_socket: af=%d type=%d protocol=%d\n", af, type, protocol);
891 if (!wsa_initted) {
892 WSASetLastError(WSANOTINITIALISED);
893 return INVALID_SOCKET;
896 /* check the socket family */
897 switch(af) {
898 case AF_INET:
899 case AF_UNSPEC:
900 break;
901 default:
902 WSASetLastError(WSAEAFNOSUPPORT);
903 return INVALID_SOCKET;
904 break;
907 /* check the socket type */
908 switch(type) {
909 case SOCK_STREAM:
910 case SOCK_DGRAM:
911 case SOCK_RAW:
912 break;
913 default:
914 WSASetLastError(WSAESOCKTNOSUPPORT);
915 return INVALID_SOCKET;
916 break;
919 /* check the protocol type */
920 if ( protocol < 0 ) { /* don't support negative values */
921 WSASetLastError(WSAEPROTONOSUPPORT);
922 return INVALID_SOCKET;
925 if ( af == AF_UNSPEC) { /* did they not specify the address family? */
926 switch(protocol) {
927 case IPPROTO_TCP:
928 if (type == SOCK_STREAM) {
929 af = AF_INET;
930 break;
932 case IPPROTO_UDP:
933 if (type == SOCK_DGRAM) {
934 af = AF_INET;
935 break;
937 default:
938 WSASetLastError(WSAEPROTOTYPE);
939 return INVALID_SOCKET;
940 break;
944 if ((sock = socket(af, type, protocol)) < 0) {
945 if (errno == EPERM) {
946 /* non super-user wants a raw socket */
947 fprintf(stderr, "WSA_socket: not enough privileges\n");
948 WSASetLastError(WSAESOCKTNOSUPPORT);
949 } else
950 errno_to_wsaerrno();
951 dprintf_winsock(stddeb, "WSA_socket: failed !\n");
952 return INVALID_SOCKET;
955 if (sock > WINSOCK_MAX_SOCKETS) {
956 /* we only support socket numbers up to WINSOCK_MAX_SOCKETS.
957 * The return value indicates no more descriptors are available
959 WSASetLastError(WSAEMFILE);
960 return INVALID_SOCKET;
963 FD_SET(sock, &fd_in_use);
965 dprintf_winsock(stddeb, "WSA_socket: fd %d\n", sock);
966 return sock;
970 struct WIN_hostent *
972 SEGPTR WINSOCK_gethostbyaddr(const char *addr, INT len, INT type)
974 struct hostent *host;
976 dprintf_winsock(stddeb, "WSA_gethostbyaddr: ptr %8x, len %d, type %d\n", (int) addr, len, type);
978 if (!wsa_initted) {
979 WSASetLastError(WSANOTINITIALISED);
980 return NULL;
983 if ((host = gethostbyaddr(addr, len, type)) == NULL) {
984 if (h_errno < 0) {
985 errno_to_wsaerrno();
986 } else {
987 herrno_to_wsaerrno();
989 return NULL;
991 CONVERT_HOSTENT(&Heap->hostent_addr, host);
993 return GET_SEG_PTR(&Heap->hostent_addr);
997 struct WIN_hostent *
999 SEGPTR WINSOCK_gethostbyname(const char *name)
1001 struct hostent *host;
1003 dprintf_winsock(stddeb, "WSA_gethostbyname: %s\n", name);
1005 if (!wsa_initted) {
1006 WSASetLastError(WSANOTINITIALISED);
1007 return NULL;
1010 if ((host = gethostbyname(name)) == NULL) {
1011 if (h_errno < 0) {
1012 errno_to_wsaerrno();
1013 } else {
1014 herrno_to_wsaerrno();
1016 return NULL;
1018 CONVERT_HOSTENT(&Heap->hostent_name, host);
1020 return GET_SEG_PTR(&Heap->hostent_name);
1023 INT WINSOCK_gethostname(char *name, INT namelen)
1025 dprintf_winsock(stddeb, "WSA_gethostname: name %s, len %d\n", name, namelen);
1027 if (!wsa_initted) {
1028 WSASetLastError(WSANOTINITIALISED);
1029 return SOCKET_ERROR;
1032 if (gethostname(name, namelen) < 0) {
1033 if (errno == EINVAL)
1034 WSASetLastError(WSAEFAULT);
1035 else
1036 errno_to_wsaerrno();
1037 return SOCKET_ERROR;
1039 return 0;
1043 struct WIN_protoent *
1045 SEGPTR WINSOCK_getprotobyname(char *name)
1047 struct protoent *proto;
1049 dprintf_winsock(stddeb, "WSA_getprotobyname: name %s\n", name);
1051 if (!wsa_initted) {
1052 WSASetLastError(WSANOTINITIALISED);
1053 return NULL;
1056 if ((proto = getprotobyname(name)) == NULL) {
1057 if (h_errno < 0) {
1058 errno_to_wsaerrno();
1059 } else {
1060 herrno_to_wsaerrno();
1062 return NULL;
1064 CONVERT_PROTOENT(&Heap->protoent_name, proto);
1066 return GET_SEG_PTR(&Heap->protoent_name);
1070 struct WIN_protoent *
1072 SEGPTR WINSOCK_getprotobynumber(INT number)
1074 struct protoent *proto;
1076 dprintf_winsock(stddeb, "WSA_getprotobynumber: num %d\n", number);
1078 if (!wsa_initted) {
1079 WSASetLastError(WSANOTINITIALISED);
1080 return NULL;
1083 if ((proto = getprotobynumber(number)) == NULL) {
1084 #if 0
1085 if (h_errno < 0) {
1086 errno_to_wsaerrno();
1087 } else {
1088 herrno_to_wsaerrno();
1090 #endif
1091 WSASetLastError(WSANO_DATA);
1092 return NULL;
1094 CONVERT_PROTOENT(&Heap->protoent_number, proto);
1096 return GET_SEG_PTR(&Heap->protoent_number);
1100 struct WIN_servent *
1102 SEGPTR WINSOCK_getservbyname(const char *name, const char *proto)
1104 struct servent *service;
1106 if (proto == NULL)
1107 proto = "tcp";
1109 dprintf_winsock(stddeb, "WSA_getservbyname: name %s, proto %s\n", name, proto);
1111 if (!wsa_initted) {
1112 WSASetLastError(WSANOTINITIALISED);
1113 return NULL;
1116 if ((service = getservbyname(name, proto)) == NULL) {
1117 if (h_errno < 0) {
1118 errno_to_wsaerrno();
1119 } else {
1120 herrno_to_wsaerrno();
1122 return NULL;
1124 CONVERT_SERVENT(&Heap->servent_name, service);
1126 return GET_SEG_PTR(&Heap->servent_name);
1130 struct WIN_servent *
1132 SEGPTR WINSOCK_getservbyport(INT port, const char *proto)
1134 struct servent *service;
1136 dprintf_winsock(stddeb, "WSA_getservbyport: port %d, name %s\n", port, proto);
1138 if (!wsa_initted) {
1139 WSASetLastError(WSANOTINITIALISED);
1140 return NULL;
1143 if ((service = getservbyport(port, proto)) == NULL) {
1144 if (h_errno < 0) {
1145 errno_to_wsaerrno();
1146 } else {
1147 herrno_to_wsaerrno();
1149 return NULL;
1151 CONVERT_SERVENT(&Heap->servent_port, service);
1153 return GET_SEG_PTR(&Heap->servent_port);
1156 /******************** winsock specific functions ************************
1159 static HANDLE new_handle = 1;
1161 static HANDLE AllocWSAHandle(void)
1163 return new_handle++;
1166 static void recv_message(int sig)
1168 static struct ipc_packet message;
1169 int message_is_valid = 0;
1170 BOOL result;
1172 message.mtype = MTYPE;
1174 signal(SIGUSR1, recv_message);
1175 while (1) {
1177 if (!message_is_valid) {
1178 if (msgrcv(wine_key, (struct msgbuf*)&(message),
1179 IPC_PACKET_SIZE, 0 /*MTYPE*/, IPC_NOWAIT) == -1) {
1180 perror("wine: winsock: msgrcv");
1181 break;
1185 result = PostMessage(message.hWnd, message.wMsg,
1186 (WPARAM)message.handle, message.lParam);
1187 if (result != FALSE) {
1188 message_is_valid = 1;
1189 break;
1191 else
1192 message_is_valid = 0;
1196 if ((wine_key = msgget(IPC_PRIVATE, 0600)) == -1)
1197 perror("wine: winsock: msgget");
1201 static void send_message( HWND hWnd, u_int wMsg, HANDLE handle, long lParam)
1203 struct ipc_packet message;
1205 message.mtype = MTYPE;
1206 message.handle = handle;
1207 message.hWnd = hWnd;
1208 message.wMsg = wMsg;
1209 message.lParam = lParam;
1211 if (msgsnd(wine_key, (struct msgbuf*)&(message),
1212 IPC_PACKET_SIZE, 0/*IPC_NOWAIT*/) == -1)
1213 perror("wine: winsock: msgsnd");
1215 kill(getppid(), SIGUSR1);
1219 HANDLE WSAAsyncGetHostByAddr(HWND hWnd, u_int wMsg, LPCSTR addr,
1220 INT len, INT type, LPSTR buf, INT buflen)
1222 HANDLE handle;
1223 struct hostent *host;
1224 int newpid;
1226 if (!wsa_initted) {
1227 WSASetLastError(WSANOTINITIALISED);
1228 return 0;
1231 handle = AllocWSAHandle();
1233 newpid = fork();
1234 if (newpid) {
1235 dprintf_winsock(stddeb, "forked, child is (%d)\n",newpid);
1236 return handle;
1237 } else {
1238 if ((host = gethostbyaddr(addr, len, type)) == NULL) {
1239 if (h_errno < 0) {
1240 errno_to_wsaerrno();
1241 } else {
1242 herrno_to_wsaerrno();
1244 send_message(hWnd, wMsg, handle, wsaerrno() << 16);
1245 exit(0);
1247 memcpy(buf, host, buflen);
1248 send_message(hWnd, wMsg, handle, 0);
1249 exit(0);
1254 HANDLE WSAAsyncGetHostByName(HWND hWnd, u_int wMsg, LPCSTR name,
1255 LPSTR buf, INT buflen)
1257 HANDLE handle;
1258 struct hostent *host;
1259 int newpid;
1261 if (!wsa_initted) {
1262 WSASetLastError(WSANOTINITIALISED);
1263 return 0;
1266 handle = AllocWSAHandle();
1268 newpid = fork();
1269 if (newpid) {
1270 dprintf_winsock(stddeb, "forked, child is (%d)\n",newpid);
1271 return handle;
1272 } else {
1273 if ((host = gethostbyname(name)) == NULL) {
1274 if (h_errno < 0) {
1275 errno_to_wsaerrno();
1276 } else {
1277 herrno_to_wsaerrno();
1279 send_message(hWnd, wMsg, handle, wsaerrno() << 16);
1280 exit(0);
1282 memcpy(buf, host, buflen);
1283 send_message(hWnd, wMsg, handle, 0);
1284 exit(0);
1289 HANDLE WSAAsyncGetProtoByName(HWND hWnd, u_int wMsg, LPCSTR name,
1290 LPSTR buf, INT buflen)
1292 HANDLE handle;
1293 struct protoent *proto;
1294 int newpid;
1296 if (!wsa_initted) {
1297 WSASetLastError(WSANOTINITIALISED);
1298 return 0;
1301 handle = AllocWSAHandle();
1303 newpid = fork();
1304 if (newpid) {
1305 dprintf_winsock(stddeb, "forked, child is (%d)\n",newpid);
1306 return handle;
1307 } else {
1308 if ((proto = getprotobyname(name)) == NULL) {
1309 if (h_errno < 0) {
1310 errno_to_wsaerrno();
1311 } else {
1312 herrno_to_wsaerrno();
1314 send_message(hWnd, wMsg, handle, wsaerrno() << 16);
1315 exit(0);
1317 memcpy(buf, proto, buflen);
1318 send_message(hWnd, wMsg, handle, 0);
1319 exit(0);
1324 HANDLE WSAAsyncGetProtoByNumber(HWND hWnd, u_int wMsg, INT number,
1325 LPSTR buf, INT buflen)
1327 HANDLE handle;
1328 struct protoent *proto;
1329 int newpid;
1331 if (!wsa_initted) {
1332 WSASetLastError(WSANOTINITIALISED);
1333 return 0;
1336 handle = AllocWSAHandle();
1338 newpid = fork();
1339 if (newpid) {
1340 dprintf_winsock(stddeb, "forked, child is (%d)\n",newpid);
1341 return handle;
1342 } else {
1343 if ((proto = getprotobynumber(number)) == NULL) {
1344 if (h_errno < 0) {
1345 errno_to_wsaerrno();
1346 } else {
1347 herrno_to_wsaerrno();
1349 send_message(hWnd, wMsg, handle, wsaerrno() << 16);
1350 exit(0);
1352 memcpy(buf, proto, buflen);
1353 send_message(hWnd, wMsg, handle, 0);
1354 exit(0);
1359 HANDLE WSAAsyncGetServByName(HWND hWnd, u_int wMsg, LPCSTR name,
1360 LPCSTR proto, LPSTR buf, INT buflen)
1362 HANDLE handle;
1363 struct servent *service;
1364 int newpid;
1366 if (!wsa_initted) {
1367 WSASetLastError(WSANOTINITIALISED);
1368 return 0;
1371 handle = AllocWSAHandle();
1373 newpid = fork();
1374 if (newpid) {
1375 dprintf_winsock(stddeb, "forked, child is (%d)\n",newpid);
1376 return handle;
1377 } else {
1378 if ((service = getservbyname(name, proto)) == NULL) {
1379 if (h_errno < 0) {
1380 errno_to_wsaerrno();
1381 } else {
1382 herrno_to_wsaerrno();
1384 send_message(hWnd, wMsg, handle, wsaerrno() << 16);
1385 exit(0);
1387 memcpy(buf, service, buflen);
1388 send_message(hWnd, wMsg, handle, 0);
1389 exit(0);
1394 HANDLE WSAAsyncGetServByPort(HWND hWnd, u_int wMsg, INT port, LPCSTR proto,
1395 LPSTR buf, INT buflen)
1397 HANDLE handle;
1398 struct servent *service;
1399 int newpid;
1401 if (!wsa_initted) {
1402 WSASetLastError(WSANOTINITIALISED);
1403 return 0;
1406 handle = AllocWSAHandle();
1408 newpid = fork();
1409 if (newpid) {
1410 dprintf_winsock(stddeb, "forked, child is (%d)\n",newpid);
1411 return handle;
1412 } else {
1413 if ((service = getservbyport(port, proto)) == NULL) {
1414 if (h_errno < 0) {
1415 errno_to_wsaerrno();
1416 } else {
1417 herrno_to_wsaerrno();
1419 send_message(hWnd, wMsg, handle, wsaerrno() << 16);
1420 exit(0);
1422 memcpy(buf, service, buflen);
1423 send_message(hWnd, wMsg, handle, 0);
1424 exit(0);
1428 INT WSAAsyncSelect(SOCKET s, HWND hWnd, u_int wMsg, long lEvent)
1430 long event;
1431 fd_set read_fds, write_fds, except_fds;
1432 int errors = 0;
1433 int newpid;
1435 if (!wsa_initted) {
1436 WSASetLastError(WSANOTINITIALISED);
1437 return SOCKET_ERROR;
1440 dprintf_winsock(stddeb, "WSA_AsyncSelect: socket %d, HWND %04x, wMsg %d, event %ld\n", s, hWnd, wMsg, lEvent);
1442 /* remove outstanding asyncselect() processes */
1443 /* kill */
1445 if (wMsg == 0 && lEvent == 0)
1446 return 0;
1448 newpid = fork();
1449 if (newpid) {
1450 dprintf_winsock(stddeb, "forked, child is (%d)\n",newpid);
1451 return 0;
1452 } else {
1453 while (1) {
1454 FD_ZERO(&read_fds);
1455 FD_ZERO(&write_fds);
1456 FD_ZERO(&except_fds);
1458 if (lEvent & FD_READ)
1459 FD_SET(s, &read_fds);
1460 if (lEvent & FD_WRITE)
1461 FD_SET(s, &write_fds);
1463 fcntl(s, F_SETFL, O_NONBLOCK);
1464 if (select(s + 1, &read_fds, &write_fds, &except_fds, NULL)<0) {
1465 errors = wsaerrno();
1468 event = 0;
1469 if (FD_ISSET(s, &read_fds))
1470 event |= FD_READ;
1471 if (FD_ISSET(s, &write_fds))
1472 event |= FD_WRITE;
1473 send_message(hWnd, wMsg, s, WSAMAKESELECTREPLY(event,errors));
1478 INT WSAFDIsSet(SOCKET fd, WinSock_fd_set *set)
1480 int i = set->fd_count;
1482 dprintf_winsock(stddeb, "__WSAFDIsSet(%d,%8lx)\n",fd,(unsigned long)set);
1484 while (i--)
1486 if (set->fd_array[i] == fd)
1488 dprintf_winsock(stddeb, "__WSAFDIsSet returning 1\n");
1489 return 1;
1492 dprintf_winsock(stddeb, "__WSAFDIsSet returning 0\n");
1493 return 0;
1496 INT WSACancelAsyncRequest(HANDLE hAsyncTaskHandle)
1498 dprintf_winsock(stddeb, "WSA_AsyncRequest: handle %04x\n", hAsyncTaskHandle);
1500 if (!wsa_initted) {
1501 WSASetLastError(WSANOTINITIALISED);
1502 return SOCKET_ERROR;
1505 return 0;
1508 INT WSACancelBlockingCall(void)
1510 dprintf_winsock(stddeb, "WSA_CancelBlockCall\n");
1512 if (!wsa_initted) {
1513 WSASetLastError(WSANOTINITIALISED);
1514 return SOCKET_ERROR;
1517 return 0;
1520 INT WSAGetLastError(void)
1522 dprintf_winsock(stddeb, "WSA_GetLastError = %x\n", wsa_errno);
1524 return wsa_errno;
1527 void WSASetLastError(INT iError)
1529 dprintf_winsock(stddeb, "WSA_SetLastErorr %d\n", iError);
1531 /* technically, we should make sure that WINESockets
1532 * has been started up correctly. But since this function
1533 * is also used internally, it makes no sense.
1535 *if (!wsa_initted) {
1536 * WSASetLastError(WSANOTINITIALISED);
1537 * return SOCKET_ERROR;
1541 wsa_errno = iError;
1544 BOOL WSAIsBlocking(void)
1546 dprintf_winsock(stddeb, "WSA_IsBlocking\n");
1548 return 0;
1551 FARPROC16 WSASetBlockingHook(FARPROC16 lpBlockFunc)
1553 dprintf_winsock(stddeb, "WSA_SetBlockHook %8lx, STUB!\n", (unsigned long) lpBlockFunc);
1555 if (!wsa_initted) {
1556 WSASetLastError(WSANOTINITIALISED);
1557 return NULL;
1560 BlockFunction = lpBlockFunc;
1562 return (FARPROC16) lpBlockFunc;
1565 INT WSAUnhookBlockingHook(void)
1567 dprintf_winsock(stddeb, "WSA_UnhookBlockingHook\n");
1569 if (!wsa_initted) {
1570 WSASetLastError(WSANOTINITIALISED);
1571 return NULL;
1574 BlockFunction = NULL;
1576 return 0;
1579 #ifdef 0
1580 WSADATA WINSOCK_data = {
1581 0x0101,
1582 0x0101,
1583 "WINE Sockets",
1584 #ifdef linux
1585 "LINUX/i386",
1586 #elif defined(__NetBSD__)
1587 "NetBSD/i386",
1588 #elif defined(sunos)
1589 "SunOS",
1590 #elif defined(__FreeBSD__)
1591 "FreeBSD",
1592 #else
1593 "Unknown",
1594 #endif
1595 WINSOCK_MAX_SOCKETS,
1596 WINSOCK_MAX_UDPDG,
1597 NULL
1599 #endif
1601 INT WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData)
1604 WSADATA WINSOCK_data = {
1605 0x0101,
1606 0x0101,
1607 "WINE Sockets",
1608 #ifdef linux
1609 "Linux/i386",
1610 #elif defined(__NetBSD__)
1611 "NetBSD/i386",
1612 #elif defined(sunos)
1613 "SunOS",
1614 #elif defined(__FreeBSD__)
1615 "FreeBSD",
1616 #else
1617 "Unknown",
1618 #endif
1619 WINSOCK_MAX_SOCKETS,
1620 WINSOCK_MAX_UDPDG,
1621 NULL
1624 dprintf_winsock(stddeb, "WSAStartup: verReq=%x\n", wVersionRequested);
1626 if (LOBYTE(wVersionRequested) < 1 ||
1627 (LOBYTE(wVersionRequested) == 1 &&
1628 HIBYTE(wVersionRequested) < 1))
1629 return WSAVERNOTSUPPORTED;
1631 if (!lpWSAData)
1632 return WSAEINVAL;
1634 /* alloc winsock heap */
1636 if ((HeapHandle = GlobalAlloc16(GMEM_FIXED,sizeof(struct WinSockHeap))) == 0)
1637 return WSASYSNOTREADY;
1639 Heap = (struct WinSockHeap *) GlobalLock16(HeapHandle);
1641 /* return winsock information */
1642 memcpy(lpWSAData, &WINSOCK_data, sizeof(WINSOCK_data));
1644 /* ipc stuff */
1646 if ((wine_key = msgget(IPC_PRIVATE, 0600)) == -1)
1647 perror("wine: winsock: msgget");
1649 signal(SIGUSR1, recv_message);
1651 /* clear */
1653 FD_ZERO(&fd_in_use);
1655 /* increment our usage count */
1656 wsa_initted++;
1657 dprintf_winsock(stddeb, "WSAStartup: succeeded\n");
1658 return(0);
1661 INT WSACleanup(void)
1663 int fd;
1665 dprintf_winsock(stddeb, "WSACleanup (%d)\n",getpid());
1667 if (!wsa_initted) {
1668 WSASetLastError(WSANOTINITIALISED);
1669 return SOCKET_ERROR;
1672 /* decrement usage count */
1673 wsa_initted--;
1675 if (wsa_initted == 0) {
1676 if (wine_key)
1677 if (msgctl(wine_key, IPC_RMID, NULL) == -1)
1678 perror("wine: winsock: msgctl");
1680 for (fd = 0; fd != FD_SETSIZE; fd++)
1681 if (FD_ISSET(fd, &fd_in_use))
1682 close(fd);
1685 return 0;
1688 VOID
1689 WsControl(DWORD x1,DWORD x2,LPDWORD x3,LPDWORD x4,LPDWORD x5,LPDWORD x6) {
1690 fprintf(stdnimp,"WsControl(%lx,%lx,%p,%p,%p,%p)\n",
1691 x1,x2,x3,x4,x5,x6
1693 fprintf(stdnimp,"WsControl(x,x,%lx,%lx,%lx,%lx)\n",
1694 x3?*x3:0,x4?*x4:0,x5?*x5:0,x6?*x6:0
1696 return;