~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/user32/dde_server.c

Version: ~ [ wine-1.5.30 ] ~ [ wine-1.5.29 ] ~ [ wine-1.5.28 ] ~ [ wine-1.5.27 ] ~ [ wine-1.5.26 ] ~ [ wine-1.5.25 ] ~ [ wine-1.5.24 ] ~ [ wine-1.5.23 ] ~ [ wine-1.5.22 ] ~ [ wine-1.5.21 ] ~ [ wine-1.5.20 ] ~ [ wine-1.5.19 ] ~ [ wine-1.5.18 ] ~ [ wine-1.5.17 ] ~ [ wine-1.5.16 ] ~ [ wine-1.5.15 ] ~ [ wine-1.5.14 ] ~ [ wine-1.5.13 ] ~ [ wine-1.5.12 ] ~ [ wine-1.5.11 ] ~ [ wine-1.5.10 ] ~ [ wine-1.5.9 ] ~ [ wine-1.5.8 ] ~ [ wine-1.5.7 ] ~ [ wine-1.4.1 ] ~ [ wine-1.5.6 ] ~ [ wine-1.5.5 ] ~ [ wine-1.5.4 ] ~ [ wine-1.5.3 ] ~ [ wine-1.5.2 ] ~ [ wine-1.5.1 ] ~ [ wine-1.5.0 ] ~ [ wine-1.4 ] ~ [ wine-1.4-rc6 ] ~ [ wine-1.4-rc5 ] ~ [ wine-1.4-rc4 ] ~ [ wine-1.4-rc3 ] ~ [ wine-1.4-rc2 ] ~ [ wine-1.4-rc1 ] ~ [ wine-1.3.37 ] ~ [ wine-1.3.36 ] ~ [ wine-1.3.35 ] ~ [ wine-1.3.34 ] ~ [ wine-1.3.33 ] ~ [ wine-1.3.32 ] ~ [ wine-1.3.31 ] ~ [ wine-1.3.30 ] ~ [ wine-1.3.29 ] ~ [ wine-1.3.28 ] ~ [ wine-1.3.27 ] ~ [ wine-1.3.26 ] ~ [ wine-1.3.25 ] ~ [ wine-1.3.24 ] ~ [ wine-1.3.23 ] ~ [ wine-1.3.22 ] ~ [ wine-1.3.21 ] ~ [ wine-1.3.20 ] ~ [ wine-1.3.19 ] ~ [ wine-1.3.18 ] ~ [ wine-1.2.3 ] ~ [ wine-1.3.17 ] ~ [ wine-1.3.16 ] ~ [ wine-1.3.15 ] ~ [ wine-1.3.14 ] ~ [ wine-1.3.13 ] ~ [ wine-1.3.12 ] ~ [ wine-1.3.11 ] ~ [ wine-1.3.10 ] ~ [ wine-1.3.9 ] ~ [ wine-1.2.2 ] ~ [ wine-1.3.8 ] ~ [ wine-1.3.7 ] ~ [ wine-1.3.6 ] ~ [ wine-1.3.5 ] ~ [ wine-1.2.1 ] ~ [ wine-1.3.4 ] ~ [ wine-1.3.3 ] ~ [ wine-1.3.2 ] ~ [ wine-1.3.1 ] ~ [ wine-1.3.0 ] ~ [ wine-1.2 ] ~ [ wine-1.2-rc7 ] ~ [ wine-1.2-rc6 ] ~ [ wine-1.2-rc5 ] ~ [ wine-1.2-rc4 ] ~ [ wine-1.2-rc3 ] ~ [ wine-1.2-rc2 ] ~ [ wine-1.2-rc1 ] ~ [ wine-1.1.44 ] ~ [ wine-1.1.43 ] ~ [ wine-1.1.42 ] ~ [ wine-1.1.41 ] ~ [ wine-1.1.40 ] ~ [ wine-1.1.39 ] ~ [ wine-1.1.38 ] ~ [ wine-1.1.37 ] ~ [ wine-1.1.36 ] ~ [ wine-1.1.35 ] ~ [ wine-1.1.34 ] ~ [ wine-1.1.33 ] ~ [ wine-1.1.32 ] ~ [ wine-1.1.31 ] ~ [ wine-1.1.30 ] ~ [ wine-1.1.29 ] ~ [ wine-1.1.28 ] ~ [ wine-1.1.27 ] ~ [ wine-1.1.26 ] ~ [ wine-1.1.25 ] ~ [ wine-1.1.24 ] ~ [ wine-1.1.23 ] ~ [ wine-1.1.22 ] ~ [ wine-1.1.21 ] ~ [ wine-1.1.20 ] ~ [ wine-1.1.19 ] ~ [ wine-1.1.18 ] ~ [ wine-1.1.17 ] ~ [ wine-1.1.16 ] ~ [ wine-1.1.15 ] ~ [ wine-1.1.14 ] ~ [ wine-1.1.13 ] ~ [ wine-1.1.12 ] ~ [ wine-1.1.11 ] ~ [ wine-1.1.10 ] ~ [ wine-1.1.9 ] ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~

  1 /*
  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
  9  * Copyright 2003, 2004, 2005 Dmitry Timoshkov
 10  *
 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
 23  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 24  */
 25 
 26 #include <stdarg.h>
 27 #include <string.h>
 28 #include "windef.h"
 29 #include "winbase.h"
 30 #include "wingdi.h"
 31 #include "winuser.h"
 32 #include "winnls.h"
 33 #include "dde.h"
 34 #include "ddeml.h"
 35 #include "win.h"
 36 #include "wine/unicode.h"
 37 #include "wine/debug.h"
 38 #include "dde_private.h"
 39 
 40 WINE_DEFAULT_DEBUG_CHANNEL(ddeml);
 41 
 42 static const WCHAR szServerNameClass[] = {'W','i','n','e','D','d','e','S','e','r','v','e','r','N','a','m','e',0};
 43 const char WDML_szServerConvClassA[] = "WineDdeServerConvA";
 44 const WCHAR WDML_szServerConvClassW[] = {'W','i','n','e','D','d','e','S','e','r','v','e','r','C','o','n','v','W',0};
 45 
 46 static LRESULT CALLBACK WDML_ServerNameProc(HWND, UINT, WPARAM, LPARAM);
 47 static LRESULT CALLBACK WDML_ServerConvProc(HWND, UINT, WPARAM, LPARAM);
 48 
 49 /******************************************************************************
 50  * DdePostAdvise [USER32.@]  Send transaction to DDE callback function.
 51  *
 52  * PARAMS
 53  *      idInst    [I] Instance identifier
 54  *      hszTopic  [I] Handle to topic name string
 55  *      hszItem   [I] Handle to item name string
 56  *
 57  * RETURNS
 58  *    Success: TRUE
 59  *    Failure: FALSE
 60  */
 61 BOOL WINAPI DdePostAdvise(DWORD idInst, HSZ hszTopic, HSZ hszItem)
 62 {
 63     WDML_INSTANCE*      pInstance = NULL;
 64     WDML_LINK*          pLink = NULL;
 65     HDDEDATA            hDdeData = 0;
 66     HGLOBAL             hItemData = 0;
 67     WDML_CONV*          pConv = NULL;
 68     ATOM                atom = 0;
 69     UINT                count;
 70 
 71     TRACE("(%d,%p,%p)\n", idInst, hszTopic, hszItem);
 72 
 73     pInstance = WDML_GetInstance(idInst);
 74 
 75     if (pInstance == NULL)
 76         return FALSE;
 77 
 78     atom = WDML_MakeAtomFromHsz(hszItem);
 79     if (!atom) return FALSE;
 80 
 81     /* first compute the number of links which will trigger a message */
 82     count = 0;
 83     for (pLink = pInstance->links[WDML_SERVER_SIDE]; pLink != NULL; pLink = pLink->next)
 84     {
 85         if (DdeCmpStringHandles(hszItem, pLink->hszItem) == 0)
 86         {
 87             count++;
 88         }
 89     }
 90     if (count >= CADV_LATEACK)
 91     {
 92         FIXME("too high value for count\n");
 93         count &= 0xFFFF;
 94     }
 95 
 96     for (pLink = pInstance->links[WDML_SERVER_SIDE]; pLink != NULL; pLink = pLink->next)
 97     {
 98         if (DdeCmpStringHandles(hszItem, pLink->hszItem) == 0)
 99         {
100             hDdeData = WDML_InvokeCallback(pInstance, XTYP_ADVREQ, pLink->uFmt, pLink->hConv,
101                                            hszTopic, hszItem, 0, --count, 0);
102 
103             if (hDdeData == CBR_BLOCK)
104             {
105                 /* MS doc is not consistent here */
106                 FIXME("CBR_BLOCK returned for ADVREQ\n");
107                 continue;
108             }
109             if (hDdeData)
110             {
111                 if (pLink->transactionType & XTYPF_NODATA)
112                 {
113                     TRACE("no data\n");
114                     hItemData = 0;
115                 }
116                 else
117                 {
118                     TRACE("with data\n");
119 
120                     hItemData = WDML_DataHandle2Global(hDdeData, FALSE, FALSE, FALSE, FALSE);
121                 }
122 
123                 pConv = WDML_GetConv(pLink->hConv, TRUE);
124 
125                 if (pConv == NULL)
126                 {
127                     if (!WDML_IsAppOwned(hDdeData))  DdeFreeDataHandle(hDdeData);
128                     goto theError;
129                 }
130 
131                 if (!PostMessageW(pConv->hwndClient, WM_DDE_DATA, (WPARAM)pConv->hwndServer,
132                                   PackDDElParam(WM_DDE_DATA, (UINT_PTR)hItemData, atom)))
133                 {
134                     ERR("post message failed\n");
135                     pConv->wStatus &= ~ST_CONNECTED;
136                     pConv->instance->lastError = DMLERR_POSTMSG_FAILED;
137                     if (!WDML_IsAppOwned(hDdeData))  DdeFreeDataHandle(hDdeData);
138                     GlobalFree(hItemData);
139                     goto theError;
140                 }
141                 if (!WDML_IsAppOwned(hDdeData))  DdeFreeDataHandle(hDdeData);
142             }
143         }
144     }
145     return TRUE;
146 
147  theError:
148     GlobalDeleteAtom(atom);
149     return FALSE;
150 }
151 
152 
153 /******************************************************************************
154  * DdeNameService [USER32.@]  {Un}registers service name of DDE server
155  *
156  * PARAMS
157  *    idInst [I] Instance identifier
158  *    hsz1   [I] Handle to service name string
159  *    hsz2   [I] Reserved
160  *    afCmd  [I] Service name flags
161  *
162  * RETURNS
163  *    Success: Non-zero
164  *    Failure: 0
165  */
166 HDDEDATA WINAPI DdeNameService(DWORD idInst, HSZ hsz1, HSZ hsz2, UINT afCmd)
167 {
168     WDML_SERVER*        pServer;
169     WDML_INSTANCE*      pInstance;
170     HWND                hwndServer;
171     WNDCLASSEXW         wndclass;
172 
173     TRACE("(%d,%p,%p,%x)\n", idInst, hsz1, hsz2, afCmd);
174 
175     /*  First check instance
176      */
177     pInstance = WDML_GetInstance(idInst);
178     if  (pInstance == NULL)
179     {
180         TRACE("Instance not found as initialised\n");
181         /*  Nothing has been initialised - exit now ! can return TRUE since effect is the same */
182         return NULL;
183     }
184 
185     if (hsz2 != 0L)
186     {
187         /*      Illegal, reserved parameter
188          */
189         pInstance->lastError = DMLERR_INVALIDPARAMETER;
190         WARN("Reserved parameter no-zero !!\n");
191         return NULL;
192     }
193     if (hsz1 == 0 && !(afCmd & DNS_UNREGISTER))
194     {
195         /*      don't know if we should check this but it makes sense
196          *      why supply REGISTER or filter flags if de-registering all
197          */
198         TRACE("General unregister unexpected flags\n");
199         pInstance->lastError = DMLERR_INVALIDPARAMETER;
200         return NULL;
201     }
202 
203     switch (afCmd & (DNS_REGISTER | DNS_UNREGISTER))
204     {
205     case DNS_REGISTER:
206         pServer = WDML_FindServer(pInstance, hsz1, 0);
207         if (pServer)
208         {
209             ERR("Trying to register already registered service!\n");
210             pInstance->lastError = DMLERR_DLL_USAGE;
211             return NULL;
212         }
213 
214         TRACE("Adding service name\n");
215 
216         WDML_IncHSZ(pInstance, hsz1);
217 
218         pServer = WDML_AddServer(pInstance, hsz1, 0);
219 
220         WDML_BroadcastDDEWindows(WDML_szEventClass, WM_WDML_REGISTER,
221                                  pServer->atomService, pServer->atomServiceSpec);
222 
223         wndclass.cbSize        = sizeof(wndclass);
224         wndclass.style         = 0;
225         wndclass.lpfnWndProc   = WDML_ServerNameProc;
226         wndclass.cbClsExtra    = 0;
227         wndclass.cbWndExtra    = 2 * sizeof(ULONG_PTR);
228         wndclass.hInstance     = 0;
229         wndclass.hIcon         = 0;
230         wndclass.hCursor       = 0;
231         wndclass.hbrBackground = 0;
232         wndclass.lpszMenuName  = NULL;
233         wndclass.lpszClassName = szServerNameClass;
234         wndclass.hIconSm       = 0;
235 
236         RegisterClassExW(&wndclass);
237 
238         hwndServer = CreateWindowW(szServerNameClass, NULL,
239                                    WS_POPUP, 0, 0, 0, 0,
240                                    0, 0, 0, 0);
241 
242         SetWindowLongPtrW(hwndServer, GWL_WDML_INSTANCE, (ULONG_PTR)pInstance);
243         SetWindowLongPtrW(hwndServer, GWL_WDML_SERVER, (ULONG_PTR)pServer);
244         TRACE("Created nameServer=%p for instance=%08x\n", hwndServer, idInst);
245 
246         pServer->hwndServer = hwndServer;
247         break;
248 
249     case DNS_UNREGISTER:
250         if (hsz1 == 0L)
251         {
252             /* General unregister situation
253              * terminate all server side pending conversations
254              */
255             while (pInstance->servers)
256                 WDML_RemoveServer(pInstance, pInstance->servers->hszService, 0);
257             pInstance->servers = NULL;
258             TRACE("General de-register - finished\n");
259         }
260         else
261         {
262             WDML_RemoveServer(pInstance, hsz1, 0L);
263         }
264         break;
265     }
266 
267     if (afCmd & (DNS_FILTERON | DNS_FILTEROFF))
268     {
269         /*      Set filter flags on to hold notifications of connection
270          */
271         pServer = WDML_FindServer(pInstance, hsz1, 0);
272         if (!pServer)
273         {
274             /*  trying to filter where no service names !!
275              */
276             pInstance->lastError = DMLERR_DLL_USAGE;
277             return NULL;
278         }
279         else
280         {
281             pServer->filterOn = (afCmd & DNS_FILTERON) != 0;
282         }
283     }
284     return (HDDEDATA)TRUE;
285 }
286 
287 /******************************************************************
288  *              WDML_CreateServerConv
289  *
290  *
291  */
292 static WDML_CONV* WDML_CreateServerConv(WDML_INSTANCE* pInstance, HWND hwndClient,
293                                         HWND hwndServerName, HSZ hszApp, HSZ hszTopic)
294 {
295     HWND        hwndServerConv;
296     WDML_CONV*  pConv;
297 
298     if (pInstance->unicode)
299     {
300         WNDCLASSEXW wndclass;
301 
302         wndclass.cbSize        = sizeof(wndclass);
303         wndclass.style         = 0;
304         wndclass.lpfnWndProc   = WDML_ServerConvProc;
305         wndclass.cbClsExtra    = 0;
306         wndclass.cbWndExtra    = 2 * sizeof(ULONG_PTR);
307         wndclass.hInstance     = 0;
308         wndclass.hIcon         = 0;
309         wndclass.hCursor       = 0;
310         wndclass.hbrBackground = 0;
311         wndclass.lpszMenuName  = NULL;
312         wndclass.lpszClassName = WDML_szServerConvClassW;
313         wndclass.hIconSm       = 0;
314 
315         RegisterClassExW(&wndclass);
316 
317         hwndServerConv = CreateWindowW(WDML_szServerConvClassW, 0,
318                                        WS_CHILD, 0, 0, 0, 0,
319                                        hwndServerName, 0, 0, 0);
320     }
321     else
322     {
323         WNDCLASSEXA wndclass;
324 
325         wndclass.cbSize        = sizeof(wndclass);
326         wndclass.style         = 0;
327         wndclass.lpfnWndProc   = WDML_ServerConvProc;
328         wndclass.cbClsExtra    = 0;
329         wndclass.cbWndExtra    = 2 * sizeof(ULONG_PTR);
330         wndclass.hInstance     = 0;
331         wndclass.hIcon         = 0;
332         wndclass.hCursor       = 0;
333         wndclass.hbrBackground = 0;
334         wndclass.lpszMenuName  = NULL;
335         wndclass.lpszClassName = WDML_szServerConvClassA;
336         wndclass.hIconSm       = 0;
337 
338         RegisterClassExA(&wndclass);
339 
340         hwndServerConv = CreateWindowA(WDML_szServerConvClassA, 0,
341                                       WS_CHILD, 0, 0, 0, 0,
342                                       hwndServerName, 0, 0, 0);
343     }
344 
345     TRACE("Created convServer=%p (nameServer=%p) for instance=%08x unicode=%d\n",
346           hwndServerConv, hwndServerName, pInstance->instanceID, pInstance->unicode);
347 
348     pConv = WDML_AddConv(pInstance, WDML_SERVER_SIDE, hszApp, hszTopic,
349                          hwndClient, hwndServerConv);
350     if (pConv)
351     {
352         SetWindowLongPtrW(hwndServerConv, GWL_WDML_INSTANCE, (ULONG_PTR)pInstance);
353         SetWindowLongPtrW(hwndServerConv, GWL_WDML_CONVERSATION, (ULONG_PTR)pConv);
354 
355         /* this should be the only place using SendMessage for WM_DDE_ACK */
356         /* note: sent messages shall not use packing */
357         SendMessageW(hwndClient, WM_DDE_ACK, (WPARAM)hwndServerConv,
358                      MAKELPARAM(WDML_MakeAtomFromHsz(hszApp), WDML_MakeAtomFromHsz(hszTopic)));
359         /* we assume we're connected since we've sent an answer...
360          * I'm not sure what we can do... it doesn't look like the return value
361          * of SendMessage is used... sigh...
362          */
363         pConv->wStatus |= ST_CONNECTED;
364     }
365     else
366     {
367         DestroyWindow(hwndServerConv);
368     }
369     return pConv;
370 }
371 
372 /******************************************************************
373  *              WDML_ServerNameProc
374  *
375  *
376  */
377 static LRESULT CALLBACK WDML_ServerNameProc(HWND hwndServer, UINT iMsg, WPARAM wParam, LPARAM lParam)
378 {
379     HWND                hwndClient;
380     HSZ                 hszApp, hszTop;
381     HDDEDATA            hDdeData = 0;
382     WDML_INSTANCE*      pInstance;
383     UINT_PTR            uiLo, uiHi;
384 
385     switch (iMsg)
386     {
387     case WM_DDE_INITIATE:
388 
389         /* wParam         -- sending window handle
390            LOWORD(lParam) -- application atom
391            HIWORD(lParam) -- topic atom */
392 
393         TRACE("WM_DDE_INITIATE message received!\n");
394         hwndClient = (HWND)wParam;
395 
396         pInstance = WDML_GetInstanceFromWnd(hwndServer);
397         if (!pInstance) return 0;
398         TRACE("idInst=%d, threadID=0x%x\n", pInstance->instanceID, GetCurrentThreadId());
399 
400         /* don't free DDEParams, since this is a broadcast */
401         UnpackDDElParam(WM_DDE_INITIATE, lParam, &uiLo, &uiHi);
402 
403         hszApp = WDML_MakeHszFromAtom(pInstance, uiLo);
404         hszTop = WDML_MakeHszFromAtom(pInstance, uiHi);
405 
406         if (!(pInstance->CBFflags & CBF_FAIL_CONNECTIONS))
407         {
408             BOOL                self = FALSE;
409             CONVCONTEXT         cc;
410             CONVCONTEXT*        pcc = NULL;
411             WDML_CONV*          pConv;
412             char                buf[256];
413 
414             if (GetWindowThreadProcessId(hwndClient, NULL) == GetWindowThreadProcessId(hwndServer, NULL) &&
415                 WDML_GetInstanceFromWnd(hwndClient) == WDML_GetInstanceFromWnd(hwndServer))
416             {
417                 self = TRUE;
418             }
419             /* FIXME: so far, we don't grab distant convcontext, so only check if remote is
420              * handled under DDEML, and if so build a default context
421              */
422            if ((GetClassNameA(hwndClient, buf, sizeof(buf)) &&
423                 lstrcmpiA(buf, WDML_szClientConvClassA) == 0) ||
424                (GetClassNameW(hwndClient, (LPWSTR)buf, sizeof(buf)/sizeof(WCHAR)) &&
425                 lstrcmpiW((LPWSTR)buf, WDML_szClientConvClassW) == 0))
426             {
427                 pcc = &cc;
428                 memset(pcc, 0, sizeof(*pcc));
429                 pcc->cb = sizeof(*pcc);
430                 pcc->iCodePage = IsWindowUnicode(hwndClient) ? CP_WINUNICODE : CP_WINANSI;
431             }
432             if ((pInstance->CBFflags & CBF_FAIL_SELFCONNECTIONS) && self)
433             {
434                 TRACE("Don't do self connection as requested\n");
435             }
436             else if (hszApp && hszTop)
437             {
438                 WDML_SERVER*    pServer = (WDML_SERVER*)GetWindowLongPtrW(hwndServer, GWL_WDML_SERVER);
439 
440                 /* check filters for name service */
441                 if (!pServer->filterOn || DdeCmpStringHandles(pServer->hszService, hszApp) == 0)
442                 {
443                     /* pass on to the callback  */
444                     hDdeData = WDML_InvokeCallback(pInstance, XTYP_CONNECT,
445                                                    0, 0, hszTop, hszApp, 0, (ULONG_PTR)pcc, self);
446                     if ((ULONG_PTR)hDdeData)
447                     {
448                         pConv = WDML_CreateServerConv(pInstance, hwndClient, hwndServer,
449                                                       hszApp, hszTop);
450                         if (pConv)
451                         {
452                             if (pcc) pConv->wStatus |= ST_ISLOCAL;
453                             WDML_InvokeCallback(pInstance, XTYP_CONNECT_CONFIRM, 0, (HCONV)pConv,
454                                                 hszTop, hszApp, 0, (ULONG_PTR)pcc, self);
455                         }
456                     }
457                 }
458             }
459             else if (pInstance->servers)
460             {
461                 /* pass on to the callback  */
462                 hDdeData = WDML_InvokeCallback(pInstance, XTYP_WILDCONNECT,
463                                                0, 0, hszTop, hszApp, 0, (ULONG_PTR)pcc, self);
464 
465                 if (hDdeData == CBR_BLOCK)
466                 {
467                     /* MS doc is not consistent here */
468                     FIXME("CBR_BLOCK returned for WILDCONNECT\n");
469                 }
470                 else if ((ULONG_PTR)hDdeData != 0)
471                 {
472                     HSZPAIR*    hszp;
473 
474                     hszp = (HSZPAIR*)DdeAccessData(hDdeData, NULL);
475                     if (hszp)
476                     {
477                         int     i;
478                         for (i = 0; hszp[i].hszSvc && hszp[i].hszTopic; i++)
479                         {
480                             pConv = WDML_CreateServerConv(pInstance, hwndClient, hwndServer,
481                                                           hszp[i].hszSvc, hszp[i].hszTopic);
482                             if (pConv)
483                             {
484                                 if (pcc) pConv->wStatus |= ST_ISLOCAL;
485                                 WDML_InvokeCallback(pInstance, XTYP_CONNECT_CONFIRM, 0, (HCONV)pConv,
486                                                     hszp[i].hszTopic, hszp[i].hszSvc, 0, (ULONG_PTR)pcc, self);
487                             }
488                         }
489                         DdeUnaccessData(hDdeData);
490                     }
491                     if (!WDML_IsAppOwned(hDdeData)) DdeFreeDataHandle(hDdeData);
492                 }
493             }
494         }
495 
496         return 0;
497 
498     case WM_DDE_REQUEST:
499         FIXME("WM_DDE_REQUEST message received!\n");
500         return 0;
501     case WM_DDE_ADVISE:
502         FIXME("WM_DDE_ADVISE message received!\n");
503         return 0;
504     case WM_DDE_UNADVISE:
505         FIXME("WM_DDE_UNADVISE message received!\n");
506         return 0;
507     case WM_DDE_EXECUTE:
508         FIXME("WM_DDE_EXECUTE message received!\n");
509         return 0;
510     case WM_DDE_POKE:
511         FIXME("WM_DDE_POKE message received!\n");
512         return 0;
513     case WM_DDE_TERMINATE:
514         FIXME("WM_DDE_TERMINATE message received!\n");
515         return 0;
516     default:
517         break;
518     }
519 
520     return DefWindowProcW(hwndServer, iMsg, wParam, lParam);
521 }
522 
523 /******************************************************************
524  *              WDML_ServerQueueRequest
525  *
526  *
527  */
528 static  WDML_XACT*      WDML_ServerQueueRequest(WDML_CONV* pConv, LPARAM lParam)
529 {
530     UINT_PTR            uiLo, uiHi;
531     WDML_XACT*          pXAct;
532 
533     UnpackDDElParam(WM_DDE_REQUEST, lParam, &uiLo, &uiHi);
534 
535     pXAct = WDML_AllocTransaction(pConv->instance, WM_DDE_REQUEST,
536                                   uiLo, WDML_MakeHszFromAtom(pConv->instance, uiHi));
537     if (pXAct) pXAct->atom = uiHi;
538     return pXAct;
539 }
540 
541 /******************************************************************
542  *              WDML_ServerHandleRequest
543  *
544  *
545  */
546 static  WDML_QUEUE_STATE WDML_ServerHandleRequest(WDML_CONV* pConv, WDML_XACT* pXAct)
547 {
548     HDDEDATA            hDdeData = 0;
549     BOOL                fAck = TRUE;
550 
551     if (!(pConv->instance->CBFflags & CBF_FAIL_REQUESTS))
552     {
553 
554         hDdeData = WDML_InvokeCallback(pConv->instance, XTYP_REQUEST, pXAct->wFmt, (HCONV)pConv,
555                                        pConv->hszTopic, pXAct->hszItem, 0, 0, 0);
556     }
557 
558     switch ((ULONG_PTR)hDdeData)
559     {
560     case 0:
561         TRACE("No data returned from the Callback\n");
562         fAck = FALSE;
563         break;
564 
565     case (ULONG_PTR)CBR_BLOCK:
566         return WDML_QS_BLOCK;
567 
568     default:
569         {
570             HGLOBAL     hMem = WDML_DataHandle2Global(hDdeData, TRUE, FALSE, FALSE, FALSE);
571             if (!PostMessageW(pConv->hwndClient, WM_DDE_DATA, (WPARAM)pConv->hwndServer,
572                               ReuseDDElParam(pXAct->lParam, WM_DDE_REQUEST, WM_DDE_DATA,
573                                              (UINT_PTR)hMem, (UINT_PTR)pXAct->atom)))
574             {
575                 pConv->instance->lastError = DMLERR_POSTMSG_FAILED;
576                 DdeFreeDataHandle(hDdeData);
577                 GlobalFree(hMem);
578                 fAck = FALSE;
579             }
580         }
581         break;
582     }
583 
584     WDML_PostAck(pConv, WDML_SERVER_SIDE, 0, FALSE, fAck, pXAct->atom, pXAct->lParam, WM_DDE_REQUEST);
585 
586     WDML_DecHSZ(pConv->instance, pXAct->hszItem);
587 
588     return WDML_QS_HANDLED;
589 }
590 
591 /******************************************************************
592  *              WDML_ServerQueueAdvise
593  *
594  *
595  */
596 static  WDML_XACT*      WDML_ServerQueueAdvise(WDML_CONV* pConv, LPARAM lParam)
597 {
598     UINT_PTR            uiLo, uiHi;
599     WDML_XACT*          pXAct;
600 
601     /* XTYP_ADVSTART transaction:
602        establish link and save link info to InstanceInfoTable */
603 
604     if (!UnpackDDElParam(WM_DDE_ADVISE, lParam, &uiLo, &uiHi))
605         return NULL;
606 
607     pXAct = WDML_AllocTransaction(pConv->instance, WM_DDE_ADVISE,
608                                   0, WDML_MakeHszFromAtom(pConv->instance, uiHi));
609     if (pXAct)
610     {
611         pXAct->hMem = (HGLOBAL)uiLo;
612         pXAct->atom = uiHi;
613     }
614     return pXAct;
615 }
616 
617 /******************************************************************
618  *              WDML_ServerHandleAdvise
619  *
620  *
621  */
622 static  WDML_QUEUE_STATE WDML_ServerHandleAdvise(WDML_CONV* pConv, WDML_XACT* pXAct)
623 {
624     UINT                uType;
625     WDML_LINK*          pLink;
626     DDEADVISE*          pDdeAdvise;
627     HDDEDATA            hDdeData = 0;
628     BOOL                fAck = TRUE;
629 
630     pDdeAdvise = GlobalLock(pXAct->hMem);
631     uType = XTYP_ADVSTART |
632             (pDdeAdvise->fDeferUpd ? XTYPF_NODATA : 0) |
633             (pDdeAdvise->fAckReq ? XTYPF_ACKREQ : 0);
634 
635     if (!(pConv->instance->CBFflags & CBF_FAIL_ADVISES))
636     {
637         hDdeData = WDML_InvokeCallback(pConv->instance, XTYP_ADVSTART, pDdeAdvise->cfFormat,
638                                        (HCONV)pConv, pConv->hszTopic, pXAct->hszItem, 0, 0, 0);
639     }
640 
641     switch ((ULONG_PTR)hDdeData)
642     {
643     case 0:
644         TRACE("No data returned from the Callback\n");
645         fAck = FALSE;
646         break;
647 
648     case (ULONG_PTR)CBR_BLOCK:
649         return WDML_QS_BLOCK;
650 
651     default:
652         /* billx: first to see if the link is already created. */
653         pLink = WDML_FindLink(pConv->instance, (HCONV)pConv, WDML_SERVER_SIDE,
654                               pXAct->hszItem, TRUE, pDdeAdvise->cfFormat);
655 
656         if (pLink != NULL)
657         {
658             /* we found a link, and only need to modify it in case it changes */
659             pLink->transactionType = uType;
660         }
661         else
662         {
663             TRACE("Adding Link with hConv %p\n", pConv);
664             WDML_AddLink(pConv->instance, (HCONV)pConv, WDML_SERVER_SIDE,
665                          uType, pXAct->hszItem, pDdeAdvise->cfFormat);
666         }
667         break;
668     }
669 
670     GlobalUnlock(pXAct->hMem);
671     if (fAck)
672     {
673         GlobalFree(pXAct->hMem);
674     }
675     pXAct->hMem = 0;
676 
677     WDML_PostAck(pConv, WDML_SERVER_SIDE, 0, FALSE, fAck, pXAct->atom, pXAct->lParam, WM_DDE_ADVISE);
678 
679     WDML_DecHSZ(pConv->instance, pXAct->hszItem);
680 
681     return WDML_QS_HANDLED;
682 }
683 
684 /******************************************************************
685  *              WDML_ServerQueueUnadvise
686  *
687  *
688  */
689 static  WDML_XACT* WDML_ServerQueueUnadvise(WDML_CONV* pConv, LPARAM lParam)
690 {
691     UINT_PTR            uiLo, uiHi;
692     WDML_XACT*          pXAct;
693 
694     UnpackDDElParam(WM_DDE_UNADVISE, lParam, &uiLo, &uiHi);
695 
696     pXAct = WDML_AllocTransaction(pConv->instance, WM_DDE_UNADVISE,
697                                   uiLo, WDML_MakeHszFromAtom(pConv->instance, uiHi));
698     if (pXAct) pXAct->atom = uiHi;
699     return pXAct;
700 }
701 
702 /******************************************************************
703  *              WDML_ServerHandleUnadvise
704  *
705  *
706  */
707 static  WDML_QUEUE_STATE WDML_ServerHandleUnadvise(WDML_CONV* pConv, WDML_XACT* pXAct)
708 {
709     WDML_LINK*  pLink;
710 
711     if (pXAct->hszItem == NULL || pXAct->wFmt == 0)
712     {
713         ERR("Unsupported yet options (null item or clipboard format)\n");
714         return WDML_QS_ERROR;
715     }
716 
717     pLink = WDML_FindLink(pConv->instance, (HCONV)pConv, WDML_SERVER_SIDE,
718                           pXAct->hszItem, TRUE, pXAct->wFmt);
719     if (pLink == NULL)
720     {
721         ERR("Couln'd find link for %p, dropping request\n", pXAct->hszItem);
722         FreeDDElParam(WM_DDE_UNADVISE, pXAct->lParam);
723         return WDML_QS_ERROR;
724     }
725 
726     if (!(pConv->instance->CBFflags & CBF_FAIL_ADVISES))
727     {
728         WDML_InvokeCallback(pConv->instance, XTYP_ADVSTOP, pXAct->wFmt, (HCONV)pConv,
729                             pConv->hszTopic, pXAct->hszItem, 0, 0, 0);
730     }
731 
732     WDML_RemoveLink(pConv->instance, (HCONV)pConv, WDML_SERVER_SIDE,
733                     pXAct->hszItem, pXAct->wFmt);
734 
735     /* send back ack */
736     WDML_PostAck(pConv, WDML_SERVER_SIDE, 0, FALSE, TRUE, pXAct->atom,
737                  pXAct->lParam, WM_DDE_UNADVISE);
738 
739     WDML_DecHSZ(pConv->instance, pXAct->hszItem);
740 
741     return WDML_QS_HANDLED;
742 }
743 
744 /******************************************************************
745  *              WDML_QueueExecute
746  *
747  *
748  */
749 static  WDML_XACT* WDML_ServerQueueExecute(WDML_CONV* pConv, LPARAM lParam)
750 {
751     WDML_XACT*  pXAct;
752 
753     pXAct = WDML_AllocTransaction(pConv->instance, WM_DDE_EXECUTE, 0, 0);
754     if (pXAct)
755     {
756         pXAct->hMem    = (HGLOBAL)lParam;
757     }
758     return pXAct;
759 }
760 
761 static BOOL data_looks_unicode( const WCHAR *data, DWORD size )
762 {
763     DWORD i;
764 
765     if (size % sizeof(WCHAR)) return FALSE;
766     for (i = 0; i < size / sizeof(WCHAR); i++) if (data[i] > 255) return FALSE;
767     return TRUE;
768 }
769 
770 /* convert data to Unicode, unless it looks like it's already Unicode */
771 static HDDEDATA map_A_to_W( DWORD instance, void *ptr, DWORD size )
772 {
773     HDDEDATA ret;
774     DWORD len;
775     const char *end;
776 
777     if (!data_looks_unicode( ptr, size ))
778     {
779         if ((end = memchr( ptr, 0, size ))) size = end + 1 - (const char *)ptr;
780         len = MultiByteToWideChar( CP_ACP, 0, ptr, size, NULL, 0 );
781         ret = DdeCreateDataHandle( instance, NULL, len * sizeof(WCHAR), 0, 0, CF_TEXT, 0);
782         MultiByteToWideChar( CP_ACP, 0, ptr, size, (WCHAR *)DdeAccessData(ret, NULL), len );
783     }
784     else ret = DdeCreateDataHandle( instance, ptr, size, 0, 0, CF_TEXT, 0 );
785 
786     return ret;
787 }
788 
789 /* convert data to ASCII, unless it looks like it's not in Unicode format */
790 static HDDEDATA map_W_to_A( DWORD instance, void *ptr, DWORD size )
791 {
792     HDDEDATA ret;
793     DWORD len;
794     const WCHAR *end;
795 
796     if (data_looks_unicode( ptr, size ))
797     {
798         size /= sizeof(WCHAR);
799         if ((end = memchrW( ptr, 0, size ))) size = end + 1 - (const WCHAR *)ptr;
800         len = WideCharToMultiByte( CP_ACP, 0, ptr, size, NULL, 0, NULL, NULL );
801         ret = DdeCreateDataHandle( instance, NULL, len, 0, 0, CF_TEXT, 0);
802         WideCharToMultiByte( CP_ACP, 0, ptr, size, (char *)DdeAccessData(ret, NULL), len, NULL, NULL );
803     }
804     else ret = DdeCreateDataHandle( instance, ptr, size, 0, 0, CF_TEXT, 0 );
805 
806     return ret;
807 }
808 
809  /******************************************************************
810  *              WDML_ServerHandleExecute
811  *
812  *
813  */
814 static  WDML_QUEUE_STATE WDML_ServerHandleExecute(WDML_CONV* pConv, WDML_XACT* pXAct)
815 {
816     HDDEDATA    hDdeData = DDE_FNOTPROCESSED;
817     BOOL        fAck = FALSE, fBusy = FALSE;
818 
819     if (!(pConv->instance->CBFflags & CBF_FAIL_EXECUTES))
820     {
821         LPVOID  ptr = GlobalLock(pXAct->hMem);
822         DWORD size = GlobalSize(pXAct->hMem);
823 
824         if (ptr)
825         {
826             if (pConv->instance->unicode)  /* Unicode server, try to map A->W */
827                 hDdeData = map_A_to_W( pConv->instance->instanceID, ptr, size );
828             else if (!IsWindowUnicode( pConv->hwndClient )) /* ASCII server and client, try to map W->A */
829                 hDdeData = map_W_to_A( pConv->instance->instanceID, ptr, size );
830             else
831                 hDdeData = DdeCreateDataHandle(pConv->instance->instanceID, ptr, size, 0, 0, CF_TEXT, 0);
832             GlobalUnlock(pXAct->hMem);
833         }
834         hDdeData = WDML_InvokeCallback(pConv->instance, XTYP_EXECUTE, 0, (HCONV)pConv,
835                                        pConv->hszTopic, 0, hDdeData, 0L, 0L);
836     }
837 
838     switch ((ULONG_PTR)hDdeData)
839     {
840     case (ULONG_PTR)CBR_BLOCK:
841         return WDML_QS_BLOCK;
842 
843     case DDE_FACK:
844         fAck = TRUE;
845         break;
846     case DDE_FBUSY:
847         fBusy = TRUE;
848         break;
849     default:
850         FIXME("Unsupported returned value %p\n", hDdeData);
851         /* fall through */
852     case DDE_FNOTPROCESSED:
853         break;
854     }
855     WDML_PostAck(pConv, WDML_SERVER_SIDE, 0, fBusy, fAck, (UINT_PTR)pXAct->hMem, 0, 0);
856 
857     return WDML_QS_HANDLED;
858 }
859 
860 /******************************************************************
861  *              WDML_ServerQueuePoke
862  *
863  *
864  */
865 static  WDML_XACT* WDML_ServerQueuePoke(WDML_CONV* pConv, LPARAM lParam)
866 {
867     UINT_PTR            uiLo, uiHi;
868     WDML_XACT*          pXAct;
869 
870     UnpackDDElParam(WM_DDE_POKE, lParam, &uiLo, &uiHi);
871 
872     pXAct = WDML_AllocTransaction(pConv->instance, WM_DDE_POKE,
873                                   0, WDML_MakeHszFromAtom(pConv->instance, uiHi));
874     if (pXAct)
875     {
876         pXAct->atom = uiHi;
877         pXAct->hMem = (HGLOBAL)uiLo;
878     }
879     return pXAct;
880 }
881 
882 /******************************************************************
883  *              WDML_ServerHandlePoke
884  *
885  *
886  */
887 static  WDML_QUEUE_STATE WDML_ServerHandlePoke(WDML_CONV* pConv, WDML_XACT* pXAct)
888 {
889     DDEPOKE*            pDdePoke;
890     HDDEDATA            hDdeData;
891     BOOL                fBusy = FALSE, fAck = FALSE;
892 
893     pDdePoke = GlobalLock(pXAct->hMem);
894     if (!pDdePoke)
895     {
896         return WDML_QS_ERROR;
897     }
898 
899     if (!(pConv->instance->CBFflags & CBF_FAIL_POKES))
900     {
901         hDdeData = DdeCreateDataHandle(pConv->instance->instanceID, pDdePoke->Value,
902                                        GlobalSize(pXAct->hMem) - FIELD_OFFSET(DDEPOKE, Value),
903                                        0, 0, pDdePoke->cfFormat, 0);
904         if (hDdeData)
905         {
906             HDDEDATA    hDdeDataOut;
907 
908             hDdeDataOut = WDML_InvokeCallback(pConv->instance, XTYP_POKE, pDdePoke->cfFormat,
909                                               (HCONV)pConv, pConv->hszTopic, pXAct->hszItem,
910                                               hDdeData, 0, 0);
911             switch ((ULONG_PTR)hDdeDataOut)
912             {
913             case DDE_FACK:
914                 fAck = TRUE;
915                 break;
916             case DDE_FBUSY:
917                 fBusy = TRUE;
918                 break;
919             default:
920                 FIXME("Unsupported returned value %p\n", hDdeDataOut);
921                 /* fal through */
922             case DDE_FNOTPROCESSED:
923                 break;
924             }
925             DdeFreeDataHandle(hDdeData);
926         }
927     }
928     GlobalUnlock(pXAct->hMem);
929 
930     if (!fAck)
931     {
932         GlobalFree(pXAct->hMem);
933     }
934     WDML_PostAck(pConv, WDML_SERVER_SIDE, 0, fBusy, fAck, pXAct->atom, pXAct->lParam, WM_DDE_POKE);
935 
936     WDML_DecHSZ(pConv->instance, pXAct->hszItem);
937 
938     return WDML_QS_HANDLED;
939 }
940 
941 /******************************************************************
942  *              WDML_ServerQueueTerminate
943  *
944  *
945  */
946 static  WDML_XACT*      WDML_ServerQueueTerminate(WDML_CONV* pConv, LPARAM lParam)
947 {
948     WDML_XACT*  pXAct;
949 
950     pXAct = WDML_AllocTransaction(pConv->instance, WM_DDE_TERMINATE, 0, 0);
951     return pXAct;
952 }
953 
954 /******************************************************************
955  *              WDML_ServerHandleTerminate
956  *
957  *
958  */
959 static  WDML_QUEUE_STATE WDML_ServerHandleTerminate(WDML_CONV* pConv, WDML_XACT* pXAct)
960 {
961     /* billx: two things to remove: the conv, and associated links.
962      * Respond with another WM_DDE_TERMINATE iMsg.
963      */
964     if (!(pConv->instance->CBFflags & CBF_SKIP_DISCONNECTS))
965     {
966         WDML_InvokeCallback(pConv->instance, XTYP_DISCONNECT, 0, (HCONV)pConv, 0, 0,
967                             0, 0, (pConv->wStatus & ST_ISSELF) ? 1 : 0);
968     }
969     PostMessageW(pConv->hwndClient, WM_DDE_TERMINATE, (WPARAM)pConv->hwndServer, 0);
970     WDML_RemoveConv(pConv, WDML_SERVER_SIDE);
971 
972     return WDML_QS_HANDLED;
973 }
974 
975 /******************************************************************
976  *              WDML_ServerHandle
977  *
978  *
979  */
980 WDML_QUEUE_STATE WDML_ServerHandle(WDML_CONV* pConv, WDML_XACT* pXAct)
981 {
982     WDML_QUEUE_STATE    qs = WDML_QS_ERROR;
983 
984     switch (pXAct->ddeMsg)
985     {
986     case WM_DDE_INITIATE:
987         FIXME("WM_DDE_INITIATE shouldn't be there!\n");
988         break;
989     case WM_DDE_REQUEST:
990         qs = WDML_ServerHandleRequest(pConv, pXAct);
991         break;
992 
993     case WM_DDE_ADVISE:
994         qs = WDML_ServerHandleAdvise(pConv, pXAct);
995         break;
996 
997     case WM_DDE_UNADVISE:
998         qs = WDML_ServerHandleUnadvise(pConv, pXAct);
999         break;
1000 
1001     case WM_DDE_EXECUTE:
1002         qs = WDML_ServerHandleExecute(pConv, pXAct);
1003         break;
1004 
1005     case WM_DDE_POKE:
1006         qs = WDML_ServerHandlePoke(pConv, pXAct);
1007         break;
1008 
1009     case WM_DDE_TERMINATE:
1010         qs = WDML_ServerHandleTerminate(pConv, pXAct);
1011         break;
1012 
1013     case WM_DDE_ACK:
1014         WARN("Shouldn't receive a ACK message (never requests them). Ignoring it\n");
1015         break;
1016 
1017     default:
1018         FIXME("Unsupported message %d\n", pXAct->ddeMsg);
1019     }
1020     return qs;
1021 }
1022 
1023 /******************************************************************
1024  *              WDML_ServerConvProc
1025  *
1026  *
1027  */
1028 static LRESULT CALLBACK WDML_ServerConvProc(HWND hwndServer, UINT iMsg, WPARAM wParam, LPARAM lParam)
1029 {
1030     WDML_INSTANCE*      pInstance;
1031     WDML_CONV*          pConv;
1032     WDML_XACT*          pXAct = NULL;
1033 
1034     TRACE("%p %04x %08lx %08lx\n", hwndServer, iMsg, wParam, lParam);
1035 
1036     if (iMsg == WM_DESTROY)
1037     {
1038         pConv = WDML_GetConvFromWnd(hwndServer);
1039         if (pConv && !(pConv->wStatus & ST_TERMINATED))
1040         {
1041             WDML_ServerHandleTerminate(pConv, NULL);
1042         }
1043     }
1044     if (iMsg < WM_DDE_FIRST || iMsg > WM_DDE_LAST)
1045     {
1046         return IsWindowUnicode(hwndServer) ? DefWindowProcW(hwndServer, iMsg, wParam, lParam) :
1047                                              DefWindowProcA(hwndServer, iMsg, wParam, lParam);
1048     }
1049 
1050     pInstance = WDML_GetInstanceFromWnd(hwndServer);
1051     pConv = WDML_GetConvFromWnd(hwndServer);
1052 
1053     if (!pConv)
1054     {
1055         ERR("Got a message (%x) on a not known conversation, dropping request\n", iMsg);
1056         return 0;
1057     }
1058     if (pConv->hwndClient != WIN_GetFullHandle( (HWND)wParam ) || pConv->hwndServer != hwndServer)
1059     {
1060         ERR("mismatch between C/S windows and conversation\n");
1061         return 0;
1062     }
1063     if (pConv->instance != pInstance || pConv->instance == NULL)
1064     {
1065         ERR("mismatch in instances\n");
1066         return 0;
1067     }
1068 
1069     switch (iMsg)
1070     {
1071     case WM_DDE_INITIATE:
1072         FIXME("WM_DDE_INITIATE message received!\n");
1073         break;
1074 
1075     case WM_DDE_REQUEST:
1076         pXAct = WDML_ServerQueueRequest(pConv, lParam);
1077         break;
1078 
1079     case WM_DDE_ADVISE:
1080         pXAct = WDML_ServerQueueAdvise(pConv, lParam);
1081         break;
1082 
1083     case WM_DDE_UNADVISE:
1084         pXAct = WDML_ServerQueueUnadvise(pConv, lParam);
1085         break;
1086 
1087     case WM_DDE_EXECUTE:
1088         pXAct = WDML_ServerQueueExecute(pConv, lParam);
1089         break;
1090 
1091     case WM_DDE_POKE:
1092         pXAct = WDML_ServerQueuePoke(pConv, lParam);
1093         break;
1094 
1095     case WM_DDE_TERMINATE:
1096         pXAct = WDML_ServerQueueTerminate(pConv, lParam);
1097         break;
1098 
1099     case WM_DDE_ACK:
1100         WARN("Shouldn't receive a ACK message (never requests them). Ignoring it\n");
1101         break;
1102 
1103     default:
1104         FIXME("Unsupported message %x\n", iMsg);
1105         break;
1106     }
1107 
1108     if (pXAct)
1109     {
1110         pXAct->lParam = lParam;
1111 
1112         if ((pConv->wStatus & ST_BLOCKED) || WDML_ServerHandle(pConv, pXAct) == WDML_QS_BLOCK)
1113         {
1114             TRACE("Transactions are blocked, add to the queue and exit\n");
1115             WDML_QueueTransaction(pConv, pXAct);
1116         }
1117         else
1118         {
1119             WDML_FreeTransaction(pInstance, pXAct, TRUE);
1120         }
1121     }
1122     else
1123         pConv->instance->lastError = DMLERR_MEMORY_ERROR;
1124 
1125     return 0;
1126 }
1127 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.