/* -*- tab-width: 8; c-basic-offset: 4 -*- */

/*
 * DDEML library
 *
 * Copyright 1997 Alexandre Julliard
 * Copyright 1997 Len White
 * Copyright 1999 Keith Matthews
 * Copyright 2000 Corel
 * Copyright 2001 Eric Pouech
 * Copyright 2004, 2005 Dmitry Timoshkov
 *
 * 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 <stdarg.h>
#include <string.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winerror.h"
#include "winnls.h"
#include "dde.h"
#include "ddeml.h"
#include "win.h"
#include "wine/debug.h"
#include "dde/dde_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(ddeml);

static LRESULT CALLBACK WDML_ClientProc(HWND, UINT, WPARAM, LPARAM);	/* only for one client, not conv list */
const WCHAR WDML_szClientConvClass[] = {'W','i','n','e','D','d','e','C','l','i','e','n','t',0};

/******************************************************************************
 * DdeConnectList [USER32.@]  Establishes conversation with DDE servers
 *
 * PARAMS
 *    idInst     [I] Instance identifier
 *    hszService [I] Handle to service name string
 *    hszTopic   [I] Handle to topic name string
 *    hConvList  [I] Handle to conversation list
 *    pCC        [I] Pointer to structure with context data
 *
 * RETURNS
 *    Success: Handle to new conversation list
 *    Failure: 0
 */
HCONVLIST WINAPI DdeConnectList(DWORD idInst, HSZ hszService, HSZ hszTopic,
				HCONVLIST hConvList, PCONVCONTEXT pCC)
{
    FIXME("(%ld,%p,%p,%p,%p): stub\n", idInst, hszService, hszTopic, hConvList, pCC);
    return (HCONVLIST)1;
}

/*****************************************************************
 * DdeQueryNextServer [USER32.@]
 */
HCONV WINAPI DdeQueryNextServer(HCONVLIST hConvList, HCONV hConvPrev)
{
    FIXME("(%p,%p): stub\n", hConvList, hConvPrev);
    return 0;
}

/******************************************************************************
 * DdeDisconnectList [USER32.@]  Destroys list and terminates conversations
 *
 *
 * PARAMS
 *    hConvList  [I] Handle to conversation list
 *
 * RETURNS
 *    Success: TRUE
 *    Failure: FALSE
 */
BOOL WINAPI DdeDisconnectList(HCONVLIST hConvList)
{
    FIXME("(%p): stub\n", hConvList);
    return TRUE;
}

/*****************************************************************
 *            DdeConnect   (USER32.@)
 */
HCONV WINAPI DdeConnect(DWORD idInst, HSZ hszService, HSZ hszTopic,
			PCONVCONTEXT pCC)
{
    HWND		hwndClient;
    WDML_INSTANCE*	pInstance;
    WDML_CONV*		pConv = NULL;
    ATOM		aSrv = 0, aTpc = 0;
    WNDCLASSEXW		wndclass;

    TRACE("(0x%lx,%p,%p,%p)\n", idInst, hszService, hszTopic, pCC);

    EnterCriticalSection(&WDML_CritSect);

    pInstance = WDML_GetInstance(idInst);
    if (!pInstance)
    {
	goto theEnd;
    }

    /* make sure this conv is never created */
    pConv = WDML_FindConv(pInstance, WDML_CLIENT_SIDE, hszService, hszTopic);
    if (pConv != NULL)
    {
	ERR("This Conv already exists: (%p)\n", pConv);
	goto theEnd;
    }

    /* we need to establish a conversation with
       server, so create a window for it       */

    wndclass.cbSize        = sizeof(wndclass);
    wndclass.style         = 0;
    wndclass.lpfnWndProc   = WDML_ClientProc;
    wndclass.cbClsExtra    = 0;
    wndclass.cbWndExtra    = 2 * sizeof(ULONG_PTR);
    wndclass.hInstance     = 0;
    wndclass.hIcon         = 0;
    wndclass.hCursor       = 0;
    wndclass.hbrBackground = 0;
    wndclass.lpszMenuName  = NULL;
    wndclass.lpszClassName = WDML_szClientConvClass;
    wndclass.hIconSm       = 0;

    RegisterClassExW(&wndclass);

    hwndClient = CreateWindowW(WDML_szClientConvClass, NULL, WS_POPUP, 0, 0, 0, 0, 0, 0, 0, 0);

    SetWindowLongPtrW(hwndClient, GWL_WDML_INSTANCE, (ULONG_PTR)pInstance);

    if (hszService)
    {
	aSrv = WDML_MakeAtomFromHsz(hszService);
	if (!aSrv) goto theEnd;
    }
    if (hszTopic)
    {
	aTpc = WDML_MakeAtomFromHsz(hszTopic);
	if (!aTpc) goto theEnd;
    }

    LeaveCriticalSection(&WDML_CritSect);

    /* note: sent messages shall not use packing */
    SendMessageTimeoutW( HWND_BROADCAST, WM_DDE_INITIATE, (WPARAM)hwndClient, MAKELPARAM(aSrv, aTpc),
                         SMTO_ABORTIFHUNG, 2000, NULL );

    EnterCriticalSection(&WDML_CritSect);

    pInstance = WDML_GetInstance(idInst);
    if (!pInstance)
    {
	goto theEnd;
    }

    /* At this point, Client WM_DDE_ACK should have saved hwndServer
       for this instance id and hwndClient if server responds.
       So get HCONV and return it. And add it to conv list */
    pConv = WDML_GetConvFromWnd(hwndClient);
    if (pConv == NULL || pConv->hwndServer == 0)
    {
	ERR("Done with INITIATE, but no Server window available\n");
	pConv = NULL;
	goto theEnd;
    }
    TRACE("Connected to Server window (%p)\n", pConv->hwndServer);
    pConv->wConvst = XST_CONNECTED;

    /* finish init of pConv */
    if (pCC != NULL)
    {
	pConv->convContext = *pCC;
    }
    else
    {
	memset(&pConv->convContext, 0, sizeof(pConv->convContext));
	pConv->convContext.cb = sizeof(pConv->convContext);
	pConv->convContext.iCodePage = CP_WINUNICODE;
    }

 theEnd:
    LeaveCriticalSection(&WDML_CritSect);

    if (aSrv) GlobalDeleteAtom(aSrv);
    if (aTpc) GlobalDeleteAtom(aTpc);
    return (HCONV)pConv;
}

