server: Add RIM_TYPEHID type / hid member to rawinput union.
[wine.git] / dlls / winsock.dll16 / socket.c
blob6d0e22d74b9ea5f0b2f502a1c826594e1a5eda08
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 "winsock2.h"
23 #include "wine/winbase16.h"
24 #include "winsock16.h"
25 #include "wownt32.h"
26 #include "winuser.h"
27 #include "wine/debug.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(winsock);
31 struct async_query_header
33 HWND hWnd;
34 UINT uMsg;
35 SEGPTR sbuf;
36 INT sbuflen;
37 HANDLE16 handle;
40 struct async_query_gethostbyname
42 struct async_query_header query;
43 char *host_name;
46 struct async_query_gethostbyaddr
48 struct async_query_header query;
49 char *host_addr;
50 int host_len;
51 int host_type;
54 struct async_query_getprotobyname
56 struct async_query_header query;
57 char *proto_name;
60 struct async_query_getprotobynumber
62 struct async_query_header query;
63 int proto_number;
66 struct async_query_getservbyname
68 struct async_query_header query;
69 char *serv_name;
70 char *serv_proto;
73 struct async_query_getservbyport
75 struct async_query_header query;
76 char *serv_proto;
77 int serv_port;
80 static INT num_startup; /* reference counter */
81 static void *he_buffer;
82 static SEGPTR he_buffer_seg;
83 static void *se_buffer;
84 static SEGPTR se_buffer_seg;
85 static void *pe_buffer;
86 static SEGPTR pe_buffer_seg;
87 static SEGPTR dbuffer_seg;
89 extern int WINAPI WS_gethostname(char *name, int namelen);
91 static fd_set *ws_fdset_16_to_32( const ws_fd_set16 *set16, fd_set *set32 )
93 UINT i;
94 set32->fd_count = set16->fd_count;
95 for (i = 0; i < set32->fd_count; i++) set32->fd_array[i] = set16->fd_array[i];
96 return set32;
99 static ws_fd_set16 *ws_fdset_32_to_16( const fd_set *set32, ws_fd_set16 *set16 )
101 UINT i;
102 set16->fd_count = set32->fd_count;
103 for (i = 0; i < set16->fd_count; i++) set16->fd_array[i] = set32->fd_array[i];
104 return set16;
107 static DWORD finish_query( struct async_query_header *query, LPARAM lparam )
109 PostMessageW( query->hWnd, query->uMsg, (WPARAM)query->handle, lparam );
110 HeapFree( GetProcessHeap(), 0, query );
111 return 0;
114 static int list_size(char** l, int item_size)
116 int i,j = 0;
117 if(l)
119 for(i=0;l[i];i++)
120 j += (item_size) ? item_size : strlen(l[i]) + 1;
121 j += (i + 1) * sizeof(char*);
123 return j;
126 static int list_dup(char** l_src, SEGPTR base, int item_size)
128 int i, offset;
129 char *ref = MapSL(base);
130 SEGPTR *l_to = (SEGPTR *)ref;
132 for (i = 0; l_src[i]; i++) ;
133 offset = (i + 1) * sizeof(char*);
134 for (i = 0; l_src[i]; i++)
136 int count = item_size ? item_size : strlen(l_src[i]) + 1;
137 memcpy( ref + offset, l_src[i], count );
138 l_to[i] = base + offset;
139 offset += count;
141 l_to[i] = 0;
142 return offset;
145 static SEGPTR get_buffer_he(int size)
147 static int he_len;
148 if (he_buffer)
150 if (he_len >= size ) return he_buffer_seg;
151 UnMapLS( he_buffer_seg );
152 HeapFree( GetProcessHeap(), 0, he_buffer );
154 he_buffer = HeapAlloc( GetProcessHeap(), 0, (he_len = size) );
155 he_buffer_seg = MapLS( he_buffer );
156 return he_buffer_seg;
159 static SEGPTR get_buffer_se(int size)
161 static int se_len;
162 if (se_buffer)
164 if (se_len >= size ) return se_buffer_seg;
165 UnMapLS( se_buffer_seg );
166 HeapFree( GetProcessHeap(), 0, se_buffer );
168 se_buffer = HeapAlloc( GetProcessHeap(), 0, (se_len = size) );
169 se_buffer_seg = MapLS( se_buffer );
170 return se_buffer_seg;
173 static SEGPTR get_buffer_pe(int size)
175 static int pe_len;
176 if (pe_buffer)
178 if (pe_len >= size ) return pe_buffer_seg;
179 UnMapLS( pe_buffer_seg );
180 HeapFree( GetProcessHeap(), 0, pe_buffer );
182 pe_buffer = HeapAlloc( GetProcessHeap(), 0, (pe_len = size) );
183 pe_buffer_seg = MapLS( pe_buffer );
184 return pe_buffer_seg;
187 /* duplicate hostent entry
188 * and handle all Win16/Win32 dependent things (struct size, ...) *correctly*.
189 * Ditto for protoent and servent.
191 static SEGPTR ws_hostent_32_to_16( const struct hostent* he, SEGPTR base, int *buff_size )
193 char *p;
194 struct ws_hostent16 *p_to;
196 int size = (sizeof(*p_to) +
197 strlen(he->h_name) + 1 +
198 list_size(he->h_aliases, 0) +
199 list_size(he->h_addr_list, he->h_length));
201 if (buff_size)
203 if (*buff_size < size)
205 *buff_size = size;
206 return 0;
208 *buff_size = size;
210 else base = get_buffer_he(size);
211 p_to = MapSL(base);
213 p_to->h_addrtype = he->h_addrtype;
214 p_to->h_length = he->h_length;
216 p = (char *)(p_to + 1);
217 p_to->h_name = base + (p - (char *)p_to);
218 strcpy(p, he->h_name);
219 p += strlen(p) + 1;
221 p_to->h_aliases = base + (p - (char *)p_to);
222 p += list_dup(he->h_aliases, p_to->h_aliases, 0);
224 p_to->h_addr_list = base + (p - (char *)p_to);
225 list_dup(he->h_addr_list, p_to->h_addr_list, he->h_length);
227 return base;
230 static SEGPTR ws_protoent_32_to_16( const struct protoent *pe, SEGPTR base, int *buff_size )
232 char *p;
233 struct ws_protoent16 *p_to;
235 int size = (sizeof(*p_to) +
236 strlen(pe->p_name) + 1 +
237 list_size(pe->p_aliases, 0));
239 if (buff_size)
241 if (*buff_size < size)
243 *buff_size = size;
244 return 0;
246 *buff_size = size;
248 else base = get_buffer_pe(size);
249 p_to = MapSL(base);
251 p_to->p_proto = pe->p_proto;
252 p = (char *)(p_to + 1);
254 p_to->p_name = base + (p - (char *)p_to);
255 strcpy(p, pe->p_name);
256 p += strlen(p) + 1;
258 p_to->p_aliases = base + (p - (char *)p_to);
259 list_dup(pe->p_aliases, p_to->p_aliases, 0);
261 return base;
264 static SEGPTR ws_servent_32_to_16( const struct servent *se, SEGPTR base, int *buff_size )
266 char *p;
267 struct ws_servent16 *p_to;
269 int size = (sizeof(*p_to) +
270 strlen(se->s_proto) + 1 +
271 strlen(se->s_name) + 1 +
272 list_size(se->s_aliases, 0));
274 if (buff_size)
276 if (*buff_size < size)
278 *buff_size = size;
279 return 0;
281 *buff_size = size;
283 else base = get_buffer_se(size);
284 p_to = MapSL(base);
286 p_to->s_port = se->s_port;
287 p = (char *)(p_to + 1);
289 p_to->s_name = base + (p - (char *)p_to);
290 strcpy(p, se->s_name);
291 p += strlen(p) + 1;
293 p_to->s_proto = base + (p - (char *)p_to);
294 strcpy(p, se->s_proto);
295 p += strlen(p) + 1;
297 p_to->s_aliases = base + (p - (char *)p_to);
298 list_dup(se->s_aliases, p_to->s_aliases, 0);
300 return base;
303 static DWORD WINAPI async_gethostbyname(LPVOID arg)
305 struct async_query_gethostbyname *aq = arg;
306 int size = 0;
307 WORD fail = 0;
308 struct hostent *he;
310 if ((he = gethostbyname( aq->host_name )))
312 size = aq->query.sbuflen;
313 if (!ws_hostent_32_to_16( he, aq->query.sbuf, &size )) fail = WSAENOBUFS;
315 else fail = GetLastError();
317 return finish_query( &aq->query, MAKELPARAM( size, fail ));
320 static DWORD WINAPI async_gethostbyaddr(LPVOID arg)
322 struct async_query_gethostbyaddr *aq = arg;
323 int size = 0;
324 WORD fail = 0;
325 struct hostent *he;
327 if ((he = gethostbyaddr(aq->host_addr,aq->host_len,aq->host_type)))
329 size = aq->query.sbuflen;
330 if (!ws_hostent_32_to_16( he, aq->query.sbuf, &size )) fail = WSAENOBUFS;
332 else fail = GetLastError();
334 return finish_query( &aq->query, MAKELPARAM( size, fail ));
337 static DWORD WINAPI async_getprotobyname(LPVOID arg)
339 struct async_query_getprotobyname *aq = arg;
340 int size = 0;
341 WORD fail = 0;
342 struct protoent *pe;
344 if ((pe = getprotobyname(aq->proto_name)))
346 size = aq->query.sbuflen;
347 if (!ws_protoent_32_to_16( pe, aq->query.sbuf, &size )) fail = WSAENOBUFS;
349 else fail = GetLastError();
351 return finish_query( &aq->query, MAKELPARAM( size, fail ));
354 static DWORD WINAPI async_getprotobynumber(LPVOID arg)
356 struct async_query_getprotobynumber *aq = arg;
357 int size = 0;
358 WORD fail = 0;
359 struct protoent *pe;
361 if ((pe = getprotobynumber(aq->proto_number)))
363 size = aq->query.sbuflen;
364 if (!ws_protoent_32_to_16( pe, aq->query.sbuf, &size )) fail = WSAENOBUFS;
366 else fail = GetLastError();
368 return finish_query( &aq->query, MAKELPARAM( size, fail ));
371 static DWORD WINAPI async_getservbyname(LPVOID arg)
373 struct async_query_getservbyname *aq = arg;
374 int size = 0;
375 WORD fail = 0;
376 struct servent *se;
378 if ((se = getservbyname(aq->serv_name,aq->serv_proto)))
380 size = aq->query.sbuflen;
381 if (!ws_servent_32_to_16( se, aq->query.sbuf, &size )) fail = WSAENOBUFS;
383 else fail = GetLastError();
385 return finish_query( &aq->query, MAKELPARAM( size, fail ));
388 static DWORD WINAPI async_getservbyport(LPVOID arg)
390 struct async_query_getservbyport *aq = arg;
391 int size = 0;
392 WORD fail = 0;
393 struct servent *se;
395 if ((se = getservbyport(aq->serv_port,aq->serv_proto)))
397 size = aq->query.sbuflen;
398 if (!ws_servent_32_to_16( se, aq->query.sbuf, &size )) fail = WSAENOBUFS;
400 else fail = GetLastError();
402 return finish_query( &aq->query, MAKELPARAM( size, fail ));
405 /****************************************************************************
406 * The main async help function.
408 * It either starts a thread or just calls the function directly for platforms
409 * with no thread support. This relies on the fact that PostMessage() does
410 * not actually call the windowproc before the function returns.
412 static HANDLE16 run_query( HWND16 hWnd, UINT uMsg, LPTHREAD_START_ROUTINE func,
413 struct async_query_header *query, SEGPTR sbuf, INT sbuflen )
415 static LONG next_handle = 0xdead;
416 HANDLE thread;
417 ULONG handle = LOWORD( InterlockedIncrement( &next_handle ));
419 /* avoid handle 0 */
420 while (!handle) handle = LOWORD( InterlockedIncrement( &next_handle ));
422 query->hWnd = HWND_32(hWnd);
423 query->uMsg = uMsg;
424 query->handle = handle;
425 query->sbuf = sbuf;
426 query->sbuflen = sbuflen;
428 thread = CreateThread( NULL, 0, func, query, 0, NULL );
429 if (!thread)
431 SetLastError( WSAEWOULDBLOCK );
432 return 0;
434 CloseHandle( thread );
435 return handle;
438 /***********************************************************************
439 * accept (WINSOCK.1)
441 SOCKET16 WINAPI accept16(SOCKET16 s, struct sockaddr* addr, INT16* addrlen16 )
443 INT addrlen32 = addrlen16 ? *addrlen16 : 0;
444 SOCKET retSocket = accept( s, addr, &addrlen32 );
445 if( addrlen16 ) *addrlen16 = addrlen32;
446 return retSocket;
449 /***********************************************************************
450 * bind (WINSOCK.2)
452 INT16 WINAPI bind16(SOCKET16 s, struct sockaddr *name, INT16 namelen)
454 return bind( s, name, namelen );
457 /***********************************************************************
458 * closesocket (WINSOCK.3)
460 INT16 WINAPI closesocket16(SOCKET16 s)
462 return closesocket(s);
465 /***********************************************************************
466 * connect (WINSOCK.4)
468 INT16 WINAPI connect16(SOCKET16 s, struct sockaddr *name, INT16 namelen)
470 return connect( s, name, namelen );
473 /***********************************************************************
474 * getpeername (WINSOCK.5)
476 INT16 WINAPI getpeername16(SOCKET16 s, struct sockaddr *name, INT16 *namelen16)
478 INT namelen32 = *namelen16;
479 INT retVal = getpeername( s, name, &namelen32 );
480 *namelen16 = namelen32;
481 return retVal;
484 /***********************************************************************
485 * getsockname (WINSOCK.6)
487 INT16 WINAPI getsockname16(SOCKET16 s, struct sockaddr *name, INT16 *namelen16)
489 INT retVal;
491 if( namelen16 )
493 INT namelen32 = *namelen16;
494 retVal = getsockname( s, name, &namelen32 );
495 *namelen16 = namelen32;
497 else retVal = SOCKET_ERROR;
498 return retVal;
501 /***********************************************************************
502 * getsockopt (WINSOCK.7)
504 INT16 WINAPI getsockopt16(SOCKET16 s, INT16 level, INT16 optname, char *optval, INT16 *optlen)
506 INT optlen32;
507 INT *p = &optlen32;
508 INT retVal;
510 if( optlen ) optlen32 = *optlen; else p = NULL;
511 retVal = getsockopt( s, (WORD)level, optname, optval, p );
512 if( optlen ) *optlen = optlen32;
513 return retVal;
516 /***********************************************************************
517 * htonl (WINSOCK.8)
519 u_long WINAPI htonl16(u_long hostlong)
521 return htonl(hostlong);
525 /***********************************************************************
526 * htons (WINSOCK.9)
528 u_short WINAPI htons16(u_short hostshort)
530 return htons(hostshort);
533 /***********************************************************************
534 * inet_addr (WINSOCK.10)
536 u_long WINAPI inet_addr16(const char *cp)
538 if (!cp) return INADDR_NONE;
539 return inet_addr(cp);
543 /***********************************************************************
544 * inet_ntoa (WINSOCK.11)
546 SEGPTR WINAPI inet_ntoa16(struct in_addr in)
548 char* retVal;
549 if (!(retVal = inet_ntoa( in ))) return 0;
550 if (!dbuffer_seg) dbuffer_seg = MapLS( retVal );
551 return dbuffer_seg;
554 /***********************************************************************
555 * ioctlsocket (WINSOCK.12)
557 INT16 WINAPI ioctlsocket16(SOCKET16 s, LONG cmd, u_long *argp)
559 return ioctlsocket( s, cmd, argp );
562 /***********************************************************************
563 * listen (WINSOCK.13)
565 INT16 WINAPI listen16(SOCKET16 s, INT16 backlog)
567 return listen( s, backlog );
570 /***********************************************************************
571 * ntohl (WINSOCK.14)
573 u_long WINAPI ntohl16(u_long netlong)
575 return ntohl(netlong);
579 /***********************************************************************
580 * ntohs (WINSOCK.15)
582 u_short WINAPI ntohs16(u_short netshort)
584 return ntohs(netshort);
587 /***********************************************************************
588 * recv (WINSOCK.16)
590 INT16 WINAPI recv16(SOCKET16 s, char *buf, INT16 len, INT16 flags)
592 return recv( s, buf, len, flags );
595 /***********************************************************************
596 * recvfrom (WINSOCK.17)
598 INT16 WINAPI recvfrom16(SOCKET16 s, char *buf, INT16 len, INT16 flags,
599 struct sockaddr *from, INT16 *fromlen16)
601 if (fromlen16)
603 INT fromlen32 = *fromlen16;
604 INT retVal = recvfrom( s, buf, len, flags, from, &fromlen32 );
605 *fromlen16 = fromlen32;
606 return retVal;
608 else return recvfrom( s, buf, len, flags, from, NULL );
611 /***********************************************************************
612 * select (WINSOCK.18)
614 INT16 WINAPI select16(INT16 nfds, ws_fd_set16 *ws_readfds,
615 ws_fd_set16 *ws_writefds, ws_fd_set16 *ws_exceptfds,
616 struct timeval* timeout)
618 fd_set read_set, write_set, except_set;
619 fd_set *pread_set = NULL, *pwrite_set = NULL, *pexcept_set = NULL;
620 int ret;
622 if (ws_readfds) pread_set = ws_fdset_16_to_32( ws_readfds, &read_set );
623 if (ws_writefds) pwrite_set = ws_fdset_16_to_32( ws_writefds, &write_set );
624 if (ws_exceptfds) pexcept_set = ws_fdset_16_to_32( ws_exceptfds, &except_set );
625 /* struct timeval is the same for both 32- and 16-bit code */
626 ret = select( nfds, pread_set, pwrite_set, pexcept_set, timeout );
627 if (ws_readfds) ws_fdset_32_to_16( &read_set, ws_readfds );
628 if (ws_writefds) ws_fdset_32_to_16( &write_set, ws_writefds );
629 if (ws_exceptfds) ws_fdset_32_to_16( &except_set, ws_exceptfds );
630 return ret;
633 /***********************************************************************
634 * send (WINSOCK.19)
636 INT16 WINAPI send16(SOCKET16 s, char *buf, INT16 len, INT16 flags)
638 return send( s, buf, len, flags );
641 /***********************************************************************
642 * sendto (WINSOCK.20)
644 INT16 WINAPI sendto16(SOCKET16 s, char *buf, INT16 len, INT16 flags,
645 struct sockaddr *to, INT16 tolen)
647 return sendto( s, buf, len, flags, to, tolen );
650 /***********************************************************************
651 * setsockopt (WINSOCK.21)
653 INT16 WINAPI setsockopt16(SOCKET16 s, INT16 level, INT16 optname,
654 char *optval, INT16 optlen)
656 if( !optval ) return SOCKET_ERROR;
657 return setsockopt( s, (WORD)level, optname, optval, optlen );
660 /***********************************************************************
661 * shutdown (WINSOCK.22)
663 INT16 WINAPI shutdown16(SOCKET16 s, INT16 how)
665 return shutdown( s, how );
668 /***********************************************************************
669 * socket (WINSOCK.23)
671 SOCKET16 WINAPI socket16(INT16 af, INT16 type, INT16 protocol)
673 return socket( af, type, protocol );
676 /***********************************************************************
677 * gethostbyaddr (WINSOCK.51)
679 SEGPTR WINAPI gethostbyaddr16(const char *addr, INT16 len, INT16 type)
681 struct hostent *he;
683 if (!(he = gethostbyaddr( addr, len, type ))) return 0;
684 return ws_hostent_32_to_16( he, 0, NULL );
687 /***********************************************************************
688 * gethostbyname (WINSOCK.52)
690 SEGPTR WINAPI gethostbyname16(const char *name)
692 struct hostent *he;
694 if (!(he = gethostbyname( name ))) return 0;
695 return ws_hostent_32_to_16( he, 0, NULL );
698 /***********************************************************************
699 * getprotobyname (WINSOCK.53)
701 SEGPTR WINAPI getprotobyname16(const char *name)
703 struct protoent *pe;
705 if (!(pe = getprotobyname( name ))) return 0;
706 return ws_protoent_32_to_16( pe, 0, NULL );
709 /***********************************************************************
710 * getprotobynumber (WINSOCK.54)
712 SEGPTR WINAPI getprotobynumber16(INT16 number)
714 struct protoent *pe;
716 if (!(pe = getprotobynumber( number ))) return 0;
717 return ws_protoent_32_to_16( pe, 0, NULL );
720 /***********************************************************************
721 * getservbyname (WINSOCK.55)
723 SEGPTR WINAPI getservbyname16(const char *name, const char *proto)
725 struct servent *se;
727 if (!(se = getservbyname( name, proto ))) return 0;
728 return ws_servent_32_to_16( se, 0, NULL );
731 /***********************************************************************
732 * getservbyport (WINSOCK.56)
734 SEGPTR WINAPI getservbyport16(INT16 port, const char *proto)
736 struct servent *se;
738 if (!(se = getservbyport( port, proto ))) return 0;
739 return ws_servent_32_to_16( se, 0, NULL );
742 /***********************************************************************
743 * gethostname (WINSOCK.57)
745 INT16 WINAPI gethostname16(char *name, INT16 namelen)
747 extern int WINAPI gethostname(char *name, INT namelen);
748 return gethostname(name, namelen);
751 /***********************************************************************
752 * WSAAsyncSelect (WINSOCK.101)
754 INT16 WINAPI WSAAsyncSelect16(SOCKET16 s, HWND16 hWnd, UINT16 wMsg, LONG lEvent)
756 return WSAAsyncSelect( s, HWND_32(hWnd), wMsg, lEvent );
759 /***********************************************************************
760 * WSAAsyncGetHostByAddr (WINSOCK.102)
762 HANDLE16 WINAPI WSAAsyncGetHostByAddr16(HWND16 hWnd, UINT16 uMsg, LPCSTR addr,
763 INT16 len, INT16 type, SEGPTR sbuf, INT16 buflen)
765 struct async_query_gethostbyaddr *aq;
767 TRACE("hwnd %04x, msg %04x, addr %p[%i]\n", hWnd, uMsg, addr, len );
769 if (!(aq = HeapAlloc( GetProcessHeap(), 0, sizeof(*aq) + len )))
771 SetLastError( WSAEWOULDBLOCK );
772 return 0;
774 aq->host_addr = (char *)(aq + 1);
775 aq->host_len = len;
776 aq->host_type = type;
777 memcpy( aq->host_addr, addr, len );
778 return run_query( hWnd, uMsg, async_gethostbyaddr, &aq->query, sbuf, buflen );
781 /***********************************************************************
782 * WSAAsyncGetHostByName (WINSOCK.103)
784 HANDLE16 WINAPI WSAAsyncGetHostByName16(HWND16 hWnd, UINT16 uMsg, LPCSTR name,
785 SEGPTR sbuf, INT16 buflen)
787 struct async_query_gethostbyname *aq;
788 unsigned int len = strlen(name) + 1;
790 TRACE("hwnd %04x, msg %04x, host %s, buffer %i\n", hWnd, uMsg, debugstr_a(name), buflen );
792 if (!(aq = HeapAlloc( GetProcessHeap(), 0, sizeof(*aq) + len )))
794 SetLastError( WSAEWOULDBLOCK );
795 return 0;
797 aq->host_name = (char *)(aq + 1);
798 strcpy( aq->host_name, name );
799 return run_query( hWnd, uMsg, async_gethostbyname, &aq->query, sbuf, buflen );
802 /***********************************************************************
803 * WSAAsyncGetProtoByNumber (WINSOCK.104)
805 HANDLE16 WINAPI WSAAsyncGetProtoByNumber16(HWND16 hWnd,UINT16 uMsg,INT16 number,
806 SEGPTR sbuf, INT16 buflen)
808 struct async_query_getprotobynumber *aq;
810 TRACE("hwnd %04x, msg %04x, num %i\n", hWnd, uMsg, number );
812 if (!(aq = HeapAlloc( GetProcessHeap(), 0, sizeof(*aq) )))
814 SetLastError( WSAEWOULDBLOCK );
815 return 0;
817 aq->proto_number = number;
818 return run_query( hWnd, uMsg, async_getprotobynumber, &aq->query, sbuf, buflen );
821 /***********************************************************************
822 * WSAAsyncGetProtoByName (WINSOCK.105)
824 HANDLE16 WINAPI WSAAsyncGetProtoByName16(HWND16 hWnd, UINT16 uMsg, LPCSTR name,
825 SEGPTR sbuf, INT16 buflen)
827 struct async_query_getprotobyname *aq;
828 unsigned int len = strlen(name) + 1;
830 TRACE("hwnd %04x, msg %04x, proto %s, buffer %i\n", hWnd, uMsg, debugstr_a(name), buflen );
832 if (!(aq = HeapAlloc( GetProcessHeap(), 0, sizeof(*aq) + len )))
834 SetLastError( WSAEWOULDBLOCK );
835 return 0;
837 aq->proto_name = (char *)(aq + 1);
838 strcpy( aq->proto_name, name );
839 return run_query( hWnd, uMsg, async_getprotobyname, &aq->query, sbuf, buflen );
842 /***********************************************************************
843 * WSAAsyncGetServByPort (WINSOCK.106)
845 HANDLE16 WINAPI WSAAsyncGetServByPort16(HWND16 hWnd, UINT16 uMsg, INT16 port,
846 LPCSTR proto, SEGPTR sbuf, INT16 buflen)
848 struct async_query_getservbyport *aq;
849 unsigned int len = strlen(proto) + 1;
851 TRACE("hwnd %04x, msg %04x, port %i, proto %s\n", hWnd, uMsg, port, debugstr_a(proto));
853 if (!(aq = HeapAlloc( GetProcessHeap(), 0, sizeof(*aq) + len )))
855 SetLastError( WSAEWOULDBLOCK );
856 return 0;
858 aq->serv_proto = (char *)(aq + 1);
859 aq->serv_port = port;
860 strcpy( aq->serv_proto, proto );
861 return run_query( hWnd, uMsg, async_getservbyport, &aq->query, sbuf, buflen );
864 /***********************************************************************
865 * WSAAsyncGetServByName (WINSOCK.107)
867 HANDLE16 WINAPI WSAAsyncGetServByName16(HWND16 hWnd, UINT16 uMsg, LPCSTR name,
868 LPCSTR proto, SEGPTR sbuf, INT16 buflen)
870 struct async_query_getservbyname *aq;
871 unsigned int len1 = strlen(name) + 1;
872 unsigned int len2 = strlen(proto) + 1;
874 TRACE("hwnd %04x, msg %04x, name %s, proto %s\n", hWnd, uMsg, debugstr_a(name), debugstr_a(proto));
876 if (!(aq = HeapAlloc( GetProcessHeap(), 0, sizeof(*aq) + len1 + len2 )))
878 SetLastError( WSAEWOULDBLOCK );
879 return 0;
881 aq->serv_name = (char *)(aq + 1);
882 aq->serv_proto = aq->serv_name + len1;
883 strcpy( aq->serv_name, name );
884 strcpy( aq->serv_proto, proto );
885 return run_query( hWnd, uMsg, async_getservbyname, &aq->query, sbuf, buflen );
888 /***********************************************************************
889 * WSACancelAsyncRequest (WINSOCK.108)
891 INT16 WINAPI WSACancelAsyncRequest16(HANDLE16 hAsyncTaskHandle)
893 FIXME("(%04x),stub\n", hAsyncTaskHandle);
894 return 0;
897 /***********************************************************************
898 * WSASetBlockingHook (WINSOCK.109)
900 FARPROC16 WINAPI WSASetBlockingHook16(FARPROC16 lpBlockFunc)
902 /* FIXME: should deal with 16-bit proc */
903 return (FARPROC16)WSASetBlockingHook( (FARPROC)lpBlockFunc );
906 /***********************************************************************
907 * WSAUnhookBlockingHook (WINSOCK.110)
909 INT16 WINAPI WSAUnhookBlockingHook16(void)
911 return WSAUnhookBlockingHook();
914 /***********************************************************************
915 * WSAGetLastError (WINSOCK.111)
917 INT WINAPI WSAGetLastError16(void)
919 return WSAGetLastError();
922 /***********************************************************************
923 * WSASetLastError (WINSOCK.112)
925 void WINAPI WSASetLastError16(INT16 iError)
927 WSASetLastError(iError);
930 /***********************************************************************
931 * WSACancelBlockingCall (WINSOCK.113)
933 INT WINAPI WSACancelBlockingCall16(void)
935 return WSACancelBlockingCall();
938 /***********************************************************************
939 * WSAIsBlocking (WINSOCK.114)
941 BOOL WINAPI WSAIsBlocking16(void)
943 return WSAIsBlocking();
946 /***********************************************************************
947 * WSAStartup (WINSOCK.115)
949 * Create socket control struct, attach it to the global list and
950 * update a pointer in the task struct.
952 INT16 WINAPI WSAStartup16(UINT16 wVersionRequested, LPWSADATA16 lpWSAData)
954 WSADATA data;
955 INT ret = WSAStartup( wVersionRequested, &data );
957 if (!ret)
959 lpWSAData->wVersion = 0x0101;
960 lpWSAData->wHighVersion = 0x0101;
961 strcpy( lpWSAData->szDescription, data.szDescription );
962 strcpy( lpWSAData->szSystemStatus, data.szSystemStatus );
963 lpWSAData->iMaxSockets = data.iMaxSockets;
964 lpWSAData->iMaxUdpDg = data.iMaxUdpDg;
965 lpWSAData->lpVendorInfo = 0;
966 num_startup++;
968 return ret;
971 /***********************************************************************
972 * WSACleanup (WINSOCK.116)
974 INT WINAPI WSACleanup16(void)
976 if (num_startup)
978 if (!--num_startup)
980 /* delete scratch buffers */
981 UnMapLS( he_buffer_seg );
982 UnMapLS( se_buffer_seg );
983 UnMapLS( pe_buffer_seg );
984 UnMapLS( dbuffer_seg );
985 he_buffer_seg = 0;
986 se_buffer_seg = 0;
987 pe_buffer_seg = 0;
988 dbuffer_seg = 0;
989 HeapFree( GetProcessHeap(), 0, he_buffer );
990 HeapFree( GetProcessHeap(), 0, se_buffer );
991 HeapFree( GetProcessHeap(), 0, pe_buffer );
992 he_buffer = NULL;
993 se_buffer = NULL;
994 pe_buffer = NULL;
997 return WSACleanup();
1001 /***********************************************************************
1002 * __WSAFDIsSet (WINSOCK.151)
1004 INT16 WINAPI __WSAFDIsSet16(SOCKET16 s, ws_fd_set16 *set)
1006 int i = set->fd_count;
1008 TRACE("(%d,%p(%i))\n", s, set, i);
1010 while (i--)
1011 if (set->fd_array[i] == s) return 1;
1012 return 0;
1015 /***********************************************************************
1016 * WSARecvEx (WINSOCK.1107)
1018 * See description for WSARecvEx()
1020 INT16 WINAPI WSARecvEx16(SOCKET16 s, char *buf, INT16 len, INT16 *flags)
1022 FIXME("(WSARecvEx16) partial packet return value not set\n");
1023 return recv16(s, buf, len, *flags);