2 * Protocol-level socket functions
4 * Copyright (C) 1993,1994,1996,1997 John Brezak, Erik Bos, Alex Korobka.
5 * Copyright (C) 2001 Stefan Leichter
6 * Copyright (C) 2004 Hans Leidekker
7 * Copyright (C) 2005 Marcus Meissner
8 * Copyright (C) 2006-2008 Kai Blin
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 #include "ws2_32_private.h"
27 WINE_DEFAULT_DEBUG_CHANNEL(winsock
);
28 WINE_DECLARE_DEBUG_CHANNEL(winediag
);
30 static char *get_fqdn(void)
35 GetComputerNameExA( ComputerNamePhysicalDnsFullyQualified
, NULL
, &size
);
36 if (GetLastError() != ERROR_MORE_DATA
) return NULL
;
37 if (!(ret
= HeapAlloc( GetProcessHeap(), 0, size
))) return NULL
;
38 if (!GetComputerNameExA( ComputerNamePhysicalDnsFullyQualified
, ret
, &size
))
40 HeapFree( GetProcessHeap(), 0, ret
);
46 /* call Unix getaddrinfo, allocating a large enough buffer */
47 static int do_getaddrinfo( const char *node
, const char *service
,
48 const struct addrinfo
*hints
, struct addrinfo
**info
)
50 struct addrinfo
*buffer
, *new_buffer
;
51 unsigned int size
= 1024;
54 if (!(buffer
= HeapAlloc( GetProcessHeap(), 0, size
)))
55 return WSA_NOT_ENOUGH_MEMORY
;
57 while ((ret
= unix_funcs
->getaddrinfo( node
, service
, hints
, buffer
, &size
)) == ERROR_INSUFFICIENT_BUFFER
)
59 if (!(new_buffer
= HeapReAlloc( GetProcessHeap(), 0, buffer
, size
)))
61 HeapFree( GetProcessHeap(), 0, buffer
);
62 return WSA_NOT_ENOUGH_MEMORY
;
70 HeapFree( GetProcessHeap(), 0, buffer
);
75 /***********************************************************************
76 * getaddrinfo (ws2_32.@)
78 int WINAPI
getaddrinfo( const char *node
, const char *service
,
79 const struct addrinfo
*hints
, struct addrinfo
**info
)
81 char *nodev6
= NULL
, *fqdn
= NULL
;
84 TRACE( "node %s, service %s, hints %p\n", debugstr_a(node
), debugstr_a(service
), hints
);
88 if (!node
&& !service
)
90 SetLastError( WSAHOST_NOT_FOUND
);
91 return WSAHOST_NOT_FOUND
;
98 if (!(fqdn
= get_fqdn())) return WSA_NOT_ENOUGH_MEMORY
;
101 else if (!hints
|| hints
->ai_family
== AF_UNSPEC
|| hints
->ai_family
== AF_INET6
)
103 /* [ipv6] or [ipv6]:portnumber are supported by Windows */
106 if (node
[0] == '[' && (close_bracket
= strchr(node
+ 1, ']')))
108 nodev6
= HeapAlloc( GetProcessHeap(), 0, close_bracket
- node
);
109 if (!nodev6
) return WSA_NOT_ENOUGH_MEMORY
;
110 lstrcpynA( nodev6
, node
+ 1, close_bracket
- node
);
116 ret
= do_getaddrinfo( node
, service
, hints
, info
);
118 if (ret
&& (!hints
|| !(hints
->ai_flags
& AI_NUMERICHOST
)) && node
)
120 if (!fqdn
&& !(fqdn
= get_fqdn()))
122 HeapFree( GetProcessHeap(), 0, nodev6
);
123 return WSA_NOT_ENOUGH_MEMORY
;
125 if (!strcmp( fqdn
, node
) || (!strncmp( fqdn
, node
, strlen( node
) ) && fqdn
[strlen( node
)] == '.'))
127 /* If it didn't work it means the host name IP is not in /etc/hosts, try again
128 * by sending a NULL host and avoid sending a NULL servname too because that
130 ERR_(winediag
)( "Failed to resolve your host name IP\n" );
131 ret
= do_getaddrinfo( NULL
, service
, hints
, info
);
132 if (!ret
&& hints
&& (hints
->ai_flags
& AI_CANONNAME
) && *info
&& !(*info
)->ai_canonname
)
134 freeaddrinfo( *info
);
141 HeapFree( GetProcessHeap(), 0, fqdn
);
142 HeapFree( GetProcessHeap(), 0, nodev6
);
144 if (!ret
&& TRACE_ON(winsock
))
148 for (ai
= *info
; ai
!= NULL
; ai
= ai
->ai_next
)
150 TRACE( "=> %p, flags %#x, family %d, type %d, protocol %d, len %ld, name %s, addr %s\n",
151 ai
, ai
->ai_flags
, ai
->ai_family
, ai
->ai_socktype
, ai
->ai_protocol
, ai
->ai_addrlen
,
152 ai
->ai_canonname
, debugstr_sockaddr(ai
->ai_addr
) );
161 static ADDRINFOEXW
*addrinfo_AtoW( const struct addrinfo
*ai
)
165 if (!(ret
= HeapAlloc( GetProcessHeap(), 0, sizeof(ADDRINFOEXW
) ))) return NULL
;
166 ret
->ai_flags
= ai
->ai_flags
;
167 ret
->ai_family
= ai
->ai_family
;
168 ret
->ai_socktype
= ai
->ai_socktype
;
169 ret
->ai_protocol
= ai
->ai_protocol
;
170 ret
->ai_addrlen
= ai
->ai_addrlen
;
171 ret
->ai_canonname
= NULL
;
175 ret
->ai_provider
= NULL
;
177 if (ai
->ai_canonname
)
179 int len
= MultiByteToWideChar( CP_ACP
, 0, ai
->ai_canonname
, -1, NULL
, 0 );
180 if (!(ret
->ai_canonname
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) )))
182 HeapFree( GetProcessHeap(), 0, ret
);
185 MultiByteToWideChar( CP_ACP
, 0, ai
->ai_canonname
, -1, ret
->ai_canonname
, len
);
189 if (!(ret
->ai_addr
= HeapAlloc( GetProcessHeap(), 0, ai
->ai_addrlen
)))
191 HeapFree( GetProcessHeap(), 0, ret
->ai_canonname
);
192 HeapFree( GetProcessHeap(), 0, ret
);
195 memcpy( ret
->ai_addr
, ai
->ai_addr
, ai
->ai_addrlen
);
200 static ADDRINFOEXW
*addrinfo_list_AtoW( const struct addrinfo
*info
)
202 ADDRINFOEXW
*ret
, *infoW
;
204 if (!(ret
= infoW
= addrinfo_AtoW( info
))) return NULL
;
205 while (info
->ai_next
)
207 if (!(infoW
->ai_next
= addrinfo_AtoW( info
->ai_next
)))
209 FreeAddrInfoExW( ret
);
212 infoW
= infoW
->ai_next
;
213 info
= info
->ai_next
;
218 static struct addrinfo
*addrinfo_WtoA( const struct addrinfoW
*ai
)
220 struct addrinfo
*ret
;
222 if (!(ret
= HeapAlloc( GetProcessHeap(), 0, sizeof(struct addrinfo
) ))) return NULL
;
223 ret
->ai_flags
= ai
->ai_flags
;
224 ret
->ai_family
= ai
->ai_family
;
225 ret
->ai_socktype
= ai
->ai_socktype
;
226 ret
->ai_protocol
= ai
->ai_protocol
;
227 ret
->ai_addrlen
= ai
->ai_addrlen
;
228 ret
->ai_canonname
= NULL
;
231 if (ai
->ai_canonname
)
233 int len
= WideCharToMultiByte( CP_ACP
, 0, ai
->ai_canonname
, -1, NULL
, 0, NULL
, NULL
);
234 if (!(ret
->ai_canonname
= HeapAlloc( GetProcessHeap(), 0, len
)))
236 HeapFree( GetProcessHeap(), 0, ret
);
239 WideCharToMultiByte( CP_ACP
, 0, ai
->ai_canonname
, -1, ret
->ai_canonname
, len
, NULL
, NULL
);
243 if (!(ret
->ai_addr
= HeapAlloc( GetProcessHeap(), 0, sizeof(struct sockaddr
) )))
245 HeapFree( GetProcessHeap(), 0, ret
->ai_canonname
);
246 HeapFree( GetProcessHeap(), 0, ret
);
249 memcpy( ret
->ai_addr
, ai
->ai_addr
, sizeof(struct sockaddr
) );
254 struct getaddrinfo_args
256 OVERLAPPED
*overlapped
;
257 LPLOOKUPSERVICE_COMPLETION_ROUTINE completion_routine
;
258 ADDRINFOEXW
**result
;
261 struct addrinfo
*hints
;
264 static void WINAPI
getaddrinfo_callback(TP_CALLBACK_INSTANCE
*instance
, void *context
)
266 struct getaddrinfo_args
*args
= context
;
267 OVERLAPPED
*overlapped
= args
->overlapped
;
268 HANDLE event
= overlapped
->hEvent
;
269 LPLOOKUPSERVICE_COMPLETION_ROUTINE completion_routine
= args
->completion_routine
;
270 struct addrinfo
*res
;
273 ret
= getaddrinfo( args
->nodename
, args
->servname
, args
->hints
, &res
);
276 *args
->result
= addrinfo_list_AtoW(res
);
277 overlapped
->u
.Pointer
= args
->result
;
281 HeapFree( GetProcessHeap(), 0, args
->nodename
);
282 HeapFree( GetProcessHeap(), 0, args
->servname
);
283 HeapFree( GetProcessHeap(), 0, args
);
285 overlapped
->Internal
= ret
;
286 if (completion_routine
) completion_routine( ret
, 0, overlapped
);
287 if (event
) SetEvent( event
);
290 static int getaddrinfoW( const WCHAR
*nodename
, const WCHAR
*servname
,
291 const struct addrinfo
*hints
, ADDRINFOEXW
**res
, OVERLAPPED
*overlapped
,
292 LPLOOKUPSERVICE_COMPLETION_ROUTINE completion_routine
)
294 int ret
= EAI_MEMORY
, len
, i
;
295 char *nodenameA
= NULL
, *servnameA
= NULL
;
296 struct addrinfo
*resA
;
297 WCHAR
*local_nodenameW
= (WCHAR
*)nodename
;
302 /* Is this an IDN? Most likely if any char is above the Ascii table, this
303 * is the simplest validation possible, further validation will be done by
304 * the native getaddrinfo() */
305 for (i
= 0; nodename
[i
]; i
++)
307 if (nodename
[i
] > 'z')
312 if (hints
&& (hints
->ai_flags
& AI_DISABLE_IDN_ENCODING
))
314 /* Name requires conversion but it was disabled */
315 ret
= WSAHOST_NOT_FOUND
;
320 len
= IdnToAscii( 0, nodename
, -1, NULL
, 0 );
323 ERR("Failed to convert %s to punycode\n", debugstr_w(nodename
));
327 if (!(local_nodenameW
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) ))) goto end
;
328 IdnToAscii( 0, nodename
, -1, local_nodenameW
, len
);
333 len
= WideCharToMultiByte( CP_ACP
, 0, local_nodenameW
, -1, NULL
, 0, NULL
, NULL
);
334 if (!(nodenameA
= HeapAlloc( GetProcessHeap(), 0, len
))) goto end
;
335 WideCharToMultiByte( CP_ACP
, 0, local_nodenameW
, -1, nodenameA
, len
, NULL
, NULL
);
339 len
= WideCharToMultiByte( CP_ACP
, 0, servname
, -1, NULL
, 0, NULL
, NULL
);
340 if (!(servnameA
= HeapAlloc( GetProcessHeap(), 0, len
))) goto end
;
341 WideCharToMultiByte( CP_ACP
, 0, servname
, -1, servnameA
, len
, NULL
, NULL
);
346 struct getaddrinfo_args
*args
;
348 if (overlapped
->hEvent
&& completion_routine
)
354 if (!(args
= HeapAlloc( GetProcessHeap(), 0, sizeof(*args
) + sizeof(*args
->hints
) ))) goto end
;
355 args
->overlapped
= overlapped
;
356 args
->completion_routine
= completion_routine
;
358 args
->nodename
= nodenameA
;
359 args
->servname
= servnameA
;
362 args
->hints
= (struct addrinfo
*)(args
+ 1);
363 args
->hints
->ai_flags
= hints
->ai_flags
;
364 args
->hints
->ai_family
= hints
->ai_family
;
365 args
->hints
->ai_socktype
= hints
->ai_socktype
;
366 args
->hints
->ai_protocol
= hints
->ai_protocol
;
368 else args
->hints
= NULL
;
370 overlapped
->Internal
= WSAEINPROGRESS
;
371 if (!TrySubmitThreadpoolCallback( getaddrinfo_callback
, args
, NULL
))
373 HeapFree( GetProcessHeap(), 0, args
);
374 ret
= GetLastError();
378 if (local_nodenameW
!= nodename
)
379 HeapFree( GetProcessHeap(), 0, local_nodenameW
);
380 SetLastError( ERROR_IO_PENDING
);
381 return ERROR_IO_PENDING
;
384 ret
= getaddrinfo( nodenameA
, servnameA
, hints
, &resA
);
387 *res
= addrinfo_list_AtoW( resA
);
388 freeaddrinfo( resA
);
392 if (local_nodenameW
!= nodename
)
393 HeapFree( GetProcessHeap(), 0, local_nodenameW
);
394 HeapFree( GetProcessHeap(), 0, nodenameA
);
395 HeapFree( GetProcessHeap(), 0, servnameA
);
400 /***********************************************************************
401 * GetAddrInfoExW (ws2_32.@)
403 int WINAPI
GetAddrInfoExW( const WCHAR
*name
, const WCHAR
*servname
, DWORD
namespace,
404 GUID
*namespace_id
, const ADDRINFOEXW
*hints
, ADDRINFOEXW
**result
,
405 struct timeval
*timeout
, OVERLAPPED
*overlapped
,
406 LPLOOKUPSERVICE_COMPLETION_ROUTINE completion_routine
, HANDLE
*handle
)
410 TRACE( "name %s, servname %s, namespace %u, namespace_id %s)\n",
411 debugstr_w(name
), debugstr_w(servname
), namespace, debugstr_guid(namespace_id
) );
413 if (namespace != NS_DNS
)
414 FIXME( "Unsupported namespace %u\n", namespace );
416 FIXME( "Unsupported namespace_id %s\n", debugstr_guid(namespace_id
) );
418 FIXME( "Unsupported timeout\n" );
420 FIXME( "Unsupported cancel handle\n" );
422 ret
= getaddrinfoW( name
, servname
, (struct addrinfo
*)hints
, result
, overlapped
, completion_routine
);
424 if (handle
) *handle
= (HANDLE
)0xdeadbeef;
429 /***********************************************************************
430 * GetAddrInfoExOverlappedResult (ws2_32.@)
432 int WINAPI
GetAddrInfoExOverlappedResult( OVERLAPPED
*overlapped
)
434 TRACE( "(%p)\n", overlapped
);
435 return overlapped
->Internal
;
439 /***********************************************************************
440 * GetAddrInfoExCancel (ws2_32.@)
442 int WINAPI
GetAddrInfoExCancel( HANDLE
*handle
)
444 FIXME( "(%p)\n", handle
);
445 return WSA_INVALID_HANDLE
;
449 /***********************************************************************
450 * GetAddrInfoW (ws2_32.@)
452 int WINAPI
GetAddrInfoW(const WCHAR
*nodename
, const WCHAR
*servname
, const ADDRINFOW
*hints
, ADDRINFOW
**res
)
454 struct addrinfo
*hintsA
= NULL
;
456 int ret
= EAI_MEMORY
;
458 TRACE( "nodename %s, servname %s, hints %p, result %p\n",
459 debugstr_w(nodename
), debugstr_w(servname
), hints
, res
);
462 if (hints
) hintsA
= addrinfo_WtoA( hints
);
463 ret
= getaddrinfoW( nodename
, servname
, hintsA
, &resex
, NULL
, NULL
);
464 freeaddrinfo( hintsA
);
469 /* ADDRINFOEXW has a layout compatible with ADDRINFOW except for the
470 * ai_next field, so we may convert it in place */
471 *res
= (ADDRINFOW
*)resex
;
474 ((ADDRINFOW
*)resex
)->ai_next
= (ADDRINFOW
*)resex
->ai_next
;
475 resex
= resex
->ai_next
;
482 /***********************************************************************
483 * freeaddrinfo (ws2_32.@)
485 void WINAPI
freeaddrinfo( struct addrinfo
*info
)
487 TRACE( "%p\n", info
);
489 HeapFree( GetProcessHeap(), 0, info
);
493 /***********************************************************************
494 * FreeAddrInfoW (ws2_32.@)
496 void WINAPI
FreeAddrInfoW( ADDRINFOW
*ai
)
501 HeapFree( GetProcessHeap(), 0, ai
->ai_canonname
);
502 HeapFree( GetProcessHeap(), 0, ai
->ai_addr
);
504 HeapFree( GetProcessHeap(), 0, ai
);
510 /***********************************************************************
511 * FreeAddrInfoEx (ws2_32.@)
513 void WINAPI
FreeAddrInfoEx( ADDRINFOEXA
*ai
)
515 TRACE( "(%p)\n", ai
);
520 HeapFree( GetProcessHeap(), 0, ai
->ai_canonname
);
521 HeapFree( GetProcessHeap(), 0, ai
->ai_addr
);
523 HeapFree( GetProcessHeap(), 0, ai
);
529 /***********************************************************************
530 * FreeAddrInfoExW (ws2_32.@)
532 void WINAPI
FreeAddrInfoExW( ADDRINFOEXW
*ai
)
534 TRACE( "(%p)\n", ai
);
539 HeapFree( GetProcessHeap(), 0, ai
->ai_canonname
);
540 HeapFree( GetProcessHeap(), 0, ai
->ai_addr
);
542 HeapFree( GetProcessHeap(), 0, ai
);
548 /***********************************************************************
549 * getnameinfo (ws2_32.@)
551 int WINAPI
getnameinfo( const SOCKADDR
*addr
, socklen_t addr_len
, char *host
,
552 DWORD host_len
, char *serv
, DWORD serv_len
, int flags
)
554 TRACE( "addr %s, addr_len %d, host %p, host_len %u, serv %p, serv_len %d, flags %#x\n",
555 debugstr_sockaddr(addr
), addr_len
, host
, host_len
, serv
, serv_len
, flags
);
557 return unix_funcs
->getnameinfo( addr
, addr_len
, host
, host_len
, serv
, serv_len
, flags
);
561 /***********************************************************************
562 * GetNameInfoW (ws2_32.@)
564 int WINAPI
GetNameInfoW( const SOCKADDR
*addr
, socklen_t addr_len
, WCHAR
*host
,
565 DWORD host_len
, WCHAR
*serv
, DWORD serv_len
, int flags
)
568 char *hostA
= NULL
, *servA
= NULL
;
570 if (host
&& (!(hostA
= HeapAlloc( GetProcessHeap(), 0, host_len
))))
572 if (serv
&& (!(servA
= HeapAlloc( GetProcessHeap(), 0, serv_len
))))
574 HeapFree( GetProcessHeap(), 0, hostA
);
578 ret
= getnameinfo( addr
, addr_len
, hostA
, host_len
, servA
, serv_len
, flags
);
581 if (host
) MultiByteToWideChar( CP_ACP
, 0, hostA
, -1, host
, host_len
);
582 if (serv
) MultiByteToWideChar( CP_ACP
, 0, servA
, -1, serv
, serv_len
);
585 HeapFree( GetProcessHeap(), 0, hostA
);
586 HeapFree( GetProcessHeap(), 0, servA
);
591 static struct hostent
*get_hostent_buffer( unsigned int size
)
593 struct per_thread_data
*data
= get_per_thread_data();
596 if (data
->he_len
>= size
) return data
->he_buffer
;
597 HeapFree( GetProcessHeap(), 0, data
->he_buffer
);
599 data
->he_buffer
= HeapAlloc( GetProcessHeap(), 0, (data
->he_len
= size
) );
600 if (!data
->he_buffer
) SetLastError(WSAENOBUFS
);
601 return data
->he_buffer
;
604 /* create a hostent entry
606 * Creates the entry with enough memory for the name, aliases
607 * addresses, and the address pointers. Also copies the name
608 * and sets up all the pointers.
610 * NOTE: The alias and address lists must be allocated with room
611 * for the NULL item terminating the list. This is true even if
612 * the list has no items ("aliases" and "addresses" must be
613 * at least "1", a truly empty list is invalid).
615 static struct hostent
*create_hostent( char *name
, int alias_count
, int aliases_size
,
616 int address_count
, int address_length
)
618 struct hostent
*p_to
;
620 unsigned int size
= sizeof(struct hostent
), i
;
622 size
+= strlen(name
) + 1;
623 size
+= alias_count
* sizeof(char *);
624 size
+= aliases_size
;
625 size
+= address_count
* sizeof(char *);
626 size
+= (address_count
- 1) * address_length
;
628 if (!(p_to
= get_hostent_buffer( size
))) return NULL
;
629 memset( p_to
, 0, size
);
631 /* Use the memory in the same way winsock does.
632 * First set the pointer for aliases, second set the pointers for addresses.
633 * Third fill the addresses indexes, fourth jump aliases names size.
634 * Fifth fill the hostname.
635 * NOTE: This method is valid for OS versions >= XP.
637 p
= (char *)(p_to
+ 1);
638 p_to
->h_aliases
= (char **)p
;
639 p
+= alias_count
* sizeof(char *);
641 p_to
->h_addr_list
= (char **)p
;
642 p
+= address_count
* sizeof(char *);
644 for (i
= 0, address_count
--; i
< address_count
; i
++, p
+= address_length
)
645 p_to
->h_addr_list
[i
] = p
;
647 /* h_aliases must be filled in manually because we don't know each string
648 * size. Leave these pointers NULL (already set to NULL by memset earlier).
659 /***********************************************************************
660 * gethostbyaddr (ws2_32.51)
662 struct hostent
* WINAPI
gethostbyaddr( const char *addr
, int len
, int family
)
664 unsigned int size
= 1024;
665 struct hostent
*host
;
668 if (!(host
= get_hostent_buffer( size
)))
671 while ((ret
= unix_funcs
->gethostbyaddr( addr
, len
, family
, host
, &size
)) == ERROR_INSUFFICIENT_BUFFER
)
673 if (!(host
= get_hostent_buffer( size
)))
678 return ret
? NULL
: host
;
686 DWORD metric
, default_route
;
689 static int __cdecl
compare_routes_by_metric_asc( const void *left
, const void *right
)
691 const struct route
*a
= left
, *b
= right
;
692 if (a
->default_route
&& b
->default_route
)
693 return a
->default_route
- b
->default_route
;
694 if (a
->default_route
&& !b
->default_route
)
696 if (b
->default_route
&& !a
->default_route
)
698 return a
->metric
- b
->metric
;
701 /* Returns the list of local IP addresses by going through the network
702 * adapters and using the local routing table to sort the addresses
703 * from highest routing priority to lowest routing priority. This
704 * functionality is inferred from the description for obtaining local
705 * IP addresses given in the Knowledge Base Article Q160215.
707 * Please note that the returned hostent is only freed when the thread
708 * closes and is replaced if another hostent is requested.
710 static struct hostent
*get_local_ips( char *hostname
)
712 int numroutes
= 0, i
, j
, default_routes
= 0;
713 IP_ADAPTER_INFO
*adapters
= NULL
, *k
;
714 struct hostent
*hostlist
= NULL
;
715 MIB_IPFORWARDTABLE
*routes
= NULL
;
716 struct route
*route_addrs
= NULL
;
717 DWORD adap_size
, route_size
, n
;
719 /* Obtain the size of the adapter list and routing table, also allocate memory */
720 if (GetAdaptersInfo( NULL
, &adap_size
) != ERROR_BUFFER_OVERFLOW
)
722 if (GetIpForwardTable( NULL
, &route_size
, FALSE
) != ERROR_INSUFFICIENT_BUFFER
)
725 adapters
= HeapAlloc( GetProcessHeap(), 0, adap_size
);
726 routes
= HeapAlloc( GetProcessHeap(), 0, route_size
);
727 if (!adapters
|| !routes
)
730 /* Obtain the adapter list and the full routing table */
731 if (GetAdaptersInfo( adapters
, &adap_size
) != NO_ERROR
)
733 if (GetIpForwardTable( routes
, &route_size
, FALSE
) != NO_ERROR
)
736 /* Store the interface associated with each route */
737 for (n
= 0; n
< routes
->dwNumEntries
; n
++)
740 DWORD ifmetric
, ifdefault
= 0;
743 /* Check if this is a default route (there may be more than one) */
744 if (!routes
->table
[n
].dwForwardDest
)
745 ifdefault
= ++default_routes
;
746 else if (routes
->table
[n
].u1
.ForwardType
!= MIB_IPROUTE_TYPE_DIRECT
)
748 ifindex
= routes
->table
[n
].dwForwardIfIndex
;
749 ifmetric
= routes
->table
[n
].dwForwardMetric1
;
750 /* Only store the lowest valued metric for an interface */
751 for (j
= 0; j
< numroutes
; j
++)
753 if (route_addrs
[j
].interface
== ifindex
)
755 if (route_addrs
[j
].metric
> ifmetric
)
756 route_addrs
[j
].metric
= ifmetric
;
762 route_addrs
= heap_realloc( route_addrs
, (numroutes
+ 1) * sizeof(struct route
) );
765 route_addrs
[numroutes
].interface
= ifindex
;
766 route_addrs
[numroutes
].metric
= ifmetric
;
767 route_addrs
[numroutes
].default_route
= ifdefault
;
768 /* If no IP is found in the next step (for whatever reason)
769 * then fall back to the magic loopback address.
771 memcpy( &route_addrs
[numroutes
].addr
.s_addr
, magic_loopback_addr
, 4 );
775 goto cleanup
; /* No routes, fall back to the Magic IP */
777 /* Find the IP address associated with each found interface */
778 for (i
= 0; i
< numroutes
; i
++)
780 for (k
= adapters
; k
!= NULL
; k
= k
->Next
)
782 char *ip
= k
->IpAddressList
.IpAddress
.String
;
784 if (route_addrs
[i
].interface
== k
->Index
)
785 route_addrs
[i
].addr
.s_addr
= inet_addr(ip
);
789 /* Allocate a hostent and enough memory for all the IPs,
790 * including the NULL at the end of the list.
792 hostlist
= create_hostent( hostname
, 1, 0, numroutes
+1, sizeof(struct in_addr
) );
793 if (hostlist
== NULL
)
795 hostlist
->h_addr_list
[numroutes
] = NULL
;
796 hostlist
->h_aliases
[0] = NULL
;
797 hostlist
->h_addrtype
= AF_INET
;
798 hostlist
->h_length
= sizeof(struct in_addr
);
800 /* Reorder the entries before placing them in the host list. Windows expects
801 * the IP list in order from highest priority to lowest (the critical thing
802 * is that most applications expect the first IP to be the default route).
805 qsort( route_addrs
, numroutes
, sizeof(struct route
), compare_routes_by_metric_asc
);
807 for (i
= 0; i
< numroutes
; i
++)
808 *(struct in_addr
*)hostlist
->h_addr_list
[i
] = route_addrs
[i
].addr
;
811 HeapFree( GetProcessHeap(), 0, route_addrs
);
812 HeapFree( GetProcessHeap(), 0, adapters
);
813 HeapFree( GetProcessHeap(), 0, routes
);
818 /***********************************************************************
819 * gethostbyname (ws2_32.52)
821 struct hostent
* WINAPI
gethostbyname( const char *name
)
823 struct hostent
*host
= NULL
;
827 TRACE( "%s\n", debugstr_a(name
) );
831 SetLastError( WSANOTINITIALISED
);
835 if ((ret
= unix_funcs
->gethostname( hostname
, 100 )))
841 if (!name
|| !name
[0])
844 /* If the hostname of the local machine is requested then return the
845 * complete list of local IP addresses */
846 if (!strcmp( name
, hostname
))
847 host
= get_local_ips( hostname
);
849 /* If any other hostname was requested (or the routing table lookup failed)
850 * then return the IP found by the host OS */
853 unsigned int size
= 1024;
856 if (!(host
= get_hostent_buffer( size
)))
859 while ((ret
= unix_funcs
->gethostbyname( name
, host
, &size
)) == ERROR_INSUFFICIENT_BUFFER
)
861 if (!(host
= get_hostent_buffer( size
)))
866 return ret
? NULL
: host
;
869 if (host
&& host
->h_addr_list
[0][0] == 127 && strcmp( name
, "localhost" ))
871 /* hostname != "localhost" but has loopback address. replace by our
873 memcpy( host
->h_addr_list
[0], magic_loopback_addr
, 4 );
880 /***********************************************************************
881 * gethostname (ws2_32.57)
883 int WINAPI
gethostname( char *name
, int namelen
)
888 TRACE( "name %p, len %d\n", name
, namelen
);
892 SetLastError( WSAEFAULT
);
896 if ((ret
= unix_funcs
->gethostname( buf
, sizeof(buf
) )))
902 TRACE( "<- %s\n", debugstr_a(buf
) );
905 WARN( "Windows supports NetBIOS name length up to 15 bytes!\n" );
908 SetLastError( WSAEFAULT
);
916 /***********************************************************************
917 * GetHostNameW (ws2_32.@)
919 int WINAPI
GetHostNameW( WCHAR
*name
, int namelen
)
924 TRACE( "name %p, len %d\n", name
, namelen
);
928 SetLastError( WSAEFAULT
);
932 if ((ret
= unix_funcs
->gethostname( buf
, sizeof(buf
) )))
938 if (MultiByteToWideChar( CP_ACP
, 0, buf
, -1, NULL
, 0 ) > namelen
)
940 SetLastError( WSAEFAULT
);
943 MultiByteToWideChar( CP_ACP
, 0, buf
, -1, name
, namelen
);
948 static char *read_etc_file( const WCHAR
*filename
, DWORD
*ret_size
)
950 WCHAR path
[MAX_PATH
];
951 DWORD size
= sizeof(path
);
956 if ((ret
= RegGetValueW( HKEY_LOCAL_MACHINE
, L
"System\\CurrentControlSet\\Services\\tcpip\\Parameters",
957 L
"DatabasePath", RRF_RT_REG_SZ
, NULL
, path
, &size
)))
959 ERR( "failed to get database path, error %u\n", ret
);
962 wcscat( path
, L
"\\" );
963 wcscat( path
, filename
);
965 file
= CreateFileW( path
, GENERIC_READ
, FILE_SHARE_READ
, NULL
, OPEN_EXISTING
, 0, NULL
);
966 if (file
== INVALID_HANDLE_VALUE
)
968 ERR( "failed to open %s, error %u\n", debugstr_w( path
), GetLastError() );
972 size
= GetFileSize( file
, NULL
);
973 if (!(data
= HeapAlloc( GetProcessHeap(), 0, size
)) ||
974 !ReadFile( file
, data
, size
, ret_size
, NULL
))
976 WARN( "failed to read file, error %u\n", GetLastError() );
977 HeapFree( GetProcessHeap(), 0, data
);
984 /* returns "end" if there was no space */
985 static char *next_space( const char *p
, const char *end
)
987 while (p
< end
&& !isspace( *p
))
992 /* returns "end" if there was no non-space */
993 static char *next_non_space( const char *p
, const char *end
)
995 while (p
< end
&& isspace( *p
))
1001 static struct protoent
*get_protoent_buffer( unsigned int size
)
1003 struct per_thread_data
*data
= get_per_thread_data();
1005 if (data
->pe_buffer
)
1007 if (data
->pe_len
>= size
) return data
->pe_buffer
;
1008 HeapFree( GetProcessHeap(), 0, data
->pe_buffer
);
1010 data
->pe_len
= size
;
1011 data
->pe_buffer
= HeapAlloc( GetProcessHeap(), 0, size
);
1012 if (!data
->pe_buffer
) SetLastError( WSAENOBUFS
);
1013 return data
->pe_buffer
;
1016 /* Parse the first valid line into a protoent structure, returning NULL if
1017 * there is no valid line. Updates cursor to point to the start of the next
1018 * line or the end of the file. */
1019 static struct protoent
*get_next_protocol( const char **cursor
, const char *end
)
1021 const char *p
= *cursor
;
1025 const char *line_end
, *next_line
;
1026 size_t needed_size
, line_len
;
1027 unsigned int alias_count
= 0;
1028 struct protoent
*proto
;
1033 for (line_end
= p
; line_end
< end
&& *line_end
!= '\n' && *line_end
!= '#'; ++line_end
)
1035 TRACE( "parsing line %s\n", debugstr_an(p
, line_end
- p
) );
1037 for (next_line
= line_end
; next_line
< end
&& *next_line
!= '\n'; ++next_line
)
1039 if (next_line
< end
)
1040 ++next_line
; /* skip over the newline */
1042 p
= next_non_space( p
, line_end
);
1049 /* parse the name */
1052 line_len
= line_end
- name
;
1054 p
= next_space( p
, line_end
);
1061 p
= next_non_space( p
, line_end
);
1063 /* parse the number */
1067 p
= next_space( p
, line_end
);
1068 p
= next_non_space( p
, line_end
);
1070 /* we will copy the entire line after the protoent structure, then
1071 * replace spaces with null bytes as necessary */
1073 while (p
< line_end
)
1077 p
= next_space( p
, line_end
);
1078 p
= next_non_space( p
, line_end
);
1080 needed_size
= sizeof(*proto
) + line_len
+ 1 + (alias_count
+ 1) * sizeof(char *);
1082 if (!(proto
= get_protoent_buffer( needed_size
)))
1084 SetLastError( WSAENOBUFS
);
1088 proto
->p_proto
= number
;
1089 proto
->p_aliases
= (char **)(proto
+ 1);
1090 proto
->p_name
= (char *)(proto
->p_aliases
+ alias_count
+ 1);
1092 memcpy( proto
->p_name
, name
, line_len
);
1093 proto
->p_name
[line_len
] = 0;
1095 line_end
= proto
->p_name
+ line_len
;
1098 q
= next_space( q
, line_end
);
1100 q
= next_non_space( q
, line_end
);
1101 /* skip over the number */
1102 q
= next_space( q
, line_end
);
1103 q
= next_non_space( q
, line_end
);
1106 while (q
< line_end
)
1108 proto
->p_aliases
[alias_count
++] = q
;
1109 q
= next_space( q
, line_end
);
1110 if (q
< line_end
) *q
++ = 0;
1111 q
= next_non_space( q
, line_end
);
1113 proto
->p_aliases
[alias_count
] = NULL
;
1115 *cursor
= next_line
;
1119 SetLastError( WSANO_DATA
);
1124 /***********************************************************************
1125 * getprotobyname (ws2_32.53)
1127 struct protoent
* WINAPI
getprotobyname( const char *name
)
1129 struct protoent
*proto
;
1134 TRACE( "%s\n", debugstr_a(name
) );
1136 if (!(file
= read_etc_file( L
"protocol", &size
)))
1138 SetLastError( WSANO_DATA
);
1143 while ((proto
= get_next_protocol( &cursor
, file
+ size
)))
1145 if (!strcasecmp( proto
->p_name
, name
))
1149 HeapFree( GetProcessHeap(), 0, file
);
1154 /***********************************************************************
1155 * getprotobynumber (ws2_32.54)
1157 struct protoent
* WINAPI
getprotobynumber( int number
)
1159 struct protoent
*proto
;
1164 TRACE( "%d\n", number
);
1166 if (!(file
= read_etc_file( L
"protocol", &size
)))
1168 SetLastError( WSANO_DATA
);
1173 while ((proto
= get_next_protocol( &cursor
, file
+ size
)))
1175 if (proto
->p_proto
== number
)
1179 HeapFree( GetProcessHeap(), 0, file
);
1184 static struct servent
*get_servent_buffer( int size
)
1186 struct per_thread_data
*data
= get_per_thread_data();
1187 if (data
->se_buffer
)
1189 if (data
->se_len
>= size
) return data
->se_buffer
;
1190 HeapFree( GetProcessHeap(), 0, data
->se_buffer
);
1192 data
->se_len
= size
;
1193 data
->se_buffer
= HeapAlloc( GetProcessHeap(), 0, size
);
1194 if (!data
->se_buffer
) SetLastError( WSAENOBUFS
);
1195 return data
->se_buffer
;
1198 /* Parse the first valid line into a servent structure, returning NULL if
1199 * there is no valid line. Updates cursor to point to the start of the next
1200 * line or the end of the file. */
1201 static struct servent
*get_next_service( const char **cursor
, const char *end
)
1203 const char *p
= *cursor
;
1207 const char *line_end
, *next_line
;
1208 size_t needed_size
, line_len
;
1209 unsigned int alias_count
= 0;
1210 struct servent
*serv
;
1215 for (line_end
= p
; line_end
< end
&& *line_end
!= '\n' && *line_end
!= '#'; ++line_end
)
1217 TRACE( "parsing line %s\n", debugstr_an(p
, line_end
- p
) );
1219 for (next_line
= line_end
; next_line
< end
&& *next_line
!= '\n'; ++next_line
)
1221 if (next_line
< end
)
1222 ++next_line
; /* skip over the newline */
1224 p
= next_non_space( p
, line_end
);
1231 /* parse the name */
1234 line_len
= line_end
- name
;
1236 p
= next_space( p
, line_end
);
1243 p
= next_non_space( p
, line_end
);
1245 /* parse the port */
1248 p
= memchr( p
, '/', line_end
- p
);
1255 p
= next_space( p
, line_end
);
1256 p
= next_non_space( p
, line_end
);
1258 /* we will copy the entire line after the servent structure, then
1259 * replace spaces with null bytes as necessary */
1261 while (p
< line_end
)
1265 p
= next_space( p
, line_end
);
1266 p
= next_non_space( p
, line_end
);
1268 needed_size
= sizeof(*serv
) + line_len
+ 1 + (alias_count
+ 1) * sizeof(char *);
1270 if (!(serv
= get_servent_buffer( needed_size
)))
1272 SetLastError( WSAENOBUFS
);
1276 serv
->s_port
= htons( port
);
1277 serv
->s_aliases
= (char **)(serv
+ 1);
1278 serv
->s_name
= (char *)(serv
->s_aliases
+ alias_count
+ 1);
1280 memcpy( serv
->s_name
, name
, line_len
);
1281 serv
->s_name
[line_len
] = 0;
1283 line_end
= serv
->s_name
+ line_len
;
1286 q
= next_space( q
, line_end
);
1288 q
= next_non_space( q
, line_end
);
1289 /* skip over the number */
1290 q
= memchr( q
, '/', line_end
- q
);
1291 serv
->s_proto
= ++q
;
1292 q
= next_space( q
, line_end
);
1293 if (q
< line_end
) *q
++ = 0;
1294 q
= next_non_space( q
, line_end
);
1297 while (q
< line_end
)
1299 serv
->s_aliases
[alias_count
++] = q
;
1300 q
= next_space( q
, line_end
);
1301 if (q
< line_end
) *q
++ = 0;
1302 q
= next_non_space( q
, line_end
);
1304 serv
->s_aliases
[alias_count
] = NULL
;
1306 *cursor
= next_line
;
1310 SetLastError( WSANO_DATA
);
1315 /***********************************************************************
1316 * getservbyname (ws2_32.55)
1318 struct servent
* WINAPI
getservbyname( const char *name
, const char *proto
)
1320 struct servent
*serv
;
1325 TRACE( "name %s, proto %s\n", debugstr_a(name
), debugstr_a(proto
) );
1327 if (!(file
= read_etc_file( L
"services", &size
)))
1329 SetLastError( WSANO_DATA
);
1334 while ((serv
= get_next_service( &cursor
, file
+ size
)))
1336 if (!strcasecmp( serv
->s_name
, name
) && (!proto
|| !strcasecmp( serv
->s_proto
, proto
)))
1340 HeapFree( GetProcessHeap(), 0, file
);
1345 /***********************************************************************
1346 * getservbyport (ws2_32.56)
1348 struct servent
* WINAPI
getservbyport( int port
, const char *proto
)
1350 struct servent
*serv
;
1355 TRACE( "port %d, proto %s\n", port
, debugstr_a(proto
) );
1357 if (!(file
= read_etc_file( L
"services", &size
)))
1359 SetLastError( WSANO_DATA
);
1364 while ((serv
= get_next_service( &cursor
, file
+ size
)))
1366 if (serv
->s_port
== port
&& (!proto
|| !strcasecmp( serv
->s_proto
, proto
)))
1370 HeapFree( GetProcessHeap(), 0, file
);
1375 /***********************************************************************
1376 * inet_ntoa (ws2_32.12)
1378 char * WINAPI
inet_ntoa( struct in_addr in
)
1380 unsigned int long_ip
= ntohl( in
.s_addr
);
1381 struct per_thread_data
*data
= get_per_thread_data();
1383 sprintf( data
->ntoa_buffer
, "%u.%u.%u.%u",
1384 (long_ip
>> 24) & 0xff,
1385 (long_ip
>> 16) & 0xff,
1386 (long_ip
>> 8) & 0xff,
1389 return data
->ntoa_buffer
;
1393 /***********************************************************************
1394 * inet_ntop (ws2_32.@)
1396 const char * WINAPI
inet_ntop( int family
, void *addr
, char *buffer
, SIZE_T len
)
1399 ULONG size
= min( len
, (ULONG
)-1 );
1401 TRACE( "family %d, addr %p, buffer %p, len %ld\n", family
, addr
, buffer
, len
);
1404 SetLastError( STATUS_INVALID_PARAMETER
);
1412 status
= RtlIpv4AddressToStringExA( (IN_ADDR
*)addr
, 0, buffer
, &size
);
1417 status
= RtlIpv6AddressToStringExA( (IN6_ADDR
*)addr
, 0, 0, buffer
, &size
);
1421 SetLastError( WSAEAFNOSUPPORT
);
1425 if (status
== STATUS_SUCCESS
) return buffer
;
1426 SetLastError( STATUS_INVALID_PARAMETER
);
1430 /***********************************************************************
1431 * inet_pton (ws2_32.@)
1433 int WINAPI
inet_pton( int family
, const char *addr
, void *buffer
)
1436 const char *terminator
;
1438 TRACE( "family %d, addr %s, buffer %p\n", family
, debugstr_a(addr
), buffer
);
1440 if (!addr
|| !buffer
)
1442 SetLastError( WSAEFAULT
);
1449 status
= RtlIpv4StringToAddressA(addr
, TRUE
, &terminator
, buffer
);
1452 status
= RtlIpv6StringToAddressA(addr
, &terminator
, buffer
);
1455 SetLastError( WSAEAFNOSUPPORT
);
1459 return (status
== STATUS_SUCCESS
&& *terminator
== 0);
1462 /***********************************************************************
1463 * InetPtonW (ws2_32.@)
1465 int WINAPI
InetPtonW( int family
, const WCHAR
*addr
, void *buffer
)
1471 TRACE( "family %d, addr %s, buffer %p\n", family
, debugstr_w(addr
), buffer
);
1475 SetLastError(WSAEFAULT
);
1476 return SOCKET_ERROR
;
1479 len
= WideCharToMultiByte( CP_ACP
, 0, addr
, -1, NULL
, 0, NULL
, NULL
);
1480 if (!(addrA
= HeapAlloc( GetProcessHeap(), 0, len
)))
1482 SetLastError( WSA_NOT_ENOUGH_MEMORY
);
1485 WideCharToMultiByte( CP_ACP
, 0, addr
, -1, addrA
, len
, NULL
, NULL
);
1487 ret
= inet_pton( family
, addrA
, buffer
);
1488 if (!ret
) SetLastError( WSAEINVAL
);
1490 HeapFree( GetProcessHeap(), 0, addrA
);
1494 /***********************************************************************
1495 * InetNtopW (ws2_32.@)
1497 const WCHAR
* WINAPI
InetNtopW( int family
, void *addr
, WCHAR
*buffer
, SIZE_T len
)
1499 char bufferA
[INET6_ADDRSTRLEN
];
1502 TRACE( "family %d, addr %p, buffer %p, len %ld\n", family
, addr
, buffer
, len
);
1504 if (inet_ntop( family
, addr
, bufferA
, sizeof(bufferA
) ))
1506 if (MultiByteToWideChar( CP_ACP
, 0, bufferA
, -1, buffer
, len
))
1509 SetLastError( ERROR_INVALID_PARAMETER
);
1515 /***********************************************************************
1516 * WSAStringToAddressA (ws2_32.@)
1518 int WINAPI
WSAStringToAddressA( char *string
, int family
, WSAPROTOCOL_INFOA
*protocol_info
,
1519 struct sockaddr
*addr
, int *addr_len
)
1523 TRACE( "string %s, family %u\n", debugstr_a(string
), family
);
1525 if (!addr
|| !addr_len
) return -1;
1529 SetLastError( WSAEINVAL
);
1534 FIXME( "ignoring protocol_info\n" );
1540 struct sockaddr_in
*addr4
= (struct sockaddr_in
*)addr
;
1542 if (*addr_len
< sizeof(struct sockaddr_in
))
1544 *addr_len
= sizeof(struct sockaddr_in
);
1545 SetLastError( WSAEFAULT
);
1548 memset( addr
, 0, sizeof(struct sockaddr_in
) );
1550 status
= RtlIpv4StringToAddressExA( string
, FALSE
, &addr4
->sin_addr
, &addr4
->sin_port
);
1551 if (status
!= STATUS_SUCCESS
)
1553 SetLastError( WSAEINVAL
);
1556 addr4
->sin_family
= AF_INET
;
1557 *addr_len
= sizeof(struct sockaddr_in
);
1562 struct sockaddr_in6
*addr6
= (struct sockaddr_in6
*)addr
;
1564 if (*addr_len
< sizeof(struct sockaddr_in6
))
1566 *addr_len
= sizeof(struct sockaddr_in6
);
1567 SetLastError( WSAEFAULT
);
1570 memset( addr
, 0, sizeof(struct sockaddr_in6
) );
1572 status
= RtlIpv6StringToAddressExA( string
, &addr6
->sin6_addr
, &addr6
->sin6_scope_id
, &addr6
->sin6_port
);
1573 if (status
!= STATUS_SUCCESS
)
1575 SetLastError( WSAEINVAL
);
1578 addr6
->sin6_family
= AF_INET6
;
1579 *addr_len
= sizeof(struct sockaddr_in6
);
1583 /* According to MSDN, only AF_INET and AF_INET6 are supported. */
1584 TRACE( "Unsupported address family specified: %d.\n", family
);
1585 SetLastError( WSAEINVAL
);
1591 /***********************************************************************
1592 * WSAStringToAddressW (ws2_32.@)
1594 int WINAPI
WSAStringToAddressW( WCHAR
*string
, int family
, WSAPROTOCOL_INFOW
*protocol_info
,
1595 struct sockaddr
*addr
, int *addr_len
)
1597 WSAPROTOCOL_INFOA infoA
;
1598 WSAPROTOCOL_INFOA
*protocol_infoA
= NULL
;
1602 TRACE( "string %s, family %u\n", debugstr_w(string
), family
);
1604 if (!addr
|| !addr_len
) return -1;
1608 protocol_infoA
= &infoA
;
1609 memcpy( protocol_infoA
, protocol_info
, FIELD_OFFSET( WSAPROTOCOL_INFOA
, szProtocol
) );
1611 if (!WideCharToMultiByte( CP_ACP
, 0, protocol_info
->szProtocol
, -1, protocol_infoA
->szProtocol
,
1612 sizeof(protocol_infoA
->szProtocol
), NULL
, NULL
))
1614 SetLastError( WSAEINVAL
);
1621 SetLastError( WSAEINVAL
);
1625 sizeA
= WideCharToMultiByte( CP_ACP
, 0, string
, -1, NULL
, 0, NULL
, NULL
);
1626 if (!(stringA
= HeapAlloc( GetProcessHeap(), 0, sizeA
)))
1628 SetLastError( WSA_NOT_ENOUGH_MEMORY
);
1631 WideCharToMultiByte( CP_ACP
, 0, string
, -1, stringA
, sizeA
, NULL
, NULL
);
1632 ret
= WSAStringToAddressA( stringA
, family
, protocol_infoA
, addr
, addr_len
);
1633 HeapFree( GetProcessHeap(), 0, stringA
);
1638 /***********************************************************************
1639 * WSAAddressToStringA (ws2_32.@)
1641 int WINAPI
WSAAddressToStringA( struct sockaddr
*addr
, DWORD addr_len
,
1642 WSAPROTOCOL_INFOA
*info
, char *string
, DWORD
*string_len
)
1644 char buffer
[54]; /* 32 digits + 7':' + '[' + '%" + 5 digits + ']:' + 5 digits + '\0' */
1647 TRACE( "addr %s\n", debugstr_sockaddr(addr
) );
1649 if (!addr
) return SOCKET_ERROR
;
1650 if (!string
|| !string_len
) return SOCKET_ERROR
;
1652 switch (addr
->sa_family
)
1656 const struct sockaddr_in
*addr4
= (const struct sockaddr_in
*)addr
;
1657 unsigned int long_ip
= ntohl( addr4
->sin_addr
.s_addr
);
1660 if (addr_len
< sizeof(struct sockaddr_in
)) return -1;
1661 sprintf( buffer
, "%u.%u.%u.%u:%u",
1662 (long_ip
>> 24) & 0xff,
1663 (long_ip
>> 16) & 0xff,
1664 (long_ip
>> 8) & 0xff,
1666 ntohs( addr4
->sin_port
) );
1668 p
= strchr( buffer
, ':' );
1669 if (!addr4
->sin_port
) *p
= 0;
1674 struct sockaddr_in6
*addr6
= (struct sockaddr_in6
*)addr
;
1678 if (addr_len
< sizeof(struct sockaddr_in6
)) return -1;
1679 if (addr6
->sin6_port
)
1680 strcpy( buffer
, "[" );
1681 len
= strlen( buffer
);
1682 if (!inet_ntop( AF_INET6
, &addr6
->sin6_addr
, &buffer
[len
], sizeof(buffer
) - len
))
1684 SetLastError( WSAEINVAL
);
1687 if (addr6
->sin6_scope_id
)
1688 sprintf( buffer
+ strlen( buffer
), "%%%u", addr6
->sin6_scope_id
);
1689 if (addr6
->sin6_port
)
1690 sprintf( buffer
+ strlen( buffer
), "]:%u", ntohs( addr6
->sin6_port
) );
1695 SetLastError( WSAEINVAL
);
1699 size
= strlen( buffer
) + 1;
1701 if (*string_len
< size
)
1704 SetLastError( WSAEFAULT
);
1708 TRACE( "=> %s, %u bytes\n", debugstr_a(buffer
), size
);
1710 strcpy( string
, buffer
);
1715 /***********************************************************************
1716 * WSAAddressToStringW (ws2_32.@)
1718 int WINAPI
WSAAddressToStringW( struct sockaddr
*addr
, DWORD addr_len
,
1719 WSAPROTOCOL_INFOW
*info
, WCHAR
*string
, DWORD
*string_len
)
1722 char buf
[54]; /* 32 digits + 7':' + '[' + '%" + 5 digits + ']:' + 5 digits + '\0' */
1724 TRACE( "(%p, %d, %p, %p, %p)\n", addr
, addr_len
, info
, string
, string_len
);
1726 if ((ret
= WSAAddressToStringA( addr
, addr_len
, NULL
, buf
, string_len
))) return ret
;
1728 MultiByteToWideChar( CP_ACP
, 0, buf
, *string_len
, string
, *string_len
);
1729 TRACE( "=> %s, %u chars\n", debugstr_w(string
), *string_len
);
1734 /***********************************************************************
1735 * inet_addr (ws2_32.11)
1737 u_long WINAPI
inet_addr( const char *str
)
1741 if (inet_pton( AF_INET
, str
, &addr
) == 1)
1747 /***********************************************************************
1750 u_long WINAPI
WS_htonl( u_long hostlong
)
1752 return htonl( hostlong
);
1756 /***********************************************************************
1759 u_short WINAPI
WS_htons( u_short hostshort
)
1761 return htons( hostshort
);
1765 /***********************************************************************
1766 * WSAHtonl (ws2_32.@)
1768 int WINAPI
WSAHtonl( SOCKET s
, u_long hostlong
, u_long
*netlong
)
1772 *netlong
= htonl( hostlong
);
1775 SetLastError( WSAEFAULT
);
1780 /***********************************************************************
1781 * WSAHtons (ws2_32.@)
1783 int WINAPI
WSAHtons( SOCKET s
, u_short hostshort
, u_short
*netshort
)
1787 *netshort
= htons( hostshort
);
1790 SetLastError( WSAEFAULT
);
1795 /***********************************************************************
1798 u_long WINAPI
WS_ntohl( u_long netlong
)
1800 return ntohl( netlong
);
1804 /***********************************************************************
1807 u_short WINAPI
WS_ntohs( u_short netshort
)
1809 return ntohs( netshort
);
1813 /***********************************************************************
1814 * WSANtohl (ws2_32.@)
1816 int WINAPI
WSANtohl( SOCKET s
, u_long netlong
, u_long
*hostlong
)
1818 if (!hostlong
) return WSAEFAULT
;
1820 *hostlong
= ntohl( netlong
);
1825 /***********************************************************************
1826 * WSANtohs (ws2_32.@)
1828 int WINAPI
WSANtohs( SOCKET s
, u_short netshort
, u_short
*hostshort
)
1830 if (!hostshort
) return WSAEFAULT
;
1832 *hostshort
= ntohs( netshort
);
1837 /***********************************************************************
1838 * WSAInstallServiceClassA (ws2_32.@)
1840 int WINAPI
WSAInstallServiceClassA( WSASERVICECLASSINFOA
*info
)
1842 FIXME( "Request to install service %s\n", debugstr_a(info
->lpszServiceClassName
) );
1843 SetLastError( WSAEACCES
);
1848 /***********************************************************************
1849 * WSAInstallServiceClassW (ws2_32.@)
1851 int WINAPI
WSAInstallServiceClassW( WSASERVICECLASSINFOW
*info
)
1853 FIXME( "Request to install service %s\n", debugstr_w(info
->lpszServiceClassName
) );
1854 SetLastError( WSAEACCES
);
1859 /***********************************************************************
1860 * WSARemoveServiceClass (ws2_32.@)
1862 int WINAPI
WSARemoveServiceClass( GUID
*info
)
1864 FIXME( "Request to remove service %s\n", debugstr_guid(info
) );
1865 SetLastError( WSATYPE_NOT_FOUND
);
1870 /***********************************************************************
1871 * WSAGetServiceClassInfoA (ws2_32.@)
1873 int WINAPI
WSAGetServiceClassInfoA( GUID
*provider
, GUID
*service
, DWORD
*len
,
1874 WSASERVICECLASSINFOA
*info
)
1876 FIXME( "(%s %s %p %p) Stub!\n", debugstr_guid(provider
), debugstr_guid(service
), len
, info
);
1877 SetLastError( WSA_NOT_ENOUGH_MEMORY
);
1882 /***********************************************************************
1883 * WSAGetServiceClassInfoW (ws2_32.@)
1885 int WINAPI
WSAGetServiceClassInfoW( GUID
*provider
, GUID
*service
, DWORD
*len
,
1886 WSASERVICECLASSINFOW
*info
)
1888 FIXME( "(%s %s %p %p) Stub!\n", debugstr_guid(provider
), debugstr_guid(service
), len
, info
);
1889 SetLastError( WSA_NOT_ENOUGH_MEMORY
);
1894 /***********************************************************************
1895 * WSAGetServiceClassNameByClassIdA (ws2_32.@)
1897 int WINAPI
WSAGetServiceClassNameByClassIdA( GUID
*class, char *service
, DWORD
*len
)
1899 FIXME( "(%s %p %p) Stub!\n", debugstr_guid(class), service
, len
);
1900 SetLastError( WSA_NOT_ENOUGH_MEMORY
);
1905 /***********************************************************************
1906 * WSAGetServiceClassNameByClassIdW (ws2_32.@)
1908 int WINAPI
WSAGetServiceClassNameByClassIdW( GUID
*class, WCHAR
*service
, DWORD
*len
)
1910 FIXME( "(%s %p %p) Stub!\n", debugstr_guid(class), service
, len
);
1911 SetLastError( WSA_NOT_ENOUGH_MEMORY
);
1916 /***********************************************************************
1917 * WSALookupServiceBeginA (ws2_32.@)
1919 int WINAPI
WSALookupServiceBeginA( WSAQUERYSETA
*query
, DWORD flags
, HANDLE
*lookup
)
1921 FIXME( "(%p 0x%08x %p) Stub!\n", query
, flags
, lookup
);
1922 SetLastError( WSA_NOT_ENOUGH_MEMORY
);
1927 /***********************************************************************
1928 * WSALookupServiceBeginW (ws2_32.@)
1930 int WINAPI
WSALookupServiceBeginW( WSAQUERYSETW
*query
, DWORD flags
, HANDLE
*lookup
)
1932 FIXME( "(%p 0x%08x %p) Stub!\n", query
, flags
, lookup
);
1933 SetLastError( WSA_NOT_ENOUGH_MEMORY
);
1938 /***********************************************************************
1939 * WSALookupServiceEnd (ws2_32.@)
1941 int WINAPI
WSALookupServiceEnd( HANDLE lookup
)
1943 FIXME("(%p) Stub!\n", lookup
);
1948 /***********************************************************************
1949 * WSALookupServiceNextA (ws2_32.@)
1951 int WINAPI
WSALookupServiceNextA( HANDLE lookup
, DWORD flags
, DWORD
*len
, WSAQUERYSETA
*results
)
1953 FIXME( "(%p 0x%08x %p %p) Stub!\n", lookup
, flags
, len
, results
);
1954 SetLastError( WSA_E_NO_MORE
);
1959 /***********************************************************************
1960 * WSALookupServiceNextW (ws2_32.@)
1962 int WINAPI
WSALookupServiceNextW( HANDLE lookup
, DWORD flags
, DWORD
*len
, WSAQUERYSETW
*results
)
1964 FIXME( "(%p 0x%08x %p %p) Stub!\n", lookup
, flags
, len
, results
);
1965 SetLastError( WSA_E_NO_MORE
);
1970 /***********************************************************************
1971 * WSASetServiceA (ws2_32.@)
1973 int WINAPI
WSASetServiceA( WSAQUERYSETA
*query
, WSAESETSERVICEOP operation
, DWORD flags
)
1975 FIXME( "(%p 0x%08x 0x%08x) Stub!\n", query
, operation
, flags
);
1980 /***********************************************************************
1981 * WSASetServiceW (ws2_32.@)
1983 int WINAPI
WSASetServiceW( WSAQUERYSETW
*query
, WSAESETSERVICEOP operation
, DWORD flags
)
1985 FIXME( "(%p 0x%08x 0x%08x) Stub!\n", query
, operation
, flags
);
1990 /***********************************************************************
1991 * WSAEnumNameSpaceProvidersA (ws2_32.@)
1993 int WINAPI
WSAEnumNameSpaceProvidersA( DWORD
*len
, WSANAMESPACE_INFOA
*buffer
)
1995 FIXME( "(%p %p) Stub!\n", len
, buffer
);
2000 /***********************************************************************
2001 * WSAEnumNameSpaceProvidersW (ws2_32.@)
2003 int WINAPI
WSAEnumNameSpaceProvidersW( DWORD
*len
, WSANAMESPACE_INFOW
*buffer
)
2005 FIXME( "(%p %p) Stub!\n", len
, buffer
);
2010 /***********************************************************************
2011 * WSAProviderConfigChange (ws2_32.@)
2013 int WINAPI
WSAProviderConfigChange( HANDLE
*handle
, OVERLAPPED
*overlapped
,
2014 LPWSAOVERLAPPED_COMPLETION_ROUTINE completion
)
2016 FIXME( "(%p %p %p) Stub!\n", handle
, overlapped
, completion
);
2021 /***********************************************************************
2022 * WSANSPIoctl (ws2_32.@)
2024 int WINAPI
WSANSPIoctl( HANDLE lookup
, DWORD code
, void *in_buffer
,
2025 DWORD in_size
, void *out_buffer
, DWORD out_size
,
2026 DWORD
*ret_size
, WSACOMPLETION
*completion
)
2028 FIXME( "(%p, 0x%08x, %p, 0x%08x, %p, 0x%08x, %p, %p) Stub!\n", lookup
, code
,
2029 in_buffer
, in_size
, out_buffer
, out_size
, ret_size
, completion
);
2030 SetLastError( WSA_NOT_ENOUGH_MEMORY
);
2035 /***********************************************************************
2036 * WSCEnableNSProvider (ws2_32.@)
2038 int WINAPI
WSCEnableNSProvider( GUID
*provider
, BOOL enable
)
2040 FIXME( "(%s 0x%08x) Stub!\n", debugstr_guid(provider
), enable
);
2045 /***********************************************************************
2046 * WSCGetProviderInfo (ws2_32.@)
2048 int WINAPI
WSCGetProviderInfo( GUID
*provider
, WSC_PROVIDER_INFO_TYPE info_type
,
2049 BYTE
*info
, size_t *len
, DWORD flags
, int *errcode
)
2051 FIXME( "(%s 0x%08x %p %p 0x%08x %p) Stub!\n",
2052 debugstr_guid(provider
), info_type
, info
, len
, flags
, errcode
);
2059 *errcode
= WSAEFAULT
;
2063 *errcode
= WSANO_RECOVERY
;
2068 /***********************************************************************
2069 * WSCGetProviderPath (ws2_32.@)
2071 int WINAPI
WSCGetProviderPath( GUID
*provider
, WCHAR
*path
, int *len
, int *errcode
)
2073 FIXME( "(%s %p %p %p) Stub!\n", debugstr_guid(provider
), path
, len
, errcode
);
2075 if (!provider
|| !len
)
2078 *errcode
= WSAEFAULT
;
2085 *errcode
= WSAEINVAL
;
2093 /***********************************************************************
2094 * WSCInstallNameSpace (ws2_32.@)
2096 int WINAPI
WSCInstallNameSpace( WCHAR
*identifier
, WCHAR
*path
, DWORD
namespace,
2097 DWORD version
, GUID
*provider
)
2099 FIXME( "(%s %s 0x%08x 0x%08x %s) Stub!\n", debugstr_w(identifier
), debugstr_w(path
),
2100 namespace, version
, debugstr_guid(provider
) );
2105 /***********************************************************************
2106 * WSCUnInstallNameSpace (ws2_32.@)
2108 int WINAPI
WSCUnInstallNameSpace( GUID
*provider
)
2110 FIXME( "(%s) Stub!\n", debugstr_guid(provider
) );
2115 /***********************************************************************
2116 * WSCWriteProviderOrder (ws2_32.@)
2118 int WINAPI
WSCWriteProviderOrder( DWORD
*entry
, DWORD number
)
2120 FIXME( "(%p 0x%08x) Stub!\n", entry
, number
);
2125 /***********************************************************************
2126 * WSCInstallProvider (ws2_32.@)
2128 int WINAPI
WSCInstallProvider( GUID
*provider
, const WCHAR
*path
,
2129 WSAPROTOCOL_INFOW
*protocol_info
, DWORD count
, int *err
)
2131 FIXME( "(%s, %s, %p, %d, %p): stub !\n", debugstr_guid(provider
),
2132 debugstr_w(path
), protocol_info
, count
, err
);
2138 /***********************************************************************
2139 * WSCDeinstallProvider (ws2_32.@)
2141 int WINAPI
WSCDeinstallProvider( GUID
*provider
, int *err
)
2143 FIXME( "(%s, %p): stub !\n", debugstr_guid(provider
), err
);
2149 /***********************************************************************
2150 * WSCSetApplicationCategory (ws2_32.@)
2152 int WINAPI
WSCSetApplicationCategory( const WCHAR
*path
, DWORD len
, const WCHAR
*extra
, DWORD extralen
,
2153 DWORD lspcat
, DWORD
*prev_lspcat
, int *err
)
2155 FIXME( "(%s %d %s %d %d %p) Stub!\n", debugstr_w(path
), len
, debugstr_w(extra
),
2156 extralen
, lspcat
, prev_lspcat
);
2161 /***********************************************************************
2162 * WSCEnumProtocols (ws2_32.@)
2164 int WINAPI
WSCEnumProtocols( int *protocols
, WSAPROTOCOL_INFOW
*info
, DWORD
*len
, int *err
)
2166 int ret
= WSAEnumProtocolsW( protocols
, info
, len
);
2168 if (ret
== SOCKET_ERROR
) *err
= WSAENOBUFS
;