/*****************************************************************
 *            DdeReconnect   (DDEML.37)
 *            DdeReconnect   (USER32.@)
 */
HCONV WINAPI DdeReconnect(HCONV hConv)
{
    WDML_CONV*	pConv;
    WDML_CONV*	pNewConv = NULL;
    ATOM	aSrv = 0, aTpc = 0;

    TRACE("(%p)\n", hConv);

    EnterCriticalSection(&WDML_CritSect);
    pConv = WDML_GetConv(hConv, FALSE);
    if (pConv != NULL && (pConv->wStatus & ST_CLIENT))
    {
	BOOL	ret;

	/* to reestablist a connection, we have to make sure that:
	 * 1/ pConv is the converstation attached to the client window (it wouldn't be
	 *    if a call to DdeReconnect would have already been done...)
	 *    FIXME: is this really an error ???
	 * 2/ the pConv conversation had really been deconnected
	 */
	if (pConv == WDML_GetConvFromWnd(pConv->hwndClient) &&
	    (pConv->wStatus & ST_TERMINATED) && !(pConv->wStatus & ST_CONNECTED))
	{
	    HWND	hwndClient = pConv->hwndClient;
	    HWND	hwndServer = pConv->hwndServer;
	    ATOM	aSrv, aTpc;

	    SetWindowLongPtrW(pConv->hwndClient, GWL_WDML_CONVERSATION, 0);

	    aSrv = WDML_MakeAtomFromHsz(pConv->hszService);
	    aTpc = WDML_MakeAtomFromHsz(pConv->hszTopic);
	    if (!aSrv || !aTpc)	goto theEnd;

	    LeaveCriticalSection(&WDML_CritSect);

            /* note: sent messages shall not use packing */
	    ret = SendMessageW(hwndServer, WM_DDE_INITIATE, (WPARAM)hwndClient,
                               MAKELPARAM(aSrv, aTpc));

	    EnterCriticalSection(&WDML_CritSect);

	    pConv = WDML_GetConv(hConv, FALSE);
	    if (pConv == NULL)
	    {
		FIXME("Should fail reconnection\n");
		goto theEnd;
	    }

	    if (ret && (pNewConv = WDML_GetConvFromWnd(pConv->hwndClient)) != NULL)
	    {
		/* re-establish all links... */
		WDML_LINK* pLink;

		for (pLink = pConv->instance->links[WDML_CLIENT_SIDE]; pLink; pLink = pLink->next)
		{
		    if (pLink->hConv == hConv)
		    {
			/* try to reestablish the links... */
			DdeClientTransaction(NULL, 0, (HCONV)pNewConv, pLink->hszItem, pLink->uFmt,
					     pLink->transactionType, 1000, NULL);
		    }
		}
	    }
	    else
	    {
		/* reset the conversation as it was */
		SetWindowLongPtrW(pConv->hwndClient, GWL_WDML_CONVERSATION, (ULONG_PTR)pConv);
	    }
	}
    }

 theEnd:
    LeaveCriticalSection(&WDML_CritSect);

    if (aSrv) GlobalDeleteAtom(aSrv);
    if (aTpc) GlobalDeleteAtom(aTpc);
    return (HCONV)pNewConv;
}

/******************************************************************
 *		WDML_ClientQueueAdvise
 *
 * Creates and queue an WM_DDE_ADVISE transaction
 */
static WDML_XACT*	WDML_ClientQueueAdvise(WDML_CONV* pConv, UINT wType, UINT wFmt, HSZ hszItem)
{
    DDEADVISE*		pDdeAdvise;
    WDML_XACT*		pXAct;
    ATOM		atom;

    TRACE("XTYP_ADVSTART (with%s data) transaction\n", (wType & XTYPF_NODATA) ? "out" : "");

    atom = WDML_MakeAtomFromHsz(hszItem);
    if (!atom) return NULL;

    pXAct = WDML_AllocTransaction(pConv->instance, WM_DDE_ADVISE, wFmt, hszItem);
    if (!pXAct)
    {
	GlobalDeleteAtom(atom);
	return NULL;
    }

    pXAct->wType = wType & ~0x0F;
    pXAct->hMem = GlobalAlloc(GHND | GMEM_DDESHARE, sizeof(DDEADVISE));
    /* FIXME: hMem is unfreed for now... should be deleted in server */

    /* pack DdeAdvise	*/
    pDdeAdvise = (DDEADVISE*)GlobalLock(pXAct->hMem);
    pDdeAdvise->fAckReq   = (wType & XTYPF_ACKREQ) ? TRUE : FALSE;
    pDdeAdvise->fDeferUpd = (wType & XTYPF_NODATA) ? TRUE : FALSE;
    pDdeAdvise->cfFormat  = wFmt;
    GlobalUnlock(pXAct->hMem);

    pXAct->lParam = PackDDElParam(WM_DDE_ADVISE, (UINT_PTR)pXAct->hMem, atom);

    return pXAct;
}

/******************************************************************
 *		WDML_HandleAdviseReply
 *
 * handles the reply to an advise request
 */
