DDEML

Eric Pouech eric.pouech at wanadoo.fr
Sat Jan 12 08:52:03 CST 2002


following the raw DDE patch, this patch fixes a few things because of
raw DDE implementation, fixes lots of memory issues (leaks, even if some
remain), and adds a few new pieces (CreateDdeDataHandle now supports
bitmaps handle, transaction abandon is implemented)

A+
-- 
---------------
Eric Pouech (http://perso.wanadoo.fr/eric.pouech/)
"The future will be better tomorrow", Vice President Dan Quayle
-------------- next part --------------
Name: ddeml
ChangeLog: fixed initialisation messages for raw DDE
	fixed DdeCreateDataHandle for non NULL or CF_TEXT formats
	various fixes (cosmetics, better error checking)
GenDate: 2002/01/12 14:32:24 UTC
ModifiedFiles: dlls/user/dde/dde_private.h dlls/user/dde/client.c dlls/user/dde/misc.c dlls/user/dde/server.c
AddedFiles: 
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/dlls/user/dde/dde_private.h,v
retrieving revision 1.3
diff -u -u -r1.3 dde_private.h
--- dlls/user/dde/dde_private.h	18 Aug 2001 16:11:28 -0000	1.3
+++ dlls/user/dde/dde_private.h	6 Jan 2002 21:23:44 -0000
@@ -132,7 +132,6 @@
     UINT			transactionType;/* 0 for no link */
     HSZ				hszItem;	/* item targetted for (hot/warm) link */
     UINT			uFmt;		/* format for data */
-    HDDEDATA			hDdeData;	/* data them selves */
 } WDML_LINK;
 
 typedef struct tagWDML_INSTANCE
@@ -161,6 +160,7 @@
 typedef struct tagDDE_DATAHANDLE_HEAD
 {
     short	cfFormat;
+    WORD        bAppOwned;
 } DDE_DATAHANDLE_HEAD;
 
 typedef enum tagWDML_SIDE
@@ -191,12 +191,12 @@
 extern	WDML_CONV*	WDML_GetConvFromWnd(HWND hWnd);
 extern	WDML_CONV*	WDML_FindConv(WDML_INSTANCE* pInstance, WDML_SIDE side, 
 				      HSZ hszService, HSZ hszTopic);	
-extern  LPARAM		WDML_PostAck(WDML_CONV* pConv, WDML_SIDE side, WORD appRetCode, 
-				     BOOL fBusy, BOOL fAck, ATOM atom, LPARAM lParam, UINT oldMsg);
+extern  BOOL		WDML_PostAck(WDML_CONV* pConv, WDML_SIDE side, WORD appRetCode, 
+				     BOOL fBusy, BOOL fAck, UINT pmt, LPARAM lParam, UINT oldMsg);
 extern	void		WDML_AddLink(WDML_INSTANCE* pInstance, HCONV hConv, WDML_SIDE side, 
 				     UINT wType, HSZ hszItem, UINT wFmt);
 extern	WDML_LINK*	WDML_FindLink(WDML_INSTANCE* pInstance, HCONV hConv, WDML_SIDE side, 
-				      HSZ hszItem, UINT uFmt);
+				      HSZ hszItem, BOOL use_fmt, UINT uFmt);
 extern	void 		WDML_RemoveLink(WDML_INSTANCE* pInstance, HCONV hConv, WDML_SIDE side, 
 					HSZ hszItem, UINT wFmt);
 extern	void		WDML_RemoveAllLinks(WDML_INSTANCE* pInstance, WDML_CONV* pConv, WDML_SIDE side);
@@ -215,6 +215,7 @@
 extern	HGLOBAL		WDML_DataHandle2Global(HDDEDATA hDdeData, BOOL fResponse, BOOL fRelease, 
 					       BOOL fDeferUpd, BOOL dAckReq);
 extern	HDDEDATA	WDML_Global2DataHandle(HGLOBAL hMem, WINE_DDEHEAD* da);
+extern  BOOL            WDML_IsAppOwned(HDDEDATA hDdeData);
 extern	WDML_INSTANCE*	WDML_GetInstance(DWORD InstId);
 extern	WDML_INSTANCE*	WDML_GetInstanceFromWnd(HWND hWnd);
 /* broadcasting to DDE windows */
Index: dlls/user/dde/client.c
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/dlls/user/dde/client.c,v
retrieving revision 1.4
diff -u -u -r1.4 client.c
--- dlls/user/dde/client.c	14 Sep 2001 00:24:40 -0000	1.4
+++ dlls/user/dde/client.c	6 Jan 2002 22:03:02 -0000
@@ -46,8 +46,7 @@
 HCONVLIST WINAPI DdeConnectList(DWORD idInst, HSZ hszService, HSZ hszTopic,
 				HCONVLIST hConvList, LPCONVCONTEXT pCC)
 {
-    FIXME("(%ld,%d,%d,%d,%p): stub\n", idInst, hszService, hszTopic,
-	  hConvList, pCC);
+    FIXME("(%ld,%d,%d,%d,%p): stub\n", idInst, hszService, hszTopic, hConvList, pCC);
     return (HCONVLIST)1;
 }
 
@@ -84,7 +83,6 @@
 			LPCONVCONTEXT pCC)
 {
     HWND		hwndClient;
-    LPARAM		lParam = 0;
     WDML_INSTANCE*	pInstance;
     WDML_CONV*		pConv = NULL;
     ATOM		aSrv = 0, aTpc = 0;
@@ -168,9 +166,8 @@
 
     LeaveCriticalSection(&WDML_CritSect);
 
-    lParam = PackDDElParam(WM_DDE_INITIATE, aSrv, aTpc);
-    SendMessageA(HWND_BROADCAST, WM_DDE_INITIATE, (WPARAM)hwndClient, lParam);
-    FreeDDElParam(WM_DDE_INITIATE, lParam);
+    /* note: sent messages shall not use packing */
+    SendMessageA(HWND_BROADCAST, WM_DDE_INITIATE, (WPARAM)hwndClient, MAKELPARAM(aSrv, aTpc));
     
     EnterCriticalSection(&WDML_CritSect);
 
@@ -180,17 +177,17 @@
 	goto theEnd;
     }
     
