/*
 * 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
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#define USE_WS_PREFIX

#include "config.h"

#include <stdarg.h>
#include <stdio.h>
#include <string.h>

#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif

#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]
 */
UINT WINAPI WSOCK32_inet_network(const char *cp)
{
#ifdef HAVE_INET_NETWORK
    return inet_network(cp);
#else
    return 0;
#endif
}

/*****************************************************************************
 *          getnetbyname       [WSOCK32.1101]
 */
struct netent * WINAPI WSOCK32_getnetbyname(const char *name)
{
#ifdef HAVE_GETNETBYNAME
    return getnetbyname(name);
#else
    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_BANDWIDTH_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;
}