static WDML_QUEUE_STATE WDML_HandleAdviseReply(WDML_CONV* pConv, MSG* msg, WDML_XACT* pXAct)
{
    DDEACK		ddeAck;
    UINT_PTR		uiLo, uiHi;
    HSZ			hsz;

    if (msg->message != WM_DDE_ACK || WIN_GetFullHandle((HWND)msg->wParam) != pConv->hwndServer)
    {
	return WDML_QS_PASS;
    }

    UnpackDDElParam(WM_DDE_ACK, msg->lParam, &uiLo, &uiHi);
    hsz = WDML_MakeHszFromAtom(pConv->instance, uiHi);

    if (DdeCmpStringHandles(hsz, pXAct->hszItem) != 0)
	return WDML_QS_PASS;

    GlobalDeleteAtom(uiHi);
    FreeDDElParam(WM_DDE_ACK, msg->lParam);

    WDML_ExtractAck(uiLo, &ddeAck);

    if (ddeAck.fAck)
    {
	WDML_LINK*	pLink;

	/* billx: first to see if the link is already created. */
	pLink = WDML_FindLink(pConv->instance, (HCONV)pConv, WDML_CLIENT_SIDE,
			      pXAct->hszItem, TRUE, pXAct->wFmt);
	if (pLink != NULL)
	{
	    /* we found a link, and only need to modify it in case it changes */
	    pLink->transactionType = pXAct->wType;
	}
	else
	{
	    WDML_AddLink(pConv->instance, (HCONV)pConv, WDML_CLIENT_SIDE,
			 pXAct->wType, pXAct->hszItem, pXAct->wFmt);
	}
        pXAct->hDdeData = (HDDEDATA)1;
    }
    else
    {
	TRACE("Returning FALSE on XTYP_ADVSTART - fAck was FALSE\n");
	GlobalFree(pXAct->hMem);
        pXAct->hDdeData = NULL;
    }

    return WDML_QS_HANDLED;
}

/******************************************************************
 *		WDML_ClientQueueUnadvise
 *
 * queues an unadvise transaction
 */
static WDML_XACT*	WDML_ClientQueueUnadvise(WDML_CONV* pConv, UINT wFmt, HSZ hszItem)
{
    WDML_XACT*	pXAct;
    ATOM	atom;

    TRACE("XTYP_ADVSTOP transaction\n");

    atom = WDML_MakeAtomFromHsz(hszItem);
    if (!atom) return NULL;

    pXAct = WDML_AllocTransaction(pConv->instance, WM_DDE_UNADVISE, wFmt, hszItem);
    if (!pXAct)
    {
	GlobalDeleteAtom(atom);
	return NULL;
    }

    /* end advise loop: post WM_DDE_UNADVISE to server to terminate link
     * on the specified item.
     */
    pXAct->lParam = PackDDElParam(WM_DDE_UNADVISE, wFmt, atom);
    return pXAct;
}

/******************************************************************
 *		WDML_HandleUnadviseReply
 *
 *
 */
static WDML_QUEUE_STATE WDML_HandleUnadviseReply(WDML_CONV* pConv, MSG* msg, WDML_XACT* pXAct)
{
    DDEACK	ddeAck;
    UINT_PTR	uiLo, uiHi;
    HSZ		hsz;

    if (msg->message != WM_DDE_ACK || WIN_GetFullHandle((HWND)msg->wParam) != pConv->hwndServer)
    {
	return WDML_QS_PASS;
    }

    UnpackDDElParam(WM_DDE_ACK, msg->lParam, &uiLo, &uiHi);
    hsz = WDML_MakeHszFromAtom(pConv->instance, uiHi);

    if (DdeCmpStringHandles(hsz, pXAct->hszItem) != 0)
	return WDML_QS_PASS;

    FreeDDElParam(WM_DDE_ACK, msg->lParam);
    GlobalDeleteAtom(uiHi);

    WDML_ExtractAck(uiLo, &ddeAck);

    TRACE("WM_DDE_ACK received while waiting for a timeout\n");

    if (!ddeAck.fAck)
    {
	TRACE("Returning FALSE on XTYP_ADVSTOP - fAck was FALSE\n");
        pXAct->hDdeData = NULL;
    }
    else
    {
	/* billx: remove the link */
	WDML_RemoveLink(pConv->instance, (HCONV)pConv, WDML_CLIENT_SIDE,
			pXAct->hszItem, pXAct->wFmt);
        pXAct->hDdeData = (HDDEDATA)1;
    }
    return WDML_QS_HANDLED;
}

/******************************************************************
 *		WDML_ClientQueueRequest
 *
 *
 */
static WDML_XACT*	WDML_ClientQueueRequest(WDML_CONV* pConv, UINT wFmt, HSZ hszItem)
{
    WDML_XACT*	pXAct;
    ATOM	atom;

    TRACE("XTYP_REQUEST transaction\n");

    atom = WDML_MakeAtomFromHsz(hszItem);
    if (!atom) return NULL;

    pXAct = WDML_AllocTransaction(pConv->instance, WM_DDE_REQUEST, wFmt, hszItem);
    if (!pXAct)
    {
	GlobalDeleteAtom(atom);
	return NULL;
    }

    pXAct->lParam = PackDDElParam(WM_DDE_REQUEST, wFmt, atom);

    return pXAct;
}

/******************************************************************
 *		WDML_HandleRequestReply
 *
 *
 */
static WDML_QUEUE_STATE WDML_HandleRequestReply(WDML_CONV* pConv, MSG* msg, WDML_XACT* pXAct)
{
    DDEACK		ddeAck;
    WINE_DDEHEAD	wdh;
    UINT_PTR		uiLo, uiHi;
    HSZ			hsz;

    if (WIN_GetFullHandle((HWND)msg->wParam) != pConv->hwndServer)
	return WDML_QS_PASS;

    switch (msg->message)
    {
    case WM_DDE_ACK:
        UnpackDDElParam(WM_DDE_ACK, msg->lParam, &uiLo, &uiHi);
        FreeDDElParam(WM_DDE_ACK, msg->lParam);
	GlobalDeleteAtom(uiHi);
	WDML_ExtractAck(uiLo, &ddeAck);
	pXAct->hDdeData = 0;
	if (ddeAck.fAck)
	    ERR("Positive answer should appear in NACK for a request, assuming negative\n");
	TRACE("Negative answer...\n");
	break;

    case WM_DDE_DATA:
        UnpackDDElParam(WM_DDE_DATA, msg->lParam, &uiLo, &uiHi);
	TRACE("Got the result (%08x)\n", uiLo);

	hsz = WDML_MakeHszFromAtom(pConv->instance, uiHi);

	if (DdeCmpStringHandles(hsz, pXAct->hszItem) != 0)
	    return WDML_QS_PASS;

	pXAct->hDdeData = WDML_Global2DataHandle((HGLOBAL)uiLo, &wdh);
	if (wdh.fRelease)
	{
	    GlobalFree((HGLOBAL)uiLo);
	}
	if (wdh.fAckReq)
	{
	    WDML_PostAck(pConv, WDML_CLIENT_SIDE, 0, FALSE, TRUE, uiHi, msg->lParam, WM_DDE_DATA);
	}
	else
	{
	    GlobalDeleteAtom(uiHi);
            FreeDDElParam(WM_DDE_ACK, msg->lParam);
	}
	break;

    default:
        FreeDDElParam(msg->message, msg->lParam);
	return WDML_QS_PASS;
    }

    return WDML_QS_HANDLED;
}

