wined3d: Add mapping for MOV instructions in shader_hw_map2gl.
[wine] / dlls / wsock32 / protocol.c
index 87e5413..85cb54b 100644 (file)
@@ -2,6 +2,7 @@
  * WSOCK32 specific functions
  *
  * Copyright (C) 2001 Stefan Leichter
+ * Copyright (C) 2008 Hans Leidekker
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
-/* All we need are a couple constants for EnumProtocols. Once it is
- * moved to ws2_32 we may no longer need it
- */
 #define USE_WS_PREFIX
 
 #include "config.h"
 
+#include <stdarg.h>
 #include <stdio.h>
 #include <string.h>
 
-#include <sys/types.h>
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#ifdef HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
 #ifdef HAVE_ARPA_INET_H
 #include <arpa/inet.h>
 #endif
 #include <netdb.h>
 #endif
 
+#include "windef.h"
 #include "winbase.h"
-#include "winnls.h"
-#include "wtypes.h"
-#include "nspapi.h"
 #include "winsock2.h"
-#include "wsipx.h"
-#include "wshisotp.h"
+#include "nspapi.h"
 
-#include "wine/unicode.h"
 #include "wine/debug.h"
+#include "wine/unicode.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(winsock);
 
-/* name of the protocols
- */
-static WCHAR NameIpx[]   = {'I', 'P', 'X', '\0'};
-static WCHAR NameSpx[]   = {'S', 'P', 'X', '\0'};
-static WCHAR NameSpxII[] = {'S', 'P', 'X', ' ', 'I', 'I', '\0'};
-static WCHAR NameTcp[]   = {'T', 'C', 'P', '/', 'I', 'P', '\0'};
-static WCHAR NameUdp[]   = {'U', 'D', 'P', '/', 'I', 'P', '\0'};
-
 /*****************************************************************************
- *          WSOCK32_EnterSingleProtocol [internal]
- *
- *    enters the protocol informations of one given protocol into the
- *    given buffer. If the given buffer is too small only the required size for
- *    the protocols are returned.
- *
- * RETURNS
- *    The number of protocols entered into the buffer
- *
- * BUGS
- *    - only implemented for IPX, SPX, SPXII, TCP, UDP
- *    - there is no check that the operating system supports the returned
- *      protocols
- */
-static INT WSOCK32_EnterSingleProtocol( INT iProtocol,
-                                        PROTOCOL_INFOA* lpBuffer,
-                                        LPDWORD lpSize, BOOL unicode)
-{ DWORD  dwLength = 0, dwOldSize = *lpSize;
-  INT    iAnz = 1;
-  WCHAR  *lpProtName = NULL;
-
-  *lpSize = sizeof( PROTOCOL_INFOA);
-  switch (iProtocol) {
-    case WS_IPPROTO_TCP :
-        dwLength = (unicode) ? sizeof(WCHAR) * (strlenW(NameTcp)+1) :
-                               WideCharToMultiByte( CP_ACP, 0, NameTcp, -1,
-                                                    NULL, 0, NULL, NULL);
-      break;
-    case WS_IPPROTO_UDP :
-        dwLength = (unicode) ? sizeof(WCHAR) * (strlenW(NameUdp)+1) :
-                               WideCharToMultiByte( CP_ACP, 0, NameUdp, -1,
-                                                    NULL, 0, NULL, NULL);
-      break;
-    case NSPROTO_IPX :
-        dwLength = (unicode) ? sizeof(WCHAR) * (strlenW(NameIpx)+1) :
-                               WideCharToMultiByte( CP_ACP, 0, NameIpx, -1,
-                                                    NULL, 0, NULL, NULL);
-      break;
-    case NSPROTO_SPX :
-        dwLength = (unicode) ? sizeof(WCHAR) * (strlenW(NameSpx)+1) :
-                               WideCharToMultiByte( CP_ACP, 0, NameSpx, -1,
-                                                    NULL, 0, NULL, NULL);
-      break;
-    case NSPROTO_SPXII :
-        dwLength = (unicode) ? sizeof(WCHAR) * (strlenW(NameSpxII)+1) :
-                               WideCharToMultiByte( CP_ACP, 0, NameSpxII, -1,
-                                                    NULL, 0, NULL, NULL);
-      break;
-    default:
-        *lpSize = 0;
-        if ((iProtocol == ISOPROTO_TP4) || (iProtocol == NSPROTO_SPX))
-          FIXME("Protocol <%s> not implemented\n",
-                (iProtocol == ISOPROTO_TP4) ? "ISOPROTO_TP4" : "NSPROTO_SPX");
-        else
-          FIXME("unknown Protocol <0x%08x>\n", iProtocol);
-      break;
-  }
-  *lpSize += dwLength;
-
-  if ( !lpBuffer || !*lpSize || (*lpSize > dwOldSize))
-     return 0;
-
-  memset( lpBuffer, 0, dwOldSize);
-
-  lpBuffer->lpProtocol = (LPSTR) &lpBuffer[ iAnz];
-  lpBuffer->iProtocol  = iProtocol;
-
-  switch (iProtocol) {
-    case WS_IPPROTO_TCP :
-        lpBuffer->dwServiceFlags = XP_FRAGMENTATION      | XP_EXPEDITED_DATA     |
-                                   XP_GRACEFUL_CLOSE     | XP_GUARANTEED_ORDER   |
-                                   XP_GUARANTEED_DELIVERY;
-        lpBuffer->iAddressFamily = WS_AF_INET;
-        lpBuffer->iMaxSockAddr   = 0x10;  /* NT4 SP5 */
-        lpBuffer->iMinSockAddr   = 0x10;  /* NT4 SP5 */
-        lpBuffer->iSocketType    = SOCK_STREAM;
-        lpBuffer->dwMessageSize  = 0;
-        lpProtName = NameTcp;
-      break;
-    case WS_IPPROTO_UDP :
-        lpBuffer->dwServiceFlags = XP_FRAGMENTATION      | XP_SUPPORTS_BROADCAST |
-                                   XP_SUPPORTS_MULTICAST | XP_MESSAGE_ORIENTED   |
-                                   XP_CONNECTIONLESS;
-        lpBuffer->iAddressFamily = WS_AF_INET;
-        lpBuffer->iMaxSockAddr   = 0x10;  /* NT4 SP5 */
-        lpBuffer->iMinSockAddr   = 0x10;  /* NT4 SP5 */
-        lpBuffer->iSocketType    = SOCK_DGRAM;
-        lpBuffer->dwMessageSize  = 65457; /* NT4 SP5 */
-        lpProtName = NameUdp;
-      break;
-    case NSPROTO_IPX :
-        lpBuffer->dwServiceFlags = XP_FRAGMENTATION      | XP_SUPPORTS_BROADCAST |
-                                   XP_SUPPORTS_MULTICAST | XP_MESSAGE_ORIENTED   |
-                                   XP_CONNECTIONLESS;
-        lpBuffer->iAddressFamily = WS_AF_IPX;
-        lpBuffer->iMaxSockAddr   = 0x10;  /* NT4 SP5 */
-        lpBuffer->iMinSockAddr   = 0x0e;  /* NT4 SP5 */
-        lpBuffer->iSocketType    = SOCK_DGRAM;
-        lpBuffer->dwMessageSize  = 576;   /* NT4 SP5 */
-        lpProtName = NameIpx;
-      break;
-    case NSPROTO_SPX :
-        lpBuffer->dwServiceFlags = XP_FRAGMENTATION      |
-                                   XP_PSEUDO_STREAM      | XP_MESSAGE_ORIENTED   |
-                                   XP_GUARANTEED_ORDER   | XP_GUARANTEED_DELIVERY;
-        lpBuffer->iAddressFamily = WS_AF_IPX;
-        lpBuffer->iMaxSockAddr   = 0x10;  /* NT4 SP5 */
-        lpBuffer->iMinSockAddr   = 0x0e;  /* NT4 SP5 */
-        lpBuffer->iSocketType    = 5;
-        lpBuffer->dwMessageSize  = -1;    /* NT4 SP5 */
-        lpProtName = NameSpx;
-      break;
-    case NSPROTO_SPXII :
-        lpBuffer->dwServiceFlags = XP_FRAGMENTATION      | XP_GRACEFUL_CLOSE     |
-                                   XP_PSEUDO_STREAM      | XP_MESSAGE_ORIENTED   |
-                                   XP_GUARANTEED_ORDER   | XP_GUARANTEED_DELIVERY;
-        lpBuffer->iAddressFamily = WS_AF_IPX;
-        lpBuffer->iMaxSockAddr   = 0x10;  /* NT4 SP5 */
-        lpBuffer->iMinSockAddr   = 0x0e;  /* NT4 SP5 */
-        lpBuffer->iSocketType    = 5;
-        lpBuffer->dwMessageSize  = -1;    /* NT4 SP5 */
-        lpProtName = NameSpxII;
-      break;
-  }
-  if (unicode)
-    strcpyW( (LPWSTR)lpBuffer->lpProtocol, lpProtName);
-  else
-    WideCharToMultiByte( CP_ACP, 0, lpProtName, -1, lpBuffer->lpProtocol,
-                         dwOldSize - iAnz * sizeof( PROTOCOL_INFOA), NULL, NULL);
-
-  return iAnz;
-}
-
-/* FIXME: EnumProtocols should be moved to winsock2, and this should be
- * implemented by calling out to WSAEnumProtocols. See:
- * http://support.microsoft.com/support/kb/articles/Q129/3/15.asp
- */
-/*****************************************************************************
- *          WSOCK32_EnumProtocol [internal]
- *
- *    Enters the information about installed protocols into a given buffer
- *
- * RETURNS
- *    SOCKET_ERROR if the buffer is to small for the requested protocol infos
- *    on success the number of protocols inside the buffer
- *
- * NOTE
- *    NT4SP5 does not return SPX if lpiProtocols == NULL
- *
- * BUGS
- *    - NT4SP5 returns in addition these list of NETBIOS protocols
- *      (address family 17), each entry two times one for socket type 2 and 5
- *
- *      iProtocol   lpProtocol
- *      0x80000000  \Device\NwlnkNb
- *      0xfffffffa  \Device\NetBT_CBENT7
- *      0xfffffffb  \Device\Nbf_CBENT7
- *      0xfffffffc  \Device\NetBT_NdisWan5
- *      0xfffffffd  \Device\NetBT_El9202
- *      0xfffffffe  \Device\Nbf_El9202
- *      0xffffffff  \Device\Nbf_NdisWan4
- *
- *    - there is no check that the operating system supports the returned
- *      protocols
+ *          inet_network       [WSOCK32.1100]
  */
