ws2_32: Move address/string conversion functions to protocol.c.

Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Zebediah Figura 2021-05-03 21:42:50 -05:00 committed by Alexandre Julliard
parent 3ba4412be6
commit 615028f8ba
2 changed files with 369 additions and 411 deletions

View file

@ -1653,3 +1653,372 @@ struct WS_servent * WINAPI WS_getservbyport( int port, const char *proto )
TRACE( "%d (i.e. port %d), %s ret %p\n", port, (int)ntohl(port), debugstr_a(proto), retval );
return retval;
}
/***********************************************************************
* inet_ntoa (ws2_32.12)
*/
char * WINAPI WS_inet_ntoa( struct WS_in_addr in )
{
unsigned int long_ip = ntohl( in.WS_s_addr );
struct per_thread_data *data = get_per_thread_data();
sprintf( data->ntoa_buffer, "%u.%u.%u.%u",
(long_ip >> 24) & 0xff,
(long_ip >> 16) & 0xff,
(long_ip >> 8) & 0xff,
long_ip & 0xff );
return data->ntoa_buffer;
}
/***********************************************************************
* inet_ntop (ws2_32.@)
*/
const char * WINAPI WS_inet_ntop( int family, void *addr, char *buffer, SIZE_T len )
{
NTSTATUS status;
ULONG size = min( len, (ULONG)-1 );
TRACE( "family %d, addr %p, buffer %p, len %ld\n", family, addr, buffer, len );
if (!buffer)
{
SetLastError( STATUS_INVALID_PARAMETER );
return NULL;
}
switch (family)
{
case WS_AF_INET:
{
status = RtlIpv4AddressToStringExA( (IN_ADDR *)addr, 0, buffer, &size );
break;
}
case WS_AF_INET6:
{
status = RtlIpv6AddressToStringExA( (IN6_ADDR *)addr, 0, 0, buffer, &size );
break;
}
default:
SetLastError( WSAEAFNOSUPPORT );
return NULL;
}
if (status == STATUS_SUCCESS) return buffer;
SetLastError( STATUS_INVALID_PARAMETER );
return NULL;
}
/***********************************************************************
* inet_pton (ws2_32.@)
*/
int WINAPI WS_inet_pton( int family, const char *addr, void *buffer )
{
NTSTATUS status;
const char *terminator;
TRACE( "family %d, addr %s, buffer %p\n", family, debugstr_a(addr), buffer );
if (!addr || !buffer)
{
SetLastError( WSAEFAULT );
return -1;
}
switch (family)
{
case WS_AF_INET:
status = RtlIpv4StringToAddressA(addr, TRUE, &terminator, buffer);
break;
case WS_AF_INET6:
status = RtlIpv6StringToAddressA(addr, &terminator, buffer);
break;
default:
SetLastError( WSAEAFNOSUPPORT );
return -1;
}
return (status == STATUS_SUCCESS && *terminator == 0);
}
/***********************************************************************
* InetPtonW (ws2_32.@)
*/
int WINAPI InetPtonW( int family, const WCHAR *addr, void *buffer )
{
char *addrA;
int len;
INT ret;
TRACE( "family %d, addr %s, buffer %p\n", family, debugstr_w(addr), buffer );
if (!addr)
{
SetLastError(WSAEFAULT);
return SOCKET_ERROR;
}
len = WideCharToMultiByte( CP_ACP, 0, addr, -1, NULL, 0, NULL, NULL );
if (!(addrA = HeapAlloc( GetProcessHeap(), 0, len )))
{
SetLastError( WSA_NOT_ENOUGH_MEMORY );
return -1;
}
WideCharToMultiByte( CP_ACP, 0, addr, -1, addrA, len, NULL, NULL );
ret = WS_inet_pton( family, addrA, buffer );
if (!ret) SetLastError( WSAEINVAL );
HeapFree( GetProcessHeap(), 0, addrA );
return ret;
}
/***********************************************************************
* InetNtopW (ws2_32.@)
*/
const WCHAR * WINAPI InetNtopW( int family, void *addr, WCHAR *buffer, SIZE_T len )
{
char bufferA[WS_INET6_ADDRSTRLEN];
PWSTR ret = NULL;
TRACE( "family %d, addr %p, buffer %p, len %ld\n", family, addr, buffer, len );
if (WS_inet_ntop( family, addr, bufferA, sizeof(bufferA) ))
{
if (MultiByteToWideChar( CP_ACP, 0, bufferA, -1, buffer, len ))
ret = buffer;
else
SetLastError( ERROR_INVALID_PARAMETER );
}
return ret;
}
/***********************************************************************
* WSAStringToAddressA (ws2_32.@)
*/
int WINAPI WSAStringToAddressA( char *string, int family, WSAPROTOCOL_INFOA *protocol_info,
struct WS_sockaddr *addr, int *addr_len )
{
NTSTATUS status;
TRACE( "string %s, family %u\n", debugstr_a(string), family );
if (!addr || !addr_len) return -1;
if (!string)
{
SetLastError( WSAEINVAL );
return -1;
}
if (protocol_info)
FIXME( "ignoring protocol_info\n" );
switch (family)
{
case WS_AF_INET:
{
struct WS_sockaddr_in *addr4 = (struct WS_sockaddr_in *)addr;
if (*addr_len < sizeof(struct WS_sockaddr_in))
{
*addr_len = sizeof(struct WS_sockaddr_in);
SetLastError( WSAEFAULT );
return -1;
}
memset( addr, 0, sizeof(struct WS_sockaddr_in) );
status = RtlIpv4StringToAddressExA( string, FALSE, &addr4->sin_addr, &addr4->sin_port );
if (status != STATUS_SUCCESS)
{
SetLastError( WSAEINVAL );
return -1;
}
addr4->sin_family = WS_AF_INET;
*addr_len = sizeof(struct WS_sockaddr_in);
return 0;
}
case WS_AF_INET6:
{
struct WS_sockaddr_in6 *addr6 = (struct WS_sockaddr_in6 *)addr;
if (*addr_len < sizeof(struct WS_sockaddr_in6))
{
*addr_len = sizeof(struct WS_sockaddr_in6);
SetLastError( WSAEFAULT );
return -1;
}
memset( addr, 0, sizeof(struct WS_sockaddr_in6) );
status = RtlIpv6StringToAddressExA( string, &addr6->sin6_addr, &addr6->sin6_scope_id, &addr6->sin6_port );
if (status != STATUS_SUCCESS)
{
SetLastError( WSAEINVAL );
return -1;
}
addr6->sin6_family = WS_AF_INET6;
*addr_len = sizeof(struct WS_sockaddr_in6);
return 0;
}
default:
/* According to MSDN, only AF_INET and AF_INET6 are supported. */
TRACE( "Unsupported address family specified: %d.\n", family );
SetLastError( WSAEINVAL );
return -1;
}
}
/***********************************************************************
* WSAStringToAddressW (ws2_32.@)
*/
int WINAPI WSAStringToAddressW( WCHAR *string, int family, WSAPROTOCOL_INFOW *protocol_info,
struct WS_sockaddr *addr, int *addr_len )
{
WSAPROTOCOL_INFOA infoA;
WSAPROTOCOL_INFOA *protocol_infoA = NULL;
int sizeA, ret;
char *stringA;
TRACE( "string %s, family %u\n", debugstr_w(string), family );
if (!addr || !addr_len) return -1;
if (protocol_info)
{
protocol_infoA = &infoA;
memcpy( protocol_infoA, protocol_info, FIELD_OFFSET( WSAPROTOCOL_INFOA, szProtocol ) );
if (!WideCharToMultiByte( CP_ACP, 0, protocol_info->szProtocol, -1, protocol_infoA->szProtocol,
sizeof(protocol_infoA->szProtocol), NULL, NULL ))
{
SetLastError( WSAEINVAL );
return -1;
}
}
if (!string)
{
SetLastError( WSAEINVAL );
return -1;
}
sizeA = WideCharToMultiByte( CP_ACP, 0, string, -1, NULL, 0, NULL, NULL );
if (!(stringA = HeapAlloc( GetProcessHeap(), 0, sizeA )))
{
SetLastError( WSA_NOT_ENOUGH_MEMORY );
return -1;
}
WideCharToMultiByte( CP_ACP, 0, string, -1, stringA, sizeA, NULL, NULL );
ret = WSAStringToAddressA( stringA, family, protocol_infoA, addr, addr_len );
HeapFree( GetProcessHeap(), 0, stringA );
return ret;
}
/***********************************************************************
* WSAAddressToStringA (ws2_32.@)
*/
int WINAPI WSAAddressToStringA( struct WS_sockaddr *addr, DWORD addr_len,
WSAPROTOCOL_INFOA *info, char *string, DWORD *string_len )
{
char buffer[54]; /* 32 digits + 7':' + '[' + '%" + 5 digits + ']:' + 5 digits + '\0' */
DWORD size;
TRACE( "addr %s\n", debugstr_sockaddr(addr) );
if (!addr) return SOCKET_ERROR;
if (!string || !string_len) return SOCKET_ERROR;
switch (addr->sa_family)
{
case WS_AF_INET:
{
const struct WS_sockaddr_in *addr4 = (const struct WS_sockaddr_in *)addr;
unsigned int long_ip = ntohl( addr4->sin_addr.WS_s_addr );
char *p;
if (addr_len < sizeof(struct WS_sockaddr_in)) return -1;
sprintf( buffer, "%u.%u.%u.%u:%u",
(long_ip >> 24) & 0xff,
(long_ip >> 16) & 0xff,
(long_ip >> 8) & 0xff,
long_ip & 0xff,
ntohs( addr4->sin_port ) );
p = strchr( buffer, ':' );
if (!addr4->sin_port) *p = 0;
break;
}
case WS_AF_INET6:
{
struct WS_sockaddr_in6 *addr6 = (struct WS_sockaddr_in6 *)addr;
size_t len;
buffer[0] = 0;
if (addr_len < sizeof(struct WS_sockaddr_in6)) return -1;
if (addr6->sin6_port)
strcpy( buffer, "[" );
len = strlen( buffer );
if (!WS_inet_ntop( WS_AF_INET6, &addr6->sin6_addr, &buffer[len], sizeof(buffer) - len ))
{
SetLastError( WSAEINVAL );
return -1;
}
if (addr6->sin6_scope_id)
sprintf( buffer + strlen( buffer ), "%%%u", addr6->sin6_scope_id );
if (addr6->sin6_port)
sprintf( buffer + strlen( buffer ), "]:%u", ntohs( addr6->sin6_port ) );
break;
}
default:
SetLastError( WSAEINVAL );
return -1;
}
size = strlen( buffer ) + 1;
if (*string_len < size)
{
*string_len = size;
SetLastError( WSAEFAULT );
return -1;
}
TRACE( "=> %s, %u bytes\n", debugstr_a(buffer), size );
*string_len = size;
strcpy( string, buffer );
return 0;
}
/***********************************************************************
* WSAAddressToStringW (ws2_32.@)
*/
int WINAPI WSAAddressToStringW( struct WS_sockaddr *addr, DWORD addr_len,
WSAPROTOCOL_INFOW *info, WCHAR *string, DWORD *string_len )
{
INT ret;
char buf[54]; /* 32 digits + 7':' + '[' + '%" + 5 digits + ']:' + 5 digits + '\0' */
TRACE( "(%p, %d, %p, %p, %p)\n", addr, addr_len, info, string, string_len );
if ((ret = WSAAddressToStringA( addr, addr_len, NULL, buf, string_len ))) return ret;
MultiByteToWideChar( CP_ACP, 0, buf, *string_len, string, *string_len );
TRACE( "=> %s, %u chars\n", debugstr_w(string), *string_len );
return 0;
}
/***********************************************************************
* inet_addr (ws2_32.11)
*/
WS_u_long WINAPI WS_inet_addr( const char *cp )
{
if (!cp) return INADDR_NONE;
return inet_addr( cp );
}

