/* Async WINSOCK DNS services
 *
 * Copyright (C) 1993,1994,1996,1997 John Brezak, Erik Bos, Alex Korobka.
 * Copyright (C) 1999 Marcus Meissner
 * Copyright (C) 2009 Alexandre Julliard
 *
 * 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
 *
 * NOTE: If you make any changes to fix a particular app, make sure
 * they don't break something else like Netscape or telnet and ftp
 * clients and servers (www.winsite.com got a lot of those).
 *
 * FIXME:
 *	- Add WSACancel* and correct handle management. (works rather well for
 *	  now without it.)
 *	- Verify & Check all calls for correctness
 *	  (currently only WSAGetHostByName*, WSAGetServByPort* calls)
 *	- Check error returns.
 *	- mirc/mirc32 Finger @linux.kernel.org sometimes fails in threaded mode.
 *	  (not sure why)
 *	- This implementation did ignore the "NOTE:" section above (since the
 *	  whole stuff did not work anyway to other changes).
 */

#include "config.h"
#include "wine/port.h"

#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winsock2.h"
#include "ws2spi.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(winsock);


struct async_query_header
{
    HWND   hWnd;
    UINT   uMsg;
    void  *sbuf;
    INT    sbuflen;
    HANDLE handle;
};

struct async_query_gethostbyname
{
    struct async_query_header query;
    char *host_name;
};

struct async_query_gethostbyaddr
{
    struct async_query_header query;
    char *host_addr;
    int   host_len;
    int   host_type;
};

struct async_query_getprotobyname
{
    struct async_query_header query;
    char *proto_name;
};

struct async_query_getprotobynumber
{
    struct async_query_header query;
    int   proto_number;
};

struct async_query_getservbyname
{
    struct async_query_header query;
    char *serv_name;
    char *serv_proto;
};

struct async_query_getservbyport
{
    struct async_query_header query;
    char *serv_proto;
    int   serv_port;
};


/* ----------------------------------- helper functions - */

static int list_size(char** l, int item_size)
{
  int i,j = 0;
  if(l)
  { for(i=0;l[i];i++)
	j += (item_size) ? item_size : strlen(l[i]) + 1;
    j += (i + 1) * sizeof(char*); }
  return j;
}

static int list_dup(char** l_src, char* ref, int item_size)
{
   char*		p = ref;
   char**		l_to = (char**)ref;
   int			i,j,k;

   for(j=0;l_src[j];j++) ;
   p += (j + 1) * sizeof(char*);
   for(i=0;i<j;i++)
   { l_to[i] = p;
     k = ( item_size ) ? item_size : strlen(l_src[i]) + 1;
     memcpy(p, l_src[i], k); p += k; }
   l_to[i] = NULL;
   return (p - ref);
}

static DWORD finish_query( struct async_query_header *query, LPARAM lparam )
{
    PostMessageW( query->hWnd, query->uMsg, (WPARAM)query->handle, lparam );
    HeapFree( GetProcessHeap(), 0, query );
    return 0;
}

/* ----- hostent */

static LPARAM copy_he(void *base, int size, const struct WS_hostent *he)
{
    char *p;
    int needed;
    struct WS_hostent *to = base;

    if (!he) return MAKELPARAM( 0, GetLastError() );

    needed = sizeof(struct WS_hostent) + strlen(he->h_name) + 1 +
                 list_size(he->h_aliases, 0) +
                 list_size(he->h_addr_list, he->h_length );
    if (size < needed) return MAKELPARAM( needed, WSAENOBUFS );

    to->h_addrtype = he->h_addrtype;
    to->h_length = he->h_length;
    p = (char *)(to + 1);
    to->h_name = p;
    strcpy(p, he->h_name); p += strlen(p) + 1;
    to->h_aliases = (char **)p;
    p += list_dup(he->h_aliases, p, 0);
    to->h_addr_list = (char **)p;
    list_dup(he->h_addr_list, p, he->h_length);
    return MAKELPARAM( needed, 0 );
}

