Implement WSAAddressToString{A,W}.
authorHans Leidekker <hans@it.vu.nl>
Thu, 4 Nov 2004 21:05:48 +0000 (21:05 +0000)
committerAlexandre Julliard <julliard@winehq.org>
Thu, 4 Nov 2004 21:05:48 +0000 (21:05 +0000)
Add tests for WSAAddressToString{A,W} and WSAStringToAddress{A,W}.
Add TRACEs to WSAStringToAddress{A,W}.

dlls/winsock/Makefile.in
dlls/winsock/socket.c
dlls/winsock/tests/sock.c

index ae27824e573fa55b26e1aabaf3438fbff378bc58..5f03748d7e9d8153eb930027ad81b24bdecbe5f9 100644 (file)
@@ -5,6 +5,7 @@ SRCDIR    = @srcdir@
 VPATH     = @srcdir@
 MODULE    = ws2_32.dll
 IMPORTS   = user32 iphlpapi kernel32 ntdll
+EXTRALIBS = $(LIBUNICODE)
 
 C_SRCS = \
        async.c \
index d2d8baac15af4c2c146d6509b48117c8af198f40..035a276a4cdcf4e7ed8bbe885fb14f0cba9678d0 100644 (file)
 #include "thread.h"
 #include "wine/server.h"
 #include "wine/debug.h"
+#include "wine/unicode.h"
 
 #ifdef HAVE_IPX
 # include "wsnwlink.h"
@@ -3693,6 +3694,9 @@ INT WINAPI WSAStringToAddressA(LPSTR AddressString,
     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 );
@@ -3775,6 +3779,9 @@ INT WINAPI WSAStringToAddressW(LPWSTR AddressString,
     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)
     {
@@ -3814,6 +3821,109 @@ INT WINAPI WSAStringToAddressW(LPWSTR AddressString,
     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)
  */
@@ -3846,25 +3956,3 @@ INT WINAPI WSCUnInstallNameSpace( LPGUID lpProviderId )
 
     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;
-}
index 96eabe7eb9eb6232aa31f809ec76796f9fe0a41c..2c73e25603daafaa73213b5f6900aaa7b674c380 100644 (file)
@@ -777,6 +777,248 @@ static test_setup tests [NUM_TESTS] =
     }
 };
 
+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 )
@@ -794,5 +1036,11 @@ START_TEST( sock )
         trace ( " **** TEST %d COMPLETE **** \n", i );
     }
 
+    test_WSAAddressToStringA();
+    test_WSAAddressToStringW();
+
+    test_WSAStringToAddressA();
+    test_WSAStringToAddressW();
+
     Exit();
 }