2 * based on Windows Sockets 1.1 specs
3 * (ftp.microsoft.com:/Advsys/winsock/spec11/WINSOCK.TXT)
5 * (C) 1993,1994 John Brezak, Erik Bos.
11 #include <sys/types.h>
13 #include <sys/ioctl.h>
15 #include <sys/filio.h>
16 #include <sys/ioccom.h>
19 #include <sys/socket.h>
20 #include <netinet/in.h>
21 #include <arpa/inet.h>
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
;
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 */
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 */
80 SEGPTR p_name WINE_PACKED
; /* official protocol name */
81 SEGPTR p_aliases WINE_PACKED
; /* alias list */
82 INT p_proto WINE_PACKED
; /* protocol # */
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 */
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 */
116 static struct WinSockHeap
*Heap
;
117 static HANDLE HeapHandle
;
119 static int ScratchPtr
;
123 #define GET_SEG_PTR(x) MAKELONG((int)((char*)(x)-(char*)Heap), \
124 GlobalHandleToSel(HeapHandle))
126 #define GET_SEG_PTR(x) ((SEGPTR)x)
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))
140 static void ResetScratch()
145 static void *scratch_alloc(int size
)
148 if(ScratchPtr
+size
> sizeof(Heap
->scratch
))
150 ret
= Heap
->scratch
+ ScratchPtr
;
155 static SEGPTR
scratch_strdup(char * s
)
157 char *ret
=scratch_alloc(strlen(s
)+1);
159 return GET_SEG_PTR(ret
);
163 static WORD
wsaerrno(void)
167 #if defined(__FreeBSD__)
168 fprintf(stderr
, "winsock: errno %d, (%s).\n",
169 errno
, sys_errlist
[errno
]);
171 fprintf(stderr
, "winsock: errno %d\n", errno
);
174 fprintf(stderr
, "winsock: errno %d\n", 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
;
219 case EPROCLIM
: return WSAEPROCLIM
;
222 case EUSERS
: return WSAEUSERS
;
225 case EDQUOT
: return WSAEDQUOT
;
227 case ESTALE
: return WSAESTALE
;
228 case EREMOTE
: return WSAEREMOTE
;
229 /* just in case we ever get here and there are no problems */
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)
248 #if defined(__FreeBSD__)
249 fprintf(stderr
, "winsock: h_errno %d, (%s).\n",
250 h_errno
, sys_errlist
[h_errno
]);
252 fprintf(stderr
, "winsock: h_errno %d.\n", h_errno
);
253 herror("wine: winsock: wsaherrno");
256 fprintf(stderr
, "winsock: h_errno %d\n", 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 */
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 ? */
291 case 0x01: *optname
= SO_DEBUG
;
293 case 0x04: *optname
= SO_REUSEADDR
;
295 case 0x08: *optname
= SO_KEEPALIVE
;
297 case 0x10: *optname
= SO_DONTROUTE
;
299 case 0x20: *optname
= SO_BROADCAST
;
301 case 0x80: *optname
= SO_LINGER
;
303 case 0x100: *optname
= SO_OOBINLINE
;
305 case 0x1001: *optname
= SO_SNDBUF
;
307 case 0x1002: *optname
= SO_RCVBUF
;
309 case 0x1007: *optname
= SO_ERROR
;
311 case 0x1008: *optname
= SO_TYPE
;
314 fprintf(stderr
, "convert_sockopt() unknown optname %d\n", *optname
);
318 case 6: *optname
= IPPROTO_TCP
;
323 static SEGPTR
copy_stringlist(char **list
)
329 s_list
= scratch_alloc(sizeof(SEGPTR
)*(i
+1));
332 void *copy
= scratch_alloc(strlen(list
[i
])+1);
333 strcpy(copy
,list
[i
]);
334 s_list
[i
]=GET_SEG_PTR(copy
);
337 return GET_SEG_PTR(s_list
);
341 static void CONVERT_HOSTENT(struct WIN_hostent
*heapent
, struct hostent
*host
)
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 */
350 heapent
->h_aliases
= 0;
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
);
369 static void CONVERT_PROTOENT(struct WIN_protoent
*heapent
,
370 struct protoent
*proto
)
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
)
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
);
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))
394 SOCKET
WINSOCK_accept(SOCKET s
, struct sockaddr
*addr
, INT
*addrlen
)
398 dprintf_winsock(stddeb
, "WSA_accept: socket %d, ptr %8x, length %d\n", s
, (int) addr
, *addrlen
);
401 WSASetLastError(WSANOTINITIALISED
);
402 return INVALID_SOCKET
;
405 if ((sock
= accept(s
, addr
, (int *) addrlen
)) < 0) {
407 return INVALID_SOCKET
;
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
);
419 WSASetLastError(WSANOTINITIALISED
);
423 if (namelen
< sizeof(*name
)) {
424 WSASetLastError(WSAEFAULT
);
428 /* check the socket family */
429 if ( ((struct sockaddr_in
*)name
)->sin_family
!= AF_INET
) {
430 WSASetLastError(WSAEAFNOSUPPORT
);
434 if (bind(s
, name
, namelen
) < 0) {
437 WSASetLastError(WSAENOTSOCK
);
440 WSASetLastError(WSAEINVAL
);
451 INT
WINSOCK_closesocket(SOCKET s
)
453 dprintf_winsock(stddeb
, "WSA_closesocket: socket %d\n", s
);
456 WSASetLastError(WSANOTINITIALISED
);
460 FD_CLR(s
, &fd_in_use
);
464 WSASetLastError(WSAENOTSOCK
);
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
);
478 WSASetLastError(WSANOTINITIALISED
);
482 if (connect(s
, name
, namelen
) < 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
);
495 WSASetLastError(WSANOTINITIALISED
);
499 if (getpeername(s
, name
, (int *) namelen
) < 0) {
503 herrno_to_wsaerrno();
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
);
515 WSASetLastError(WSANOTINITIALISED
);
519 if (getsockname(s
, name
, (int *) namelen
) < 0) {
523 herrno_to_wsaerrno();
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
);
536 WSASetLastError(WSANOTINITIALISED
);
540 convert_sockopt(&level
, &optname
);
542 if (getsockopt(s
, (int) level
, optname
, optval
, (int *) optlen
) < 0) {
544 WSASetLastError(WSAENOTSOCK
);
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
)
571 /* dprintf_winsock(stddeb, "WSA_inet_ntoa: %8lx\n", (int) in);*/
573 if ((s
= inet_ntoa(in
)) == 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
)
588 dprintf_winsock(stddeb
, "WSA_ioctl: socket %d, cmd %lX, ptr %8x\n", s
, cmd
, (int) argp
);
591 WSASetLastError(WSANOTINITIALISED
);
595 /* Why can't they all use the same ioctl numbers */
599 if(cmd
== _IOR('f',127,u_long
))
604 if(cmd
== _IOW('f',126,u_long
) || cmd
== _IOR('f',126,u_long
))
609 if(cmd
== _IOW('f',125,u_long
))
616 fprintf(stderr
,"Unknown winsock ioctl. Trying anyway\n");
618 dprintf_winsock(stddeb
,"Recognized as %s\n", ctlname
);
621 if (ioctl(s
, newcmd
, newargp
) < 0) {
623 WSASetLastError(WSAENOTSOCK
);
631 INT
WINSOCK_listen(SOCKET s
, INT backlog
)
633 dprintf_winsock(stddeb
, "WSA_listen: socket %d, backlog %d\n", s
, backlog
);
636 WSASetLastError(WSANOTINITIALISED
);
640 if (listen(s
, backlog
) < 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
)
661 dprintf_winsock(stddeb
, "WSA_recv: socket %d, ptr %8x, length %d, flags %d\n", s
, (int) buf
, len
, flags
);
664 WSASetLastError(WSANOTINITIALISED
);
668 if ((length
= recv(s
, buf
, len
, flags
)) < 0) {
675 INT
WINSOCK_recvfrom(SOCKET s
, char *buf
, INT len
, INT flags
,
676 struct sockaddr
*from
, int *fromlen
)
680 dprintf_winsock(stddeb
, "WSA_recvfrom: socket %d, ptr %8lx, length %d, flags %d\n", s
, (unsigned long)buf
, len
, flags
);
683 WSASetLastError(WSANOTINITIALISED
);
687 if ((length
= recvfrom(s
, buf
, len
, flags
, from
, fromlen
)) < 0) {
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
)
702 fd_set readfds
,writefds
,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
);
710 WSASetLastError(WSANOTINITIALISED
);
711 dprintf_winsock(stddeb
, "WSA_select: returning error WSANOTINITIALISED\n");
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
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");
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");
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");
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
);
762 dprintf_winsock(stddeb
, "WSA_select returning: Error %d\n",SOCKET_ERROR
);
766 /* update the winsock fd sets */
767 if(ws_readfds
!=NULL
) {
768 dprintf_winsock(stddeb
, "readfds: ");
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
;
779 dprintf_winsock(stddeb
, "readfds: (null)\n");
781 if(ws_writefds
!=NULL
) {
782 dprintf_winsock(stddeb
, "writefds: ");
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
;
793 dprintf_winsock(stddeb
, "writefds: (null)\n");
795 if(ws_exceptfds
!=NULL
) {
796 dprintf_winsock(stddeb
, "exceptfds: ");
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
;
807 dprintf_winsock(stddeb
, "exceptfds: (null)\n");
810 dprintf_winsock(stddeb
, "WSA_select returning: %d\n",ret
);
814 INT
WINSOCK_send(SOCKET s
, char *buf
, INT len
, INT flags
)
818 dprintf_winsock(stddeb
, "WSA_send: socket %d, ptr %8lx, length %d, flags %d\n", s
, (unsigned long) buf
, len
, flags
);
821 WSASetLastError(WSANOTINITIALISED
);
825 if ((length
= send(s
, buf
, len
, flags
)) < 0) {
832 INT
WINSOCK_sendto(SOCKET s
, char *buf
, INT len
, INT flags
,
833 struct sockaddr
*to
, INT tolen
)
837 dprintf_winsock(stddeb
, "WSA_sendto: socket %d, ptr %8lx, length %d, flags %d\n", s
, (unsigned long) buf
, len
, flags
);
840 WSASetLastError(WSANOTINITIALISED
);
844 if ((length
= sendto(s
, buf
, len
, flags
, to
, tolen
)) < 0) {
851 INT
WINSOCK_setsockopt(SOCKET s
, INT level
, INT optname
, const char *optval
,
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
);
858 WSASetLastError(WSANOTINITIALISED
);
862 if (setsockopt(s
, level
, optname
, optval
, optlen
) < 0) {
869 INT
WINSOCK_shutdown(SOCKET s
, INT how
)
871 dprintf_winsock(stddeb
, "WSA_shutdown: socket s %d, how %d\n", s
, how
);
874 WSASetLastError(WSANOTINITIALISED
);
878 if (shutdown(s
, how
) < 0) {
885 SOCKET
WINSOCK_socket(INT af
, INT type
, INT protocol
)
889 dprintf_winsock(stddeb
, "WSA_socket: af=%d type=%d protocol=%d\n", af
, type
, protocol
);
892 WSASetLastError(WSANOTINITIALISED
);
893 return INVALID_SOCKET
;
896 /* check the socket family */
902 WSASetLastError(WSAEAFNOSUPPORT
);
903 return INVALID_SOCKET
;
907 /* check the socket type */
914 WSASetLastError(WSAESOCKTNOSUPPORT
);
915 return INVALID_SOCKET
;
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? */
928 if (type
== SOCK_STREAM
) {
933 if (type
== SOCK_DGRAM
) {
938 WSASetLastError(WSAEPROTOTYPE
);
939 return INVALID_SOCKET
;
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
);
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
);
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
);
979 WSASetLastError(WSANOTINITIALISED
);
983 if ((host
= gethostbyaddr(addr
, len
, type
)) == NULL
) {
987 herrno_to_wsaerrno();
991 CONVERT_HOSTENT(&Heap
->hostent_addr
, host
);
993 return GET_SEG_PTR(&Heap
->hostent_addr
);
999 SEGPTR
WINSOCK_gethostbyname(const char *name
)
1001 struct hostent
*host
;
1003 dprintf_winsock(stddeb
, "WSA_gethostbyname: %s\n", name
);
1006 WSASetLastError(WSANOTINITIALISED
);
1010 if ((host
= gethostbyname(name
)) == NULL
) {
1012 errno_to_wsaerrno();
1014 herrno_to_wsaerrno();
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
);
1028 WSASetLastError(WSANOTINITIALISED
);
1029 return SOCKET_ERROR
;
1032 if (gethostname(name
, namelen
) < 0) {
1033 if (errno
== EINVAL
)
1034 WSASetLastError(WSAEFAULT
);
1036 errno_to_wsaerrno();
1037 return SOCKET_ERROR
;
1043 struct WIN_protoent *
1045 SEGPTR
WINSOCK_getprotobyname(char *name
)
1047 struct protoent
*proto
;
1049 dprintf_winsock(stddeb
, "WSA_getprotobyname: name %s\n", name
);
1052 WSASetLastError(WSANOTINITIALISED
);
1056 if ((proto
= getprotobyname(name
)) == NULL
) {
1058 errno_to_wsaerrno();
1060 herrno_to_wsaerrno();
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
);
1079 WSASetLastError(WSANOTINITIALISED
);
1083 if ((proto
= getprotobynumber(number
)) == NULL
) {
1086 errno_to_wsaerrno();
1088 herrno_to_wsaerrno();
1091 WSASetLastError(WSANO_DATA
);
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
;
1109 dprintf_winsock(stddeb
, "WSA_getservbyname: name %s, proto %s\n", name
, proto
);
1112 WSASetLastError(WSANOTINITIALISED
);
1116 if ((service
= getservbyname(name
, proto
)) == NULL
) {
1118 errno_to_wsaerrno();
1120 herrno_to_wsaerrno();
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
);
1139 WSASetLastError(WSANOTINITIALISED
);
1143 if ((service
= getservbyport(port
, proto
)) == NULL
) {
1145 errno_to_wsaerrno();
1147 herrno_to_wsaerrno();
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;
1172 message
.mtype
= MTYPE
;
1174 signal(SIGUSR1
, recv_message
);
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");
1185 result
= PostMessage(message
.hWnd
, message
.wMsg
,
1186 (WPARAM
)message
.handle
, message
.lParam
);
1187 if (result
!= FALSE
) {
1188 message_is_valid
= 1;
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
)
1223 struct hostent
*host
;
1227 WSASetLastError(WSANOTINITIALISED
);
1231 handle
= AllocWSAHandle();
1235 dprintf_winsock(stddeb
, "forked, child is (%d)\n",newpid
);
1238 if ((host
= gethostbyaddr(addr
, len
, type
)) == NULL
) {
1240 errno_to_wsaerrno();
1242 herrno_to_wsaerrno();
1244 send_message(hWnd
, wMsg
, handle
, wsaerrno() << 16);
1247 memcpy(buf
, host
, buflen
);
1248 send_message(hWnd
, wMsg
, handle
, 0);
1254 HANDLE
WSAAsyncGetHostByName(HWND hWnd
, u_int wMsg
, LPCSTR name
,
1255 LPSTR buf
, INT buflen
)
1258 struct hostent
*host
;
1262 WSASetLastError(WSANOTINITIALISED
);
1266 handle
= AllocWSAHandle();
1270 dprintf_winsock(stddeb
, "forked, child is (%d)\n",newpid
);
1273 if ((host
= gethostbyname(name
)) == NULL
) {
1275 errno_to_wsaerrno();
1277 herrno_to_wsaerrno();
1279 send_message(hWnd
, wMsg
, handle
, wsaerrno() << 16);
1282 memcpy(buf
, host
, buflen
);
1283 send_message(hWnd
, wMsg
, handle
, 0);
1289 HANDLE
WSAAsyncGetProtoByName(HWND hWnd
, u_int wMsg
, LPCSTR name
,
1290 LPSTR buf
, INT buflen
)
1293 struct protoent
*proto
;
1297 WSASetLastError(WSANOTINITIALISED
);
1301 handle
= AllocWSAHandle();
1305 dprintf_winsock(stddeb
, "forked, child is (%d)\n",newpid
);
1308 if ((proto
= getprotobyname(name
)) == NULL
) {
1310 errno_to_wsaerrno();
1312 herrno_to_wsaerrno();
1314 send_message(hWnd
, wMsg
, handle
, wsaerrno() << 16);
1317 memcpy(buf
, proto
, buflen
);
1318 send_message(hWnd
, wMsg
, handle
, 0);
1324 HANDLE
WSAAsyncGetProtoByNumber(HWND hWnd
, u_int wMsg
, INT number
,
1325 LPSTR buf
, INT buflen
)
1328 struct protoent
*proto
;
1332 WSASetLastError(WSANOTINITIALISED
);
1336 handle
= AllocWSAHandle();
1340 dprintf_winsock(stddeb
, "forked, child is (%d)\n",newpid
);
1343 if ((proto
= getprotobynumber(number
)) == NULL
) {
1345 errno_to_wsaerrno();
1347 herrno_to_wsaerrno();
1349 send_message(hWnd
, wMsg
, handle
, wsaerrno() << 16);
1352 memcpy(buf
, proto
, buflen
);
1353 send_message(hWnd
, wMsg
, handle
, 0);
1359 HANDLE
WSAAsyncGetServByName(HWND hWnd
, u_int wMsg
, LPCSTR name
,
1360 LPCSTR proto
, LPSTR buf
, INT buflen
)
1363 struct servent
*service
;
1367 WSASetLastError(WSANOTINITIALISED
);
1371 handle
= AllocWSAHandle();
1375 dprintf_winsock(stddeb
, "forked, child is (%d)\n",newpid
);
1378 if ((service
= getservbyname(name
, proto
)) == NULL
) {
1380 errno_to_wsaerrno();
1382 herrno_to_wsaerrno();
1384 send_message(hWnd
, wMsg
, handle
, wsaerrno() << 16);
1387 memcpy(buf
, service
, buflen
);
1388 send_message(hWnd
, wMsg
, handle
, 0);
1394 HANDLE
WSAAsyncGetServByPort(HWND hWnd
, u_int wMsg
, INT port
, LPCSTR proto
,
1395 LPSTR buf
, INT buflen
)
1398 struct servent
*service
;
1402 WSASetLastError(WSANOTINITIALISED
);
1406 handle
= AllocWSAHandle();
1410 dprintf_winsock(stddeb
, "forked, child is (%d)\n",newpid
);
1413 if ((service
= getservbyport(port
, proto
)) == NULL
) {
1415 errno_to_wsaerrno();
1417 herrno_to_wsaerrno();
1419 send_message(hWnd
, wMsg
, handle
, wsaerrno() << 16);
1422 memcpy(buf
, service
, buflen
);
1423 send_message(hWnd
, wMsg
, handle
, 0);
1428 INT
WSAAsyncSelect(SOCKET s
, HWND hWnd
, u_int wMsg
, long lEvent
)
1431 fd_set read_fds
, write_fds
, except_fds
;
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 */
1445 if (wMsg
== 0 && lEvent
== 0)
1450 dprintf_winsock(stddeb
, "forked, child is (%d)\n",newpid
);
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();
1469 if (FD_ISSET(s
, &read_fds
))
1471 if (FD_ISSET(s
, &write_fds
))
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
);
1486 if (set
->fd_array
[i
] == fd
)
1488 dprintf_winsock(stddeb
, "__WSAFDIsSet returning 1\n");
1492 dprintf_winsock(stddeb
, "__WSAFDIsSet returning 0\n");
1496 INT
WSACancelAsyncRequest(HANDLE hAsyncTaskHandle
)
1498 dprintf_winsock(stddeb
, "WSA_AsyncRequest: handle %04x\n", hAsyncTaskHandle
);
1501 WSASetLastError(WSANOTINITIALISED
);
1502 return SOCKET_ERROR
;
1508 INT
WSACancelBlockingCall(void)
1510 dprintf_winsock(stddeb
, "WSA_CancelBlockCall\n");
1513 WSASetLastError(WSANOTINITIALISED
);
1514 return SOCKET_ERROR
;
1520 INT
WSAGetLastError(void)
1522 dprintf_winsock(stddeb
, "WSA_GetLastError = %x\n", 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;
1544 BOOL
WSAIsBlocking(void)
1546 dprintf_winsock(stddeb
, "WSA_IsBlocking\n");
1551 FARPROC16
WSASetBlockingHook(FARPROC16 lpBlockFunc
)
1553 dprintf_winsock(stddeb
, "WSA_SetBlockHook %8lx, STUB!\n", (unsigned long) lpBlockFunc
);
1556 WSASetLastError(WSANOTINITIALISED
);
1560 BlockFunction
= lpBlockFunc
;
1562 return (FARPROC16
) lpBlockFunc
;
1565 INT
WSAUnhookBlockingHook(void)
1567 dprintf_winsock(stddeb
, "WSA_UnhookBlockingHook\n");
1570 WSASetLastError(WSANOTINITIALISED
);
1574 BlockFunction
= NULL
;
1580 WSADATA WINSOCK_data
= {
1586 #elif defined(__NetBSD__)
1588 #elif defined(sunos)
1590 #elif defined(__FreeBSD__)
1595 WINSOCK_MAX_SOCKETS
,
1601 INT
WSAStartup(WORD wVersionRequested
, LPWSADATA lpWSAData
)
1604 WSADATA WINSOCK_data
= {
1610 #elif defined(__NetBSD__)
1612 #elif defined(sunos)
1614 #elif defined(__FreeBSD__)
1619 WINSOCK_MAX_SOCKETS
,
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
;
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
));
1646 if ((wine_key
= msgget(IPC_PRIVATE
, 0600)) == -1)
1647 perror("wine: winsock: msgget");
1649 signal(SIGUSR1
, recv_message
);
1653 FD_ZERO(&fd_in_use
);
1655 /* increment our usage count */
1657 dprintf_winsock(stddeb
, "WSAStartup: succeeded\n");
1661 INT
WSACleanup(void)
1665 dprintf_winsock(stddeb
, "WSACleanup (%d)\n",getpid());
1668 WSASetLastError(WSANOTINITIALISED
);
1669 return SOCKET_ERROR
;
1672 /* decrement usage count */
1675 if (wsa_initted
== 0) {
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
))
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",
1693 fprintf(stdnimp
,"WsControl(x,x,%lx,%lx,%lx,%lx)\n",
1694 x3
?*x3
:0,x4
?*x4
:0,x5
?*x5
:0,x6
?*x6
:0