static DWORD WINAPI async_gethostbyname(LPVOID arg)
{
    struct async_query_gethostbyname *aq = arg;
    struct WS_hostent *he = WS_gethostbyname( aq->host_name );

    return finish_query( &aq->query, copy_he( aq->query.sbuf, aq->query.sbuflen, he ));
}

static DWORD WINAPI async_gethostbyaddr(LPVOID arg)
{
    struct async_query_gethostbyaddr *aq = arg;
    struct WS_hostent *he = WS_gethostbyaddr( aq->host_addr, aq->host_len, aq->host_type );

    return finish_query( &aq->query, copy_he( aq->query.sbuf, aq->query.sbuflen, he ));
}

/* ----- protoent */

static LPARAM copy_pe(void *base, int size, const struct WS_protoent* pe)
{
    char *p;
    int needed;
    struct WS_protoent *to = base;

    if (!pe) return MAKELPARAM( 0, GetLastError() );

    needed = sizeof(struct WS_protoent) + strlen(pe->p_name) + 1 + list_size(pe->p_aliases, 0);
    if (size < needed) return MAKELPARAM( needed, WSAENOBUFS );

    to->p_proto = pe->p_proto;
    p = (char *)(to + 1);
    to->p_name = p;
    strcpy(p, pe->p_name); p += strlen(p) + 1;
    to->p_aliases = (char **)p;
    list_dup(pe->p_aliases, p, 0);
    return MAKELPARAM( needed, 0 );
}

static DWORD WINAPI async_getprotobyname(LPVOID arg)
{
    struct async_query_getprotobyname *aq = arg;
    struct WS_protoent *pe = WS_getprotobyname( aq->proto_name );

    return finish_query( &aq->query, copy_pe( aq->query.sbuf, aq->query.sbuflen, pe ));
}

static DWORD WINAPI async_getprotobynumber(LPVOID arg)
{
    struct async_query_getprotobynumber *aq = arg;
    struct WS_protoent *pe = WS_getprotobynumber( aq->proto_number );

    return finish_query( &aq->query, copy_pe( aq->query.sbuf, aq->query.sbuflen, pe ));
}

/* ----- servent */

static LPARAM copy_se(void *base, int size, const struct WS_servent* se)
{
    char *p;
    int needed;
    struct WS_servent *to = base;

    if (!se) return MAKELPARAM( 0, GetLastError() );

    needed = sizeof(struct WS_servent) + strlen(se->s_proto) + strlen(se->s_name) + 2 + list_size(se->s_aliases, 0);
    if (size < needed) return MAKELPARAM( needed, WSAENOBUFS );

    to->s_port = se->s_port;
    p = (char *)(to + 1);
    to->s_name = p;
    strcpy(p, se->s_name); p += strlen(p) + 1;
    to->s_proto = p;
    strcpy(p, se->s_proto); p += strlen(p) + 1;
    to->s_aliases = (char **)p;
    list_dup(se->s_aliases, p, 0);
    return MAKELPARAM( needed, 0 );
}

static DWORD WINAPI async_getservbyname(LPVOID arg)
{
    struct async_query_getservbyname *aq = arg;
    struct WS_servent *se = WS_getservbyname( aq->serv_name, aq->serv_proto );

    return finish_query( &aq->query, copy_se( aq->query.sbuf, aq->query.sbuflen, se ));
}

static DWORD WINAPI async_getservbyport(LPVOID arg)
{
    struct async_query_getservbyport *aq = arg;
    struct WS_servent *se = WS_getservbyport( aq->serv_port, aq->serv_proto );

    return finish_query( &aq->query, copy_se( aq->query.sbuf, aq->query.sbuflen, se ));
}


/****************************************************************************
 * The main async help function.
 *
 * It either starts a thread or just calls the function directly for platforms
 * with no thread support. This relies on the fact that PostMessage() does
 * not actually call the windowproc before the function returns.
 */