View file

@ -40,10 +40,6 @@
# define sipx_node sipx_addr.x_host.c_host
#endif /* __FreeBSD__ */
#ifndef INADDR_NONE
#define INADDR_NONE ~0UL
#endif
#if !defined(TCP_KEEPIDLE) && defined(TCP_KEEPALIVE)
/* TCP_KEEPALIVE is the Mac OS name for TCP_KEEPIDLE */
#define TCP_KEEPIDLE TCP_KEEPALIVE
@ -3896,16 +3892,6 @@ int WINAPI WSAHtons(SOCKET s, WS_u_short hostshort, WS_u_short *lpnetshort)
}
/***********************************************************************
* inet_addr (WS2_32.11)
*/
WS_u_long WINAPI WS_inet_addr(const char *cp)
{
if (!cp) return INADDR_NONE;
return inet_addr(cp);
}
/***********************************************************************
* ntohl (WS2_32.14)
*/
@ -3924,23 +3910,6 @@ WS_u_short WINAPI WS_ntohs(WS_u_short netshort)
}
/***********************************************************************
* inet_ntoa (WS2_32.12)
*/
char* WINAPI WS_inet_ntoa(struct WS_in_addr in)
{
unsigned int long_ip = ntohl(in.WS_s_addr);
struct per_thread_data *data = get_per_thread_data();
sprintf( data->ntoa_buffer, "%u.%u.%u.%u",
(long_ip >> 24) & 0xff,
(long_ip >> 16) & 0xff,
(long_ip >> 8) & 0xff,
long_ip & 0xff);
return data->ntoa_buffer;
}
static const char *debugstr_wsaioctl(DWORD code)
{
const char *name = NULL, *buf_type, *family;
@ -6449,386 +6418,6 @@ int WINAPI WSARemoveServiceClass(LPGUID info)
return SOCKET_ERROR;
}
/***********************************************************************
* inet_ntop (WS2_32.@)
*/
PCSTR WINAPI WS_inet_ntop( INT family, PVOID addr, PSTR buffer, SIZE_T len )
{
NTSTATUS status;
ULONG size = min( len, (ULONG)-1 );
TRACE("family %d, addr (%p), buffer (%p), len %ld\n", family, addr, buffer, len);
if (!buffer)
{
SetLastError( STATUS_INVALID_PARAMETER );
return NULL;
}
switch (family)
{
case WS_AF_INET:
{
status = RtlIpv4AddressToStringExA( (IN_ADDR *)addr, 0, buffer, &size );
break;
}
case WS_AF_INET6:
{
status = RtlIpv6AddressToStringExA( (IN6_ADDR *)addr, 0, 0, buffer, &size );
break;
}
default:
SetLastError( WSAEAFNOSUPPORT );
return NULL;
}
if (status == STATUS_SUCCESS) return buffer;
SetLastError( STATUS_INVALID_PARAMETER );
return NULL;
}
/***********************************************************************
* inet_pton (WS2_32.@)
*/
INT WINAPI WS_inet_pton(INT family, const char *addr, void *buffer)
{
NTSTATUS status;
const char *terminator;
TRACE("family %d, addr %s, buffer (%p)\n", family, debugstr_a(addr), buffer);
if (!addr || !buffer)
{
SetLastError(WSAEFAULT);
return SOCKET_ERROR;
}
switch (family)
{
case WS_AF_INET:
status = RtlIpv4StringToAddressA(addr, TRUE, &terminator, buffer);
break;
case WS_AF_INET6:
status = RtlIpv6StringToAddressA(addr, &terminator, buffer);
break;
default:
SetLastError(WSAEAFNOSUPPORT);
return SOCKET_ERROR;
}
return (status == STATUS_SUCCESS && *terminator == 0);
}
/***********************************************************************
* InetPtonW (WS2_32.@)
*/
INT WINAPI InetPtonW(INT family, PCWSTR addr, PVOID buffer)
{
char *addrA;
int len;
INT ret;
TRACE("family %d, addr %s, buffer (%p)\n", family, debugstr_w(addr), buffer);
if (!addr)
{
SetLastError(WSAEFAULT);
return SOCKET_ERROR;
}
len = WideCharToMultiByte(CP_ACP, 0, addr, -1, NULL, 0, NULL, NULL);
if (!(addrA = HeapAlloc(GetProcessHeap(), 0, len)))
{
SetLastError(WSA_NOT_ENOUGH_MEMORY);
return SOCKET_ERROR;
}
WideCharToMultiByte(CP_ACP, 0, addr, -1, addrA, len, NULL, NULL);
ret = WS_inet_pton(family, addrA, buffer);
if (!ret) SetLastError(WSAEINVAL);
HeapFree(GetProcessHeap(), 0, addrA);
return ret;
}
/***********************************************************************
* InetNtopW (WS2_32.@)
*/
PCWSTR WINAPI InetNtopW(INT family, PVOID addr, PWSTR buffer, SIZE_T len)
{
char bufferA[WS_INET6_ADDRSTRLEN];
PWSTR ret = NULL;
TRACE("family %d, addr (%p), buffer (%p), len %ld\n", family, addr, buffer, len);
if (WS_inet_ntop(family, addr, bufferA, sizeof(bufferA)))
{
if (MultiByteToWideChar(CP_ACP, 0, bufferA, -1, buffer, len))
ret = buffer;
else
SetLastError(ERROR_INVALID_PARAMETER);
}
return ret;
}
/***********************************************************************
* WSAStringToAddressA (WS2_32.80)
*/
INT WINAPI WSAStringToAddressA(LPSTR AddressString,
INT AddressFamily,
LPWSAPROTOCOL_INFOA lpProtocolInfo,
LPSOCKADDR lpAddress,
LPINT lpAddressLength)
{
INT res=0;
NTSTATUS status;
TRACE( "(%s, %x, %p, %p, %p)\n", debugstr_a(AddressString), AddressFamily,
lpProtocolInfo, lpAddress, lpAddressLength );
if (!lpAddressLength || !lpAddress) return SOCKET_ERROR;
if (!AddressString)
{
SetLastError(WSAEINVAL);
return SOCKET_ERROR;
}
if (lpProtocolInfo)
FIXME("ProtocolInfo not implemented.\n");
switch(AddressFamily)
{
case WS_AF_INET:
{
SOCKADDR_IN *addr4 = (SOCKADDR_IN *)lpAddress;
/* If lpAddressLength is too small, tell caller the size we need */
if (*lpAddressLength < sizeof(SOCKADDR_IN))
{
*lpAddressLength = sizeof(SOCKADDR_IN);
res = WSAEFAULT;
break;
}
memset(lpAddress, 0, sizeof(SOCKADDR_IN));
status = RtlIpv4StringToAddressExA(AddressString, FALSE, &addr4->sin_addr, &addr4->sin_port);
if (status != STATUS_SUCCESS)
{
res = WSAEINVAL;
break;
}
addr4->sin_family = WS_AF_INET;
*lpAddressLength = sizeof(SOCKADDR_IN);
break;
}
case WS_AF_INET6:
{
SOCKADDR_IN6 *addr6 = (SOCKADDR_IN6 *)lpAddress;
/* If lpAddressLength is too small, tell caller the size we need */
if (*lpAddressLength < sizeof(SOCKADDR_IN6))
{
*lpAddressLength = sizeof(SOCKADDR_IN6);
res = WSAEFAULT;
break;
}
memset(lpAddress, 0, sizeof(SOCKADDR_IN6));
status = RtlIpv6StringToAddressExA(AddressString, &addr6->sin6_addr, &addr6->sin6_scope_id, &addr6->sin6_port);
if (status != STATUS_SUCCESS)
{
res = WSAEINVAL;
break;
}
addr6->sin6_family = WS_AF_INET6;
*lpAddressLength = sizeof(SOCKADDR_IN6);
break;
}
default:
/* According to MSDN, only AF_INET and AF_INET6 are supported. */
TRACE("Unsupported address family specified: %d.\n", AddressFamily);
res = WSAEINVAL;
}
if (!res) return 0;
SetLastError(res);
return SOCKET_ERROR;
}
/***********************************************************************
* WSAStringToAddressW (WS2_32.81)
*
* FIXME: Does anybody know if this function allows using Hebrew/Arabic/Chinese... digits?
* If this should be the case, it would be required to map these digits
* to Unicode digits (0-9) using FoldString first.
*/
INT WINAPI WSAStringToAddressW(LPWSTR AddressString,
INT AddressFamily,
LPWSAPROTOCOL_INFOW lpProtocolInfo,
LPSOCKADDR lpAddress,
LPINT lpAddressLength)
{
INT sBuffer,res=0;
LPSTR workBuffer=NULL;
WSAPROTOCOL_INFOA infoA;
LPWSAPROTOCOL_INFOA lpProtoInfoA = NULL;
TRACE( "(%s, %x, %p, %p, %p)\n", debugstr_w(AddressString), AddressFamily, lpProtocolInfo,
lpAddress, lpAddressLength );
if (!lpAddressLength || !lpAddress) return SOCKET_ERROR;
/* if ProtocolInfo is available - convert to ANSI variant */
if (lpProtocolInfo)
{
lpProtoInfoA = &infoA;
memcpy( lpProtoInfoA, lpProtocolInfo, FIELD_OFFSET( WSAPROTOCOL_INFOA, szProtocol ) );
if (!WideCharToMultiByte( CP_ACP, 0, lpProtocolInfo->szProtocol, -1,
lpProtoInfoA->szProtocol, WSAPROTOCOL_LEN+1, NULL, NULL ))
{
SetLastError(WSAEINVAL);
return SOCKET_ERROR;
}
}
if (AddressString)
{
/* Translate AddressString to ANSI code page - assumes that only
standard digits 0-9 are used with this API call */
sBuffer = WideCharToMultiByte( CP_ACP, 0, AddressString, -1, NULL, 0, NULL, NULL );
workBuffer = HeapAlloc( GetProcessHeap(), 0, sBuffer );
if (workBuffer)
{
WideCharToMultiByte( CP_ACP, 0, AddressString, -1, workBuffer, sBuffer, NULL, NULL );
res = WSAStringToAddressA(workBuffer,AddressFamily,lpProtoInfoA,
lpAddress,lpAddressLength);
HeapFree( GetProcessHeap(), 0, workBuffer );
return res;
}
else
res = WSA_NOT_ENOUGH_MEMORY;
}
else
res = WSAEINVAL;
SetLastError(res);
return SOCKET_ERROR;
}
/***********************************************************************
* WSAAddressToStringA (WS2_32.27)
*
* See WSAAddressToStringW
*/
INT WINAPI WSAAddressToStringA( LPSOCKADDR sockaddr, DWORD len,
LPWSAPROTOCOL_INFOA info, LPSTR string,
LPDWORD lenstr )
{
DWORD size;
CHAR buffer[54]; /* 32 digits + 7':' + '[' + '%" + 5 digits + ']:' + 5 digits + '\0' */
CHAR *p;
TRACE( "(%p, %d, %p, %p, %p)\n", sockaddr, len, info, string, lenstr );
if (!sockaddr) return SOCKET_ERROR;
if (!string || !lenstr) return SOCKET_ERROR;
switch(sockaddr->sa_family)
{
case WS_AF_INET:
{
unsigned int long_ip = ntohl(((SOCKADDR_IN *)sockaddr)->sin_addr.WS_s_addr);
if (len < sizeof(SOCKADDR_IN)) return SOCKET_ERROR;
sprintf( buffer, "%u.%u.%u.%u:%u",
(long_ip >> 24) & 0xff,
(long_ip >> 16) & 0xff,
(long_ip >> 8) & 0xff,
long_ip & 0xff,
ntohs( ((SOCKADDR_IN *)sockaddr)->sin_port ) );
p = strchr( buffer, ':' );
if (!((SOCKADDR_IN *)sockaddr)->sin_port) *p = 0;
break;
}
case WS_AF_INET6:
{
struct WS_sockaddr_in6 *sockaddr6 = (LPSOCKADDR_IN6) sockaddr;
size_t slen;
buffer[0] = 0;
if (len < sizeof(SOCKADDR_IN6)) return SOCKET_ERROR;
if ((sockaddr6->sin6_port))
strcpy(buffer, "[");
slen = strlen(buffer);
if (!WS_inet_ntop(WS_AF_INET6, &sockaddr6->sin6_addr, &buffer[slen], sizeof(buffer) - slen))
{
SetLastError(WSAEINVAL);
return SOCKET_ERROR;
}
if ((sockaddr6->sin6_scope_id))
sprintf(buffer+strlen(buffer), "%%%u", sockaddr6->sin6_scope_id);
if ((sockaddr6->sin6_port))
sprintf(buffer+strlen(buffer), "]:%u", ntohs(sockaddr6->sin6_port));
break;
}
default:
SetLastError(WSAEINVAL);
return SOCKET_ERROR;
}
size = strlen( buffer ) + 1;
if (*lenstr < size)
{
*lenstr = size;
SetLastError(WSAEFAULT);
return SOCKET_ERROR;
}
TRACE("=> %s,%u bytes\n", debugstr_a(buffer), size);
*lenstr = size;
strcpy( string, buffer );
return 0;
}
/***********************************************************************
* WSAAddressToStringW (WS2_32.28)
*
* Convert a sockaddr address into a readable address string.
*
* PARAMS
* sockaddr [I] Pointer to a sockaddr structure.
* len [I] Size of the sockaddr structure.
* info [I] Pointer to a WSAPROTOCOL_INFOW structure (optional).
* string [I/O] Pointer to a buffer to receive the address string.
* lenstr [I/O] Size of the receive buffer in WCHARs.
*
* RETURNS
* Success: 0
* Failure: SOCKET_ERROR
*
* NOTES
* The 'info' parameter is ignored.
*/
INT WINAPI WSAAddressToStringW( LPSOCKADDR sockaddr, DWORD len,
LPWSAPROTOCOL_INFOW info, LPWSTR string,
LPDWORD lenstr )
{
INT ret;
char buf[54]; /* 32 digits + 7':' + '[' + '%" + 5 digits + ']:' + 5 digits + '\0' */
TRACE( "(%p, %d, %p, %p, %p)\n", sockaddr, len, info, string, lenstr );
if ((ret = WSAAddressToStringA(sockaddr, len, NULL, buf, lenstr))) return ret;
MultiByteToWideChar(CP_ACP, 0, buf, *lenstr, string, *lenstr);
TRACE("=> %s,%u chars\n", debugstr_w(string), *lenstr);
return 0;
}
/***********************************************************************
* WSAEnumNameSpaceProvidersA (WS2_32.34)
*/