/*
 * DDEML library
 *
 * Copyright 1997 Alexandre Julliard
 * Copyright 1997 Len White
 * Copyright 1999 Keith Matthews
 * Copyright 2000 Corel
 * Copyright 2001,2002,2009 Eric Pouech
 *
 * 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 "wine/port.h"

#include <stdarg.h>
#include <string.h>
#include "windef.h"
#include "winbase.h"
#include "wine/windef16.h"
#include "wine/winbase16.h"
#include "wownt32.h"
#include "dde.h"
#include "ddeml.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(ddeml);


typedef HDDEDATA (CALLBACK *PFNCALLBACK16)(UINT16,UINT16,HCONV,HSZ,HSZ,HDDEDATA,
                                           DWORD,DWORD);

typedef struct
{
    UINT16  cb;
    UINT16  wFlags;
    UINT16  wCountryID;
    INT16   iCodePage;
    DWORD   dwLangID;
    DWORD   dwSecurity;
} CONVCONTEXT16, *LPCONVCONTEXT16;

typedef struct
{
    DWORD          cb;
    DWORD          hUser;
    HCONV          hConvPartner;
    HSZ            hszSvcPartner;
    HSZ            hszServiceReq;
    HSZ            hszTopic;
    HSZ            hszItem;
    UINT16         wFmt;
    UINT16         wType;
    UINT16         wStatus;
    UINT16         wConvst;
    UINT16         wLastError;
    HCONVLIST      hConvList;
    CONVCONTEXT16  ConvCtxt;
} CONVINFO16, *LPCONVINFO16;

static void map1632_conv_context(CONVCONTEXT* cc32, const CONVCONTEXT16* cc16)
{
    cc32->cb = sizeof(*cc32);
    cc32->wFlags = cc16->wFlags;
    cc32->wCountryID = cc16->wCountryID;
    cc32->iCodePage = cc16->iCodePage;
    cc32->dwLangID = cc16->dwLangID;
    cc32->dwSecurity = cc16->dwSecurity;
}

static void map3216_conv_context(CONVCONTEXT16* cc16, const CONVCONTEXT* cc32)
{
    cc16->cb = sizeof(*cc16);
    cc16->wFlags = cc32->wFlags;
    cc16->wCountryID = cc32->wCountryID;
    cc16->iCodePage = cc32->iCodePage;
    cc16->dwLangID = cc32->dwLangID;
    cc16->dwSecurity = cc32->dwSecurity;
}

/******************************************************************
 *		WDML_InvokeCallback16
 *
 *
 */
static HDDEDATA	CALLBACK WDML_InvokeCallback16(DWORD pfn16, UINT uType, UINT uFmt,
                                               HCONV hConv, HSZ hsz1, HSZ hsz2,
                                               HDDEDATA hdata, ULONG_PTR dwData1, ULONG_PTR dwData2)
{
    DWORD               d1 = 0;
    HDDEDATA            ret;
    CONVCONTEXT16       cc16;
    WORD args[16];

    switch (uType)
    {
    case XTYP_CONNECT:
    case XTYP_WILDCONNECT:
        if (dwData1)
        {
            map3216_conv_context(&cc16, (const CONVCONTEXT*)dwData1);
            d1 = MapLS(&cc16);
        }
        break;
    default:
        d1 = dwData1;
        break;
    }
    args[15] = HIWORD(uType);
    args[14] = LOWORD(uType);
    args[13] = HIWORD(uFmt);
    args[12] = LOWORD(uFmt);
    args[11] = HIWORD(hConv);
    args[10] = LOWORD(hConv);
    args[9]  = HIWORD(hsz1);
    args[8]  = LOWORD(hsz1);
    args[7]  = HIWORD(hsz2);
    args[6]  = LOWORD(hsz2);
    args[5]  = HIWORD(hdata);
    args[4]  = LOWORD(hdata);
    args[3]  = HIWORD(d1);
    args[2]  = LOWORD(d1);
    args[1]  = HIWORD(dwData2);
    args[0]  = LOWORD(dwData2);
    WOWCallback16Ex(pfn16, WCB16_PASCAL, sizeof(args), args, (DWORD *)&ret);

    switch (uType)
    {
    case XTYP_CONNECT:
    case XTYP_WILDCONNECT:
        if (d1 != 0) UnMapLS(d1);
        break;
    }
    return ret;
}