/******************************************************************
 *		WDML_BuildExecuteCommand
 *
 * Creates a DDE block suitable for sending in WM_DDE_COMMAND
 * It also takes care of string conversion between the two window procedures
 */
static	HGLOBAL	WDML_BuildExecuteCommand(WDML_CONV* pConv, LPCVOID pData, DWORD cbData)
{
    HGLOBAL	hMem;
    BOOL	clientUnicode, serverUnicode;
    DWORD	memSize;

    clientUnicode = IsWindowUnicode(pConv->hwndClient);
    serverUnicode = IsWindowUnicode(pConv->hwndServer);

    if (clientUnicode == serverUnicode)
    {
	memSize = cbData;
    }
    else
    {
	if (clientUnicode)
	{
	    memSize = WideCharToMultiByte( CP_ACP, 0, pData, cbData, NULL, 0, NULL, NULL);
	}
	else
	{
	    memSize = MultiByteToWideChar( CP_ACP, 0, pData, cbData, NULL, 0) * sizeof(WCHAR);
	}
    }

    hMem = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, memSize);

    if (hMem)
    {
	LPBYTE	pDst;

	pDst = GlobalLock(hMem);
	if (pDst)
	{
	    if (clientUnicode == serverUnicode)
	    {
		memcpy(pDst, pData, cbData);
	    }
	    else
	    {
		if (clientUnicode)
		{
		    WideCharToMultiByte( CP_ACP, 0, pData, cbData, pDst, memSize, NULL, NULL);
		}
		else
		{
		    MultiByteToWideChar( CP_ACP, 0, pData, cbData, (LPWSTR)pDst, memSize/sizeof(WCHAR));
		}
	    }

	    GlobalUnlock(hMem);
	}
	else
	{
	    GlobalFree(hMem);
	    hMem = 0;
	}
    }
    return hMem;
}

/******************************************************************
 *		WDML_ClientQueueExecute
 *
 *
 */
static WDML_XACT*	WDML_ClientQueueExecute(WDML_CONV* pConv, LPCVOID pData, DWORD cbData)
{
    WDML_XACT*	pXAct;

    TRACE("XTYP_EXECUTE transaction\n");

    pXAct = WDML_AllocTransaction(pConv->instance, WM_DDE_EXECUTE, 0, 0);
    if (!pXAct)
	return NULL;

    if (cbData == (DWORD)-1)
    {
	HDDEDATA	hDdeData = (HDDEDATA)pData;

	pData = DdeAccessData(hDdeData, &cbData);
	if (pData)
	{
	    pXAct->hMem = WDML_BuildExecuteCommand(pConv, pData, cbData);
	    DdeUnaccessData(hDdeData);
	}
    }
    else
    {
	pXAct->hMem = WDML_BuildExecuteCommand(pConv, pData, cbData);
    }

    pXAct->lParam = (LPARAM)pXAct->hMem;

    return pXAct;
}

/******************************************************************
 *		WDML_HandleExecuteReply
 *
 *
 */
static WDML_QUEUE_STATE WDML_HandleExecuteReply(WDML_CONV* pConv, MSG* msg, WDML_XACT* pXAct)
{
    DDEACK	ddeAck;
    UINT_PTR	uiLo, uiHi;

    if (msg->message != WM_DDE_ACK || WIN_GetFullHandle((HWND)msg->wParam) != pConv->hwndServer)
    {
	return WDML_QS_PASS;
    }

    UnpackDDElParam(WM_DDE_ACK, msg->lParam, &uiLo, &uiHi);
    FreeDDElParam(WM_DDE_ACK, msg->lParam);

    if ((HANDLE)uiHi != pXAct->hMem)
    {
        return WDML_QS_PASS;
    }

    WDML_ExtractAck(uiLo, &ddeAck);
    pXAct->hDdeData = (HDDEDATA)(UINT_PTR)ddeAck.fAck;

    TRACE("hDdeData = %p\n", pXAct->hDdeData);
    pConv->instance->lastError = (pXAct->hDdeData != 0) ? DMLERR_NO_ERROR : DMLERR_NOTPROCESSED;

    return WDML_QS_HANDLED;
}

/******************************************************************
 *		WDML_ClientQueuePoke
 *
 *
 */
static WDML_XACT*	WDML_ClientQueuePoke(WDML_CONV* pConv, LPCVOID pData, DWORD cbData,
					     UINT wFmt, HSZ hszItem)
{
    WDML_XACT*	pXAct;
    ATOM	atom;

    TRACE("XTYP_POKE transaction\n");

    atom = WDML_MakeAtomFromHsz(hszItem);
    if (!atom) return NULL;

    pXAct = WDML_AllocTransaction(pConv->instance, WM_DDE_POKE, wFmt, hszItem);
    if (!pXAct)
    {
	GlobalDeleteAtom(atom);
	return NULL;
    }

    if (cbData == (DWORD)-1)
    {
	pXAct->hMem = (HDDEDATA)pData;
    }
    else
    {
	DDEPOKE*	ddePoke;

	pXAct->hMem = GlobalAlloc(GHND | GMEM_DDESHARE, sizeof(DDEPOKE) + cbData);
	ddePoke = GlobalLock(pXAct->hMem);
	if (ddePoke)
	{
	    memcpy(ddePoke->Value, pData, cbData);
	    ddePoke->fRelease = FALSE; /* FIXME: app owned ? */
	    ddePoke->cfFormat = wFmt;
	    GlobalUnlock(pXAct->hMem);
	}
    }

    pXAct->lParam = PackDDElParam(WM_DDE_POKE, (UINT_PTR)pXAct->hMem, atom);

    return pXAct;
}