-static INT WSOCK32_EnumProtocol( LPINT lpiProtocols, PROTOCOL_INFOA* lpBuffer,
-                                 LPDWORD lpdwLength, BOOL unicode)
-{ DWORD dwCurSize, dwOldSize = *lpdwLength, dwTemp;
-  INT   anz = 0, i;
-  INT   iLocal[] = { WS_IPPROTO_TCP, WS_IPPROTO_UDP, NSPROTO_IPX, NSPROTO_SPXII, 0};
-
-  if (!lpiProtocols) lpiProtocols = iLocal;
-
-  *lpdwLength = 0;
-  while ( *lpiProtocols )
-  { dwCurSize = 0;
-    WSOCK32_EnterSingleProtocol( *lpiProtocols, NULL, &dwCurSize, unicode);
-
-    if ( lpBuffer && dwCurSize && ((*lpdwLength + dwCurSize) <= dwOldSize))
-    { /* reserve the required space for the current protocol_info after the
-       * last protocol_info before the start of the string buffer and adjust
-       * the references into the string buffer
-       */
-      memmove( &((char*)&lpBuffer[ anz])[dwCurSize],
-                 &lpBuffer[ anz],
-               *lpdwLength - anz * sizeof( PROTOCOL_INFOA));
-      for (i=0; i < anz; i++)
-        lpBuffer[i].lpProtocol += dwCurSize;
-
-      dwTemp = dwCurSize;
-      anz += WSOCK32_EnterSingleProtocol( *lpiProtocols, &lpBuffer[anz],
-                                          &dwTemp, unicode);
-    }
-
-    *lpdwLength += dwCurSize;
-    lpiProtocols++;
-  }
-
-  if (dwOldSize < *lpdwLength) anz = SOCKET_ERROR;
-
-  return anz;
+UINT WINAPI WSOCK32_inet_network(const char *cp)
+{
+#ifdef HAVE_INET_NETWORK
+    return inet_network(cp);
+#else
+    return 0;
+#endif
 }
 
 /*****************************************************************************
- *          EnumProtocolsA       [WSOCK32.1111]
- *
- *    see function WSOCK32_EnumProtocol for RETURNS, BUGS
+ *          getnetbyname       [WSOCK32.1101]
  */
-INT WINAPI EnumProtocolsA( LPINT lpiProtocols, LPVOID lpBuffer,
-                           LPDWORD lpdwLength)
+struct netent * WINAPI WSOCK32_getnetbyname(const char *name)
 {
-   return WSOCK32_EnumProtocol( lpiProtocols, (PROTOCOL_INFOA*) lpBuffer,
-                                lpdwLength, FALSE);
+#ifdef HAVE_GETNETBYNAME
+    return getnetbyname(name);
+#else
+    return NULL;
+#endif
 }
 
-/*****************************************************************************
- *          EnumProtocolsW       [WSOCK32.1112]
- *
- *    see function WSOCK32_EnumProtocol for RETURNS, BUGS
- */
-INT WINAPI EnumProtocolsW( LPINT lpiProtocols, LPVOID lpBuffer,
-                           LPDWORD lpdwLength)
+static DWORD map_service(DWORD wsaflags)
 {
-   return WSOCK32_EnumProtocol( lpiProtocols, (PROTOCOL_INFOA*) lpBuffer,
-                                lpdwLength, TRUE);
+    DWORD flags = 0;
+
+    if (wsaflags & XP1_CONNECTIONLESS)      flags |= XP_CONNECTIONLESS;
+    if (wsaflags & XP1_GUARANTEED_DELIVERY) flags |= XP_GUARANTEED_DELIVERY;
+    if (wsaflags & XP1_GUARANTEED_ORDER)    flags |= XP_GUARANTEED_ORDER;
+    if (wsaflags & XP1_MESSAGE_ORIENTED)    flags |= XP_MESSAGE_ORIENTED;
+    if (wsaflags & XP1_PSEUDO_STREAM)       flags |= XP_PSEUDO_STREAM;
+    if (wsaflags & XP1_GRACEFUL_CLOSE)      flags |= XP_GRACEFUL_CLOSE;
+    if (wsaflags & XP1_EXPEDITED_DATA)      flags |= XP_EXPEDITED_DATA;
+    if (wsaflags & XP1_CONNECT_DATA)        flags |= XP_CONNECT_DATA;
+    if (wsaflags & XP1_DISCONNECT_DATA)     flags |= XP_DISCONNECT_DATA;
+    if (wsaflags & XP1_SUPPORT_BROADCAST)   flags |= XP_SUPPORTS_BROADCAST;
+    if (wsaflags & XP1_SUPPORT_MULTIPOINT)  flags |= XP_SUPPORTS_MULTICAST;
+    if (wsaflags & XP1_QOS_SUPPORTED)       flags |= XP_BANDWITH_ALLOCATION;
+    if (wsaflags & XP1_PARTIAL_MESSAGE)     flags |= XP_FRAGMENTATION;
+    return flags;
 }
 
 /*****************************************************************************
- *          inet_network       [WSOCK32.1100]
+ *          EnumProtocolsA       [WSOCK32.1111]
  */
-UINT WINAPI WSOCK32_inet_network(const char *cp)
+INT WINAPI EnumProtocolsA(LPINT protocols, LPVOID buffer, LPDWORD buflen)
 {
-    return inet_network(cp);
+    INT ret;
+    DWORD size, string_size = WSAPROTOCOL_LEN + 1;
+
+    TRACE("%p, %p, %p\n", protocols, buffer, buflen);
+
+    if (!buflen) return SOCKET_ERROR;
+
+    size = 0;
+    ret = WSAEnumProtocolsA(protocols, NULL, &size);
+
+    if (ret == SOCKET_ERROR && WSAGetLastError() == WSAENOBUFS)
+    {
+        DWORD num_protocols = size / sizeof(WSAPROTOCOL_INFOA);
+        if (*buflen < num_protocols * (sizeof(PROTOCOL_INFOA) + string_size))
+        {
+            *buflen = num_protocols * (sizeof(PROTOCOL_INFOA) + string_size);
+            return SOCKET_ERROR;
+        }
+        if (buffer)
+        {
+            WSAPROTOCOL_INFOA *wsabuf;
+            PROTOCOL_INFOA *pi = buffer;
+            unsigned int i, string_offset;
+
+            if (!(wsabuf = HeapAlloc(GetProcessHeap(), 0, size))) return SOCKET_ERROR;
+
+            ret = WSAEnumProtocolsA(protocols, wsabuf, &size);
+            string_offset = ret * sizeof(PROTOCOL_INFOA);
+
+            for (i = 0; i < ret; i++)
+            {
+                pi[i].dwServiceFlags = map_service(wsabuf[i].dwServiceFlags1);
+                pi[i].iAddressFamily = wsabuf[i].iAddressFamily;
+                pi[i].iMaxSockAddr   = wsabuf[i].iMaxSockAddr;
+                pi[i].iMinSockAddr   = wsabuf[i].iMinSockAddr;
+                pi[i].iSocketType    = wsabuf[i].iSocketType;
+                pi[i].iProtocol      = wsabuf[i].iProtocol;
+                pi[i].dwMessageSize  = wsabuf[i].dwMessageSize;
+
+                memcpy((char *)buffer + string_offset, wsabuf[i].szProtocol, string_size);
+                pi[i].lpProtocol = (char *)buffer + string_offset;
+                string_offset += string_size;
+            }
+            HeapFree(GetProcessHeap(), 0, wsabuf);
+        }
+    }
+    return ret;
 }
 
 /*****************************************************************************
- *          getnetbyname       [WSOCK32.1101]
+ *          EnumProtocolsW       [WSOCK32.1112]
  */
-struct netent * WINAPI WSOCK32_getnetbyname(const char *name)
+INT WINAPI EnumProtocolsW(LPINT protocols, LPVOID buffer, LPDWORD buflen)
 {
-#ifdef HAVE_GETNETBYNAME
-    return getnetbyname(name);
-#else
-    return NULL;
-#endif
+    INT ret;
+    DWORD size, string_size = (WSAPROTOCOL_LEN + 1) * sizeof(WCHAR);
+
+    TRACE("%p, %p, %p\n", protocols, buffer, buflen);
+
+    if (!buflen) return SOCKET_ERROR;
+
+    size = 0;
+    ret = WSAEnumProtocolsW(protocols, NULL, &size);
+
+    if (ret == SOCKET_ERROR && WSAGetLastError() == WSAENOBUFS)
+    {
+        DWORD num_protocols = size / sizeof(WSAPROTOCOL_INFOW);
+        if (*buflen < num_protocols * (sizeof(PROTOCOL_INFOW) + string_size))
+        {
+            *buflen = num_protocols * (sizeof(PROTOCOL_INFOW) + string_size);
+            return SOCKET_ERROR;
+        }
+        if (buffer)
+        {
+            WSAPROTOCOL_INFOW *wsabuf;
+            PROTOCOL_INFOW *pi = buffer;
+            unsigned int i, string_offset;
+
+            if (!(wsabuf = HeapAlloc(GetProcessHeap(), 0, size))) return SOCKET_ERROR;
+
+            ret = WSAEnumProtocolsW(protocols, wsabuf, &size);
+            string_offset = ret * sizeof(PROTOCOL_INFOW);
+
+            for (i = 0; i < ret; i++)
+            {
+                pi[i].dwServiceFlags = map_service(wsabuf[i].dwServiceFlags1);
+                pi[i].iAddressFamily = wsabuf[i].iAddressFamily;
+                pi[i].iMaxSockAddr   = wsabuf[i].iMaxSockAddr;
+                pi[i].iMinSockAddr   = wsabuf[i].iMinSockAddr;
+                pi[i].iSocketType    = wsabuf[i].iSocketType;
+                pi[i].iProtocol      = wsabuf[i].iProtocol;
+                pi[i].dwMessageSize  = wsabuf[i].dwMessageSize;
+
+                memcpy((char *)buffer + string_offset, wsabuf[i].szProtocol, string_size);
+                pi[i].lpProtocol = (WCHAR *)(char *)buffer + string_offset;
+                string_offset += string_size;
+            }
+            HeapFree(GetProcessHeap(), 0, wsabuf);
+        }
+    }
+    return ret;
 }