-    TRACE("WM_DDE_INITIATE was processed\n");
     /* 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(".. but no Server window available\n");
+	ERR("Done with INITIATE, but no Server window available\n");
 	pConv = NULL;
 	goto theEnd;
     }
+    TRACE("Connected to Server window (%x)\n", pConv->hwndServer);
     pConv->wConvst = XST_CONNECTED;
 
     /* finish init of pConv */
@@ -227,7 +224,6 @@
     pConv = WDML_GetConv(hConv, FALSE);
     if (pConv != NULL && (pConv->wStatus & ST_CLIENT))
     {
-	LPARAM	lParam;
 	BOOL	ret;
 
 	/* to reestablist a connection, we have to make sure that:
@@ -251,9 +247,9 @@
 
 	    LeaveCriticalSection(&WDML_CritSect);
 
-	    lParam = PackDDElParam(WM_DDE_INITIATE, aSrv, aTpc);
-	    ret = SendMessageA(hwndServer, WM_DDE_INITIATE, (WPARAM)hwndClient, lParam);
-	    FreeDDElParam(WM_DDE_INITIATE, lParam);
+            /* note: sent messages shall not use packing */
+	    ret = SendMessageA(hwndServer, WM_DDE_INITIATE, (WPARAM)hwndClient, 
+                               MAKELPARAM(aSrv, aTpc));
 	    
 	    EnterCriticalSection(&WDML_CritSect);
 
@@ -320,7 +316,8 @@
 
     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;
@@ -366,7 +363,7 @@
 	
 	/* billx: first to see if the link is already created. */
 	pLink = WDML_FindLink(pConv->instance, (HCONV)pConv, WDML_CLIENT_SIDE, 
-			      pXAct->hszItem, pXAct->wFmt);
+			      pXAct->hszItem, TRUE, pXAct->wFmt);
 	if (pLink != NULL)	
 	{	
 	    /* we found a link, and only need to modify it in case it changes */
@@ -377,14 +374,15 @@
 	    WDML_AddLink(pConv->instance, (HCONV)pConv, WDML_CLIENT_SIDE, 
 			 pXAct->wType, pXAct->hszItem, pXAct->wFmt);
 	}
+        pXAct->hDdeData = (HDDEDATA)1;
     }
     else
     {
-	TRACE("Returning TRUE on XTYP_ADVSTART - fAck was FALSE\n");
+	TRACE("Returning FALSE on XTYP_ADVSTART - fAck was FALSE\n");
 	GlobalFree(pXAct->hMem);
+        pXAct->hDdeData = (HDDEDATA)0;
     }
 
-    pXAct->hDdeData = (HDDEDATA)1;
     return WDML_QS_HANDLED;
 }
 
@@ -448,15 +446,16 @@
 	    
     if (!ddeAck.fAck)
     {
-	TRACE("Returning TRUE on XTYP_ADVSTOP - fAck was FALSE\n");
+	TRACE("Returning FALSE on XTYP_ADVSTOP - fAck was FALSE\n");
+        pXAct->hDdeData = (HDDEDATA)0;
     }
     else
     {
 	/* billx: remove the link */
 	WDML_RemoveLink(pConv->instance, (HCONV)pConv, WDML_CLIENT_SIDE, 
 			pXAct->hszItem, pXAct->wFmt);
+        pXAct->hDdeData = (HDDEDATA)1;
     }
-    pXAct->hDdeData = (HDDEDATA)1;
     return WDML_QS_HANDLED;
 }
 
@@ -501,11 +500,12 @@
 
     if (WIN_GetFullHandle(msg->wParam) != pConv->hwndServer)
 	return WDML_QS_PASS;
-    UnpackDDElParam(WM_DDE_ACK, msg->lParam, &uiLo, &uiHi);
 
     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;
@@ -515,6 +515,7 @@
 	break;
 
     case WM_DDE_DATA:
+        UnpackDDElParam(WM_DDE_DATA, msg->lParam, &uiLo, &uiHi);
 	TRACE("Got the result (%08lx)\n", (DWORD)uiLo);
 
 	hsz = WDML_MakeHszFromAtom(pConv->instance, uiHi);
@@ -522,7 +523,6 @@
 	if (DdeCmpStringHandles(hsz, pXAct->hszItem) != 0)
 	    return WDML_QS_PASS;
 
-	/* FIXME: memory clean up ? */
 	pXAct->hDdeData = WDML_Global2DataHandle((HGLOBAL)uiLo, &wdh);
 	if (wdh.fRelease)
 	{
@@ -530,16 +530,17 @@
 	}
 	if (wdh.fAckReq)
 	{
-	    WDML_PostAck(pConv, WDML_CLIENT_SIDE, 0, FALSE, TRUE, (HSZ)uiHi, msg->lParam, 
-			 WM_DDE_DATA);
+	    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;
     }
 
@@ -669,15 +670,12 @@
 
     if (uiHi != pXAct->hMem)
     {
-	return WDML_QS_PASS;
+        return WDML_QS_PASS;
     }
 
     WDML_ExtractAck(uiLo, &ddeAck);
-    if (!ddeAck.fAck)
-    {
-	GlobalFree(pXAct->hMem);
-    }
-    pXAct->hDdeData = (HDDEDATA)1;
+    pXAct->hDdeData = (HDDEDATA)ddeAck.fAck;
+
     return WDML_QS_HANDLED;
 }
 
@@ -832,17 +830,18 @@
      *  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, wdh.cfFormat);
