/*
 * 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);
        }
        else
        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 themselved
 */
#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.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;
}