/******************************************************************
 *		WDML_HandlePokeReply
 *
 *
 */
static WDML_QUEUE_STATE WDML_HandlePokeReply(WDML_CONV* pConv, MSG* msg, WDML_XACT* pXAct)
{
    DDEACK	ddeAck;
    UINT_PTR	uiLo, uiHi;
    HSZ		hsz;

    if (msg->message != WM_DDE_ACK && WIN_GetFullHandle((HWND)msg->wParam) != pConv->hwndServer)
    {
	return WDML_QS_PASS;
    }

    UnpackDDElParam(WM_DDE_ACK, msg->lParam, &uiLo, &uiHi);
    hsz = WDML_MakeHszFromAtom(pConv->instance, uiHi);
    if (DdeCmpStringHandles(hsz, pXAct->hszItem) != 0)
    {
	return WDML_QS_PASS;
    }
    FreeDDElParam(WM_DDE_ACK, msg->lParam);
    GlobalDeleteAtom(uiHi);

    WDML_ExtractAck(uiLo, &ddeAck);
    GlobalFree(pXAct->hMem);

    pXAct->hDdeData = (HDDEDATA)TRUE;
    return TRUE;
}

/******************************************************************
 *		WDML_ClientQueueTerminate
 *
 * Creates and queue an WM_DDE_TERMINATE transaction
 */
static WDML_XACT*	WDML_ClientQueueTerminate(WDML_CONV* pConv)
{
    WDML_XACT*		pXAct;

    pXAct = WDML_AllocTransaction(pConv->instance, WM_DDE_TERMINATE, 0, 0);
    if (!pXAct)
	return NULL;

    pXAct->lParam = 0;
    pConv->wStatus &= ~ST_CONNECTED;

    return pXAct;
}

/******************************************************************
 *		WDML_HandleTerminateReply
 *
 * handles the reply to a terminate request
 */
static WDML_QUEUE_STATE WDML_HandleTerminateReply(WDML_CONV* pConv, MSG* msg, WDML_XACT* pXAct)
{
    if (msg->message != WM_DDE_TERMINATE)
    {
	/* FIXME: should delete data passed here */
	return WDML_QS_SWALLOWED;
    }

    if (WIN_GetFullHandle((HWND)msg->wParam) != pConv->hwndServer)
    {
	FIXME("hmmm shouldn't happen\n");
	return WDML_QS_PASS;
    }
    if (!pConv->instance->CBFflags & CBF_SKIP_DISCONNECTS)
    {
	WDML_InvokeCallback(pConv->instance, XTYP_DISCONNECT, 0, (HCONV)pConv,
			    0, 0, 0, 0, (pConv->wStatus & ST_ISSELF) ? 1 : 0);
    }
    WDML_RemoveConv(pConv, WDML_CLIENT_SIDE);
    return WDML_QS_HANDLED;
}

/******************************************************************
 *		WDML_HandleReplyData
 *
 *
 */
static WDML_QUEUE_STATE WDML_HandleIncomingData(WDML_CONV* pConv, MSG* msg, HDDEDATA* hdd)
{
    UINT_PTR		uiLo, uiHi;
    HDDEDATA		hDdeDataIn, hDdeDataOut;
    WDML_LINK*		pLink;
    WINE_DDEHEAD	wdh;
    HSZ			hsz;

    TRACE("WM_DDE_DATA message received in the Client Proc!\n");
    /* wParam -- sending window handle	*/
    /* lParam -- hDdeData & item HSZ	*/

    UnpackDDElParam(WM_DDE_DATA, msg->lParam, &uiLo, &uiHi);
    hsz = WDML_MakeHszFromAtom(pConv->instance, uiHi);

    hDdeDataIn = WDML_Global2DataHandle((HGLOBAL)uiLo, &wdh);

    /* billx:
     *  For hot link, data should be passed to its callback with
     * XTYP_ADVDATA and callback should return the proper status.
     */
    pLink = WDML_FindLink(pConv->instance, (HCONV)pConv, WDML_CLIENT_SIDE, hsz,
                          uiLo ? TRUE : FALSE, wdh.cfFormat);
    if (!pLink)
    {
	WDML_DecHSZ(pConv->instance, hsz);
        DdeFreeDataHandle(hDdeDataIn);
	return WDML_QS_PASS;
    }

    if (hDdeDataIn != 0 && wdh.fAckReq)
    {
	WDML_PostAck(pConv, WDML_CLIENT_SIDE, 0, FALSE, TRUE, uiHi, msg->lParam, WM_DDE_DATA);
	if (msg->lParam)
	    msg->lParam = 0;
    }
    else
    {
	GlobalDeleteAtom(uiHi);
    }

    hDdeDataOut = WDML_InvokeCallback(pConv->instance, XTYP_ADVDATA, pLink->uFmt, pLink->hConv,
				      pConv->hszTopic, pLink->hszItem, hDdeDataIn, 0, 0);

    if (hDdeDataOut != (HDDEDATA)DDE_FACK || wdh.fRelease)
    {
        if (uiLo) GlobalFree((HANDLE)uiLo);
    }

    DdeFreeDataHandle(hDdeDataIn);

    WDML_DecHSZ(pConv->instance, hsz);
    if (msg->lParam)
	FreeDDElParam(WM_DDE_DATA, msg->lParam);

    return WDML_QS_HANDLED;
}

/******************************************************************
 *		WDML_HandleIncomingTerminate
 *
 *
 */