+    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);
+	WDML_PostAck(pConv, WDML_CLIENT_SIDE, 0, FALSE, TRUE, uiHi, msg->lParam, WM_DDE_DATA);
 	if (msg->lParam)
 	    msg->lParam = 0;
     }
@@ -853,14 +852,16 @@
 	
     hDdeDataOut = WDML_InvokeCallback(pConv->instance, XTYP_ADVDATA, pLink->uFmt, pLink->hConv, 
 				      pConv->hszTopic, pLink->hszItem, hDdeDataIn, 0, 0);
-    if (hDdeDataOut == (HDDEDATA)DDE_FACK)
-    {
-	pLink->hDdeData = hDdeDataIn;
-    }
-    if (wdh.fRelease) 
+
+    if (hDdeDataOut != (HDDEDATA)DDE_FACK || wdh.fRelease) 
     {
-	DdeFreeDataHandle(hDdeDataIn);
+        if (uiLo)
+        {
+            GlobalFree(uiLo);
+        }
     }
+
+    DdeFreeDataHandle(hDdeDataIn);
     
     WDML_DecHSZ(pConv->instance, hsz);
     if (msg->lParam)
@@ -961,10 +962,10 @@
 	{
 	    *hdd = pXAct->hDdeData;
 	}
-	WDML_FreeTransaction(pConv->instance, pXAct, FALSE); /* FIXME: should we free intermediate pmts ? */
+	WDML_FreeTransaction(pConv->instance, pXAct, TRUE);
 	break;
     case WDML_QS_PASS:
-	/* no pending transaction found, try a warm link or a termination request */
+	/* no pending transaction found, try a warm/hot link or a termination request */
 	switch (msg->message)
 	{
 	case WM_DDE_DATA:
@@ -1006,7 +1007,7 @@
 	 * single process they need to share the access to the internal data
 	 */
 	if (MsgWaitForMultipleObjects(0, NULL, FALSE, 
-				      dwTime - dwTimeout, QS_POSTMESSAGE) == WAIT_OBJECT_0)
+				      dwTimeout - dwTime, QS_POSTMESSAGE) == WAIT_OBJECT_0)
 	{
 	    BOOL	ret = FALSE;
 	    MSG		msg;
@@ -1156,7 +1157,6 @@
 	WDML_UnQueueTransaction(pConv, pXAct);
 	WDML_FreeTransaction(pConv->instance, pXAct, TRUE);
 	goto theError;
-
     }
     pXAct->dwTimeout = dwTimeout;
     /* FIXME: should set the app bits on *pdwResult */
@@ -1192,6 +1192,56 @@
     return 0;
 }
 
+/*****************************************************************
+ *            DdeAbandonTransaction (USER32.@)
+ */
+BOOL WINAPI DdeAbandonTransaction(DWORD idInst, HCONV hConv, DWORD idTransaction)
+{
+    WDML_INSTANCE*	pInstance;
+    WDML_CONV*		pConv;
+    WDML_XACT*          pXAct;
+
+    TRACE("(%08lx,%08lx,%08ld);\n", idInst, (DWORD)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
  *
@@ -1204,7 +1254,6 @@
     HSZ		hszSrv, hszTpc;
 
     if (iMsg == WM_DDE_ACK &&
-	UnpackDDElParam(WM_DDE_ACK, lParam, &uiLo, &uiHi) &&
 	/* in the initial WM_INITIATE sendmessage */
 	((pConv = WDML_GetConvFromWnd(hwnd)) == NULL || pConv->wStatus == XST_INIT1))
     {
@@ -1212,7 +1261,9 @@
 	char		buf[256];
 	WDML_INSTANCE*	pInstance;
 
-	FreeDDElParam(WM_DDE_ACK, lParam);
+        /* note: sent messages do not need packing */
+	uiLo = LOWORD(lParam);
+        uiHi = HIWORD(lParam);
 
 	/* FIXME: convlist should be handled here */
 	if (pConv)
@@ -1220,6 +1271,7 @@
 	    /* we already have started the conv with a server, drop other replies */
 	    GlobalDeleteAtom(uiLo);
 	    GlobalDeleteAtom(uiHi);
+            PostMessageA((HWND)wParam, WM_DDE_TERMINATE, (WPARAM)hwnd, 0);
 	    return 0;
 	}
 
@@ -1228,8 +1280,7 @@
 	hszSrv = WDML_MakeHszFromAtom(pInstance, uiLo);
 	hszTpc = WDML_MakeHszFromAtom(pInstance, uiHi);
 
-	pConv = WDML_AddConv(pInstance, WDML_CLIENT_SIDE, hszSrv, hszTpc, 
-			     hwnd, (HWND)wParam);
+	pConv = WDML_AddConv(pInstance, WDML_CLIENT_SIDE, hszSrv, hszTpc, hwnd, (HWND)wParam);
 
 	SetWindowLongA(hwnd, GWL_WDML_CONVERSATION, (DWORD)pConv);
 	pConv->wStatus |= ST_CONNECTED;
@@ -1281,15 +1332,6 @@
 }
 
 /*****************************************************************
- *            DdeAbandonTransaction (USER32.@)
- */
-BOOL WINAPI DdeAbandonTransaction(DWORD idInst, HCONV hConv, DWORD idTransaction)
-{
-    FIXME("empty stub\n");
-    return TRUE;
-}
-
-/*****************************************************************
  *            DdeDisconnect   (USER32.@)
  */
 BOOL WINAPI DdeDisconnect(HCONV hConv)
@@ -1308,33 +1350,33 @@
     }
     
     EnterCriticalSection(&WDML_CritSect);