#define MAX_THUNKS      32
/* As DDEML doesn't provide a way to get back to an InstanceID when
 * a callback is run, we use thunk in order to implement simply the
 * 32bit->16bit callback mechanism.
 * For each 16bit instance, we create a thunk, which will be passed as
 * a 32bit callback. This thunk also stores (in the code!) the 16bit
 * address of the 16bit callback, and passes it back to
 * WDML_InvokeCallback16.
 * The code below is mainly to create the thunks themselves
 */
#include "pshpack1.h"
static struct ddeml_thunk
{
    BYTE        popl_eax;        /* popl  %eax (return address) */
    BYTE        pushl_func;      /* pushl $pfn16 (16bit callback function) */
    SEGPTR      pfn16;
    BYTE        pushl_eax;       /* pushl %eax */
    BYTE        jmp;             /* ljmp WDML_InvokeCallback16 */
    DWORD       callback;
    DWORD       instId;          /* instance ID */
} *DDEML16_Thunks;
#include "poppack.h"

static CRITICAL_SECTION ddeml_cs;
static CRITICAL_SECTION_DEBUG critsect_debug =
{
    0, 0, &ddeml_cs,
    { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
      0, 0, { (DWORD_PTR)(__FILE__ ": ddeml_cs") }
};
static CRITICAL_SECTION ddeml_cs = { &critsect_debug, -1, 0, 0, 0, 0 };

static struct ddeml_thunk*      DDEML_AddThunk(DWORD instId, DWORD pfn16)
{
    struct ddeml_thunk* thunk;

    if (!DDEML16_Thunks)
    {
        DDEML16_Thunks = VirtualAlloc(NULL, MAX_THUNKS * sizeof(*DDEML16_Thunks), MEM_COMMIT,
                                      PAGE_EXECUTE_READWRITE);
        if (!DDEML16_Thunks) return NULL;
        for (thunk = DDEML16_Thunks; thunk < &DDEML16_Thunks[MAX_THUNKS]; thunk++)
        {
            thunk->popl_eax     = 0x58;   /* popl  %eax */
            thunk->pushl_func   = 0x68;   /* pushl $pfn16 */
            thunk->pfn16        = 0;
            thunk->pushl_eax    = 0x50;   /* pushl %eax */
            thunk->jmp          = 0xe9;   /* jmp WDML_InvokeCallback16 */
            thunk->callback     = (char *)WDML_InvokeCallback16 - (char *)(&thunk->callback + 1);
            thunk->instId       = 0;
        }
    }
    for (thunk = DDEML16_Thunks; thunk < &DDEML16_Thunks[MAX_THUNKS]; thunk++)
    {
        /* either instId is 0, and we're looking for an empty slot, or
         * instId is an already existing instance, and we should find its thunk
         */
        if (thunk->instId == instId)
        {
            thunk->pfn16 = pfn16;
            return thunk;
        }
    }
    FIXME("Out of ddeml-thunks. Bump MAX_THUNKS\n");
    return NULL;
}

/******************************************************************************
 *            DdeInitialize   (DDEML.2)
 */
UINT16 WINAPI DdeInitialize16(LPDWORD pidInst, PFNCALLBACK16 pfnCallback,
			      DWORD afCmd, DWORD ulRes)
{
    UINT16 ret;
    struct ddeml_thunk* thunk;

    EnterCriticalSection(&ddeml_cs);
    if ((thunk = DDEML_AddThunk(*pidInst, (DWORD)pfnCallback)))
    {
        ret = DdeInitializeA(pidInst, (PFNCALLBACK)thunk, afCmd, ulRes);
        if (ret == DMLERR_NO_ERROR) thunk->instId = *pidInst;
    }
    else ret = DMLERR_SYS_ERROR;
    LeaveCriticalSection(&ddeml_cs);
    return ret;
}

/*****************************************************************
 *            DdeUninitialize   (DDEML.3)
 */
BOOL16 WINAPI DdeUninitialize16(DWORD idInst)
{
    struct ddeml_thunk* thunk;
    BOOL16              ret = FALSE;

    if (!DdeUninitialize(idInst)) return FALSE;
    EnterCriticalSection(&ddeml_cs);
    for (thunk = DDEML16_Thunks; thunk < &DDEML16_Thunks[MAX_THUNKS]; thunk++)
    {
        if (thunk->instId == idInst)
        {
            thunk->instId = 0;
            ret = TRUE;
            break;
        }
    }
    LeaveCriticalSection(&ddeml_cs);
    if (!ret) FIXME("Should never happen\n");
    return ret;
}

/*****************************************************************
 * DdeConnectList [DDEML.4]
 */

HCONVLIST WINAPI DdeConnectList16(DWORD idInst, HSZ hszService, HSZ hszTopic,
				  HCONVLIST hConvList, LPCONVCONTEXT16 pCC16)
{
    CONVCONTEXT	        cc;
    CONVCONTEXT*	pCC = NULL;

    if (pCC16)
        map1632_conv_context(pCC = &cc, pCC16);
    return DdeConnectList(idInst, hszService, hszTopic, hConvList, pCC);
}

/*****************************************************************
 * DdeQueryNextServer [DDEML.5]
 */
HCONV WINAPI DdeQueryNextServer16(HCONVLIST hConvList, HCONV hConvPrev)
{
    return DdeQueryNextServer(hConvList, hConvPrev);
}

/*****************************************************************
 *            DdeDisconnectList (DDEML.6)
 */
BOOL16 WINAPI DdeDisconnectList16(HCONVLIST hConvList)
{
    return (BOOL16)DdeDisconnectList(hConvList);
}


/*****************************************************************
 *		DdeQueryString (DDEML.23)
 */
DWORD WINAPI DdeQueryString16(DWORD idInst, HSZ hsz, LPSTR lpsz, DWORD cchMax,
                              INT16 codepage)
{
    return DdeQueryStringA(idInst, hsz, lpsz, cchMax, codepage);
}

/*****************************************************************
 *            DdeConnect   (DDEML.7)
 */
HCONV WINAPI DdeConnect16(DWORD idInst, HSZ hszService, HSZ hszTopic,
                          LPCONVCONTEXT16 pCC16)
{
    CONVCONTEXT	        cc;
    CONVCONTEXT*	pCC = NULL;

    if (pCC16)
        map1632_conv_context(pCC = &cc, pCC16);
    return DdeConnect(idInst, hszService, hszTopic, pCC);
}

/*****************************************************************
 *            DdeDisconnect   (DDEML.8)
 */
BOOL16 WINAPI DdeDisconnect16(HCONV hConv)
{
    return (BOOL16)DdeDisconnect(hConv);
}

/*****************************************************************
 *            DdeSetUserHandle (DDEML.10)
 */
BOOL16 WINAPI DdeSetUserHandle16(HCONV hConv, DWORD id, DWORD hUser)
{
    return DdeSetUserHandle(hConv, id, hUser);
}

/*****************************************************************
 *            DdeCreateDataHandle (DDEML.14)
 */
HDDEDATA WINAPI DdeCreateDataHandle16(DWORD idInst, LPBYTE pSrc, DWORD cb,
                                      DWORD cbOff, HSZ hszItem, UINT16 wFmt,
				      UINT16 afCmd)
{
    return DdeCreateDataHandle(idInst, pSrc, cb, cbOff, hszItem, wFmt, afCmd);
}

/*****************************************************************
 *            DdeCreateStringHandle   (DDEML.21)
 */
HSZ WINAPI DdeCreateStringHandle16(DWORD idInst, LPCSTR str, INT16 codepage)
{
    if  (codepage)
    {
        return DdeCreateStringHandleA(idInst, str, codepage);
    }
    else
    {
        TRACE("Default codepage supplied\n");
        return DdeCreateStringHandleA(idInst, str, CP_WINANSI);
    }
}

/*****************************************************************
 *            DdeFreeStringHandle   (DDEML.22)
 */
BOOL16 WINAPI DdeFreeStringHandle16(DWORD idInst, HSZ hsz)
{
    return (BOOL16)DdeFreeStringHandle(idInst, hsz);
}

/*****************************************************************
 *            DdeFreeDataHandle   (DDEML.19)
 */
BOOL16 WINAPI DdeFreeDataHandle16(HDDEDATA hData)
{
    return (BOOL16)DdeFreeDataHandle(hData);
}

/*****************************************************************
 *            DdeKeepStringHandle   (DDEML.24)
 */
BOOL16 WINAPI DdeKeepStringHandle16(DWORD idInst, HSZ hsz)
{
    return DdeKeepStringHandle(idInst, hsz);
}

/*****************************************************************
 *            DdeClientTransaction  (DDEML.11)
 */
HDDEDATA WINAPI DdeClientTransaction16(LPVOID pData, DWORD cbData, HCONV hConv,
                                       HSZ hszItem, UINT16 wFmt, UINT16 wType,
                                       DWORD dwTimeout, LPDWORD pdwResult)
{
    if (cbData != (DWORD)-1)
    {
        /* pData is not a pointer if cbData is -1, so we linearize the address
         * here rather than in the calling code. */
        pData = MapSL((SEGPTR)pData);
    }
    return DdeClientTransaction(pData, cbData, hConv, hszItem,
                                wFmt, wType, dwTimeout, pdwResult);
}

/*****************************************************************
 *
 *            DdeAbandonTransaction (DDEML.12)
 *
 */
BOOL16 WINAPI DdeAbandonTransaction16(DWORD idInst, HCONV hConv, DWORD idTransaction)
{
    return (BOOL16)DdeAbandonTransaction(idInst, hConv, idTransaction);
}

/*****************************************************************
 * DdePostAdvise [DDEML.13]
 */
BOOL16 WINAPI DdePostAdvise16(DWORD idInst, HSZ hszTopic, HSZ hszItem)
{
    return (BOOL16)DdePostAdvise(idInst, hszTopic, hszItem);
}

/*****************************************************************
 *            DdeAddData (DDEML.15)
 */
HDDEDATA WINAPI DdeAddData16(HDDEDATA hData, LPBYTE pSrc, DWORD cb, DWORD cbOff)
{
    return DdeAddData(hData, pSrc, cb, cbOff);
}

/*****************************************************************
 * DdeGetData [DDEML.16]
 */
DWORD WINAPI DdeGetData16(HDDEDATA hData, LPBYTE pDst, DWORD cbMax, DWORD cbOff)
{
    return DdeGetData(hData, pDst, cbMax, cbOff);
}

/*****************************************************************
 *            DdeAccessData (DDEML.17)
 */
LPBYTE WINAPI DdeAccessData16(HDDEDATA hData, LPDWORD pcbDataSize)
{
    FIXME("expect trouble\n");
    /* FIXME: there's a memory leak here... */
    return (LPBYTE)MapLS(DdeAccessData(hData, pcbDataSize));
}

/*****************************************************************
 *            DdeUnaccessData (DDEML.18)
 */
BOOL16 WINAPI DdeUnaccessData16(HDDEDATA hData)
{
    return DdeUnaccessData(hData);
}

/*****************************************************************
 *            DdeEnableCallback (DDEML.26)
 */
BOOL16 WINAPI DdeEnableCallback16(DWORD idInst, HCONV hConv, UINT16 wCmd)
{
    return DdeEnableCallback(idInst, hConv, wCmd);
}

/*****************************************************************
 *            DdeNameService  (DDEML.27)
 */
HDDEDATA WINAPI DdeNameService16(DWORD idInst, HSZ hsz1, HSZ hsz2, UINT16 afCmd)
{
    return DdeNameService(idInst, hsz1, hsz2, afCmd);
}

/*****************************************************************
 *            DdeGetLastError  (DDEML.20)
 */
UINT16 WINAPI DdeGetLastError16(DWORD idInst)
{
    return (UINT16)DdeGetLastError(idInst);
}

/*****************************************************************
 *            DdeCmpStringHandles (DDEML.36)
 */
INT16 WINAPI DdeCmpStringHandles16(HSZ hsz1, HSZ hsz2)
{
    return DdeCmpStringHandles(hsz1, hsz2);
}

/******************************************************************
 *		DdeQueryConvInfo (DDEML.9)
 *
 */
UINT16 WINAPI DdeQueryConvInfo16(HCONV hConv, DWORD idTransaction,
                                 LPCONVINFO16 lpConvInfo)
{
    CONVINFO    ci32;
    CONVINFO16  ci16;
    UINT        ret;

    ci32.cb = sizeof(ci32);
    ci32.ConvCtxt.cb = sizeof(ci32.ConvCtxt);

    ret = DdeQueryConvInfo(hConv, idTransaction, &ci32);
    if (ret == 0) return 0;

    ci16.cb = lpConvInfo->cb;
    ci16.hUser = ci32.hUser;
    ci16.hConvPartner = ci32.hConvPartner;
    ci16.hszSvcPartner = ci32.hszSvcPartner;
    ci16.hszServiceReq = ci32.hszServiceReq;
    ci16.hszTopic = ci32.hszTopic;
    ci16.hszItem = ci32.hszItem;
    ci16.wFmt = ci32.wFmt;
    ci16.wType = ci32.wType;
    ci16.wStatus = ci32.wStatus;
    ci16.wConvst = ci32.wConvst;
    ci16.wLastError = ci32.wLastError;
    ci16.hConvList = ci32.hConvList;

    map3216_conv_context(&ci16.ConvCtxt, &ci32.ConvCtxt);

    memcpy(lpConvInfo, &ci16, lpConvInfo->cb);
    return lpConvInfo->cb;
}
