/*
 * WSOCK32 specific functions
 *
 * Copyright (C) 1993,1994,1996,1997 John Brezak, Erik Bos, Alex Korobka.
 * Copyright (C) 2003 Juan Lang.
 *
 * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */


#include "config.h"
#include <stdarg.h>

#include "windef.h"
#include "winbase.h"
#include "wine/debug.h"
#include "winsock2.h"
#include "winnt.h"
#include "wscontrol.h"
#include "iphlpapi.h"

WINE_DEFAULT_DEBUG_CHANNEL(winsock);

/* internal remapper function for the IP_ constants */
static INT _remap_optname(INT level, INT optname)
{
  TRACE("level=%d, optname=%d\n", level, optname);
  if (level == IPPROTO_IP) {
    switch (optname) {       /***** from value *****/
      case 2: return 9;      /* IP_MULTICAST_IF    */
      case 3: return 10;     /* IP_MULTICAST_TTL   */
      case 4: return 11;     /* IP_MULTICAST_LOOP  */
      case 5: return 12;     /* IP_ADD_MEMBERSHIP  */
      case 6: return 13;     /* IP_DROP_MEMBERSHIP */
      case 7: return 4;      /* IP_TTL             */
      case 8: return 3;      /* IP_TOS             */
      case 9: return 14;     /* IP_DONTFRAGMENT    */
      default: FIXME("Unknown optname %d, can't remap!\n", optname); return optname; 
    }
  } else {
    /* don't need to do anything */
    return optname;
  }
}

/***********************************************************************
 *		setsockopt		(WSOCK32.21)
 *
 * We have these forwarders because, for reasons unknown to us mere mortals,
 * the values of the IP_ constants changed between winsock.h and winsock2.h.
 * So, we need to remap them here.
 */
INT WINAPI WS1_setsockopt(SOCKET s, INT level, INT optname, char *optval, INT optlen)
{
  return setsockopt(s, level, _remap_optname(level, optname), optval, optlen);
}

/***********************************************************************
 *		getsockopt		(WSOCK32.7)
 */
INT WINAPI WS1_getsockopt(SOCKET s, INT level, INT optname, char *optval, INT *optlen)
{
  return getsockopt(s, level, _remap_optname(level, optname), optval, optlen);
}

/***********************************************************************
 *		WsControl (WSOCK32.1001)
 *
 * WsControl seems to be an undocumented Win95 function. A lot of
 * discussion about WsControl can be found on the net, e.g.
 * Subject:      Re: WSOCK32.DLL WsControl Exported Function
 * From:         "Peter Rindfuss" <rindfuss-s@medea.wz-berlin.de>
 * Date:         1997/08/17
 *
 * The WSCNTL_TCPIP_QUERY_INFO option is partially implemented based
 * on observing the behaviour of WsControl with an app in
 * Windows 98.  It is not fully implemented, and there could
 * be (are?) errors due to incorrect assumptions made.
 *
 *
 * WsControl returns WSCTL_SUCCESS on success.
 * ERROR_LOCK_VIOLATION is returned if the output buffer length
 * (*pcbResponseInfoLen) is too small.  This is an unusual error code, but
 * it matches Win98's behavior.  Other errors come from winerror.h, not from
 * winsock.h.  Again, this is to match Win98 behavior.
 *
 */