-    pConv = WDML_GetConv(hConv, FALSE);
+    pConv = WDML_GetConv(hConv, TRUE);
     if (pConv != NULL)
     {
-	if (pConv->wStatus & ST_CONNECTED)
-	{
-	    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);
-		    WDML_SyncWaitTransactionReply(hConv, 10000, pXAct);
-		    for (i = 0; i < count; i++)
-			EnterCriticalSection(&WDML_CritSect);
-		    ret = TRUE;
-		}
-		else
-		{
-		    FIXME("Not implemented yet for a server side conversation\n");
-		}
-	    }
-	}
-	/* still have to destroy data assosiated with conversation */
-	WDML_RemoveConv(pConv, WDML_CLIENT_SIDE);
+        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 (PostMessageA(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);
 
Index: dlls/user/dde/misc.c
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/dlls/user/dde/misc.c,v
retrieving revision 1.6
diff -u -u -r1.6 misc.c
--- dlls/user/dde/misc.c	14 Sep 2001 00:24:40 -0000	1.6
+++ dlls/user/dde/misc.c	6 Jan 2002 22:02:40 -0000
@@ -86,7 +86,7 @@
      params = GlobalLock(hMem);
      if (params == NULL)
      {
-	  ERR("GlobalLock failed\n");
+	  ERR("GlobalLock failed (%x)\n", hMem);
 	  return 0;
      }
      
@@ -130,7 +130,7 @@
      params = GlobalLock(hMem);
      if (params == NULL)
      {
-	  ERR("GlobalLock failed\n");
+	  ERR("GlobalLock failed (%x)\n", hMem);
 	  return FALSE;
      }
      
@@ -383,9 +383,7 @@
     
     if (!pInstance->clientOnly)
     {
-	
 	/* Check for other way of setting Client-only !! */
-	
 	pInstance->clientOnly = 
 	    (pInstance->CBFflags & CBF_FAIL_ALLSVRXACTIONS) == CBF_FAIL_ALLSVRXACTIONS;
     }
@@ -622,7 +620,6 @@
     /*  Stage one - check if we have a handle for this instance
      */
     WDML_INSTANCE*		pInstance;
-    WDML_INSTANCE*		reference_inst;
     WDML_CONV*			pConv;
     WDML_CONV*			pConvNext;
 
@@ -665,20 +662,16 @@
     
     if (WDML_InstanceList == pInstance)
     {
-	/* special case - the first/only entry
-	 */
+	/* special case - the first/only entry */
 	WDML_InstanceList = pInstance->next;
     }
     else
     {
-	/* general case
-	 */
-	reference_inst = WDML_InstanceList;
-	while (reference_inst->next != pInstance)
-	{
-	    reference_inst = pInstance->next;
-	}
-	reference_inst->next = pInstance->next;
+	/* general case, remove entry */
+	WDML_INSTANCE*	inst;
+	
+	for (inst = WDML_InstanceList; inst->next != pInstance; inst = inst->next);
+	inst->next = pInstance->next;
     }
     /* leave crit sect and release the heap entry
      */
@@ -849,7 +842,7 @@
 
     if (GetAtomNameW((ATOM)hsz, nameBuffer, MAX_BUFFER_LEN))
 	return GlobalAddAtomW(nameBuffer);
-    WARN("HSZ 0x%xnot found\n", hsz);
+    WARN("HSZ 0x%x not found\n", hsz);
     return 0;
 }
 
@@ -864,8 +857,15 @@
 {
     WCHAR nameBuffer[MAX_BUFFER_LEN];
 
-    GlobalGetAtomNameW(atom, nameBuffer, MAX_BUFFER_LEN);
-    return DdeCreateStringHandleW(pInstance->instanceID, nameBuffer, CP_WINUNICODE);
+    if (!atom) return (HSZ)0;
+
+    if (GlobalGetAtomNameW(atom, nameBuffer, MAX_BUFFER_LEN))
+    {
+	TRACE("%x => %s\n", atom, debugstr_w(nameBuffer));
+	return DdeCreateStringHandleW(pInstance->instanceID, nameBuffer, CP_WINUNICODE);
+    }
+    WARN("ATOM 0x%x not found\n", atom);
+    return 0;
 }
 
 /******************************************************************
@@ -914,12 +914,12 @@
 		    pPrev->next = pCurrent->next;
 		}
 		HeapFree(GetProcessHeap(), 0, pCurrent);
-		DeleteAtom(hsz);
+		DeleteAtom((ATOM)hsz);
 	    }
 	    return TRUE;
 	}
     }
-    WARN("HSZ 0x%xnot found\n", hsz);
+    WARN("HSZ 0x%x not found\n", hsz);
    
     return FALSE;
 }
@@ -989,10 +989,10 @@
     switch (codepage)
     {
     case CP_WINANSI:
-	ret = GetAtomNameA(hsz, ptr, cchMax);
+	ret = GetAtomNameA((ATOM)hsz, ptr, cchMax);
 	break;
     case CP_WINUNICODE:
-	ret = GetAtomNameW(hsz, ptr, cchMax);
+	ret = GetAtomNameW((ATOM)hsz, ptr, cchMax);
     default:
 	ERR("Unknown code page %d\n", codepage);
 	ret = 0;
@@ -1035,8 +1035,7 @@
     DWORD		ret = 0;
     WDML_INSTANCE*	pInstance;
 
-    TRACE("(%ld, 0x%x, %p, %ld, %d)\n",
-	  idInst, hsz, psz, cchMax, iCodePage);
+    TRACE("(%ld, 0x%x, %p, %ld, %d)\n", idInst, hsz, psz, cchMax, iCodePage);
     
     EnterCriticalSection(&WDML_CritSect);
     
@@ -1066,11 +1065,11 @@
     switch (codepage)
     {
     case CP_WINANSI:
-	hsz = AddAtomA(ptr);
+	hsz = (HSZ)AddAtomA(ptr);
 	TRACE("added atom %s with HSZ 0x%x, \n", debugstr_a(ptr), hsz);
 	break;
     case CP_WINUNICODE:
-	hsz = AddAtomW(ptr);
+	hsz = (HSZ)AddAtomW(ptr);
 	TRACE("added atom %s with HSZ 0x%x, \n", debugstr_w(ptr), hsz);
 	break;
     default:
@@ -1208,8 +1207,8 @@
     int		ret = 0;
     int		ret1, ret2;
     
-    ret1 = GetAtomNameW(hsz1, psz1, MAX_BUFFER_LEN);
-    ret2 = GetAtomNameW(hsz2, psz2, MAX_BUFFER_LEN);
+    ret1 = GetAtomNameW((ATOM)hsz1, psz1, MAX_BUFFER_LEN);
+    ret2 = GetAtomNameW((ATOM)hsz2, psz2, MAX_BUFFER_LEN);
 
     TRACE("(%x<%s> %x<%s>);\n", hsz1, debugstr_w(psz1), hsz2, debugstr_w(psz2));
     
@@ -1260,22 +1259,23 @@
 /*****************************************************************
  *            DdeCreateDataHandle (USER32.@)
  */
