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

This commit is contained in:
Hans Leidekker 2008-10-30 15:06:25 +01:00 committed by Alexandre Julliard
parent 59dde0d9a7
commit bc5dd3022a
2 changed files with 135 additions and 2 deletions

View 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
@ -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;
}

View File

@ -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