blob: e047724d564ecc0b726a88d369666b60d6d1419d [file] [log] [blame]
Eric Pouech6a03ac02001-06-22 23:02:48 +00001/*
2 * DDEML library
3 *
4 * Copyright 1997 Alexandre Julliard
5 * Copyright 1997 Len White
6 * Copyright 1999 Keith Matthews
7 * Copyright 2000 Corel
8 * Copyright 2001 Eric Pouech
Dmitry Timoshkovca7b25c2005-02-14 11:53:15 +00009 * Copyright 2003, 2004, 2005 Dmitry Timoshkov
Alexandre Julliard0799c1a2002-03-09 23:29:33 +000010 *
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
15 *
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, write to the Free Software
Jonathan Ernst360a3f92006-05-18 14:49:52 +020023 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
Eric Pouech6a03ac02001-06-22 23:02:48 +000024 */
25
Alexandre Julliarde37c6e12003-09-05 23:08:26 +000026#include <stdarg.h>
Eric Pouech6a03ac02001-06-22 23:02:48 +000027#include <string.h>
Eric Pouech6a03ac02001-06-22 23:02:48 +000028#include "windef.h"
Alexandre Julliarde37c6e12003-09-05 23:08:26 +000029#include "winbase.h"
Eric Pouech6a03ac02001-06-22 23:02:48 +000030#include "wingdi.h"
31#include "winuser.h"
Eric Pouech6a03ac02001-06-22 23:02:48 +000032#include "dde.h"
33#include "ddeml.h"
Alexandre Julliardf44bbb82001-09-14 00:24:39 +000034#include "win.h"
Alexandre Julliard0799c1a2002-03-09 23:29:33 +000035#include "wine/debug.h"
Alexandre Julliard075f98e2005-06-09 10:21:31 +000036#include "dde_private.h"
Eric Pouech6a03ac02001-06-22 23:02:48 +000037
Alexandre Julliard0799c1a2002-03-09 23:29:33 +000038WINE_DEFAULT_DEBUG_CHANNEL(ddeml);
Eric Pouech6a03ac02001-06-22 23:02:48 +000039
Dmitry Timoshkovca7b25c2005-02-14 11:53:15 +000040static const WCHAR szServerNameClass[] = {'W','i','n','e','D','d','e','S','e','r','v','e','r','N','a','m','e',0};
Dmitry Timoshkov87458a52005-07-08 11:33:09 +000041const char WDML_szServerConvClassA[] = "WineDdeServerConvA";
42const WCHAR WDML_szServerConvClassW[] = {'W','i','n','e','D','d','e','S','e','r','v','e','r','C','o','n','v','W',0};
Eric Pouech6a03ac02001-06-22 23:02:48 +000043
44static LRESULT CALLBACK WDML_ServerNameProc(HWND, UINT, WPARAM, LPARAM);
45static LRESULT CALLBACK WDML_ServerConvProc(HWND, UINT, WPARAM, LPARAM);
46
47/******************************************************************************
48 * DdePostAdvise [USER32.@] Send transaction to DDE callback function.
49 *
Eric Pouech78a41342001-08-09 22:07:22 +000050 * PARAMS
51 * idInst [I] Instance identifier
52 * hszTopic [I] Handle to topic name string
53 * hszItem [I] Handle to item name string
54 *
Eric Pouech6a03ac02001-06-22 23:02:48 +000055 * RETURNS
56 * Success: TRUE
57 * Failure: FALSE
58 */
Eric Pouech78a41342001-08-09 22:07:22 +000059BOOL WINAPI DdePostAdvise(DWORD idInst, HSZ hszTopic, HSZ hszItem)
Eric Pouech6a03ac02001-06-22 23:02:48 +000060{
Eric Pouech78a41342001-08-09 22:07:22 +000061 WDML_INSTANCE* pInstance = NULL;
Eric Pouech6a03ac02001-06-22 23:02:48 +000062 WDML_LINK* pLink = NULL;
Eric Pouech01ff6892002-01-18 19:30:15 +000063 HDDEDATA hDdeData = 0;
64 HGLOBAL hItemData = 0;
Eric Pouech6a03ac02001-06-22 23:02:48 +000065 WDML_CONV* pConv = NULL;
Eric Pouech78a41342001-08-09 22:07:22 +000066 ATOM atom = 0;
67 UINT count;
68
Michael Stefaniuc3c60ce82006-09-30 00:25:15 +020069 TRACE("(%d,%p,%p)\n", idInst, hszTopic, hszItem);
Vincent Béron9a624912002-05-31 23:06:46 +000070
Eric Pouech78a41342001-08-09 22:07:22 +000071 pInstance = WDML_GetInstance(idInst);
Vincent Béron9a624912002-05-31 23:06:46 +000072
Eric Pouech78a41342001-08-09 22:07:22 +000073 if (pInstance == NULL || pInstance->links == NULL)
Dmitry Timoshkova3722bf2006-11-15 21:22:35 +080074 return FALSE;
Vincent Béron9a624912002-05-31 23:06:46 +000075
Eric Pouech78a41342001-08-09 22:07:22 +000076 atom = WDML_MakeAtomFromHsz(hszItem);
Dmitry Timoshkova3722bf2006-11-15 21:22:35 +080077 if (!atom) return FALSE;
Eric Pouech78a41342001-08-09 22:07:22 +000078
79 /* first compute the number of links which will trigger a message */
80 count = 0;
81 for (pLink = pInstance->links[WDML_SERVER_SIDE]; pLink != NULL; pLink = pLink->next)
Eric Pouech6a03ac02001-06-22 23:02:48 +000082 {
83 if (DdeCmpStringHandles(hszItem, pLink->hszItem) == 0)
84 {
Eric Pouech78a41342001-08-09 22:07:22 +000085 count++;
86 }
87 }
88 if (count >= CADV_LATEACK)
89 {
90 FIXME("too high value for count\n");
91 count &= 0xFFFF;
92 }
93
94 for (pLink = pInstance->links[WDML_SERVER_SIDE]; pLink != NULL; pLink = pLink->next)
95 {
96 if (DdeCmpStringHandles(hszItem, pLink->hszItem) == 0)
97 {
98 hDdeData = WDML_InvokeCallback(pInstance, XTYP_ADVREQ, pLink->uFmt, pLink->hConv,
Dmitry Timoshkov3e6b5e52003-06-04 20:16:17 +000099 hszTopic, hszItem, 0, --count, 0);
Vincent Béron9a624912002-05-31 23:06:46 +0000100
Eric Pouech01ff6892002-01-18 19:30:15 +0000101 if (hDdeData == (HDDEDATA)CBR_BLOCK)
Eric Pouech6a03ac02001-06-22 23:02:48 +0000102 {
Eric Pouech78a41342001-08-09 22:07:22 +0000103 /* MS doc is not consistent here */
104 FIXME("CBR_BLOCK returned for ADVREQ\n");
105 continue;
Eric Pouech6a03ac02001-06-22 23:02:48 +0000106 }
Eric Pouech6a03ac02001-06-22 23:02:48 +0000107 if (hDdeData)
108 {
109 if (pLink->transactionType & XTYPF_NODATA)
110 {
111 TRACE("no data\n");
112 hItemData = 0;
113 }
114 else
115 {
116 TRACE("with data\n");
Vincent Béron9a624912002-05-31 23:06:46 +0000117
Eric Pouech6a03ac02001-06-22 23:02:48 +0000118 hItemData = WDML_DataHandle2Global(hDdeData, FALSE, FALSE, FALSE, FALSE);
119 }
Vincent Béron9a624912002-05-31 23:06:46 +0000120
Eric Pouech78a41342001-08-09 22:07:22 +0000121 pConv = WDML_GetConv(pLink->hConv, TRUE);
Vincent Béron9a624912002-05-31 23:06:46 +0000122
Eric Pouech78a41342001-08-09 22:07:22 +0000123 if (pConv == NULL)
124 {
Eric Pouech01ff6892002-01-18 19:30:15 +0000125 if (!WDML_IsAppOwned(hDdeData)) DdeFreeDataHandle(hDdeData);
Eric Pouech78a41342001-08-09 22:07:22 +0000126 goto theError;
127 }
Vincent Béron9a624912002-05-31 23:06:46 +0000128
Dmitry Timoshkovca7b25c2005-02-14 11:53:15 +0000129 if (!PostMessageW(pConv->hwndClient, WM_DDE_DATA, (WPARAM)pConv->hwndServer,
Dmitry Timoshkov37d39962003-05-19 23:27:16 +0000130 PackDDElParam(WM_DDE_DATA, (UINT_PTR)hItemData, atom)))
Eric Pouech6a03ac02001-06-22 23:02:48 +0000131 {
132 ERR("post message failed\n");
Eric Pouech01ff6892002-01-18 19:30:15 +0000133 pConv->wStatus &= ~ST_CONNECTED;
Dmitry Timoshkov5ef324e2006-11-15 21:21:44 +0800134 pConv->instance->lastError = DMLERR_POSTMSG_FAILED;
Eric Pouech01ff6892002-01-18 19:30:15 +0000135 if (!WDML_IsAppOwned(hDdeData)) DdeFreeDataHandle(hDdeData);
Eric Pouech78a41342001-08-09 22:07:22 +0000136 GlobalFree(hItemData);
137 goto theError;
Vincent Béron9a624912002-05-31 23:06:46 +0000138 }
Eric Pouech01ff6892002-01-18 19:30:15 +0000139 if (!WDML_IsAppOwned(hDdeData)) DdeFreeDataHandle(hDdeData);
Eric Pouech6a03ac02001-06-22 23:02:48 +0000140 }
141 }
142 }
Eric Pouech6a03ac02001-06-22 23:02:48 +0000143 return TRUE;
Dmitry Timoshkova3722bf2006-11-15 21:22:35 +0800144
Eric Pouech78a41342001-08-09 22:07:22 +0000145 theError:
Eric Pouech78a41342001-08-09 22:07:22 +0000146 if (atom) GlobalDeleteAtom(atom);
147 return FALSE;
Eric Pouech6a03ac02001-06-22 23:02:48 +0000148}
149
150
151/******************************************************************************
152 * DdeNameService [USER32.@] {Un}registers service name of DDE server
153 *
154 * PARAMS
155 * idInst [I] Instance identifier
156 * hsz1 [I] Handle to service name string
157 * hsz2 [I] Reserved
158 * afCmd [I] Service name flags
159 *
160 * RETURNS
161 * Success: Non-zero
162 * Failure: 0
163 */
164HDDEDATA WINAPI DdeNameService(DWORD idInst, HSZ hsz1, HSZ hsz2, UINT afCmd)
165{
166 WDML_SERVER* pServer;
Eric Pouech78a41342001-08-09 22:07:22 +0000167 WDML_INSTANCE* pInstance;
Eric Pouech6a03ac02001-06-22 23:02:48 +0000168 HDDEDATA hDdeData;
Eric Pouech6a03ac02001-06-22 23:02:48 +0000169 HWND hwndServer;
Dmitry Timoshkovca7b25c2005-02-14 11:53:15 +0000170 WNDCLASSEXW wndclass;
Vincent Béron9a624912002-05-31 23:06:46 +0000171
Francois Gougetd2667a42002-12-02 18:10:57 +0000172 hDdeData = NULL;
Vincent Béron9a624912002-05-31 23:06:46 +0000173
Michael Stefaniuc3c60ce82006-09-30 00:25:15 +0200174 TRACE("(%d,%p,%p,%x)\n", idInst, hsz1, hsz2, afCmd);
Vincent Béron9a624912002-05-31 23:06:46 +0000175
Eric Pouech6a03ac02001-06-22 23:02:48 +0000176 /* First check instance
177 */
Eric Pouech78a41342001-08-09 22:07:22 +0000178 pInstance = WDML_GetInstance(idInst);
179 if (pInstance == NULL)
Eric Pouech6a03ac02001-06-22 23:02:48 +0000180 {
181 TRACE("Instance not found as initialised\n");
Eric Pouech6a03ac02001-06-22 23:02:48 +0000182 /* Nothing has been initialised - exit now ! can return TRUE since effect is the same */
Dmitry Timoshkova3722bf2006-11-15 21:22:35 +0800183 return NULL;
Eric Pouech6a03ac02001-06-22 23:02:48 +0000184 }
Vincent Béron9a624912002-05-31 23:06:46 +0000185
Eric Pouech6a03ac02001-06-22 23:02:48 +0000186 if (hsz2 != 0L)
187 {
188 /* Illegal, reserved parameter
189 */
Eric Pouech78a41342001-08-09 22:07:22 +0000190 pInstance->lastError = DMLERR_INVALIDPARAMETER;
191 WARN("Reserved parameter no-zero !!\n");
Dmitry Timoshkova3722bf2006-11-15 21:22:35 +0800192 return NULL;
Eric Pouech6a03ac02001-06-22 23:02:48 +0000193 }
Dmitry Timoshkov37d39962003-05-19 23:27:16 +0000194 if (hsz1 == 0 && !(afCmd & DNS_UNREGISTER))
Eric Pouech6a03ac02001-06-22 23:02:48 +0000195 {
Eric Pouech78a41342001-08-09 22:07:22 +0000196 /* don't know if we should check this but it makes sense
197 * why supply REGISTER or filter flags if de-registering all
Eric Pouech6a03ac02001-06-22 23:02:48 +0000198 */
Eric Pouech78a41342001-08-09 22:07:22 +0000199 TRACE("General unregister unexpected flags\n");
200 pInstance->lastError = DMLERR_INVALIDPARAMETER;
Dmitry Timoshkova3722bf2006-11-15 21:22:35 +0800201 return NULL;
Eric Pouech6a03ac02001-06-22 23:02:48 +0000202 }
Vincent Béron9a624912002-05-31 23:06:46 +0000203
Dmitry Timoshkov37d39962003-05-19 23:27:16 +0000204 switch (afCmd & (DNS_REGISTER | DNS_UNREGISTER))
Eric Pouech6a03ac02001-06-22 23:02:48 +0000205 {
Eric Pouech78a41342001-08-09 22:07:22 +0000206 case DNS_REGISTER:
207 pServer = WDML_FindServer(pInstance, hsz1, 0);
Eric Pouech6a03ac02001-06-22 23:02:48 +0000208 if (pServer)
Eric Pouech6a03ac02001-06-22 23:02:48 +0000209 {
Eric Pouech78a41342001-08-09 22:07:22 +0000210 ERR("Trying to register already registered service!\n");
211 pInstance->lastError = DMLERR_DLL_USAGE;
Dmitry Timoshkova3722bf2006-11-15 21:22:35 +0800212 return NULL;
Vincent Béron9a624912002-05-31 23:06:46 +0000213 }
Eric Pouech78a41342001-08-09 22:07:22 +0000214
215 TRACE("Adding service name\n");
Vincent Béron9a624912002-05-31 23:06:46 +0000216
Eric Pouech78a41342001-08-09 22:07:22 +0000217 WDML_IncHSZ(pInstance, hsz1);
Vincent Béron9a624912002-05-31 23:06:46 +0000218
Eric Pouech78a41342001-08-09 22:07:22 +0000219 pServer = WDML_AddServer(pInstance, hsz1, 0);
Vincent Béron9a624912002-05-31 23:06:46 +0000220
221 WDML_BroadcastDDEWindows(WDML_szEventClass, WM_WDML_REGISTER,
Eric Pouech78a41342001-08-09 22:07:22 +0000222 pServer->atomService, pServer->atomServiceSpec);
Vincent Béron9a624912002-05-31 23:06:46 +0000223
Eric Pouech6a03ac02001-06-22 23:02:48 +0000224 wndclass.cbSize = sizeof(wndclass);
225 wndclass.style = 0;
226 wndclass.lpfnWndProc = WDML_ServerNameProc;
227 wndclass.cbClsExtra = 0;
Dmitry Timoshkovca7b25c2005-02-14 11:53:15 +0000228 wndclass.cbWndExtra = 2 * sizeof(ULONG_PTR);
Eric Pouech6a03ac02001-06-22 23:02:48 +0000229 wndclass.hInstance = 0;
230 wndclass.hIcon = 0;
231 wndclass.hCursor = 0;
232 wndclass.hbrBackground = 0;
233 wndclass.lpszMenuName = NULL;
Dmitry Timoshkovca7b25c2005-02-14 11:53:15 +0000234 wndclass.lpszClassName = szServerNameClass;
Eric Pouech6a03ac02001-06-22 23:02:48 +0000235 wndclass.hIconSm = 0;
Vincent Béron9a624912002-05-31 23:06:46 +0000236
Dmitry Timoshkovca7b25c2005-02-14 11:53:15 +0000237 RegisterClassExW(&wndclass);
Vincent Béron9a624912002-05-31 23:06:46 +0000238
Dmitry Timoshkovca7b25c2005-02-14 11:53:15 +0000239 hwndServer = CreateWindowW(szServerNameClass, NULL,
Eric Pouech6a03ac02001-06-22 23:02:48 +0000240 WS_POPUP, 0, 0, 0, 0,
241 0, 0, 0, 0);
Eric Pouech78a41342001-08-09 22:07:22 +0000242
Dmitry Timoshkovca7b25c2005-02-14 11:53:15 +0000243 SetWindowLongPtrW(hwndServer, GWL_WDML_INSTANCE, (ULONG_PTR)pInstance);
244 SetWindowLongPtrW(hwndServer, GWL_WDML_SERVER, (ULONG_PTR)pServer);
Michael Stefaniuc3c60ce82006-09-30 00:25:15 +0200245 TRACE("Created nameServer=%p for instance=%08x\n", hwndServer, idInst);
Vincent Béron9a624912002-05-31 23:06:46 +0000246
Eric Pouech6a03ac02001-06-22 23:02:48 +0000247 pServer->hwndServer = hwndServer;
Eric Pouech78a41342001-08-09 22:07:22 +0000248 break;
249
250 case DNS_UNREGISTER:
251 if (hsz1 == 0L)
252 {
253 /* General unregister situation
Vincent Béron9a624912002-05-31 23:06:46 +0000254 * terminate all server side pending conversations
Eric Pouech78a41342001-08-09 22:07:22 +0000255 */
256 while (pInstance->servers)
257 WDML_RemoveServer(pInstance, pInstance->servers->hszService, 0);
258 pInstance->servers = NULL;
259 TRACE("General de-register - finished\n");
260 }
261 else
262 {
263 WDML_RemoveServer(pInstance, hsz1, 0L);
264 }
265 break;
Dmitry Timoshkov37d39962003-05-19 23:27:16 +0000266 }
267
268 if (afCmd & (DNS_FILTERON | DNS_FILTEROFF))
269 {
Eric Pouech6a03ac02001-06-22 23:02:48 +0000270 /* Set filter flags on to hold notifications of connection
Eric Pouech6a03ac02001-06-22 23:02:48 +0000271 */
Eric Pouech78a41342001-08-09 22:07:22 +0000272 pServer = WDML_FindServer(pInstance, hsz1, 0);
Eric Pouech6a03ac02001-06-22 23:02:48 +0000273 if (!pServer)
274 {
275 /* trying to filter where no service names !!
276 */
Eric Pouech78a41342001-08-09 22:07:22 +0000277 pInstance->lastError = DMLERR_DLL_USAGE;
Dmitry Timoshkova3722bf2006-11-15 21:22:35 +0800278 return NULL;
Vincent Béron9a624912002-05-31 23:06:46 +0000279 }
280 else
Eric Pouech6a03ac02001-06-22 23:02:48 +0000281 {
Dmitry Timoshkov37d39962003-05-19 23:27:16 +0000282 pServer->filterOn = (afCmd & DNS_FILTERON) != 0;
Eric Pouech6a03ac02001-06-22 23:02:48 +0000283 }
284 }
Eric Pouech6a03ac02001-06-22 23:02:48 +0000285 return (HDDEDATA)TRUE;
Eric Pouech6a03ac02001-06-22 23:02:48 +0000286}
287
288/******************************************************************
289 * WDML_CreateServerConv
290 *
291 *
292 */
Vincent Béron9a624912002-05-31 23:06:46 +0000293static WDML_CONV* WDML_CreateServerConv(WDML_INSTANCE* pInstance, HWND hwndClient,
Eric Pouech78a41342001-08-09 22:07:22 +0000294 HWND hwndServerName, HSZ hszApp, HSZ hszTopic)
Eric Pouech6a03ac02001-06-22 23:02:48 +0000295{
Eric Pouech6a03ac02001-06-22 23:02:48 +0000296 HWND hwndServerConv;
297 WDML_CONV* pConv;
Vincent Béron9a624912002-05-31 23:06:46 +0000298
Dmitry Timoshkov87458a52005-07-08 11:33:09 +0000299 if (pInstance->unicode)
300 {
301 WNDCLASSEXW wndclass;
Eric Pouech6a03ac02001-06-22 23:02:48 +0000302
Dmitry Timoshkov87458a52005-07-08 11:33:09 +0000303 wndclass.cbSize = sizeof(wndclass);
304 wndclass.style = 0;
305 wndclass.lpfnWndProc = WDML_ServerConvProc;
306 wndclass.cbClsExtra = 0;
307 wndclass.cbWndExtra = 2 * sizeof(ULONG_PTR);
308 wndclass.hInstance = 0;
309 wndclass.hIcon = 0;
310 wndclass.hCursor = 0;
311 wndclass.hbrBackground = 0;
312 wndclass.lpszMenuName = NULL;
313 wndclass.lpszClassName = WDML_szServerConvClassW;
314 wndclass.hIconSm = 0;
Eric Pouech78a41342001-08-09 22:07:22 +0000315
Dmitry Timoshkov87458a52005-07-08 11:33:09 +0000316 RegisterClassExW(&wndclass);
317
318 hwndServerConv = CreateWindowW(WDML_szServerConvClassW, 0,
Eric Pouech78a41342001-08-09 22:07:22 +0000319 WS_CHILD, 0, 0, 0, 0,
320 hwndServerName, 0, 0, 0);
Dmitry Timoshkov87458a52005-07-08 11:33:09 +0000321 }
322 else
323 {
324 WNDCLASSEXA wndclass;
325
326 wndclass.cbSize = sizeof(wndclass);
327 wndclass.style = 0;
328 wndclass.lpfnWndProc = WDML_ServerConvProc;
329 wndclass.cbClsExtra = 0;
330 wndclass.cbWndExtra = 2 * sizeof(ULONG_PTR);
331 wndclass.hInstance = 0;
332 wndclass.hIcon = 0;
333 wndclass.hCursor = 0;
334 wndclass.hbrBackground = 0;
335 wndclass.lpszMenuName = NULL;
336 wndclass.lpszClassName = WDML_szServerConvClassA;
337 wndclass.hIconSm = 0;
338
339 RegisterClassExA(&wndclass);
340
341 hwndServerConv = CreateWindowA(WDML_szServerConvClassA, 0,
342 WS_CHILD, 0, 0, 0, 0,
343 hwndServerName, 0, 0, 0);
344 }
Eric Pouech78a41342001-08-09 22:07:22 +0000345
Michael Stefaniuc3c60ce82006-09-30 00:25:15 +0200346 TRACE("Created convServer=%p (nameServer=%p) for instance=%08x\n",
Eric Pouech78a41342001-08-09 22:07:22 +0000347 hwndServerConv, hwndServerName, pInstance->instanceID);
Vincent Béron9a624912002-05-31 23:06:46 +0000348
349 pConv = WDML_AddConv(pInstance, WDML_SERVER_SIDE, hszApp, hszTopic,
Eric Pouech78a41342001-08-09 22:07:22 +0000350 hwndClient, hwndServerConv);
351 if (pConv)
352 {
Dmitry Timoshkovca7b25c2005-02-14 11:53:15 +0000353 SetWindowLongPtrW(hwndServerConv, GWL_WDML_INSTANCE, (ULONG_PTR)pInstance);
354 SetWindowLongPtrW(hwndServerConv, GWL_WDML_CONVERSATION, (ULONG_PTR)pConv);
Eric Pouech78a41342001-08-09 22:07:22 +0000355
356 /* this should be the only place using SendMessage for WM_DDE_ACK */
Eric Pouech01ff6892002-01-18 19:30:15 +0000357 /* note: sent messages shall not use packing */
Dmitry Timoshkovca7b25c2005-02-14 11:53:15 +0000358 SendMessageW(hwndClient, WM_DDE_ACK, (WPARAM)hwndServerConv,
Eric Pouech01ff6892002-01-18 19:30:15 +0000359 MAKELPARAM(WDML_MakeAtomFromHsz(hszApp), WDML_MakeAtomFromHsz(hszTopic)));
Vincent Béron9a624912002-05-31 23:06:46 +0000360 /* we assume we're connected since we've sent an answer...
Eric Pouech78a41342001-08-09 22:07:22 +0000361 * I'm not sure what we can do... it doesn't look like the return value
362 * of SendMessage is used... sigh...
363 */
364 pConv->wStatus |= ST_CONNECTED;
365 }
366 else
367 {
368 DestroyWindow(hwndServerConv);
369 }
370 return pConv;
Eric Pouech6a03ac02001-06-22 23:02:48 +0000371}
372
373/******************************************************************
374 * WDML_ServerNameProc
375 *
376 *
377 */
378static LRESULT CALLBACK WDML_ServerNameProc(HWND hwndServer, UINT iMsg, WPARAM wParam, LPARAM lParam)
379{
380 HWND hwndClient;
381 HSZ hszApp, hszTop;
382 HDDEDATA hDdeData = 0;
Eric Pouech78a41342001-08-09 22:07:22 +0000383 WDML_INSTANCE* pInstance;
Dmitry Timoshkov37d39962003-05-19 23:27:16 +0000384 UINT_PTR uiLo, uiHi;
Vincent Béron9a624912002-05-31 23:06:46 +0000385
Eric Pouech6a03ac02001-06-22 23:02:48 +0000386 switch (iMsg)
387 {
388 case WM_DDE_INITIATE:
Vincent Béron9a624912002-05-31 23:06:46 +0000389
Eric Pouech6a03ac02001-06-22 23:02:48 +0000390 /* wParam -- sending window handle
391 LOWORD(lParam) -- application atom
392 HIWORD(lParam) -- topic atom */
Vincent Béron9a624912002-05-31 23:06:46 +0000393
Eric Pouech78a41342001-08-09 22:07:22 +0000394 TRACE("WM_DDE_INITIATE message received!\n");
Eric Pouech6a03ac02001-06-22 23:02:48 +0000395 hwndClient = (HWND)wParam;
Vincent Béron9a624912002-05-31 23:06:46 +0000396
Eric Pouech78a41342001-08-09 22:07:22 +0000397 pInstance = WDML_GetInstanceFromWnd(hwndServer);
Michael Stefaniuc3c60ce82006-09-30 00:25:15 +0200398 TRACE("idInst=%d, threadID=0x%x\n", pInstance->instanceID, GetCurrentThreadId());
Eric Pouech78a41342001-08-09 22:07:22 +0000399 if (!pInstance) return 0;
400
Eric Pouech6a03ac02001-06-22 23:02:48 +0000401 /* don't free DDEParams, since this is a broadcast */
Vincent Béron9a624912002-05-31 23:06:46 +0000402 UnpackDDElParam(WM_DDE_INITIATE, lParam, &uiLo, &uiHi);
403
Eric Pouech78a41342001-08-09 22:07:22 +0000404 hszApp = WDML_MakeHszFromAtom(pInstance, uiLo);
405 hszTop = WDML_MakeHszFromAtom(pInstance, uiHi);
Vincent Béron9a624912002-05-31 23:06:46 +0000406
Eric Pouech78a41342001-08-09 22:07:22 +0000407 if (!(pInstance->CBFflags & CBF_FAIL_CONNECTIONS))
Eric Pouech6a03ac02001-06-22 23:02:48 +0000408 {
Eric Pouech78a41342001-08-09 22:07:22 +0000409 BOOL self = FALSE;
410 CONVCONTEXT cc;
411 CONVCONTEXT* pcc = NULL;
412 WDML_CONV* pConv;
Dmitry Timoshkov87458a52005-07-08 11:33:09 +0000413 char buf[256];
Eric Pouech78a41342001-08-09 22:07:22 +0000414
415 if (GetWindowThreadProcessId(hwndClient, NULL) == GetWindowThreadProcessId(hwndServer, NULL) &&
416 WDML_GetInstanceFromWnd(hwndClient) == WDML_GetInstanceFromWnd(hwndServer))
Eric Pouech6a03ac02001-06-22 23:02:48 +0000417 {
Eric Pouech78a41342001-08-09 22:07:22 +0000418 self = TRUE;
419 }
420 /* FIXME: so far, we don't grab distant convcontext, so only check if remote is
421 * handled under DDEML, and if so build a default context
422 */
Dmitry Timoshkov87458a52005-07-08 11:33:09 +0000423 if ((GetClassNameA(hwndClient, buf, sizeof(buf)) &&
424 lstrcmpiA(buf, WDML_szClientConvClassA) == 0) ||
425 (GetClassNameW(hwndClient, (LPWSTR)buf, sizeof(buf)/sizeof(WCHAR)) &&
426 lstrcmpiW((LPWSTR)buf, WDML_szClientConvClassW) == 0))
Eric Pouech78a41342001-08-09 22:07:22 +0000427 {
428 pcc = &cc;
429 memset(pcc, 0, sizeof(*pcc));
430 pcc->cb = sizeof(*pcc);
Dmitry Timoshkov87458a52005-07-08 11:33:09 +0000431 pcc->iCodePage = IsWindowUnicode(hwndClient) ? CP_WINUNICODE : CP_WINANSI;
Eric Pouech78a41342001-08-09 22:07:22 +0000432 }
433 if ((pInstance->CBFflags & CBF_FAIL_SELFCONNECTIONS) && self)
434 {
435 TRACE("Don't do self connection as requested\n");
436 }
Vincent Béron9a624912002-05-31 23:06:46 +0000437 else if (hszApp && hszTop)
Eric Pouech78a41342001-08-09 22:07:22 +0000438 {
Dmitry Timoshkovca7b25c2005-02-14 11:53:15 +0000439 WDML_SERVER* pServer = (WDML_SERVER*)GetWindowLongPtrW(hwndServer, GWL_WDML_SERVER);
Vincent Béron9a624912002-05-31 23:06:46 +0000440
Eric Pouech78a41342001-08-09 22:07:22 +0000441 /* check filters for name service */
442 if (!pServer->filterOn || DdeCmpStringHandles(pServer->hszService, hszApp) == 0)
Eric Pouech6a03ac02001-06-22 23:02:48 +0000443 {
Eric Pouech78a41342001-08-09 22:07:22 +0000444 /* pass on to the callback */
445 hDdeData = WDML_InvokeCallback(pInstance, XTYP_CONNECT,
Dmitry Timoshkov85ef4562004-04-26 23:29:44 +0000446 0, 0, hszTop, hszApp, 0, (ULONG_PTR)pcc, self);
Dmitry Timoshkovca7b25c2005-02-14 11:53:15 +0000447 if ((ULONG_PTR)hDdeData)
Eric Pouech78a41342001-08-09 22:07:22 +0000448 {
Vincent Béron9a624912002-05-31 23:06:46 +0000449 pConv = WDML_CreateServerConv(pInstance, hwndClient, hwndServer,
Eric Pouech78a41342001-08-09 22:07:22 +0000450 hszApp, hszTop);
Dmitry Timoshkov37d39962003-05-19 23:27:16 +0000451 if (pConv)
452 {
453 if (pcc) pConv->wStatus |= ST_ISLOCAL;
454 WDML_InvokeCallback(pInstance, XTYP_CONNECT_CONFIRM, 0, (HCONV)pConv,
Dmitry Timoshkov85ef4562004-04-26 23:29:44 +0000455 hszTop, hszApp, 0, (ULONG_PTR)pcc, self);
Dmitry Timoshkov37d39962003-05-19 23:27:16 +0000456 }
Eric Pouech78a41342001-08-09 22:07:22 +0000457 }
Eric Pouech6a03ac02001-06-22 23:02:48 +0000458 }
459 }
Eric Pouech78a41342001-08-09 22:07:22 +0000460 else if (pInstance->servers)
Eric Pouech6a03ac02001-06-22 23:02:48 +0000461 {
Eric Pouech78a41342001-08-09 22:07:22 +0000462 /* pass on to the callback */
463 hDdeData = WDML_InvokeCallback(pInstance, XTYP_WILDCONNECT,
Dmitry Timoshkov85ef4562004-04-26 23:29:44 +0000464 0, 0, hszTop, hszApp, 0, (ULONG_PTR)pcc, self);
Eric Pouech78a41342001-08-09 22:07:22 +0000465
Eric Pouech01ff6892002-01-18 19:30:15 +0000466 if (hDdeData == (HDDEDATA)CBR_BLOCK)
Eric Pouech78a41342001-08-09 22:07:22 +0000467 {
468 /* MS doc is not consistent here */
469 FIXME("CBR_BLOCK returned for WILDCONNECT\n");
470 }
Dmitry Timoshkovca7b25c2005-02-14 11:53:15 +0000471 else if ((ULONG_PTR)hDdeData != 0)
Eric Pouech6a03ac02001-06-22 23:02:48 +0000472 {
473 HSZPAIR* hszp;
Vincent Béron9a624912002-05-31 23:06:46 +0000474
Eric Pouech6a03ac02001-06-22 23:02:48 +0000475 hszp = (HSZPAIR*)DdeAccessData(hDdeData, NULL);
476 if (hszp)
477 {
478 int i;
479 for (i = 0; hszp[i].hszSvc && hszp[i].hszTopic; i++)
480 {
Vincent Béron9a624912002-05-31 23:06:46 +0000481 pConv = WDML_CreateServerConv(pInstance, hwndClient, hwndServer,
Eric Pouech78a41342001-08-09 22:07:22 +0000482 hszp[i].hszSvc, hszp[i].hszTopic);
Dmitry Timoshkov37d39962003-05-19 23:27:16 +0000483 if (pConv)
484 {
485 if (pcc) pConv->wStatus |= ST_ISLOCAL;
486 WDML_InvokeCallback(pInstance, XTYP_CONNECT_CONFIRM, 0, (HCONV)pConv,
Dmitry Timoshkov85ef4562004-04-26 23:29:44 +0000487 hszp[i].hszTopic, hszp[i].hszSvc, 0, (ULONG_PTR)pcc, self);
Dmitry Timoshkov37d39962003-05-19 23:27:16 +0000488 }
Vincent Béron9a624912002-05-31 23:06:46 +0000489 }
Eric Pouech6a03ac02001-06-22 23:02:48 +0000490 DdeUnaccessData(hDdeData);
491 }
Eric Pouech01ff6892002-01-18 19:30:15 +0000492 if (!WDML_IsAppOwned(hDdeData)) DdeFreeDataHandle(hDdeData);
Eric Pouech6a03ac02001-06-22 23:02:48 +0000493 }
494 }
495 }
Vincent Béron9a624912002-05-31 23:06:46 +0000496
Eric Pouech6a03ac02001-06-22 23:02:48 +0000497 return 0;
Vincent Béron9a624912002-05-31 23:06:46 +0000498
Eric Pouech6a03ac02001-06-22 23:02:48 +0000499 case WM_DDE_REQUEST:
500 FIXME("WM_DDE_REQUEST message received!\n");
501 return 0;
502 case WM_DDE_ADVISE:
503 FIXME("WM_DDE_ADVISE message received!\n");
504 return 0;
505 case WM_DDE_UNADVISE:
506 FIXME("WM_DDE_UNADVISE message received!\n");
507 return 0;
508 case WM_DDE_EXECUTE:
509 FIXME("WM_DDE_EXECUTE message received!\n");
510 return 0;
511 case WM_DDE_POKE:
512 FIXME("WM_DDE_POKE message received!\n");
513 return 0;
514 case WM_DDE_TERMINATE:
515 FIXME("WM_DDE_TERMINATE message received!\n");
516 return 0;
Dmitry Timoshkovca7b25c2005-02-14 11:53:15 +0000517 default:
518 break;
Eric Pouech6a03ac02001-06-22 23:02:48 +0000519 }
Vincent Béron9a624912002-05-31 23:06:46 +0000520
Dmitry Timoshkovca7b25c2005-02-14 11:53:15 +0000521 return DefWindowProcW(hwndServer, iMsg, wParam, lParam);
Eric Pouech6a03ac02001-06-22 23:02:48 +0000522}
523
524/******************************************************************
Eric Pouech78a41342001-08-09 22:07:22 +0000525 * WDML_ServerQueueRequest
526 *
527 *
528 */
529static WDML_XACT* WDML_ServerQueueRequest(WDML_CONV* pConv, LPARAM lParam)
530{
Dmitry Timoshkov37d39962003-05-19 23:27:16 +0000531 UINT_PTR uiLo, uiHi;
Eric Pouech78a41342001-08-09 22:07:22 +0000532 WDML_XACT* pXAct;
533
534 UnpackDDElParam(WM_DDE_REQUEST, lParam, &uiLo, &uiHi);
535
Vincent Béron9a624912002-05-31 23:06:46 +0000536 pXAct = WDML_AllocTransaction(pConv->instance, WM_DDE_REQUEST,
Eric Pouech78a41342001-08-09 22:07:22 +0000537 uiLo, WDML_MakeHszFromAtom(pConv->instance, uiHi));
538 if (pXAct) pXAct->atom = uiHi;
539 return pXAct;
540}
541
542/******************************************************************
Eric Pouech6a03ac02001-06-22 23:02:48 +0000543 * WDML_ServerHandleRequest
544 *
545 *
546 */
Eric Pouech78a41342001-08-09 22:07:22 +0000547static WDML_QUEUE_STATE WDML_ServerHandleRequest(WDML_CONV* pConv, WDML_XACT* pXAct)
Eric Pouech6a03ac02001-06-22 23:02:48 +0000548{
Eric Pouech78a41342001-08-09 22:07:22 +0000549 HDDEDATA hDdeData = 0;
Dmitry Timoshkov7266da32005-02-01 18:47:55 +0000550 BOOL fAck = TRUE;
Eric Pouech6a03ac02001-06-22 23:02:48 +0000551
Eric Pouech78a41342001-08-09 22:07:22 +0000552 if (!(pConv->instance->CBFflags & CBF_FAIL_REQUESTS))
Eric Pouech6a03ac02001-06-22 23:02:48 +0000553 {
Vincent Béron9a624912002-05-31 23:06:46 +0000554
555 hDdeData = WDML_InvokeCallback(pConv->instance, XTYP_REQUEST, pXAct->wFmt, (HCONV)pConv,
Eric Pouech78a41342001-08-09 22:07:22 +0000556 pConv->hszTopic, pXAct->hszItem, 0, 0, 0);
Eric Pouech6a03ac02001-06-22 23:02:48 +0000557 }
Eric Pouech78a41342001-08-09 22:07:22 +0000558
Dmitry Timoshkov37d39962003-05-19 23:27:16 +0000559 switch ((ULONG_PTR)hDdeData)
Eric Pouech6a03ac02001-06-22 23:02:48 +0000560 {
Eric Pouech78a41342001-08-09 22:07:22 +0000561 case 0:
Dmitry Timoshkov7266da32005-02-01 18:47:55 +0000562 TRACE("No data returned from the Callback\n");
563 fAck = FALSE;
Eric Pouech78a41342001-08-09 22:07:22 +0000564 break;
Dmitry Timoshkov7266da32005-02-01 18:47:55 +0000565
Huw Daviese937e462004-06-14 19:35:14 +0000566 case (ULONG_PTR)CBR_BLOCK:
Dmitry Timoshkov7266da32005-02-01 18:47:55 +0000567 return WDML_QS_BLOCK;
568
Eric Pouech78a41342001-08-09 22:07:22 +0000569 default:
570 {
Dmitry Timoshkov3e6b5e52003-06-04 20:16:17 +0000571 HGLOBAL hMem = WDML_DataHandle2Global(hDdeData, TRUE, FALSE, FALSE, FALSE);
Dmitry Timoshkovca7b25c2005-02-14 11:53:15 +0000572 if (!PostMessageW(pConv->hwndClient, WM_DDE_DATA, (WPARAM)pConv->hwndServer,
Vincent Béron9a624912002-05-31 23:06:46 +0000573 ReuseDDElParam(pXAct->lParam, WM_DDE_REQUEST, WM_DDE_DATA,
Dmitry Timoshkov3e6b5e52003-06-04 20:16:17 +0000574 (UINT_PTR)hMem, (UINT_PTR)pXAct->atom)))
Eric Pouech78a41342001-08-09 22:07:22 +0000575 {
Dmitry Timoshkov5ef324e2006-11-15 21:21:44 +0800576 pConv->instance->lastError = DMLERR_POSTMSG_FAILED;
Eric Pouech78a41342001-08-09 22:07:22 +0000577 DdeFreeDataHandle(hDdeData);
578 GlobalFree(hMem);
Dmitry Timoshkov7266da32005-02-01 18:47:55 +0000579 fAck = FALSE;
Eric Pouech78a41342001-08-09 22:07:22 +0000580 }
Eric Pouech6a03ac02001-06-22 23:02:48 +0000581 }
Eric Pouech78a41342001-08-09 22:07:22 +0000582 break;
Eric Pouech6a03ac02001-06-22 23:02:48 +0000583 }
Dmitry Timoshkov7266da32005-02-01 18:47:55 +0000584
585 WDML_PostAck(pConv, WDML_SERVER_SIDE, 0, FALSE, fAck, pXAct->atom, pXAct->lParam, WM_DDE_REQUEST);
586
Eric Pouech78a41342001-08-09 22:07:22 +0000587 WDML_DecHSZ(pConv->instance, pXAct->hszItem);
Dmitry Timoshkov7266da32005-02-01 18:47:55 +0000588
589 return WDML_QS_HANDLED;
Eric Pouech78a41342001-08-09 22:07:22 +0000590}
Eric Pouech6a03ac02001-06-22 23:02:48 +0000591
Eric Pouech78a41342001-08-09 22:07:22 +0000592/******************************************************************
593 * WDML_ServerQueueAdvise
594 *
595 *
596 */
597static WDML_XACT* WDML_ServerQueueAdvise(WDML_CONV* pConv, LPARAM lParam)
598{
Dmitry Timoshkov37d39962003-05-19 23:27:16 +0000599 UINT_PTR uiLo, uiHi;
Eric Pouech78a41342001-08-09 22:07:22 +0000600 WDML_XACT* pXAct;
601
Vincent Béron9a624912002-05-31 23:06:46 +0000602 /* XTYP_ADVSTART transaction:
Eric Pouech78a41342001-08-09 22:07:22 +0000603 establish link and save link info to InstanceInfoTable */
Vincent Béron9a624912002-05-31 23:06:46 +0000604
Eric Pouech01ff6892002-01-18 19:30:15 +0000605 if (!UnpackDDElParam(WM_DDE_ADVISE, lParam, &uiLo, &uiHi))
606 return NULL;
Vincent Béron9a624912002-05-31 23:06:46 +0000607
608 pXAct = WDML_AllocTransaction(pConv->instance, WM_DDE_ADVISE,
Eric Pouech78a41342001-08-09 22:07:22 +0000609 0, WDML_MakeHszFromAtom(pConv->instance, uiHi));
610 if (pXAct)
611 {
612 pXAct->hMem = (HGLOBAL)uiLo;
613 pXAct->atom = uiHi;
614 }
615 return pXAct;
Eric Pouech6a03ac02001-06-22 23:02:48 +0000616}
617
618/******************************************************************
619 * WDML_ServerHandleAdvise
620 *
621 *
622 */
Eric Pouech78a41342001-08-09 22:07:22 +0000623static WDML_QUEUE_STATE WDML_ServerHandleAdvise(WDML_CONV* pConv, WDML_XACT* pXAct)
Eric Pouech6a03ac02001-06-22 23:02:48 +0000624{
Eric Pouech78a41342001-08-09 22:07:22 +0000625 UINT uType;
Eric Pouech6a03ac02001-06-22 23:02:48 +0000626 WDML_LINK* pLink;
627 DDEADVISE* pDdeAdvise;
Dmitry Timoshkov7266da32005-02-01 18:47:55 +0000628 HDDEDATA hDdeData = 0;
629 BOOL fAck = TRUE;
Eric Pouech6a03ac02001-06-22 23:02:48 +0000630
Eric Pouech78a41342001-08-09 22:07:22 +0000631 pDdeAdvise = (DDEADVISE*)GlobalLock(pXAct->hMem);
Vincent Béron9a624912002-05-31 23:06:46 +0000632 uType = XTYP_ADVSTART |
Eric Pouech6a03ac02001-06-22 23:02:48 +0000633 (pDdeAdvise->fDeferUpd ? XTYPF_NODATA : 0) |
634 (pDdeAdvise->fAckReq ? XTYPF_ACKREQ : 0);
Vincent Béron9a624912002-05-31 23:06:46 +0000635
Eric Pouech78a41342001-08-09 22:07:22 +0000636 if (!(pConv->instance->CBFflags & CBF_FAIL_ADVISES))
Eric Pouech6a03ac02001-06-22 23:02:48 +0000637 {
Vincent Béron9a624912002-05-31 23:06:46 +0000638 hDdeData = WDML_InvokeCallback(pConv->instance, XTYP_ADVSTART, pDdeAdvise->cfFormat,
Eric Pouech78a41342001-08-09 22:07:22 +0000639 (HCONV)pConv, pConv->hszTopic, pXAct->hszItem, 0, 0, 0);
Eric Pouech6a03ac02001-06-22 23:02:48 +0000640 }
Eric Pouech78a41342001-08-09 22:07:22 +0000641
Dmitry Timoshkov7266da32005-02-01 18:47:55 +0000642 switch ((ULONG_PTR)hDdeData)
Eric Pouech78a41342001-08-09 22:07:22 +0000643 {
Dmitry Timoshkov7266da32005-02-01 18:47:55 +0000644 case 0:
645 TRACE("No data returned from the Callback\n");
646 fAck = FALSE;
647 break;
Vincent Béron9a624912002-05-31 23:06:46 +0000648
Dmitry Timoshkov7266da32005-02-01 18:47:55 +0000649 case (ULONG_PTR)CBR_BLOCK:
650 return WDML_QS_BLOCK;
651
652 default:
Eric Pouech6a03ac02001-06-22 23:02:48 +0000653 /* billx: first to see if the link is already created. */
Vincent Béron9a624912002-05-31 23:06:46 +0000654 pLink = WDML_FindLink(pConv->instance, (HCONV)pConv, WDML_SERVER_SIDE,
Eric Pouech01ff6892002-01-18 19:30:15 +0000655 pXAct->hszItem, TRUE, pDdeAdvise->cfFormat);
Eric Pouech6a03ac02001-06-22 23:02:48 +0000656
657 if (pLink != NULL)
658 {
659 /* we found a link, and only need to modify it in case it changes */
660 pLink->transactionType = uType;
661 }
662 else
663 {
Dmitry Timoshkov37d39962003-05-19 23:27:16 +0000664 TRACE("Adding Link with hConv %p\n", pConv);
Vincent Béron9a624912002-05-31 23:06:46 +0000665 WDML_AddLink(pConv->instance, (HCONV)pConv, WDML_SERVER_SIDE,
Eric Pouech78a41342001-08-09 22:07:22 +0000666 uType, pXAct->hszItem, pDdeAdvise->cfFormat);
Eric Pouech6a03ac02001-06-22 23:02:48 +0000667 }
Dmitry Timoshkov7266da32005-02-01 18:47:55 +0000668 break;
Eric Pouech6a03ac02001-06-22 23:02:48 +0000669 }
Vincent Béron9a624912002-05-31 23:06:46 +0000670
Eric Pouech78a41342001-08-09 22:07:22 +0000671 GlobalUnlock(pXAct->hMem);
672 if (fAck)
Eric Pouech01ff6892002-01-18 19:30:15 +0000673 {
Eric Pouech78a41342001-08-09 22:07:22 +0000674 GlobalFree(pXAct->hMem);
Eric Pouech01ff6892002-01-18 19:30:15 +0000675 }
676 pXAct->hMem = 0;
Eric Pouech6a03ac02001-06-22 23:02:48 +0000677
Eric Pouech78a41342001-08-09 22:07:22 +0000678 WDML_PostAck(pConv, WDML_SERVER_SIDE, 0, FALSE, fAck, pXAct->atom, pXAct->lParam, WM_DDE_ADVISE);
679
680 WDML_DecHSZ(pConv->instance, pXAct->hszItem);
681
682 return WDML_QS_HANDLED;
683}
684
685/******************************************************************
686 * WDML_ServerQueueUnadvise
687 *
688 *
689 */
690static WDML_XACT* WDML_ServerQueueUnadvise(WDML_CONV* pConv, LPARAM lParam)
691{
Dmitry Timoshkov37d39962003-05-19 23:27:16 +0000692 UINT_PTR uiLo, uiHi;
Eric Pouech78a41342001-08-09 22:07:22 +0000693 WDML_XACT* pXAct;
694
695 UnpackDDElParam(WM_DDE_UNADVISE, lParam, &uiLo, &uiHi);
Vincent Béron9a624912002-05-31 23:06:46 +0000696
697 pXAct = WDML_AllocTransaction(pConv->instance, WM_DDE_UNADVISE,
Eric Pouech78a41342001-08-09 22:07:22 +0000698 uiLo, WDML_MakeHszFromAtom(pConv->instance, uiHi));
699 if (pXAct) pXAct->atom = uiHi;
700 return pXAct;
Eric Pouech6a03ac02001-06-22 23:02:48 +0000701}
702
703/******************************************************************
704 * WDML_ServerHandleUnadvise
705 *
706 *
707 */
Eric Pouech78a41342001-08-09 22:07:22 +0000708static WDML_QUEUE_STATE WDML_ServerHandleUnadvise(WDML_CONV* pConv, WDML_XACT* pXAct)
Eric Pouech6a03ac02001-06-22 23:02:48 +0000709{
Eric Pouech78a41342001-08-09 22:07:22 +0000710 WDML_LINK* pLink;
Eric Pouech6a03ac02001-06-22 23:02:48 +0000711
Francois Gougetd2667a42002-12-02 18:10:57 +0000712 if (pXAct->hszItem == NULL || pXAct->wFmt == 0)
Eric Pouech6a03ac02001-06-22 23:02:48 +0000713 {
Eric Pouech78a41342001-08-09 22:07:22 +0000714 ERR("Unsupported yet options (null item or clipboard format)\n");
715 return WDML_QS_ERROR;
Eric Pouech6a03ac02001-06-22 23:02:48 +0000716 }
717
Vincent Béron9a624912002-05-31 23:06:46 +0000718 pLink = WDML_FindLink(pConv->instance, (HCONV)pConv, WDML_SERVER_SIDE,
Eric Pouech01ff6892002-01-18 19:30:15 +0000719 pXAct->hszItem, TRUE, pXAct->wFmt);
Eric Pouech6a03ac02001-06-22 23:02:48 +0000720 if (pLink == NULL)
721 {
Dmitry Timoshkov37d39962003-05-19 23:27:16 +0000722 ERR("Couln'd find link for %p, dropping request\n", pXAct->hszItem);
Eric Pouech78a41342001-08-09 22:07:22 +0000723 FreeDDElParam(WM_DDE_UNADVISE, pXAct->lParam);
724 return WDML_QS_ERROR;
Eric Pouech6a03ac02001-06-22 23:02:48 +0000725 }
726
Eric Pouech78a41342001-08-09 22:07:22 +0000727 if (!(pConv->instance->CBFflags & CBF_FAIL_ADVISES))
Eric Pouech6a03ac02001-06-22 23:02:48 +0000728 {
Vincent Béron9a624912002-05-31 23:06:46 +0000729 WDML_InvokeCallback(pConv->instance, XTYP_ADVSTOP, pXAct->wFmt, (HCONV)pConv,
Eric Pouech78a41342001-08-09 22:07:22 +0000730 pConv->hszTopic, pXAct->hszItem, 0, 0, 0);
Eric Pouech6a03ac02001-06-22 23:02:48 +0000731 }
Vincent Béron9a624912002-05-31 23:06:46 +0000732
733 WDML_RemoveLink(pConv->instance, (HCONV)pConv, WDML_SERVER_SIDE,
Eric Pouech78a41342001-08-09 22:07:22 +0000734 pXAct->hszItem, pXAct->wFmt);
Vincent Béron9a624912002-05-31 23:06:46 +0000735
Eric Pouech6a03ac02001-06-22 23:02:48 +0000736 /* send back ack */
Vincent Béron9a624912002-05-31 23:06:46 +0000737 WDML_PostAck(pConv, WDML_SERVER_SIDE, 0, FALSE, TRUE, pXAct->atom,
Eric Pouech01ff6892002-01-18 19:30:15 +0000738 pXAct->lParam, WM_DDE_UNADVISE);
Vincent Béron9a624912002-05-31 23:06:46 +0000739
Eric Pouech78a41342001-08-09 22:07:22 +0000740 WDML_DecHSZ(pConv->instance, pXAct->hszItem);
741
742 return WDML_QS_HANDLED;
Eric Pouech6a03ac02001-06-22 23:02:48 +0000743}
744
745/******************************************************************
Eric Pouech78a41342001-08-09 22:07:22 +0000746 * WDML_QueueExecute
747 *
748 *
749 */
750static WDML_XACT* WDML_ServerQueueExecute(WDML_CONV* pConv, LPARAM lParam)
751{
752 WDML_XACT* pXAct;
753
754 pXAct = WDML_AllocTransaction(pConv->instance, WM_DDE_EXECUTE, 0, 0);
755 if (pXAct)
756 {
757 pXAct->hMem = (HGLOBAL)lParam;
758 }
Vincent Béron9a624912002-05-31 23:06:46 +0000759 return pXAct;
Eric Pouech78a41342001-08-09 22:07:22 +0000760}
761
762 /******************************************************************
Eric Pouech6a03ac02001-06-22 23:02:48 +0000763 * WDML_ServerHandleExecute
764 *
765 *
766 */
Eric Pouech78a41342001-08-09 22:07:22 +0000767static WDML_QUEUE_STATE WDML_ServerHandleExecute(WDML_CONV* pConv, WDML_XACT* pXAct)
Eric Pouech6a03ac02001-06-22 23:02:48 +0000768{
Eric Pouech78a41342001-08-09 22:07:22 +0000769 HDDEDATA hDdeData = DDE_FNOTPROCESSED;
770 BOOL fAck = FALSE, fBusy = FALSE;
Eric Pouech6a03ac02001-06-22 23:02:48 +0000771
Eric Pouech78a41342001-08-09 22:07:22 +0000772 if (!(pConv->instance->CBFflags & CBF_FAIL_EXECUTES))
Eric Pouech6a03ac02001-06-22 23:02:48 +0000773 {
Eric Pouech78a41342001-08-09 22:07:22 +0000774 LPVOID ptr = GlobalLock(pXAct->hMem);
Vincent Béron9a624912002-05-31 23:06:46 +0000775
Eric Pouech6a03ac02001-06-22 23:02:48 +0000776 if (ptr)
777 {
Eric Pouech78a41342001-08-09 22:07:22 +0000778 hDdeData = DdeCreateDataHandle(0, ptr, GlobalSize(pXAct->hMem),
Eric Pouech6a03ac02001-06-22 23:02:48 +0000779 0, 0, CF_TEXT, 0);
Eric Pouech78a41342001-08-09 22:07:22 +0000780 GlobalUnlock(pXAct->hMem);
Vincent Béron9a624912002-05-31 23:06:46 +0000781 }
782 hDdeData = WDML_InvokeCallback(pConv->instance, XTYP_EXECUTE, 0, (HCONV)pConv,
Eric Pouech78a41342001-08-09 22:07:22 +0000783 pConv->hszTopic, 0, hDdeData, 0L, 0L);
Eric Pouech6a03ac02001-06-22 23:02:48 +0000784 }
Vincent Béron9a624912002-05-31 23:06:46 +0000785
Dmitry Timoshkov7266da32005-02-01 18:47:55 +0000786 switch ((ULONG_PTR)hDdeData)
Eric Pouech6a03ac02001-06-22 23:02:48 +0000787 {
Dmitry Timoshkov7266da32005-02-01 18:47:55 +0000788 case (ULONG_PTR)CBR_BLOCK:
789 return WDML_QS_BLOCK;
790
Vincent Béron9a624912002-05-31 23:06:46 +0000791 case DDE_FACK:
792 fAck = TRUE;
Eric Pouech6a03ac02001-06-22 23:02:48 +0000793 break;
Vincent Béron9a624912002-05-31 23:06:46 +0000794 case DDE_FBUSY:
795 fBusy = TRUE;
Eric Pouech6a03ac02001-06-22 23:02:48 +0000796 break;
Vincent Béron9a624912002-05-31 23:06:46 +0000797 default:
Dmitry Timoshkov7266da32005-02-01 18:47:55 +0000798 FIXME("Unsupported returned value %p\n", hDdeData);
Francois Gouget588ff372001-08-21 17:07:17 +0000799 /* fall through */
Vincent Béron9a624912002-05-31 23:06:46 +0000800 case DDE_FNOTPROCESSED:
Eric Pouech6a03ac02001-06-22 23:02:48 +0000801 break;
Vincent Béron9a624912002-05-31 23:06:46 +0000802 }
Alexandre Julliarda8a422f2002-11-22 20:43:01 +0000803 WDML_PostAck(pConv, WDML_SERVER_SIDE, 0, fBusy, fAck, (UINT)pXAct->hMem, 0, 0);
Vincent Béron9a624912002-05-31 23:06:46 +0000804
Eric Pouech78a41342001-08-09 22:07:22 +0000805 return WDML_QS_HANDLED;
806}
807
808/******************************************************************
809 * WDML_ServerQueuePoke
810 *
811 *
812 */
813static WDML_XACT* WDML_ServerQueuePoke(WDML_CONV* pConv, LPARAM lParam)
814{
Dmitry Timoshkov37d39962003-05-19 23:27:16 +0000815 UINT_PTR uiLo, uiHi;
Eric Pouech78a41342001-08-09 22:07:22 +0000816 WDML_XACT* pXAct;
817
818 UnpackDDElParam(WM_DDE_POKE, lParam, &uiLo, &uiHi);
819
Vincent Béron9a624912002-05-31 23:06:46 +0000820 pXAct = WDML_AllocTransaction(pConv->instance, WM_DDE_POKE,
Eric Pouech78a41342001-08-09 22:07:22 +0000821 0, WDML_MakeHszFromAtom(pConv->instance, uiHi));
822 if (pXAct)
823 {
824 pXAct->atom = uiHi;
825 pXAct->hMem = (HGLOBAL)uiLo;
826 }
827 return pXAct;
Eric Pouech6a03ac02001-06-22 23:02:48 +0000828}
829
830/******************************************************************
831 * WDML_ServerHandlePoke
832 *
833 *
834 */
Eric Pouech78a41342001-08-09 22:07:22 +0000835static WDML_QUEUE_STATE WDML_ServerHandlePoke(WDML_CONV* pConv, WDML_XACT* pXAct)
Eric Pouech6a03ac02001-06-22 23:02:48 +0000836{
Eric Pouech6a03ac02001-06-22 23:02:48 +0000837 DDEPOKE* pDdePoke;
838 HDDEDATA hDdeData;
Eric Pouech78a41342001-08-09 22:07:22 +0000839 BOOL fBusy = FALSE, fAck = FALSE;
Eric Pouech6a03ac02001-06-22 23:02:48 +0000840
Eric Pouech78a41342001-08-09 22:07:22 +0000841 pDdePoke = (DDEPOKE*)GlobalLock(pXAct->hMem);
Eric Pouech6a03ac02001-06-22 23:02:48 +0000842 if (!pDdePoke)
843 {
Eric Pouech78a41342001-08-09 22:07:22 +0000844 return WDML_QS_ERROR;
Eric Pouech6a03ac02001-06-22 23:02:48 +0000845 }
846
Eric Pouech78a41342001-08-09 22:07:22 +0000847 if (!(pConv->instance->CBFflags & CBF_FAIL_POKES))
Eric Pouech6a03ac02001-06-22 23:02:48 +0000848 {
Vincent Béron9a624912002-05-31 23:06:46 +0000849 hDdeData = DdeCreateDataHandle(pConv->instance->instanceID, pDdePoke->Value,
850 GlobalSize(pXAct->hMem) - sizeof(DDEPOKE) + 1,
Eric Pouech6a03ac02001-06-22 23:02:48 +0000851 0, 0, pDdePoke->cfFormat, 0);
Vincent Béron9a624912002-05-31 23:06:46 +0000852 if (hDdeData)
Eric Pouech6a03ac02001-06-22 23:02:48 +0000853 {
854 HDDEDATA hDdeDataOut;
Vincent Béron9a624912002-05-31 23:06:46 +0000855
856 hDdeDataOut = WDML_InvokeCallback(pConv->instance, XTYP_POKE, pDdePoke->cfFormat,
857 (HCONV)pConv, pConv->hszTopic, pXAct->hszItem,
Eric Pouech78a41342001-08-09 22:07:22 +0000858 hDdeData, 0, 0);
Dmitry Timoshkov37d39962003-05-19 23:27:16 +0000859 switch ((ULONG_PTR)hDdeDataOut)
Eric Pouech6a03ac02001-06-22 23:02:48 +0000860 {
861 case DDE_FACK:
Vincent Béron9a624912002-05-31 23:06:46 +0000862 fAck = TRUE;
Eric Pouech6a03ac02001-06-22 23:02:48 +0000863 break;
864 case DDE_FBUSY:
Eric Pouech78a41342001-08-09 22:07:22 +0000865 fBusy = TRUE;
Eric Pouech6a03ac02001-06-22 23:02:48 +0000866 break;
867 default:
Dmitry Timoshkov37d39962003-05-19 23:27:16 +0000868 FIXME("Unsupported returned value %p\n", hDdeDataOut);
Francois Gouget588ff372001-08-21 17:07:17 +0000869 /* fal through */
Vincent Béron9a624912002-05-31 23:06:46 +0000870 case DDE_FNOTPROCESSED:
Eric Pouech6a03ac02001-06-22 23:02:48 +0000871 break;
872 }
873 DdeFreeDataHandle(hDdeData);
874 }
875 }
Eric Pouech78a41342001-08-09 22:07:22 +0000876 GlobalUnlock(pXAct->hMem);
Vincent Béron9a624912002-05-31 23:06:46 +0000877
Eric Pouech78a41342001-08-09 22:07:22 +0000878 if (!fAck)
Eric Pouech01ff6892002-01-18 19:30:15 +0000879 {
Eric Pouech78a41342001-08-09 22:07:22 +0000880 GlobalFree(pXAct->hMem);
Eric Pouech01ff6892002-01-18 19:30:15 +0000881 }
Eric Pouech78a41342001-08-09 22:07:22 +0000882 WDML_PostAck(pConv, WDML_SERVER_SIDE, 0, fBusy, fAck, pXAct->atom, pXAct->lParam, WM_DDE_POKE);
Eric Pouech6a03ac02001-06-22 23:02:48 +0000883
Eric Pouech78a41342001-08-09 22:07:22 +0000884 WDML_DecHSZ(pConv->instance, pXAct->hszItem);
885
886 return WDML_QS_HANDLED;
887}
888
889/******************************************************************
890 * WDML_ServerQueueTerminate
891 *
892 *
893 */
894static WDML_XACT* WDML_ServerQueueTerminate(WDML_CONV* pConv, LPARAM lParam)
895{
896 WDML_XACT* pXAct;
897
898 pXAct = WDML_AllocTransaction(pConv->instance, WM_DDE_TERMINATE, 0, 0);
899 return pXAct;
Eric Pouech6a03ac02001-06-22 23:02:48 +0000900}
901
902/******************************************************************
903 * WDML_ServerHandleTerminate
904 *
905 *
906 */
Eric Pouech78a41342001-08-09 22:07:22 +0000907static WDML_QUEUE_STATE WDML_ServerHandleTerminate(WDML_CONV* pConv, WDML_XACT* pXAct)
Eric Pouech6a03ac02001-06-22 23:02:48 +0000908{
Eric Pouech6a03ac02001-06-22 23:02:48 +0000909 /* billx: two things to remove: the conv, and associated links.
Eric Pouech78a41342001-08-09 22:07:22 +0000910 * Respond with another WM_DDE_TERMINATE iMsg.
911 */
912 if (!(pConv->instance->CBFflags & CBF_SKIP_DISCONNECTS))
913 {
Vincent Béron9a624912002-05-31 23:06:46 +0000914 WDML_InvokeCallback(pConv->instance, XTYP_DISCONNECT, 0, (HCONV)pConv, 0, 0,
Eric Pouech78a41342001-08-09 22:07:22 +0000915 0, 0, (pConv->wStatus & ST_ISSELF) ? 1 : 0);
916 }
Dmitry Timoshkovca7b25c2005-02-14 11:53:15 +0000917 PostMessageW(pConv->hwndClient, WM_DDE_TERMINATE, (WPARAM)pConv->hwndServer, 0);
Eric Pouech78a41342001-08-09 22:07:22 +0000918 WDML_RemoveConv(pConv, WDML_SERVER_SIDE);
Vincent Béron9a624912002-05-31 23:06:46 +0000919
Eric Pouech78a41342001-08-09 22:07:22 +0000920 return WDML_QS_HANDLED;
921}
922
923/******************************************************************
924 * WDML_ServerHandle
925 *
926 *
927 */
Dmitry Timoshkov37d39962003-05-19 23:27:16 +0000928WDML_QUEUE_STATE WDML_ServerHandle(WDML_CONV* pConv, WDML_XACT* pXAct)
Eric Pouech78a41342001-08-09 22:07:22 +0000929{
930 WDML_QUEUE_STATE qs = WDML_QS_ERROR;
931
932 switch (pXAct->ddeMsg)
933 {
934 case WM_DDE_INITIATE:
935 FIXME("WM_DDE_INITIATE shouldn't be there!\n");
936 break;
937 case WM_DDE_REQUEST:
938 qs = WDML_ServerHandleRequest(pConv, pXAct);
939 break;
Vincent Béron9a624912002-05-31 23:06:46 +0000940
Eric Pouech78a41342001-08-09 22:07:22 +0000941 case WM_DDE_ADVISE:
942 qs = WDML_ServerHandleAdvise(pConv, pXAct);
943 break;
Vincent Béron9a624912002-05-31 23:06:46 +0000944
Eric Pouech78a41342001-08-09 22:07:22 +0000945 case WM_DDE_UNADVISE:
946 qs = WDML_ServerHandleUnadvise(pConv, pXAct);
947 break;
Vincent Béron9a624912002-05-31 23:06:46 +0000948
Eric Pouech78a41342001-08-09 22:07:22 +0000949 case WM_DDE_EXECUTE:
950 qs = WDML_ServerHandleExecute(pConv, pXAct);
951 break;
Vincent Béron9a624912002-05-31 23:06:46 +0000952
Eric Pouech78a41342001-08-09 22:07:22 +0000953 case WM_DDE_POKE:
954 qs = WDML_ServerHandlePoke(pConv, pXAct);
955 break;
Vincent Béron9a624912002-05-31 23:06:46 +0000956
Eric Pouech78a41342001-08-09 22:07:22 +0000957 case WM_DDE_TERMINATE:
958 qs = WDML_ServerHandleTerminate(pConv, pXAct);
959 break;
960
961 case WM_DDE_ACK:
962 WARN("Shouldn't receive a ACK message (never requests them). Ignoring it\n");
963 break;
964
965 default:
966 FIXME("Unsupported message %d\n", pXAct->ddeMsg);
967 }
968 return qs;
Eric Pouech6a03ac02001-06-22 23:02:48 +0000969}
970
971/******************************************************************
972 * WDML_ServerConvProc
973 *
974 *
975 */
976static LRESULT CALLBACK WDML_ServerConvProc(HWND hwndServer, UINT iMsg, WPARAM wParam, LPARAM lParam)
977{
Eric Pouech78a41342001-08-09 22:07:22 +0000978 WDML_INSTANCE* pInstance;
Eric Pouech6a03ac02001-06-22 23:02:48 +0000979 WDML_CONV* pConv;
Eric Pouech78a41342001-08-09 22:07:22 +0000980 WDML_XACT* pXAct = NULL;
Eric Pouech6a03ac02001-06-22 23:02:48 +0000981
Dmitry Timoshkov3c9e7a72007-05-24 23:41:17 +0900982 TRACE("%p %04x %08lx %08lx\n", hwndServer, iMsg, wParam, lParam);
Dmitry Timoshkov7266da32005-02-01 18:47:55 +0000983
Eric Pouech78a41342001-08-09 22:07:22 +0000984 if (iMsg == WM_DESTROY)
985 {
Eric Pouech78a41342001-08-09 22:07:22 +0000986 pConv = WDML_GetConvFromWnd(hwndServer);
987 if (pConv && !(pConv->wStatus & ST_TERMINATED))
988 {
989 WDML_ServerHandleTerminate(pConv, NULL);
990 }
Eric Pouech78a41342001-08-09 22:07:22 +0000991 }
Eric Pouech6a03ac02001-06-22 23:02:48 +0000992 if (iMsg < WM_DDE_FIRST || iMsg > WM_DDE_LAST)
993 {
Dmitry Timoshkov87458a52005-07-08 11:33:09 +0000994 return IsWindowUnicode(hwndServer) ? DefWindowProcW(hwndServer, iMsg, wParam, lParam) :
995 DefWindowProcA(hwndServer, iMsg, wParam, lParam);
Eric Pouech6a03ac02001-06-22 23:02:48 +0000996 }
997
Eric Pouech78a41342001-08-09 22:07:22 +0000998 pInstance = WDML_GetInstanceFromWnd(hwndServer);
999 pConv = WDML_GetConvFromWnd(hwndServer);
1000
Vincent Béron9a624912002-05-31 23:06:46 +00001001 if (!pConv)
Eric Pouech6a03ac02001-06-22 23:02:48 +00001002 {
Dmitry Timoshkov37d39962003-05-19 23:27:16 +00001003 ERR("Got a message (%x) on a not known conversation, dropping request\n", iMsg);
Dmitry Timoshkova3722bf2006-11-15 21:22:35 +08001004 return 0;
Eric Pouech78a41342001-08-09 22:07:22 +00001005 }
Alexandre Julliardf44bbb82001-09-14 00:24:39 +00001006 if (pConv->hwndClient != WIN_GetFullHandle( (HWND)wParam ) || pConv->hwndServer != hwndServer)
Eric Pouech78a41342001-08-09 22:07:22 +00001007 {
1008 ERR("mismatch between C/S windows and converstation\n");
Dmitry Timoshkova3722bf2006-11-15 21:22:35 +08001009 return 0;
Eric Pouech78a41342001-08-09 22:07:22 +00001010 }
1011 if (pConv->instance != pInstance || pConv->instance == NULL)
1012 {
1013 ERR("mismatch in instances\n");
Dmitry Timoshkova3722bf2006-11-15 21:22:35 +08001014 return 0;
Eric Pouech6a03ac02001-06-22 23:02:48 +00001015 }
1016
Eric Pouech6a03ac02001-06-22 23:02:48 +00001017 switch (iMsg)
1018 {
1019 case WM_DDE_INITIATE:
Eric Pouech78a41342001-08-09 22:07:22 +00001020 FIXME("WM_DDE_INITIATE message received!\n");
Eric Pouech6a03ac02001-06-22 23:02:48 +00001021 break;
Vincent Béron9a624912002-05-31 23:06:46 +00001022
Eric Pouech6a03ac02001-06-22 23:02:48 +00001023 case WM_DDE_REQUEST:
Eric Pouech78a41342001-08-09 22:07:22 +00001024 pXAct = WDML_ServerQueueRequest(pConv, lParam);
Eric Pouech6a03ac02001-06-22 23:02:48 +00001025 break;
Vincent Béron9a624912002-05-31 23:06:46 +00001026
Eric Pouech6a03ac02001-06-22 23:02:48 +00001027 case WM_DDE_ADVISE:
Eric Pouech78a41342001-08-09 22:07:22 +00001028 pXAct = WDML_ServerQueueAdvise(pConv, lParam);
Eric Pouech6a03ac02001-06-22 23:02:48 +00001029 break;
Vincent Béron9a624912002-05-31 23:06:46 +00001030
Eric Pouech6a03ac02001-06-22 23:02:48 +00001031 case WM_DDE_UNADVISE:
Eric Pouech78a41342001-08-09 22:07:22 +00001032 pXAct = WDML_ServerQueueUnadvise(pConv, lParam);
Eric Pouech6a03ac02001-06-22 23:02:48 +00001033 break;
Vincent Béron9a624912002-05-31 23:06:46 +00001034
Eric Pouech6a03ac02001-06-22 23:02:48 +00001035 case WM_DDE_EXECUTE:
Eric Pouech78a41342001-08-09 22:07:22 +00001036 pXAct = WDML_ServerQueueExecute(pConv, lParam);
Eric Pouech6a03ac02001-06-22 23:02:48 +00001037 break;
Vincent Béron9a624912002-05-31 23:06:46 +00001038
Eric Pouech6a03ac02001-06-22 23:02:48 +00001039 case WM_DDE_POKE:
Eric Pouech78a41342001-08-09 22:07:22 +00001040 pXAct = WDML_ServerQueuePoke(pConv, lParam);
Eric Pouech6a03ac02001-06-22 23:02:48 +00001041 break;
Vincent Béron9a624912002-05-31 23:06:46 +00001042
Eric Pouech6a03ac02001-06-22 23:02:48 +00001043 case WM_DDE_TERMINATE:
Eric Pouech78a41342001-08-09 22:07:22 +00001044 pXAct = WDML_ServerQueueTerminate(pConv, lParam);
Eric Pouech6a03ac02001-06-22 23:02:48 +00001045 break;
1046
1047 case WM_DDE_ACK:
1048 WARN("Shouldn't receive a ACK message (never requests them). Ignoring it\n");
1049 break;
1050
1051 default:
Dmitry Timoshkov37d39962003-05-19 23:27:16 +00001052 FIXME("Unsupported message %x\n", iMsg);
Dmitry Timoshkov3a7bd672006-11-21 14:43:48 +08001053 break;
Eric Pouech6a03ac02001-06-22 23:02:48 +00001054 }
Vincent Béron9a624912002-05-31 23:06:46 +00001055
1056 if (pXAct)
Eric Pouech78a41342001-08-09 22:07:22 +00001057 {
1058 pXAct->lParam = lParam;
Dmitry Timoshkov3a7bd672006-11-21 14:43:48 +08001059
1060 if ((pConv->wStatus & ST_BLOCKED) || WDML_ServerHandle(pConv, pXAct) == WDML_QS_BLOCK)
Eric Pouech78a41342001-08-09 22:07:22 +00001061 {
Dmitry Timoshkov3a7bd672006-11-21 14:43:48 +08001062 TRACE("Transactions are blocked, add to the queue and exit\n");
Eric Pouech78a41342001-08-09 22:07:22 +00001063 WDML_QueueTransaction(pConv, pXAct);
1064 }
1065 else
1066 {
1067 WDML_FreeTransaction(pInstance, pXAct, TRUE);
1068 }
1069 }
Dmitry Timoshkov3a7bd672006-11-21 14:43:48 +08001070 else
1071 pConv->instance->lastError = DMLERR_MEMORY_ERROR;
Dmitry Timoshkova3722bf2006-11-15 21:22:35 +08001072
Eric Pouech6a03ac02001-06-22 23:02:48 +00001073 return 0;
1074}