-HDDEDATA WINAPI DdeCreateDataHandle(DWORD idInst, LPBYTE pSrc, DWORD cb, 
-				    DWORD cbOff, HSZ hszItem, UINT wFmt, 
-				    UINT afCmd)
-{
-    /*
-      For now, we ignore idInst, hszItem, wFmt, and afCmd.
-      The purpose of these arguments still need to be investigated.
-    */
+HDDEDATA WINAPI DdeCreateDataHandle(DWORD idInst, LPBYTE pSrc, DWORD cb, DWORD cbOff, 
+                                    HSZ hszItem, UINT wFmt, UINT afCmd)
+{
+    /* For now, we ignore idInst, hszItem.
+     * The purpose of these arguments still need to be investigated.
+     */
     
     HGLOBAL     		hMem;
     LPBYTE      		pByte;
     DDE_DATAHANDLE_HEAD*	pDdh;
     
-    TRACE("(%ld,%p,%ld,%ld,0x%lx,%d,%d): semi-stub\n",
-	  idInst,pSrc,cb,cbOff,(DWORD)hszItem,wFmt,afCmd);
+    TRACE("(%ld,%p,%ld,%ld,0x%lx,%d,%d)\n",
+	  idInst, pSrc, cb, cbOff, (DWORD)hszItem, wFmt, afCmd);
     
+    if (afCmd != 0 && afCmd != HDATA_APPOWNED)
+        return 0;
+
     /* we use the first 4 bytes to store the size */
     if (!(hMem = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, cb + sizeof(DDE_DATAHANDLE_HEAD))))
     {
@@ -1284,8 +1284,15 @@
     }   
     
     pDdh = (DDE_DATAHANDLE_HEAD*)GlobalLock(hMem);
+    if (!pDdh)
+    {
+        GlobalFree(hMem);
+        return 0;
+    }
+
     pDdh->cfFormat = wFmt;
-    
+    pDdh->bAppOwned = (afCmd == HDATA_APPOWNED);
+
     pByte = (LPBYTE)(pDdh + 1);
     if (pSrc)
     {
@@ -1420,6 +1427,25 @@
     return GlobalFree((HGLOBAL)hData) == 0;
 }
 
+/******************************************************************
+ *		WDML_IsAppOwned
+ *
+ *
+ */
+BOOL WDML_IsAppOwned(HDDEDATA hData)
+{
+    DDE_DATAHANDLE_HEAD*	pDdh;
+    BOOL                        ret = FALSE;
+
+    pDdh = (DDE_DATAHANDLE_HEAD*)GlobalLock((HGLOBAL)hData);
+    if (pDdh != NULL)
+    {
+        ret = pDdh->bAppOwned;
+        GlobalUnlock((HGLOBAL)hData);
+    }
+    return ret;
+}
+
 /* ================================================================
  *
  *                  Global <=> Data handle management
@@ -1437,17 +1463,51 @@
 {
     DDEDATA*    pDd;
     HDDEDATA	ret = 0;
+    DWORD       size;
 
     if (hMem)
     {
         pDd = GlobalLock(hMem);
+        size = GlobalSize(hMem) - sizeof(WINE_DDEHEAD);
         if (pDd)
         {
 	    if (p) memcpy(p, pDd, sizeof(WINE_DDEHEAD));
-            ret = DdeCreateDataHandle(0, pDd->Value,
-				      GlobalSize(hMem) - sizeof(WINE_DDEHEAD),
-				      0, 0, pDd->cfFormat, 0);
-	    GlobalUnlock(hMem);
+            switch (pDd->cfFormat)
+            {
+            default:
+                FIXME("Unsupported format (%d) for data... assuming raw information\n", 
+                      pDd->cfFormat);
+                /* fall thru */
+            case 0:
+            case CF_TEXT:
+                ret = DdeCreateDataHandle(0, pDd->Value, size, 0, 0, pDd->cfFormat, 0);
+                break;
+            case CF_BITMAP:
+                if (size >= sizeof(BITMAP))
+                {
+                    BITMAP*     bmp = (BITMAP*)pDd->Value;
+                    int         count = bmp->bmWidthBytes * bmp->bmHeight * bmp->bmPlanes;
+                    if (size >= sizeof(BITMAP) + count)
+                    {
+                        HBITMAP hbmp;
+
+                        if ((hbmp = CreateBitmap(bmp->bmWidth, bmp->bmHeight, 
+                                                 bmp->bmPlanes, bmp->bmBitsPixel,
+                                                 pDd->Value + sizeof(BITMAP))))
+                        {
+                            ret = DdeCreateDataHandle(0, (LPBYTE)&hbmp, sizeof(hbmp), 
+                                                      0, 0, CF_BITMAP, 0);
+                        }
+                        else ERR("Can't create bmp\n");
+                    }
+                    else
+                    {
+                        ERR("Wrong count: %lu / %d\n", size, sizeof(BITMAP) + count);
+                    }
+                } else ERR("No bitmap header\n");
+                break;
+            }
+            GlobalUnlock(hMem);
         }
     }
     return ret;
