wsock32: Make EnumProtocols a wrapper around WSAEnumProtocols instead of forwarding directly.

Hans Leidekker hans at codeweavers.com
Thu Oct 30 09:06:25 CDT 2008


Fixes http://bugs.winehq.org/show_bug.cgi?id=14731

 -Hans

diff --git a/dlls/wsock32/protocol.c b/dlls/wsock32/protocol.c
index cd2cf71..85cb54b 100644
--- a/dlls/wsock32/protocol.c
+++ b/dlls/wsock32/protocol.c
@@ -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
@@ -36,9 +37,13 @@
 #include "windef.h"
 #include "winbase.h"
 #include "winsock2.h"
+#include "nspapi.h"
 
+#include "wine/debug.h"
 #include "wine/unicode.h"
 
+WINE_DEFAULT_DEBUG_CHANNEL(winsock);
+
 /*****************************************************************************
  *          inet_network       [WSOCK32.1100]
  */
@@ -62,3 +67,131 @@ struct netent * WINAPI WSOCK32_getnetbyname(const char *name)
     return NULL;
 #endif
 }
+
+static DWORD map_service(DWORD wsaflags)
+{
+    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;
+}
+
+/*****************************************************************************
+ *          EnumProtocolsA       [WSOCK32.1111]
+ */
+INT WINAPI EnumProtocolsA(LPINT protocols, LPVOID buffer, LPDWORD buflen)
+{
+    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;
+}
+
+/*****************************************************************************
+ *          EnumProtocolsW       [WSOCK32.1112]
+ */
+INT WINAPI EnumProtocolsW(LPINT protocols, LPVOID buffer, LPDWORD buflen)
+{
+    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;
+}
diff --git a/dlls/wsock32/wsock32.spec b/dlls/wsock32/wsock32.spec
index 9297984..db0b76d 100644
--- a/dlls/wsock32/wsock32.spec
+++ b/dlls/wsock32/wsock32.spec
@@ -62,8 +62,8 @@
 1108 stdcall s_perror(str)
 1109 stdcall GetAddressByNameA(long ptr str ptr long ptr ptr ptr ptr ptr)
 1110 stdcall GetAddressByNameW(long ptr wstr ptr long ptr ptr ptr ptr ptr)
-1111 stdcall EnumProtocolsA(ptr ptr ptr) ws2_32.WSAEnumProtocolsA
-1112 stdcall EnumProtocolsW(ptr ptr ptr) ws2_32.WSAEnumProtocolsW
+1111 stdcall EnumProtocolsA(ptr ptr ptr)
+1112 stdcall EnumProtocolsW(ptr ptr ptr)
 1113 stdcall GetTypeByNameA(str ptr)
 1114 stdcall GetTypeByNameW(wstr ptr)
 #1115 stub GetNameByTypeA



More information about the wine-patches mailing list