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>
32 static WORD wsa_errno
;
33 static int wsa_initted
;
34 static key_t wine_key
= 0;
35 static FARPROC BlockFunction
;
36 static fd_set fd_in_use
;
50 #define IPC_PACKET_SIZE (sizeof(struct ipc_packet) - sizeof(long))
51 #define MTYPE 0xb0b0eb05
53 /* These structures are Win16 only */
56 SEGPTR h_name WINE_PACKED
; /* official name of host */
57 SEGPTR h_aliases WINE_PACKED
; /* alias list */
58 INT h_addrtype WINE_PACKED
; /* host address type */
59 INT h_length WINE_PACKED
; /* length of address */
60 char **h_addr_list WINE_PACKED
; /* list of addresses from name server */
66 SEGPTR p_name WINE_PACKED
; /* official protocol name */
67 SEGPTR p_aliases WINE_PACKED
; /* alias list */
68 INT p_proto WINE_PACKED
; /* protocol # */
72 SEGPTR s_name WINE_PACKED
; /* official service name */
73 SEGPTR s_aliases WINE_PACKED
; /* alias list */
74 INT s_port WINE_PACKED
; /* port # */
75 SEGPTR s_proto WINE_PACKED
; /* protocol to use */
81 struct WIN_hostent hostent_addr
;
82 struct WIN_hostent hostent_name
;
83 struct WIN_protoent protoent_name
;
84 struct WIN_protoent protoent_number
;
85 struct WIN_servent servent_name
;
86 struct WIN_servent servent_port
;
88 struct WIN_hostent WSAhostent_addr
;
89 struct WIN_hostent WSAhostent_name
;
90 struct WIN_protoent WSAprotoent_name
;
91 struct WIN_protoent WSAprotoent_number
;
92 struct WIN_servent WSAservent_name
;
93 struct WIN_servent WSAservent_port
;
94 /* 8K scratch buffer for aliases and friends are hopefully enough */
97 static struct WinSockHeap
*Heap
;
98 static HANDLE HeapHandle
;
100 static int ScratchPtr
;
104 #define GET_SEG_PTR(x) MAKELONG((int)((char*)(x)-(char*)Heap), \
105 GlobalHandleToSel(HeapHandle))
107 #define GET_SEG_PTR(x) ((SEGPTR)x)
114 #define dump_sockaddr(a) \
115 fprintf(stderr, "sockaddr_in: family %d, address %s, port %d\n", \
116 ((struct sockaddr_in *)a)->sin_family, \
117 inet_ntoa(((struct sockaddr_in *)a)->sin_addr), \
118 ntohs(((struct sockaddr_in *)a)->sin_port))
121 static void ResetScratch()
126 static void *scratch_alloc(int size
)
129 if(ScratchPtr
+size
> sizeof(Heap
->scratch
))
131 ret
= Heap
->scratch
+ ScratchPtr
;
136 static SEGPTR
scratch_strdup(char * s
)
138 char *ret
=scratch_alloc(strlen(s
)+1);
140 return GET_SEG_PTR(ret
);
144 static WORD
wsaerrno(void)
148 #if defined(__FreeBSD__)
149 fprintf(stderr
, "winsock: errno %d, (%s).\n",
150 errno
, sys_errlist
[errno
]);
152 fprintf(stderr
, "winsock: errno %d, (%s).\n",
153 errno
, strerror(errno
));
156 fprintf(stderr
, "winsock: errno %d\n", errno
);
162 case EINTR
: return WSAEINTR
;
163 case EBADF
: return WSAEBADF
;
164 case EACCES
: return WSAEACCES
;
165 case EFAULT
: return WSAEFAULT
;
166 case EINVAL
: return WSAEINVAL
;
167 case EMFILE
: return WSAEMFILE
;
168 case EWOULDBLOCK
: return WSAEWOULDBLOCK
;
169 case EINPROGRESS
: return WSAEINPROGRESS
;
170 case EALREADY
: return WSAEALREADY
;
171 case ENOTSOCK
: return WSAENOTSOCK
;
172 case EDESTADDRREQ
: return WSAEDESTADDRREQ
;
173 case EMSGSIZE
: return WSAEMSGSIZE
;
174 case EPROTOTYPE
: return WSAEPROTOTYPE
;
175 case ENOPROTOOPT
: return WSAENOPROTOOPT
;
176 case EPROTONOSUPPORT
: return WSAEPROTONOSUPPORT
;
177 case ESOCKTNOSUPPORT
: return WSAESOCKTNOSUPPORT
;
178 case EOPNOTSUPP
: return WSAEOPNOTSUPP
;
179 case EPFNOSUPPORT
: return WSAEPFNOSUPPORT
;
180 case EAFNOSUPPORT
: return WSAEAFNOSUPPORT
;
181 case EADDRINUSE
: return WSAEADDRINUSE
;
182 case EADDRNOTAVAIL
: return WSAEADDRNOTAVAIL
;
183 case ENETDOWN
: return WSAENETDOWN
;
184 case ENETUNREACH
: return WSAENETUNREACH
;
185 case ENETRESET
: return WSAENETRESET
;
186 case ECONNABORTED
: return WSAECONNABORTED
;
187 case ECONNRESET
: return WSAECONNRESET
;
188 case ENOBUFS
: return WSAENOBUFS
;
189 case EISCONN
: return WSAEISCONN
;
190 case ENOTCONN
: return WSAENOTCONN
;
191 case ESHUTDOWN
: return WSAESHUTDOWN
;
192 case ETOOMANYREFS
: return WSAETOOMANYREFS
;
193 case ETIMEDOUT
: return WSAETIMEDOUT
;
194 case ECONNREFUSED
: return WSAECONNREFUSED
;
195 case ELOOP
: return WSAELOOP
;
196 case ENAMETOOLONG
: return WSAENAMETOOLONG
;
197 case EHOSTDOWN
: return WSAEHOSTDOWN
;
198 case EHOSTUNREACH
: return WSAEHOSTUNREACH
;
199 case ENOTEMPTY
: return WSAENOTEMPTY
;
201 case EPROCLIM
: return WSAEPROCLIM
;
203 case EUSERS
: return WSAEUSERS
;
205 case EDQUOT
: return WSAEDQUOT
;
207 case ESTALE
: return WSAESTALE
;
208 case EREMOTE
: return WSAEREMOTE
;
209 /* just in case we ever get here and there are no problems */
213 fprintf(stderr
, "winsock: unknown errorno %d!\n", errno
);
214 return WSAEOPNOTSUPP
;
218 static void errno_to_wsaerrno(void)
220 wsa_errno
= wsaerrno();
224 static WORD
wsaherrno(void)
228 #if defined(__FreeBSD__)
229 fprintf(stderr
, "winsock: h_errno %d, (%s).\n",
230 h_errno
, sys_errlist
[h_errno
]);
232 fprintf(stderr
, "winsock: h_errno %d.\n", h_errno
);
233 herror("wine: winsock: wsaherrno");
236 fprintf(stderr
, "winsock: h_errno %d\n", h_errno
);
242 case TRY_AGAIN
: return WSATRY_AGAIN
;
243 case HOST_NOT_FOUND
: return WSAHOST_NOT_FOUND
;
244 case NO_RECOVERY
: return WSANO_RECOVERY
;
245 case NO_DATA
: return WSANO_DATA
;
246 /* just in case we ever get here and there are no problems */
251 fprintf(stderr
, "winsock: unknown h_errorno %d!\n", h_errno
);
252 return WSAEOPNOTSUPP
;
257 static void herrno_to_wsaerrno(void)
259 wsa_errno
= wsaherrno();
263 static void convert_sockopt(INT
*level
, INT
*optname
)
265 /* $%#%!#! why couldn't they use the same values for both winsock and unix ? */
271 case 0x01: *optname
= SO_DEBUG
;
273 case 0x04: *optname
= SO_REUSEADDR
;
275 case 0x08: *optname
= SO_KEEPALIVE
;
277 case 0x10: *optname
= SO_DONTROUTE
;
279 case 0x20: *optname
= SO_BROADCAST
;
281 case 0x80: *optname
= SO_LINGER
;
283 case 0x100: *optname
= SO_OOBINLINE
;
285 case 0x1001: *optname
= SO_SNDBUF
;
287 case 0x1002: *optname
= SO_RCVBUF
;
289 case 0x1007: *optname
= SO_ERROR
;
291 case 0x1008: *optname
= SO_TYPE
;
294 fprintf(stderr
, "convert_sockopt() unknown optname %d\n", *optname
);
298 case 6: *optname
= IPPROTO_TCP
;
303 static SEGPTR
copy_stringlist(char **list
)
309 s_list
= scratch_alloc(sizeof(SEGPTR
)*(i
+1));
312 void *copy
= scratch_alloc(strlen(list
[i
])+1);
313 strcpy(copy
,list
[i
]);
314 s_list
[i
]=GET_SEG_PTR(copy
);
317 return GET_SEG_PTR(s_list
);
321 static void CONVERT_HOSTENT(struct WIN_hostent
*heapent
, struct hostent
*host
)
326 strcpy(heapent
->hostname
,host
->h_name
);
327 heapent
->h_name
= GET_SEG_PTR(heapent
->hostname
);
328 /* Convert aliases. Have to create array with FAR pointers */
330 heapent
->h_aliases
= 0;
332 heapent
->h_aliases
= copy_stringlist(host
->h_aliases
);
334 heapent
->h_addrtype
= host
->h_addrtype
;
335 heapent
->h_length
= host
->h_length
;
336 for(i
=0;host
->h_addr_list
[i
];i
++)
338 addr_list
=scratch_alloc(sizeof(SEGPTR
)*(i
+1));
339 heapent
->h_addr_list
= (char**)GET_SEG_PTR(addr_list
);
340 for(i
=0;host
->h_addr_list
[i
];i
++)
342 void *addr
=scratch_alloc(host
->h_length
);
343 memcpy(addr
,host
->h_addr_list
[i
],host
->h_length
);
344 addr_list
[i
]=GET_SEG_PTR(addr
);
349 static void CONVERT_PROTOENT(struct WIN_protoent
*heapent
,
350 struct protoent
*proto
)
353 heapent
->p_name
= scratch_strdup(proto
->p_name
);
354 heapent
->p_aliases
=proto
->p_aliases
?
355 copy_stringlist(proto
->p_aliases
) : 0;
356 heapent
->p_proto
= proto
->p_proto
;
359 static void CONVERT_SERVENT(struct WIN_servent
*heapent
, struct servent
*serv
)
362 heapent
->s_name
= scratch_strdup(serv
->s_name
);
363 heapent
->s_aliases
= serv
->s_aliases
?
364 copy_stringlist(serv
->s_aliases
) : 0;
365 heapent
->s_port
= serv
->s_port
;
366 heapent
->s_proto
= scratch_strdup(serv
->s_proto
);
369 #define CONVERT_HOSTENT(a,b) memcpy(a, &b, sizeof(a))
370 #define CONVERT_PROTOENT(a,b) memcpy(a, &b, sizeof(a))
371 #define CONVERT_SERVENT(a,b) memcpy(a, &b, sizeof(a))
374 SOCKET
WINSOCK_accept(SOCKET s
, struct sockaddr
*addr
, INT
*addrlen
)
378 dprintf_winsock(stddeb
, "WSA_accept: socket %d, ptr %8x, length %d\n", s
, (int) addr
, *addrlen
);
380 if ((sock
= accept(s
, addr
, (int *) addrlen
)) < 0) {
382 return INVALID_SOCKET
;
387 INT
WINSOCK_bind(SOCKET s
, struct sockaddr
*name
, INT namelen
)
389 dprintf_winsock(stddeb
, "WSA_bind: socket %d, ptr %8x, length %d\n", s
, (int) name
, namelen
);
392 if (bind(s
, name
, namelen
) < 0) {
399 INT
WINSOCK_closesocket(SOCKET s
)
401 dprintf_winsock(stddeb
, "WSA_closesocket: socket %d\n", s
);
403 FD_CLR(s
, &fd_in_use
);
412 INT
WINSOCK_connect(SOCKET s
, struct sockaddr
*name
, INT namelen
)
414 dprintf_winsock(stddeb
, "WSA_connect: socket %d, ptr %8x, length %d\n", s
, (int) name
, namelen
);
417 if (connect(s
, name
, namelen
) < 0) {
424 INT
WINSOCK_getpeername(SOCKET s
, struct sockaddr
*name
, INT
*namelen
)
426 dprintf_winsock(stddeb
, "WSA_getpeername: socket: %d, ptr %8x, ptr %8x\n", s
, (int) name
, *namelen
);
429 if (getpeername(s
, name
, (int *) namelen
) < 0) {
433 herrno_to_wsaerrno();
440 INT
WINSOCK_getsockname(SOCKET s
, struct sockaddr
*name
, INT
*namelen
)
442 dprintf_winsock(stddeb
, "WSA_getsockname: socket: %d, ptr %8x, ptr %8x\n", s
, (int) name
, (int) *namelen
);
443 if (getsockname(s
, name
, (int *) namelen
) < 0) {
447 herrno_to_wsaerrno();
455 WINSOCK_getsockopt(SOCKET s
, INT level
, INT optname
, char *optval
, INT
*optlen
)
457 dprintf_winsock(stddeb
, "WSA_getsockopt: socket: %d, opt %d, ptr %8x, ptr %8x\n", s
, level
, (int) optval
, (int) *optlen
);
458 convert_sockopt(&level
, &optname
);
460 if (getsockopt(s
, (int) level
, optname
, optval
, (int *) optlen
) < 0) {
467 u_long
WINSOCK_htonl(u_long hostlong
)
469 return( htonl(hostlong
) );
472 u_short
WINSOCK_htons(u_short hostshort
)
474 return( htons(hostshort
) );
477 u_long
WINSOCK_inet_addr(char *cp
)
479 return( inet_addr(cp
) );
482 char *WINSOCK_inet_ntoa(struct in_addr in
)
486 /* dprintf_winsock(stddeb, "WSA_inet_ntoa: %8lx\n", (int) in);*/
488 if ((s
= inet_ntoa(in
)) == NULL
) {
493 strncpy(Heap
->ntoa_buffer
, s
, sizeof(Heap
->ntoa_buffer
) );
495 return (char *) GET_SEG_PTR(&Heap
->ntoa_buffer
);
498 INT
WINSOCK_ioctlsocket(SOCKET s
, u_long cmd
, u_long
*argp
)
503 dprintf_winsock(stddeb
, "WSA_ioctl: socket %d, cmd %lX, ptr %8x\n", s
, cmd
, (int) argp
);
505 /* Why can't they all use the same ioctl numbers */
509 if(cmd
== _IOR('f',127,u_long
))
514 if(cmd
== _IOW('f',126,u_long
) || cmd
== _IOR('f',126,u_long
))
519 if(cmd
== _IOW('f',125,u_long
))
526 fprintf(stderr
,"Unknown winsock ioctl. Trying anyway\n");
528 dprintf_winsock(stddeb
,"Recognized as %s\n", ctlname
);
531 if (ioctl(s
, newcmd
, newargp
) < 0) {
538 INT
WINSOCK_listen(SOCKET s
, INT backlog
)
540 dprintf_winsock(stddeb
, "WSA_listen: socket %d, backlog %d\n", s
, backlog
);
542 if (listen(s
, backlog
) < 0) {
549 u_long
WINSOCK_ntohl(u_long netlong
)
551 return( ntohl(netlong
) );
554 u_short
WINSOCK_ntohs(u_short netshort
)
556 return( ntohs(netshort
) );
559 INT
WINSOCK_recv(SOCKET s
, char *buf
, INT len
, INT flags
)
563 dprintf_winsock(stddeb
, "WSA_recv: socket %d, ptr %8x, length %d, flags %d\n", s
, (int) buf
, len
, flags
);
565 if ((length
= recv(s
, buf
, len
, flags
)) < 0) {
572 INT
WINSOCK_recvfrom(SOCKET s
, char *buf
, INT len
, INT flags
,
573 struct sockaddr
*from
, int *fromlen
)
577 dprintf_winsock(stddeb
, "WSA_recvfrom: socket %d, ptr %8lx, length %d, flags %d\n", s
, (unsigned long)buf
, len
, flags
);
579 if ((length
= recvfrom(s
, buf
, len
, flags
, from
, fromlen
)) < 0) {
586 INT
WINSOCK_select(INT nfds
, fd_set
*readfds
, fd_set
*writefds
,
587 fd_set
*exceptfds
, struct timeval
*timeout
)
589 dprintf_winsock(stddeb
, "WSA_select: fd # %d, ptr %8lx, ptr %8lx, ptr %8lX\n", nfds
, (unsigned long) readfds
, (unsigned long) writefds
, (unsigned long) exceptfds
);
591 return(select(nfds
, readfds
, writefds
, exceptfds
, timeout
));
594 INT
WINSOCK_send(SOCKET s
, char *buf
, INT len
, INT flags
)
598 dprintf_winsock(stddeb
, "WSA_send: socket %d, ptr %8lx, length %d, flags %d\n", s
, (unsigned long) buf
, len
, flags
);
600 if ((length
= send(s
, buf
, len
, flags
)) < 0) {
607 INT
WINSOCK_sendto(SOCKET s
, char *buf
, INT len
, INT flags
,
608 struct sockaddr
*to
, INT tolen
)
612 dprintf_winsock(stddeb
, "WSA_sendto: socket %d, ptr %8lx, length %d, flags %d\n", s
, (unsigned long) buf
, len
, flags
);
614 if ((length
= sendto(s
, buf
, len
, flags
, to
, tolen
)) < 0) {
621 INT
WINSOCK_setsockopt(SOCKET s
, INT level
, INT optname
, const char *optval
,
624 dprintf_winsock(stddeb
, "WSA_setsockopt: socket %d, level %d, opt %d, ptr %8x, len %d\n", s
, level
, optname
, (int) optval
, optlen
);
625 convert_sockopt(&level
, &optname
);
627 if (setsockopt(s
, level
, optname
, optval
, optlen
) < 0) {
634 INT
WINSOCK_shutdown(SOCKET s
, INT how
)
636 dprintf_winsock(stddeb
, "WSA_shutdown: socket s %d, how %d\n", s
, how
);
638 if (shutdown(s
, how
) < 0) {
645 SOCKET
WINSOCK_socket(INT af
, INT type
, INT protocol
)
649 dprintf_winsock(stddeb
, "WSA_socket: af=%d type=%d protocol=%d\n", af
, type
, protocol
);
651 if ((sock
= socket(af
, type
, protocol
)) < 0) {
653 dprintf_winsock(stddeb
, "WSA_socket: failed !\n");
654 return INVALID_SOCKET
;
658 /* we set the value of wsa_errno directly, because
659 * only support socket numbers up to 0xffff. The
660 * value return indicates there are no descriptors available
662 wsa_errno
= WSAEMFILE
;
663 return INVALID_SOCKET
;
666 FD_SET(sock
, &fd_in_use
);
668 dprintf_winsock(stddeb
, "WSA_socket: fd %d\n", sock
);
675 SEGPTR
WINSOCK_gethostbyaddr(const char *addr
, INT len
, INT type
)
677 struct hostent
*host
;
679 dprintf_winsock(stddeb
, "WSA_gethostbyaddr: ptr %8x, len %d, type %d\n", (int) addr
, len
, type
);
681 if ((host
= gethostbyaddr(addr
, len
, type
)) == NULL
) {
685 herrno_to_wsaerrno();
689 CONVERT_HOSTENT(&Heap
->hostent_addr
, host
);
691 return GET_SEG_PTR(&Heap
->hostent_addr
);
697 SEGPTR
WINSOCK_gethostbyname(const char *name
)
699 struct hostent
*host
;
701 dprintf_winsock(stddeb
, "WSA_gethostbyname: %s\n", name
);
703 if ((host
= gethostbyname(name
)) == NULL
) {
707 herrno_to_wsaerrno();
711 CONVERT_HOSTENT(&Heap
->hostent_name
, host
);
713 return GET_SEG_PTR(&Heap
->hostent_name
);
716 INT
WINSOCK_gethostname(char *name
, INT namelen
)
718 dprintf_winsock(stddeb
, "WSA_gethostname: name %s, len %d\n", name
, namelen
);
720 if (gethostname(name
, namelen
) < 0) {
724 herrno_to_wsaerrno();
732 struct WIN_protoent *
734 SEGPTR
WINSOCK_getprotobyname(char *name
)
736 struct protoent
*proto
;
738 dprintf_winsock(stddeb
, "WSA_getprotobyname: name %s\n", name
);
740 if ((proto
= getprotobyname(name
)) == NULL
) {
744 herrno_to_wsaerrno();
748 CONVERT_PROTOENT(&Heap
->protoent_name
, proto
);
750 return GET_SEG_PTR(&Heap
->protoent_name
);
754 struct WIN_protoent *
756 SEGPTR
WINSOCK_getprotobynumber(INT number
)
758 struct protoent
*proto
;
760 dprintf_winsock(stddeb
, "WSA_getprotobynumber: num %d\n", number
);
762 if ((proto
= getprotobynumber(number
)) == NULL
) {
766 herrno_to_wsaerrno();
770 CONVERT_PROTOENT(&Heap
->protoent_number
, proto
);
772 return GET_SEG_PTR(&Heap
->protoent_number
);
778 SEGPTR
WINSOCK_getservbyname(const char *name
, const char *proto
)
780 struct servent
*service
;
785 dprintf_winsock(stddeb
, "WSA_getservbyname: name %s, proto %s\n", name
, proto
);
787 if ((service
= getservbyname(name
, proto
)) == NULL
) {
791 herrno_to_wsaerrno();
795 CONVERT_SERVENT(&Heap
->servent_name
, service
);
797 return GET_SEG_PTR(&Heap
->servent_name
);
803 SEGPTR
WINSOCK_getservbyport(INT port
, const char *proto
)
805 struct servent
*service
;
807 dprintf_winsock(stddeb
, "WSA_getservbyport: port %d, name %s\n", port
, proto
);
809 if ((service
= getservbyport(port
, proto
)) == NULL
) {
813 herrno_to_wsaerrno();
817 CONVERT_SERVENT(&Heap
->servent_port
, service
);
819 return GET_SEG_PTR(&Heap
->servent_port
);
822 /******************** winsock specific functions ************************
825 static HANDLE new_handle
= 0;
827 static HANDLE
AllocWSAHandle(void)
832 static void recv_message(int sig
)
834 struct ipc_packet message
;
836 /* FIXME: something about no message of desired type */
837 if (msgrcv(wine_key
, (struct msgbuf
*)&(message
),
838 IPC_PACKET_SIZE
, MTYPE
, IPC_NOWAIT
) == -1)
839 perror("wine: msgrcv");
842 "WSA: PostMessage (hwnd "NPFMT
", wMsg %d, wParam "NPFMT
", lParam %ld)\n",
848 PostMessage(message
.hWnd
, message
.wMsg
, (WPARAM
)message
.handle
, message
.lParam
);
850 signal(SIGUSR1
, recv_message
);
854 static void send_message( HWND hWnd
, u_int wMsg
, HANDLE handle
, long lParam
)
856 struct ipc_packet message
;
858 message
.mtype
= MTYPE
;
859 message
.handle
= handle
;
862 message
.lParam
= lParam
;
865 "WSA: send (hwnd "NPFMT
", wMsg %d, handle "NPFMT
", lParam %ld)\n",
866 hWnd
, wMsg
, handle
, lParam
);
868 /* FIXME: something about invalid argument */
869 if (msgsnd(wine_key
, (struct msgbuf
*)&(message
),
870 IPC_PACKET_SIZE
, IPC_NOWAIT
) == -1)
871 perror("wine: msgsnd");
873 kill(getppid(), SIGUSR1
);
877 HANDLE
WSAAsyncGetHostByAddr(HWND hWnd
, u_int wMsg
, const char *addr
,
878 INT len
, INT type
, char *buf
, INT buflen
)
881 struct hostent
*host
;
883 handle
= AllocWSAHandle();
888 if ((host
= gethostbyaddr(addr
, len
, type
)) == NULL
) {
892 herrno_to_wsaerrno();
894 send_message(hWnd
, wMsg
, handle
, wsaerrno() << 16);
897 memcpy(buf
, host
, buflen
);
898 send_message(hWnd
, wMsg
, handle
, 0);
904 HANDLE
WSAAsyncGetHostByName(HWND hWnd
, u_int wMsg
, const char *name
,
905 char *buf
, INT buflen
)
908 struct hostent
*host
;
910 handle
= AllocWSAHandle();
915 if ((host
= gethostbyname(name
)) == NULL
) {
919 herrno_to_wsaerrno();
921 send_message(hWnd
, wMsg
, handle
, wsaerrno() << 16);
924 memcpy(buf
, host
, buflen
);
925 send_message(hWnd
, wMsg
, handle
, 0);
931 HANDLE
WSAAsyncGetProtoByName(HWND hWnd
, u_int wMsg
, const char *name
,
932 char *buf
, INT buflen
)
935 struct protoent
*proto
;
937 handle
= AllocWSAHandle();
942 if ((proto
= getprotobyname(name
)) == NULL
) {
946 herrno_to_wsaerrno();
948 send_message(hWnd
, wMsg
, handle
, wsaerrno() << 16);
951 memcpy(buf
, proto
, buflen
);
952 send_message(hWnd
, wMsg
, handle
, 0);
958 HANDLE
WSAAsyncGetProtoByNumber(HWND hWnd
, u_int wMsg
, INT number
,
959 char *buf
, INT buflen
)
962 struct protoent
*proto
;
964 handle
= AllocWSAHandle();
969 if ((proto
= getprotobynumber(number
)) == NULL
) {
973 herrno_to_wsaerrno();
975 send_message(hWnd
, wMsg
, handle
, wsaerrno() << 16);
978 memcpy(buf
, proto
, buflen
);
979 send_message(hWnd
, wMsg
, handle
, 0);
985 HANDLE
WSAAsyncGetServByName(HWND hWnd
, u_int wMsg
, const char *name
,
986 const char *proto
, char *buf
, INT buflen
)
989 struct servent
*service
;
991 handle
= AllocWSAHandle();
996 if ((service
= getservbyname(name
, proto
)) == NULL
) {
1000 herrno_to_wsaerrno();
1002 send_message(hWnd
, wMsg
, handle
, wsaerrno() << 16);
1005 memcpy(buf
, service
, buflen
);
1006 send_message(hWnd
, wMsg
, handle
, 0);
1012 HANDLE
WSAAsyncGetServByPort(HWND hWnd
, u_int wMsg
, INT port
, const char
1013 *proto
, char *buf
, INT buflen
)
1016 struct servent
*service
;
1018 handle
= AllocWSAHandle();
1023 if ((service
= getservbyport(port
, proto
)) == NULL
) {
1025 errno_to_wsaerrno();
1027 herrno_to_wsaerrno();
1029 send_message(hWnd
, wMsg
, handle
, wsaerrno() << 16);
1032 memcpy(buf
, service
, buflen
);
1033 send_message(hWnd
, wMsg
, handle
, 0);
1038 INT
WSAAsyncSelect(SOCKET s
, HWND hWnd
, u_int wMsg
, long lEvent
)
1041 fd_set read_fds
, write_fds
, except_fds
;
1043 dprintf_winsock(stddeb
, "WSA_AsyncSelect: socket %d, HWND "NPFMT
", wMsg %d, event %ld\n", s
, hWnd
, wMsg
, lEvent
);
1045 /* remove outstanding asyncselect() processes */
1048 if (wMsg
== 0 && lEvent
== 0)
1056 FD_ZERO(&write_fds
);
1057 FD_ZERO(&except_fds
);
1059 if (lEvent
& FD_READ
)
1060 FD_SET(s
, &read_fds
);
1061 if (lEvent
& FD_WRITE
)
1062 FD_SET(s
, &write_fds
);
1064 fcntl(s
, F_SETFL
, O_NONBLOCK
);
1065 select(s
+ 1, &read_fds
, &write_fds
, &except_fds
, NULL
);
1068 if (FD_ISSET(s
, &read_fds
))
1070 if (FD_ISSET(s
, &write_fds
))
1072 /* FIXME: the first time through we get a winsock error of 2, why? */
1073 send_message(hWnd
, wMsg
, (HANDLE
)s
, (wsaerrno() << 16) | event
);
1078 INT
WSAFDIsSet(INT fd
, fd_set
*set
)
1080 return( FD_ISSET(fd
, set
) );
1083 INT
WSACancelAsyncRequest(HANDLE hAsyncTaskHandle
)
1085 dprintf_winsock(stddeb
, "WSA_AsyncRequest: handle "NPFMT
"\n", hAsyncTaskHandle
);
1090 INT
WSACancelBlockingCall(void)
1092 dprintf_winsock(stddeb
, "WSA_CancelBlockCall\n");
1096 INT
WSAGetLastError(void)
1098 dprintf_winsock(stddeb
, "WSA_GetLastError = %x\n", wsa_errno
);
1103 void WSASetLastError(INT iError
)
1105 dprintf_winsock(stddeb
, "WSA_SetLastErorr %d\n", iError
);
1110 BOOL
WSAIsBlocking(void)
1112 dprintf_winsock(stddeb
, "WSA_IsBlocking\n");
1117 FARPROC
WSASetBlockingHook(FARPROC lpBlockFunc
)
1119 dprintf_winsock(stddeb
, "WSA_SetBlockHook %8lx, STUB!\n", (unsigned long) lpBlockFunc
);
1120 BlockFunction
= lpBlockFunc
;
1122 return (FARPROC
) lpBlockFunc
;
1125 INT
WSAUnhookBlockingHook(void)
1127 dprintf_winsock(stddeb
, "WSA_UnhookBlockingHook\n");
1128 BlockFunction
= NULL
;
1133 WSADATA WINSOCK_data
= {
1151 INT
WSAStartup(WORD wVersionRequested
, LPWSADATA lpWSAData
)
1154 dprintf_winsock(stddeb
, "WSAStartup: verReq=%x\n", wVersionRequested
);
1156 if (LOBYTE(wVersionRequested
) < 1 ||
1157 (LOBYTE(wVersionRequested
) == 1 &&
1158 HIBYTE(wVersionRequested
) < 1))
1159 return WSAVERNOTSUPPORTED
;
1164 /* alloc winsock heap */
1166 if ((HeapHandle
= GlobalAlloc(GMEM_FIXED
,sizeof(struct WinSockHeap
))) == 0)
1167 return WSASYSNOTREADY
;
1169 Heap
= (struct WinSockHeap
*) GlobalLock(HeapHandle
);
1170 bcopy(&WINSOCK_data
, lpWSAData
, sizeof(WINSOCK_data
));
1174 if ((wine_key
= msgget(IPC_PRIVATE
, 0600)) == -1)
1175 perror("wine: msgget");
1177 signal(SIGUSR1
, recv_message
);
1181 FD_ZERO(&fd_in_use
);
1187 INT
WSACleanup(void)
1192 if (msgctl(wine_key
, IPC_RMID
, NULL
) == -1)
1193 perror("wine: shmctl");
1195 for (fd
= 0; fd
!= FD_SETSIZE
; fd
++)
1196 if (FD_ISSET(fd
, &fd_in_use
))