@@ -1465,28 +1525,56 @@
     DWORD                       dwSize;
     HGLOBAL                     hMem = 0;
  
-    dwSize = GlobalSize(hDdeData) - sizeof(DDE_DATAHANDLE_HEAD);
-    pDdh = (DDE_DATAHANDLE_HEAD*)GlobalLock(hDdeData);
+    dwSize = GlobalSize((HGLOBAL)hDdeData) - sizeof(DDE_DATAHANDLE_HEAD);
+    pDdh = (DDE_DATAHANDLE_HEAD*)GlobalLock((HGLOBAL)hDdeData);
     if (dwSize && pDdh)
     {
-        hMem = GlobalAlloc(sizeof(WINE_DDEHEAD) + dwSize, GMEM_MOVEABLE | GMEM_DDESHARE);
-        if (hMem)
-        {
-            WINE_DDEHEAD*    wdh;
+        WINE_DDEHEAD*    wdh = NULL;
  
-            wdh = GlobalLock(hMem);
-            if (wdh)
+        switch (pDdh->cfFormat)
+        {
+        default:
+            FIXME("Unsupported format (%d) for data... passing raw information\n", pDdh->cfFormat);
+            /* fall thru */
+        case 0:
+        case CF_TEXT:
+            hMem = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, sizeof(WINE_DDEHEAD) + dwSize);
+            if (hMem && (wdh = GlobalLock(hMem))) 
             {
-                wdh->fResponse = fResponse;
-                wdh->fRelease = fRelease;
-		wdh->fDeferUpd = fDeferUpd;
-                wdh->fAckReq = fAckReq;
-                wdh->cfFormat = pDdh->cfFormat;
                 memcpy(wdh + 1, pDdh + 1, dwSize);
-                GlobalUnlock(hMem);
             }
+            break;
+        case CF_BITMAP:
+            if (dwSize >= sizeof(HBITMAP))
+            {
+                BITMAP  bmp;
+                DWORD   count;
+                HBITMAP hbmp = *(HBITMAP*)(pDdh + 1);
+
+                if (GetObjectA(hbmp, sizeof(bmp), &bmp))
+                {
+                    count = bmp.bmWidthBytes * bmp.bmHeight;
+                    hMem = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, 
+                                       sizeof(WINE_DDEHEAD) + sizeof(bmp) + count);
+                    if (hMem && (wdh = GlobalLock(hMem))) 
+                    {
+                        memcpy(wdh + 1, &bmp, sizeof(bmp));
+                        GetBitmapBits(hbmp, count, ((char*)(wdh + 1)) + sizeof(bmp));
+                    }
+                }
+            }
+            break;
         }
-        GlobalUnlock(hDdeData);
+        if (wdh)
+        {
+            wdh->fResponse = fResponse;
+            wdh->fRelease = fRelease;
+            wdh->fDeferUpd = fDeferUpd;
+            wdh->fAckReq = fAckReq;
+            wdh->cfFormat = pDdh->cfFormat;
+            GlobalUnlock(hMem);
+        }
+        GlobalUnlock((HGLOBAL)hDdeData);
     }
  
     return hMem;
@@ -1779,8 +1867,8 @@
  *
  *
  */
-LPARAM		WDML_PostAck(WDML_CONV* pConv, WDML_SIDE side, WORD appRetCode, 
-			     BOOL fBusy, BOOL fAck, ATOM atom, LPARAM lParam, UINT oldMsg)
+BOOL		WDML_PostAck(WDML_CONV* pConv, WDML_SIDE side, WORD appRetCode, 
+			     BOOL fBusy, BOOL fAck, UINT pmt, LPARAM lParam, UINT oldMsg)
 {
     DDEACK	ddeAck;
     HWND	from, to;
@@ -1803,16 +1891,15 @@
 
     TRACE("Posting a %s ack\n", ddeAck.fAck ? "positive" : "negative");
 		    
-    if (lParam) {
-	PostMessageA(to, WM_DDE_ACK, (WPARAM)from, 
-		     ReuseDDElParam(lParam, oldMsg, WM_DDE_ACK, *(WORD*)&ddeAck, atom));
+    lParam = (lParam) ? ReuseDDElParam(lParam, oldMsg, WM_DDE_ACK, *(WORD*)&ddeAck, pmt) :
+        PackDDElParam(WM_DDE_ACK, *(WORD*)&ddeAck, pmt);
+    if (!PostMessageA(to, WM_DDE_ACK, (WPARAM)from, lParam))
+    {
+	pConv->wStatus &= ~ST_CONNECTED;
+        FreeDDElParam(WM_DDE_ACK, lParam);
+        return FALSE;
     }
-    else 
-    {
-	lParam = PackDDElParam(WM_DDE_ACK, *(WORD*)&ddeAck, atom);
-	PostMessageA(to, WM_DDE_ACK, (WPARAM)from, lParam);
-    }
-    return lParam;
+    return TRUE;
 }
 
 /*****************************************************************
@@ -1949,9 +2036,9 @@
     {
 	ret = 0;
     }
-    else if (hConv & 1)
+    else if ((DWORD)hConv & 1)
     {
-	pConv = WDML_GetConv(hConv & ~1, FALSE);
+	pConv = WDML_GetConv((DWORD)hConv & ~1, FALSE);
 	if (pConv != NULL)
 	{
 	    FIXME("Request on remote conversation information is not implemented yet\n");
@@ -1960,7 +2047,7 @@
     }
     LeaveCriticalSection(&WDML_CritSect);
     if (ret != 0)
-	memcpy(lpConvInfo, &ci, min(lpConvInfo->cb, sizeof(ci)));
+	memcpy(lpConvInfo, &ci, min((size_t)lpConvInfo->cb, sizeof(ci)));
     return ret;
 }
 
@@ -1991,7 +2078,6 @@
     pLink->transactionType = wType;
     WDML_IncHSZ(pInstance, pLink->hszItem = hszItem);
     pLink->uFmt = wFmt;
-    pLink->hDdeData = 0;
     pLink->next = pInstance->links[side];
     pInstance->links[side] = pLink;
 }
@@ -2024,11 +2110,6 @@
 		pPrev->next = pCurrent->next;
 	    }
 	    
-	    if (pCurrent->hDdeData)
-	    {
-		DdeFreeDataHandle(pCurrent->hDdeData);
-	    }
-
 	    WDML_DecHSZ(pInstance, pCurrent->hszItem);
 	    HeapFree(GetProcessHeap(), 0, pCurrent);
 	    break;
@@ -2071,10 +2152,6 @@
 		pNext = pCurrent->next;
 	    }
 	    
-	    if (pCurrent->hDdeData)
-	    {
-		DdeFreeDataHandle(pCurrent->hDdeData);
-	    }
 	    WDML_DecHSZ(pInstance, pCurrent->hszItem);
 	    
 	    HeapFree(GetProcessHeap(), 0, pCurrent);
@@ -2099,7 +2176,7 @@
  *
  */
 WDML_LINK* 	WDML_FindLink(WDML_INSTANCE* pInstance, HCONV hConv, WDML_SIDE side, 
-			      HSZ hszItem, UINT uFmt)
+			      HSZ hszItem, BOOL use_fmt, UINT uFmt)
 {
     WDML_LINK*	pCurrent = NULL;
     
@@ -2109,7 +2186,7 @@
 	
 	if (pCurrent->hConv == hConv &&
 	    DdeCmpStringHandles(pCurrent->hszItem, hszItem) == 0 &&
-	    pCurrent->uFmt == uFmt)
+	    (!use_fmt || pCurrent->uFmt == uFmt))
 	{
 	    break;
 	}