static HANDLE run_query( HWND hWnd, UINT uMsg, LPTHREAD_START_ROUTINE func,
                         struct async_query_header *query, void *sbuf, INT sbuflen )
{
    static LONG next_handle = 0xdead;
    HANDLE thread;
    ULONG handle = LOWORD( InterlockedIncrement( &next_handle ));

    /* avoid handle 0 */
    while (!handle) handle = LOWORD( InterlockedIncrement( &next_handle ));

    query->hWnd    = hWnd;
    query->uMsg    = uMsg;
    query->handle  = UlongToHandle( handle );
    query->sbuf    = sbuf;
    query->sbuflen = sbuflen;

    thread = CreateThread( NULL, 0, func, query, 0, NULL );
    if (!thread)
    {
        SetLastError( WSAEWOULDBLOCK );
        HeapFree( GetProcessHeap(), 0, query );
        return 0;
    }
    CloseHandle( thread );
    return UlongToHandle( handle );
}


/***********************************************************************
 *       WSAAsyncGetHostByAddr        (WS2_32.102)
 */
HANDLE WINAPI WSAAsyncGetHostByAddr(HWND hWnd, UINT uMsg, LPCSTR addr,
                               INT len, INT type, LPSTR sbuf, INT buflen)
{
    struct async_query_gethostbyaddr *aq;

    TRACE("hwnd %p, msg %04x, addr %p[%i]\n", hWnd, uMsg, addr, len );

    if (!(aq = HeapAlloc( GetProcessHeap(), 0, sizeof(*aq) + len )))
    {
        SetLastError( WSAEWOULDBLOCK );
        return 0;
    }
    aq->host_addr = (char *)(aq + 1);
    aq->host_len  = len;
    aq->host_type = type;
    memcpy( aq->host_addr, addr, len );
    return run_query( hWnd, uMsg, async_gethostbyaddr, &aq->query, sbuf, buflen );
}

/***********************************************************************
 *       WSAAsyncGetHostByName	(WS2_32.103)
 */
HANDLE WINAPI WSAAsyncGetHostByName(HWND hWnd, UINT uMsg, LPCSTR name,
					LPSTR sbuf, INT buflen)
{
    struct async_query_gethostbyname *aq;
    unsigned int len = strlen(name) + 1;

    TRACE("hwnd %p, msg %04x, host %s, buffer %i\n", hWnd, uMsg, debugstr_a(name), buflen );

    if (!(aq = HeapAlloc( GetProcessHeap(), 0, sizeof(*aq) + len )))
    {
        SetLastError( WSAEWOULDBLOCK );
        return 0;
    }
    aq->host_name = (char *)(aq + 1);
    strcpy( aq->host_name, name );
    return run_query( hWnd, uMsg, async_gethostbyname, &aq->query, sbuf, buflen );
}

/***********************************************************************
 *       WSAAsyncGetProtoByName       (WS2_32.105)
 */
HANDLE WINAPI WSAAsyncGetProtoByName(HWND hWnd, UINT uMsg, LPCSTR name,
                                         LPSTR sbuf, INT buflen)
{
    struct async_query_getprotobyname *aq;
    unsigned int len = strlen(name) + 1;

    TRACE("hwnd %p, msg %04x, proto %s, buffer %i\n", hWnd, uMsg, debugstr_a(name), buflen );

    if (!(aq = HeapAlloc( GetProcessHeap(), 0, sizeof(*aq) + len )))
    {
        SetLastError( WSAEWOULDBLOCK );
        return 0;
    }
    aq->proto_name = (char *)(aq + 1);
    strcpy( aq->proto_name, name );
    return run_query( hWnd, uMsg, async_getprotobyname, &aq->query, sbuf, buflen );
}


/***********************************************************************
 *       WSAAsyncGetProtoByNumber     (WS2_32.104)
 */
