diff --git a/dlls/ws2_32/protocol.c b/dlls/ws2_32/protocol.c index 2cb6ef4be1c..fe30f26db53 100644 --- a/dlls/ws2_32/protocol.c +++ b/dlls/ws2_32/protocol.c @@ -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 ); +} diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index 2776e2f0014..3d930d13bb6 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -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) */