@@ -2150,7 +2227,7 @@
     pXAct->next = NULL;
     pXAct->wType = 0;
     pXAct->wFmt = wFmt;
-    WDML_IncHSZ(pInstance, pXAct->hszItem = hszItem);
+    if ((pXAct->hszItem = hszItem)) WDML_IncHSZ(pInstance, pXAct->hszItem);
     pXAct->atom = 0;
     pXAct->hMem = 0;
     pXAct->lParam = 0;
@@ -2199,10 +2276,12 @@
  */
 void	WDML_FreeTransaction(WDML_INSTANCE* pInstance, WDML_XACT* pXAct, BOOL doFreePmt)
 {
-    /* free pmt(s) in pXAct too */
-    if (doFreePmt && pXAct->hMem)
+    /* free pmt(s) in pXAct too. check against one for not deleting TRUE return values */
+    if (doFreePmt && (DWORD)pXAct->hMem > 1)
+    {
 	GlobalFree(pXAct->hMem);
-    WDML_DecHSZ(pInstance, pXAct->hszItem);
+    }
+    if (pXAct->hszItem) WDML_DecHSZ(pInstance, pXAct->hszItem);
 
     HeapFree(GetProcessHeap(), 0, pXAct);
 }
Index: dlls/user/dde/server.c
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/dlls/user/dde/server.c,v
retrieving revision 1.5
diff -u -u -r1.5 server.c
--- dlls/user/dde/server.c	14 Sep 2001 00:24:40 -0000	1.5
+++ dlls/user/dde/server.c	6 Jan 2002 22:02:26 -0000
@@ -47,7 +47,8 @@
 {
     WDML_INSTANCE*	pInstance = NULL;
     WDML_LINK*		pLink = NULL;
-    HDDEDATA		hDdeData = 0, hItemData = 0;
+    HDDEDATA		hDdeData = 0;
+    HGLOBAL             hItemData = 0;
     WDML_CONV*		pConv = NULL;
     ATOM		atom = 0;
     UINT		count;
@@ -88,7 +89,7 @@
 	    hDdeData = WDML_InvokeCallback(pInstance, XTYP_ADVREQ, pLink->uFmt, pLink->hConv,
 					   hszTopic, hszItem, 0, count--, 0);
 		
-	    if (hDdeData == CBR_BLOCK)
+	    if (hDdeData == (HDDEDATA)CBR_BLOCK)
 	    {
 		/* MS doc is not consistent here */
 		FIXME("CBR_BLOCK returned for ADVREQ\n");
@@ -112,8 +113,7 @@
 		
 		if (pConv == NULL)
 		{
-		    /* FIXME: wrong if app owned... */
-		    DdeFreeDataHandle(hDdeData);
+		    if (!WDML_IsAppOwned(hDdeData))  DdeFreeDataHandle(hDdeData);
 		    goto theError;
 		}
 		
@@ -121,11 +121,12 @@
 				  PackDDElParam(WM_DDE_DATA, (UINT)hItemData, atom)))
 		{
 		    ERR("post message failed\n");
-		    /* FIXME: wrong if app owned... */
-		    DdeFreeDataHandle(hDdeData);
+                    pConv->wStatus &= ~ST_CONNECTED;
+		    if (!WDML_IsAppOwned(hDdeData))  DdeFreeDataHandle(hDdeData);
 		    GlobalFree(hItemData);
 		    goto theError;
-		}		    
+		}	
+                if (!WDML_IsAppOwned(hDdeData))  DdeFreeDataHandle(hDdeData);
 	    }
 	}
     }
@@ -352,10 +353,9 @@
 	SetWindowLongA(hwndServerConv, GWL_WDML_CONVERSATION, (DWORD)pConv);
 
 	/* this should be the only place using SendMessage for WM_DDE_ACK */