static WDML_QUEUE_STATE WDML_HandleIncomingTerminate(WDML_CONV* pConv, MSG* msg, HDDEDATA* hdd)
{
    if (pConv->hwndServer != WIN_GetFullHandle((HWND)msg->wParam))
	return WDML_QS_PASS;

    pConv->wStatus |= ST_TERMINATED;
    if (!pConv->instance->CBFflags & CBF_SKIP_DISCONNECTS)
    {
	WDML_InvokeCallback(pConv->instance, XTYP_DISCONNECT, 0, (HCONV)pConv,
			    0, 0, 0, 0, (pConv->wStatus & ST_ISSELF) ? 1 : 0);
    }
    if (pConv->wStatus & ST_CONNECTED)
    {
	/* don't care about result code (if server exists or not) */
	PostMessageW(pConv->hwndServer, WM_DDE_TERMINATE, (WPARAM)pConv->hwndClient, 0L);
	pConv->wStatus &= ~ST_CONNECTED;
    }
    /* have to keep connection around to allow reconnection */
    return WDML_QS_HANDLED;
}

/******************************************************************
 *		WDML_HandleReply
 *
 * handles any incoming reply, and try to match to an already sent request
 */
static WDML_QUEUE_STATE	WDML_HandleReply(WDML_CONV* pConv, MSG* msg, HDDEDATA* hdd)
{
    WDML_XACT*		pXAct = pConv->transactions;
    WDML_QUEUE_STATE	qs;

    if (pConv->transactions)
    {
	/* first check message against a pending transaction, if any */
	switch (pXAct->ddeMsg)
	{
	case WM_DDE_ADVISE:
	    qs = WDML_HandleAdviseReply(pConv, msg, pXAct);
	    break;
	case WM_DDE_UNADVISE:
	    qs = WDML_HandleUnadviseReply(pConv, msg, pXAct);
	    break;
	case WM_DDE_EXECUTE:
	    qs = WDML_HandleExecuteReply(pConv, msg, pXAct);
	    break;
	case WM_DDE_REQUEST:
	    qs = WDML_HandleRequestReply(pConv, msg, pXAct);
	    break;
	case WM_DDE_POKE:
	    qs = WDML_HandlePokeReply(pConv, msg, pXAct);
	    break;
	case WM_DDE_TERMINATE:
	    qs = WDML_HandleTerminateReply(pConv, msg, pXAct);
	    break;
	default:
	    qs = WDML_QS_ERROR;
	    FIXME("oooch\n");
	}
    }
    else
    {
	qs = WDML_QS_PASS;
    }

    /* now check the results */
    switch (qs)
    {
    case WDML_QS_ERROR:
    case WDML_QS_SWALLOWED:
	*hdd = 0;
	break;
    case WDML_QS_HANDLED:
	/* ok, we have resolved a pending transaction
	 * notify callback if asynchronous, and remove it in any case
	 */
	WDML_UnQueueTransaction(pConv, pXAct);
	if (pXAct->dwTimeout == TIMEOUT_ASYNC && pXAct->ddeMsg != WM_DDE_TERMINATE)
	{
	    WDML_InvokeCallback(pConv->instance, XTYP_XACT_COMPLETE, pXAct->wFmt,
				(HCONV)pConv, pConv->hszTopic, pXAct->hszItem,
				pXAct->hDdeData, MAKELONG(0, pXAct->xActID), 0 /* FIXME */);
	    qs = WDML_QS_PASS;
	}
	else
	{
	    *hdd = pXAct->hDdeData;
	}
	WDML_FreeTransaction(pConv->instance, pXAct, TRUE);
	break;
    case WDML_QS_PASS:
	/* no pending transaction found, try a warm/hot link or a termination request */
	switch (msg->message)
	{
	case WM_DDE_DATA:
	    qs = WDML_HandleIncomingData(pConv, msg, hdd);
	    break;
	case WM_DDE_TERMINATE:
	    qs = WDML_HandleIncomingTerminate(pConv, msg, hdd);
	    break;
	}
	break;
    case WDML_QS_BLOCK:
	FIXME("shouldn't be used on client side\n");
	break;
    }

    return qs;
}

/******************************************************************
 *		WDML_SyncWaitTransactionReply
 *
 * waits until an answer for a sent request is received
 * time out is also handled. only used for synchronous transactions
 */
static HDDEDATA WDML_SyncWaitTransactionReply(HCONV hConv, DWORD dwTimeout, WDML_XACT* pXAct)
{
    DWORD	dwTime;
    DWORD	err;
    WDML_CONV*	pConv;

    TRACE("Starting wait for a timeout of %ld ms\n", dwTimeout);

    /* FIXME: time 32 bit wrap around */
    dwTimeout += GetCurrentTime();

    while ((dwTime = GetCurrentTime()) < dwTimeout)
    {
	/* we cannot be in the crit sect all the time because when client and server run in a
	 * single process they need to share the access to the internal data
	 */
	if (MsgWaitForMultipleObjects(0, NULL, FALSE,
				      dwTimeout - dwTime, QS_POSTMESSAGE) == WAIT_OBJECT_0)
	{
	    BOOL	ret = FALSE;
	    MSG		msg;
	    WDML_CONV*	pConv;
	    HDDEDATA	hdd;

	    EnterCriticalSection(&WDML_CritSect);

	    pConv = WDML_GetConv(hConv, FALSE);
	    if (pConv == NULL)
	    {
		LeaveCriticalSection(&WDML_CritSect);
		/* conversation no longer available... return failure */
		break;
	    }
	    while (PeekMessageW(&msg, pConv->hwndClient, WM_DDE_FIRST, WM_DDE_LAST, PM_REMOVE))
	    {
		/* check that either pXAct has been processed or no more xActions are pending */
		ret = (pConv->transactions == pXAct);
		ret = WDML_HandleReply(pConv, &msg, &hdd) == WDML_QS_HANDLED &&
		    (pConv->transactions == NULL || ret);
		if (ret) break;
	    }
	    LeaveCriticalSection(&WDML_CritSect);
	    if (ret)
	    {
		return hdd;
	    }
	}
    }

    TRACE("Timeout !!\n");

    EnterCriticalSection(&WDML_CritSect);

    pConv = WDML_GetConv(hConv, FALSE);
    if (pConv != NULL)
    {
	if (pConv->transactions)
	{
	    switch (pConv->transactions->ddeMsg)
	    {
	    case WM_DDE_ADVISE:		err = DMLERR_ADVACKTIMEOUT;	break;
	    case WM_DDE_REQUEST:	err = DMLERR_DATAACKTIMEOUT; 	break;
	    case WM_DDE_EXECUTE:	err = DMLERR_EXECACKTIMEOUT;	break;
	    case WM_DDE_POKE:		err = DMLERR_POKEACKTIMEOUT;	break;
	    case WM_DDE_UNADVISE:	err = DMLERR_UNADVACKTIMEOUT;	break;
	    default:			err = DMLERR_INVALIDPARAMETER;	break;
	    }

	    pConv->instance->lastError = err;
	}
    }
    LeaveCriticalSection(&WDML_CritSect);

    return 0;
}

