Implementation of WSAStringToAddress(A/W), WSAHtonl, WSAHtons.

diff --git a/dlls/winsock/socket.c b/dlls/winsock/socket.c
index 0b1c62c..5e23f99 100644
--- a/dlls/winsock/socket.c
+++ b/dlls/winsock/socket.c
@@ -118,6 +118,7 @@
 #include "wingdi.h"
 #include "winuser.h"
 #include "winerror.h"
+#include "winnls.h"
 #include "winsock2.h"
 #include "mswsock.h"
 #include "ws2tcpip.h"
@@ -1665,20 +1666,39 @@
 
 /***********************************************************************
  *		WSAHtonl		(WS2_32.46)
+ *  From MSDN decription of error codes, this function should also
+ *  check if WinSock has been initialized and the socket is a valid
+ *  socket. But why? This function only translates a host byte order
+ *  u_long into a network byte order u_long...
  */
 int WINAPI WSAHtonl(SOCKET s, u_long hostlong, u_long *lpnetlong)
 {
-    FIXME("stub.\n");
-    return INVALID_SOCKET;
+    if (lpnetlong)
+    {
+        *lpnetlong = htonl(hostlong);
+        return 0;
+    }
+    WSASetLastError(WSAEFAULT);
+    return SOCKET_ERROR;
 }
 
 /***********************************************************************
  *		WSAHtons		(WS2_32.47)
+ *  From MSDN decription of error codes, this function should also
+ *  check if WinSock has been initialized and the socket is a valid
+ *  socket. But why? This function only translates a host byte order
+ *  u_short into a network byte order u_short...
  */
 int WINAPI WSAHtons(SOCKET s, u_short hostshort, u_short *lpnetshort)
 {
-    FIXME("stub.\n");
-    return INVALID_SOCKET;
+
+    if (lpnetshort)
+    {
+        *lpnetshort = htons(hostshort);
+        return 0;
+    }
+    WSASetLastError(WSAEFAULT);
+    return SOCKET_ERROR;
 }
 
 
@@ -3564,12 +3584,133 @@
  */
 INT WINAPI WSAStringToAddressA(LPSTR AddressString,
                                INT AddressFamily,
-                               LPWSAPROTOCOL_INFOA lpProtocolInfo, 
+                               LPWSAPROTOCOL_INFOA lpProtocolInfo,
                                LPSOCKADDR lpAddress,
                                LPINT lpAddressLength)
 {
-    FIXME("(%s, %x, %p, %p, %p) Stub!\n", AddressString, AddressFamily, lpProtocolInfo, lpAddress, lpAddressLength);
-    return 0;
+    INT res=0;
+    LONG inetaddr;
+    LPSTR workBuffer=NULL,ptrPort;
+
+    if (AddressString)
+    {
+        workBuffer = HeapAlloc( GetProcessHeap(), 0, strlen(AddressString)+1 );
+        if (workBuffer)
+        {
+            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 AdressString 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 = (u_short)atoi(ptrPort+1);
+                            *ptrPort = '\0';
+                        }
+                        else
+                            ((LPSOCKADDR_IN)lpAddress)->sin_port = 0;
+                        inetaddr = inet_addr(workBuffer);
+                        if (inetaddr != INADDR_NONE)
+                        {
+                            ((LPSOCKADDR_IN)lpAddress)->sin_addr.WS_s_addr = inetaddr;
+                            res = 0;
+                        }
+                        else
+                            res = WSAEINVAL;
+                    }
+                }
+                if (lpProtocolInfo)
+                    FIXME("(%s, %x, %p, %p, %p) - ProtocolInfo not implemented!\n",
+                        AddressString, AddressFamily,
+                        lpProtocolInfo, lpAddress, lpAddressLength);
+
+                break;
+            default:
+                FIXME("(%s, %x, %p, %p, %p) - AddressFamiliy not implemented!\n",
+                    AddressString, AddressFamily,
+                    lpProtocolInfo, lpAddress, lpAddressLength);
+            }
+            HeapFree( GetProcessHeap(), 0, workBuffer );
+        }
+        else
+            res = WSA_NOT_ENOUGH_MEMORY;
+    }
+    else
+        res = WSAEINVAL;
+
+    if (!res) return 0;
+    WSASetLastError(res);
+    return SOCKET_ERROR;
+}
+
+/***********************************************************************
+ *              WSAStringToAddressW                      (WS2_32.81)
+ *
+ * Does anybody know if this functions allows to use 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;
+
+    /* 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 ))
+        {
+            WSASetLastError( 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;
+
+    WSASetLastError(res);
+    return SOCKET_ERROR;
 }
 
 /***********************************************************************
diff --git a/dlls/winsock/ws2_32.spec b/dlls/winsock/ws2_32.spec
index 52f59fb..fe3df27 100644
--- a/dlls/winsock/ws2_32.spec
+++ b/dlls/winsock/ws2_32.spec
@@ -82,7 +82,7 @@
 78  stdcall  WSASocketA(long long long ptr long long)
 79  stub     WSASocketW
 80  stdcall  WSAStringToAddressA(str long ptr ptr ptr)
-81  stub     WSAStringToAddressW
+81  stdcall  WSAStringToAddressW(wstr long ptr ptr ptr)
 82  stdcall  WSAWaitForMultipleEvents(long ptr long long long) kernel32.WaitForMultipleObjectsEx
 83  stdcall  WSCDeinstallProvider(ptr ptr)
 84  stub     WSCEnableNSProvider
diff --git a/include/winsock2.h b/include/winsock2.h
index 21cc3c7..0e4c32f 100644
--- a/include/winsock2.h
+++ b/include/winsock2.h
@@ -558,10 +558,10 @@
 /* WSASetServiceW */
 SOCKET WINAPI WSASocketA(int,int,int,LPWSAPROTOCOL_INFOA,GROUP,DWORD);
 SOCKET WINAPI WSASocketW(int,int,int,LPWSAPROTOCOL_INFOW,GROUP,DWORD);
+#define WSASocket WINELIB_NAME_AW(WSASocket)
 INT WINAPI WSAStringToAddressA(LPSTR,INT,LPWSAPROTOCOL_INFOA,LPSOCKADDR,LPINT);
-INT WINAPI WSAStringToAddressW(LPSTR,INT,LPWSAPROTOCOL_INFOA,LPSOCKADDR,LPINT);
-#define WSASocket                  WINELIB_NAME_AW(WSASocket)
-#define WSAStringToAddress         WINELIB_NAME_AW(WSAStringToAddress)
+INT WINAPI WSAStringToAddressW(LPWSTR,INT,LPWSAPROTOCOL_INFOW,LPSOCKADDR,LPINT);
+#define WSAStringToAddress WINELIB_NAME_AW(WSAStringToAddress)
 DWORD WINAPI WSAWaitForMultipleEvents(DWORD,const WSAEVENT*,BOOL,DWORD,BOOL);
 #endif /* WS_API_PROTOTYPES */