Module: wine Branch: master Commit: bc5dd3022a448c51a2915d1ca8c62ff136da373e URL: http://source.winehq.org/git/wine.git/?a=commit;h=bc5dd3022a448c51a2915d1ca8...
Author: Hans Leidekker hans@codeweavers.com Date: Thu Oct 30 15:06:25 2008 +0100
wsock32: Make EnumProtocols a wrapper around WSAEnumProtocols instead of forwarding directly.
---
dlls/wsock32/protocol.c | 133 +++++++++++++++++++++++++++++++++++++++++++++ dlls/wsock32/wsock32.spec | 4 +- 2 files changed, 135 insertions(+), 2 deletions(-)
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