/*****************************************************************
 *            DdeClientTransaction  (USER32.@)
 */
HDDEDATA WINAPI DdeClientTransaction(LPBYTE pData, DWORD cbData, HCONV hConv, HSZ hszItem, UINT wFmt,
				     UINT wType, DWORD dwTimeout, LPDWORD pdwResult)
{
    WDML_CONV*		pConv;
    WDML_XACT*		pXAct;
    HDDEDATA		hDdeData = 0;

    TRACE("(%p,%ld,%p,%p,%x,%x,%ld,%p)\n",
	  pData, cbData, hConv, hszItem, wFmt, wType, dwTimeout, pdwResult);

    if (hConv == 0)
    {
	ERR("Invalid conversation handle\n");
	return 0;
    }

    EnterCriticalSection(&WDML_CritSect);

    pConv = WDML_GetConv(hConv, TRUE);
    if (pConv == NULL)
    {
	/* cannot set error... cannot get back to DDE instance */
	goto theError;
    }

    switch (wType)
    {
    case XTYP_EXECUTE:
	if (hszItem != 0 || wFmt != 0)
	{
	    pConv->instance->lastError = DMLERR_INVALIDPARAMETER;
	    goto theError;
	}
	pXAct = WDML_ClientQueueExecute(pConv, pData, cbData);
	break;
    case XTYP_POKE:
	pXAct = WDML_ClientQueuePoke(pConv, pData, cbData, wFmt, hszItem);
	break;
    case XTYP_ADVSTART|XTYPF_NODATA:
    case XTYP_ADVSTART|XTYPF_NODATA|XTYPF_ACKREQ:
    case XTYP_ADVSTART:
    case XTYP_ADVSTART|XTYPF_ACKREQ:
	if (pData)
	{
	    pConv->instance->lastError = DMLERR_INVALIDPARAMETER;
	    goto theError;
	}
	pXAct = WDML_ClientQueueAdvise(pConv, wType, wFmt, hszItem);
	break;
    case XTYP_ADVSTOP:
	if (pData)
	{
	    pConv->instance->lastError = DMLERR_INVALIDPARAMETER;
	    goto theError;
	}
	pXAct = WDML_ClientQueueUnadvise(pConv, wFmt, hszItem);
	break;
    case XTYP_REQUEST:
	if (pData)
	{
	    pConv->instance->lastError = DMLERR_INVALIDPARAMETER;
	    goto theError;
	}
	pXAct = WDML_ClientQueueRequest(pConv, wFmt, hszItem);
	break;
    default:
	FIXME("Unknown transation\n");
	/* unknown transaction type */
	pConv->instance->lastError = DMLERR_INVALIDPARAMETER;
	goto theError;
    }

    if (pXAct == NULL)
    {
	pConv->instance->lastError = DMLERR_MEMORY_ERROR;
	goto theError;
    }

    WDML_QueueTransaction(pConv, pXAct);

    if (!PostMessageW(pConv->hwndServer, pXAct->ddeMsg, (WPARAM)pConv->hwndClient, pXAct->lParam))
    {
	WARN("Failed posting message %x to %p (error=0x%lx)\n",
	      pXAct->ddeMsg, pConv->hwndServer, GetLastError());
	pConv->wStatus &= ~ST_CONNECTED;
	WDML_UnQueueTransaction(pConv, pXAct);
	WDML_FreeTransaction(pConv->instance, pXAct, TRUE);
	goto theError;
    }
    pXAct->dwTimeout = dwTimeout;
    /* FIXME: should set the app bits on *pdwResult */

    if (dwTimeout == TIMEOUT_ASYNC)
    {
	if (pdwResult)
	{
	    *pdwResult = MAKELONG(0, pXAct->xActID);
	}
	hDdeData = (HDDEDATA)1;
    }
    else
    {
	DWORD	count, i;

	if (pdwResult)
	{
	    *pdwResult = 0L;
	}
	count = WDML_CritSect.RecursionCount;
	for (i = 0; i < count; i++)
	    LeaveCriticalSection(&WDML_CritSect);
	hDdeData = WDML_SyncWaitTransactionReply((HCONV)pConv, dwTimeout, pXAct);
	for (i = 0; i < count; i++)
	    EnterCriticalSection(&WDML_CritSect);
    }
    LeaveCriticalSection(&WDML_CritSect);

    return hDdeData;
 theError:
    LeaveCriticalSection(&WDML_CritSect);
    return 0;
}

/*****************************************************************
 *            DdeAbandonTransaction (USER32.@)
 */
BOOL WINAPI DdeAbandonTransaction(DWORD idInst, HCONV hConv, DWORD idTransaction)
{
    WDML_INSTANCE*	pInstance;
    WDML_CONV*		pConv;
    WDML_XACT*          pXAct;

    TRACE("(%08lx,%p,%08ld);\n", idInst, hConv, idTransaction);

    EnterCriticalSection(&WDML_CritSect);
    if ((pInstance = WDML_GetInstance(idInst)))
    {
        if (hConv)
        {
            if ((pConv = WDML_GetConv(hConv, TRUE)) && pConv->instance == pInstance)
            {
                for (pXAct = pConv->transactions; pXAct; pXAct = pXAct->next)
                {
                    if (pXAct->dwTimeout == TIMEOUT_ASYNC &&
                        (idTransaction == 0 || pXAct->xActID == idTransaction))
                    {
                        WDML_UnQueueTransaction(pConv, pXAct);
                        WDML_FreeTransaction(pInstance, pXAct, TRUE);
                    }
                }
            }
        }
        else
        {
            for (pConv = pInstance->convs[WDML_CLIENT_SIDE]; pConv; pConv = pConv->next)
            {
                if (!(pConv->wStatus & ST_CONNECTED)) continue;
                for (pXAct = pConv->transactions; pXAct; pXAct = pXAct->next)
                {
                    if (pXAct->dwTimeout == TIMEOUT_ASYNC)
                    {
                        WDML_UnQueueTransaction(pConv, pXAct);
                        WDML_FreeTransaction(pInstance, pXAct, TRUE);
                    }
                }
            }
        }
    }
    LeaveCriticalSection(&WDML_CritSect);

    return TRUE;
}