+        /* note: sent messages shall not use packing */
 	SendMessageA(hwndClient, WM_DDE_ACK, (WPARAM)hwndServerConv,
-		     PackDDElParam(WM_DDE_ACK, 
-				   WDML_MakeAtomFromHsz(hszApp), 
-				   WDML_MakeAtomFromHsz(hszTopic)));
+		     MAKELPARAM(WDML_MakeAtomFromHsz(hszApp), WDML_MakeAtomFromHsz(hszTopic)));
 	/* we assume we're connected since we've sent an answer... 
 	 * I'm not sure what we can do... it doesn't look like the return value
 	 * of SendMessage is used... sigh...
@@ -457,7 +457,7 @@
 		hDdeData = WDML_InvokeCallback(pInstance, XTYP_WILDCONNECT,
 					       0, 0, hszTop, hszApp, 0, (DWORD)pcc, self);
 
-		if (hDdeData == CBR_BLOCK)
+		if (hDdeData == (HDDEDATA)CBR_BLOCK)
 		{
 		    /* MS doc is not consistent here */
 		    FIXME("CBR_BLOCK returned for WILDCONNECT\n");
@@ -478,13 +478,10 @@
 			}	
 			DdeUnaccessData(hDdeData);
 		    }
+                    if (!WDML_IsAppOwned(hDdeData)) DdeFreeDataHandle(hDdeData);
 		}
 	    }
 	}
-	/*
-	  billx: make a conv and add it to the server list - 
-	  this can be delayed when link is created for the conv. NO NEED !!!
-	*/
 	
 	return 0;
 	
@@ -548,11 +545,11 @@
 				       pConv->hszTopic, pXAct->hszItem, 0, 0, 0);
     }
 
-    switch (hDdeData)
+    switch ((DWORD)hDdeData)
     {
     case 0:
-	WDML_PostAck(pConv, WDML_SERVER_SIDE, 0, FALSE, FALSE, pXAct->hszItem, 
-		     pXAct->lParam, WM_DDE_REQUEST);
+	WDML_PostAck(pConv, WDML_SERVER_SIDE, 0, FALSE, FALSE, pXAct->atom, 
+                     pXAct->lParam, WM_DDE_REQUEST);
 	break;
     case CBR_BLOCK:
 	ret = WDML_QS_BLOCK;
@@ -587,7 +584,8 @@
     /* XTYP_ADVSTART transaction: 
        establish link and save link info to InstanceInfoTable */
 	
-    UnpackDDElParam(WM_DDE_ADVISE, lParam, &uiLo, &uiHi);
+    if (!UnpackDDElParam(WM_DDE_ADVISE, lParam, &uiLo, &uiHi))
+	return NULL;
 	
     pXAct = WDML_AllocTransaction(pConv->instance, WM_DDE_ADVISE, 
 				  0, WDML_MakeHszFromAtom(pConv->instance, uiHi));
@@ -633,7 +631,7 @@
 	
 	/* billx: first to see if the link is already created. */
 	pLink = WDML_FindLink(pConv->instance, (HCONV)pConv, WDML_SERVER_SIDE, 
-			      pXAct->hszItem, pDdeAdvise->cfFormat);
+			      pXAct->hszItem, TRUE, pDdeAdvise->cfFormat);
 
 	if (pLink != NULL)
 	{
@@ -643,7 +641,6 @@
 	else
 	{
 	    TRACE("Adding Link with hConv=0x%lx\n", (DWORD)pConv);
-	    
 	    WDML_AddLink(pConv->instance, (HCONV)pConv, WDML_SERVER_SIDE, 
 			 uType, pXAct->hszItem, pDdeAdvise->cfFormat);
 	}
@@ -656,7 +653,10 @@
 	
     GlobalUnlock(pXAct->hMem);
     if (fAck)
+    {
 	GlobalFree(pXAct->hMem);
+    }
+    pXAct->hMem = 0;
 
     WDML_PostAck(pConv, WDML_SERVER_SIDE, 0, FALSE, fAck, pXAct->atom, pXAct->lParam, WM_DDE_ADVISE);
 
@@ -699,7 +699,7 @@
     }
 
     pLink = WDML_FindLink(pConv->instance, (HCONV)pConv, WDML_SERVER_SIDE, 
-			  pXAct->hszItem, pXAct->wFmt);
+			  pXAct->hszItem, TRUE, pXAct->wFmt);
     if (pLink == NULL)
     {
 	ERR("Couln'd find link for %08lx, dropping request\n", (DWORD)pXAct->hszItem);
@@ -718,7 +718,7 @@
 	
     /* send back ack */
     WDML_PostAck(pConv, WDML_SERVER_SIDE, 0, FALSE, TRUE, pXAct->atom, 
-		 pXAct->lParam, WM_DDE_UNADVISE);
+                 pXAct->lParam, WM_DDE_UNADVISE);
 	
     WDML_DecHSZ(pConv->instance, pXAct->hszItem);
 
@@ -856,8 +856,9 @@
     GlobalUnlock(pXAct->hMem);
     
     if (!fAck)
+    {
 	GlobalFree(pXAct->hMem);
-   
+    }
     WDML_PostAck(pConv, WDML_SERVER_SIDE, 0, fBusy, fAck, pXAct->atom, pXAct->lParam, WM_DDE_POKE);
 
     WDML_DecHSZ(pConv->instance, pXAct->hszItem);
@@ -893,7 +894,6 @@
 	WDML_InvokeCallback(pConv->instance, XTYP_DISCONNECT, 0, (HCONV)pConv, 0, 0, 
 			    0, 0, (pConv->wStatus & ST_ISSELF) ? 1 : 0);
     }
-
     PostMessageA(pConv->hwndClient, WM_DDE_TERMINATE, (WPARAM)pConv->hwndServer, 0);
     WDML_RemoveConv(pConv, WDML_SERVER_SIDE);
 	


More information about the wine-patches mailing list