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/socket.h>
16 #include <netinet/in.h>
17 #include <arpa/inet.h>
27 static WORD wsa_errno;
28 static int wsa_initted;
29 static key_t wine_key = 0;
30 static FARPROC BlockFunction;
31 static fd_set fd_in_use;
45 #define IPC_PACKET_SIZE (sizeof(struct ipc_packet) - sizeof(long))
46 #define MTYPE 0xb0b0eb05
48 /* These structures are Win16 only */
51 SEGPTR h_name WINE_PACKED; /* official name of host */
52 SEGPTR h_aliases WINE_PACKED; /* alias list */
53 INT h_addrtype WINE_PACKED; /* host address type */
54 INT h_length WINE_PACKED; /* length of address */
55 char **h_addr_list WINE_PACKED; /* list of addresses from name server */
61 SEGPTR p_name WINE_PACKED; /* official protocol name */
62 SEGPTR p_aliases WINE_PACKED; /* alias list */
63 INT p_proto WINE_PACKED; /* protocol # */
67 SEGPTR s_name WINE_PACKED; /* official service name */
68 SEGPTR s_aliases WINE_PACKED; /* alias list */
69 INT s_port WINE_PACKED; /* port # */
70 SEGPTR s_proto WINE_PACKED; /* protocol to use */
76 struct WIN_hostent hostent_addr;
77 struct WIN_hostent hostent_name;
78 struct WIN_protoent protoent_name;
79 struct WIN_protoent protoent_number;
80 struct WIN_servent servent_name;
81 struct WIN_servent servent_port;
83 struct WIN_hostent WSAhostent_addr;
84 struct WIN_hostent WSAhostent_name;
85 struct WIN_protoent WSAprotoent_name;
86 struct WIN_protoent WSAprotoent_number;
87 struct WIN_servent WSAservent_name;
88 struct WIN_servent WSAservent_port;
89 /* 8K scratch buffer for aliases and friends are hopefully enough */
92 static struct WinSockHeap *Heap;
93 static int HeapHandle;
94 static int ScratchPtr;
97 #define GET_SEG_PTR(x) MAKELONG((int)((char*)(x)-(char*)Heap), \
98 GlobalHandleToSel(HeapHandle))
100 #define GET_SEG_PTR(x) (x)
107 #define dump_sockaddr(a) \
108 fprintf(stderr, "sockaddr_in: family %d, address %s, port %d\n", \
109 ((struct sockaddr_in *)a)->sin_family, \
110 inet_ntoa(((struct sockaddr_in *)a)->sin_addr), \
111 ntohs(((struct sockaddr_in *)a)->sin_port))
113 static void ResetScratch()
118 static void *scratch_alloc(int size)
121 if(ScratchPtr+size > sizeof(Heap->scratch))
123 ret = Heap->scratch + ScratchPtr;
128 static SEGPTR scratch_strdup(char * s)
130 char *ret=scratch_alloc(strlen(s)+1);
132 return GET_SEG_PTR(ret);
135 static WORD wsaerrno(void)
139 #if defined(__FreeBSD__)
140 fprintf(stderr, "winsock: errno %d, (%s).\n",
141 errno, sys_errlist[errno]);
143 fprintf(stderr, "winsock: errno %d, (%s).\n",
144 errno, strerror(errno));
147 fprintf(stderr, "winsock: errno %d\n", errno);
153 case EINTR: return WSAEINTR;
154 case EACCES: return WSAEACCES;
155 case EFAULT: return WSAEFAULT;
156 case EINVAL: return WSAEINVAL;
157 case EMFILE: return WSAEMFILE;
158 case EWOULDBLOCK: return WSAEWOULDBLOCK;
159 case EINPROGRESS: return WSAEINPROGRESS;
160 case EALREADY: return WSAEALREADY;
162 case ENOTSOCK: return WSAENOTSOCK;
163 case EDESTADDRREQ: return WSAEDESTADDRREQ;
164 case EMSGSIZE: return WSAEMSGSIZE;
165 case EPROTOTYPE: return WSAEPROTOTYPE;
166 case ENOPROTOOPT: return WSAENOPROTOOPT;
167 case EPROTONOSUPPORT: return WSAEPROTONOSUPPORT;
168 case ESOCKTNOSUPPORT: return WSAESOCKTNOSUPPORT;
169 case EOPNOTSUPP: return WSAEOPNOTSUPP;
170 case EPFNOSUPPORT: return WSAEPFNOSUPPORT;
171 case EAFNOSUPPORT: return WSAEAFNOSUPPORT;
172 case EADDRINUSE: return WSAEADDRINUSE;
173 case EADDRNOTAVAIL: return WSAEADDRNOTAVAIL;
174 case ENETDOWN: return WSAENETDOWN;
175 case ENETUNREACH: return WSAENETUNREACH;
176 case ENETRESET: return WSAENETRESET;
177 case ECONNABORTED: return WSAECONNABORTED;
178 case ECONNRESET: return WSAECONNRESET;
179 case ENOBUFS: return WSAENOBUFS;
180 case EISCONN: return WSAEISCONN;
181 case ENOTCONN: return WSAENOTCONN;
182 case ESHUTDOWN: return WSAESHUTDOWN;
183 case ETOOMANYREFS: return WSAETOOMANYREFS;
184 case ETIMEDOUT: return WSAETIMEDOUT;
185 case ECONNREFUSED: return WSAECONNREFUSED;
186 case ELOOP: return WSAELOOP;
187 case ENAMETOOLONG: return WSAENAMETOOLONG;
188 case EHOSTDOWN: return WSAEHOSTDOWN;
189 case EHOSTUNREACH: return WSAEHOSTUNREACH;
190 case ENOTEMPTY: return WSAENOTEMPTY;
192 case EPROCLIM: return WSAEPROCLIM;
194 case EUSERS: return WSAEUSERS;
195 case EDQUOT: return WSAEDQUOT;
196 case ESTALE: return WSAESTALE;
197 case EREMOTE: return WSAEREMOTE;
200 fprintf(stderr, "winsock: unknown errorno %d!\n", errno);
201 return WSAEOPNOTSUPP;
205 static void errno_to_wsaerrno(void)
207 wsa_errno = wsaerrno();
210 static void convert_sockopt(INT *level, INT *optname)
212 /* $%#%!@! why couldn't they use the same values for both winsock and unix ? */
218 case 0x01: *optname = SO_DEBUG;
220 case 0x04: *optname = SO_REUSEADDR;
222 case 0x08: *optname = SO_KEEPALIVE;
224 case 0x10: *optname = SO_DONTROUTE;
226 case 0x20: *optname = SO_BROADCAST;
228 case 0x80: *optname = SO_LINGER;
230 case 0x100: *optname = SO_OOBINLINE;
232 case 0x1001: *optname = SO_SNDBUF;
234 case 0x1002: *optname = SO_RCVBUF;
236 case 0x1007: *optname = SO_ERROR;
238 case 0x1008: *optname = SO_TYPE;
241 fprintf(stderr, "convert_sockopt() unknown optname %d\n", *optname);
245 case 6: *optname = IPPROTO_TCP;
250 static SEGPTR copy_stringlist(char **list)
256 s_list = scratch_alloc(sizeof(SEGPTR)*(i+1));
259 void *copy = scratch_alloc(strlen(list[i])+1);
260 strcpy(copy,list[i]);
261 s_list[i]=GET_SEG_PTR(copy);
264 return GET_SEG_PTR(s_list);
268 static void CONVERT_HOSTENT(struct WIN_hostent *heapent, struct hostent *host)
273 strcpy(heapent->hostname,host->h_name);
274 heapent->h_name = GET_SEG_PTR(heapent->hostname);
275 /* Convert aliases. Have to create array with FAR pointers */
277 heapent->h_aliases = 0;
279 heapent->h_aliases = copy_stringlist(host->h_aliases);
281 heapent->h_addrtype = host->h_addrtype;
282 heapent->h_length = host->h_length;
283 for(i=0;host->h_addr_list[i];i++)
285 addr_list=scratch_alloc(sizeof(SEGPTR)*(i+1));
286 heapent->h_addr_list = GET_SEG_PTR(addr_list);
287 for(i=0;host->h_addr_list[i];i++)
289 void *addr=scratch_alloc(host->h_length);
290 memcpy(addr,host->h_addr_list[i],host->h_length);
291 addr_list[i]=GET_SEG_PTR(addr);
296 static void CONVERT_PROTOENT(struct WIN_protoent *heapent,
297 struct protoent *proto)
300 heapent->p_name= scratch_strdup(proto->p_name);
301 heapent->p_aliases=proto->p_aliases ?
302 copy_stringlist(proto->p_aliases) : 0;
303 heapent->p_proto = proto->p_proto;
306 static void CONVERT_SERVENT(struct WIN_servent *heapent, struct servent *serv)
309 heapent->s_name = scratch_strdup(serv->s_name);
310 heapent->s_aliases = serv->s_aliases ?
311 copy_stringlist(serv->s_aliases) : 0;
312 heapent->s_port = serv->s_port;
313 heapent->s_proto = scratch_strdup(serv->s_proto);
316 #define CONVERT_HOSTENT(a,b) memcpy(a, &b, sizeof(a))
317 #define CONVERT_PROTOENT(a,b) memcpy(a, &b, sizeof(a))
318 #define CONVERT_SERVENT(a,b) memcpy(a, &b, sizeof(a))
321 SOCKET WINSOCK_accept(SOCKET s, struct sockaddr *addr, INT *addrlen)
325 dprintf_winsock(stddeb, "WSA_accept: socket %d, ptr %8x, length %d\n", s, (int) addr, *addrlen);
327 if ((sock = accept(s, addr, (int *) addrlen)) < 0) {
329 return INVALID_SOCKET;
334 INT WINSOCK_bind(SOCKET s, struct sockaddr *name, INT namelen)
336 dprintf_winsock(stddeb, "WSA_bind: socket %d, ptr %8x, length %d\n", s, (int) name, namelen);
339 if (bind(s, name, namelen) < 0) {
346 INT WINSOCK_closesocket(SOCKET s)
348 dprintf_winsock(stddeb, "WSA_closesocket: socket %d\n", s);
350 FD_CLR(s, &fd_in_use);
359 INT WINSOCK_connect(SOCKET s, struct sockaddr *name, INT namelen)
361 dprintf_winsock(stddeb, "WSA_connect: socket %d, ptr %8x, length %d\n", s, (int) name, namelen);
364 if (connect(s, name, namelen) < 0) {
371 INT WINSOCK_getpeername(SOCKET s, struct sockaddr *name, INT *namelen)
373 dprintf_winsock(stddeb, "WSA_getpeername: socket: %d, ptr %8x, ptr %8x\n", s, (int) name, *namelen);
376 if (getpeername(s, name, (int *) namelen) < 0) {
383 INT WINSOCK_getsockname(SOCKET s, struct sockaddr *name, INT *namelen)
385 dprintf_winsock(stddeb, "WSA_getsockname: socket: %d, ptr %8x, ptr %8x\n", s, (int) name, (int) *namelen);
386 if (getsockname(s, name, (int *) namelen) < 0) {
394 WINSOCK_getsockopt(SOCKET s, INT level, INT optname, char *optval, INT *optlen)
396 dprintf_winsock(stddeb, "WSA_getsockopt: socket: %d, opt %d, ptr %8x, ptr %8x\n", s, level, (int) optval, (int) *optlen);
397 convert_sockopt(&level, &optname);
399 if (getsockopt(s, (int) level, optname, optval, (int *) optlen) < 0) {
406 u_long WINSOCK_htonl(u_long hostlong)
408 return( htonl(hostlong) );
411 u_short WINSOCK_htons(u_short hostshort)
413 return( htons(hostshort) );
416 u_long WINSOCK_inet_addr(char *cp)
418 return( inet_addr(cp) );
421 char *WINSOCK_inet_ntoa(struct in_addr in)
425 /* dprintf_winsock(stddeb, "WSA_inet_ntoa: %8lx\n", (int) in);*/
427 if ((s = inet_ntoa(in)) == NULL) {
432 strncpy(Heap->ntoa_buffer, s, sizeof(Heap->ntoa_buffer) );
434 return (char *) GET_SEG_PTR(&Heap->ntoa_buffer);
437 INT WINSOCK_ioctlsocket(SOCKET s, u_long cmd, u_long *argp)
442 dprintf_winsock(stddeb, "WSA_ioctl: socket %d, cmd %lX, ptr %8x\n", s, cmd, (int) argp);
444 /* Why can't they all use the same ioctl numbers */
448 if(cmd == _IOR('f',127,u_long))
453 if(cmd == _IOW('f',126,u_long) || cmd == _IOR('f',126,u_long))
458 if(cmd == _IOW('f',125,u_long))
465 fprintf(stderr,"Unknown winsock ioctl. Trying anyway\n");
467 dprintf_winsock(stddeb,"Recognized as %s\n", ctlname);
470 if (ioctl(s, newcmd, newargp) < 0) {
477 INT WINSOCK_listen(SOCKET s, INT backlog)
479 dprintf_winsock(stddeb, "WSA_listen: socket %d, backlog %d\n", s, backlog);
481 if (listen(s, backlog) < 0) {
488 u_long WINSOCK_ntohl(u_long netlong)
490 return( ntohl(netlong) );
493 u_short WINSOCK_ntohs(u_short netshort)
495 return( ntohs(netshort) );
498 INT WINSOCK_recv(SOCKET s, char *buf, INT len, INT flags)
502 dprintf_winsock(stddeb, "WSA_recv: socket %d, ptr %8x, length %d, flags %d\n", s, (int) buf, len, flags);
504 if ((length = recv(s, buf, len, flags)) < 0) {
511 INT WINSOCK_recvfrom(SOCKET s, char *buf, INT len, INT flags,
512 struct sockaddr *from, int *fromlen)
516 dprintf_winsock(stddeb, "WSA_recvfrom: socket %d, ptr %8lx, length %d, flags %d\n", s, (unsigned long)buf, len, flags);
518 if ((length = recvfrom(s, buf, len, flags, from, fromlen)) < 0) {
525 INT WINSOCK_select(INT nfds, fd_set *readfds, fd_set *writefds,
526 fd_set *exceptfds, struct timeval *timeout)
528 dprintf_winsock(stddeb, "WSA_select: fd # %d, ptr %8lx, ptr %8lx, ptr %8lX\n", nfds, (unsigned long) readfds, (unsigned long) writefds, (unsigned long) exceptfds);
530 return(select(nfds, readfds, writefds, exceptfds, timeout));
533 INT WINSOCK_send(SOCKET s, char *buf, INT len, INT flags)
537 dprintf_winsock(stddeb, "WSA_send: socket %d, ptr %8lx, length %d, flags %d\n", s, (unsigned long) buf, len, flags);
539 if ((length = send(s, buf, len, flags)) < 0) {
546 INT WINSOCK_sendto(SOCKET s, char *buf, INT len, INT flags,
547 struct sockaddr *to, INT tolen)
551 dprintf_winsock(stddeb, "WSA_sendto: socket %d, ptr %8lx, length %d, flags %d\n", s, (unsigned long) buf, len, flags);
553 if ((length = sendto(s, buf, len, flags, to, tolen)) < 0) {
560 INT WINSOCK_setsockopt(SOCKET s, INT level, INT optname, const char *optval,
563 dprintf_winsock(stddeb, "WSA_setsockopt: socket %d, level %d, opt %d, ptr %8x, len %d\n", s, level, optname, (int) optval, optlen);
564 convert_sockopt(&level, &optname);
566 if (setsockopt(s, level, optname, optval, optlen) < 0) {
573 INT WINSOCK_shutdown(SOCKET s, INT how)
575 dprintf_winsock(stddeb, "WSA_shutdown: socket s %d, how %d\n", s, how);
577 if (shutdown(s, how) < 0) {
584 SOCKET WINSOCK_socket(INT af, INT type, INT protocol)
588 dprintf_winsock(stddeb, "WSA_socket: af=%d type=%d protocol=%d\n", af, type, protocol);
590 if ((sock = socket(af, type, protocol)) < 0) {
592 dprintf_winsock(stddeb, "WSA_socket: failed !\n");
593 return INVALID_SOCKET;
597 wsa_errno = WSAEMFILE;
598 return INVALID_SOCKET;
601 FD_SET(sock, &fd_in_use);
603 dprintf_winsock(stddeb, "WSA_socket: fd %d\n", sock);
610 SEGPTR WINSOCK_gethostbyaddr(const char *addr, INT len, INT type)
612 struct hostent *host;
614 dprintf_winsock(stddeb, "WSA_gethostbyaddr: ptr %8x, len %d, type %d\n", (int) addr, len, type);
616 if ((host = gethostbyaddr(addr, len, type)) == NULL) {
620 CONVERT_HOSTENT(&Heap->hostent_addr, host);
622 return GET_SEG_PTR(&Heap->hostent_addr);
628 SEGPTR WINSOCK_gethostbyname(const char *name)
630 struct hostent *host;
632 dprintf_winsock(stddeb, "WSA_gethostbyname: %s\n", name);
634 if ((host = gethostbyname(name)) == NULL) {
638 CONVERT_HOSTENT(&Heap->hostent_name, host);
640 return GET_SEG_PTR(&Heap->hostent_name);
643 INT WINSOCK_gethostname(char *name, INT namelen)
645 dprintf_winsock(stddeb, "WSA_gethostname: name %s, len %d\n", name, namelen);
647 if (gethostname(name, namelen) < 0) {
655 struct WIN_protoent *
657 SEGPTR WINSOCK_getprotobyname(char *name)
659 struct protoent *proto;
661 dprintf_winsock(stddeb, "WSA_getprotobyname: name %s\n", name);
663 if ((proto = getprotobyname(name)) == NULL) {
667 CONVERT_PROTOENT(&Heap->protoent_name, proto);
669 return GET_SEG_PTR(&Heap->protoent_name);
673 struct WIN_protoent *
675 SEGPTR WINSOCK_getprotobynumber(INT number)
677 struct protoent *proto;
679 dprintf_winsock(stddeb, "WSA_getprotobynumber: num %d\n", number);
681 if ((proto = getprotobynumber(number)) == NULL) {
685 CONVERT_PROTOENT(&Heap->protoent_number, proto);
687 return GET_SEG_PTR(&Heap->protoent_number);
693 SEGPTR WINSOCK_getservbyname(const char *name, const char *proto)
695 struct servent *service;
700 dprintf_winsock(stddeb, "WSA_getservbyname: name %s, proto %s\n", name, proto);
702 if ((service = getservbyname(name, proto)) == NULL) {
706 CONVERT_SERVENT(&Heap->servent_name, service);
708 return GET_SEG_PTR(&Heap->servent_name);
714 SEGPTR WINSOCK_getservbyport(INT port, const char *proto)
716 struct servent *service;
718 dprintf_winsock(stddeb, "WSA_getservbyport: port %d, name %s\n", port, proto);
720 if ((service = getservbyport(port, proto)) == NULL) {
724 CONVERT_SERVENT(&Heap->servent_port, service);
726 return GET_SEG_PTR(&Heap->servent_port);
729 /******************** winsock specific functions ************************
732 static HANDLE new_handle = 0;
734 static HANDLE AllocWSAHandle(void)
739 static void recv_message(int sig)
741 struct ipc_packet message;
743 if (msgrcv(wine_key, &message, IPC_PACKET_SIZE, MTYPE, IPC_NOWAIT) == -1)
744 perror("wine: msgrcv");
747 "WSA: PostMessage (hwnd %d, wMsg %d, wParam %d, lParam %ld)\n",
753 PostMessage(message.hWnd, message.wMsg, message.handle, message.lParam);
755 signal(SIGUSR1, recv_message);
759 static void send_message(HANDLE handle, HWND hWnd, u_int wMsg, long lParam)
761 struct ipc_packet message;
763 message.mtype = MTYPE;
764 message.handle = handle;
767 message.lParam = lParam;
770 "WSA: send (hwnd %d, wMsg %d, handle %d, lParam %ld)\n",
771 hWnd, wMsg, handle, lParam);
773 if (msgsnd(wine_key, &message, IPC_PACKET_SIZE, IPC_NOWAIT) == -1)
774 perror("wine: msgsnd");
776 kill(getppid(), SIGUSR1);
780 HANDLE WSAAsyncGetHostByAddr(HWND hWnd, u_int wMsg, const char *addr,
781 INT len, INT type, char *buf, INT buflen)
784 struct hostent *host;
786 handle = AllocWSAHandle();
791 if ((host = gethostbyaddr(addr, len, type)) == NULL) {
792 send_message(hWnd, wMsg, handle, wsaerrno() << 16);
795 memcpy(buf, host, buflen);
796 send_message(hWnd, wMsg, handle, 0);
802 HANDLE WSAAsyncGetHostByName(HWND hWnd, u_int wMsg, const char *name,
803 char *buf, INT buflen)
806 struct hostent *host;
808 handle = AllocWSAHandle();
813 if ((host = gethostbyname(name)) == NULL) {
814 send_message(hWnd, wMsg, handle, wsaerrno() << 16);
817 memcpy(buf, host, buflen);
818 send_message(hWnd, wMsg, handle, 0);
824 HANDLE WSAAsyncGetProtoByName(HWND hWnd, u_int wMsg, const char *name,
825 char *buf, INT buflen)
828 struct protoent *proto;
830 handle = AllocWSAHandle();
835 if ((proto = getprotobyname(name)) == NULL) {
836 send_message(hWnd, wMsg, handle, wsaerrno() << 16);
839 memcpy(buf, proto, buflen);
840 send_message(hWnd, wMsg, handle, 0);
846 HANDLE WSAAsyncGetProtoByNumber(HWND hWnd, u_int wMsg, INT number,
847 char *buf, INT buflen)
850 struct protoent *proto;
852 handle = AllocWSAHandle();
857 if ((proto = getprotobynumber(number)) == NULL) {
858 send_message(hWnd, wMsg, handle, wsaerrno() << 16);
861 memcpy(buf, proto, buflen);
862 send_message(hWnd, wMsg, handle, 0);
868 HANDLE WSAAsyncGetServByName(HWND hWnd, u_int wMsg, const char *name,
869 const char *proto, char *buf, INT buflen)
872 struct servent *service;
874 handle = AllocWSAHandle();
879 if ((service = getservbyname(name, proto)) == NULL) {
880 send_message(hWnd, wMsg, handle, wsaerrno() << 16);
883 memcpy(buf, service, buflen);
884 send_message(hWnd, wMsg, handle, 0);
890 HANDLE WSAAsyncGetServByPort(HWND hWnd, u_int wMsg, INT port, const char
891 *proto, char *buf, INT buflen)
894 struct servent *service;
896 handle = AllocWSAHandle();
901 if ((service = getservbyport(port, proto)) == NULL) {
902 send_message(hWnd, wMsg, handle, wsaerrno() << 16);
905 memcpy(buf, service, buflen);
906 send_message(hWnd, wMsg, handle, 0);
911 INT WSAAsyncSelect(SOCKET s, HWND hWnd, u_int wMsg, long lEvent)
914 fd_set read_fds, write_fds, except_fds;
916 dprintf_winsock(stddeb, "WSA_AsyncSelect: socket %d, HWND %d, wMsg %d, event %ld\n", s, hWnd, wMsg, lEvent);
918 /* remove outstanding asyncselect() processes */
921 if (wMsg == 0 && lEvent == 0)
930 FD_ZERO(&except_fds);
932 if (lEvent & FD_READ)
933 FD_SET(s, &read_fds);
934 if (lEvent & FD_WRITE)
935 FD_SET(s, &write_fds);
937 fcntl(s, F_SETFL, O_NONBLOCK);
938 select(s + 1, &read_fds, &write_fds, &except_fds, NULL);
941 if (FD_ISSET(s, &read_fds))
943 if (FD_ISSET(s, &write_fds))
946 send_message(hWnd, wMsg, s, (wsaerrno() << 16) | event);
951 INT WSAFDIsSet(INT fd, fd_set *set)
953 return( FD_ISSET(fd, set) );
956 INT WSACancelAsyncRequest(HANDLE hAsyncTaskHandle)
958 dprintf_winsock(stddeb, "WSA_AsyncRequest: handle %d\n", hAsyncTaskHandle);
963 INT WSACancelBlockingCall(void)
965 dprintf_winsock(stddeb, "WSA_CancelBlockCall\n");
969 INT WSAGetLastError(void)
971 dprintf_winsock(stddeb, "WSA_GetLastError = %x\n", wsa_errno);
976 void WSASetLastError(INT iError)
978 dprintf_winsock(stddeb, "WSA_SetLastErorr %d\n", iError);
983 BOOL WSAIsBlocking(void)
985 dprintf_winsock(stddeb, "WSA_IsBlocking\n");
990 FARPROC WSASetBlockingHook(FARPROC lpBlockFunc)
992 dprintf_winsock(stddeb, "WSA_SetBlockHook %8lx, STUB!\n", (unsigned long) lpBlockFunc);
993 BlockFunction = lpBlockFunc;
995 return (FARPROC) lpBlockFunc;
998 INT WSAUnhookBlockingHook(void)
1000 dprintf_winsock(stddeb, "WSA_UnhookBlockingHook\n");
1001 BlockFunction = NULL;
1006 WSADATA WINSOCK_data = {
1024 INT WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData)
1027 dprintf_winsock(stddeb, "WSAStartup: verReq=%x\n", wVersionRequested);
1029 if (LOBYTE(wVersionRequested) < 1 ||
1030 (LOBYTE(wVersionRequested) == 1 &&
1031 HIBYTE(wVersionRequested) < 1))
1032 return WSAVERNOTSUPPORTED;
1037 /* alloc winsock heap */
1039 if ((HeapHandle = GlobalAlloc(GMEM_FIXED,sizeof(struct WinSockHeap))) == 0)
1040 return WSASYSNOTREADY;
1042 Heap = (struct WinSockHeap *) GlobalLock(HeapHandle);
1043 bcopy(&WINSOCK_data, lpWSAData, sizeof(WINSOCK_data));
1047 if ((wine_key = msgget(IPC_PRIVATE, 0600)) == -1)
1048 perror("wine: msgget");
1050 signal(SIGUSR1, recv_message);
1054 FD_ZERO(&fd_in_use);
1060 INT WSACleanup(void)
1065 if (msgctl(wine_key, IPC_RMID, NULL) == -1)
1066 perror("wine: shmctl");
1068 for (fd = 0; fd != FD_SETSIZE; fd++)
1069 if (FD_ISSET(fd, &fd_in_use))