/******************************************************************
 *		WDML_ClientProc
 *
 * Window Proc created on client side for each conversation
 */
static LRESULT CALLBACK WDML_ClientProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
    UINT	uiLo, uiHi;
    WDML_CONV*	pConv = NULL;
    HSZ		hszSrv, hszTpc;

    TRACE("%p %04x %08x %08lx\n", hwnd, iMsg, wParam , lParam);

    if (iMsg == WM_DDE_ACK &&
	/* in the initial WM_INITIATE sendmessage */
	((pConv = WDML_GetConvFromWnd(hwnd)) == NULL || pConv->wStatus == XST_INIT1))
    {
	/* In response to WM_DDE_INITIATE, save server window  */
	WCHAR		buf[256];
	WDML_INSTANCE*	pInstance;

        /* note: sent messages do not need packing */
	uiLo = LOWORD(lParam);
        uiHi = HIWORD(lParam);

	/* FIXME: convlist should be handled here */
	if (pConv)
	{
	    /* we already have started the conv with a server, drop other replies */
	    GlobalDeleteAtom(uiLo);
	    GlobalDeleteAtom(uiHi);
            PostMessageW((HWND)wParam, WM_DDE_TERMINATE, (WPARAM)hwnd, 0);
	    return 0;
	}

	pInstance = WDML_GetInstanceFromWnd(hwnd);

	hszSrv = WDML_MakeHszFromAtom(pInstance, uiLo);
	hszTpc = WDML_MakeHszFromAtom(pInstance, uiHi);

	pConv = WDML_AddConv(pInstance, WDML_CLIENT_SIDE, hszSrv, hszTpc, hwnd, (HWND)wParam);

	SetWindowLongPtrW(hwnd, GWL_WDML_CONVERSATION, (ULONG_PTR)pConv);
	pConv->wStatus |= ST_CONNECTED;
	pConv->wConvst = XST_INIT1;

	/* check if server is handled by DDEML */
	if (GetClassNameW((HWND)wParam, buf, sizeof(buf)/sizeof(WCHAR)) &&
	     lstrcmpiW(buf, WDML_szServerConvClass) == 0)
	{
	    pConv->wStatus |= ST_ISLOCAL;
	}

	WDML_BroadcastDDEWindows(WDML_szEventClass, WM_WDML_CONNECT_CONFIRM, (WPARAM)hwnd, wParam);

	GlobalDeleteAtom(uiLo);
	GlobalDeleteAtom(uiHi);

	/* accept conversation */
	return 1;
    }

    if (iMsg >= WM_DDE_FIRST && iMsg <= WM_DDE_LAST)
    {
	EnterCriticalSection(&WDML_CritSect);

	pConv = WDML_GetConvFromWnd(hwnd);

	if (pConv)
	{
	    MSG		msg;
	    HDDEDATA	hdd;

	    msg.hwnd = hwnd;
	    msg.message = iMsg;
	    msg.wParam = wParam;
	    msg.lParam = lParam;

	    WDML_HandleReply(pConv, &msg, &hdd);
	}

	LeaveCriticalSection(&WDML_CritSect);
	return 0;
    }

    return DefWindowProcW(hwnd, iMsg, wParam, lParam);
}

/*****************************************************************
 *            DdeDisconnect   (USER32.@)
 */
BOOL WINAPI DdeDisconnect(HCONV hConv)
{
    WDML_CONV*	pConv = NULL;
    WDML_XACT*	pXAct;
    DWORD	count, i;
    BOOL	ret = FALSE;

    TRACE("(%p)\n", hConv);

    if (hConv == 0)
    {
	ERR("DdeDisconnect(): hConv = 0\n");
	return FALSE;
    }

    EnterCriticalSection(&WDML_CritSect);
    pConv = WDML_GetConv(hConv, TRUE);
    if (pConv != NULL)
    {
        if (pConv->wStatus & ST_CLIENT)
        {
            /* FIXME: should abandon all pending transactions */
            pXAct = WDML_ClientQueueTerminate(pConv);
            if (pXAct != NULL)
            {
                count = WDML_CritSect.RecursionCount;
                for (i = 0; i < count; i++)
                    LeaveCriticalSection(&WDML_CritSect);
                if (PostMessageW(pConv->hwndServer, pXAct->ddeMsg,
                                 (WPARAM)pConv->hwndClient, pXAct->lParam))
                    WDML_SyncWaitTransactionReply(hConv, 10000, pXAct);
                for (i = 0; i < count; i++)
                    EnterCriticalSection(&WDML_CritSect);
                ret = TRUE;
                WDML_FreeTransaction(pConv->instance, pXAct, TRUE);
                /* still have to destroy data assosiated with conversation */
                WDML_RemoveConv(pConv, WDML_CLIENT_SIDE);
            }
            else
            {
                FIXME("Not implemented yet for a server side conversation\n");
            }
        }
    }
    LeaveCriticalSection(&WDML_CritSect);

    return ret;
}

/*****************************************************************
 *            DdeImpersonateClient (USER32.@)
 */
BOOL WINAPI DdeImpersonateClient(HCONV hConv)
{
    WDML_CONV*	pConv;
    BOOL	ret = FALSE;

    TRACE("(%p)\n", hConv);

    EnterCriticalSection(&WDML_CritSect);
    pConv = WDML_GetConv(hConv, TRUE);
    if (pConv)
    {
	ret = ImpersonateDdeClientWindow(pConv->hwndClient, pConv->hwndServer);
    }
    LeaveCriticalSection(&WDML_CritSect);
    return ret;
}
