ws2_32: Return WSAEINVAL for unhandled address families in WSAStringToAddress.
Prepare for IPv6 support.
This commit is contained in:
parent
0d750e3282
commit
d89f2b4810
|
@ -4429,7 +4429,6 @@ INT WINAPI WSAStringToAddressA(LPSTR AddressString,
|
||||||
LPINT lpAddressLength)
|
LPINT lpAddressLength)
|
||||||
{
|
{
|
||||||
INT res=0;
|
INT res=0;
|
||||||
struct in_addr inetaddr;
|
|
||||||
LPSTR workBuffer=NULL,ptrPort;
|
LPSTR workBuffer=NULL,ptrPort;
|
||||||
|
|
||||||
TRACE( "(%s, %x, %p, %p, %p)\n", AddressString, AddressFamily, lpProtocolInfo,
|
TRACE( "(%s, %x, %p, %p, %p)\n", AddressString, AddressFamily, lpProtocolInfo,
|
||||||
|
@ -4437,63 +4436,84 @@ INT WINAPI WSAStringToAddressA(LPSTR AddressString,
|
||||||
|
|
||||||
if (!lpAddressLength || !lpAddress) return SOCKET_ERROR;
|
if (!lpAddressLength || !lpAddress) return SOCKET_ERROR;
|
||||||
|
|
||||||
if (AddressString)
|
if (!AddressString)
|
||||||
{
|
{
|
||||||
workBuffer = HeapAlloc( GetProcessHeap(), 0, strlen(AddressString)+1 );
|
WSASetLastError(WSAEINVAL);
|
||||||
if (workBuffer)
|
return SOCKET_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lpProtocolInfo)
|
||||||
|
FIXME("ProtocolInfo not implemented.\n");
|
||||||
|
|
||||||
|
workBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||||
|
strlen(AddressString) + 1);
|
||||||
|
if (!workBuffer)
|
||||||
{
|
{
|
||||||
strcpy(workBuffer,AddressString);
|
WSASetLastError(WSA_NOT_ENOUGH_MEMORY);
|
||||||
switch (AddressFamily)
|
return SOCKET_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy(workBuffer, AddressString);
|
||||||
|
|
||||||
|
switch(AddressFamily)
|
||||||
{
|
{
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
/* caller wants to know the size of the socket buffer */
|
{
|
||||||
|
struct in_addr inetaddr;
|
||||||
|
|
||||||
|
/* If lpAddressLength is too small, tell caller the size we need */
|
||||||
if (*lpAddressLength < sizeof(SOCKADDR_IN))
|
if (*lpAddressLength < sizeof(SOCKADDR_IN))
|
||||||
{
|
{
|
||||||
*lpAddressLength = sizeof(SOCKADDR_IN);
|
*lpAddressLength = sizeof(SOCKADDR_IN);
|
||||||
res = WSAEFAULT;
|
res = WSAEFAULT;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else
|
memset(lpAddress, 0, sizeof(SOCKADDR_IN));
|
||||||
{
|
|
||||||
/* caller wants to translate an AddressString into a SOCKADDR */
|
|
||||||
if (lpAddress)
|
|
||||||
{
|
|
||||||
memset(lpAddress,0,sizeof(SOCKADDR_IN));
|
|
||||||
((LPSOCKADDR_IN)lpAddress)->sin_family = AF_INET;
|
((LPSOCKADDR_IN)lpAddress)->sin_family = AF_INET;
|
||||||
ptrPort = strchr(workBuffer,':');
|
|
||||||
if (ptrPort)
|
ptrPort = strchr(workBuffer, ':');
|
||||||
|
if(ptrPort)
|
||||||
{
|
{
|
||||||
((LPSOCKADDR_IN)lpAddress)->sin_port = (WS_u_short)atoi(ptrPort+1);
|
((LPSOCKADDR_IN)lpAddress)->sin_port = (WS_u_short)atoi(ptrPort+1);
|
||||||
*ptrPort = '\0';
|
*ptrPort = '\0';
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
((LPSOCKADDR_IN)lpAddress)->sin_port = 0;
|
((LPSOCKADDR_IN)lpAddress)->sin_port = 0;
|
||||||
if (inet_aton(workBuffer, &inetaddr) > 0)
|
}
|
||||||
|
|
||||||
|
if(inet_aton(workBuffer, &inetaddr) > 0)
|
||||||
{
|
{
|
||||||
((LPSOCKADDR_IN)lpAddress)->sin_addr.WS_s_addr = inetaddr.s_addr;
|
((LPSOCKADDR_IN)lpAddress)->sin_addr.WS_s_addr = inetaddr.s_addr;
|
||||||
res = 0;
|
res = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
res = WSAEINVAL;
|
res = WSAEINVAL;
|
||||||
}
|
|
||||||
}
|
|
||||||
if (lpProtocolInfo)
|
|
||||||
FIXME("(%s, %x, %p, %p, %p) - ProtocolInfo not implemented!\n",
|
|
||||||
AddressString, AddressFamily,
|
|
||||||
lpProtocolInfo, lpAddress, lpAddressLength);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
|
||||||
FIXME("(%s, %x, %p, %p, %p) - AddressFamiliy not implemented!\n",
|
|
||||||
AddressString, AddressFamily,
|
|
||||||
lpProtocolInfo, lpAddress, lpAddressLength);
|
|
||||||
}
|
}
|
||||||
HeapFree( GetProcessHeap(), 0, workBuffer );
|
case AF_INET6:
|
||||||
|
{
|
||||||
|
/* If lpAddressLength is too small, tell caller the size we need */
|
||||||
|
if (*lpAddressLength < sizeof(SOCKADDR_IN6))
|
||||||
|
{
|
||||||
|
*lpAddressLength = sizeof(SOCKADDR_IN6);
|
||||||
|
res = WSAEFAULT;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else
|
FIXME("We don't support IPv6 yet.\n");
|
||||||
res = WSA_NOT_ENOUGH_MEMORY;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
res = WSAEINVAL;
|
res = WSAEINVAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
/* According to MSDN, only AF_INET and AF_INET6 are supported. */
|
||||||
|
TRACE("Unsupported address family specified: %d.\n", AddressFamily);
|
||||||
|
res = WSAEINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
HeapFree(GetProcessHeap(), 0, workBuffer);
|
||||||
|
|
||||||
if (!res) return 0;
|
if (!res) return 0;
|
||||||
WSASetLastError(res);
|
WSASetLastError(res);
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include <windef.h>
|
#include <windef.h>
|
||||||
#include <winbase.h>
|
#include <winbase.h>
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
|
#include <ws2tcpip.h>
|
||||||
#include <mswsock.h>
|
#include <mswsock.h>
|
||||||
#include "wine/test.h"
|
#include "wine/test.h"
|
||||||
#include <winnt.h>
|
#include <winnt.h>
|
||||||
|
@ -1250,6 +1251,7 @@ static void test_WSAStringToAddressA(void)
|
||||||
{
|
{
|
||||||
INT ret, len;
|
INT ret, len;
|
||||||
SOCKADDR_IN sockaddr;
|
SOCKADDR_IN sockaddr;
|
||||||
|
SOCKADDR_IN6 sockaddr6;
|
||||||
int GLE;
|
int GLE;
|
||||||
|
|
||||||
CHAR address1[] = "0.0.0.0";
|
CHAR address1[] = "0.0.0.0";
|
||||||
|
@ -1257,6 +1259,9 @@ static void test_WSAStringToAddressA(void)
|
||||||
CHAR address3[] = "255.255.255.255";
|
CHAR address3[] = "255.255.255.255";
|
||||||
CHAR address4[] = "127.127.127.127:65535";
|
CHAR address4[] = "127.127.127.127:65535";
|
||||||
CHAR address5[] = "255.255.255.255:65535";
|
CHAR address5[] = "255.255.255.255:65535";
|
||||||
|
CHAR address6[] = "::1";
|
||||||
|
CHAR address7[] = "[::1]";
|
||||||
|
CHAR address8[] = "[::1]:65535";
|
||||||
|
|
||||||
len = 0;
|
len = 0;
|
||||||
sockaddr.sin_family = AF_INET;
|
sockaddr.sin_family = AF_INET;
|
||||||
|
@ -1308,12 +1313,45 @@ static void test_WSAStringToAddressA(void)
|
||||||
ok( (ret == 0 && sockaddr.sin_addr.s_addr == 0xffffffff && sockaddr.sin_port == 0xffff) ||
|
ok( (ret == 0 && sockaddr.sin_addr.s_addr == 0xffffffff && sockaddr.sin_port == 0xffff) ||
|
||||||
(ret == SOCKET_ERROR && (GLE == ERROR_INVALID_PARAMETER || GLE == WSAEINVAL)),
|
(ret == SOCKET_ERROR && (GLE == ERROR_INVALID_PARAMETER || GLE == WSAEINVAL)),
|
||||||
"WSAStringToAddressA() failed unexpectedly: %d\n", GLE );
|
"WSAStringToAddressA() failed unexpectedly: %d\n", GLE );
|
||||||
|
|
||||||
|
len = sizeof(sockaddr6);
|
||||||
|
memset(&sockaddr6, 0, len);
|
||||||
|
sockaddr6.sin6_family = AF_INET6;
|
||||||
|
|
||||||
|
ret = WSAStringToAddressA( address6, AF_INET6, NULL, (SOCKADDR*)&sockaddr6,
|
||||||
|
&len );
|
||||||
|
GLE = WSAGetLastError();
|
||||||
|
ok( ret == 0 || (ret == SOCKET_ERROR && GLE == WSAEINVAL),
|
||||||
|
"WSAStringToAddressA() failed for IPv6 address: %d\n", GLE);
|
||||||
|
|
||||||
|
len = sizeof(sockaddr6);
|
||||||
|
memset(&sockaddr6, 0, len);
|
||||||
|
sockaddr6.sin6_family = AF_INET6;
|
||||||
|
|
||||||
|
ret = WSAStringToAddressA( address7, AF_INET6, NULL, (SOCKADDR*)&sockaddr6,
|
||||||
|
&len );
|
||||||
|
GLE = WSAGetLastError();
|
||||||
|
ok( ret == 0 || (ret == SOCKET_ERROR && GLE == WSAEINVAL),
|
||||||
|
"WSAStringToAddressA() failed for IPv6 address: %d\n", GLE);
|
||||||
|
|
||||||
|
len = sizeof(sockaddr6);
|
||||||
|
memset(&sockaddr6, 0, len);
|
||||||
|
sockaddr6.sin6_family = AF_INET6;
|
||||||
|
|
||||||
|
ret = WSAStringToAddressA( address8, AF_INET6, NULL, (SOCKADDR*)&sockaddr6,
|
||||||
|
&len );
|
||||||
|
GLE = WSAGetLastError();
|
||||||
|
ok( (ret == 0 && sockaddr6.sin6_port == 0xffff) ||
|
||||||
|
(ret == SOCKET_ERROR && GLE == WSAEINVAL),
|
||||||
|
"WSAStringToAddressA() failed for IPv6 address: %d\n", GLE);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_WSAStringToAddressW(void)
|
static void test_WSAStringToAddressW(void)
|
||||||
{
|
{
|
||||||
INT ret, len;
|
INT ret, len;
|
||||||
SOCKADDR_IN sockaddr;
|
SOCKADDR_IN sockaddr;
|
||||||
|
SOCKADDR_IN6 sockaddr6;
|
||||||
int GLE;
|
int GLE;
|
||||||
|
|
||||||
WCHAR address1[] = { '0','.','0','.','0','.','0', 0 };
|
WCHAR address1[] = { '0','.','0','.','0','.','0', 0 };
|
||||||
|
@ -1323,6 +1361,9 @@ static void test_WSAStringToAddressW(void)
|
||||||
':', '6', '5', '5', '3', '5', 0 };
|
':', '6', '5', '5', '3', '5', 0 };
|
||||||
WCHAR address5[] = { '2','5','5','.','2','5','5','.','2','5','5','.','2','5','5', ':',
|
WCHAR address5[] = { '2','5','5','.','2','5','5','.','2','5','5','.','2','5','5', ':',
|
||||||
'6', '5', '5', '3', '5', 0 };
|
'6', '5', '5', '3', '5', 0 };
|
||||||
|
WCHAR address6[] = {':',':','1','\0'};
|
||||||
|
WCHAR address7[] = {'[',':',':','1',']','\0'};
|
||||||
|
WCHAR address8[] = {'[',':',':','1',']',':','6','5','5','3','5','\0'};
|
||||||
|
|
||||||
len = 0;
|
len = 0;
|
||||||
sockaddr.sin_family = AF_INET;
|
sockaddr.sin_family = AF_INET;
|
||||||
|
@ -1373,6 +1414,38 @@ static void test_WSAStringToAddressW(void)
|
||||||
ok( (ret == 0 && sockaddr.sin_addr.s_addr == 0xffffffff && sockaddr.sin_port == 0xffff) ||
|
ok( (ret == 0 && sockaddr.sin_addr.s_addr == 0xffffffff && sockaddr.sin_port == 0xffff) ||
|
||||||
(ret == SOCKET_ERROR && (GLE == ERROR_INVALID_PARAMETER || GLE == WSAEINVAL)),
|
(ret == SOCKET_ERROR && (GLE == ERROR_INVALID_PARAMETER || GLE == WSAEINVAL)),
|
||||||
"WSAStringToAddressW() failed unexpectedly: %d\n", GLE );
|
"WSAStringToAddressW() failed unexpectedly: %d\n", GLE );
|
||||||
|
|
||||||
|
len = sizeof(sockaddr6);
|
||||||
|
memset(&sockaddr6, 0, len);
|
||||||
|
sockaddr6.sin6_family = AF_INET6;
|
||||||
|
|
||||||
|
ret = WSAStringToAddressW( address6, AF_INET6, NULL, (SOCKADDR*)&sockaddr6,
|
||||||
|
&len );
|
||||||
|
GLE = WSAGetLastError();
|
||||||
|
ok( ret == 0 || (ret == SOCKET_ERROR && GLE == WSAEINVAL),
|
||||||
|
"WSAStringToAddressW() failed for IPv6 address: %d\n", GLE);
|
||||||
|
|
||||||
|
len = sizeof(sockaddr6);
|
||||||
|
memset(&sockaddr6, 0, len);
|
||||||
|
sockaddr6.sin6_family = AF_INET6;
|
||||||
|
|
||||||
|
ret = WSAStringToAddressW( address7, AF_INET6, NULL, (SOCKADDR*)&sockaddr6,
|
||||||
|
&len );
|
||||||
|
GLE = WSAGetLastError();
|
||||||
|
ok( ret == 0 || (ret == SOCKET_ERROR && GLE == WSAEINVAL),
|
||||||
|
"WSAStringToAddressW() failed for IPv6 address: %d\n", GLE);
|
||||||
|
|
||||||
|
len = sizeof(sockaddr6);
|
||||||
|
memset(&sockaddr6, 0, len);
|
||||||
|
sockaddr6.sin6_family = AF_INET6;
|
||||||
|
|
||||||
|
ret = WSAStringToAddressW( address8, AF_INET6, NULL, (SOCKADDR*)&sockaddr6,
|
||||||
|
&len );
|
||||||
|
GLE = WSAGetLastError();
|
||||||
|
ok( (ret == 0 && sockaddr6.sin6_port == 0xffff) ||
|
||||||
|
(ret == SOCKET_ERROR && GLE == WSAEINVAL),
|
||||||
|
"WSAStringToAddressW() failed for IPv6 address: %d\n", GLE);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID WINAPI SelectReadThread(select_thread_params *par)
|
static VOID WINAPI SelectReadThread(select_thread_params *par)
|
||||||
|
|
Loading…
Reference in New Issue