HANDLE WINAPI WSAAsyncGetProtoByNumber(HWND hWnd, UINT uMsg, INT number,
                                           LPSTR sbuf, INT buflen)
{
    struct async_query_getprotobynumber *aq;

    TRACE("hwnd %p, msg %04x, num %i\n", hWnd, uMsg, number );

    if (!(aq = HeapAlloc( GetProcessHeap(), 0, sizeof(*aq) )))
    {
        SetLastError( WSAEWOULDBLOCK );
        return 0;
    }
    aq->proto_number = number;
    return run_query( hWnd, uMsg, async_getprotobynumber, &aq->query, sbuf, buflen );
}

/***********************************************************************
 *       WSAAsyncGetServByName        (WS2_32.107)
 */
HANDLE WINAPI WSAAsyncGetServByName(HWND hWnd, UINT uMsg, LPCSTR name,
                                        LPCSTR proto, LPSTR sbuf, INT buflen)
{
    struct async_query_getservbyname *aq;
    unsigned int len1 = strlen(name) + 1;
    unsigned int len2 = strlen(proto) + 1;

    TRACE("hwnd %p, msg %04x, name %s, proto %s\n", hWnd, uMsg, debugstr_a(name), debugstr_a(proto));

    if (!(aq = HeapAlloc( GetProcessHeap(), 0, sizeof(*aq) + len1 + len2 )))
    {
        SetLastError( WSAEWOULDBLOCK );
        return 0;
    }
    aq->serv_name  = (char *)(aq + 1);
    aq->serv_proto = aq->serv_name + len1;
    strcpy( aq->serv_name, name );
    strcpy( aq->serv_proto, proto );
    return run_query( hWnd, uMsg, async_getservbyname, &aq->query, sbuf, buflen );
}

/***********************************************************************
 *       WSAAsyncGetServByPort        (WS2_32.106)
 */
HANDLE WINAPI WSAAsyncGetServByPort(HWND hWnd, UINT uMsg, INT port,
                                        LPCSTR proto, LPSTR sbuf, INT buflen)
{
    struct async_query_getservbyport *aq;
    unsigned int len = proto ? strlen(proto) + 1 : 0;

    TRACE("hwnd %p, msg %04x, port %i, proto %s\n", hWnd, uMsg, port, debugstr_a(proto));

    if (!(aq = HeapAlloc( GetProcessHeap(), 0, sizeof(*aq) + len )))
    {
        SetLastError( WSAEWOULDBLOCK );
        return 0;
    }

    if (proto)
    {
        aq->serv_proto = (char *)(aq + 1);
        strcpy( aq->serv_proto, proto );
    }
    else
        aq->serv_proto = NULL;

    aq->serv_port = port;

    return run_query( hWnd, uMsg, async_getservbyport, &aq->query, sbuf, buflen );
}

/***********************************************************************
 *       WSACancelAsyncRequest	(WS2_32.108)
 */
INT WINAPI WSACancelAsyncRequest(HANDLE hAsyncTaskHandle)
{
    FIXME("(%p),stub\n", hAsyncTaskHandle);
    return 0;
}

/***********************************************************************
 *       WSApSetPostRoutine	(WS2_32.24)
 */
INT WINAPI WSApSetPostRoutine(LPWPUPOSTMESSAGE lpPostRoutine)
{
    FIXME("(%p), stub !\n", lpPostRoutine);
    return 0;
}

/***********************************************************************
 *        WPUCompleteOverlappedRequest   (WS2_32.25)
 */
WSAEVENT WINAPI WPUCompleteOverlappedRequest(SOCKET s, LPWSAOVERLAPPED overlapped,
                                             DWORD error, DWORD transferred, LPINT errcode)
{
    FIXME("(0x%08lx,%p,0x%08x,0x%08x,%p), stub !\n", s, overlapped, error, transferred, errcode);

    if (errcode)
        *errcode = WSAEINVAL;

    return NULL;
}
