#include "thread.h"
#include "wine/server.h"
#include "wine/debug.h"
+#include "wine/unicode.h"
#ifdef HAVE_IPX
# include "wsnwlink.h"
LONG inetaddr;
LPSTR workBuffer=NULL,ptrPort;
+ TRACE( "(%s, %x, %p, %p, %d)\n", AddressString, AddressFamily, lpProtocolInfo,
+ lpAddress, *lpAddressLength );
+
if (AddressString)
{
workBuffer = HeapAlloc( GetProcessHeap(), 0, strlen(AddressString)+1 );
WSAPROTOCOL_INFOA infoA;
LPWSAPROTOCOL_INFOA lpProtoInfoA = NULL;
+ TRACE( "(%s, %x, %p, %p, %d)\n", debugstr_w(AddressString), AddressFamily, lpProtocolInfo,
+ lpAddress, *lpAddressLength );
+
/* if ProtocolInfo is available - convert to ANSI variant */
if (lpProtocolInfo)
{
return SOCKET_ERROR;
}
+/***********************************************************************
+ * WSAAddressToStringA (WS2_32.27)
+ *
+ * See WSAAddressToStringW
+ */
+INT WINAPI WSAAddressToStringA( LPSOCKADDR sockaddr, DWORD len,
+ LPWSAPROTOCOL_INFOA info, LPSTR string,
+ LPDWORD lenstr )
+{
+ INT size;
+ CHAR buffer[22]; /* 12 digits + 3 dots + ':' + 5 digits + '\0' */
+ static const CHAR format[] = "%d.%d.%d.%d:%d";
+ CHAR *p;
+
+ TRACE( "(%p, %lx, %p, %p, %ld)\n", sockaddr, len, info, string, *lenstr );
+
+ if (!sockaddr || len < sizeof(SOCKADDR_IN)) return SOCKET_ERROR;
+
+ /* sin_family is garanteed to be the first u_short */
+ if (((SOCKADDR_IN *)sockaddr)->sin_family != AF_INET) return SOCKET_ERROR;
+
+ sprintf( buffer, format,
+ ntohl( ((SOCKADDR_IN *)sockaddr)->sin_addr.WS_s_addr ) >> 24 & 0xff,
+ ntohl( ((SOCKADDR_IN *)sockaddr)->sin_addr.WS_s_addr ) >> 16 & 0xff,
+ ntohl( ((SOCKADDR_IN *)sockaddr)->sin_addr.WS_s_addr ) >> 8 & 0xff,
+ ntohl( ((SOCKADDR_IN *)sockaddr)->sin_addr.WS_s_addr ) & 0xff,
+ ntohs( ((SOCKADDR_IN *)sockaddr)->sin_port ) );
+
+ p = strchr( buffer, ':' );
+ if (!((SOCKADDR_IN *)sockaddr)->sin_port) *p = 0;
+
+ size = strlen( buffer );
+
+ if (*lenstr < size)
+ {
+ *lenstr = size;
+ return SOCKET_ERROR;
+ }
+
+ 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.
+ *
+ * BUGS
+ * Only supports AF_INET addresses.
+ */
+INT WINAPI WSAAddressToStringW( LPSOCKADDR sockaddr, DWORD len,
+ LPWSAPROTOCOL_INFOW info, LPWSTR string,
+ LPDWORD lenstr )
+{
+ INT size;
+ WCHAR buffer[22]; /* 12 digits + 3 dots + ':' + 5 digits + '\0' */
+ static const WCHAR format[] = { '%','d','.','%','d','.','%','d','.','%','d', ':', '%', 'd',0 };
+ WCHAR *p;
+
+ TRACE( "(%p, %lx, %p, %p, %ld)\n", sockaddr, len, info, string, *lenstr );
+
+ if (!sockaddr || len < sizeof(SOCKADDR_IN)) return SOCKET_ERROR;
+
+ /* sin_family is garanteed to be the first u_short */
+ if (((SOCKADDR_IN *)sockaddr)->sin_family != AF_INET) return SOCKET_ERROR;
+
+ sprintfW( buffer, format,
+ ntohl( ((SOCKADDR_IN *)sockaddr)->sin_addr.WS_s_addr ) >> 24 & 0xff,
+ ntohl( ((SOCKADDR_IN *)sockaddr)->sin_addr.WS_s_addr ) >> 16 & 0xff,
+ ntohl( ((SOCKADDR_IN *)sockaddr)->sin_addr.WS_s_addr ) >> 8 & 0xff,
+ ntohl( ((SOCKADDR_IN *)sockaddr)->sin_addr.WS_s_addr ) & 0xff,
+ ntohs( ((SOCKADDR_IN *)sockaddr)->sin_port ) );
+
+ p = strchrW( buffer, ':' );
+ if (!((SOCKADDR_IN *)sockaddr)->sin_port) *p = 0;
+
+ size = lstrlenW( buffer );
+
+ if (*lenstr < size)
+ {
+ *lenstr = size;
+ return SOCKET_ERROR;
+ }
+
+ lstrcpyW( string, buffer );
+ return 0;
+}
+
/***********************************************************************
* WSALookupServiceBeginA (WS2_32.59)
*/
return NO_ERROR;
}
-
-INT WINAPI WSAAddressToStringA(LPSOCKADDR lpsaAddress,
- DWORD dwAddressLenght,
- LPWSAPROTOCOL_INFOA lpProtocolInfo,
- LPSTR lpszAddressString,
- LPDWORD lpdwAddressStringLength)
-{
- FIXME("Stub!");
- WSASetLastError(WSAENOBUFS);
- return SOCKET_ERROR;
-}
-
-INT WINAPI WSAAddressToStringW(LPSOCKADDR lpsaAddress,
- DWORD dwAddressLenght,
- LPWSAPROTOCOL_INFOW lpProtocolInfo,
- LPWSTR lpszAddressString,
- LPDWORD lpdwAddressStringLength)
-{
- FIXME("Stub!");
- WSASetLastError(WSAENOBUFS);
- return SOCKET_ERROR;
-}
}
};
+static void test_WSAAddressToStringA()
+{
+ INT ret;
+ DWORD len;
+ SOCKADDR_IN sockaddr;
+ CHAR address[22]; /* 12 digits + 3 dots + ':' + 5 digits + '\0' */
+
+ CHAR expect1[] = "0.0.0.0";
+ CHAR expect2[] = "255.255.255.255";
+ CHAR expect3[] = "0.0.0.0:65535";
+ CHAR expect4[] = "255.255.255.255:65535";
+
+ len = 0;
+
+ sockaddr.sin_family = AF_INET;
+ sockaddr.sin_port = 0;
+ sockaddr.sin_addr.s_addr = 0;
+
+ ret = WSAAddressToStringA( (SOCKADDR*)&sockaddr, sizeof(sockaddr), NULL, address, &len );
+ ok( ret == SOCKET_ERROR, "WSAAddressToStringA() succeeded unexpectedly: %d\n", WSAGetLastError() );
+
+ len = sizeof(address);
+
+ sockaddr.sin_family = AF_INET;
+ sockaddr.sin_port = 0;
+ sockaddr.sin_addr.s_addr = 0;
+
+ ret = WSAAddressToStringA( (SOCKADDR*)&sockaddr, sizeof(sockaddr), NULL, address, &len );
+ ok( !ret, "WSAAddressToStringA() failed unexpectedly: %d\n", WSAGetLastError() );
+
+ ok( !strcmp( address, expect1 ), "Expected: %s, got: %s\n", expect1, address );
+
+ len = sizeof(address);
+
+ sockaddr.sin_family = AF_INET;
+ sockaddr.sin_port = 0;
+ sockaddr.sin_addr.s_addr = 0xffffffff;
+
+ ret = WSAAddressToStringA( (SOCKADDR*)&sockaddr, sizeof(sockaddr), NULL, address, &len );
+ ok( !ret, "WSAAddressToStringA() failed unexpectedly: %d\n", WSAGetLastError() );
+
+ ok( !strcmp( address, expect2 ), "Expected: %s, got: %s\n", expect2, address );
+
+ len = sizeof(address);
+
+ sockaddr.sin_family = AF_INET;
+ sockaddr.sin_port = 0xffff;
+ sockaddr.sin_addr.s_addr = 0;
+
+ ret = WSAAddressToStringA( (SOCKADDR*)&sockaddr, sizeof(sockaddr), NULL, address, &len );
+ ok( !ret, "WSAAddressToStringA() failed unexpectedly: %d\n", WSAGetLastError() );
+
+ ok( !strcmp( address, expect3 ), "Expected: %s, got: %s\n", expect3, address );
+
+ len = sizeof(address);
+
+ sockaddr.sin_family = AF_INET;
+ sockaddr.sin_port = 0xffff;
+ sockaddr.sin_addr.s_addr = 0xffffffff;
+
+ ret = WSAAddressToStringA( (SOCKADDR*)&sockaddr, sizeof(sockaddr), NULL, address, &len );
+ ok( !ret, "WSAAddressToStringA() failed unexpectedly: %d\n", WSAGetLastError() );
+
+ ok( !strcmp( address, expect4 ), "Expected: %s, got: %s\n", expect4, address );
+}
+
+static void test_WSAAddressToStringW()
+{
+ INT ret;
+ DWORD len;
+ SOCKADDR_IN sockaddr;
+ WCHAR address[22]; /* 12 digits + 3 dots + ':' + 5 digits + '\0' */
+
+ WCHAR expect1[] = { '0','.','0','.','0','.','0', 0 };
+ WCHAR expect2[] = { '2','5','5','.','2','5','5','.','2','5','5','.','2','5','5', 0 };
+ WCHAR expect3[] = { '0','.','0','.','0','.','0', ':', '6', '5', '5', '3', '5', 0 };
+ WCHAR expect4[] = { '2','5','5','.','2','5','5','.','2','5','5','.','2','5','5', ':',
+ '6', '5', '5', '3', '5', 0 };
+
+ len = 0;
+
+ sockaddr.sin_family = AF_INET;
+ sockaddr.sin_port = 0;
+ sockaddr.sin_addr.s_addr = 0;
+
+ ret = WSAAddressToStringW( (SOCKADDR*)&sockaddr, sizeof(sockaddr), NULL, address, &len );
+ ok( ret == SOCKET_ERROR, "WSAAddressToStringW() succeeded unexpectedly: %x\n", WSAGetLastError() );
+
+ len = sizeof(address);
+
+ sockaddr.sin_family = AF_INET;
+ sockaddr.sin_port = 0;
+ sockaddr.sin_addr.s_addr = 0;
+
+ ret = WSAAddressToStringW( (SOCKADDR*)&sockaddr, sizeof(sockaddr), NULL, address, &len );
+ ok( !ret, "WSAAddressToStringW() failed unexpectedly: %x\n", WSAGetLastError() );
+
+ ok( !lstrcmpW( address, expect1 ), "Expected different address string\n" );
+
+ len = sizeof(address);
+
+ sockaddr.sin_family = AF_INET;
+ sockaddr.sin_port = 0;
+ sockaddr.sin_addr.s_addr = 0xffffffff;
+
+ ret = WSAAddressToStringW( (SOCKADDR*)&sockaddr, sizeof(sockaddr), NULL, address, &len );
+ ok( !ret, "WSAAddressToStringW() failed unexpectedly: %x\n", WSAGetLastError() );
+
+ ok( !lstrcmpW( address, expect2 ), "Expected different address string\n" );
+
+ len = sizeof(address);
+
+ sockaddr.sin_family = AF_INET;
+ sockaddr.sin_port = 0xffff;
+ sockaddr.sin_addr.s_addr = 0;
+
+ ret = WSAAddressToStringW( (SOCKADDR*)&sockaddr, sizeof(sockaddr), NULL, address, &len );
+ ok( !ret, "WSAAddressToStringW() failed unexpectedly: %x\n", WSAGetLastError() );
+
+ ok( !lstrcmpW( address, expect3 ), "Expected different address string\n" );
+
+ len = sizeof(address);
+
+ sockaddr.sin_family = AF_INET;
+ sockaddr.sin_port = 0xffff;
+ sockaddr.sin_addr.s_addr = 0xffffffff;
+
+ ret = WSAAddressToStringW( (SOCKADDR*)&sockaddr, sizeof(sockaddr), NULL, address, &len );
+ ok( !ret, "WSAAddressToStringW() failed unexpectedly: %x\n", WSAGetLastError() );
+
+ ok( !lstrcmpW( address, expect4 ), "Expected different address string\n" );
+}
+
+static void test_WSAStringToAddressA()
+{
+ INT ret, len;
+ SOCKADDR_IN sockaddr;
+
+ CHAR address1[] = "0.0.0.0";
+ CHAR address2[] = "127.127.127.127";
+ CHAR address3[] = "255.255.255.255";
+ CHAR address4[] = "127.127.127.127:65535";
+ CHAR address5[] = "255.255.255.255:65535";
+
+ len = 0;
+ sockaddr.sin_family = AF_INET;
+
+ ret = WSAStringToAddressA( address1, AF_INET, NULL, (SOCKADDR*)&sockaddr, &len );
+ ok( ret == SOCKET_ERROR, "WSAStringToAddressA() succeeded unexpectedly: %x\n",
+ WSAGetLastError() );
+
+ len = sizeof(sockaddr);
+ sockaddr.sin_port = 0;
+ sockaddr.sin_addr.s_addr = 0;
+
+ ret = WSAStringToAddressA( address1, AF_INET, NULL, (SOCKADDR*)&sockaddr, &len );
+ ok( !ret && sockaddr.sin_addr.s_addr == 0,
+ "WSAStringToAddressA() failed unexpectedly: %d\n", WSAGetLastError() );
+
+ len = sizeof(sockaddr);
+ sockaddr.sin_port = 0;
+ sockaddr.sin_addr.s_addr = 0;
+
+ ret = WSAStringToAddressA( address2, AF_INET, NULL, (SOCKADDR*)&sockaddr, &len );
+ ok( !ret && sockaddr.sin_addr.s_addr == 0x7f7f7f7f,
+ "WSAStringToAddressA() failed unexpectedly: %d\n", WSAGetLastError() );
+
+ len = sizeof(sockaddr);
+
+ ret = WSAStringToAddressA( address3, AF_INET, NULL, (SOCKADDR*)&sockaddr, &len );
+ ok( ret, "WSAStringToAddressA() succeeded unexpectedly: %d\n", WSAGetLastError() );
+
+ len = sizeof(sockaddr);
+ sockaddr.sin_port = 0;
+ sockaddr.sin_addr.s_addr = 0;
+
+ ret = WSAStringToAddressA( address4, AF_INET, NULL, (SOCKADDR*)&sockaddr, &len );
+ ok( !ret && sockaddr.sin_addr.s_addr == 0x7f7f7f7f && sockaddr.sin_port == 0xffff,
+ "WSAStringToAddressA() failed unexpectedly: %d\n", WSAGetLastError() );
+
+ len = sizeof(sockaddr);
+
+ ret = WSAStringToAddressA( address5, AF_INET, NULL, (SOCKADDR*)&sockaddr, &len );
+ ok( ret, "WSAStringToAddressA() succeeded unexpectedly: %d\n", WSAGetLastError() );
+}
+
+static void test_WSAStringToAddressW()
+{
+ INT ret, len;
+ SOCKADDR_IN sockaddr;
+
+ WCHAR address1[] = { '0','.','0','.','0','.','0', 0 };
+ WCHAR address2[] = { '1','2','7','.','1','2','7','.','1','2','7','.','1','2','7', 0 };
+ WCHAR address3[] = { '2','5','5','.','2','5','5','.','2','5','5','.','2','5','5', 0 };
+ WCHAR address4[] = { '1','2','7','.','1','2','7','.','1','2','7','.','1','2','7',
+ ':', '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 };
+
+ len = 0;
+ sockaddr.sin_family = AF_INET;
+
+ ret = WSAStringToAddressW( address1, AF_INET, NULL, (SOCKADDR*)&sockaddr, &len );
+ ok( ret == SOCKET_ERROR, "WSAStringToAddressW() failed unexpectedly: %d\n",
+ WSAGetLastError() );
+
+ len = sizeof(sockaddr);
+ sockaddr.sin_port = 0;
+ sockaddr.sin_addr.s_addr = 0;
+
+ ret = WSAStringToAddressW( address1, AF_INET, NULL, (SOCKADDR*)&sockaddr, &len );
+ ok( !ret && sockaddr.sin_addr.s_addr == 0,
+ "WSAStringToAddressW() failed unexpectedly: %d\n", WSAGetLastError() );
+
+ len = sizeof(sockaddr);
+
+ sockaddr.sin_port = 0;
+ sockaddr.sin_addr.s_addr = 0;
+
+ ret = WSAStringToAddressW( address2, AF_INET, NULL, (SOCKADDR*)&sockaddr, &len );
+ ok( !ret && sockaddr.sin_addr.s_addr == 0x7f7f7f7f,
+ "WSAStringToAddressW() failed unexpectedly: %d\n", WSAGetLastError() );
+
+ len = sizeof(sockaddr);
+
+ ret = WSAStringToAddressW( address3, AF_INET, NULL, (SOCKADDR*)&sockaddr, &len );
+ ok( ret, "WSAStringToAddressW() failed unexpectedly: %d\n", WSAGetLastError() );
+
+ len = sizeof(sockaddr);
+ sockaddr.sin_port = 0;
+ sockaddr.sin_addr.s_addr = 0;
+
+ ret = WSAStringToAddressW( address4, AF_INET, NULL, (SOCKADDR*)&sockaddr, &len );
+ ok( !ret && sockaddr.sin_addr.s_addr == 0x7f7f7f7f && sockaddr.sin_port == 0xffff,
+ "WSAStringToAddressW() failed unexpectedly: %d\n", WSAGetLastError() );
+
+ len = sizeof(sockaddr);
+
+ ret = WSAStringToAddressW( address5, AF_INET, NULL, (SOCKADDR*)&sockaddr, &len );
+ ok( ret, "WSAStringToAddressW() succeeded unexpectedly: %d\n", WSAGetLastError() );
+}
+
/**************** Main program ***************/
START_TEST( sock )
trace ( " **** TEST %d COMPLETE **** \n", i );
}
+ test_WSAAddressToStringA();
+ test_WSAAddressToStringW();
+
+ test_WSAStringToAddressA();
+ test_WSAStringToAddressW();
+
Exit();
}