Kai Blin : ws2_32:
Return WSAEINVAL for unhandled address families in WSAStringToAddress.
Alexandre Julliard
julliard at wine.codeweavers.com
Fri Jun 29 08:15:00 CDT 2007
Module: wine
Branch: master
Commit: d89f2b4810ebbef1deb3b4377e5af44d09c6ef74
URL: http://source.winehq.org/git/wine.git/?a=commit;h=d89f2b4810ebbef1deb3b4377e5af44d09c6ef74
Author: Kai Blin <kai.blin at gmail.com>
Date: Fri Jun 29 12:41:28 2007 +0200
ws2_32: Return WSAEINVAL for unhandled address families in WSAStringToAddress.
Prepare for IPv6 support.
---
dlls/ws2_32/socket.c | 122 +++++++++++++++++++++++++++-------------------
dlls/ws2_32/tests/sock.c | 73 +++++++++++++++++++++++++++
2 files changed, 144 insertions(+), 51 deletions(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index 92fd3f6..90fa9b0 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -4429,7 +4429,6 @@ INT WINAPI WSAStringToAddressA(LPSTR AddressString,
LPINT lpAddressLength)
{
INT res=0;
- struct in_addr inetaddr;
LPSTR workBuffer=NULL,ptrPort;
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 (AddressString)
+ if (!AddressString)
{
- workBuffer = HeapAlloc( GetProcessHeap(), 0, strlen(AddressString)+1 );
- if (workBuffer)
+ WSASetLastError(WSAEINVAL);
+ return SOCKET_ERROR;
+ }
+
+ if (lpProtocolInfo)
+ FIXME("ProtocolInfo not implemented.\n");
+
+ workBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+ strlen(AddressString) + 1);
+ if (!workBuffer)
+ {
+ WSASetLastError(WSA_NOT_ENOUGH_MEMORY);
+ return SOCKET_ERROR;
+ }
+
+ strcpy(workBuffer, AddressString);
+
+ switch(AddressFamily)
+ {
+ case AF_INET:
+ {
+ struct in_addr inetaddr;
+
+ /* If lpAddressLength is too small, tell caller the size we need */
+ if (*lpAddressLength < sizeof(SOCKADDR_IN))
{
- strcpy(workBuffer,AddressString);
- switch (AddressFamily)
- {
- case AF_INET:
- /* caller wants to know the size of the socket buffer */
- if (*lpAddressLength < sizeof(SOCKADDR_IN))
- {
- *lpAddressLength = sizeof(SOCKADDR_IN);
- res = WSAEFAULT;
- }
- else
- {
- /* caller wants to translate an AddressString into a SOCKADDR */
- if (lpAddress)
- {
- memset(lpAddress,0,sizeof(SOCKADDR_IN));
- ((LPSOCKADDR_IN)lpAddress)->sin_family = AF_INET;
- ptrPort = strchr(workBuffer,':');
- if (ptrPort)
- {
- ((LPSOCKADDR_IN)lpAddress)->sin_port = (WS_u_short)atoi(ptrPort+1);
- *ptrPort = '\0';
- }
- else
- ((LPSOCKADDR_IN)lpAddress)->sin_port = 0;
- if (inet_aton(workBuffer, &inetaddr) > 0)
- {
- ((LPSOCKADDR_IN)lpAddress)->sin_addr.WS_s_addr = inetaddr.s_addr;
- res = 0;
- }
- else
- res = WSAEINVAL;
- }
- }
- if (lpProtocolInfo)
- FIXME("(%s, %x, %p, %p, %p) - ProtocolInfo not implemented!\n",
- AddressString, AddressFamily,
- lpProtocolInfo, lpAddress, lpAddressLength);
+ *lpAddressLength = sizeof(SOCKADDR_IN);
+ res = WSAEFAULT;
+ break;
+ }
+ memset(lpAddress, 0, sizeof(SOCKADDR_IN));
- break;
- default:
- FIXME("(%s, %x, %p, %p, %p) - AddressFamiliy not implemented!\n",
- AddressString, AddressFamily,
- lpProtocolInfo, lpAddress, lpAddressLength);
- }
- HeapFree( GetProcessHeap(), 0, workBuffer );
+ ((LPSOCKADDR_IN)lpAddress)->sin_family = AF_INET;
+
+ ptrPort = strchr(workBuffer, ':');
+ if(ptrPort)
+ {
+ ((LPSOCKADDR_IN)lpAddress)->sin_port = (WS_u_short)atoi(ptrPort+1);
+ *ptrPort = '\0';
}
else
- res = WSA_NOT_ENOUGH_MEMORY;
+ {
+ ((LPSOCKADDR_IN)lpAddress)->sin_port = 0;
+ }
+
+ if(inet_aton(workBuffer, &inetaddr) > 0)
+ {
+ ((LPSOCKADDR_IN)lpAddress)->sin_addr.WS_s_addr = inetaddr.s_addr;
+ res = 0;
+ }
+ else
+ res = WSAEINVAL;
+
+ break;
+
}
- else
+ 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;
+ }
+ FIXME("We don't support IPv6 yet.\n");
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;
WSASetLastError(res);
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c
index cc41320..7eb6d38 100644
--- a/dlls/ws2_32/tests/sock.c
+++ b/dlls/ws2_32/tests/sock.c
@@ -24,6 +24,7 @@
#include <windef.h>
#include <winbase.h>
#include <winsock2.h>
+#include <ws2tcpip.h>
#include <mswsock.h>
#include "wine/test.h"
#include <winnt.h>
@@ -1250,6 +1251,7 @@ static void test_WSAStringToAddressA(void)
{
INT ret, len;
SOCKADDR_IN sockaddr;
+ SOCKADDR_IN6 sockaddr6;
int GLE;
CHAR address1[] = "0.0.0.0";
@@ -1257,6 +1259,9 @@ static void test_WSAStringToAddressA(void)
CHAR address3[] = "255.255.255.255";
CHAR address4[] = "127.127.127.127:65535";
CHAR address5[] = "255.255.255.255:65535";
+ CHAR address6[] = "::1";
+ CHAR address7[] = "[::1]";
+ CHAR address8[] = "[::1]:65535";
len = 0;
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) ||
(ret == SOCKET_ERROR && (GLE == ERROR_INVALID_PARAMETER || GLE == WSAEINVAL)),
"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)
{
INT ret, len;
SOCKADDR_IN sockaddr;
+ SOCKADDR_IN6 sockaddr6;
int GLE;
WCHAR address1[] = { '0','.','0','.','0','.','0', 0 };
@@ -1323,6 +1361,9 @@ static void test_WSAStringToAddressW(void)
':', '6', '5', '5', '3', '5', 0 };
WCHAR address5[] = { '2','5','5','.','2','5','5','.','2','5','5','.','2','5','5', ':',
'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;
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) ||
(ret == SOCKET_ERROR && (GLE == ERROR_INVALID_PARAMETER || GLE == WSAEINVAL)),
"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)
More information about the wine-cvs
mailing list