DWORD WINAPI WsControl(DWORD protocol,
                       DWORD action,
                       LPVOID pRequestInfo,
                       LPDWORD pcbRequestInfoLen,
                       LPVOID pResponseInfo,
                       LPDWORD pcbResponseInfoLen)
{

   /* Get the command structure into a pointer we can use,
      rather than void */
   TDIObjectID *pcommand = (TDIObjectID *)pRequestInfo;

   /* validate input parameters.  Error codes are from winerror.h, not from
    * winsock.h.  pcbResponseInfoLen is apparently allowed to be NULL for some
    * commands, since winipcfg.exe fails if we ensure it's non-NULL in every
    * case.
    */
   if (protocol != IPPROTO_TCP) return ERROR_INVALID_PARAMETER;
   if (!pcommand) return ERROR_INVALID_PARAMETER;
   if (!pcbRequestInfoLen) return ERROR_INVALID_ACCESS;
   if (*pcbRequestInfoLen < sizeof(TDIObjectID)) return ERROR_INVALID_ACCESS;
   if (!pResponseInfo) return ERROR_INVALID_PARAMETER;
   if (pcommand->toi_type != INFO_TYPE_PROVIDER) return ERROR_INVALID_PARAMETER;

   TRACE ("   WsControl TOI_ID=>0x%lx<, {TEI_ENTITY=0x%lx, TEI_INSTANCE=0x%lx}, TOI_CLASS=0x%lx, TOI_TYPE=0x%lx\n",
      pcommand->toi_id, pcommand->toi_entity.tei_entity,
      pcommand->toi_entity.tei_instance,
      pcommand->toi_class, pcommand->toi_type );

   switch (action)
   {
   case WSCNTL_TCPIP_QUERY_INFO:
   {
      if (pcommand->toi_class != INFO_CLASS_GENERIC &&
       pcommand->toi_class != INFO_CLASS_PROTOCOL)
      {
         ERR("Unexpected class %ld for WSCNTL_TCPIP_QUERY_INFO",
          pcommand->toi_class);
         return ERROR_BAD_ENVIRONMENT;
      }

      switch (pcommand->toi_id)
      {
         /* ENTITY_LIST_ID gets the list of "entity IDs", where an entity
            may represent an interface, or a datagram service, or address
            translation, or other fun things.  Typically an entity ID represents
            a class of service, which is further queried for what type it is.
            Different types will then have more specific queries defined.
         */
         case ENTITY_LIST_ID:
         {
            TDIEntityID *baseptr = (TDIEntityID *)pResponseInfo;
            DWORD numInt, i, ifTable, spaceNeeded;
            PMIB_IFTABLE table;

            if (!pcbResponseInfoLen)
               return ERROR_BAD_ENVIRONMENT;
            if (pcommand->toi_class != INFO_CLASS_GENERIC)
            {
               FIXME ("Unexpected Option for ENTITY_LIST_ID request -> toi_class=0x%lx",
                    pcommand->toi_class);
               return (ERROR_BAD_ENVIRONMENT);
            }

            GetNumberOfInterfaces(&numInt);
            spaceNeeded = sizeof(TDIEntityID) * (numInt * 2 + 3);

            if (*pcbResponseInfoLen < spaceNeeded)
               return (ERROR_LOCK_VIOLATION);

            ifTable = 0;
            GetIfTable(NULL, &ifTable, FALSE);
            table = (PMIB_IFTABLE)calloc(1, ifTable);
            if (!table)
               return ERROR_NOT_ENOUGH_MEMORY;
            GetIfTable(table, &ifTable, FALSE);

            spaceNeeded = sizeof(TDIEntityID) * (table->dwNumEntries + 4);
            if (*pcbResponseInfoLen < spaceNeeded)
            {
               free(table);
               return (ERROR_LOCK_VIOLATION);
            }

            memset(baseptr, 0, spaceNeeded);

            for (i = 0; i < table->dwNumEntries; i++)
            {
               /* Return IF_GENERIC and CL_NL_ENTITY on every interface, and
                * AT_ENTITY, CL_TL_ENTITY, and CO_TL_ENTITY on the first
                * interface.  MS returns them only on the loopback interface,
                * but it doesn't seem to matter.
                */
               if (i == 0)
               {
                  baseptr->tei_entity = CO_TL_ENTITY;
                  baseptr->tei_instance = table->table[i].dwIndex;
                  baseptr++;
                  baseptr->tei_entity = CL_TL_ENTITY;
                  baseptr->tei_instance = table->table[i].dwIndex;
                  baseptr++;
                  baseptr->tei_entity = AT_ENTITY;
                  baseptr->tei_instance = table->table[i].dwIndex;
                  baseptr++;
               }
               baseptr->tei_entity = CL_NL_ENTITY;
               baseptr->tei_instance = table->table[i].dwIndex;
               baseptr++;
               baseptr->tei_entity = IF_GENERIC;
               baseptr->tei_instance = table->table[i].dwIndex;
               baseptr++;
            }

            *pcbResponseInfoLen = spaceNeeded;
            free(table);

            break;
         }

         /* Returns MIB-II statistics for an interface */
         case ENTITY_TYPE_ID:
            switch (pcommand->toi_entity.tei_entity)
            {
            case IF_GENERIC:
               if (pcommand->toi_class == INFO_CLASS_GENERIC)
               {
                  if (!pcbResponseInfoLen)
                     return ERROR_BAD_ENVIRONMENT;
                  *((ULONG *)pResponseInfo) = IF_MIB;
                  *pcbResponseInfoLen = sizeof(ULONG);
               }
               else if (pcommand->toi_class == INFO_CLASS_PROTOCOL)
               {
                  MIB_IFROW row;
                  DWORD index = pcommand->toi_entity.tei_instance, ret;
                  DWORD size = sizeof(row) - sizeof(row.wszName) -
                   sizeof(row.bDescr);

                  if (!pcbResponseInfoLen)
                     return ERROR_BAD_ENVIRONMENT;
                  if (*pcbResponseInfoLen < size)
                     return (ERROR_LOCK_VIOLATION);
                  row.dwIndex = index;
                  ret = GetIfEntry(&row);
                  if (ret != NO_ERROR)
                  {
                     /* FIXME: Win98's arp.exe insists on querying index 1 for
                      * its MIB-II stats, regardless of the tei_instances
                      * returned in the ENTITY_LIST query above.  If the query
                      * fails, arp.exe fails.  So, I do this hack return value
                      * if index is 1 and the query failed just to get arp.exe
                      * to continue.
                      */
                     if (index == 1)
                        return NO_ERROR;
                     ERR ("Error retrieving data for interface index %lu\n",
                      index);
                     return ret;
                  }
                  size = sizeof(row) - sizeof(row.wszName) -
                   sizeof(row.bDescr) + row.dwDescrLen;
                  if (*pcbResponseInfoLen < size)
                     return (ERROR_LOCK_VIOLATION);
                  memcpy(pResponseInfo, &row.dwIndex, size);
                  *pcbResponseInfoLen = size;
               }
               break;

            /* Returns address-translation related data.  In our case, this is
             * ARP.
             */
            case AT_ENTITY:
               if (pcommand->toi_class == INFO_CLASS_GENERIC)
               {
                  if (!pcbResponseInfoLen)
                     return ERROR_BAD_ENVIRONMENT;
                  *((ULONG *)pResponseInfo) = AT_ARP;
                  *pcbResponseInfoLen = sizeof(ULONG);
               }
               else if (pcommand->toi_class == INFO_CLASS_PROTOCOL)
               {
                  PMIB_IPNETTABLE table;
                  DWORD size;
                  PULONG output = (PULONG)pResponseInfo;

                  if (!pcbResponseInfoLen)
                     return ERROR_BAD_ENVIRONMENT;
                  if (*pcbResponseInfoLen < sizeof(ULONG) * 2)
                     return (ERROR_LOCK_VIOLATION);
                  GetIpNetTable(NULL, &size, FALSE);
                  table = (PMIB_IPNETTABLE)calloc(1, size);
                  if (!table)
                     return ERROR_NOT_ENOUGH_MEMORY;
                  GetIpNetTable(table, &size, FALSE);
                  /* FIXME: I don't understand the meaning of the ARP output
                   * very well, but it seems to indicate how many ARP entries
                   * exist.  I don't know whether this should reflect the
                   * number per interface, as I'm only testing with a single
                   * interface.  So, I lie and say all ARP entries exist on
                   * a single interface--the first one that appears in the
                   * ARP table.
                   */
                  *(output++) = table->dwNumEntries;
                  *output = table->table[0].dwIndex;
                  free(table);
                  *pcbResponseInfoLen = sizeof(ULONG) * 2;
               }
               break;

            /* Returns connectionless network layer statistics--in our case,
             * this is IP.
             */
            case CL_NL_ENTITY:
               if (pcommand->toi_class == INFO_CLASS_GENERIC)
               {
                  if (!pcbResponseInfoLen)
                     return ERROR_BAD_ENVIRONMENT;
                  *((ULONG *)pResponseInfo) = CL_NL_IP;
                  *pcbResponseInfoLen = sizeof(ULONG);
               }
               else if (pcommand->toi_class == INFO_CLASS_PROTOCOL)
               {
                  if (!pcbResponseInfoLen)
                     return ERROR_BAD_ENVIRONMENT;
                  if (*pcbResponseInfoLen < sizeof(MIB_IPSTATS))
                     return ERROR_LOCK_VIOLATION;
                  GetIpStatistics((PMIB_IPSTATS)pResponseInfo);

                  *pcbResponseInfoLen = sizeof(MIB_IPSTATS);
               }
               break;

            /* Returns connectionless transport layer statistics--in our case,
             * this is UDP.
             */
            case CL_TL_ENTITY:
               if (pcommand->toi_class == INFO_CLASS_GENERIC)
               {
                  if (!pcbResponseInfoLen)
                     return ERROR_BAD_ENVIRONMENT;
                  *((ULONG *)pResponseInfo) = CL_TL_UDP;
                  *pcbResponseInfoLen = sizeof(ULONG);
               }
               else if (pcommand->toi_class == INFO_CLASS_PROTOCOL)
               {
                  if (!pcbResponseInfoLen)
                     return ERROR_BAD_ENVIRONMENT;
                  if (*pcbResponseInfoLen < sizeof(MIB_UDPSTATS))
                     return ERROR_LOCK_VIOLATION;
                  GetUdpStatistics((PMIB_UDPSTATS)pResponseInfo);
                  *pcbResponseInfoLen = sizeof(MIB_UDPSTATS);
               }
               break;

            /* Returns connection-oriented transport layer statistics--in our
             * case, this is TCP.
             */
            case CO_TL_ENTITY:
               if (pcommand->toi_class == INFO_CLASS_GENERIC)
               {
                  if (!pcbResponseInfoLen)
                     return ERROR_BAD_ENVIRONMENT;
                  *((ULONG *)pResponseInfo) = CO_TL_TCP;
                  *pcbResponseInfoLen = sizeof(ULONG);
               }
               else if (pcommand->toi_class == INFO_CLASS_PROTOCOL)
               {
                  if (!pcbResponseInfoLen)
                     return ERROR_BAD_ENVIRONMENT;
                  if (*pcbResponseInfoLen < sizeof(MIB_TCPSTATS))
                     return ERROR_LOCK_VIOLATION;
                  GetTcpStatistics((PMIB_TCPSTATS)pResponseInfo);
                  *pcbResponseInfoLen = sizeof(MIB_TCPSTATS);
               }
               break;

            default:
               ERR("Unknown entity %ld for ENTITY_TYPE_ID query",
                pcommand->toi_entity.tei_entity);
         }
         break;

         /* This call returns the IP address, subnet mask, and broadcast
          * address for an interface.  If there are multiple IP addresses for
          * the interface with the given index, returns the "first" one.
          */
         case IP_MIB_ADDRTABLE_ENTRY_ID:
         {
            DWORD index = pcommand->toi_entity.tei_instance;
            PMIB_IPADDRROW baseIPInfo = (PMIB_IPADDRROW) pResponseInfo;
            PMIB_IPADDRTABLE table;
            DWORD tableSize, i;

            if (!pcbResponseInfoLen)
               return ERROR_BAD_ENVIRONMENT;
            if (*pcbResponseInfoLen < sizeof(MIB_IPADDRROW))
               return (ERROR_LOCK_VIOLATION);

            /* get entire table, because there isn't an exported function that
               gets just one entry. */
            tableSize = 0;
            GetIpAddrTable(NULL, &tableSize, FALSE);
            table = (PMIB_IPADDRTABLE)calloc(1, tableSize);
            if (!table)
               return ERROR_NOT_ENOUGH_MEMORY;
            GetIpAddrTable(table, &tableSize, FALSE);
            for (i = 0; i < table->dwNumEntries; i++)
            {
               if (table->table[i].dwIndex == index)
               {
                  TRACE("Found IP info for tei_instance 0x%lx:\n", index);
                  TRACE("IP 0x%08lx, mask 0x%08lx\n", table->table[i].dwAddr,
                   table->table[i].dwMask);
                  memcpy(baseIPInfo, &table->table[i], sizeof(MIB_IPADDRROW));
                  break;
               }
            }
            free(table);

            *pcbResponseInfoLen = sizeof(MIB_IPADDRROW);
            break;
         }

         case IP_MIB_TABLE_ENTRY_ID:
         {
            switch (pcommand->toi_entity.tei_entity)
            {
            /* This call returns the routing table.
             * No official documentation found, even the name of the command is unknown.
             * Work is based on
             * http://www.cyberport.com/~tangent/programming/winsock/articles/wscontrol.html
             * and testings done with winipcfg.exe, route.exe and ipconfig.exe.
             * pcommand->toi_entity.tei_instance seems to be the interface number
             * but route.exe outputs only the information for the last interface
             * if only the routes for the pcommand->toi_entity.tei_instance
             * interface are returned. */
               case CL_NL_ENTITY:
               {
                  DWORD routeTableSize, numRoutes, ndx;
                  PMIB_IPFORWARDTABLE table;
                  IPRouteEntry *winRouteTable  = (IPRouteEntry *) pResponseInfo;

                  if (!pcbResponseInfoLen)
                     return ERROR_BAD_ENVIRONMENT;
                  GetIpForwardTable(NULL, &routeTableSize, FALSE);
                  numRoutes = min(routeTableSize - sizeof(MIB_IPFORWARDTABLE),
                   0) / sizeof(MIB_IPFORWARDROW) + 1;
                  if (*pcbResponseInfoLen < sizeof(IPRouteEntry) * numRoutes)
                     return (ERROR_LOCK_VIOLATION);
                  table = (PMIB_IPFORWARDTABLE)calloc(1, routeTableSize);
                  if (!table)
                     return ERROR_NOT_ENOUGH_MEMORY;
                  GetIpForwardTable(table, &routeTableSize, FALSE);

                  memset(pResponseInfo, 0, sizeof(IPRouteEntry) * numRoutes);
                  for (ndx = 0; ndx < table->dwNumEntries; ndx++)
                  {
                     winRouteTable->ire_addr = table->table[ndx].dwForwardDest;
                     winRouteTable->ire_index =
                      table->table[ndx].dwForwardIfIndex;
                     winRouteTable->ire_metric =
                      table->table[ndx].dwForwardMetric1;
                     /* winRouteTable->ire_option4 =
                     winRouteTable->ire_option5 =
                     winRouteTable->ire_option6 = */
                     winRouteTable->ire_gw = table->table[ndx].dwForwardNextHop;
                     /* winRouteTable->ire_option8 =
                     winRouteTable->ire_option9 =
                     winRouteTable->ire_option10 = */
                     winRouteTable->ire_mask = table->table[ndx].dwForwardMask;
                     /* winRouteTable->ire_option12 = */
                     winRouteTable++;
                  }

                  /* calculate the length of the data in the output buffer */
                  *pcbResponseInfoLen = sizeof(IPRouteEntry) *
                   table->dwNumEntries;

                  free(table);
               }
               break;

               case AT_ARP:
               {
                  DWORD arpTableSize, numEntries, ret;
                  PMIB_IPNETTABLE table;

                  if (!pcbResponseInfoLen)
                     return ERROR_BAD_ENVIRONMENT;
                  GetIpNetTable(NULL, &arpTableSize, FALSE);
                  numEntries = min(arpTableSize - sizeof(MIB_IPNETTABLE),
                   0) / sizeof(MIB_IPNETROW) + 1;
                  if (*pcbResponseInfoLen < sizeof(MIB_IPNETROW) * numEntries)
                     return (ERROR_LOCK_VIOLATION);
                  table = (PMIB_IPNETTABLE)calloc(1, arpTableSize);
                  if (!table)
                     return ERROR_NOT_ENOUGH_MEMORY;
                  ret = GetIpNetTable(table, &arpTableSize, FALSE);
                  if (ret != NO_ERROR)
                     return ret;
                  if (*pcbResponseInfoLen < sizeof(MIB_IPNETROW) *
                   table->dwNumEntries)
                  {
                     free(table);
                     return ERROR_LOCK_VIOLATION;
                  }
                  memcpy(pResponseInfo, table->table, sizeof(MIB_IPNETROW) *
                   table->dwNumEntries);

                  /* calculate the length of the data in the output buffer */
                  *pcbResponseInfoLen = sizeof(MIB_IPNETROW) *
                   table->dwNumEntries;

                  free(table);
               }
               break;

               case CO_TL_ENTITY:
               {
                  DWORD tcpTableSize, numEntries, ret;
                  PMIB_TCPTABLE table;
                  DWORD i;

                  if (!pcbResponseInfoLen)
                     return ERROR_BAD_ENVIRONMENT;
                  GetTcpTable(NULL, &tcpTableSize, FALSE);
                  numEntries = min(tcpTableSize - sizeof(MIB_TCPTABLE),
                   0) / sizeof(MIB_TCPROW) + 1;
                  if (*pcbResponseInfoLen < sizeof(MIB_TCPROW) * numEntries)
                     return (ERROR_LOCK_VIOLATION);
                  table = (PMIB_TCPTABLE)calloc(1, tcpTableSize);
                  if (!table)
                     return ERROR_NOT_ENOUGH_MEMORY;
                  ret = GetTcpTable(table, &tcpTableSize, FALSE);
                  if (ret != NO_ERROR)
                     return ret;
                  if (*pcbResponseInfoLen < sizeof(MIB_TCPROW) *
                   table->dwNumEntries)
                  {
                     free(table);
                     return ERROR_LOCK_VIOLATION;
                  }
                  for (i = 0; i < table->dwNumEntries; i++)
                  {
                     USHORT sPort;

                     sPort = ntohs((USHORT)table->table[i].dwLocalPort);
                     table->table[i].dwLocalPort = (DWORD)sPort;
                     sPort = ntohs((USHORT)table->table[i].dwRemotePort);
                     table->table[i].dwRemotePort = (DWORD)sPort;
                  }
                  memcpy(pResponseInfo, table->table, sizeof(MIB_TCPROW) *
                   table->dwNumEntries);

                  /* calculate the length of the data in the output buffer */
                  *pcbResponseInfoLen = sizeof(MIB_TCPROW) *
                   table->dwNumEntries;

                  free(table);
               }
               break;

               default:
               {
                  FIXME ("Command ID Not Supported -> toi_id=0x%lx, toi_entity={tei_entity=0x%lx, tei_instance=0x%lx}, toi_class=0x%lx\n",
                     pcommand->toi_id, pcommand->toi_entity.tei_entity,
                     pcommand->toi_entity.tei_instance, pcommand->toi_class);

                  return (ERROR_BAD_ENVIRONMENT);
               }
            }
         }
         break;


         default:
         {
            FIXME ("Command ID Not Supported -> toi_id=0x%lx, toi_entity={tei_entity=0x%lx, tei_instance=0x%lx}, toi_class=0x%lx\n",
               pcommand->toi_id, pcommand->toi_entity.tei_entity,
               pcommand->toi_entity.tei_instance, pcommand->toi_class);

            return (ERROR_BAD_ENVIRONMENT);
         }
      }

      break;
   }

   case WSCNTL_TCPIP_ICMP_ECHO:
   {
      unsigned int addr = *(unsigned int*)pRequestInfo;
      #if 0
         int timeout= *(unsigned int*)(inbuf+4);
         short x1 = *(unsigned short*)(inbuf+8);
         short sendbufsize = *(unsigned short*)(inbuf+10);
         char x2 = *(unsigned char*)(inbuf+12);
         char ttl = *(unsigned char*)(inbuf+13);
         char service = *(unsigned char*)(inbuf+14);
         char type= *(unsigned char*)(inbuf+15); /* 0x2: don't fragment*/
      #endif

      FIXME("(ICMP_ECHO) to 0x%08x stub \n", addr);
      break;
   }

   default:
      FIXME("Protocol Not Supported -> protocol=0x%lx, action=0x%lx, Request=%p, RequestLen=%p, Response=%p, ResponseLen=%p\n",
       protocol, action, pRequestInfo, pcbRequestInfoLen, pResponseInfo, pcbResponseInfoLen);

      return (WSAEOPNOTSUPP);

   }

   return (WSCTL_SUCCESS);
}



/***********************************************************************
 *		WSARecvEx			(WSOCK32.1107)
 *
 * WSARecvEx is a Microsoft specific extension to winsock that is identical to recv
 * except that has an in/out argument call flags that has the value MSG_PARTIAL ored
 * into the flags parameter when a partial packet is read. This only applies to
 * sockets using the datagram protocol. This method does not seem to be implemented
 * correctly by microsoft as the winsock implementation does not set the MSG_PARTIAL
 * flag when a fragmented packet arrives.
 */
INT WINAPI WSARecvEx(SOCKET s, char *buf, INT len, INT *flags)
{
    FIXME("(WSARecvEx) partial packet return value not set \n");
    return recv(s, buf, len, *flags);
}


/***********************************************************************
 *       s_perror         (WSOCK32.1108)
 */
void WINAPI s_perror(LPCSTR message)
{
    FIXME("(%s): stub\n",message);
    return;
}
