ws2_32: Close the dest socket (Coverity).
[wine.git] / dlls / winsock.dll16 / socket.c
blobac325cd67a665d75a2ecf424654ba16e3a01f938
1 /*
2 * 16-bit socket functions
4 * Copyright (C) 1993,1994,1996,1997 John Brezak, Erik Bos, Alex Korobka
5 * Copyright (C) 2003 Alexandre Julliard
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include "config.h"
24 #include "winsock2.h"
25 #include "wine/winbase16.h"
26 #include "winsock16.h"
27 #include "wownt32.h"
28 #include "winuser.h"
29 #include "wine/debug.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(winsock);
33 struct async_query_header
35 HWND hWnd;
36 UINT uMsg;
37 SEGPTR sbuf;
38 INT sbuflen;
39 HANDLE16 handle;
42 struct async_query_gethostbyname
44 struct async_query_header query;
45 char *host_name;
48 struct async_query_gethostbyaddr
50 struct async_query_header query;
51 char *host_addr;
52 int host_len;
53 int host_type;
56 struct async_query_getprotobyname
58 struct async_query_header query;
59 char *proto_name;
62 struct async_query_getprotobynumber
64 struct async_query_header query;
65 int proto_number;
68 struct async_query_getservbyname
70 struct async_query_header query;
71 char *serv_name;
72 char *serv_proto;
75 struct async_query_getservbyport
77 struct async_query_header query;
78 char *serv_proto;
79 int serv_port;
82 static INT num_startup; /* reference counter */
83 static void *he_buffer;
84 static SEGPTR he_buffer_seg;
85 static void *se_buffer;
86 static SEGPTR se_buffer_seg;
87 static void *pe_buffer;
88 static SEGPTR pe_buffer_seg;
89 static SEGPTR dbuffer_seg;
91 extern int WINAPI WS_gethostname(char *name, int namelen);
93 static fd_set *ws_fdset_16_to_32( const ws_fd_set16 *set16, fd_set *set32 )
95 UINT i;
96 set32->fd_count = set16->fd_count;
97 for (i = 0; i < set32->fd_count; i++) set32->fd_array[i] = set16->fd_array[i];
98 return set32;
101 static ws_fd_set16 *ws_fdset_32_to_16( const fd_set *set32, ws_fd_set16 *set16 )
103 UINT i;
104 set16->fd_count = set32->fd_count;
105 for (i = 0; i < set16->fd_count; i++) set16->fd_array[i] = set32->fd_array[i];
106 return set16;
109 static DWORD finish_query( struct async_query_header *query, LPARAM lparam )
111 PostMessageW( query->hWnd, query->uMsg, (WPARAM)query->handle, lparam );
112 HeapFree( GetProcessHeap(), 0, query );
113 return 0;
116 static int list_size(char** l, int item_size)
118 int i,j = 0;
119 if(l)
121 for(i=0;l[i];i++)
122 j += (item_size) ? item_size : strlen(l[i]) + 1;
123 j += (i + 1) * sizeof(char*);
125 return j;
128 static int list_dup(char** l_src, SEGPTR base, int item_size)
130 int i, offset;
131 char *ref = MapSL(base);
132 SEGPTR *l_to = (SEGPTR *)ref;
134 for (i = 0; l_src[i]; i++) ;
135 offset = (i + 1) * sizeof(char*);
136 for (i = 0; l_src[i]; i++)
138 int count = item_size ? item_size : strlen(l_src[i]) + 1;
139 memcpy( ref + offset, l_src[i], count );
140 l_to[i] = base + offset;
141 offset += count;
143 l_to[i] = 0;
144 return offset;
147 static SEGPTR get_buffer_he(int size)
149 static int he_len;
150 if (he_buffer)
152 if (he_len >= size ) return he_buffer_seg;
153 UnMapLS( he_buffer_seg );
154 HeapFree( GetProcessHeap(), 0, he_buffer );
156 he_buffer = HeapAlloc( GetProcessHeap(), 0, (he_len = size) );
157 he_buffer_seg = MapLS( he_buffer );
158 return he_buffer_seg;
161 static SEGPTR get_buffer_se(int size)
163 static int se_len;
164 if (se_buffer)
166 if (se_len >= size ) return se_buffer_seg;
167 UnMapLS( se_buffer_seg );
168 HeapFree( GetProcessHeap(), 0, se_buffer );
170 se_buffer = HeapAlloc( GetProcessHeap(), 0, (se_len = size) );
171 se_buffer_seg = MapLS( se_buffer );
172 return se_buffer_seg;
175 static SEGPTR get_buffer_pe(int size)
177 static int pe_len;
178 if (pe_buffer)
180 if (pe_len >= size ) return pe_buffer_seg;
181 UnMapLS( pe_buffer_seg );
182 HeapFree( GetProcessHeap(), 0, pe_buffer );
184 pe_buffer = HeapAlloc( GetProcessHeap(), 0, (pe_len = size) );
185 pe_buffer_seg = MapLS( pe_buffer );
186 return pe_buffer_seg;
189 /* duplicate hostent entry
190 * and handle all Win16/Win32 dependent things (struct size, ...) *correctly*.
191 * Ditto for protoent and servent.
193 static SEGPTR ws_hostent_32_to_16( const struct hostent* he, SEGPTR base, int *buff_size )
195 char *p;
196 struct ws_hostent16 *p_to;
198 int size = (sizeof(*p_to) +
199 strlen(he->h_name) + 1 +
200 list_size(he->h_aliases, 0) +
201 list_size(he->h_addr_list, he->h_length));
203 if (buff_size)
205 if (*buff_size < size)
207 *buff_size = size;
208 return 0;
210 *buff_size = size;
212 else base = get_buffer_he(size);
213 p_to = MapSL(base);
215 p_to->h_addrtype = he->h_addrtype;
216 p_to->h_length = he->h_length;
218 p = (char *)(p_to + 1);
219 p_to->h_name = base + (p - (char *)p_to);
220 strcpy(p, he->h_name);
221 p += strlen(p) + 1;
223 p_to->h_aliases = base + (p - (char *)p_to);
224 p += list_dup(he->h_aliases, p_to->h_aliases, 0);
226 p_to->h_addr_list = base + (p - (char *)p_to);
227 list_dup(he->h_addr_list, p_to->h_addr_list, he->h_length);
229 return base;
232 static SEGPTR ws_protoent_32_to_16( const struct protoent *pe, SEGPTR base, int *buff_size )
234 char *p;
235 struct ws_protoent16 *p_to;
237 int size = (sizeof(*p_to) +
238 strlen(pe->p_name) + 1 +
239 list_size(pe->p_aliases, 0));
241 if (buff_size)
243 if (*buff_size < size)
245 *buff_size = size;
246 return 0;
248 *buff_size = size;
250 else base = get_buffer_pe(size);
251 p_to = MapSL(base);
253 p_to->p_proto = pe->p_proto;
254 p = (char *)(p_to + 1);
256 p_to->p_name = base + (p - (char *)p_to);
257 strcpy(p, pe->p_name);
258 p += strlen(p) + 1;
260 p_to->p_aliases = base + (p - (char *)p_to);
261 list_dup(pe->p_aliases, p_to->p_aliases, 0);
263 return base;
266 static SEGPTR ws_servent_32_to_16( const struct servent *se, SEGPTR base, int *buff_size )
268 char *p;
269 struct ws_servent16 *p_to;
271 int size = (sizeof(*p_to) +
272 strlen(se->s_proto) + 1 +
273 strlen(se->s_name) + 1 +
274 list_size(se->s_aliases, 0));
276 if (buff_size)
278 if (*buff_size < size)
280 *buff_size = size;
281 return 0;
283 *buff_size = size;
285 else base = get_buffer_se(size);
286 p_to = MapSL(base);
288 p_to->s_port = se->s_port;
289 p = (char *)(p_to + 1);
291 p_to->s_name = base + (p - (char *)p_to);
292 strcpy(p, se->s_name);
293 p += strlen(p) + 1;
295 p_to->s_proto = base + (p - (char *)p_to);
296 strcpy(p, se->s_proto);
297 p += strlen(p) + 1;
299 p_to->s_aliases = base + (p - (char *)p_to);
300 list_dup(se->s_aliases, p_to->s_aliases, 0);
302 return base;
305 static DWORD WINAPI async_gethostbyname(LPVOID arg)
307 struct async_query_gethostbyname *aq = arg;
308 int size = 0;
309 WORD fail = 0;
310 struct hostent *he;
312 if ((he = gethostbyname( aq->host_name )))
314 size = aq->query.sbuflen;
315 if (!ws_hostent_32_to_16( he, aq->query.sbuf, &size )) fail = WSAENOBUFS;
317 else fail = GetLastError();
319 return finish_query( &aq->query, MAKELPARAM( size, fail ));
322 static DWORD WINAPI async_gethostbyaddr(LPVOID arg)
324 struct async_query_gethostbyaddr *aq = arg;
325 int size = 0;
326 WORD fail = 0;
327 struct hostent *he;
329 if ((he = gethostbyaddr(aq->host_addr,aq->host_len,aq->host_type)))
331 size = aq->query.sbuflen;
332 if (!ws_hostent_32_to_16( he, aq->query.sbuf, &size )) fail = WSAENOBUFS;
334 else fail = GetLastError();
336 return finish_query( &aq->query, MAKELPARAM( size, fail ));
339 static DWORD WINAPI async_getprotobyname(LPVOID arg)
341 struct async_query_getprotobyname *aq = arg;
342 int size = 0;
343 WORD fail = 0;
344 struct protoent *pe;
346 if ((pe = getprotobyname(aq->proto_name)))
348 size = aq->query.sbuflen;
349 if (!ws_protoent_32_to_16( pe, aq->query.sbuf, &size )) fail = WSAENOBUFS;
351 else fail = GetLastError();
353 return finish_query( &aq->query, MAKELPARAM( size, fail ));
356 static DWORD WINAPI async_getprotobynumber(LPVOID arg)
358 struct async_query_getprotobynumber *aq = arg;
359 int size = 0;
360 WORD fail = 0;
361 struct protoent *pe;
363 if ((pe = getprotobynumber(aq->proto_number)))
365 size = aq->query.sbuflen;
366 if (!ws_protoent_32_to_16( pe, aq->query.sbuf, &size )) fail = WSAENOBUFS;
368 else fail = GetLastError();
370 return finish_query( &aq->query, MAKELPARAM( size, fail ));
373 static DWORD WINAPI async_getservbyname(LPVOID arg)
375 struct async_query_getservbyname *aq = arg;
376 int size = 0;
377 WORD fail = 0;
378 struct servent *se;
380 if ((se = getservbyname(aq->serv_name,aq->serv_proto)))
382 size = aq->query.sbuflen;
383 if (!ws_servent_32_to_16( se, aq->query.sbuf, &size )) fail = WSAENOBUFS;
385 else fail = GetLastError();
387 return finish_query( &aq->query, MAKELPARAM( size, fail ));
390 static DWORD WINAPI async_getservbyport(LPVOID arg)
392 struct async_query_getservbyport *aq = arg;
393 int size = 0;
394 WORD fail = 0;
395 struct servent *se;
397 if ((se = getservbyport(aq->serv_port,aq->serv_proto)))
399 size = aq->query.sbuflen;
400 if (!ws_servent_32_to_16( se, aq->query.sbuf, &size )) fail = WSAENOBUFS;
402 else fail = GetLastError();
404 return finish_query( &aq->query, MAKELPARAM( size, fail ));
407 /****************************************************************************
408 * The main async help function.
410 * It either starts a thread or just calls the function directly for platforms
411 * with no thread support. This relies on the fact that PostMessage() does
412 * not actually call the windowproc before the function returns.
414 static HANDLE16 run_query( HWND16 hWnd, UINT uMsg, LPTHREAD_START_ROUTINE func,
415 struct async_query_header *query, SEGPTR sbuf, INT sbuflen )
417 static LONG next_handle = 0xdead;
418 HANDLE thread;
419 ULONG handle = LOWORD( InterlockedIncrement( &next_handle ));
421 /* avoid handle 0 */
422 while (!handle) handle = LOWORD( InterlockedIncrement( &next_handle ));
424 query->hWnd = HWND_32(hWnd);
425 query->uMsg = uMsg;
426 query->handle = handle;
427 query->sbuf = sbuf;
428 query->sbuflen = sbuflen;
430 thread = CreateThread( NULL, 0, func, query, 0, NULL );
431 if (!thread)
433 SetLastError( WSAEWOULDBLOCK );
434 return 0;
436 CloseHandle( thread );
437 return handle;
440 /***********************************************************************
441 * accept (WINSOCK.1)
443 SOCKET16 WINAPI accept16(SOCKET16 s, struct sockaddr* addr, INT16* addrlen16 )
445 INT addrlen32 = addrlen16 ? *addrlen16 : 0;
446 SOCKET retSocket = accept( s, addr, &addrlen32 );
447 if( addrlen16 ) *addrlen16 = addrlen32;
448 return retSocket;
451 /***********************************************************************
452 * bind (WINSOCK.2)
454 INT16 WINAPI bind16(SOCKET16 s, struct sockaddr *name, INT16 namelen)
456 return bind( s, name, namelen );
459 /***********************************************************************
460 * closesocket (WINSOCK.3)
462 INT16 WINAPI closesocket16(SOCKET16 s)
464 return closesocket(s);
467 /***********************************************************************
468 * connect (WINSOCK.4)
470 INT16 WINAPI connect16(SOCKET16 s, struct sockaddr *name, INT16 namelen)
472 return connect( s, name, namelen );
475 /***********************************************************************
476 * getpeername (WINSOCK.5)
478 INT16 WINAPI getpeername16(SOCKET16 s, struct sockaddr *name, INT16 *namelen16)
480 INT namelen32 = *namelen16;
481 INT retVal = getpeername( s, name, &namelen32 );
482 *namelen16 = namelen32;
483 return retVal;
486 /***********************************************************************
487 * getsockname (WINSOCK.6)
489 INT16 WINAPI getsockname16(SOCKET16 s, struct sockaddr *name, INT16 *namelen16)
491 INT retVal;
493 if( namelen16 )
495 INT namelen32 = *namelen16;
496 retVal = getsockname( s, name, &namelen32 );
497 *namelen16 = namelen32;
499 else retVal = SOCKET_ERROR;
500 return retVal;
503 /***********************************************************************
504 * getsockopt (WINSOCK.7)
506 INT16 WINAPI getsockopt16(SOCKET16 s, INT16 level, INT16 optname, char *optval, INT16 *optlen)
508 INT optlen32;
509 INT *p = &optlen32;
510 INT retVal;
512 if( optlen ) optlen32 = *optlen; else p = NULL;
513 retVal = getsockopt( s, (WORD)level, optname, optval, p );
514 if( optlen ) *optlen = optlen32;
515 return retVal;
518 /***********************************************************************
519 * htonl (WINSOCK.8)
521 u_long WINAPI htonl16(u_long hostlong)
523 return htonl(hostlong);
527 /***********************************************************************
528 * htons (WINSOCK.9)
530 u_short WINAPI htons16(u_short hostshort)
532 return htons(hostshort);
535 /***********************************************************************
536 * inet_addr (WINSOCK.10)
538 u_long WINAPI inet_addr16(const char *cp)
540 if (!cp) return INADDR_NONE;
541 return inet_addr(cp);
545 /***********************************************************************
546 * inet_ntoa (WINSOCK.11)
548 SEGPTR WINAPI inet_ntoa16(struct in_addr in)
550 char* retVal;
551 if (!(retVal = inet_ntoa( in ))) return 0;
552 if (!dbuffer_seg) dbuffer_seg = MapLS( retVal );
553 return dbuffer_seg;
556 /***********************************************************************
557 * ioctlsocket (WINSOCK.12)
559 INT16 WINAPI ioctlsocket16(SOCKET16 s, LONG cmd, u_long *argp)
561 return ioctlsocket( s, cmd, argp );
564 /***********************************************************************
565 * listen (WINSOCK.13)
567 INT16 WINAPI listen16(SOCKET16 s, INT16 backlog)
569 return listen( s, backlog );
572 /***********************************************************************
573 * ntohl (WINSOCK.14)
575 u_long WINAPI ntohl16(u_long netlong)
577 return ntohl(netlong);
581 /***********************************************************************
582 * ntohs (WINSOCK.15)
584 u_short WINAPI ntohs16(u_short netshort)
586 return ntohs(netshort);
589 /***********************************************************************
590 * recv (WINSOCK.16)
592 INT16 WINAPI recv16(SOCKET16 s, char *buf, INT16 len, INT16 flags)
594 return recv( s, buf, len, flags );
597 /***********************************************************************
598 * recvfrom (WINSOCK.17)
600 INT16 WINAPI recvfrom16(SOCKET16 s, char *buf, INT16 len, INT16 flags,
601 struct sockaddr *from, INT16 *fromlen16)
603 if (fromlen16)
605 INT fromlen32 = *fromlen16;
606 INT retVal = recvfrom( s, buf, len, flags, from, &fromlen32 );
607 *fromlen16 = fromlen32;
608 return retVal;
610 else return recvfrom( s, buf, len, flags, from, NULL );
613 /***********************************************************************
614 * select (WINSOCK.18)
616 INT16 WINAPI select16(INT16 nfds, ws_fd_set16 *ws_readfds,
617 ws_fd_set16 *ws_writefds, ws_fd_set16 *ws_exceptfds,
618 struct timeval* timeout)
620 fd_set read_set, write_set, except_set;
621 fd_set *pread_set = NULL, *pwrite_set = NULL, *pexcept_set = NULL;
622 int ret;
624 if (ws_readfds) pread_set = ws_fdset_16_to_32( ws_readfds, &read_set );
625 if (ws_writefds) pwrite_set = ws_fdset_16_to_32( ws_writefds, &write_set );
626 if (ws_exceptfds) pexcept_set = ws_fdset_16_to_32( ws_exceptfds, &except_set );
627 /* struct timeval is the same for both 32- and 16-bit code */
628 ret = select( nfds, pread_set, pwrite_set, pexcept_set, timeout );
629 if (ws_readfds) ws_fdset_32_to_16( &read_set, ws_readfds );
630 if (ws_writefds) ws_fdset_32_to_16( &write_set, ws_writefds );
631 if (ws_exceptfds) ws_fdset_32_to_16( &except_set, ws_exceptfds );
632 return ret;
635 /***********************************************************************
636 * send (WINSOCK.19)
638 INT16 WINAPI send16(SOCKET16 s, char *buf, INT16 len, INT16 flags)
640 return send( s, buf, len, flags );
643 /***********************************************************************
644 * sendto (WINSOCK.20)
646 INT16 WINAPI sendto16(SOCKET16 s, char *buf, INT16 len, INT16 flags,
647 struct sockaddr *to, INT16 tolen)
649 return sendto( s, buf, len, flags, to, tolen );
652 /***********************************************************************
653 * setsockopt (WINSOCK.21)
655 INT16 WINAPI setsockopt16(SOCKET16 s, INT16 level, INT16 optname,
656 char *optval, INT16 optlen)
658 if( !optval ) return SOCKET_ERROR;
659 return setsockopt( s, (WORD)level, optname, optval, optlen );
662 /***********************************************************************
663 * shutdown (WINSOCK.22)
665 INT16 WINAPI shutdown16(SOCKET16 s, INT16 how)
667 return shutdown( s, how );
670 /***********************************************************************
671 * socket (WINSOCK.23)
673 SOCKET16 WINAPI socket16(INT16 af, INT16 type, INT16 protocol)
675 return socket( af, type, protocol );
678 /***********************************************************************
679 * gethostbyaddr (WINSOCK.51)
681 SEGPTR WINAPI gethostbyaddr16(const char *addr, INT16 len, INT16 type)
683 struct hostent *he;
685 if (!(he = gethostbyaddr( addr, len, type ))) return 0;
686 return ws_hostent_32_to_16( he, 0, NULL );
689 /***********************************************************************
690 * gethostbyname (WINSOCK.52)
692 SEGPTR WINAPI gethostbyname16(const char *name)
694 struct hostent *he;
696 if (!(he = gethostbyname( name ))) return 0;
697 return ws_hostent_32_to_16( he, 0, NULL );
700 /***********************************************************************
701 * getprotobyname (WINSOCK.53)
703 SEGPTR WINAPI getprotobyname16(const char *name)
705 struct protoent *pe;
707 if (!(pe = getprotobyname( name ))) return 0;
708 return ws_protoent_32_to_16( pe, 0, NULL );
711 /***********************************************************************
712 * getprotobynumber (WINSOCK.54)
714 SEGPTR WINAPI getprotobynumber16(INT16 number)
716 struct protoent *pe;
718 if (!(pe = getprotobynumber( number ))) return 0;
719 return ws_protoent_32_to_16( pe, 0, NULL );
722 /***********************************************************************
723 * getservbyname (WINSOCK.55)
725 SEGPTR WINAPI getservbyname16(const char *name, const char *proto)
727 struct servent *se;
729 if (!(se = getservbyname( name, proto ))) return 0;
730 return ws_servent_32_to_16( se, 0, NULL );
733 /***********************************************************************
734 * getservbyport (WINSOCK.56)
736 SEGPTR WINAPI getservbyport16(INT16 port, const char *proto)
738 struct servent *se;
740 if (!(se = getservbyport( port, proto ))) return 0;
741 return ws_servent_32_to_16( se, 0, NULL );
744 /***********************************************************************
745 * gethostname (WINSOCK.57)
747 INT16 WINAPI gethostname16(char *name, INT16 namelen)
749 extern int WINAPI gethostname(char *name, INT namelen);
750 return gethostname(name, namelen);
753 /***********************************************************************
754 * WSAAsyncSelect (WINSOCK.101)
756 INT16 WINAPI WSAAsyncSelect16(SOCKET16 s, HWND16 hWnd, UINT16 wMsg, LONG lEvent)
758 return WSAAsyncSelect( s, HWND_32(hWnd), wMsg, lEvent );
761 /***********************************************************************
762 * WSAAsyncGetHostByAddr (WINSOCK.102)
764 HANDLE16 WINAPI WSAAsyncGetHostByAddr16(HWND16 hWnd, UINT16 uMsg, LPCSTR addr,
765 INT16 len, INT16 type, SEGPTR sbuf, INT16 buflen)
767 struct async_query_gethostbyaddr *aq;
769 TRACE("hwnd %04x, msg %04x, addr %p[%i]\n", hWnd, uMsg, addr, len );
771 if (!(aq = HeapAlloc( GetProcessHeap(), 0, sizeof(*aq) + len )))
773 SetLastError( WSAEWOULDBLOCK );
774 return 0;
776 aq->host_addr = (char *)(aq + 1);
777 aq->host_len = len;
778 aq->host_type = type;
779 memcpy( aq->host_addr, addr, len );
780 return run_query( hWnd, uMsg, async_gethostbyaddr, &aq->query, sbuf, buflen );
783 /***********************************************************************
784 * WSAAsyncGetHostByName (WINSOCK.103)
786 HANDLE16 WINAPI WSAAsyncGetHostByName16(HWND16 hWnd, UINT16 uMsg, LPCSTR name,
787 SEGPTR sbuf, INT16 buflen)
789 struct async_query_gethostbyname *aq;
790 unsigned int len = strlen(name) + 1;
792 TRACE("hwnd %04x, msg %04x, host %s, buffer %i\n", hWnd, uMsg, debugstr_a(name), buflen );
794 if (!(aq = HeapAlloc( GetProcessHeap(), 0, sizeof(*aq) + len )))
796 SetLastError( WSAEWOULDBLOCK );
797 return 0;
799 aq->host_name = (char *)(aq + 1);
800 strcpy( aq->host_name, name );
801 return run_query( hWnd, uMsg, async_gethostbyname, &aq->query, sbuf, buflen );
804 /***********************************************************************
805 * WSAAsyncGetProtoByNumber (WINSOCK.104)
807 HANDLE16 WINAPI WSAAsyncGetProtoByNumber16(HWND16 hWnd,UINT16 uMsg,INT16 number,
808 SEGPTR sbuf, INT16 buflen)
810 struct async_query_getprotobynumber *aq;
812 TRACE("hwnd %04x, msg %04x, num %i\n", hWnd, uMsg, number );
814 if (!(aq = HeapAlloc( GetProcessHeap(), 0, sizeof(*aq) )))
816 SetLastError( WSAEWOULDBLOCK );
817 return 0;
819 aq->proto_number = number;
820 return run_query( hWnd, uMsg, async_getprotobynumber, &aq->query, sbuf, buflen );
823 /***********************************************************************
824 * WSAAsyncGetProtoByName (WINSOCK.105)
826 HANDLE16 WINAPI WSAAsyncGetProtoByName16(HWND16 hWnd, UINT16 uMsg, LPCSTR name,
827 SEGPTR sbuf, INT16 buflen)
829 struct async_query_getprotobyname *aq;
830 unsigned int len = strlen(name) + 1;
832 TRACE("hwnd %04x, msg %04x, proto %s, buffer %i\n", hWnd, uMsg, debugstr_a(name), buflen );
834 if (!(aq = HeapAlloc( GetProcessHeap(), 0, sizeof(*aq) + len )))
836 SetLastError( WSAEWOULDBLOCK );
837 return 0;
839 aq->proto_name = (char *)(aq + 1);
840 strcpy( aq->proto_name, name );
841 return run_query( hWnd, uMsg, async_getprotobyname, &aq->query, sbuf, buflen );
844 /***********************************************************************
845 * WSAAsyncGetServByPort (WINSOCK.106)
847 HANDLE16 WINAPI WSAAsyncGetServByPort16(HWND16 hWnd, UINT16 uMsg, INT16 port,
848 LPCSTR proto, SEGPTR sbuf, INT16 buflen)
850 struct async_query_getservbyport *aq;
851 unsigned int len = strlen(proto) + 1;
853 TRACE("hwnd %04x, msg %04x, port %i, proto %s\n", hWnd, uMsg, port, debugstr_a(proto));
855 if (!(aq = HeapAlloc( GetProcessHeap(), 0, sizeof(*aq) + len )))
857 SetLastError( WSAEWOULDBLOCK );
858 return 0;
860 aq->serv_proto = (char *)(aq + 1);
861 aq->serv_port = port;
862 strcpy( aq->serv_proto, proto );
863 return run_query( hWnd, uMsg, async_getservbyport, &aq->query, sbuf, buflen );
866 /***********************************************************************
867 * WSAAsyncGetServByName (WINSOCK.107)
869 HANDLE16 WINAPI WSAAsyncGetServByName16(HWND16 hWnd, UINT16 uMsg, LPCSTR name,
870 LPCSTR proto, SEGPTR sbuf, INT16 buflen)
872 struct async_query_getservbyname *aq;
873 unsigned int len1 = strlen(name) + 1;
874 unsigned int len2 = strlen(proto) + 1;
876 TRACE("hwnd %04x, msg %04x, name %s, proto %s\n", hWnd, uMsg, debugstr_a(name), debugstr_a(proto));
878 if (!(aq = HeapAlloc( GetProcessHeap(), 0, sizeof(*aq) + len1 + len2 )))
880 SetLastError( WSAEWOULDBLOCK );
881 return 0;
883 aq->serv_name = (char *)(aq + 1);
884 aq->serv_proto = aq->serv_name + len1;
885 strcpy( aq->serv_name, name );
886 strcpy( aq->serv_proto, proto );
887 return run_query( hWnd, uMsg, async_getservbyname, &aq->query, sbuf, buflen );
890 /***********************************************************************
891 * WSACancelAsyncRequest (WINSOCK.108)
893 INT16 WINAPI WSACancelAsyncRequest16(HANDLE16 hAsyncTaskHandle)
895 FIXME("(%04x),stub\n", hAsyncTaskHandle);
896 return 0;
899 /***********************************************************************
900 * WSASetBlockingHook (WINSOCK.109)
902 FARPROC16 WINAPI WSASetBlockingHook16(FARPROC16 lpBlockFunc)
904 /* FIXME: should deal with 16-bit proc */
905 return (FARPROC16)WSASetBlockingHook( (FARPROC)lpBlockFunc );
908 /***********************************************************************
909 * WSAUnhookBlockingHook (WINSOCK.110)
911 INT16 WINAPI WSAUnhookBlockingHook16(void)
913 return WSAUnhookBlockingHook();
916 /***********************************************************************
917 * WSAGetLastError (WINSOCK.111)
919 INT WINAPI WSAGetLastError16(void)
921 return WSAGetLastError();
924 /***********************************************************************
925 * WSASetLastError (WINSOCK.112)
927 void WINAPI WSASetLastError16(INT16 iError)
929 WSASetLastError(iError);
932 /***********************************************************************
933 * WSACancelBlockingCall (WINSOCK.113)
935 INT WINAPI WSACancelBlockingCall16(void)
937 return WSACancelBlockingCall();
940 /***********************************************************************
941 * WSAIsBlocking (WINSOCK.114)
943 BOOL WINAPI WSAIsBlocking16(void)
945 return WSAIsBlocking();
948 /***********************************************************************
949 * WSAStartup (WINSOCK.115)
951 * Create socket control struct, attach it to the global list and
952 * update a pointer in the task struct.
954 INT16 WINAPI WSAStartup16(UINT16 wVersionRequested, LPWSADATA16 lpWSAData)
956 WSADATA data;
957 INT ret = WSAStartup( wVersionRequested, &data );
959 if (!ret)
961 lpWSAData->wVersion = 0x0101;
962 lpWSAData->wHighVersion = 0x0101;
963 strcpy( lpWSAData->szDescription, data.szDescription );
964 strcpy( lpWSAData->szSystemStatus, data.szSystemStatus );
965 lpWSAData->iMaxSockets = data.iMaxSockets;
966 lpWSAData->iMaxUdpDg = data.iMaxUdpDg;
967 lpWSAData->lpVendorInfo = 0;
968 num_startup++;
970 return ret;
973 /***********************************************************************
974 * WSACleanup (WINSOCK.116)
976 INT WINAPI WSACleanup16(void)
978 if (num_startup)
980 if (!--num_startup)
982 /* delete scratch buffers */
983 UnMapLS( he_buffer_seg );
984 UnMapLS( se_buffer_seg );
985 UnMapLS( pe_buffer_seg );
986 UnMapLS( dbuffer_seg );
987 he_buffer_seg = 0;
988 se_buffer_seg = 0;
989 pe_buffer_seg = 0;
990 dbuffer_seg = 0;
991 HeapFree( GetProcessHeap(), 0, he_buffer );
992 HeapFree( GetProcessHeap(), 0, se_buffer );
993 HeapFree( GetProcessHeap(), 0, pe_buffer );
994 he_buffer = NULL;
995 se_buffer = NULL;
996 pe_buffer = NULL;
999 return WSACleanup();
1003 /***********************************************************************
1004 * __WSAFDIsSet (WINSOCK.151)
1006 INT16 WINAPI __WSAFDIsSet16(SOCKET16 s, ws_fd_set16 *set)
1008 int i = set->fd_count;
1010 TRACE("(%d,%p(%i))\n", s, set, i);
1012 while (i--)
1013 if (set->fd_array[i] == s) return 1;
1014 return 0;
1017 /***********************************************************************
1018 * WSARecvEx (WINSOCK.1107)
1020 * See description for WSARecvEx()
1022 INT16 WINAPI WSARecvEx16(SOCKET16 s, char *buf, INT16 len, INT16 *flags)
1024 FIXME("(WSARecvEx16) partial packet return value not set\n");
1025 return recv16(s, buf, len, *flags);