/*
 * MSWSOCK specific functions
 *
 * Copyright (C) 2003 André Johansen
 *
 * 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
 */

#include "config.h"

#include <stdarg.h>

#include "windef.h"
#include "winbase.h"
#include "winsock2.h"
#include "mswsock.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(mswsock);

static LPFN_ACCEPTEX acceptex_fn;
static LPFN_GETACCEPTEXSOCKADDRS acceptexsockaddrs_fn;
static LPFN_TRANSMITFILE transmitfile_fn;
static BOOL initialised;

/* Get pointers to the ws2_32 implementations.
 * NOTE: This assumes that ws2_32 contains only one implementation
 * of these functions, i.e. that you cannot get different functions
 * back by passing another socket in. If that ever changes, we'll need
 * to think about associating the functions with the socket and
 * exposing that information to this dll somehow.
 */
static void get_fn(SOCKET s, GUID* guid, FARPROC* fn)
{
    FARPROC func;
    DWORD len;
    if (!WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, guid, sizeof(*guid),
                  &func, sizeof(func), &len, NULL, NULL))
        *fn = func;
}

static void get_fn_pointers(SOCKET s)
{
    GUID acceptex_guid = WSAID_ACCEPTEX;
    GUID acceptexsockaddrs_guid = WSAID_GETACCEPTEXSOCKADDRS;
    GUID transmitfile_guid = WSAID_TRANSMITFILE;

    get_fn(s, &acceptex_guid, (FARPROC*)&acceptex_fn);
    get_fn(s, &acceptexsockaddrs_guid, (FARPROC*)&acceptexsockaddrs_fn);
    get_fn(s, &transmitfile_guid, (FARPROC*)&transmitfile_fn);
    initialised = TRUE;
}

/***********************************************************************
 *		AcceptEx (MSWSOCK.@)
 *
 * Accept a new connection, retrieving the connected addresses and initial data.
 *
 * listener       [I] Listening socket
 * acceptor       [I] Socket to accept on
 * dest           [O] Destination for inital data
 * dest_len       [I] Size of dest in bytes
 * local_addr_len [I] Number of bytes reserved in dest for local addrress
 * rem_addr_len   [I] Number of bytes reserved in dest for remote addrress
 * received       [O] Destination for number of bytes of initial data
 * overlapped     [I] For asynchronous execution
 *
 * RETURNS
 * Success: TRUE
 * Failure: FALSE. Use WSAGetLastError() for details of the error.
 */
BOOL WINAPI AcceptEx(SOCKET listener, SOCKET acceptor, PVOID dest, DWORD dest_len,
                     DWORD local_addr_len, DWORD rem_addr_len, LPDWORD received,
                     LPOVERLAPPED overlapped)
{
    if (!initialised)
        get_fn_pointers(acceptor);

    if (!acceptex_fn)
        return FALSE;

    return acceptex_fn(listener, acceptor, dest, dest_len, local_addr_len,
                       rem_addr_len, received, overlapped);
}

/***********************************************************************
 *		GetAcceptExSockaddrs (MSWSOCK.@)
 *
 * Get infomation about an accepted socket.
 *
 * data           [O] Destination for the first block of data from AcceptEx()
 * data_len       [I] length of data in bytes
 * local_len      [I] Bytes reserved for local addrinfo
 * rem_len        [I] Bytes reserved for remote addrinfo
 * local_addr     [O] Destination for local sockaddr
 * local_addr_len [I] Size of local_addr
 * rem_addr       [O] Destination for remote sockaddr
 * rem_addr_len   [I] Size of rem_addr
 *
 * RETURNS
 *  Nothing.
 */
VOID WINAPI GetAcceptExSockaddrs(PVOID data, DWORD data_len, DWORD local_len, DWORD rem_len,
                                 struct sockaddr **local_addr, LPINT local_addr_len,
                                 struct sockaddr **rem_addr, LPINT rem_addr_len)
{
    if (acceptexsockaddrs_fn)
        acceptexsockaddrs_fn(data, data_len, local_len, rem_len,
                             local_addr, local_addr_len, rem_addr, rem_addr_len);
}


/***********************************************************************
 *		TransmitFile (MSWSOCK.@)
 *
 * Transmit a file over a socket.
 *
 * PARAMS
 * s          [I] Handle to a connected socket
 * file       [I] Opened file handle for file to send
 * total_len  [I] Total number of file bytes to send
 * chunk_len  [I] Chunk size to send file in (0=default)
 * overlapped [I] For asynchronous operation
 * buffers    [I] Head/tail data, or NULL if none
 * flags      [I] TF_ Flags from mswsock.h
 *
 * RETURNS
 * Success: TRUE
 * Failure: FALSE. Use WSAGetLastError() for details of the error.
 */
BOOL WINAPI TransmitFile(SOCKET s, HANDLE file, DWORD total_len,
                         DWORD chunk_len, LPOVERLAPPED overlapped,
                         LPTRANSMIT_FILE_BUFFERS buffers, DWORD flags)
{
    if (!initialised)
        get_fn_pointers(s);

    if (!transmitfile_fn)
        return FALSE;

    return transmitfile_fn(s, file, total_len, chunk_len, overlapped, buffers, flags);
}

/***********************************************************************
 *		WSARecvEx (MSWSOCK.@)
 */
INT WINAPI WSARecvEx(
	SOCKET s,   /* [in] Descriptor identifying a connected socket */
	char *buf,  /* [out] Buffer for the incoming data */
	INT len,    /* [in] Length of buf, in bytes */
        INT *flags) /* [in/out] Indicator specifying whether the message is
	               fully or partially received for datagram sockets */
{
    FIXME("not implemented\n");
    
    return SOCKET_ERROR;
}
