ReactOS 0.4.17-dev-1321-g5c122a9
ddemisc.c
Go to the documentation of this file.
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 <user32.h>
27
28#include "dde_private.h"
29
31
32/* convert between ATOM and HSZ avoiding compiler warnings */
33#define ATOM2HSZ(atom) ((HSZ) (ULONG_PTR)(atom))
34#define HSZ2ATOM(hsz) ((ATOM) (ULONG_PTR)(hsz))
35
37static LONG WDML_MaxInstanceID = 0; /* OK for present, have to worry about wrap-around later */
38#ifdef __REACTOS__
39const WCHAR WDML_szEventClass[] = L"DDEMLEvent";
40#else
41const WCHAR WDML_szEventClass[] = L"WineDdeEventClass";
42#endif
43
44/* protection for instance list */
47{
48 0, 0, &WDML_CritSect,
50 0, 0, { (DWORD_PTR)(__FILE__ ": WDML_CritSect") }
51};
52static CRITICAL_SECTION WDML_CritSect = { &critsect_debug, -1, 0, 0, 0, 0 };
53
54/* ================================================================
55 *
56 * Pure DDE (non DDEML) management
57 *
58 * ================================================================ */
59
60
61/*****************************************************************
62 * PackDDElParam (USER32.@)
63 *
64 * RETURNS
65 * the packed lParam
66 */
68{
69 HGLOBAL hMem;
71
72 switch (msg)
73 {
74 case WM_DDE_ACK:
75 case WM_DDE_ADVISE:
76 case WM_DDE_DATA:
77 case WM_DDE_POKE:
78 if (!(hMem = GlobalAlloc(GMEM_DDESHARE, sizeof(UINT_PTR) * 2)))
79 {
80 ERR("GlobalAlloc failed\n");
81 return 0;
82 }
83 if (!(params = GlobalLock(hMem)))
84 {
85 ERR("GlobalLock failed (%p)\n", hMem);
86 return 0;
87 }
88 params[0] = uiLo;
89 params[1] = uiHi;
90 GlobalUnlock(hMem);
91 return (LPARAM)hMem;
92
93 case WM_DDE_EXECUTE:
94 return uiHi;
95
96 default:
97 return MAKELONG(uiLo, uiHi);
98 }
99}
100
101
102/*****************************************************************
103 * UnpackDDElParam (USER32.@)
104 *
105 * RETURNS
106 * success: nonzero
107 * failure: zero
108 */
110 PUINT_PTR uiLo, PUINT_PTR uiHi)
111{
113
114 switch (msg)
115 {
116 case WM_DDE_ACK:
117 case WM_DDE_ADVISE:
118 case WM_DDE_DATA:
119 case WM_DDE_POKE:
120 if (!lParam || !(params = GlobalLock((HGLOBAL)lParam)))
121 {
122 if (uiLo) *uiLo = 0;
123 if (uiHi) *uiHi = 0;
124 return FALSE;
125 }
126 if (uiLo) *uiLo = params[0];
127 if (uiHi) *uiHi = params[1];
129 return TRUE;
130
131 case WM_DDE_EXECUTE:
132 if (uiLo) *uiLo = 0;
133 if (uiHi) *uiHi = lParam;
134 return TRUE;
135
136 default:
137 if (uiLo) *uiLo = LOWORD(lParam);
138 if (uiHi) *uiHi = HIWORD(lParam);
139 return TRUE;
140 }
141}
142
143
144/*****************************************************************
145 * FreeDDElParam (USER32.@)
146 *
147 * RETURNS
148 * success: nonzero
149 * failure: zero
150 */
152{
153 switch (msg)
154 {
155 case WM_DDE_ACK:
156 case WM_DDE_ADVISE:
157 case WM_DDE_DATA:
158 case WM_DDE_POKE:
159 /* first check if it's a global handle */
160 if (!GlobalHandle( (LPVOID)lParam )) return TRUE;
161 return !GlobalFree( (HGLOBAL)lParam );
162
163 default:
164 return TRUE;
165 }
166}
167
168
169/*****************************************************************
170 * ReuseDDElParam (USER32.@)
171 *
172 * RETURNS
173 * the packed lParam
174 */
176 UINT_PTR uiLo, UINT_PTR uiHi)
177{
179
180 switch (msgIn)
181 {
182 case WM_DDE_ACK:
183 case WM_DDE_ADVISE:
184 case WM_DDE_DATA:
185 case WM_DDE_POKE:
186 switch(msgOut)
187 {
188 case WM_DDE_ACK:
189 case WM_DDE_ADVISE:
190 case WM_DDE_DATA:
191 case WM_DDE_POKE:
192 if (!lParam) return 0;
193 if (!(params = GlobalLock( (HGLOBAL)lParam )))
194 {
195 ERR("GlobalLock failed\n");
196 return 0;
197 }
198 params[0] = uiLo;
199 params[1] = uiHi;
200 TRACE("Reusing pack %08Ix %08Ix\n", uiLo, uiHi);
202 return lParam;
203
204 case WM_DDE_EXECUTE:
205 FreeDDElParam( msgIn, lParam );
206 return uiHi;
207
208 default:
209 FreeDDElParam( msgIn, lParam );
210 return MAKELPARAM(uiLo, uiHi);
211 }
212
213 default:
214 return PackDDElParam( msgOut, uiLo, uiHi );
215 }
216}
217
218/*****************************************************************
219 * ImpersonateDdeClientWindow (USER32.@)
220 *
221 * PARAMS
222 * hWndClient [I] handle to DDE client window
223 * hWndServer [I] handle to DDE server window
224 */
226{
227 FIXME("(%p %p): stub\n", hWndClient, hWndServer);
228 return FALSE;
229}
230
231/*****************************************************************
232 * DdeSetQualityOfService (USER32.@)
233 */
234
237{
238 FIXME("(%p %p %p): stub\n", hwndClient, pqosNew, pqosPrev);
239 return TRUE;
240}
241
242/* ================================================================
243 *
244 * WDML Error management
245 *
246 * ================================================================ */
247
248/******************************************************************************
249 * DdeGetLastError [USER32.@] Gets most recent error code
250 *
251 * PARAMS
252 * idInst [I] Instance identifier
253 *
254 * RETURNS
255 * Last error code
256 */
258{
261
262 /* First check instance
263 */
264 pInstance = WDML_GetInstance(idInst);
265 if (pInstance == NULL)
266 {
268 }
269 else
270 {
271 error_code = pInstance->lastError;
272 pInstance->lastError = 0;
273 }
274
275 return error_code;
276}
277
278/******************************************************************
279 * WDML_SetAllLastError
280 *
281 *
282 */
283static void WDML_SetAllLastError(DWORD lastError)
284{
285 DWORD threadID;
287 threadID = GetCurrentThreadId();
289 while (pInstance)
290 {
291 if (pInstance->threadID == threadID)
292 pInstance->lastError = lastError;
293 pInstance = pInstance->next;
294 }
295}
296
297/* ================================================================
298 *
299 * String management
300 *
301 * ================================================================ */
302
303
304/******************************************************************
305 * WDML_FindNode
306 *
307 *
308 */
310{
311 HSZNode* pNode;
312
313 if (pInstance == NULL) return NULL;
314
315 for (pNode = pInstance->nodeList; pNode != NULL; pNode = pNode->next)
316 {
317 if (pNode->hsz == hsz) break;
318 }
319 if (!pNode) WARN("HSZ %p not found\n", hsz);
320 return pNode;
321}
322
323/******************************************************************
324 * WDML_MakeAtomFromHsz
325 *
326 * Creates a global atom from an existing HSZ
327 * Generally used before sending an HSZ as an atom to a remote app
328 */
330{
331 WCHAR nameBuffer[MAX_BUFFER_LEN];
332
333 if (GetAtomNameW(HSZ2ATOM(hsz), nameBuffer, MAX_BUFFER_LEN))
334 return GlobalAddAtomW(nameBuffer);
335 WARN("HSZ %p not found\n", hsz);
336 return 0;
337}
338
339/******************************************************************
340 * WDML_MakeHszFromAtom
341 *
342 * Creates a HSZ from an existing global atom
343 * Generally used while receiving a global atom and transforming it
344 * into an HSZ
345 */
347{
348 WCHAR nameBuffer[MAX_BUFFER_LEN];
349
350 if (!atom) return NULL;
351
352 if (GlobalGetAtomNameW(atom, nameBuffer, MAX_BUFFER_LEN))
353 {
354 TRACE("%x => %s\n", atom, debugstr_w(nameBuffer));
355 return DdeCreateStringHandleW(pInstance->instanceID, nameBuffer, CP_WINUNICODE);
356 }
357 WARN("ATOM 0x%x not found\n", atom);
358 return 0;
359}
360
361/******************************************************************
362 * WDML_IncHSZ
363 *
364 *
365 */
367{
368 HSZNode* pNode;
369
370 pNode = WDML_FindNode(pInstance, hsz);
371 if (!pNode) return FALSE;
372
373 pNode->refCount++;
374 return TRUE;
375}
376
377/******************************************************************************
378 * WDML_DecHSZ (INTERNAL)
379 *
380 * Decrease the ref count of an HSZ. If it reaches 0, the node is removed from the list
381 * of HSZ nodes
382 * Returns -1 is the HSZ isn't found, otherwise it's the current (after --) of the ref count
383 */
385{
386 HSZNode* pPrev = NULL;
387 HSZNode* pCurrent;
388
389 for (pCurrent = pInstance->nodeList; pCurrent != NULL; pCurrent = (pPrev = pCurrent)->next)
390 {
391 /* If we found the node we were looking for and its ref count is one,
392 * we can remove it
393 */
394 if (pCurrent->hsz == hsz)
395 {
396 if (--pCurrent->refCount == 0)
397 {
398 if (pCurrent == pInstance->nodeList)
399 {
400 pInstance->nodeList = pCurrent->next;
401 }
402 else
403 {
404 pPrev->next = pCurrent->next;
405 }
406 HeapFree(GetProcessHeap(), 0, pCurrent);
407 DeleteAtom(HSZ2ATOM(hsz));
408 }
409 return TRUE;
410 }
411 }
412 WARN("HSZ %p not found\n", hsz);
413
414 return FALSE;
415}
416
417/******************************************************************************
418 * WDML_FreeAllHSZ (INTERNAL)
419 *
420 * Frees up all the strings still allocated in the list and
421 * remove all the nodes from the list of HSZ nodes.
422 */
424{
425 /* Free any strings created in this instance.
426 */
427 while (pInstance->nodeList != NULL)
428 {
429 DdeFreeStringHandle(pInstance->instanceID, pInstance->nodeList->hsz);
430 }
431}
432
433/******************************************************************************
434 * InsertHSZNode (INTERNAL)
435 *
436 * Insert a node to the head of the list.
437 */
439{
440 if (hsz != 0)
441 {
442 HSZNode* pNew = NULL;
443 /* Create a new node for this HSZ.
444 */
445 pNew = HeapAlloc(GetProcessHeap(), 0, sizeof(HSZNode));
446 if (pNew != NULL)
447 {
448 pNew->hsz = hsz;
449 pNew->next = pInstance->nodeList;
450 pNew->refCount = 1;
451 pInstance->nodeList = pNew;
452 }
453 else
454 {
455 ERR("Primary HSZ Node allocation failed - out of memory\n");
456 }
457 }
458}
459
460/******************************************************************
461 * WDML_QueryString
462 *
463 *
464 */
466 int codepage)
467{
469 int ret;
470 /* If psz is null, we have to return only the length
471 * of the string.
472 */
473 if (ptr == NULL)
474 {
475 ptr = pString;
477 }
478
479 /* if there is no input windows returns a NULL string */
480 if (hsz == NULL)
481 {
482 CHAR *t_ptr = ptr;
483 *t_ptr = '\0';
484 return 1;
485 }
486
487 switch (codepage)
488 {
489 case CP_WINANSI:
491 break;
492 case CP_WINUNICODE:
494 break;
495 default:
496 ERR("Unknown code page %d\n", codepage);
497 ret = 0;
498 }
499 return ret;
500}
501
502/*****************************************************************
503 * DdeQueryStringA [USER32.@]
504 */
505DWORD WINAPI DdeQueryStringA(DWORD idInst, HSZ hsz, LPSTR psz, DWORD cchMax, INT iCodePage)
506{
507 DWORD ret = 0;
509
510 TRACE("(%ld, %p, %p, %ld, %d)\n", idInst, hsz, psz, cchMax, iCodePage);
511
512 /* First check instance
513 */
514 pInstance = WDML_GetInstance(idInst);
515 if (pInstance != NULL)
516 {
517 if (iCodePage == 0) iCodePage = CP_WINANSI;
518 ret = WDML_QueryString(pInstance, hsz, psz, cchMax, iCodePage);
519 }
520
521 TRACE("returning %ld (%s)\n", ret, debugstr_a(psz));
522 return ret;
523}
524
525/*****************************************************************
526 * DdeQueryStringW [USER32.@]
527 */
528
529DWORD WINAPI DdeQueryStringW(DWORD idInst, HSZ hsz, LPWSTR psz, DWORD cchMax, INT iCodePage)
530{
531 DWORD ret = 0;
533
534 TRACE("(%ld, %p, %p, %ld, %d)\n", idInst, hsz, psz, cchMax, iCodePage);
535
536 /* First check instance
537 */
538 pInstance = WDML_GetInstance(idInst);
539 if (pInstance != NULL)
540 {
541 if (iCodePage == 0) iCodePage = CP_WINUNICODE;
542 ret = WDML_QueryString(pInstance, hsz, psz, cchMax, iCodePage);
543 }
544
545 TRACE("returning %ld (%s)\n", ret, debugstr_w(psz));
546 return ret;
547}
548
549/******************************************************************
550 * DML_CreateString
551 *
552 *
553 */
555{
556 HSZ hsz;
557
558 switch (codepage)
559 {
560 case CP_WINANSI:
561 hsz = ATOM2HSZ(AddAtomA(ptr));
562 TRACE("added atom %s with HSZ %p,\n", debugstr_a(ptr), hsz);
563 break;
564 case CP_WINUNICODE:
565 hsz = ATOM2HSZ(AddAtomW(ptr));
566 TRACE("added atom %s with HSZ %p,\n", debugstr_w(ptr), hsz);
567 break;
568 default:
569 ERR("Unknown code page %d\n", codepage);
570 return 0;
571 }
573 return hsz;
574}
575
576/*****************************************************************
577 * DdeCreateStringHandleA [USER32.@]
578 *
579 * See DdeCreateStringHandleW.
580 */
582{
583 HSZ hsz = 0;
585
586 TRACE("(%ld,%s,%d)\n", idInst, debugstr_a(psz), codepage);
587
588 pInstance = WDML_GetInstance(idInst);
589 if (pInstance == NULL)
591 else
592 {
593 if (codepage == 0) codepage = CP_WINANSI;
595 }
596
597 return hsz;
598}
599
600
601/******************************************************************************
602 * DdeCreateStringHandleW [USER32.@] Creates handle to identify string
603 *
604 * PARAMS
605 * idInst [I] Instance identifier
606 * psz [I] Pointer to string
607 * codepage [I] Code page identifier
608 * RETURNS
609 * Success: String handle
610 * Failure: 0
611 */
613{
615 HSZ hsz = 0;
616
617 pInstance = WDML_GetInstance(idInst);
618 if (pInstance == NULL)
620 else
621 {
622 if (codepage == 0) codepage = CP_WINUNICODE;
624 }
625
626 return hsz;
627}
628
629/*****************************************************************
630 * DdeFreeStringHandle (USER32.@)
631 * RETURNS
632 * success: nonzero
633 * fail: zero
634 */
636{
638 BOOL ret = FALSE;
639
640 TRACE("(%ld,%p):\n", idInst, hsz);
641
642 /* First check instance
643 */
644 pInstance = WDML_GetInstance(idInst);
645 if (pInstance)
646 ret = WDML_DecHSZ(pInstance, hsz);
647
648 return ret;
649}
650
651/*****************************************************************
652 * DdeKeepStringHandle (USER32.@)
653 *
654 * RETURNS
655 * success: nonzero
656 * fail: zero
657 */
659{
661 BOOL ret = FALSE;
662
663 TRACE("(%ld,%p):\n", idInst, hsz);
664
665 /* First check instance
666 */
667 pInstance = WDML_GetInstance(idInst);
668 if (pInstance)
669 ret = WDML_IncHSZ(pInstance, hsz);
670
671 return ret;
672}
673
674/*****************************************************************
675 * DdeCmpStringHandles (USER32.@)
676 *
677 * Compares the value of two string handles. This comparison is
678 * not case sensitive.
679 *
680 * PARAMS
681 * hsz1 [I] Handle to the first string
682 * hsz2 [I] Handle to the second string
683 *
684 * RETURNS
685 * -1 The value of hsz1 is zero or less than hsz2
686 * 0 The values of hsz 1 and 2 are the same or both zero.
687 * 1 The value of hsz2 is zero of less than hsz1
688 */
689INT WINAPI DdeCmpStringHandles(HSZ hsz1, HSZ hsz2)
690{
691 WCHAR psz1[MAX_BUFFER_LEN];
692 WCHAR psz2[MAX_BUFFER_LEN];
693 int ret = 0;
694 int ret1, ret2;
695
696 ret1 = GetAtomNameW(HSZ2ATOM(hsz1), psz1, MAX_BUFFER_LEN);
697 ret2 = GetAtomNameW(HSZ2ATOM(hsz2), psz2, MAX_BUFFER_LEN);
698
699 TRACE("(%p<%s> %p<%s>);\n", hsz1, debugstr_w(psz1), hsz2, debugstr_w(psz2));
700
701 /* Make sure we found both strings. */
702 if (ret1 == 0 && ret2 == 0)
703 {
704 /* If both are not found, return both "zero strings". */
705 ret = 0;
706 }
707 else if (ret1 == 0)
708 {
709 /* If hsz1 is a not found, return hsz1 is "zero string". */
710 ret = -1;
711 }
712 else if (ret2 == 0)
713 {
714 /* If hsz2 is a not found, return hsz2 is "zero string". */
715 ret = 1;
716 }
717 else
718 {
719 /* Compare the two strings we got (case insensitive). */
720 ret = lstrcmpiW(psz1, psz2);
721 /* Since strcmp returns any number smaller than
722 * 0 when the first string is found to be less than
723 * the second one we must make sure we are returning
724 * the proper values.
725 */
726 if (ret < 0)
727 {
728 ret = -1;
729 }
730 else if (ret > 0)
731 {
732 ret = 1;
733 }
734 }
735
736 return ret;
737}
738
739/* ================================================================
740 *
741 * Instance management
742 *
743 * ================================================================ */
744
745/******************************************************************************
746 * IncrementInstanceId
747 *
748 * generic routine to increment the max instance Id and allocate a new application instance
749 */
751{
753
754 pInstance->instanceID = id;
755 TRACE("New instance id %ld allocated\n", id);
756}
757
758/******************************************************************
759 * WDML_EventProc
760 *
761 *
762 */
764{
766 HSZ hsz1, hsz2;
767
768 switch (uMsg)
769 {
770 case WM_WDML_REGISTER:
772 /* try calling the Callback */
773 if (pInstance && !(pInstance->CBFflags & CBF_SKIP_REGISTRATIONS))
774 {
777 WDML_InvokeCallback(pInstance, XTYP_REGISTER, 0, 0, hsz1, hsz2, 0, 0, 0);
778 WDML_DecHSZ(pInstance, hsz1);
779 WDML_DecHSZ(pInstance, hsz2);
780 }
781 break;
782
785 if (pInstance && !(pInstance->CBFflags & CBF_SKIP_UNREGISTRATIONS))
786 {
789 WDML_InvokeCallback(pInstance, XTYP_UNREGISTER, 0, 0, hsz1, hsz2, 0, 0, 0);
790 WDML_DecHSZ(pInstance, hsz1);
791 WDML_DecHSZ(pInstance, hsz2);
792 }
793 break;
794
797 if (pInstance && !(pInstance->CBFflags & CBF_SKIP_CONNECT_CONFIRMS))
798 {
799 WDML_CONV* pConv;
800 /* confirm connection...
801 * lookup for this conv handle
802 */
805 for (pConv = pInstance->convs[WDML_SERVER_SIDE]; pConv != NULL; pConv = pConv->next)
806 {
807 if (pConv->hwndClient == client && pConv->hwndServer == server)
808 break;
809 }
810 if (pConv)
811 {
812 pConv->wStatus |= ST_ISLOCAL;
813
815 pConv->hszTopic, pConv->hszService, 0, 0,
816 (pConv->wStatus & ST_ISSELF) ? 1 : 0);
817 }
818 }
819 break;
820 default:
821 return DefWindowProcW(hwndEvent, uMsg, wParam, lParam);
822 }
823 return 0;
824}
825
826/******************************************************************
827 * WDML_Initialize
828 *
829 *
830 */
832 DWORD afCmd, DWORD ulRes, BOOL bUnicode)
833{
835 WDML_INSTANCE* reference_inst;
836 UINT ret;
837 WNDCLASSEXW wndclass;
838
839 TRACE("(%p,%p,0x%lx,%ld,0x%x)\n",
840 pidInst, pfnCallback, afCmd, ulRes, bUnicode);
841
842 if (ulRes)
843 {
844 ERR("Reserved value not zero? What does this mean?\n");
845 /* trap this and no more until we know more */
846 return DMLERR_NO_ERROR;
847 }
848
849 /* grab enough heap for one control struct - not really necessary for re-initialise
850 * but allows us to use same validation routines */
852 if (pInstance == NULL)
853 {
854 /* catastrophe !! warn user & abort */
855 ERR("Instance create failed - out of memory\n");
856 return DMLERR_SYS_ERROR;
857 }
858 pInstance->next = NULL;
859 pInstance->monitor = (afCmd | APPCLASS_MONITOR);
860
861 /* messy bit, spec implies that 'Client Only' can be set in 2 different ways, catch 1 here */
862
863 pInstance->clientOnly = afCmd & APPCMD_CLIENTONLY;
864 pInstance->instanceID = *pidInst; /* May need to add calling proc Id */
865 pInstance->threadID = GetCurrentThreadId();
866 pInstance->callback = *pfnCallback;
867 pInstance->unicode = bUnicode;
868 pInstance->nodeList = NULL; /* node will be added later */
869 pInstance->monitorFlags = afCmd & MF_MASK;
870 pInstance->wStatus = 0;
871 pInstance->lastError = DMLERR_NO_ERROR;
872 pInstance->servers = NULL;
873 pInstance->convs[0] = NULL;
874 pInstance->convs[1] = NULL;
875 pInstance->links[0] = NULL;
876 pInstance->links[1] = NULL;
877
878 /* isolate CBF flags in one go, expect this will go the way of all attempts to be clever !! */
879
880 pInstance->CBFflags = afCmd^((afCmd&MF_MASK)|((afCmd&APPCMD_MASK)|(afCmd&APPCLASS_MASK)));
881
882 if (!pInstance->clientOnly)
883 {
884 /* Check for other way of setting Client-only !! */
885 pInstance->clientOnly =
887 }
888
889 TRACE("instance created - checking validity\n");
890
891 if (*pidInst == 0)
892 {
893 /* Initialisation of new Instance Identifier */
894 TRACE("new instance, callback %p flags %lX\n", pfnCallback, afCmd);
895
897
898 if (WDML_InstanceList == NULL)
899 {
900 /* can't be another instance in this case, assign to the base pointer */
902
903 /* since first must force filter of XTYP_CONNECT and XTYP_WILDCONNECT for
904 * present
905 * ------------------------------- NOTE NOTE NOTE --------------------------
906 *
907 * the manual is not clear if this condition
908 * applies to the first call to DdeInitialize from an application, or the
909 * first call for a given callback !!!
910 */
911
912 pInstance->CBFflags = pInstance->CBFflags|APPCMD_FILTERINITS;
913 TRACE("First application instance detected OK\n");
914 /* allocate new instance ID */
916 }
917 else
918 {
919 /* really need to chain the new one in to the latest here, but after checking conditions
920 * such as trying to start a conversation from an application trying to monitor */
921 reference_inst = WDML_InstanceList;
922 TRACE("Subsequent application instance - starting checks\n");
923 while (reference_inst->next != NULL)
924 {
925 /*
926 * This set of tests will work if application uses same instance Id
927 * at application level once allocated - which is what manual implies
928 * should happen. If someone tries to be
929 * clever (lazy ?) it will fail to pick up that later calls are for
930 * the same application - should we trust them ?
931 */
932 if (pInstance->instanceID == reference_inst->instanceID)
933 {
934 /* Check 1 - must be same Client-only state */
935
936 if (pInstance->clientOnly != reference_inst->clientOnly)
937 {
939 goto theError;
940 }
941
942 /* Check 2 - cannot use 'Monitor' with any non-monitor modes */
943
944 if (pInstance->monitor != reference_inst->monitor)
945 {
947 goto theError;
948 }
949
950 /* Check 3 - must supply different callback address */
951
952 if (pInstance->callback == reference_inst->callback)
953 {
955 goto theError;
956 }
957 }
958 reference_inst = reference_inst->next;
959 }
960 /* All cleared, add to chain */
961
962 TRACE("Application Instance checks finished\n");
964 reference_inst->next = pInstance;
965 }
967
968 *pidInst = pInstance->instanceID;
969
970 /* for deadlock issues, windows must always be created when outside the critical section */
971 wndclass.cbSize = sizeof(wndclass);
972 wndclass.style = 0;
973 wndclass.lpfnWndProc = WDML_EventProc;
974 wndclass.cbClsExtra = 0;
975 wndclass.cbWndExtra = sizeof(ULONG_PTR);
976 wndclass.hInstance = 0;
977 wndclass.hIcon = 0;
978 wndclass.hCursor = 0;
979 wndclass.hbrBackground = 0;
980 wndclass.lpszMenuName = NULL;
982 wndclass.hIconSm = 0;
983
984 RegisterClassExW(&wndclass);
985
987 WS_POPUP, 0, 0, 0, 0,
988 0, 0, 0, 0);
989
991
992 TRACE("New application instance processing finished OK\n");
993 }
994 else
995 {
996 /* Reinitialisation situation --- FIX */
997 TRACE("reinitialisation of (%p,%p,0x%lx,%ld): stub\n", pidInst, pfnCallback, afCmd, ulRes);
998
1000
1001 if (WDML_InstanceList == NULL)
1002 {
1004 goto theError;
1005 }
1006 /* can't reinitialise if we have initialised nothing !! */
1007 reference_inst = WDML_InstanceList;
1008 /* must first check if we have been given a valid instance to re-initialise !! how do we do that ? */
1009 /*
1010 * MS allows initialisation without specifying a callback, should we allow addition of the
1011 * callback by a later call to initialise ? - if so this lot will have to change
1012 */
1013 while (reference_inst->next != NULL)
1014 {
1015 if (*pidInst == reference_inst->instanceID && pfnCallback == reference_inst->callback)
1016 {
1017 /* Check 1 - cannot change client-only mode if set via APPCMD_CLIENTONLY */
1018
1019 if (reference_inst->clientOnly)
1020 {
1021 if ((reference_inst->CBFflags & CBF_FAIL_ALLSVRXACTIONS) != CBF_FAIL_ALLSVRXACTIONS)
1022 {
1023 /* i.e. Was set to Client-only and through APPCMD_CLIENTONLY */
1024
1025 if (!(afCmd & APPCMD_CLIENTONLY))
1026 {
1028 goto theError;
1029 }
1030 }
1031 }
1032 /* Check 2 - cannot change monitor modes */
1033
1034 if (pInstance->monitor != reference_inst->monitor)
1035 {
1037 goto theError;
1038 }
1039
1040 /* Check 3 - trying to set Client-only via APPCMD when not set so previously */
1041
1042 if ((afCmd&APPCMD_CLIENTONLY) && !reference_inst->clientOnly)
1043 {
1045 goto theError;
1046 }
1047 break;
1048 }
1049 reference_inst = reference_inst->next;
1050 }
1051 if (reference_inst->next == NULL)
1052 {
1054 goto theError;
1055 }
1056 /* All checked - change relevant flags */
1057
1058 reference_inst->CBFflags = pInstance->CBFflags;
1059 reference_inst->clientOnly = pInstance->clientOnly;
1060 reference_inst->monitorFlags = pInstance->monitorFlags;
1061
1062 HeapFree(GetProcessHeap(), 0, pInstance); /* finished - release heap space used as work store */
1063
1065 }
1066
1067 return DMLERR_NO_ERROR;
1068 theError:
1071 return ret;
1072}
1073
1074/******************************************************************************
1075 * DdeInitializeA (USER32.@)
1076 *
1077 * See DdeInitializeW.
1078 */
1080 DWORD afCmd, DWORD ulRes)
1081{
1082 return WDML_Initialize(pidInst, pfnCallback, afCmd, ulRes, FALSE);
1083}
1084
1085/******************************************************************************
1086 * DdeInitializeW [USER32.@]
1087 * Registers an application with the DDEML
1088 *
1089 * PARAMS
1090 * pidInst [I] Pointer to instance identifier
1091 * pfnCallback [I] Pointer to callback function
1092 * afCmd [I] Set of command and filter flags
1093 * ulRes [I] Reserved
1094 *
1095 * RETURNS
1096 * Success: DMLERR_NO_ERROR
1097 * Failure: DMLERR_DLL_USAGE, DMLERR_INVALIDPARAMETER, DMLERR_SYS_ERROR
1098 */
1100 DWORD afCmd, DWORD ulRes)
1101{
1102 return WDML_Initialize(pidInst, pfnCallback, afCmd, ulRes, TRUE);
1103}
1104
1105/*****************************************************************
1106 * DdeUninitialize [USER32.@] Frees DDEML resources
1107 *
1108 * PARAMS
1109 * idInst [I] Instance identifier
1110 *
1111 * RETURNS
1112 * Success: TRUE
1113 * Failure: FALSE
1114 */
1115
1117{
1118 /* Stage one - check if we have a handle for this instance
1119 */
1121 WDML_CONV* pConv;
1122 WDML_CONV* pConvNext;
1123
1124 TRACE("(%ld)\n", idInst);
1125
1126 /* First check instance
1127 */
1128 pInstance = WDML_GetInstance(idInst);
1129 if (pInstance == NULL)
1130 {
1131 /*
1132 * Needs something here to record NOT_INITIALIZED ready for DdeGetLastError
1133 */
1134 return FALSE;
1135 }
1136
1137 /* first terminate all conversations client side
1138 * this shall close existing links...
1139 */
1140 for (pConv = pInstance->convs[WDML_CLIENT_SIDE]; pConv != NULL; pConv = pConvNext)
1141 {
1142 pConvNext = pConv->next;
1143 DdeDisconnect((HCONV)pConv);
1144 }
1145 if (pInstance->convs[WDML_CLIENT_SIDE])
1146 FIXME("still pending conversations\n");
1147
1148 /* then unregister all known service names */
1149 DdeNameService(idInst, 0, 0, DNS_UNREGISTER);
1150
1151 /* Free the nodes that were not freed by this instance
1152 * and remove the nodes from the list of HSZ nodes.
1153 */
1155
1156 NtUserDestroyWindow( pInstance->hwndEvent );
1157
1158 /* OK now delete the instance handle itself */
1159
1161 {
1162 /* special case - the first/only entry */
1164 }
1165 else
1166 {
1167 /* general case, remove entry */
1168 WDML_INSTANCE* inst;
1169
1170 for (inst = WDML_InstanceList; inst->next != pInstance; inst = inst->next);
1171 inst->next = pInstance->next;
1172 }
1173 /* release the heap entry
1174 */
1176
1177 return TRUE;
1178}
1179
1180/******************************************************************
1181 * WDML_NotifyThreadExit
1182 *
1183 *
1184 */
1186{
1190
1193 {
1194 next = pInstance->next;
1195 if (pInstance->threadID == tid)
1196 {
1198 DdeUninitialize(pInstance->instanceID);
1200 }
1201 }
1203}
1204
1205/******************************************************************
1206 * WDML_InvokeCallback
1207 *
1208 *
1209 */
1210HDDEDATA WDML_InvokeCallback(WDML_INSTANCE* pInstance, UINT uType, UINT uFmt, HCONV hConv,
1211 HSZ hsz1, HSZ hsz2, HDDEDATA hdata,
1212 ULONG_PTR dwData1, ULONG_PTR dwData2)
1213{
1214 HDDEDATA ret;
1215
1216 if (pInstance == NULL)
1217 return NULL;
1218
1219 TRACE("invoking CB[%p] (%x %x %p %p %p %p %Ix %Ix)\n",
1220 pInstance->callback, uType, uFmt,
1221 hConv, hsz1, hsz2, hdata, dwData1, dwData2);
1222 ret = pInstance->callback(uType, uFmt, hConv, hsz1, hsz2, hdata, dwData1, dwData2);
1223 TRACE("done => %p\n", ret);
1224 return ret;
1225}
1226
1227/*****************************************************************************
1228 * WDML_GetInstance
1229 *
1230 * generic routine to return a pointer to the relevant DDE_HANDLE_ENTRY
1231 * for an instance Id, or NULL if the entry does not exist
1232 *
1233 */
1235{
1237
1239
1241 {
1242 if (pInstance->instanceID == instId)
1243 {
1244 if (GetCurrentThreadId() != pInstance->threadID)
1245 {
1246 FIXME("Tried to get instance from wrong thread\n");
1247 continue;
1248 }
1249 break;
1250 }
1251 }
1252
1254
1255 if (!pInstance)
1256 WARN("Instance entry missing for id %04lx\n", instId);
1257 return pInstance;
1258}
1259
1260/******************************************************************
1261 * WDML_GetInstanceFromWnd
1262 *
1263 *
1264 */
1266{
1268}
1269
1270/* ================================================================
1271 *
1272 * Data handle management
1273 *
1274 * ================================================================ */
1275
1276/*****************************************************************
1277 * DdeCreateDataHandle (USER32.@)
1278 */
1279HDDEDATA WINAPI DdeCreateDataHandle(DWORD idInst, LPBYTE pSrc, DWORD cb, DWORD cbOff,
1280 HSZ hszItem, UINT wFmt, UINT afCmd)
1281{
1282
1283 /* Other than check for validity we will ignore for now idInst, hszItem.
1284 * The purpose of these arguments still need to be investigated.
1285 */
1286
1288 HGLOBAL hMem;
1289 LPBYTE pByte;
1290 DDE_DATAHANDLE_HEAD* pDdh;
1291 WCHAR psz[MAX_BUFFER_LEN];
1292
1293 pInstance = WDML_GetInstance(idInst);
1294 if (pInstance == NULL)
1295 {
1297 return NULL;
1298 }
1299
1300 if (!GetAtomNameW(HSZ2ATOM(hszItem), psz, MAX_BUFFER_LEN))
1301 {
1302 psz[0] = HSZ2ATOM(hszItem);
1303 psz[1] = 0;
1304 }
1305
1306 TRACE("(%ld,%p,cb %ld, cbOff %ld,%p <%s>,fmt %04x,%x)\n",
1307 idInst, pSrc, cb, cbOff, hszItem, debugstr_w(psz), wFmt, afCmd);
1308
1309 if (afCmd != 0 && afCmd != HDATA_APPOWNED)
1310 return 0;
1311
1312 /* we use the first 4 bytes to store the size */
1313 if (!(hMem = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, cb + cbOff + sizeof(DDE_DATAHANDLE_HEAD))))
1314 {
1315 ERR("GlobalAlloc failed\n");
1316 return 0;
1317 }
1318
1319 pDdh = GlobalLock(hMem);
1320 if (!pDdh)
1321 {
1322 GlobalFree(hMem);
1323 return 0;
1324 }
1325
1326 pDdh->cfFormat = wFmt;
1327 pDdh->bAppOwned = (afCmd == HDATA_APPOWNED);
1328
1329 pByte = (LPBYTE)(pDdh + 1);
1330 if (pSrc)
1331 {
1332 if (cbOff) memset(pByte, 0, cbOff);
1333 memcpy(pByte + cbOff, pSrc, cb);
1334 }
1335 GlobalUnlock(hMem);
1336
1337 TRACE("=> %p\n", hMem);
1338 return hMem;
1339}
1340
1341/*****************************************************************
1342 *
1343 * DdeAddData (USER32.@)
1344 */
1345HDDEDATA WINAPI DdeAddData(HDDEDATA hData, LPBYTE pSrc, DWORD cb, DWORD cbOff)
1346{
1347 DWORD old_sz, new_sz;
1348 LPBYTE pDst;
1349
1350 TRACE("(%p,%p,cb %ld, cbOff %ld)\n", hData, pSrc, cb, cbOff);
1351
1352 pDst = DdeAccessData(hData, &old_sz);
1353 if (!pDst) return 0;
1354
1355 new_sz = cb + cbOff;
1356 if (new_sz > old_sz)
1357 {
1358 DdeUnaccessData(hData);
1359 hData = GlobalReAlloc(hData, new_sz + sizeof(DDE_DATAHANDLE_HEAD),
1361 pDst = DdeAccessData(hData, &old_sz);
1362 }
1363
1364 if (!pDst) return 0;
1365
1366 memcpy(pDst + cbOff, pSrc, cb);
1367 DdeUnaccessData(hData);
1368 return hData;
1369}
1370
1371/******************************************************************************
1372 * DdeGetData [USER32.@] Copies data from DDE object to local buffer
1373 *
1374 *
1375 * PARAMS
1376 * hData [I] Handle to DDE object
1377 * pDst [I] Pointer to destination buffer
1378 * cbMax [I] Amount of data to copy
1379 * cbOff [I] Offset to beginning of data
1380 *
1381 * RETURNS
1382 * Size of memory object associated with handle
1383 */
1384DWORD WINAPI DdeGetData(HDDEDATA hData, LPBYTE pDst, DWORD cbMax, DWORD cbOff)
1385{
1386 DWORD dwSize, dwRet;
1387 LPBYTE pByte;
1388
1389 TRACE("(%p,%p,%ld,%ld)\n", hData, pDst, cbMax, cbOff);
1390
1391 pByte = DdeAccessData(hData, &dwSize);
1392
1393 if (pByte)
1394 {
1395 if (!pDst)
1396 {
1397 dwRet = dwSize;
1398 }
1399 else if (cbOff + cbMax < dwSize)
1400 {
1401 dwRet = cbMax;
1402 }
1403 else if (cbOff < dwSize)
1404 {
1405 dwRet = dwSize - cbOff;
1406 }
1407 else
1408 {
1409 dwRet = 0;
1410 }
1411 if (pDst && dwRet != 0)
1412 {
1413 memcpy(pDst, pByte + cbOff, dwRet);
1414 }
1415 DdeUnaccessData(hData);
1416 }
1417 else
1418 {
1419 dwRet = 0;
1420 }
1421 return dwRet;
1422}
1423
1424/*****************************************************************
1425 * DdeAccessData (USER32.@)
1426 */
1427LPBYTE WINAPI DdeAccessData(HDDEDATA hData, LPDWORD pcbDataSize)
1428{
1429 HGLOBAL hMem = hData;
1430 DDE_DATAHANDLE_HEAD* pDdh;
1431
1432 TRACE("(%p,%p)\n", hData, pcbDataSize);
1433
1434 pDdh = GlobalLock(hMem);
1435 if (pDdh == NULL)
1436 {
1437 ERR("Failed on GlobalLock(%p)\n", hMem);
1438 return 0;
1439 }
1440
1441 if (pcbDataSize != NULL)
1442 {
1443 *pcbDataSize = GlobalSize(hMem) - sizeof(DDE_DATAHANDLE_HEAD);
1444 }
1445 TRACE("=> %p (%Iu) fmt %04x\n", pDdh + 1, GlobalSize(hMem) - sizeof(DDE_DATAHANDLE_HEAD), pDdh->cfFormat);
1446 return (LPBYTE)(pDdh + 1);
1447}
1448
1449/*****************************************************************
1450 * DdeUnaccessData (USER32.@)
1451 */
1453{
1454 HGLOBAL hMem = hData;
1455
1456 TRACE("(%p)\n", hData);
1457
1458 GlobalUnlock(hMem);
1459
1460 return TRUE;
1461}
1462
1463/*****************************************************************
1464 * DdeFreeDataHandle (USER32.@)
1465 */
1467{
1468 TRACE("(%p)\n", hData);
1469
1470 /* 1 is the handle value returned by an asynchronous operation. */
1471 if (hData == (HDDEDATA)1)
1472 return TRUE;
1473
1474 return GlobalFree(hData) == 0;
1475}
1476
1477/******************************************************************
1478 * WDML_IsAppOwned
1479 *
1480 *
1481 */
1482BOOL WDML_IsAppOwned(HDDEDATA hData)
1483{
1484 DDE_DATAHANDLE_HEAD* pDdh;
1485 BOOL ret = FALSE;
1486
1487 pDdh = GlobalLock(hData);
1488 if (pDdh != NULL)
1489 {
1490 ret = pDdh->bAppOwned;
1491 GlobalUnlock(hData);
1492 }
1493 return ret;
1494}
1495
1496/* ================================================================
1497 *
1498 * Global <=> Data handle management
1499 *
1500 * ================================================================ */
1501
1502/* Note: we use a DDEDATA, but layout of DDEDATA, DDEADVISE and DDEPOKE structures is similar:
1503 * offset size
1504 * (bytes) (bits) comment
1505 * 0 16 bit fields for options (release, ackreq, response...)
1506 * 2 16 clipboard format
1507 * 4 ? data to be used
1508 */
1510{
1511 DDEDATA* pDd;
1512 HDDEDATA ret = 0;
1513 DWORD size;
1514
1515 if (hMem)
1516 {
1517 pDd = GlobalLock(hMem);
1518 size = GlobalSize(hMem) - sizeof(WINE_DDEHEAD);
1519 if (pDd)
1520 {
1521 if (p) memcpy(p, pDd, sizeof(WINE_DDEHEAD));
1522 switch (pDd->cfFormat)
1523 {
1524 default:
1525 FIXME("Unsupported format (%04x) for data %p, passing raw information\n",
1526 pDd->cfFormat, hMem);
1527 /* fall through */
1528 case 0:
1529 case CF_TEXT:
1530 ret = DdeCreateDataHandle(pConv->instance->instanceID, pDd->Value, size, 0, 0, pDd->cfFormat, 0);
1531 break;
1532 case CF_BITMAP:
1533 if (size >= sizeof(BITMAP))
1534 {
1535 BITMAP* bmp = (BITMAP*)pDd->Value;
1537 if (size >= sizeof(BITMAP) + count)
1538 {
1539 HBITMAP hbmp;
1540
1543 pDd->Value + sizeof(BITMAP))))
1544 {
1545 ret = DdeCreateDataHandle(pConv->instance->instanceID, (LPBYTE)&hbmp, sizeof(hbmp),
1546 0, 0, CF_BITMAP, 0);
1547 }
1548 else ERR("Can't create bmp\n");
1549 }
1550 else
1551 {
1552 ERR("Wrong count: %lu / %d\n", size, count);
1553 }
1554 } else ERR("No bitmap header\n");
1555 break;
1556 }
1557 GlobalUnlock(hMem);
1558 }
1559 }
1560 return ret;
1561}
1562
1563/******************************************************************
1564 * WDML_DataHandle2Global
1565 *
1566 *
1567 */
1568HGLOBAL WDML_DataHandle2Global(HDDEDATA hDdeData, BOOL fResponse, BOOL fRelease,
1569 BOOL fDeferUpd, BOOL fAckReq)
1570{
1571 DDE_DATAHANDLE_HEAD* pDdh;
1572 DWORD dwSize;
1573 HGLOBAL hMem = 0;
1574
1575 dwSize = GlobalSize(hDdeData) - sizeof(DDE_DATAHANDLE_HEAD);
1576 pDdh = GlobalLock(hDdeData);
1577 if (dwSize && pDdh)
1578 {
1579 WINE_DDEHEAD* wdh = NULL;
1580
1581 switch (pDdh->cfFormat)
1582 {
1583 default:
1584 FIXME("Unsupported format (%04x) for data %p, passing raw information\n",
1585 pDdh->cfFormat, hDdeData);
1586 /* fall through */
1587 case 0:
1588 case CF_TEXT:
1590 if (hMem && (wdh = GlobalLock(hMem)))
1591 {
1592 memcpy(wdh + 1, pDdh + 1, dwSize);
1593 }
1594 break;
1595 case CF_BITMAP:
1596 if (dwSize >= sizeof(HBITMAP))
1597 {
1598 BITMAP bmp;
1599 DWORD count;
1600 HBITMAP hbmp = *(HBITMAP*)(pDdh + 1);
1601
1602 if (GetObjectW(hbmp, sizeof(bmp), &bmp))
1603 {
1606 sizeof(WINE_DDEHEAD) + sizeof(bmp) + count);
1607 if (hMem && (wdh = GlobalLock(hMem)))
1608 {
1609 memcpy(wdh + 1, &bmp, sizeof(bmp));
1610 GetBitmapBits(hbmp, count, ((char*)(wdh + 1)) + sizeof(bmp));
1611 }
1612 }
1613 }
1614 break;
1615 }
1616 if (wdh)
1617 {
1618 wdh->unused = 0;
1619 wdh->fResponse = fResponse;
1620 wdh->fRelease = fRelease;
1621 wdh->fDeferUpd = fDeferUpd;
1622 wdh->fAckReq = fAckReq;
1623 wdh->cfFormat = pDdh->cfFormat;
1624 GlobalUnlock(hMem);
1625 }
1626 GlobalUnlock(hDdeData);
1627 }
1628
1629 return hMem;
1630}
1631
1632/* ================================================================
1633 *
1634 * Server management
1635 *
1636 * ================================================================ */
1637
1638/******************************************************************
1639 * WDML_AddServer
1640 *
1641 *
1642 */
1644{
1645 WDML_SERVER* pServer;
1646 WCHAR buf1[256];
1647 WCHAR buf2[256];
1648
1649 pServer = HeapAlloc(GetProcessHeap(), 0, sizeof(WDML_SERVER));
1650 if (pServer == NULL) return NULL;
1651
1652 pServer->hszService = hszService;
1653 WDML_IncHSZ(pInstance, hszService);
1654
1655 DdeQueryStringW(pInstance->instanceID, hszService, buf1, 256, CP_WINUNICODE);
1656#ifdef __REACTOS__
1657 swprintf(buf2, 256, L"%s(0x%*x)", buf1, (int)(2*sizeof(ULONG_PTR)), GetCurrentProcessId());
1658#else
1659 swprintf(buf2, 256, L"%s(0x%*x)", buf1, 2*sizeof(ULONG_PTR), GetCurrentProcessId());
1660#endif
1661 pServer->hszServiceSpec = DdeCreateStringHandleW(pInstance->instanceID, buf2, CP_WINUNICODE);
1662
1663 pServer->atomService = WDML_MakeAtomFromHsz(pServer->hszService);
1665
1666 pServer->filterOn = TRUE;
1667
1668 pServer->next = pInstance->servers;
1669 pInstance->servers = pServer;
1670 return pServer;
1671}
1672
1673/******************************************************************
1674 * WDML_RemoveServer
1675 *
1676 *
1677 */
1679{
1680 WDML_SERVER* pPrev = NULL;
1681 WDML_SERVER* pServer = NULL;
1682 WDML_CONV* pConv;
1683 WDML_CONV* pConvNext;
1684
1685 pServer = pInstance->servers;
1686
1687 while (pServer != NULL)
1688 {
1689 if (DdeCmpStringHandles(pServer->hszService, hszService) == 0)
1690 {
1692 pServer->atomService, pServer->atomServiceSpec);
1693 /* terminate all conversations for given topic */
1694 for (pConv = pInstance->convs[WDML_SERVER_SIDE]; pConv != NULL; pConv = pConvNext)
1695 {
1696 pConvNext = pConv->next;
1697 if (DdeCmpStringHandles(pConv->hszService, hszService) == 0)
1698 {
1699 HWND client = pConv->hwndClient, server = pConv->hwndServer;
1701 /* don't care about return code (whether client window is present or not) */
1703 }
1704 }
1705 if (pServer == pInstance->servers)
1706 {
1707 pInstance->servers = pServer->next;
1708 }
1709 else
1710 {
1711 pPrev->next = pServer->next;
1712 }
1713
1716 WDML_DecHSZ(pInstance, pServer->hszService);
1717
1718 GlobalDeleteAtom(pServer->atomService);
1720
1721 HeapFree(GetProcessHeap(), 0, pServer);
1722 break;
1723 }
1724
1725 pPrev = pServer;
1726 pServer = pServer->next;
1727 }
1728}
1729
1730/*****************************************************************************
1731 * WDML_FindServer
1732 *
1733 * generic routine to return a pointer to the relevant ServiceNode
1734 * for a given service name, or NULL if the entry does not exist
1735 *
1736 */
1738{
1739 WDML_SERVER* pServer;
1740
1741 for (pServer = pInstance->servers; pServer != NULL; pServer = pServer->next)
1742 {
1743 if (hszService == pServer->hszService)
1744 {
1745 return pServer;
1746 }
1747 }
1748 TRACE("Service name missing\n");
1749 return NULL;
1750}
1751
1752/* ================================================================
1753 *
1754 * Link (hot & warm) management
1755 *
1756 * ================================================================ */
1757
1758/******************************************************************
1759 * WDML_AddLink
1760 *
1761 *
1762 */
1764 UINT wType, HSZ hszItem, UINT wFmt)
1765{
1766 WDML_LINK* pLink;
1767
1768 pLink = HeapAlloc(GetProcessHeap(), 0, sizeof(WDML_LINK));
1769 if (pLink == NULL)
1770 {
1771 ERR("OOM\n");
1772 return;
1773 }
1774
1775 pLink->hConv = hConv;
1776 pLink->transactionType = wType;
1777 WDML_IncHSZ(pInstance, pLink->hszItem = hszItem);
1778 pLink->uFmt = wFmt;
1779 pLink->next = pInstance->links[side];
1780 pInstance->links[side] = pLink;
1781}
1782
1783/******************************************************************
1784 * WDML_RemoveLink
1785 *
1786 *
1787 */
1789 HSZ hszItem, UINT uFmt)
1790{
1791 WDML_LINK* pPrev = NULL;
1792 WDML_LINK* pCurrent = NULL;
1793
1794 pCurrent = pInstance->links[side];
1795
1796 while (pCurrent != NULL)
1797 {
1798 if (pCurrent->hConv == hConv &&
1799 DdeCmpStringHandles(pCurrent->hszItem, hszItem) == 0 &&
1800 pCurrent->uFmt == uFmt)
1801 {
1802 if (pCurrent == pInstance->links[side])
1803 {
1804 pInstance->links[side] = pCurrent->next;
1805 }
1806 else
1807 {
1808 pPrev->next = pCurrent->next;
1809 }
1810
1811 WDML_DecHSZ(pInstance, pCurrent->hszItem);
1812 HeapFree(GetProcessHeap(), 0, pCurrent);
1813 break;
1814 }
1815
1816 pPrev = pCurrent;
1817 pCurrent = pCurrent->next;
1818 }
1819}
1820
1821/* this function is called to remove all links related to the conv.
1822 It should be called from both client and server when terminating
1823 the conversation.
1824*/
1825/******************************************************************
1826 * WDML_RemoveAllLinks
1827 *
1828 *
1829 */
1831{
1832 WDML_LINK* pPrev = NULL;
1833 WDML_LINK* pCurrent = NULL;
1834 WDML_LINK* pNext = NULL;
1835
1836 pCurrent = pInstance->links[side];
1837
1838 while (pCurrent != NULL)
1839 {
1840 if (pCurrent->hConv == (HCONV)pConv)
1841 {
1842 if (pCurrent == pInstance->links[side])
1843 {
1844 pInstance->links[side] = pCurrent->next;
1845 pNext = pCurrent->next;
1846 }
1847 else
1848 {
1849 pPrev->next = pCurrent->next;
1850 pNext = pCurrent->next;
1851 }
1852
1853 WDML_DecHSZ(pInstance, pCurrent->hszItem);
1854
1855 HeapFree(GetProcessHeap(), 0, pCurrent);
1856 pCurrent = NULL;
1857 }
1858
1859 if (pCurrent)
1860 {
1861 pPrev = pCurrent;
1862 pCurrent = pCurrent->next;
1863 }
1864 else
1865 {
1866 pCurrent = pNext;
1867 }
1868 }
1869}
1870
1871/******************************************************************
1872 * WDML_FindLink
1873 *
1874 *
1875 */
1877 HSZ hszItem, BOOL use_fmt, UINT uFmt)
1878{
1879 WDML_LINK* pCurrent;
1880
1881 for (pCurrent = pInstance->links[side]; pCurrent != NULL; pCurrent = pCurrent->next)
1882 {
1883 /* we don't need to check for transaction type as it can be altered */
1884
1885 if (pCurrent->hConv == hConv &&
1886 DdeCmpStringHandles(pCurrent->hszItem, hszItem) == 0 &&
1887 (!use_fmt || pCurrent->uFmt == uFmt))
1888 {
1889 break;
1890 }
1891
1892 }
1893
1894 return pCurrent;
1895}
1896
1897/* ================================================================
1898 *
1899 * Transaction management
1900 *
1901 * ================================================================ */
1902
1903/******************************************************************
1904 * WDML_AllocTransaction
1905 *
1906 * Alloc a transaction structure for handling the message ddeMsg
1907 */
1909 UINT wFmt, HSZ hszItem)
1910{
1911 WDML_XACT* pXAct;
1912 static WORD tid = 1; /* FIXME: wrap around */
1913
1914 pXAct = HeapAlloc(GetProcessHeap(), 0, sizeof(WDML_XACT));
1915 if (!pXAct)
1916 {
1917 pInstance->lastError = DMLERR_MEMORY_ERROR;
1918 return NULL;
1919 }
1920
1921 pXAct->xActID = tid++;
1922 pXAct->ddeMsg = ddeMsg;
1923 pXAct->hDdeData = 0;
1924 pXAct->hUser = 0;
1925 pXAct->next = NULL;
1926 pXAct->wType = 0;
1927 pXAct->wFmt = wFmt;
1928 if ((pXAct->hszItem = hszItem)) WDML_IncHSZ(pInstance, pXAct->hszItem);
1929 pXAct->atom = 0;
1930 pXAct->hMem = 0;
1931 pXAct->lParam = 0;
1932
1933 return pXAct;
1934}
1935
1936/******************************************************************
1937 * WDML_QueueTransaction
1938 *
1939 * Adds a transaction to the list of transaction
1940 */
1942{
1943 WDML_XACT** pt;
1944
1945 /* advance to last in queue */
1946 for (pt = &pConv->transactions; *pt != NULL; pt = &(*pt)->next);
1947 *pt = pXAct;
1948}
1949
1950/******************************************************************
1951 * WDML_UnQueueTransaction
1952 *
1953 *
1954 */
1956{
1957 WDML_XACT** pt;
1958
1959 for (pt = &pConv->transactions; *pt; pt = &(*pt)->next)
1960 {
1961 if (*pt == pXAct)
1962 {
1963 *pt = pXAct->next;
1964 return TRUE;
1965 }
1966 }
1967 return FALSE;
1968}
1969
1970/******************************************************************
1971 * WDML_FreeTransaction
1972 *
1973 *
1974 */
1976{
1977 /* free pmt(s) in pXAct too. check against one for not deleting TRUE return values */
1978 if (doFreePmt && (ULONG_PTR)pXAct->hMem > 1)
1979 {
1980 GlobalFree(pXAct->hMem);
1981 }
1982 if (pXAct->hszItem) WDML_DecHSZ(pInstance, pXAct->hszItem);
1983
1984 HeapFree(GetProcessHeap(), 0, pXAct);
1985}
1986
1987/******************************************************************
1988 * WDML_FindTransaction
1989 *
1990 *
1991 */
1993{
1994 WDML_XACT* pXAct;
1995
1996 tid = HIWORD(tid);
1997 for (pXAct = pConv->transactions; pXAct; pXAct = pXAct->next)
1998 {
1999 if (pXAct->xActID == tid)
2000 break;
2001 }
2002 return pXAct;
2003}
2004
2005/* ================================================================
2006 *
2007 * Conversation management
2008 *
2009 * ================================================================ */
2010
2011/******************************************************************
2012 * WDML_AddConv
2013 *
2014 *
2015 */
2017 HSZ hszService, HSZ hszTopic, HWND hwndClient, HWND hwndServer)
2018{
2019 WDML_CONV* pConv;
2020
2021 /* no conversation yet, add it */
2022 pConv = HeapAlloc(GetProcessHeap(), 0, sizeof(WDML_CONV));
2023 if (!pConv) return NULL;
2024
2025 pConv->instance = pInstance;
2026 WDML_IncHSZ(pInstance, pConv->hszService = hszService);
2028 pConv->magic = WDML_CONV_MAGIC;
2029 pConv->hwndServer = hwndServer;
2030 pConv->hwndClient = hwndClient;
2031 pConv->transactions = NULL;
2032 pConv->hUser = 0;
2033 pConv->wStatus = (side == WDML_CLIENT_SIDE) ? ST_CLIENT : 0L;
2034 pConv->wStatus |= pInstance->wStatus;
2035 /* check if both side of the conversation are of the same instance */
2036 if (GetWindowThreadProcessId(hwndClient, NULL) == GetWindowThreadProcessId(hwndServer, NULL) &&
2037 WDML_GetInstanceFromWnd(hwndClient) == WDML_GetInstanceFromWnd(hwndServer))
2038 {
2039 pConv->wStatus |= ST_ISSELF;
2040 }
2041 pConv->wConvst = XST_NULL;
2042
2043 pConv->next = pInstance->convs[side];
2044 pInstance->convs[side] = pConv;
2045
2046 TRACE("pConv->wStatus %04lx pInstance(%p)\n", pConv->wStatus, pInstance);
2047
2048 return pConv;
2049}
2050
2051/******************************************************************
2052 * WDML_FindConv
2053 *
2054 *
2055 */
2057 HSZ hszService, HSZ hszTopic)
2058{
2059 WDML_CONV* pCurrent;
2060
2061 for (pCurrent = pInstance->convs[side]; pCurrent != NULL; pCurrent = pCurrent->next)
2062 {
2063 if (DdeCmpStringHandles(pCurrent->hszService, hszService) == 0 &&
2064 DdeCmpStringHandles(pCurrent->hszTopic, hszTopic) == 0)
2065 {
2066 return pCurrent;
2067 }
2068
2069 }
2070 return NULL;
2071}
2072
2073/******************************************************************
2074 * WDML_RemoveConv
2075 *
2076 *
2077 */
2079{
2080 WDML_CONV* pPrev = NULL;
2081 WDML_CONV* pCurrent;
2082 WDML_XACT* pXAct;
2083 WDML_XACT* pXActNext;
2084 HWND hWnd;
2085
2086 if (!pRef)
2087 return;
2088
2089 /* remove any pending transaction */
2090 for (pXAct = pRef->transactions; pXAct != NULL; pXAct = pXActNext)
2091 {
2092 pXActNext = pXAct->next;
2093 WDML_FreeTransaction(pRef->instance, pXAct, TRUE);
2094 }
2095
2096 WDML_RemoveAllLinks(pRef->instance, pRef, side);
2097
2098 /* FIXME: should we keep the window around ? it seems so (at least on client side
2099 * to let QueryConvInfo work after conv termination, but also to implement
2100 * DdeReconnect...
2101 */
2102 /* destroy conversation window, but first remove pConv from hWnd.
2103 * this would help the wndProc do appropriate handling upon a WM_DESTROY message
2104 */
2105 hWnd = (side == WDML_CLIENT_SIDE) ? pRef->hwndClient : pRef->hwndServer;
2107
2108 NtUserDestroyWindow((side == WDML_CLIENT_SIDE) ? pRef->hwndClient : pRef->hwndServer);
2109
2110 WDML_DecHSZ(pRef->instance, pRef->hszService);
2111 WDML_DecHSZ(pRef->instance, pRef->hszTopic);
2112
2113 for (pCurrent = pRef->instance->convs[side]; pCurrent != NULL; pCurrent = (pPrev = pCurrent)->next)
2114 {
2115 if (pCurrent == pRef)
2116 {
2117 if (pCurrent == pRef->instance->convs[side])
2118 {
2119 pRef->instance->convs[side] = pCurrent->next;
2120 }
2121 else
2122 {
2123 pPrev->next = pCurrent->next;
2124 }
2125 /* Ensure compiler doesn't optimize out the assignment with 0. */
2126 SecureZeroMemory(&pCurrent->magic, sizeof(pCurrent->magic));
2127 HeapFree(GetProcessHeap(), 0, pCurrent);
2128 break;
2129 }
2130 }
2131}
2132
2133/******************************************************************
2134 * WDML_EnableCallback
2135 */
2137{
2138 if (wCmd == EC_DISABLE)
2139 {
2140 pConv->wStatus |= ST_BLOCKED;
2141 TRACE("EC_DISABLE: conv %p status flags %04lx\n", pConv, pConv->wStatus);
2142 return TRUE;
2143 }
2144
2145 if (wCmd == EC_QUERYWAITING)
2146 return pConv->transactions != NULL;
2147
2148 if (wCmd != EC_ENABLEALL && wCmd != EC_ENABLEONE)
2149 {
2150 FIXME("Unknown command code %04x\n", wCmd);
2151 return FALSE;
2152 }
2153
2154 if (wCmd == EC_ENABLEALL)
2155 {
2156 pConv->wStatus &= ~ST_BLOCKED;
2157 TRACE("EC_ENABLEALL: conv %p status flags %04lx\n", pConv, pConv->wStatus);
2158 }
2159
2160 while (pConv->transactions)
2161 {
2162 WDML_XACT *pXAct = pConv->transactions;
2163
2164 if (pConv->wStatus & ST_CLIENT)
2165 {
2166 /* transaction should be in the queue until handled */
2167 WDML_ClientHandle(pConv, pXAct, 0, NULL);
2168 WDML_UnQueueTransaction(pConv, pXAct);
2169 }
2170 else
2171 {
2172 /* transaction should be removed from the queue before handling */
2173 WDML_UnQueueTransaction(pConv, pXAct);
2174 WDML_ServerHandle(pConv, pXAct);
2175 }
2176
2177 WDML_FreeTransaction(pConv->instance, pXAct, TRUE);
2178
2179 if (wCmd == EC_ENABLEONE) break;
2180 }
2181 return TRUE;
2182}
2183
2184/*****************************************************************
2185 * DdeEnableCallback (USER32.@)
2186 */
2187BOOL WINAPI DdeEnableCallback(DWORD idInst, HCONV hConv, UINT wCmd)
2188{
2189 BOOL ret = FALSE;
2190 WDML_CONV *pConv;
2191
2192 TRACE("(%ld, %p, %04x)\n", idInst, hConv, wCmd);
2193
2194 if (hConv)
2195 {
2196 pConv = WDML_GetConv(hConv, TRUE);
2197
2198 if (pConv && pConv->instance->instanceID == idInst)
2199 ret = WDML_EnableCallback(pConv, wCmd);
2200 }
2201 else
2202 {
2204
2205 if (!pInstance)
2206 return FALSE;
2207
2208 TRACE("adding flags %04x to instance %p\n", wCmd, pInstance);
2209 pInstance->wStatus |= wCmd;
2210
2211 if (wCmd == EC_DISABLE)
2212 {
2213 pInstance->wStatus |= ST_BLOCKED;
2214 TRACE("EC_DISABLE: inst %p status flags %04lx\n", pInstance, pInstance->wStatus);
2215 }
2216 else if (wCmd == EC_ENABLEALL)
2217 {
2218 pInstance->wStatus &= ~ST_BLOCKED;
2219 TRACE("EC_ENABLEALL: inst %p status flags %04lx\n", pInstance, pInstance->wStatus);
2220 }
2221
2222 ret = TRUE;
2223
2224 for (pConv = pInstance->convs[WDML_CLIENT_SIDE]; pConv != NULL; pConv = pConv->next)
2225 {
2226 ret = WDML_EnableCallback(pConv, wCmd);
2227 if (ret && wCmd == EC_QUERYWAITING) break;
2228 }
2229 }
2230
2231 return ret;
2232}
2233
2234/******************************************************************
2235 * WDML_GetConv
2236 *
2237 *
2238 */
2239WDML_CONV* WDML_GetConv(HCONV hConv, BOOL checkConnected)
2240{
2241 WDML_CONV* pConv = (WDML_CONV*)hConv;
2242
2243 /* FIXME: should do better checking */
2244 if (pConv == NULL || pConv->magic != WDML_CONV_MAGIC) return NULL;
2245
2246 if (!pConv->instance)
2247 {
2248 WARN("wrong thread ID, no instance\n");
2249 return NULL;
2250 }
2251
2252 if (pConv->instance->threadID != GetCurrentThreadId())
2253 {
2254 WARN("wrong thread ID\n");
2255 pConv->instance->lastError = DMLERR_INVALIDPARAMETER; /* FIXME: check */
2256 return NULL;
2257 }
2258
2259 if (checkConnected && !(pConv->wStatus & ST_CONNECTED))
2260 {
2261 WARN("found conv but ain't connected\n");
2262 pConv->instance->lastError = DMLERR_NO_CONV_ESTABLISHED;
2263 return NULL;
2264 }
2265
2266 return pConv;
2267}
2268
2269/******************************************************************
2270 * WDML_GetConvFromWnd
2271 *
2272 *
2273 */
2275{
2277}
2278
2279/******************************************************************
2280 * WDML_PostAck
2281 *
2282 *
2283 */
2284BOOL WDML_PostAck(WDML_CONV* pConv, WDML_SIDE side, WORD appRetCode,
2285 BOOL fBusy, BOOL fAck, UINT_PTR pmt, LPARAM lParam, UINT oldMsg)
2286{
2287 DDEACK ddeAck;
2288 HWND from, to;
2289
2290 if (side == WDML_SERVER_SIDE)
2291 {
2292 from = pConv->hwndServer;
2293 to = pConv->hwndClient;
2294 }
2295 else
2296 {
2297 to = pConv->hwndServer;
2298 from = pConv->hwndClient;
2299 }
2300
2301 ddeAck.bAppReturnCode = appRetCode;
2302 ddeAck.reserved = 0;
2303 ddeAck.fBusy = fBusy;
2304 ddeAck.fAck = fAck;
2305
2306 TRACE("Posting a %s ack\n", ddeAck.fAck ? "positive" : "negative");
2307
2308 lParam = (lParam) ? ReuseDDElParam(lParam, oldMsg, WM_DDE_ACK, *(WORD*)&ddeAck, pmt) :
2309 PackDDElParam(WM_DDE_ACK, *(WORD*)&ddeAck, pmt);
2311 {
2312 pConv->wStatus &= ~ST_CONNECTED;
2313 pConv->instance->lastError = DMLERR_POSTMSG_FAILED;
2315 return FALSE;
2316 }
2317 return TRUE;
2318}
2319
2320/*****************************************************************
2321 * DdeSetUserHandle (USER32.@)
2322 */
2323BOOL WINAPI DdeSetUserHandle(HCONV hConv, DWORD id, DWORD hUser)
2324{
2325 WDML_CONV* pConv;
2326
2327 pConv = WDML_GetConv(hConv, FALSE);
2328 if (pConv == NULL)
2329 return FALSE;
2330
2331 if (id == QID_SYNC)
2332 {
2333 pConv->hUser = hUser;
2334 }
2335 else
2336 {
2337 WDML_XACT* pXAct;
2338
2339 pXAct = WDML_FindTransaction(pConv, id);
2340 if (pXAct)
2341 {
2342 pXAct->hUser = hUser;
2343 }
2344 else
2345 {
2346 pConv->instance->lastError = DMLERR_UNFOUND_QUEUE_ID;
2347 return FALSE;
2348 }
2349 }
2350 return TRUE;
2351}
2352
2353/******************************************************************
2354 * WDML_GetLocalConvInfo
2355 *
2356 *
2357 */
2359{
2360 BOOL ret = TRUE;
2361 WDML_LINK* pLink;
2362 WDML_SIDE side;
2363
2364 ci->hConvPartner = (pConv->wStatus & ST_ISLOCAL) ? (HCONV)((ULONG_PTR)pConv | 1) : 0;
2365 ci->hszSvcPartner = pConv->hszService;
2366 ci->hszServiceReq = pConv->hszService; /* FIXME: they shouldn't be the same, should they ? */
2367 ci->hszTopic = pConv->hszTopic;
2368 ci->wStatus = pConv->wStatus;
2369
2370 side = (pConv->wStatus & ST_CLIENT) ? WDML_CLIENT_SIDE : WDML_SERVER_SIDE;
2371
2372 for (pLink = pConv->instance->links[side]; pLink != NULL; pLink = pLink->next)
2373 {
2374 if (pLink->hConv == (HCONV)pConv)
2375 {
2376 ci->wStatus |= ST_ADVISE;
2377 break;
2378 }
2379 }
2380
2381 /* FIXME: non handled status flags:
2382 ST_BLOCKED
2383 ST_BLOCKNEXT
2384 ST_INLIST
2385 */
2386
2387 ci->wConvst = pConv->wConvst; /* FIXME */
2388
2389 ci->wLastError = 0; /* FIXME: note it's not the instance last error */
2390 ci->hConvList = 0;
2391 ci->ConvCtxt = pConv->convContext;
2392 if (ci->wStatus & ST_CLIENT)
2393 {
2394 ci->hwnd = pConv->hwndClient;
2395 ci->hwndPartner = pConv->hwndServer;
2396 }
2397 else
2398 {
2399 ci->hwnd = pConv->hwndServer;
2400 ci->hwndPartner = pConv->hwndClient;
2401 }
2402 if (id == QID_SYNC)
2403 {
2404 ci->hUser = pConv->hUser;
2405 ci->hszItem = 0;
2406 ci->wFmt = 0;
2407 ci->wType = 0;
2408 }
2409 else
2410 {
2411 WDML_XACT* pXAct;
2412
2413 pXAct = WDML_FindTransaction(pConv, id);
2414 if (pXAct)
2415 {
2416 ci->hUser = pXAct->hUser;
2417 ci->hszItem = pXAct->hszItem;
2418 ci->wFmt = pXAct->wFmt;
2419 ci->wType = pXAct->wType;
2420 }
2421 else
2422 {
2423 ret = 0;
2424 pConv->instance->lastError = DMLERR_UNFOUND_QUEUE_ID;
2425 }
2426 }
2427 return ret;
2428}
2429
2430/******************************************************************
2431 * DdeQueryConvInfo (USER32.@)
2432 *
2433 * FIXME: Set last DDE error on failure.
2434 */
2435UINT WINAPI DdeQueryConvInfo(HCONV hConv, DWORD id, PCONVINFO lpConvInfo)
2436{
2437 UINT ret = lpConvInfo->cb;
2438 CONVINFO ci;
2439 WDML_CONV* pConv;
2440
2441 TRACE("(%p,%lx,%p)\n", hConv, id, lpConvInfo);
2442
2443 if (!hConv)
2444 {
2445 FIXME("hConv is NULL\n");
2446 return 0;
2447 }
2448
2449 pConv = WDML_GetConv(hConv, FALSE);
2450 if (pConv != NULL)
2451 {
2452 if (!WDML_GetLocalConvInfo(pConv, &ci, id))
2453 ret = 0;
2454 }
2455 else
2456 {
2457 if ((ULONG_PTR)hConv & 1)
2458 {
2459 pConv = WDML_GetConv((HCONV)((ULONG_PTR)hConv & ~1), FALSE);
2460 if (pConv != NULL)
2461 FIXME("Request on remote conversation information is not implemented yet\n");
2462 }
2463 ret = 0;
2464 }
2465
2466 if (ret != 0)
2467 {
2468 ci.cb = lpConvInfo->cb;
2469 memcpy(lpConvInfo, &ci, min((size_t)lpConvInfo->cb, sizeof(ci)));
2470 }
2471 return ret;
2472}
2473
2474/* ================================================================
2475 *
2476 * Information broadcast across DDEML implementations
2477 *
2478 * ================================================================ */
2479
2481{
2486};
2487
2488/******************************************************************
2489 * WDML_BroadcastEnumProc
2490 *
2491 *
2492 */
2494{
2496 WCHAR buffer[128];
2497
2498 if (GetClassNameW(hWnd, buffer, 128) > 0 &&
2499 lstrcmpiW(buffer, s->clsName) == 0)
2500 {
2501 PostMessageW(hWnd, s->uMsg, s->wParam, s->lParam);
2502 }
2503 return TRUE;
2504}
2505
2506/******************************************************************
2507 * WDML_BroadcastDDEWindows
2508 *
2509 *
2510 */
2512{
2513 struct tagWDML_BroadcastPmt s;
2514
2515 s.clsName = clsName;
2516 s.uMsg = uMsg;
2517 s.wParam = wParam;
2518 s.lParam = lParam;
2520}
UINT cchMax
#define InterlockedIncrement
Definition: armddk.h:53
#define msg(x)
Definition: auth_time.c:54
HWND hWnd
Definition: settings.c:17
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define CF_BITMAP
Definition: constants.h:397
#define CF_TEXT
Definition: constants.h:396
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
HBITMAP hbmp
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
#define WM_DDE_DATA
Definition: dde.h:42
#define WM_DDE_POKE
Definition: dde.h:44
#define WM_DDE_ADVISE
Definition: dde.h:39
#define WM_DDE_ACK
Definition: dde.h:41
#define WM_DDE_EXECUTE
Definition: dde.h:45
#define WM_DDE_TERMINATE
Definition: dde.h:38
#define WM_WDML_CONNECT_CONFIRM
Definition: dde_private.h:253
WDML_QUEUE_STATE WDML_ServerHandle(WDML_CONV *pConv, WDML_XACT *pXAct)
Definition: ddeserver.c:978
#define GWL_WDML_CONVERSATION
Definition: dde_private.h:263
enum tagWDML_SIDE WDML_SIDE
struct tagDDE_DATAHANDLE_HEAD DDE_DATAHANDLE_HEAD
#define WDML_CONV_MAGIC
Definition: dde_private.h:144
HDDEDATA WDML_ClientHandle(WDML_CONV *pConv, WDML_XACT *pXAct, DWORD dwTimeout, LPDWORD pdwResult)
Definition: ddeclient.c:1095
#define WM_WDML_REGISTER
Definition: dde_private.h:251
@ WDML_SERVER_SIDE
Definition: dde_private.h:184
@ WDML_CLIENT_SIDE
Definition: dde_private.h:184
#define MAX_BUFFER_LEN
Definition: dde_private.h:37
#define WM_WDML_UNREGISTER
Definition: dde_private.h:252
#define GWL_WDML_INSTANCE
Definition: dde_private.h:262
void WDML_QueueTransaction(WDML_CONV *pConv, WDML_XACT *pXAct)
Definition: ddemisc.c:1941
static int WDML_QueryString(WDML_INSTANCE *pInstance, HSZ hsz, LPVOID ptr, DWORD cchMax, int codepage)
Definition: ddemisc.c:465
BOOL WINAPI DdeUnaccessData(HDDEDATA hData)
Definition: ddemisc.c:1452
static BOOL CALLBACK WDML_BroadcastEnumProc(HWND hWnd, LPARAM lParam)
Definition: ddemisc.c:2493
WDML_INSTANCE * WDML_GetInstanceFromWnd(HWND hWnd)
Definition: ddemisc.c:1265
static HSZ WDML_CreateString(WDML_INSTANCE *pInstance, LPCVOID ptr, int codepage)
Definition: ddemisc.c:554
HDDEDATA WDML_Global2DataHandle(WDML_CONV *pConv, HGLOBAL hMem, WINE_DDEHEAD *p)
Definition: ddemisc.c:1509
static WDML_XACT * WDML_FindTransaction(WDML_CONV *pConv, DWORD tid)
Definition: ddemisc.c:1992
BOOL WINAPI DdeUninitialize(DWORD idInst)
Definition: ddemisc.c:1116
#define ATOM2HSZ(atom)
Definition: ddemisc.c:33
BOOL WINAPI DdeFreeDataHandle(HDDEDATA hData)
Definition: ddemisc.c:1466
const WCHAR WDML_szEventClass[]
Definition: ddemisc.c:41
WDML_CONV * WDML_AddConv(WDML_INSTANCE *pInstance, WDML_SIDE side, HSZ hszService, HSZ hszTopic, HWND hwndClient, HWND hwndServer)
Definition: ddemisc.c:2016
HDDEDATA WDML_InvokeCallback(WDML_INSTANCE *pInstance, UINT uType, UINT uFmt, HCONV hConv, HSZ hsz1, HSZ hsz2, HDDEDATA hdata, ULONG_PTR dwData1, ULONG_PTR dwData2)
Definition: ddemisc.c:1210
static BOOL WDML_GetLocalConvInfo(WDML_CONV *pConv, CONVINFO *ci, DWORD id)
Definition: ddemisc.c:2358
static void WDML_IncrementInstanceId(WDML_INSTANCE *pInstance)
Definition: ddemisc.c:750
WDML_CONV * WDML_GetConv(HCONV hConv, BOOL checkConnected)
Definition: ddemisc.c:2239
UINT WINAPI DdeQueryConvInfo(HCONV hConv, DWORD id, PCONVINFO lpConvInfo)
Definition: ddemisc.c:2435
BOOL WDML_PostAck(WDML_CONV *pConv, WDML_SIDE side, WORD appRetCode, BOOL fBusy, BOOL fAck, UINT_PTR pmt, LPARAM lParam, UINT oldMsg)
Definition: ddemisc.c:2284
HSZ WDML_MakeHszFromAtom(const WDML_INSTANCE *pInstance, ATOM atom)
Definition: ddemisc.c:346
void WDML_RemoveLink(WDML_INSTANCE *pInstance, HCONV hConv, WDML_SIDE side, HSZ hszItem, UINT uFmt)
Definition: ddemisc.c:1788
INT WINAPI DdeCmpStringHandles(HSZ hsz1, HSZ hsz2)
Definition: ddemisc.c:689
static void WDML_FreeAllHSZ(WDML_INSTANCE *pInstance)
Definition: ddemisc.c:423
static void WDML_SetAllLastError(DWORD lastError)
Definition: ddemisc.c:283
void WDML_FreeTransaction(WDML_INSTANCE *pInstance, WDML_XACT *pXAct, BOOL doFreePmt)
Definition: ddemisc.c:1975
static void WDML_InsertHSZNode(WDML_INSTANCE *pInstance, HSZ hsz)
Definition: ddemisc.c:438
HDDEDATA WINAPI DdeCreateDataHandle(DWORD idInst, LPBYTE pSrc, DWORD cb, DWORD cbOff, HSZ hszItem, UINT wFmt, UINT afCmd)
Definition: ddemisc.c:1279
static CRITICAL_SECTION_DEBUG critsect_debug
Definition: ddemisc.c:46
BOOL WINAPI ImpersonateDdeClientWindow(HWND hWndClient, HWND hWndServer)
Definition: ddemisc.c:225
BOOL WDML_IncHSZ(WDML_INSTANCE *pInstance, HSZ hsz)
Definition: ddemisc.c:366
WDML_SERVER * WDML_AddServer(WDML_INSTANCE *pInstance, HSZ hszService, HSZ hszTopic)
Definition: ddemisc.c:1643
BOOL WDML_DecHSZ(WDML_INSTANCE *pInstance, HSZ hsz)
Definition: ddemisc.c:384
static HSZNode * WDML_FindNode(WDML_INSTANCE *pInstance, HSZ hsz)
Definition: ddemisc.c:309
BOOL WINAPI DdeKeepStringHandle(DWORD idInst, HSZ hsz)
Definition: ddemisc.c:658
void WDML_RemoveConv(WDML_CONV *pRef, WDML_SIDE side)
Definition: ddemisc.c:2078
WDML_INSTANCE * WDML_GetInstance(DWORD instId)
Definition: ddemisc.c:1234
BOOL WINAPI UnpackDDElParam(UINT msg, LPARAM lParam, PUINT_PTR uiLo, PUINT_PTR uiHi)
Definition: ddemisc.c:109
static UINT WDML_Initialize(LPDWORD pidInst, PFNCALLBACK pfnCallback, DWORD afCmd, DWORD ulRes, BOOL bUnicode)
Definition: ddemisc.c:831
HSZ WINAPI DdeCreateStringHandleW(DWORD idInst, LPCWSTR psz, INT codepage)
Definition: ddemisc.c:612
BOOL WINAPI DdeFreeStringHandle(DWORD idInst, HSZ hsz)
Definition: ddemisc.c:635
WDML_XACT * WDML_AllocTransaction(WDML_INSTANCE *pInstance, UINT ddeMsg, UINT wFmt, HSZ hszItem)
Definition: ddemisc.c:1908
UINT WINAPI DdeInitializeA(LPDWORD pidInst, PFNCALLBACK pfnCallback, DWORD afCmd, DWORD ulRes)
Definition: ddemisc.c:1079
void WDML_RemoveServer(WDML_INSTANCE *pInstance, HSZ hszService, HSZ hszTopic)
Definition: ddemisc.c:1678
ATOM WDML_MakeAtomFromHsz(HSZ hsz)
Definition: ddemisc.c:329
static WDML_INSTANCE * WDML_InstanceList
Definition: ddemisc.c:36
UINT WINAPI DdeInitializeW(LPDWORD pidInst, PFNCALLBACK pfnCallback, DWORD afCmd, DWORD ulRes)
Definition: ddemisc.c:1099
BOOL WINAPI DdeSetQualityOfService(HWND hwndClient, const SECURITY_QUALITY_OF_SERVICE *pqosNew, PSECURITY_QUALITY_OF_SERVICE pqosPrev)
Definition: ddemisc.c:235
void WDML_NotifyThreadDetach(void)
Definition: ddemisc.c:1185
BOOL WINAPI DdeEnableCallback(DWORD idInst, HCONV hConv, UINT wCmd)
Definition: ddemisc.c:2187
#define HSZ2ATOM(hsz)
Definition: ddemisc.c:34
LPBYTE WINAPI DdeAccessData(HDDEDATA hData, LPDWORD pcbDataSize)
Definition: ddemisc.c:1427
DWORD WINAPI DdeGetData(HDDEDATA hData, LPBYTE pDst, DWORD cbMax, DWORD cbOff)
Definition: ddemisc.c:1384
static LONG WDML_MaxInstanceID
Definition: ddemisc.c:37
static BOOL WDML_EnableCallback(WDML_CONV *pConv, UINT wCmd)
Definition: ddemisc.c:2136
WDML_LINK * WDML_FindLink(WDML_INSTANCE *pInstance, HCONV hConv, WDML_SIDE side, HSZ hszItem, BOOL use_fmt, UINT uFmt)
Definition: ddemisc.c:1876
HGLOBAL WDML_DataHandle2Global(HDDEDATA hDdeData, BOOL fResponse, BOOL fRelease, BOOL fDeferUpd, BOOL fAckReq)
Definition: ddemisc.c:1568
WDML_CONV * WDML_FindConv(WDML_INSTANCE *pInstance, WDML_SIDE side, HSZ hszService, HSZ hszTopic)
Definition: ddemisc.c:2056
static CRITICAL_SECTION WDML_CritSect
Definition: ddemisc.c:45
BOOL WDML_UnQueueTransaction(WDML_CONV *pConv, WDML_XACT *pXAct)
Definition: ddemisc.c:1955
UINT WINAPI DdeGetLastError(DWORD idInst)
Definition: ddemisc.c:257
static void WDML_RemoveAllLinks(WDML_INSTANCE *pInstance, WDML_CONV *pConv, WDML_SIDE side)
Definition: ddemisc.c:1830
DWORD WINAPI DdeQueryStringA(DWORD idInst, HSZ hsz, LPSTR psz, DWORD cchMax, INT iCodePage)
Definition: ddemisc.c:505
DWORD WINAPI DdeQueryStringW(DWORD idInst, HSZ hsz, LPWSTR psz, DWORD cchMax, INT iCodePage)
Definition: ddemisc.c:529
LPARAM WINAPI PackDDElParam(UINT msg, UINT_PTR uiLo, UINT_PTR uiHi)
Definition: ddemisc.c:67
BOOL WDML_IsAppOwned(HDDEDATA hData)
Definition: ddemisc.c:1482
static LRESULT CALLBACK WDML_EventProc(HWND hwndEvent, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: ddemisc.c:763
LPARAM WINAPI ReuseDDElParam(LPARAM lParam, UINT msgIn, UINT msgOut, UINT_PTR uiLo, UINT_PTR uiHi)
Definition: ddemisc.c:175
HSZ WINAPI DdeCreateStringHandleA(DWORD idInst, LPCSTR psz, INT codepage)
Definition: ddemisc.c:581
BOOL WINAPI FreeDDElParam(UINT msg, LPARAM lParam)
Definition: ddemisc.c:151
WDML_SERVER * WDML_FindServer(WDML_INSTANCE *pInstance, HSZ hszService, HSZ hszTopic)
Definition: ddemisc.c:1737
WDML_CONV * WDML_GetConvFromWnd(HWND hWnd)
Definition: ddemisc.c:2274
void WDML_AddLink(WDML_INSTANCE *pInstance, HCONV hConv, WDML_SIDE side, UINT wType, HSZ hszItem, UINT wFmt)
Definition: ddemisc.c:1763
BOOL WINAPI DdeSetUserHandle(HCONV hConv, DWORD id, DWORD hUser)
Definition: ddemisc.c:2323
HDDEDATA WINAPI DdeAddData(HDDEDATA hData, LPBYTE pSrc, DWORD cb, DWORD cbOff)
Definition: ddemisc.c:1345
void WDML_BroadcastDDEWindows(LPCWSTR clsName, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: ddemisc.c:2511
#define HDATA_APPOWNED
Definition: ddeml.h:267
#define ST_CONNECTED
Definition: ddeml.h:80
#define ST_CLIENT
Definition: ddeml.h:84
#define DNS_UNREGISTER
Definition: ddeml.h:153
#define CBF_SKIP_CONNECT_CONFIRMS
Definition: ddeml.h:111
#define XST_NULL
Definition: ddeml.h:62
#define DMLERR_POSTMSG_FAILED
Definition: ddeml.h:258
#define DMLERR_NO_ERROR
Definition: ddeml.h:242
#define EC_ENABLEALL
Definition: ddeml.h:94
#define APPCMD_FILTERINITS
Definition: ddeml.h:123
#define DMLERR_UNFOUND_QUEUE_ID
Definition: ddeml.h:263
#define DMLERR_MEMORY_ERROR
Definition: ddeml.h:254
#define XTYP_CONNECT_CONFIRM
Definition: ddeml.h:187
#define ST_ISLOCAL
Definition: ddeml.h:82
#define XTYP_UNREGISTER
Definition: ddeml.h:193
#define XTYP_REGISTER
Definition: ddeml.h:190
#define APPCLASS_MASK
Definition: ddeml.h:132
#define APPCMD_MASK
Definition: ddeml.h:124
#define ST_ISSELF
Definition: ddeml.h:88
#define EC_DISABLE
Definition: ddeml.h:96
#define APPCLASS_MONITOR
Definition: ddeml.h:131
HDDEDATA(CALLBACK * PFNCALLBACK)(UINT, UINT, HCONV, HSZ, HSZ, HDDEDATA, ULONG_PTR, ULONG_PTR)
Definition: ddeml.h:290
#define MF_MASK
Definition: ddeml.h:146
BOOL WINAPI DdeDisconnect(HCONV)
Definition: ddeclient.c:1368
#define QID_SYNC
Definition: ddeml.h:40
#define ST_BLOCKED
Definition: ddeml.h:83
#define CBF_SKIP_REGISTRATIONS
Definition: ddeml.h:112
#define CP_WINANSI
Definition: ddeml.h:32
#define EC_QUERYWAITING
Definition: ddeml.h:97
HDDEDATA WINAPI DdeNameService(DWORD, HSZ, HSZ, UINT)
Definition: ddeserver.c:159
#define CP_WINUNICODE
Definition: ddeml.h:33
#define DMLERR_NO_CONV_ESTABLISHED
Definition: ddeml.h:256
#define DMLERR_DLL_USAGE
Definition: ddeml.h:250
#define DMLERR_SYS_ERROR
Definition: ddeml.h:261
#define CBF_FAIL_ALLSVRXACTIONS
Definition: ddeml.h:109
#define EC_ENABLEONE
Definition: ddeml.h:95
#define APPCMD_CLIENTONLY
Definition: ddeml.h:122
#define ST_ADVISE
Definition: ddeml.h:81
#define DMLERR_INVALIDPARAMETER
Definition: ddeml.h:252
#define CBF_SKIP_UNREGISTRATIONS
Definition: ddeml.h:113
WORD ATOM
Definition: dimm.idl:113
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define HeapFree(x, y, z)
Definition: compat.h:735
#define CALLBACK
Definition: compat.h:35
UINT WINAPI GetAtomNameW(ATOM nAtom, LPWSTR lpBuffer, int nSize)
Definition: atom.c:569
UINT WINAPI GlobalGetAtomNameW(ATOM nAtom, LPWSTR lpBuffer, int nSize)
Definition: atom.c:476
ATOM WINAPI AddAtomA(LPCSTR lpString)
Definition: atom.c:506
ATOM WINAPI DeleteAtom(ATOM nAtom)
Definition: atom.c:526
ATOM WINAPI AddAtomW(LPCWSTR lpString)
Definition: atom.c:516
UINT WINAPI GetAtomNameA(ATOM nAtom, LPSTR lpBuffer, int nSize)
Definition: atom.c:557
ATOM WINAPI GlobalDeleteAtom(ATOM nAtom)
Definition: atom.c:444
ATOM WINAPI GlobalAddAtomW(LPCWSTR lpString)
Definition: atom.c:434
int WINAPI lstrcmpiW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4171
static MonoProfilerRuntimeShutdownBeginCallback cb
Definition: metahost.c:118
#define pt(x, y)
Definition: drawing.c:79
return ret
Definition: mutex.c:147
#define L(x)
Definition: resources.c:13
#define ULONG_PTR
Definition: config.h:101
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
FxString * pString
FxWmiInstanceExternal * pInstance
Definition: fxwmiapi.cpp:117
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLdouble s
Definition: gl.h:2039
GLuint buffer
Definition: glext.h:5915
GLsizeiptr size
Definition: glext.h:5919
GLfloat GLfloat p
Definition: glext.h:8902
GLenum const GLfloat * params
Definition: glext.h:5645
GLuint id
Definition: glext.h:5910
unsigned int UINT
Definition: sysinfo.c:13
HGLOBAL NTAPI GlobalHandle(LPCVOID pMem)
Definition: heapmem.c:705
HGLOBAL NTAPI GlobalFree(HGLOBAL hMem)
Definition: heapmem.c:611
HGLOBAL NTAPI GlobalReAlloc(HGLOBAL hMem, SIZE_T dwBytes, UINT uFlags)
Definition: heapmem.c:825
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
HGLOBAL NTAPI GlobalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:368
SIZE_T NTAPI GlobalSize(HGLOBAL hMem)
Definition: heapmem.c:1090
BOOLEAN NTAPI NtUserDestroyWindow(HWND Wnd)
Definition: window.c:3041
static TfClientId tid
static ERESOURCE GlobalLock
Definition: sys_arch.c:8
#define debugstr_a
Definition: kernel32.h:31
#define debugstr_w
Definition: kernel32.h:32
if(dx< 0)
Definition: linetemp.h:194
LONG_PTR LPARAM
Definition: minwindef.h:175
LONG_PTR LRESULT
Definition: minwindef.h:176
UINT_PTR WPARAM
Definition: minwindef.h:174
CONST void * LPCVOID
Definition: minwindef.h:164
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
static PVOID ptr
Definition: dispmode.c:27
BITMAP bmp
Definition: alphablend.c:62
static HBITMAP
Definition: button.c:44
#define min(a, b)
Definition: monoChain.cc:55
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
#define LOWORD(l)
Definition: pedump.c:82
short WCHAR
Definition: pedump.c:58
#define WS_POPUP
Definition: pedump.c:616
long LONG
Definition: pedump.c:60
char CHAR
Definition: pedump.c:57
_In_opt_ void _In_ DWORD _In_opt_ LPTHREAD_START_ROUTINE pfnCallback
Definition: shlwapi.h:66
#define GetWindowLongPtrW
Definition: winuser.h:4983
#define MAKELPARAM(l, h)
Definition: winuser.h:4116
LRESULT WINAPI DefWindowProcW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
BOOL WINAPI PostMessageW(_In_opt_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
BOOL WINAPI EnumWindows(_In_ WNDENUMPROC lpEnumFunc, _In_ LPARAM lParam)
ATOM WINAPI RegisterClassExW(_In_ CONST WNDCLASSEXW *)
#define CreateWindowW(a, b, c, d, e, f, g, h, i, j, k)
Definition: winuser.h:4470
int WINAPI GetClassNameW(_In_ HWND hWnd, _Out_writes_to_(nMaxCount, return) LPWSTR lpClassName, _In_ int nMaxCount)
#define SetWindowLongPtrW
Definition: winuser.h:5512
#define memset(x, y, z)
Definition: compat.h:39
static FILE * client
Definition: client.c:37
static HSZ hszTopic
Definition: shlexec.c:148
#define TRACE(s)
Definition: solgame.cpp:4
CardRegion * from
Definition: spigame.cpp:19
Definition: dde.h:51
unsigned short fBusy
Definition: dde.h:52
unsigned short fAck
Definition: dde.h:52
unsigned short reserved
Definition: dde.h:52
unsigned short bAppReturnCode
Definition: dde.h:52
Definition: dde.h:57
BYTE Value[1]
Definition: dde.h:60
short cfFormat
Definition: dde.h:59
unsigned short unused
Definition: dde_private.h:86
unsigned short fRelease
Definition: dde_private.h:88
unsigned short fResponse
Definition: dde_private.h:87
unsigned short fAckReq
Definition: dde_private.h:90
unsigned short fDeferUpd
Definition: dde_private.h:89
short cfFormat
Definition: dde_private.h:91
LPCWSTR lpszClassName
Definition: winuser.h:3334
LPCWSTR lpszMenuName
Definition: winuser.h:3333
HBRUSH hbrBackground
Definition: winuser.h:3332
WNDPROC lpfnWndProc
Definition: winuser.h:3326
UINT cbSize
Definition: winuser.h:3324
int cbWndExtra
Definition: winuser.h:3328
HCURSOR hCursor
Definition: winuser.h:3331
HICON hIconSm
Definition: winuser.h:3335
HINSTANCE hInstance
Definition: winuser.h:3329
UINT style
Definition: winuser.h:3325
int cbClsExtra
Definition: winuser.h:3327
HICON hIcon
Definition: winuser.h:3330
LONG bmHeight
Definition: wingdi.h:1869
LONG bmWidth
Definition: wingdi.h:1868
LONG bmWidthBytes
Definition: wingdi.h:1870
WORD bmPlanes
Definition: wingdi.h:1871
WORD bmBitsPixel
Definition: wingdi.h:1872
HWND hwnd
Definition: ddeml.h:331
UINT wLastError
Definition: ddeml.h:328
HSZ hszSvcPartner
Definition: ddeml.h:320
HWND hwndPartner
Definition: ddeml.h:332
HCONVLIST hConvList
Definition: ddeml.h:329
UINT wFmt
Definition: ddeml.h:324
CONVCONTEXT ConvCtxt
Definition: ddeml.h:330
HSZ hszTopic
Definition: ddeml.h:322
HSZ hszItem
Definition: ddeml.h:323
UINT wConvst
Definition: ddeml.h:327
DWORD hUser
Definition: ddeml.h:318
UINT wStatus
Definition: ddeml.h:326
HCONV hConvPartner
Definition: ddeml.h:319
UINT wType
Definition: ddeml.h:325
HSZ hszServiceReq
Definition: ddeml.h:321
DWORD cb
Definition: ddeml.h:317
struct tagHSZNode * next
Definition: dde_private.h:96
unsigned refCount
Definition: dde_private.h:98
struct tagWDML_CONV * next
Definition: dde_private.h:129
CONVCONTEXT convContext
Definition: dde_private.h:135
WDML_XACT * transactions
Definition: dde_private.h:138
struct tagWDML_INSTANCE * instance
Definition: dde_private.h:130
struct tagWDML_INSTANCE * next
Definition: dde_private.h:157
PFNCALLBACK callback
Definition: dde_private.h:164
struct tagWDML_SERVER * next
Definition: dde_private.h:103
ATOM atomServiceSpec
Definition: dde_private.h:107
HDDEDATA hDdeData
Definition: dde_private.h:116
struct tagWDML_XACT * next
Definition: dde_private.h:113
LPARAM lParam
Definition: dde_private.h:124
HGLOBAL hMem
Definition: dde_private.h:123
PSYMCRYPT_PARALLEL_HASH_OPERATION next
#define DWORD_PTR
Definition: treelist.c:76
const char * LPCSTR
Definition: typedefs.h:52
uint32_t * PUINT_PTR
Definition: typedefs.h:65
const uint16_t * LPCWSTR
Definition: typedefs.h:57
unsigned char * LPBYTE
Definition: typedefs.h:53
uint16_t * LPWSTR
Definition: typedefs.h:56
uint32_t * LPDWORD
Definition: typedefs.h:59
char * LPSTR
Definition: typedefs.h:51
int32_t INT
Definition: typedefs.h:58
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define MAKELONG(a, b)
Definition: typedefs.h:249
#define HIWORD(l)
Definition: typedefs.h:247
#define WIN_GetFullHandle(h)
Definition: user_x.h:108
static rfbScreenInfoPtr server
Definition: vnc.c:74
static int error_code[8]
Definition: odbccp32.c:53
int codepage
Definition: win_iconv.c:156
#define SecureZeroMemory
Definition: winbase.h:1441
DWORD WINAPI GetCurrentThreadId(void)
Definition: thread.c:462
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
DWORD WINAPI GetCurrentProcessId(void)
Definition: proc.c:1207
DWORD WINAPI GetWindowThreadProcessId(HWND hWnd, PDWORD lpdwProcessId)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
#define GMEM_MOVEABLE
Definition: winbase.h:318
#define GMEM_DDESHARE
Definition: winbase.h:322
#define WINAPI
Definition: msvc.h:6
#define swprintf
Definition: winemm.h:209
int WINAPI GetObjectW(_In_ HANDLE h, _In_ int c, _Out_writes_bytes_opt_(c) LPVOID pv)
HBITMAP WINAPI CreateBitmap(_In_ INT cx, _In_ INT cy, _In_ UINT cPlanes, _In_ UINT cBitsPerPel, _In_opt_ const VOID *pvBits)
LONG WINAPI GetBitmapBits(_In_ HBITMAP hbit, _In_ LONG cb, _Out_writes_bytes_(cb) LPVOID lpvBits)