ReactOS 0.4.15-dev-7958-gcd0bb1a
dde.c
Go to the documentation of this file.
1/*
2 * Unit tests for DDE functions
3 *
4 * Copyright (c) 2004 Dmitry Timoshkov
5 * Copyright (c) 2007 James Hawkins
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22#include <stdarg.h>
23#include <stdio.h>
24
25#include "windef.h"
26#include "winbase.h"
27#include "winuser.h"
28#include "winnls.h"
29#include "dde.h"
30#include "ddeml.h"
31#include "winerror.h"
32
33#include "wine/test.h"
34
35static const WCHAR TEST_DDE_SERVICE[] = {'T','e','s','t','D','D','E','S','e','r','v','i','c','e',0};
36
37static char exec_cmdA[] = "ANSI dde command";
38static WCHAR exec_cmdAW[] = {'A','N','S','I',' ','d','d','e',' ','c','o','m','m','a','n','d',0};
39static WCHAR exec_cmdW[] = {'u','n','i','c','o','d','e',' ','d','d','e',' ','c','o','m','m','a','n','d',0};
40static char exec_cmdWA[] = "unicode dde command";
41
43
44static const DWORD default_timeout = 200;
45
46static BOOL is_cjk(void)
47{
48 int lang_id = PRIMARYLANGID(GetUserDefaultLangID());
49
50 if (lang_id == LANG_CHINESE || lang_id == LANG_JAPANESE || lang_id == LANG_KOREAN)
51 return TRUE;
52 return FALSE;
53}
54
55static void flush_events(void)
56{
57 MSG msg;
58 int diff = default_timeout;
59 int min_timeout = 50;
60 DWORD time = GetTickCount() + diff;
61
62 while (diff > 0)
63 {
64 if (MsgWaitForMultipleObjects( 0, NULL, FALSE, min_timeout, QS_ALLINPUT ) == WAIT_TIMEOUT) break;
65 while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageA( &msg );
66 diff = time - GetTickCount();
67 min_timeout = 10;
68 }
69}
70
72{
73 WNDCLASSA wcA;
74 ATOM aclass;
75
76 memset(&wcA, 0, sizeof(wcA));
77 wcA.lpfnWndProc = wndproc;
78 wcA.lpszClassName = name;
80 aclass = RegisterClassA(&wcA);
81 ok (aclass, "RegisterClass failed\n");
82
86 ok(*hwnd != NULL, "CreateWindowExA failed\n");
87}
88
90{
93}
94
96{
97 UINT_PTR lo, hi;
98 char str[MAX_PATH], *ptr;
99 HGLOBAL hglobal;
100 DDEDATA *data;
101 DDEPOKE *poke;
102 DWORD size;
103
104 static int msg_index = 0;
105 static HWND client = 0;
106 static BOOL executed = FALSE;
107
108 if (msg < WM_DDE_FIRST || msg > WM_DDE_LAST)
110
111 msg_index++;
112
113 switch (msg)
114 {
115 case WM_DDE_INITIATE:
116 {
117 client = (HWND)wparam;
118 ok(msg_index == 1, "Expected 1, got %d\n", msg_index);
119
121 ok(!lstrcmpA(str, "TestDDEService"), "Expected TestDDEService, got %s\n", str);
122
124 ok(!lstrcmpA(str, "TestDDETopic"), "Expected TestDDETopic, got %s\n", str);
125
127
128 break;
129 }
130
131 case WM_DDE_REQUEST:
132 {
133 ok((msg_index >= 2 && msg_index <= 4) ||
134 (msg_index >= 7 && msg_index <= 8),
135 "Expected 2, 3, 4, 7 or 8, got %d\n", msg_index);
136 ok(wparam == (WPARAM)client, "Expected client hwnd, got %08lx\n", wparam);
137 ok(LOWORD(lparam) == CF_TEXT, "Expected CF_TEXT, got %d\n", LOWORD(lparam));
138
140 if (msg_index < 8)
141 ok(!lstrcmpA(str, "request"), "Expected request, got %s\n", str);
142 else
143 ok(!lstrcmpA(str, "executed"), "Expected executed, got %s\n", str);
144
145 if (msg_index == 8)
146 {
147 if (executed)
148 lstrcpyA(str, "command executed\r\n");
149 else
150 lstrcpyA(str, "command not executed\r\n");
151 }
152 else
153 lstrcpyA(str, "requested data\r\n");
154
156 hglobal = GlobalAlloc(GMEM_MOVEABLE, size);
157 ok(hglobal != NULL, "Expected non-NULL hglobal\n");
158
159 data = GlobalLock(hglobal);
161
162 /* setting fResponse to FALSE at this point destroys
163 * the internal messaging state of native dde
164 */
165 data->fResponse = TRUE;
166
167 if (msg_index == 2)
168 data->fRelease = TRUE;
169 else if (msg_index == 3)
170 data->fAckReq = TRUE;
171
172 data->cfFormat = CF_TEXT;
173 lstrcpyA((LPSTR)data->Value, str);
174 GlobalUnlock(hglobal);
175
178
179 break;
180 }
181
182 case WM_DDE_POKE:
183 {
184 ok(msg_index == 5 || msg_index == 6, "Expected 5 or 6, got %d\n", msg_index);
185 ok(wparam == (WPARAM)client, "Expected client hwnd, got %08lx\n", wparam);
186
188
190 ok(!lstrcmpA(str, "poker"), "Expected poker, got %s\n", str);
191
192 poke = GlobalLock((HGLOBAL)lo);
193 ok(poke != NULL, "Expected non-NULL poke\n");
194 ok(poke->fReserved == 0, "Expected 0, got %d\n", poke->fReserved);
195 ok(poke->unused == 0, "Expected 0, got %d\n", poke->unused);
196 ok(poke->fRelease == TRUE, "Expected TRUE, got %d\n", poke->fRelease);
197 ok(poke->cfFormat == CF_TEXT, "Expected CF_TEXT, got %d\n", poke->cfFormat);
198
199 if (msg_index == 5)
200 {
201 size = GlobalSize((HGLOBAL)lo);
202 ok(size == 4 || broken(size == 32), /* sizes are rounded up on win9x */ "got %d\n", size);
203 }
204 else
205 ok(!lstrcmpA((LPSTR)poke->Value, "poke data\r\n"),
206 "Expected 'poke data\\r\\n', got %s\n", poke->Value);
207
209
212
213 break;
214 }
215
216 case WM_DDE_EXECUTE:
217 {
218 ok(msg_index == 7, "Expected 7, got %d\n", msg_index);
219 ok(wparam == (WPARAM)client, "Expected client hwnd, got %08lx\n", wparam);
220
222 ok(!lstrcmpA(ptr, "[Command(Var)]"), "Expected [Command(Var)], got %s\n", ptr);
224
225 executed = TRUE;
226
229
230 break;
231 }
232
233 case WM_DDE_TERMINATE:
234 {
235 ok(msg_index == 9, "Expected 9, got %d\n", msg_index);
236 ok(wparam == (WPARAM)client, "Expected client hwnd, got %08lx\n", wparam);
237 ok(lparam == 0, "Expected 0, got %08lx\n", lparam);
238
240
241 break;
242 }
243
244 case WM_DDE_ACK: /* happens on win9x when fAckReq is TRUE, ignore it */
245 ok(msg_index == 4, "Expected 4, got %d\n", msg_index);
246 msg_index--;
247 break;
248
249 default:
250 ok(FALSE, "Unhandled msg: %08x\n", msg);
251 }
252
254}
255
256static void test_msg_server(HANDLE hproc, HANDLE hthread)
257{
258 MSG msg;
259 HWND hwnd;
260 DWORD res;
261
263 ResumeThread( hthread );
264
265 while (MsgWaitForMultipleObjects( 1, &hproc, FALSE, INFINITE, QS_ALLINPUT ) != 0)
266 {
267 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
268 }
269
270 destroy_dde_window(&hwnd, "dde_server");
271 GetExitCodeProcess( hproc, &res );
272 ok( !res, "client failed with %u error(s)\n", res );
273}
274
275static HDDEDATA CALLBACK client_ddeml_callback(UINT uType, UINT uFmt, HCONV hconv,
276 HSZ hsz1, HSZ hsz2, HDDEDATA hdata,
277 ULONG_PTR dwData1, ULONG_PTR dwData2)
278{
279 ok(FALSE, "Unhandled msg: %08x\n", uType);
280 return 0;
281}
282
283static void test_ddeml_client(void)
284{
285 UINT ret;
286 char buffer[32];
287 LPSTR str;
288 DWORD size, res;
289 HDDEDATA hdata, op;
290 HSZ server, topic, item;
292 HCONV conversation;
293
294 client_pid = 0;
296 ok(ret == DMLERR_NO_ERROR, "Expected DMLERR_NO_ERROR, got %d\n", ret);
297
298 /* FIXME: make these atoms global and check them in the server */
299
302
304 conversation = DdeConnect(client_pid, server, topic, NULL);
305 ok(conversation != NULL, "Expected non-NULL conversation\n");
307 ok(ret == DMLERR_NO_ERROR, "Expected DMLERR_NO_ERROR, got %d\n", ret);
308
310
312
313 /* XTYP_REQUEST, fRelease = TRUE */
314 res = 0xdeadbeef;
316 hdata = DdeClientTransaction(NULL, 0, conversation, item, CF_TEXT, XTYP_REQUEST, default_timeout, &res);
318 ok(ret == DMLERR_NO_ERROR, "Expected DMLERR_NO_ERROR, got %d\n", ret);
319 ok(res == DDE_FNOTPROCESSED || broken(res == 0xdeadbeef), /* win9x */
320 "Expected DDE_FNOTPROCESSED, got %08x\n", res);
321 ok( hdata != NULL, "hdata is NULL\n" );
322 if (hdata)
323 {
324 str = (LPSTR)DdeAccessData(hdata, &size);
325 ok(!lstrcmpA(str, "requested data\r\n"), "Expected 'requested data\\r\\n', got %s\n", str);
326 ok(size == 17, "Expected 17, got %d\n", size);
327
328 ret = DdeUnaccessData(hdata);
329 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
330 }
331
332 /* XTYP_REQUEST, fAckReq = TRUE */
333 res = 0xdeadbeef;
335 hdata = DdeClientTransaction(NULL, 0, conversation, item, CF_TEXT, XTYP_REQUEST, default_timeout, &res);
337 ok(res == DDE_FNOTPROCESSED || broken(res == 0xdeadbeef), /* win9x */
338 "Expected DDE_FNOTPROCESSED, got %x\n", res);
340 ok(ret == DMLERR_MEMORY_ERROR || broken(ret == 0), /* win9x */
341 "Expected DMLERR_MEMORY_ERROR, got %d\n", ret);
342 ok( hdata != NULL, "hdata is NULL\n" );
343 if (hdata)
344 {
345 str = (LPSTR)DdeAccessData(hdata, &size);
346 ok(!lstrcmpA(str, "requested data\r\n"), "Expected 'requested data\\r\\n', got %s\n", str);
347 ok(size == 17, "Expected 17, got %d\n", size);
348
349 ret = DdeUnaccessData(hdata);
350 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
351 }
352
353 /* XTYP_REQUEST, all params normal */
354 res = 0xdeadbeef;
356 hdata = DdeClientTransaction(NULL, 0, conversation, item, CF_TEXT, XTYP_REQUEST, default_timeout, &res);
358 ok(ret == DMLERR_NO_ERROR, "Expected DMLERR_NO_ERROR, got %d\n", ret);
359 ok(res == DDE_FNOTPROCESSED || broken(res == 0xdeadbeef), /* win9x */
360 "Expected DDE_FNOTPROCESSED, got %x\n", res);
361 if (hdata == NULL)
362 ok(FALSE, "hdata is NULL\n");
363 else
364 {
365 str = (LPSTR)DdeAccessData(hdata, &size);
366 ok(!lstrcmpA(str, "requested data\r\n"), "Expected 'requested data\\r\\n', got %s\n", str);
367 ok(size == 17, "Expected 17, got %d\n", size);
368
369 ret = DdeUnaccessData(hdata);
370 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
371 }
372
373 /* XTYP_REQUEST, no item */
374 res = 0xdeadbeef;
376 hdata = DdeClientTransaction(NULL, 0, conversation, 0, CF_TEXT, XTYP_REQUEST, default_timeout, &res);
378 ok(hdata == NULL, "Expected NULL hdata, got %p\n", hdata);
379 ok(res == 0xdeadbeef, "Expected 0xdeadbeef, got %08x\n", res);
380 ok(ret == DMLERR_INVALIDPARAMETER, "Expected DMLERR_INVALIDPARAMETER, got %d\n", ret);
381
383
385
386 lstrcpyA(buffer, "poke data\r\n");
388 0, item, CF_TEXT, 0);
389 ok(hdata != NULL, "Expected non-NULL hdata\n");
390
391 /* XTYP_POKE, no item */
392 res = 0xdeadbeef;
394 op = DdeClientTransaction((LPBYTE)hdata, -1, conversation, 0, CF_TEXT, XTYP_POKE, default_timeout, &res);
396 ok(op == NULL, "Expected NULL, got %p\n", op);
397 ok(res == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", res);
398 ok(ret == DMLERR_INVALIDPARAMETER, "Expected DMLERR_INVALIDPARAMETER, got %d\n", ret);
399
400 /* XTYP_POKE, no data */
401 res = 0xdeadbeef;
403 op = DdeClientTransaction(NULL, 0, conversation, 0, CF_TEXT, XTYP_POKE, default_timeout, &res);
405 ok(op == NULL, "Expected NULL, got %p\n", op);
406 ok(res == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", res);
407 ok(ret == DMLERR_INVALIDPARAMETER, "Expected DMLERR_INVALIDPARAMETER, got %d\n", ret);
408
409 /* XTYP_POKE, wrong size */
410 res = 0xdeadbeef;
412 op = DdeClientTransaction((LPBYTE)hdata, 0, conversation, item, CF_TEXT, XTYP_POKE, default_timeout, &res);
414 ok(op == (HDDEDATA)TRUE, "Expected TRUE, got %p\n", op);
415 ok(res == DDE_FACK || broken(res == (0xdead0000 | DDE_FACK)), /* win9x */
416 "Expected DDE_FACK, got %x\n", res);
417 ok(ret == DMLERR_NO_ERROR, "Expected DMLERR_NO_ERROR, got %d\n", ret);
418
419 /* XTYP_POKE, correct params */
420 res = 0xdeadbeef;
422 op = DdeClientTransaction((LPBYTE)hdata, -1, conversation, item, CF_TEXT, XTYP_POKE, default_timeout, &res);
424 ok(op == (HDDEDATA)TRUE, "Expected TRUE, got %p\n", op);
425 ok(res == DDE_FACK || broken(res == (0xdead0000 | DDE_FACK)), /* win9x */
426 "Expected DDE_FACK, got %x\n", res);
427 ok(ret == DMLERR_NO_ERROR, "Expected DMLERR_NO_ERROR, got %d\n", ret);
428
429 DdeFreeDataHandle(hdata);
430
431 lstrcpyA(buffer, "[Command(Var)]");
433 0, NULL, CF_TEXT, 0);
434 ok(hdata != NULL, "Expected non-NULL hdata\n");
435
436 /* XTYP_EXECUTE, correct params */
437 res = 0xdeadbeef;
439 op = DdeClientTransaction((LPBYTE)hdata, -1, conversation, NULL, 0, XTYP_EXECUTE, default_timeout, &res);
441 ok(ret == DMLERR_NO_ERROR, "Expected DMLERR_NO_ERROR, got %d\n", ret);
442 ok(op == (HDDEDATA)TRUE, "Expected TRUE, got %p\n", op);
443 ok(res == DDE_FACK || broken(res == (0xdead0000 | DDE_FACK)), /* win9x */
444 "Expected DDE_FACK, got %x\n", res);
445
446 /* XTYP_EXECUTE, no data */
447 res = 0xdeadbeef;
449 op = DdeClientTransaction(NULL, 0, conversation, NULL, 0, XTYP_EXECUTE, default_timeout, &res);
451 ok(op == NULL || broken(op == (HDDEDATA)TRUE), /* win9x */ "Expected NULL, got %p\n", op);
452 if (!op)
453 {
454 ok(res == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", res);
455 ok(ret == DMLERR_MEMORY_ERROR, "Expected DMLERR_MEMORY_ERROR, got %d\n", ret);
456 }
457 else /* win9x */
458 {
459 ok(res == (0xdead0000 | DDE_FACK), "Expected DDE_FACK, got %x\n", res);
460 ok(ret == DMLERR_NO_ERROR, "Expected DMLERR_NO_ERROR, got %d\n", ret);
461 }
462
463 /* XTYP_EXECUTE, no data, -1 size */
464 res = 0xdeadbeef;
466 op = DdeClientTransaction(NULL, -1, conversation, NULL, 0, XTYP_EXECUTE, default_timeout, &res);
468 ok(op == NULL, "Expected NULL, got %p\n", op);
469 ok(res == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", res);
471 "Expected DMLERR_INVALIDPARAMETER, got %d\n", ret);
472
474 DdeFreeDataHandle(hdata);
475
477
478 /* verify the execute */
479 res = 0xdeadbeef;
481 hdata = DdeClientTransaction(NULL, 0, conversation, item, CF_TEXT, XTYP_REQUEST, default_timeout, &res);
483 ok(ret == DMLERR_NO_ERROR, "Expected DMLERR_NO_ERROR, got %d\n", ret);
484 ok(res == DDE_FNOTPROCESSED || broken(res == (0xdead0000 | DDE_FNOTPROCESSED)), /* win9x */
485 "Expected DDE_FNOTPROCESSED, got %d\n", res);
486 if (hdata == NULL)
487 ok(FALSE, "hdata is NULL\n");
488 else
489 {
490 str = (LPSTR)DdeAccessData(hdata, &size);
491 ok(!lstrcmpA(str, "command executed\r\n"), "Expected 'command executed\\r\\n', got %s\n", str);
492 ok(size == 19, "Expected 19, got %d\n", size);
493
494 ret = DdeUnaccessData(hdata);
495 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
496 }
497
498 /* invalid transactions */
499 res = 0xdeadbeef;
503 ok(op == NULL, "Expected NULL, got %p\n", op);
504 ok(res == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", res);
505 ok(ret == DMLERR_INVALIDPARAMETER, "Expected DMLERR_INVALIDPARAMETER, got %d\n", ret);
506
507 res = 0xdeadbeef;
511 ok(op == NULL, "Expected NULL, got %p\n", op);
512 ok(res == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", res);
513 ok(ret == DMLERR_INVALIDPARAMETER, "Expected DMLERR_INVALIDPARAMETER, got %d\n", ret);
514
515 res = 0xdeadbeef;
519 ok(op == NULL, "Expected NULL, got %p\n", op);
520 ok(res == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", res);
521 ok(ret == DMLERR_INVALIDPARAMETER, "Expected DMLERR_INVALIDPARAMETER, got %d\n", ret);
522
523 res = 0xdeadbeef;
527 ok(op == NULL, "Expected NULL, got %p\n", op);
528 ok(res == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", res);
529 ok(ret == DMLERR_INVALIDPARAMETER, "Expected DMLERR_INVALIDPARAMETER, got %d\n", ret);
530
531 res = 0xdeadbeef;
535 ok(op == NULL, "Expected NULL, got %p\n", op);
536 ok(res == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", res);
537 ok(ret == DMLERR_INVALIDPARAMETER, "Expected DMLERR_INVALIDPARAMETER, got %d\n", ret);
538
539 res = 0xdeadbeef;
543 ok(op == NULL, "Expected NULL, got %p\n", op);
544 ok(res == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", res);
545 ok(ret == DMLERR_INVALIDPARAMETER, "Expected DMLERR_INVALIDPARAMETER, got %d\n", ret);
546
547 res = 0xdeadbeef;
551 ok(op == NULL, "Expected NULL, got %p\n", op);
552 ok(res == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", res);
553 ok(ret == DMLERR_INVALIDPARAMETER, "Expected DMLERR_INVALIDPARAMETER, got %d\n", ret);
554
555 res = 0xdeadbeef;
559 ok(op == NULL, "Expected NULL, got %p\n", op);
560 ok(res == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", res);
561 ok(ret == DMLERR_INVALIDPARAMETER, "Expected DMLERR_INVALIDPARAMETER, got %d\n", ret);
562
563 res = 0xdeadbeef;
567 ok(op == NULL, "Expected NULL, got %p\n", op);
568 ok(res == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", res);
569 ok(ret == DMLERR_INVALIDPARAMETER, "Expected DMLERR_INVALIDPARAMETER, got %d\n", ret);
570
571 res = 0xdeadbeef;
575 ok(op == NULL, "Expected NULL, got %p\n", op);
576 ok(res == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", res);
577 ok(ret == DMLERR_INVALIDPARAMETER, "Expected DMLERR_INVALIDPARAMETER, got %d\n", ret);
578
580
581 ret = DdeDisconnect(conversation);
582 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
583
585 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
586}
587
589
590static HDDEDATA CALLBACK server_ddeml_callback(UINT uType, UINT uFmt, HCONV hconv,
591 HSZ hsz1, HSZ hsz2, HDDEDATA hdata,
592 ULONG_PTR dwData1, ULONG_PTR dwData2)
593{
594 char str[MAX_PATH], *ptr;
595 HDDEDATA ret = NULL;
596 DWORD size;
597
598 static int msg_index = 0;
599 static HCONV conversation = 0;
600
601 msg_index++;
602
603 switch (uType)
604 {
605 case XTYP_REGISTER:
606 {
607 ok(msg_index == 1, "Expected 1, got %d\n", msg_index);
608 ok(uFmt == 0, "Expected 0, got %d\n", uFmt);
609 ok(hconv == 0, "Expected 0, got %p\n", hconv);
610 ok(hdata == 0, "Expected 0, got %p\n", hdata);
611 ok(dwData1 == 0, "Expected 0, got %08lx\n", dwData1);
612 ok(dwData2 == 0, "Expected 0, got %08lx\n", dwData2);
613
615 ok(!lstrcmpA(str, "TestDDEServer"), "Expected TestDDEServer, got %s\n", str);
616 ok(size == 13, "Expected 13, got %d\n", size);
617
619 if (!strncmp( str, "TestDDEServer:(", 15 )) /* win9x style */
620 {
621 ok(size == 16 + 2*sizeof(WORD), "Got size %d for %s\n", size, str);
622 }
623 else
624 {
625 ok(!strncmp(str, "TestDDEServer(", 14), "Expected TestDDEServer(, got %s\n", str);
626 ok(size == 17 + 2*sizeof(ULONG_PTR), "Got size %d for %s\n", size, str);
627 }
628 ok(str[size - 1] == ')', "Expected ')', got %c\n", str[size - 1]);
629
630 return (HDDEDATA)TRUE;
631 }
632
633 case XTYP_CONNECT:
634 {
635 ok(msg_index == 2, "Expected 2, got %d\n", msg_index);
636 ok(uFmt == 0, "Expected 0, got %d\n", uFmt);
637 ok(hconv == 0, "Expected 0, got %p\n", hconv);
638 ok(hdata == 0, "Expected 0, got %p\n", hdata);
639 ok(dwData1 == 0, "Expected 0, got %08lx\n", dwData1);
640 ok(dwData2 == FALSE, "Expected FALSE, got %08lx\n", dwData2);
641
643 ok(!lstrcmpA(str, "TestDDETopic"), "Expected TestDDETopic, got %s\n", str);
644 ok(size == 12, "Expected 12, got %d\n", size);
645
647 ok(!lstrcmpA(str, "TestDDEServer"), "Expected TestDDEServer, got %s\n", str);
648 ok(size == 13, "Expected 13, got %d\n", size);
649
650 return (HDDEDATA)TRUE;
651 }
652
654 {
655 conversation = hconv;
656
657 ok(msg_index == 3, "Expected 3, got %d\n", msg_index);
658 ok(uFmt == 0, "Expected 0, got %d\n", uFmt);
659 ok(hconv != NULL, "Expected non-NULL hconv\n");
660 ok(hdata == 0, "Expected 0, got %p\n", hdata);
661 ok(dwData1 == 0, "Expected 0, got %08lx\n", dwData1);
662 ok(dwData2 == FALSE, "Expected FALSE, got %08lx\n", dwData2);
663
665 ok(!lstrcmpA(str, "TestDDETopic"), "Expected TestDDETopic, got %s\n", str);
666 ok(size == 12, "Expected 12, got %d\n", size);
667
669 ok(!lstrcmpA(str, "TestDDEServer"), "Expected TestDDEServer, got %s\n", str);
670 ok(size == 13, "Expected 13, got %d\n", size);
671
672 return (HDDEDATA)TRUE;
673 }
674
675 case XTYP_REQUEST:
676 {
677 ok(msg_index == 4 || msg_index == 5 || msg_index == 6,
678 "Expected 4, 5 or 6, got %d\n", msg_index);
679 ok(hconv == conversation, "Expected conversation handle, got %p\n", hconv);
680 ok(hdata == 0, "Expected 0, got %p\n", hdata);
681 ok(dwData1 == 0, "Expected 0, got %08lx\n", dwData1);
682 ok(dwData2 == 0, "Expected 0, got %08lx\n", dwData2);
683
684 if (msg_index == 4)
685 ok(uFmt == 0xbeef, "Expected 0xbeef, got %08x\n", uFmt);
686 else
687 ok(uFmt == CF_TEXT, "Expected CF_TEXT, got %08x\n", uFmt);
688
690 ok(!lstrcmpA(str, "TestDDETopic"), "Expected TestDDETopic, got %s\n", str);
691 ok(size == 12, "Expected 12, got %d\n", size);
692
694
695 if (msg_index == 5)
696 {
697 {
698 ok(!lstrcmpA(str, ""), "Expected empty string, got %s\n", str);
699 ok(size == 1, "Expected 1, got %d\n", size);
700 }
701 }
702 else if (msg_index == 6)
703 {
704 ok(!lstrcmpA(str, "request"), "Expected request, got %s\n", str);
705 ok(size == 7, "Expected 7, got %d\n", size);
706 }
707
708 if (msg_index == 6)
709 {
710 lstrcpyA(str, "requested data\r\n");
712 0, hsz2, CF_TEXT, 0);
713 }
714
715 return NULL;
716 }
717
718 case XTYP_POKE:
719 {
720 ok(msg_index == 7 || msg_index == 8, "Expected 7 or 8, got %d\n", msg_index);
721 ok(uFmt == CF_TEXT, "Expected CF_TEXT, got %d\n", uFmt);
722 ok(hconv == conversation, "Expected conversation handle, got %p\n", hconv);
723 ok(dwData1 == 0, "Expected 0, got %08lx\n", dwData1);
724 ok(dwData2 == 0, "Expected 0, got %08lx\n", dwData2);
725
727 ok(!lstrcmpA(str, "TestDDETopic"), "Expected TestDDETopic, got %s\n", str);
728 ok(size == 12, "Expected 12, got %d\n", size);
729
730 ptr = (LPSTR)DdeAccessData(hdata, &size);
731 ok(!lstrcmpA(ptr, "poke data\r\n"), "Expected 'poke data\\r\\n', got %s\n", ptr);
732 ok(size == 12 || broken(size == 28), /* sizes are rounded up on win9x */
733 "Expected 12, got %d\n", size);
734 DdeUnaccessData(hdata);
735
737 if (msg_index == 7)
738 {
739 {
740 ok(!lstrcmpA(str, ""), "Expected empty string, got %s\n", str);
741 ok(size == 1, "Expected 1, got %d\n", size);
742 }
743 }
744 else
745 {
746 ok(!lstrcmpA(str, "poke"), "Expected poke, got %s\n", str);
747 ok(size == 4, "Expected 4, got %d\n", size);
748 }
749
750 return (HDDEDATA)DDE_FACK;
751 }
752
753 case XTYP_EXECUTE:
754 {
755 ok(msg_index >= 9 && msg_index <= 11, "Expected 9 or 11, got %d\n", msg_index);
756 ok(uFmt == 0, "Expected 0, got %d\n", uFmt);
757 ok(hconv == conversation, "Expected conversation handle, got %p\n", hconv);
758 ok(dwData1 == 0, "Expected 0, got %08lx\n", dwData1);
759 ok(dwData2 == 0, "Expected 0, got %08lx\n", dwData2);
760 ok(hsz2 == 0, "Expected 0, got %p\n", hsz2);
761
763 ok(!lstrcmpA(str, "TestDDETopic"), "Expected TestDDETopic, got %s\n", str);
764 ok(size == 12, "Expected 12, got %d\n", size);
765
766 if (msg_index == 9 || msg_index == 11)
767 {
768 ptr = (LPSTR)DdeAccessData(hdata, &size);
769
770 if (msg_index == 9)
771 {
772 ok(!lstrcmpA(ptr, "[Command(Var)]"), "Expected '[Command(Var)]', got %s\n", ptr);
773 ok(size == 15, "Expected 15, got %d\n", size);
774 ret = (HDDEDATA)DDE_FACK;
775 }
776 else
777 {
778 ok(!lstrcmpA(ptr, "[BadCommand(Var)]"), "Expected '[BadCommand(Var)]', got %s\n", ptr);
779 ok(size == 18, "Expected 18, got %d\n", size);
781 }
782
783 DdeUnaccessData(hdata);
784 }
785 else if (msg_index == 10)
786 {
787 DWORD rsize = 0;
788
789 size = DdeGetData(hdata, NULL, 0, 0);
790 ok(size == 17, "DdeGetData should have returned 17 not %d\n", size);
792 ok(ptr != NULL,"HeapAlloc should have returned ptr not NULL\n");
793 rsize = DdeGetData(hdata, (LPBYTE)ptr, size, 0);
794 ok(rsize == size, "DdeGetData did not return %d bytes but %d\n", size, rsize);
795
796 ok(!lstrcmpA(ptr, "[Command-2(Var)]"), "Expected '[Command-2(Var)]' got %s\n", ptr);
797 ok(size == 17, "Expected 17, got %d\n", size);
798 ret = (HDDEDATA)DDE_FACK;
799
801 }
802
803 return ret;
804 }
805
806 case XTYP_DISCONNECT:
807 {
808 ok(msg_index == 12, "Expected 12, got %d\n", msg_index);
809 ok(uFmt == 0, "Expected 0, got %d\n", uFmt);
810 ok(hconv == conversation, "Expected conversation handle, got %p\n", hconv);
811 ok(dwData1 == 0, "Expected 0, got %08lx\n", dwData1);
812 ok(dwData2 == 0, "Expected 0, got %08lx\n", dwData2);
813 ok(hsz1 == 0, "Expected 0, got %p\n", hsz2);
814 ok(hsz2 == 0, "Expected 0, got %p\n", hsz2);
815
816 return 0;
817 }
818
819 default:
820 ok(FALSE, "Unhandled msg: %08x\n", uType);
821 }
822
823 return 0;
824}
825
826static void test_ddeml_server(HANDLE hproc)
827{
828 MSG msg;
829 UINT res;
830 BOOL ret;
831 HSZ server;
832 HDDEDATA hdata;
833
834 /* set up DDE server */
835 server_pid = 0;
837 ok(res == DMLERR_NO_ERROR, "Expected DMLERR_NO_ERROR, got %d\n", res);
838
840 ok(server != NULL, "Expected non-NULL string handle\n");
841
843 ok(hdata == (HDDEDATA)TRUE, "Expected TRUE, got %p\n", hdata);
844
845 while (MsgWaitForMultipleObjects( 1, &hproc, FALSE, INFINITE, QS_ALLINPUT ) != 0)
846 {
847 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
848 }
850 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
851 GetExitCodeProcess( hproc, &res );
852 ok( !res, "client failed with %u error(s)\n", res );
853}
854
858
860{
861 char str[MAX_PATH];
862 UINT_PTR lo, hi;
863 DDEDATA *data;
864 DDEACK *ack;
865 DWORD size;
866 LPSTR ptr;
867
868 static int msg_index = 0;
869
870 if (msg < WM_DDE_FIRST || msg > WM_DDE_LAST)
872
873 msg_index++;
874
875 switch (msg)
876 {
877 case WM_DDE_INITIATE:
878 {
879 ok(msg_index == 1, "Expected 1, got %d\n", msg_index);
880 ok(wparam == (WPARAM)client_hwnd, "Expected client hwnd, got %08lx\n", wparam);
881
883 ok(LOWORD(lparam) == server, "Expected server atom, got %08x\n", LOWORD(lparam));
884 ok(!lstrcmpA(str, "TestDDEServer"), "Expected TestDDEServer, got %s\n", str);
885 ok(size == 13, "Expected 13, got %d\n", size);
886
888 ok(HIWORD(lparam) == topic, "Expected topic atom, got %08x\n", HIWORD(lparam));
889 ok(!lstrcmpA(str, "TestDDETopic"), "Expected TestDDETopic, got %s\n", str);
890 ok(size == 12, "Expected 12, got %d\n", size);
891
892 break;
893 }
894
895 case WM_DDE_ACK:
896 {
897 ok((msg_index >= 2 && msg_index <= 4) || (msg_index >= 6 && msg_index <= 11),
898 "Expected 2, 3, 4, 6, 7, 8, 9, 10 or 11, got %d\n", msg_index);
899
900 if (msg_index == 2)
901 {
903 ok(wparam != 0, "Expected non-NULL wparam, got %08lx\n", wparam);
904
906 ok(LOWORD(lparam) == server, "Expected server atom, got %08x\n", LOWORD(lparam));
907 ok(!lstrcmpA(str, "TestDDEServer"), "Expected TestDDEServer, got %s\n", str);
908 ok(size == 13, "Expected 13, got %d\n", size);
909
911 ok(HIWORD(lparam) == topic, "Expected topic atom, got %08x\n", HIWORD(lparam));
912 ok(!lstrcmpA(str, "TestDDETopic"), "Expected TestDDETopic, got %s\n", str);
913 ok(size == 12, "Expected 12, got %d\n", size);
914 }
915 else if (msg_index >= 9 && msg_index <= 11)
916 {
917 ok(wparam == (WPARAM)server_hwnd, "Expected server hwnd, got %08lx\n", wparam);
918
920
921 ack = (DDEACK *)&lo;
922 ok(ack->bAppReturnCode == 0, "Expected 0, got %d\n", ack->bAppReturnCode);
923 ok(ack->reserved == 0, "Expected 0, got %d\n", ack->reserved);
924 ok(ack->fBusy == FALSE, "Expected FALSE, got %d\n", ack->fBusy);
925
926 ok(hi == (UINT_PTR)execute_hglobal, "Expected execute hglobal, got %08lx\n", hi);
927 ptr = GlobalLock((HGLOBAL)hi);
928
929 if (msg_index == 9)
930 {
931 ok(ack->fAck == TRUE, "Expected TRUE, got %d\n", ack->fAck);
932 ok(!lstrcmpA(ptr, "[Command(Var)]"), "Expected '[Command(Var)]', got %s\n", ptr);
933 } else if (msg_index == 10)
934 {
935 ok(ack->fAck == TRUE, "Expected TRUE, got %d\n", ack->fAck);
936 ok(!lstrcmpA(ptr, "[Command-2(Var)]"), "Expected '[Command-2(Var)]', got %s\n", ptr);
937 }
938 else
939 {
940 ok(ack->fAck == FALSE, "Expected FALSE, got %d\n", ack->fAck);
941 ok(!lstrcmpA(ptr, "[BadCommand(Var)]"), "Expected '[BadCommand(Var)]', got %s\n", ptr);
942 }
943
945 }
946 else
947 {
948 ok(wparam == (WPARAM)server_hwnd, "Expected server hwnd, got %08lx\n", wparam);
949
951
952 ack = (DDEACK *)&lo;
953 ok(ack->bAppReturnCode == 0, "Expected 0, got %d\n", ack->bAppReturnCode);
954 ok(ack->reserved == 0, "Expected 0, got %d\n", ack->reserved);
955 ok(ack->fBusy == FALSE, "Expected FALSE, got %d\n", ack->fBusy);
956
957 if (msg_index >= 7)
958 ok(ack->fAck == TRUE, "Expected TRUE, got %d\n", ack->fAck);
959 else
960 {
961 if (msg_index == 6) todo_wine
962 ok(ack->fAck == FALSE, "Expected FALSE, got %d\n", ack->fAck);
963 }
964
966 if (msg_index == 3)
967 {
968 ok(hi == item, "Expected item atom, got %08lx\n", hi);
969 ok(!lstrcmpA(str, "request"), "Expected request, got %s\n", str);
970 ok(size == 7, "Expected 7, got %d\n", size);
971 }
972 else if (msg_index == 4 || msg_index == 7)
973 {
974 ok(hi == 0, "Expected 0, got %08lx\n", hi);
975 ok(size == 0, "Expected empty string, got %d\n", size);
976 }
977 else
978 {
979 ok(hi == item, "Expected item atom, got %08lx\n", hi);
980 if (msg_index == 6) todo_wine
981 {
982 ok(!lstrcmpA(str, "poke"), "Expected poke, got %s\n", str);
983 ok(size == 4, "Expected 4, got %d\n", size);
984 }
985 }
986 }
987
988 break;
989 }
990
991 case WM_DDE_DATA:
992 {
993 ok(msg_index == 5, "Expected 5, got %d\n", msg_index);
994 ok(wparam == (WPARAM)server_hwnd, "Expected server hwnd, got %08lx\n", wparam);
995
997
998 data = GlobalLock((HGLOBAL)lo);
999 ok(data->unused == 0, "Expected 0, got %d\n", data->unused);
1000 ok(data->fResponse == TRUE, "Expected TRUE, got %d\n", data->fResponse);
1001 todo_wine
1002 {
1003 ok(data->fRelease == TRUE, "Expected TRUE, got %d\n", data->fRelease);
1004 }
1005 ok(data->fAckReq == 0, "Expected 0, got %d\n", data->fAckReq);
1006 ok(data->cfFormat == CF_TEXT, "Expected CF_TEXT, got %d\n", data->cfFormat);
1007 ok(!lstrcmpA((LPSTR)data->Value, "requested data\r\n"),
1008 "Expected 'requested data\\r\\n', got %s\n", data->Value);
1009 GlobalUnlock((HGLOBAL)lo);
1010
1012 ok(hi == item, "Expected item atom, got %08x\n", HIWORD(lparam));
1013 ok(!lstrcmpA(str, "request"), "Expected request, got %s\n", str);
1014 ok(size == 7, "Expected 7, got %d\n", size);
1015
1016 GlobalFree((HGLOBAL)lo);
1017 GlobalDeleteAtom(hi);
1018
1019 break;
1020 }
1021
1022 default:
1023 ok(FALSE, "Unhandled msg: %08x\n", msg);
1024 }
1025
1026 return DefWindowProcA(hwnd, msg, wparam, lparam);
1027}
1028
1030{
1031 HGLOBAL hglobal;
1032 DDEPOKE *poke;
1033 DWORD size;
1034
1035 size = FIELD_OFFSET(DDEPOKE, Value[sizeof("poke data\r\n")]);
1036 hglobal = GlobalAlloc(GMEM_DDESHARE, size);
1037 ok(hglobal != 0, "Expected non-NULL hglobal\n");
1038
1039 poke = GlobalLock(hglobal);
1040 poke->unused = 0;
1041 poke->fRelease = TRUE;
1042 poke->fReserved = TRUE;
1043 poke->cfFormat = CF_TEXT;
1044 lstrcpyA((LPSTR)poke->Value, "poke data\r\n");
1045 GlobalUnlock(hglobal);
1046
1047 return hglobal;
1048}
1049
1051{
1052 HGLOBAL hglobal;
1053 LPSTR ptr;
1054
1055 hglobal = GlobalAlloc(GMEM_DDESHARE, lstrlenA(command) + 1);
1056 ok(hglobal != 0, "Expected non-NULL hglobal\n");
1057
1058 ptr = GlobalLock(hglobal);
1060 GlobalUnlock(hglobal);
1061
1062 return hglobal;
1063}
1064
1065static void test_msg_client(void)
1066{
1067 HGLOBAL hglobal;
1068 LPARAM lparam;
1069
1071
1072 server = GlobalAddAtomA("TestDDEServer");
1073 ok(server != 0, "Expected non-NULL server\n");
1074
1075 topic = GlobalAddAtomA("TestDDETopic");
1076 ok(topic != 0, "Expected non-NULL topic\n");
1077
1079
1082
1083 flush_events();
1084
1085 item = GlobalAddAtomA("request");
1086 ok(item != 0, "Expected non-NULL item\n");
1087
1088 /* WM_DDE_REQUEST, bad clipboard format */
1089 lparam = PackDDElParam(WM_DDE_REQUEST, 0xdeadbeef, item);
1091
1092 flush_events();
1093
1094 /* WM_DDE_REQUEST, no item */
1097
1098 flush_events();
1099
1100 /* WM_DDE_REQUEST, no client hwnd */
1103
1104 flush_events();
1105
1106 /* WM_DDE_REQUEST, correct params */
1109
1110 flush_events();
1111
1113 item = GlobalAddAtomA("poke");
1114 ok(item != 0, "Expected non-NULL item\n");
1115
1116 hglobal = create_poke();
1117
1118 /* WM_DDE_POKE, no ddepoke */
1120 /* win9x returns 0 here and crashes in PostMessageA */
1121 if (lparam) {
1123 flush_events();
1124 }
1125 else
1126 win_skip("no lparam for WM_DDE_POKE\n");
1127
1128
1129 /* WM_DDE_POKE, no item */
1130 lparam = PackDDElParam(WM_DDE_POKE, (UINT_PTR)hglobal, 0);
1132
1133 flush_events();
1134
1135 hglobal = create_poke();
1136
1137 /* WM_DDE_POKE, no client hwnd */
1140
1141 flush_events();
1142
1143 /* WM_DDE_POKE, all params correct */
1146
1147 flush_events();
1148
1149 execute_hglobal = create_execute("[Command(Var)]");
1150
1151 /* WM_DDE_EXECUTE, no lparam */
1153
1154 flush_events();
1155
1156 /* WM_DDE_EXECUTE, no hglobal */
1159
1160 flush_events();
1161
1162 /* WM_DDE_EXECUTE, no client hwnd */
1165
1166 flush_events();
1167
1168 /* WM_DDE_EXECUTE, all params correct */
1171
1172 flush_events();
1173
1175 execute_hglobal = create_execute("[Command-2(Var)]");
1176
1177 /* WM_DDE_EXECUTE, all params correct */
1180
1181 flush_events();
1182
1184 execute_hglobal = create_execute("[BadCommand(Var)]");
1185
1186 /* WM_DDE_EXECUTE that will get rejected */
1189
1190 flush_events();
1191
1192 destroy_dde_window(&client_hwnd, "dde_client");
1193}
1194
1196{
1197 UINT_PTR lo, hi;
1198
1199 trace("hook_dde_client_wndprocA: %p %04x %08lx %08lx\n", hwnd, msg, wparam, lparam);
1200
1201 switch (msg)
1202 {
1203 case WM_DDE_ACK:
1204 UnpackDDElParam(WM_DDE_ACK, lparam, &lo, &hi);
1205 trace("WM_DDE_ACK: status %04lx hglobal %p\n", lo, (HGLOBAL)hi);
1206 break;
1207
1208 default:
1209 break;
1210 }
1212}
1213
1215{
1216 UINT_PTR lo, hi;
1217
1218 trace("hook_dde_client_wndprocW: %p %04x %08lx %08lx\n", hwnd, msg, wparam, lparam);
1219
1220 switch (msg)
1221 {
1222 case WM_DDE_ACK:
1223 UnpackDDElParam(WM_DDE_ACK, lparam, &lo, &hi);
1224 trace("WM_DDE_ACK: status %04lx hglobal %p\n", lo, (HGLOBAL)hi);
1225 break;
1226
1227 default:
1228 break;
1229 }
1231}
1232
1234{
1235 static BOOL client_unicode, conv_unicode;
1236 static int step;
1237
1238 switch (msg)
1239 {
1240 case WM_DDE_INITIATE:
1241 {
1243
1244 trace("server A: got WM_DDE_INITIATE from %p (%s) with %08lx\n",
1245 (HWND)wparam, client_unicode ? "Unicode" : "ANSI", lparam);
1246
1247 if (LOWORD(lparam) == aService)
1248 {
1249 client_unicode = IsWindowUnicode((HWND)wparam);
1250 conv_unicode = client_unicode;
1251 if (step >= 10) client_unicode = !client_unicode; /* change the client window type */
1252
1253 if (client_unicode)
1256 else
1259 trace("server: sending WM_DDE_ACK to %p\n", (HWND)wparam);
1261 }
1262 else
1263 GlobalDeleteAtom(aService);
1264 return 0;
1265 }
1266
1267 case WM_DDE_EXECUTE:
1268 {
1269 DDEACK ack;
1270 WORD status;
1271 LPCSTR cmd;
1272 UINT_PTR lo, hi;
1273
1274 trace("server A: got WM_DDE_EXECUTE from %p with %08lx\n", (HWND)wparam, lparam);
1275
1277 trace("%08lx => lo %04lx hi %04lx\n", lparam, lo, hi);
1278
1279 ack.bAppReturnCode = 0;
1280 ack.reserved = 0;
1281 ack.fBusy = 0;
1282 /* We have to send a negative acknowledge even if we don't
1283 * accept the command, otherwise Windows goes mad and next time
1284 * we send an acknowledge DDEML drops the connection.
1285 * Not sure how to call it: a bug or a feature.
1286 */
1287 ack.fAck = 0;
1288
1289 if ((cmd = GlobalLock((HGLOBAL)hi)))
1290 {
1292
1293 switch (step % 5)
1294 {
1295 case 0: /* bad command */
1296 trace( "server A got unhandled command\n" );
1297 break;
1298
1299 case 1: /* ANSI command */
1300 if (!conv_unicode)
1301 ok( !lstrcmpA(cmd, exec_cmdA), "server A got wrong command '%s'\n", cmd );
1302 else /* we get garbage as the A command was mapped W->A */
1303 ok( cmd[0] != exec_cmdA[0], "server A got wrong command '%s'\n", cmd );
1304 break;
1305
1306 case 2: /* ANSI command in Unicode format */
1307 if (conv_unicode)
1308 ok( !lstrcmpA(cmd, exec_cmdA), "server A got wrong command '%s'\n", cmd );
1309 else
1310 ok( !lstrcmpW((LPCWSTR)cmd, exec_cmdAW), "server A got wrong command '%s'\n", cmd );
1311 break;
1312
1313 case 3: /* Unicode command */
1314 if (!conv_unicode)
1315 ok( !lstrcmpW((LPCWSTR)cmd, exec_cmdW), "server A got wrong command '%s'\n", cmd );
1316 else /* correctly mapped W->A */
1317 ok( !lstrcmpA(cmd, exec_cmdWA), "server A got wrong command '%s'\n", cmd );
1318 break;
1319
1320 case 4: /* Unicode command in ANSI format */
1321 if (!conv_unicode)
1322 ok( !lstrcmpA(cmd, exec_cmdWA), "server A got wrong command '%s'\n", cmd );
1323 else /* we get garbage as the A command was mapped W->A */
1324 ok( cmd[0] != exec_cmdWA[0], "server A got wrong command '%s'\n", cmd );
1325 break;
1326 }
1327 GlobalUnlock((HGLOBAL)hi);
1328 }
1329 else ok( 0, "bad command data %lx\n", hi );
1330
1331 step++;
1332 trace("server A: posting %s WM_DDE_ACK to %p\n", ack.fAck ? "POSITIVE" : "NEGATIVE", (HWND)wparam);
1333
1334 status = *((WORD *)&ack);
1336
1338 return 0;
1339 }
1340
1341 case WM_DDE_TERMINATE:
1342 {
1343 DDEACK ack;
1344 WORD status;
1345
1346 trace("server A: got WM_DDE_TERMINATE from %p with %08lx\n", (HWND)wparam, lparam);
1347
1348 ack.bAppReturnCode = 0;
1349 ack.reserved = 0;
1350 ack.fBusy = 0;
1351 ack.fAck = 1;
1352
1353 trace("server A: posting %s WM_DDE_ACK to %p\n", ack.fAck ? "POSITIVE" : "NEGATIVE", (HWND)wparam);
1354
1355 status = *((WORD *)&ack);
1357
1359 return 0;
1360 }
1361
1362 default:
1363 break;
1364 }
1365
1366 return DefWindowProcA(hwnd, msg, wparam, lparam);
1367}
1368
1370{
1371 static BOOL client_unicode, conv_unicode;
1372 static int step;
1373
1374 switch (msg)
1375 {
1376 case WM_DDE_INITIATE:
1377 {
1379
1380 if (LOWORD(lparam) == aService)
1381 {
1382 client_unicode = IsWindowUnicode((HWND)wparam);
1383 conv_unicode = client_unicode;
1384 if (step >= 10) client_unicode = !client_unicode; /* change the client window type */
1385
1386 if (client_unicode)
1389 else
1392 trace("server W: sending WM_DDE_ACK to %p\n", (HWND)wparam);
1394 }
1395 else
1396 GlobalDeleteAtom(aService);
1397
1398 trace("server W: got WM_DDE_INITIATE from %p with %08lx (client %s conv %s)\n", (HWND)wparam,
1399 lparam, client_unicode ? "Unicode" : "ANSI", conv_unicode ? "Unicode" : "ANSI" );
1400
1401 return 0;
1402 }
1403
1404 case WM_DDE_EXECUTE:
1405 {
1406 DDEACK ack;
1407 WORD status;
1408 LPCSTR cmd;
1409 UINT_PTR lo, hi;
1410
1411 trace("server W: got WM_DDE_EXECUTE from %p with %08lx\n", (HWND)wparam, lparam);
1412
1414 trace("%08lx => lo %04lx hi %04lx\n", lparam, lo, hi);
1415
1416 ack.bAppReturnCode = 0;
1417 ack.reserved = 0;
1418 ack.fBusy = 0;
1419 /* We have to send a negative acknowledge even if we don't
1420 * accept the command, otherwise Windows goes mad and next time
1421 * we send an acknowledge DDEML drops the connection.
1422 * Not sure how to call it: a bug or a feature.
1423 */
1424 ack.fAck = 0;
1425
1426 if ((cmd = GlobalLock((HGLOBAL)hi)))
1427 {
1429
1430 switch (step % 5)
1431 {
1432 case 0: /* bad command */
1433 trace( "server W got unhandled command\n" );
1434 break;
1435
1436 case 1: /* ANSI command */
1437 if (conv_unicode && !client_unicode) /* W->A mapping -> garbage */
1438 ok( cmd[0] != exec_cmdA[0], "server W got wrong command '%s'\n", cmd );
1439 else if (!conv_unicode && client_unicode) /* A->W mapping */
1440 ok( !lstrcmpW((LPCWSTR)cmd, exec_cmdAW), "server W got wrong command '%s'\n", cmd );
1441 else
1442 ok( !lstrcmpA(cmd, exec_cmdA), "server W got wrong command '%s'\n", cmd );
1443 break;
1444
1445 case 2: /* ANSI command in Unicode format */
1446 if (conv_unicode && !client_unicode) /* W->A mapping */
1447 ok( !lstrcmpA(cmd, exec_cmdA), "server W got wrong command '%s'\n", cmd );
1448 else if (!conv_unicode && client_unicode) /* A->W mapping */
1449 ok( *(WCHAR *)cmd == exec_cmdAW[0], "server W got wrong command '%s'\n", cmd );
1450 else
1451 ok( !lstrcmpW((LPCWSTR)cmd, exec_cmdAW), "server W got wrong command '%s'\n", cmd );
1452 break;
1453
1454 case 3: /* Unicode command */
1455 if (conv_unicode && !client_unicode) /* W->A mapping */
1456 ok( !lstrcmpA(cmd, exec_cmdWA), "server W got wrong command '%s'\n", cmd );
1457 else if (!conv_unicode && client_unicode) /* A->W mapping */
1458 ok( *(WCHAR *)cmd == exec_cmdW[0], "server W got wrong command '%s'\n", cmd );
1459 else
1460 ok( !lstrcmpW((LPCWSTR)cmd, exec_cmdW), "server W got wrong command '%s'\n", cmd );
1461 break;
1462
1463 case 4: /* Unicode command in ANSI format */
1464 if (conv_unicode && !client_unicode) /* W->A mapping -> garbage */
1465 ok( cmd[0] != exec_cmdWA[0], "server W got wrong command '%s'\n", cmd );
1466 else if (!conv_unicode && client_unicode) /* A->W mapping */
1467 ok( !lstrcmpW((LPCWSTR)cmd, exec_cmdW), "server W got wrong command '%s'\n", cmd );
1468 else
1469 ok( !lstrcmpA(cmd, exec_cmdWA), "server W got wrong command '%s'\n", cmd );
1470 break;
1471 }
1472 GlobalUnlock((HGLOBAL)hi);
1473 }
1474 else ok( 0, "bad command data %lx\n", hi );
1475
1476 step++;
1477 trace("server W: posting %s WM_DDE_ACK to %p\n", ack.fAck ? "POSITIVE" : "NEGATIVE", (HWND)wparam);
1478
1479 status = *((WORD *)&ack);
1481
1483 return 0;
1484 }
1485
1486 case WM_DDE_TERMINATE:
1487 {
1488 DDEACK ack;
1489 WORD status;
1490
1491 trace("server W: got WM_DDE_TERMINATE from %p with %08lx\n", (HWND)wparam, lparam);
1492
1493 ack.bAppReturnCode = 0;
1494 ack.reserved = 0;
1495 ack.fBusy = 0;
1496 ack.fAck = 1;
1497
1498 trace("server W: posting %s WM_DDE_ACK to %p\n", ack.fAck ? "POSITIVE" : "NEGATIVE", (HWND)wparam);
1499
1500 status = *((WORD *)&ack);
1502
1504 return 0;
1505 }
1506
1507 default:
1508 break;
1509 }
1510
1511 return DefWindowProcW(hwnd, msg, wparam, lparam);
1512}
1513
1514static HWND create_dde_server( BOOL unicode )
1515{
1516 WNDCLASSA wcA;
1517 WNDCLASSW wcW;
1518 HWND server;
1519 static const char server_class_nameA[] = "dde_server_windowA";
1520 static const WCHAR server_class_nameW[] = {'d','d','e','_','s','e','r','v','e','r','_','w','i','n','d','o','w','W',0};
1521
1522 if (unicode)
1523 {
1524 memset(&wcW, 0, sizeof(wcW));
1526 wcW.lpszClassName = server_class_nameW;
1527 wcW.hInstance = GetModuleHandleA(0);
1528 RegisterClassW(&wcW);
1529
1530 server = CreateWindowExW(0, server_class_nameW, NULL, WS_POPUP,
1531 100, 100, CW_USEDEFAULT, CW_USEDEFAULT,
1533 }
1534 else
1535 {
1536 memset(&wcA, 0, sizeof(wcA));
1538 wcA.lpszClassName = server_class_nameA;
1539 wcA.hInstance = GetModuleHandleA(0);
1540 RegisterClassA(&wcA);
1541
1542 server = CreateWindowExA(0, server_class_nameA, NULL, WS_POPUP,
1543 100, 100, CW_USEDEFAULT, CW_USEDEFAULT,
1545 }
1546 ok(!IsWindowUnicode(server) == !unicode, "wrong unicode type\n");
1547 return server;
1548}
1549
1550static HDDEDATA CALLBACK client_dde_callback(UINT uType, UINT uFmt, HCONV hconv,
1551 HSZ hsz1, HSZ hsz2, HDDEDATA hdata,
1552 ULONG_PTR dwData1, ULONG_PTR dwData2)
1553{
1554 static const char * const cmd_type[15] = {
1555 "XTYP_ERROR", "XTYP_ADVDATA", "XTYP_ADVREQ", "XTYP_ADVSTART",
1556 "XTYP_ADVSTOP", "XTYP_EXECUTE", "XTYP_CONNECT", "XTYP_CONNECT_CONFIRM",
1557 "XTYP_XACT_COMPLETE", "XTYP_POKE", "XTYP_REGISTER", "XTYP_REQUEST",
1558 "XTYP_DISCONNECT", "XTYP_UNREGISTER", "XTYP_WILDCONNECT" };
1559 UINT type;
1560 const char *cmd_name;
1561
1562 type = (uType & XTYP_MASK) >> XTYP_SHIFT;
1563 cmd_name = (type <= 14) ? cmd_type[type] : "unknown";
1564
1565 trace("client_dde_callback: %04x (%s) %d %p %p %p %p %08lx %08lx\n",
1566 uType, cmd_name, uFmt, hconv, hsz1, hsz2, hdata, dwData1, dwData2);
1567 return 0;
1568}
1569
1570static void test_dde_aw_transaction( BOOL client_unicode, BOOL server_unicode )
1571{
1572 HSZ hsz_server;
1574 HCONV hconv;
1575 HWND hwnd_server;
1576 CONVINFO info;
1577 HDDEDATA hdata;
1578 BOOL conv_unicode = client_unicode;
1579 BOOL got;
1580 static char test_cmd[] = "test dde command";
1581
1582 if (!(hwnd_server = create_dde_server( server_unicode ))) return;
1583
1584 dde_inst = 0;
1585 if (client_unicode)
1587 else
1589 ok(ret == DMLERR_NO_ERROR, "DdeInitializeA failed with error %04x (%x)\n",
1591
1593
1594 hconv = DdeConnect(dde_inst, hsz_server, 0, NULL);
1595 ok(hconv != 0, "DdeConnect error %x\n", DdeGetLastError(dde_inst));
1597 ok(err == DMLERR_NO_ERROR, "wrong dde error %x\n", err);
1598
1599 info.cb = sizeof(info);
1600 ret = DdeQueryConvInfo(hconv, QID_SYNC, &info);
1601 ok(ret, "wrong info size %d, DdeQueryConvInfo error %x\n", ret, DdeGetLastError(dde_inst));
1602 ok(info.ConvCtxt.iCodePage == (client_unicode ? CP_WINUNICODE : CP_WINANSI),
1603 "wrong iCodePage %d\n", info.ConvCtxt.iCodePage);
1604 ok(!info.hConvPartner, "unexpected info.hConvPartner: %p\n", info.hConvPartner);
1605todo_wine {
1606 ok((info.wStatus & DDE_FACK), "unexpected info.wStatus: %04x\n", info.wStatus);
1607}
1608 ok((info.wStatus & (ST_CONNECTED | ST_CLIENT)) == (ST_CONNECTED | ST_CLIENT), "unexpected info.wStatus: %04x\n", info.wStatus);
1609 ok(info.wConvst == XST_CONNECTED, "unexpected info.wConvst: %04x\n", info.wConvst);
1610 ok(info.wType == 0, "unexpected info.wType: %04x\n", info.wType);
1611
1612 client_unicode = IsWindowUnicode( info.hwnd );
1613 trace("hwnd %p, hwndPartner %p, unicode %u\n", info.hwnd, info.hwndPartner, client_unicode);
1614
1615 trace("sending test client transaction command\n");
1616 ret = 0xdeadbeef;
1617 hdata = DdeClientTransaction((LPBYTE)test_cmd, strlen(test_cmd) + 1, hconv, (HSZ)0xdead, 0xbeef, XTYP_EXECUTE, 1000, &ret);
1618 ok(!hdata, "DdeClientTransaction succeeded\n");
1619 ok(ret == DDE_FNOTPROCESSED || broken(ret == (0xdead0000 | DDE_FNOTPROCESSED)), /* win9x */
1620 "wrong status code %04x\n", ret);
1622 ok(err == DMLERR_NOTPROCESSED, "wrong dde error %x\n", err);
1623
1624 trace("sending ANSI client transaction command\n");
1625 ret = 0xdeadbeef;
1626 hdata = DdeClientTransaction((LPBYTE)exec_cmdA, lstrlenA(exec_cmdA) + 1, hconv, 0, 0, XTYP_EXECUTE, 1000, &ret);
1628 if (conv_unicode && (!client_unicode || !server_unicode)) /* W->A mapping -> garbage */
1629 {
1630 ok(!hdata, "DdeClientTransaction returned %p, error %x\n", hdata, err);
1631 ok(ret == DDE_FNOTPROCESSED, "wrong status code %04x\n", ret);
1632 ok(err == DMLERR_NOTPROCESSED, "DdeClientTransaction returned error %x\n", err);
1633 }
1634 else if (!conv_unicode && client_unicode && server_unicode) /* A->W mapping -> wrong cmd */
1635 {
1636 ok(!hdata, "DdeClientTransaction returned %p, error %x\n", hdata, err);
1637 ok(ret == DDE_FNOTPROCESSED, "wrong status code %04x\n", ret);
1638 ok(err == DMLERR_NOTPROCESSED, "DdeClientTransaction returned error %x\n", err);
1639 }
1640 else /* no mapping */
1641 {
1642 ok(hdata != 0, "DdeClientTransaction returned %p, error %x\n", hdata, err);
1643 ok(ret == DDE_FACK, "wrong status code %04x\n", ret);
1644 ok(err == DMLERR_NO_ERROR, "wrong dde error %x\n", err);
1645 }
1646
1647 trace("sending ANSI-as-Unicode client transaction command\n");
1648 ret = 0xdeadbeef;
1650 hconv, 0, 0, XTYP_EXECUTE, 1000, &ret);
1652 if (conv_unicode && (!client_unicode || !server_unicode)) /* W->A mapping */
1653 {
1654 ok(hdata != 0, "DdeClientTransaction returned %p, error %x\n", hdata, err);
1655 ok(ret == DDE_FACK, "wrong status code %04x\n", ret);
1656 ok(err == DMLERR_NO_ERROR, "wrong dde error %x\n", err);
1657 }
1658 else if (!conv_unicode && client_unicode && server_unicode) /* A->W mapping -> garbage */
1659 {
1660 ok(!hdata, "DdeClientTransaction returned %p, error %x\n", hdata, err);
1661 ok(ret == DDE_FNOTPROCESSED, "wrong status code %04x\n", ret);
1662 ok(err == DMLERR_NOTPROCESSED, "DdeClientTransaction returned error %x\n", err);
1663 }
1664 else /* no mapping */
1665 {
1666 ok(!hdata, "DdeClientTransaction returned %p, error %x\n", hdata, err);
1667 ok(ret == DDE_FNOTPROCESSED || broken(ret == (0xdead0000 | DDE_FNOTPROCESSED)), /* win9x */
1668 "wrong status code %04x\n", ret);
1669 ok(err == DMLERR_NOTPROCESSED, "DdeClientTransaction returned error %x\n", err);
1670 }
1671
1672 trace("sending unicode client transaction command\n");
1673 ret = 0xdeadbeef;
1674 hdata = DdeClientTransaction((LPBYTE)exec_cmdW, (lstrlenW(exec_cmdW) + 1) * sizeof(WCHAR), hconv, 0, 0, XTYP_EXECUTE, 1000, &ret);
1676 if (conv_unicode && (!client_unicode || !server_unicode)) /* W->A mapping -> wrong cmd */
1677 {
1678 ok(!hdata, "DdeClientTransaction returned %p, error %x\n", hdata, err);
1679 ok(ret == DDE_FNOTPROCESSED, "wrong status code %04x\n", ret);
1680 ok(err == DMLERR_NOTPROCESSED, "DdeClientTransaction returned error %x\n", err);
1681 }
1682 else if (!conv_unicode && client_unicode && server_unicode) /* A->W mapping -> garbage */
1683 {
1684 ok(!hdata, "DdeClientTransaction returned %p, error %x\n", hdata, err);
1685 ok(ret == DDE_FNOTPROCESSED, "wrong status code %04x\n", ret);
1686 ok(err == DMLERR_NOTPROCESSED, "DdeClientTransaction returned error %x\n", err);
1687 }
1688 else /* no mapping */
1689 {
1690 ok(hdata != 0, "DdeClientTransaction returned %p, error %x\n", hdata, err);
1691 ok(ret == DDE_FACK, "wrong status code %04x\n", ret);
1692 ok(err == DMLERR_NO_ERROR, "wrong dde error %x\n", err);
1693 }
1694
1695 trace("sending Unicode-as-ANSI client transaction command\n");
1696 ret = 0xdeadbeef;
1697 hdata = DdeClientTransaction((LPBYTE)exec_cmdWA, lstrlenA(exec_cmdWA) + 1, hconv, 0, 0, XTYP_EXECUTE, 1000, &ret);
1699 if (conv_unicode && (!client_unicode || !server_unicode)) /* W->A mapping -> garbage */
1700 {
1701 ok(!hdata, "DdeClientTransaction returned %p, error %x\n", hdata, err);
1702 ok(ret == DDE_FNOTPROCESSED, "wrong status code %04x\n", ret);
1703 ok(err == DMLERR_NOTPROCESSED, "DdeClientTransaction returned error %x\n", err);
1704 }
1705 else if (!conv_unicode && client_unicode && server_unicode) /* A->W mapping */
1706 {
1707 ok(hdata != 0, "DdeClientTransaction returned %p, error %x\n", hdata, err);
1708 ok(ret == DDE_FACK, "wrong status code %04x\n", ret);
1709 ok(err == DMLERR_NO_ERROR, "wrong dde error %x\n", err);
1710 }
1711 else /* no mapping */
1712 {
1713 ok(!hdata, "DdeClientTransaction returned %p, error %x\n", hdata, err);
1714 ok(ret == DDE_FNOTPROCESSED, "wrong status code %04x\n", ret);
1715 ok(err == DMLERR_NOTPROCESSED, "DdeClientTransaction returned error %x\n", err);
1716 }
1717
1718 got = DdeDisconnect(hconv);
1719 ok(got, "DdeDisconnect error %x\n", DdeGetLastError(dde_inst));
1720
1721 info.cb = sizeof(info);
1722 ret = DdeQueryConvInfo(hconv, QID_SYNC, &info);
1723 ok(!ret, "DdeQueryConvInfo should fail\n");
1725todo_wine {
1726 ok(err == DMLERR_INVALIDPARAMETER, "wrong dde error %x\n", err);
1727}
1728
1729 got = DdeFreeStringHandle(dde_inst, hsz_server);
1730 ok(got, "DdeFreeStringHandle error %x\n", DdeGetLastError(dde_inst));
1731
1732 /* This call hangs on win2k SP4 and XP SP1.
1733 DdeUninitialize(dde_inst);*/
1734
1735 DestroyWindow(hwnd_server);
1736}
1737
1738static void test_initialisation(void)
1739{
1740 UINT ret;
1741 DWORD res;
1742 HDDEDATA hdata;
1743 HSZ server, topic, item;
1745 HCONV conversation;
1746
1747 /* Initialise without a valid server window. */
1748 client_pid = 0;
1750 ok(ret == DMLERR_NO_ERROR, "Expected DMLERR_NO_ERROR, got %d\n", ret);
1751
1752
1753 server = DdeCreateStringHandleA(client_pid, "TestDDEService", CP_WINANSI);
1755
1757
1758 /* There is no server window so no conversation can be extracted */
1759 conversation = DdeConnect(client_pid, server, topic, NULL);
1760 ok(conversation == NULL, "Expected NULL conversation, %p\n", conversation);
1762 ok(ret == DMLERR_NO_CONV_ESTABLISHED, "Expected DMLERR_NO_CONV_ESTABLISHED, got %d\n", ret);
1763
1765
1767
1768 /* There is no conversation so an invalid parameter results */
1769 res = 0xdeadbeef;
1771 hdata = DdeClientTransaction(NULL, 0, conversation, item, CF_TEXT, XTYP_REQUEST, default_timeout, &res);
1772 ok(hdata == NULL, "Expected NULL, got %p\n", hdata);
1775 ok(ret == DMLERR_INVALIDPARAMETER, "Expected DMLERR_INVALIDPARAMETER, got %d\n", ret);
1776 ok(res == 0xdeadbeef, "Expected 0xdeadbeef, got %08x\n", res);
1777
1779 ret = DdeDisconnect(conversation);
1780 ok(ret == FALSE, "Expected FALSE, got %d\n", ret);
1781
1783 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1784}
1785
1787{
1788 static const WCHAR dde_string[] = {'D','D','E',' ','S','t','r','i','n','g',0};
1789 HSZ str_handle;
1790 WCHAR bufW[256];
1791 char buf[256];
1792 ATOM atom;
1793 int ret;
1794
1795 str_handle = DdeCreateStringHandleW(dde_inst, dde_string, codepage);
1796 ok(str_handle != 0, "DdeCreateStringHandleW failed with error %08x\n",
1798
1799 ret = DdeQueryStringW(dde_inst, str_handle, NULL, 0, codepage);
1800 if (codepage == CP_WINANSI)
1801 ok(ret == 1, "DdeQueryStringW returned wrong length %d\n", ret);
1802 else
1803 ok(ret == lstrlenW(dde_string), "DdeQueryStringW returned wrong length %d\n", ret);
1804
1805 ret = DdeQueryStringW(dde_inst, str_handle, bufW, 256, codepage);
1806 if (codepage == CP_WINANSI)
1807 {
1808 ok(ret == 1, "DdeQueryStringW returned wrong length %d\n", ret);
1809 ok(!lstrcmpA("D", (LPCSTR)bufW), "DdeQueryStringW returned wrong string\n");
1810 }
1811 else
1812 {
1813 ok(ret == lstrlenW(dde_string), "DdeQueryStringW returned wrong length %d\n", ret);
1814 ok(!lstrcmpW(dde_string, bufW), "DdeQueryStringW returned wrong string\n");
1815 }
1816
1817 ret = DdeQueryStringA(dde_inst, str_handle, buf, 256, CP_WINANSI);
1818 if (codepage == CP_WINANSI)
1819 {
1820 ok(ret == 1, "DdeQueryStringA returned wrong length %d\n", ret);
1821 ok(!lstrcmpA("D", buf), "DdeQueryStringW returned wrong string\n");
1822 }
1823 else
1824 {
1825 ok(ret == lstrlenA("DDE String"), "DdeQueryStringA returned wrong length %d\n", ret);
1826 ok(!lstrcmpA("DDE String", buf), "DdeQueryStringA returned wrong string %s\n", buf);
1827 }
1828
1829 ret = DdeQueryStringA(dde_inst, str_handle, buf, 256, CP_WINUNICODE);
1830 if (codepage == CP_WINANSI)
1831 {
1832 ok(ret == 1, "DdeQueryStringA returned wrong length %d\n", ret);
1833 ok(!lstrcmpA("D", buf), "DdeQueryStringA returned wrong string %s\n", buf);
1834 }
1835 else
1836 {
1837 ok(ret == lstrlenA("DDE String"), "DdeQueryStringA returned wrong length %d\n", ret);
1838 ok(!lstrcmpW(dde_string, (LPCWSTR)buf), "DdeQueryStringW returned wrong string\n");
1839 }
1840
1841 if (codepage == CP_WINANSI)
1842 {
1843 atom = FindAtomA((LPSTR)dde_string);
1844 ok(atom != 0, "Expected a valid atom\n");
1845
1846 SetLastError(0xdeadbeef);
1847 atom = GlobalFindAtomA((LPSTR)dde_string);
1848 ok(atom == 0, "Expected 0, got %d\n", atom);
1850 "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
1851 }
1852 else
1853 {
1854 atom = FindAtomW(dde_string);
1855 ok(atom != 0, "Expected a valid atom\n");
1856
1857 SetLastError(0xdeadbeef);
1858 atom = GlobalFindAtomW(dde_string);
1859 ok(atom == 0, "Expected 0, got %d\n", atom);
1861 "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
1862 }
1863
1864 ok(DdeFreeStringHandle(dde_inst, str_handle), "DdeFreeStringHandle failed\n");
1865}
1866
1868{
1869 HDDEDATA hdata;
1870 DWORD dde_inst, dde_inst2;
1871 DWORD size;
1872 UINT res, err;
1873 BOOL ret;
1874 HSZ item;
1875 LPBYTE ptr;
1876 WCHAR item_str[] = {'i','t','e','m',0};
1877
1878 dde_inst = 0;
1879 dde_inst2 = 0;
1881 ok(res == DMLERR_NO_ERROR, "Expected DMLERR_NO_ERROR, got %d\n", res);
1882
1884 ok(res == DMLERR_NO_ERROR, "Expected DMLERR_NO_ERROR, got %d\n", res);
1885
1886 /* 0 instance id
1887 * This block tests an invalid instance Id. The correct behaviour is that if the instance Id
1888 * is invalid then the lastError of all instances is set to the error. There are two instances
1889 * created, lastError is cleared, an error is generated and then both instances are checked to
1890 * ensure that they both have the same error set
1891 */
1893 ok(item == NULL, "Expected NULL hsz got %p\n", item);
1895 ok(err == DMLERR_INVALIDPARAMETER, "Expected DMLERR_INVALIDPARAMETER, got %d\n", err);
1896 err = DdeGetLastError(dde_inst2);
1897 ok(err == DMLERR_INVALIDPARAMETER, "Expected DMLERR_INVALIDPARAMETER, got %d\n", err);
1899 ok(item == NULL, "Expected NULL hsz got %p\n", item);
1901 ok(err == DMLERR_INVALIDPARAMETER, "Expected DMLERR_INVALIDPARAMETER, got %d\n", err);
1902 err = DdeGetLastError(dde_inst2);
1903 ok(err == DMLERR_INVALIDPARAMETER, "Expected DMLERR_INVALIDPARAMETER, got %d\n", err);
1904
1906 ok(item != NULL, "Expected non-NULL hsz\n");
1907 item = DdeCreateStringHandleA(dde_inst2, "item", CP_WINANSI);
1908 ok(item != NULL, "Expected non-NULL hsz\n");
1909
1910 if (0) {
1911 /* do not test with an invalid instance id: that crashes on win9x */
1912 hdata = DdeCreateDataHandle(0xdeadbeef, (LPBYTE)"data", MAX_PATH, 0, item, CF_TEXT, 0);
1913 }
1914
1915 /* 0 instance id
1916 * This block tests an invalid instance Id. The correct behaviour is that if the instance Id
1917 * is invalid then the lastError of all instances is set to the error. There are two instances
1918 * created, lastError is cleared, an error is generated and then both instances are checked to
1919 * ensure that they both have the same error set
1920 */
1922 DdeGetLastError(dde_inst2);
1923 hdata = DdeCreateDataHandle(0, (LPBYTE)"data", MAX_PATH, 0, item, CF_TEXT, 0);
1925 ok(hdata == NULL, "Expected NULL, got %p\n", hdata);
1926 ok(err == DMLERR_INVALIDPARAMETER, "Expected DMLERR_INVALIDPARAMETER, got %d\n", err);
1927 err = DdeGetLastError(dde_inst2);
1928 ok(err == DMLERR_INVALIDPARAMETER, "Expected DMLERR_INVALIDPARAMETER, got %d\n", err);
1929
1930 ret = DdeUninitialize(dde_inst2);
1931 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1932
1933
1934 /* NULL pSrc */
1938 ok(hdata != NULL, "Expected non-NULL hdata\n");
1939 ok(err == DMLERR_NO_ERROR, "Expected DMLERR_NO_ERROR, got %d\n", err);
1940
1941 ptr = DdeAccessData(hdata, &size);
1942 ok(ptr != NULL, "Expected non-NULL ptr\n");
1943 ok(size == 260, "Expected 260, got %d\n", size);
1944
1945 ret = DdeUnaccessData(hdata);
1946 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1947
1948 ret = DdeFreeDataHandle(hdata);
1949 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1950
1951 /* cb is zero */
1953 hdata = DdeCreateDataHandle(dde_inst, (LPBYTE)"data", 0, 0, item, CF_TEXT, 0);
1955 ok(hdata != NULL, "Expected non-NULL hdata\n");
1956 ok(err == DMLERR_NO_ERROR, "Expected DMLERR_NO_ERROR, got %d\n", err);
1957
1958 ptr = DdeAccessData(hdata, &size);
1959 ok(ptr != NULL, "Expected non-NULL ptr\n");
1960 ok(size == 0, "Expected 0, got %d\n", size);
1961
1962 ret = DdeUnaccessData(hdata);
1963 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1964
1965 ret = DdeFreeDataHandle(hdata);
1966 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1967
1968 /* cbOff is non-zero */
1970 hdata = DdeCreateDataHandle(dde_inst, (LPBYTE)"data", MAX_PATH, 2, item, CF_TEXT, 0);
1972 ok(hdata != NULL, "Expected non-NULL hdata\n");
1973 ok(err == DMLERR_NO_ERROR, "Expected DMLERR_NO_ERROR, got %d\n", err);
1974
1975 ptr = DdeAccessData(hdata, &size);
1976 ok(ptr != NULL, "Expected non-NULL ptr\n");
1977 ok(size == 262, "Expected 262, got %d\n", size);
1978 todo_wine
1979 {
1980 ok(lstrlenA((LPSTR)ptr) == 0, "Expected 0, got %d\n", lstrlenA((LPSTR)ptr));
1981 }
1982
1983 ret = DdeUnaccessData(hdata);
1984 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1985
1986 ret = DdeFreeDataHandle(hdata);
1987 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1988
1989 /* NULL item */
1991 hdata = DdeCreateDataHandle(dde_inst, (LPBYTE)"data", MAX_PATH, 0, 0, CF_TEXT, 0);
1993 ok(hdata != NULL, "Expected non-NULL hdata\n");
1994 ok(err == DMLERR_NO_ERROR, "Expected DMLERR_NO_ERROR, got %d\n", err);
1995
1996 ptr = DdeAccessData(hdata, &size);
1997 ok(ptr != NULL, "Expected non-NULL ptr\n");
1998 ok(!lstrcmpA((LPSTR)ptr, "data"), "Expected data, got %s\n", ptr);
1999 ok(size == 260, "Expected 260, got %d\n", size);
2000
2001 ret = DdeUnaccessData(hdata);
2002 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
2003
2004 ret = DdeFreeDataHandle(hdata);
2005 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
2006
2007 /* NULL item */
2009 hdata = DdeCreateDataHandle(dde_inst, (LPBYTE)"data", MAX_PATH, 0, (HSZ)0xdeadbeef, CF_TEXT, 0);
2011 ok(hdata != NULL, "Expected non-NULL hdata\n");
2012 ok(err == DMLERR_NO_ERROR, "Expected DMLERR_NO_ERROR, got %d\n", err);
2013
2014 ptr = DdeAccessData(hdata, &size);
2015 ok(ptr != NULL, "Expected non-NULL ptr\n");
2016 ok(!lstrcmpA((LPSTR)ptr, "data"), "Expected data, got %s\n", ptr);
2017 ok(size == 260, "Expected 260, got %d\n", size);
2018
2019 ret = DdeUnaccessData(hdata);
2020 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
2021
2022 ret = DdeFreeDataHandle(hdata);
2023 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
2024
2025 /* invalid clipboard format */
2027 hdata = DdeCreateDataHandle(dde_inst, (LPBYTE)"data", MAX_PATH, 0, item, 0xdeadbeef, 0);
2029 ok(hdata != NULL, "Expected non-NULL hdata\n");
2030 ok(err == DMLERR_NO_ERROR, "Expected DMLERR_NO_ERROR, got %d\n", err);
2031
2032 ptr = DdeAccessData(hdata, &size);
2033 ok(ptr != NULL, "Expected non-NULL ptr\n");
2034 ok(!lstrcmpA((LPSTR)ptr, "data"), "Expected data, got %s\n", ptr);
2035 ok(size == 260, "Expected 260, got %d\n", size);
2036
2037 ret = DdeUnaccessData(hdata);
2038 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
2039
2040 ret = DdeFreeDataHandle(hdata);
2041 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
2042
2044 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
2045}
2046
2048{
2050
2051 dde_inst = 0xdeadbeef;
2052 SetLastError(0xdeadbeef);
2054 ok(ret == DMLERR_INVALIDPARAMETER, "DdeInitializeW should fail, but got %04x instead\n", ret);
2055 ok(DdeGetLastError(dde_inst) == DMLERR_INVALIDPARAMETER, "expected DMLERR_INVALIDPARAMETER\n");
2056
2057 dde_inst = 0;
2059 ok(ret == DMLERR_NO_ERROR, "DdeInitializeW failed with error %04x (%08x)\n",
2061
2065
2066 ok(DdeUninitialize(dde_inst), "DdeUninitialize failed\n");
2067}
2068
2069static void test_FreeDDElParam(void)
2070{
2071 HGLOBAL val, hglobal;
2072 BOOL ret;
2073
2075 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
2076
2077 hglobal = GlobalAlloc(GMEM_DDESHARE, 100);
2079 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
2080 val = GlobalFree(hglobal);
2081 ok(val == NULL, "Expected NULL, got %p\n", val);
2082
2083 hglobal = GlobalAlloc(GMEM_DDESHARE, 100);
2085 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
2086
2087 hglobal = GlobalAlloc(GMEM_DDESHARE, 100);
2089 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
2090 val = GlobalFree(hglobal);
2091 ok(val == NULL, "Expected NULL, got %p\n", val);
2092
2093 hglobal = GlobalAlloc(GMEM_DDESHARE, 100);
2094 ret = FreeDDElParam(WM_DDE_ACK, (LPARAM)hglobal);
2095 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
2096
2097 hglobal = GlobalAlloc(GMEM_DDESHARE, 100);
2098 ret = FreeDDElParam(WM_DDE_DATA, (LPARAM)hglobal);
2099 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
2100
2101 hglobal = GlobalAlloc(GMEM_DDESHARE, 100);
2103 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
2104 val = GlobalFree(hglobal);
2105 ok(val == NULL, "Expected NULL, got %p\n", val);
2106
2107 hglobal = GlobalAlloc(GMEM_DDESHARE, 100);
2108 ret = FreeDDElParam(WM_DDE_POKE, (LPARAM)hglobal);
2109 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
2110
2111 hglobal = GlobalAlloc(GMEM_DDESHARE, 100);
2113 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
2114 val = GlobalFree(hglobal);
2115 ok(val == NULL, "Expected NULL, got %p\n", val);
2116}
2117
2118static void test_PackDDElParam(void)
2119{
2120 UINT_PTR lo, hi, *ptr;
2121 LPARAM lparam;
2122 BOOL ret;
2123
2124 lparam = PackDDElParam(WM_DDE_INITIATE, 0xcafe, 0xbeef);
2125 /* value gets sign-extended despite being an LPARAM */
2126 ok(lparam == (int)0xbeefcafe, "Expected 0xbeefcafe, got %08lx\n", lparam);
2127
2128 lo = hi = 0;
2130 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
2131 ok(lo == 0xcafe, "Expected 0xcafe, got %08lx\n", lo);
2132 ok(hi == 0xbeef, "Expected 0xbeef, got %08lx\n", hi);
2133
2135 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
2136
2137 lparam = PackDDElParam(WM_DDE_TERMINATE, 0xcafe, 0xbeef);
2138 ok(lparam == (int)0xbeefcafe, "Expected 0xbeefcafe, got %08lx\n", lparam);
2139
2140 lo = hi = 0;
2142 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
2143 ok(lo == 0xcafe, "Expected 0xcafe, got %08lx\n", lo);
2144 ok(hi == 0xbeef, "Expected 0xbeef, got %08lx\n", hi);
2145
2147 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
2148
2149 lparam = PackDDElParam(WM_DDE_ADVISE, 0xcafe, 0xbeef);
2150 /* win9x returns 0 here */
2151 if (lparam) {
2153 ok(ptr != NULL, "Expected non-NULL ptr\n");
2154 ok(ptr[0] == 0xcafe, "Expected 0xcafe, got %08lx\n", ptr[0]);
2155 ok(ptr[1] == 0xbeef, "Expected 0xbeef, got %08lx\n", ptr[1]);
2156
2158 ok(ret == 1, "Expected 1, got %d\n", ret);
2159
2160 lo = hi = 0;
2162 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
2163 ok(lo == 0xcafe, "Expected 0xcafe, got %08lx\n", lo);
2164 ok(hi == 0xbeef, "Expected 0xbeef, got %08lx\n", hi);
2165 }
2166 else
2167 win_skip("no lparam for WM_DDE_ADVISE\n");
2168
2170 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
2171
2172 lparam = PackDDElParam(WM_DDE_UNADVISE, 0xcafe, 0xbeef);
2173 ok(lparam == (int)0xbeefcafe, "Expected 0xbeefcafe, got %08lx\n", lparam);
2174
2175 lo = hi = 0;
2177 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
2178 ok(lo == 0xcafe, "Expected 0xcafe, got %08lx\n", lo);
2179 ok(hi == 0xbeef, "Expected 0xbeef, got %08lx\n", hi);
2180
2182 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
2183
2184 lparam = PackDDElParam(WM_DDE_ACK, 0xcafe, 0xbeef);
2185 /* win9x returns the input (0xbeef<<16 | 0xcafe) here */
2186 if (lparam != (int)0xbeefcafe) {
2188 ok(ptr != NULL, "Expected non-NULL ptr\n");
2189 ok(ptr[0] == 0xcafe, "Expected 0xcafe, got %08lx\n", ptr[0]);
2190 ok(ptr[1] == 0xbeef, "Expected 0xbeef, got %08lx\n", ptr[1]);
2191
2193 ok(ret == 1, "Expected 1, got %d\n", ret);
2194
2195 lo = hi = 0;
2196 ret = UnpackDDElParam(WM_DDE_ACK, lparam, &lo, &hi);
2197 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
2198 ok(lo == 0xcafe, "Expected 0xcafe, got %08lx\n", lo);
2199 ok(hi == 0xbeef, "Expected 0xbeef, got %08lx\n", hi);
2200
2202 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
2203 }
2204 else
2205 win_skip("got lparam 0x%lx for WM_DDE_ACK\n", lparam);
2206
2207 lparam = PackDDElParam(WM_DDE_DATA, 0xcafe, 0xbeef);
2208 /* win9x returns 0 here */
2209 if (lparam) {
2211 ok(ptr != NULL, "Expected non-NULL ptr\n");
2212 ok(ptr[0] == 0xcafe, "Expected 0xcafe, got %08lx\n", ptr[0]);
2213 ok(ptr[1] == 0xbeef, "Expected 0xbeef, got %08lx\n", ptr[1]);
2214
2216 ok(ret == 1, "Expected 1, got %d\n", ret);
2217
2218 lo = hi = 0;
2219 ret = UnpackDDElParam(WM_DDE_DATA, lparam, &lo, &hi);
2220 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
2221 ok(lo == 0xcafe, "Expected 0xcafe, got %08lx\n", lo);
2222 ok(hi == 0xbeef, "Expected 0xbeef, got %08lx\n", hi);
2223 }
2224 else
2225 win_skip("no lparam for WM_DDE_DATA\n");
2226
2228 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
2229
2230 lparam = PackDDElParam(WM_DDE_REQUEST, 0xcafe, 0xbeef);
2231 ok(lparam == (int)0xbeefcafe, "Expected 0xbeefcafe, got %08lx\n", lparam);
2232
2233 lo = hi = 0;
2235 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
2236 ok(lo == 0xcafe, "Expected 0xcafe, got %08lx\n", lo);
2237 ok(hi == 0xbeef, "Expected 0xbeef, got %08lx\n", hi);
2238
2240 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
2241
2242 lparam = PackDDElParam(WM_DDE_POKE, 0xcafe, 0xbeef);
2243 /* win9x returns 0 here */
2244 if (lparam) {
2246 ok(ptr != NULL, "Expected non-NULL ptr\n");
2247 ok(ptr[0] == 0xcafe, "Expected 0xcafe, got %08lx\n", ptr[0]);
2248 ok(ptr[1] == 0xbeef, "Expected 0xbeef, got %08lx\n", ptr[1]);
2249
2251 ok(ret == 1, "Expected 1, got %d\n", ret);
2252
2253 lo = hi = 0;
2254 ret = UnpackDDElParam(WM_DDE_POKE, lparam, &lo, &hi);
2255 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
2256 ok(lo == 0xcafe, "Expected 0xcafe, got %08lx\n", lo);
2257 ok(hi == 0xbeef, "Expected 0xbeef, got %08lx\n", hi);
2258 }
2259 else
2260 win_skip("no lparam for WM_DDE_POKE\n");
2261
2263 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
2264
2265 lparam = PackDDElParam(WM_DDE_EXECUTE, 0xcafe, 0xbeef);
2266 ok(lparam == 0xbeef, "Expected 0xbeef, got %08lx\n", lparam);
2267
2268 lo = hi = 0;
2270 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
2271 ok(lo == 0, "Expected 0, got %08lx\n", lo);
2272 ok(hi == 0xbeef, "Expected 0xbeef, got %08lx\n", hi);
2273
2275 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
2276}
2277
2278static void test_UnpackDDElParam(void)
2279{
2280 UINT_PTR lo, hi, *ptr;
2281 HGLOBAL hglobal;
2282 BOOL ret;
2283
2284 /* NULL lParam */
2285 lo = 0xdead;
2286 hi = 0xbeef;
2287 ret = UnpackDDElParam(WM_DDE_INITIATE, 0, &lo, &hi);
2288 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
2289 ok(lo == 0, "Expected 0, got %08lx\n", lo);
2290 ok(hi == 0, "Expected 0, got %08lx\n", hi);
2291
2292 /* NULL lo */
2293 lo = 0xdead;
2294 hi = 0xbeef;
2295 ret = UnpackDDElParam(WM_DDE_INITIATE, 0xcafebabe, NULL, &hi);
2296 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
2297 ok(lo == 0xdead, "Expected 0xdead, got %08lx\n", lo);
2298 ok(hi == 0xcafe, "Expected 0xcafe, got %08lx\n", hi);
2299
2300 /* NULL hi */
2301 lo = 0xdead;
2302 hi = 0xbeef;
2303 ret = UnpackDDElParam(WM_DDE_INITIATE, 0xcafebabe, &lo, NULL);
2304 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
2305 ok(lo == 0xbabe, "Expected 0xbabe, got %08lx\n", lo);
2306 ok(hi == 0xbeef, "Expected 0xbeef, got %08lx\n", hi);
2307
2308 lo = 0xdead;
2309 hi = 0xbeef;
2310 ret = UnpackDDElParam(WM_DDE_INITIATE, 0xcafebabe, &lo, &hi);
2311 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
2312 ok(lo == 0xbabe, "Expected 0xbabe, got %08lx\n", lo);
2313 ok(hi == 0xcafe, "Expected 0xcafe, got %08lx\n", hi);
2314
2315 lo = 0xdead;
2316 hi = 0xbeef;
2317 ret = UnpackDDElParam(WM_DDE_TERMINATE, 0xcafebabe, &lo, &hi);
2318 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
2319 ok(lo == 0xbabe, "Expected 0xbabe, got %08lx\n", lo);
2320 ok(hi == 0xcafe, "Expected 0xcafe, got %08lx\n", hi);
2321
2322 lo = 0xdead;
2323 hi = 0xbeef;
2324 ret = UnpackDDElParam(WM_DDE_ADVISE, 0, &lo, &hi);
2325 ok(ret == FALSE, "Expected FALSE, got %d\n", ret);
2326 ok(lo == 0 ||
2327 broken(lo == 0xdead), /* win2k */
2328 "Expected 0, got %08lx\n", lo);
2329 ok(hi == 0 ||
2330 broken(hi == 0xbeef), /* win2k */
2331 "Expected 0, got %08lx\n", hi);
2332
2333 hglobal = GlobalAlloc(GMEM_DDESHARE, 2 * sizeof(*ptr));
2334 ptr = GlobalLock(hglobal);
2335 ptr[0] = 0xcafebabe;
2336 ptr[1] = 0xdeadbeef;
2337 GlobalUnlock(hglobal);
2338
2339 lo = 0xdead;
2340 hi = 0xbeef;
2341 ret = UnpackDDElParam(WM_DDE_ADVISE, (LPARAM)hglobal, &lo, &hi);
2342 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
2343 ok(lo == 0xcafebabe, "Expected 0xcafebabe, got %08lx\n", lo);
2344 ok(hi == 0xdeadbeef, "Expected 0xdeadbeef, got %08lx\n", hi);
2345
2346 lo = 0xdead;
2347 hi = 0xbeef;
2348 ret = UnpackDDElParam(WM_DDE_UNADVISE, 0xcafebabe, &lo, &hi);
2349 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
2350 ok(lo == 0xbabe, "Expected 0xbabe, got %08lx\n", lo);
2351 ok(hi == 0xcafe, "Expected 0xcafe, got %08lx\n", hi);
2352
2353 lo = 0xdead;
2354 hi = 0xbeef;
2355 ret = UnpackDDElParam(WM_DDE_ACK, (LPARAM)hglobal, &lo, &hi);
2356 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
2357 ok(lo == 0xcafebabe, "Expected 0xcafebabe, got %08lx\n", lo);
2358 ok(hi == 0xdeadbeef, "Expected 0xdeadbeef, got %08lx\n", hi);
2359
2360 lo = 0xdead;
2361 hi = 0xbeef;
2362 ret = UnpackDDElParam(WM_DDE_DATA, (LPARAM)hglobal, &lo, &hi);
2363 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
2364 ok(lo == 0xcafebabe, "Expected 0xcafebabe, got %08lx\n", lo);
2365 ok(hi == 0xdeadbeef, "Expected 0xdeadbeef, got %08lx\n", hi);
2366
2367 lo = 0xdead;
2368 hi = 0xbeef;
2369 ret = UnpackDDElParam(WM_DDE_REQUEST, 0xcafebabe, &lo, &hi);
2370 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
2371 ok(lo == 0xbabe, "Expected 0xbabe, got %08lx\n", lo);
2372 ok(hi == 0xcafe, "Expected 0xcafe, got %08lx\n", hi);
2373
2374 lo = 0xdead;
2375 hi = 0xbeef;
2376 ret = UnpackDDElParam(WM_DDE_POKE, (LPARAM)hglobal, &lo, &hi);
2377 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
2378 ok(lo == 0xcafebabe, "Expected 0xcafebabe, got %08lx\n", lo);
2379 ok(hi == 0xdeadbeef, "Expected 0xdeadbeef, got %08lx\n", hi);
2380
2381 lo = 0xdead;
2382 hi = 0xbeef;
2383 ret = UnpackDDElParam(WM_DDE_EXECUTE, 0xcafebabe, &lo, &hi);
2384 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
2385 ok(lo == 0, "Expected 0, got %08lx\n", lo);
2386 ok(hi == 0xcafebabe, "Expected 0xcafebabe, got %08lx\n", hi);
2387
2388 GlobalFree(hglobal);
2389}
2390
2391static char test_cmd_a_to_a[] = "Test dde command";
2392static WCHAR test_cmd_w_to_w[][32] = {
2393 {'t','e','s','t',' ','d','d','e',' ','c','o','m','m','a','n','d',0},
2394 { 0x2018, 0x2019, 0x0161, 0x0041, 0x02dc, 0 }, /* some chars that should map properly to CP1252 */
2395 { 0x2026, 0x2020, 0x2021, 0x0d0a, 0 }, /* false negative for IsTextUnicode */
2396 { 0x4efa, 0x4efc, 0x0061, 0x4efe, 0 }, /* some Chinese chars */
2397 { 0x0061, 0x0062, 0x0063, 0x9152, 0 }, /* Chinese with latin characters begin */
2398};
2400
2401static HDDEDATA CALLBACK server_end_to_end_callback(UINT uType, UINT uFmt, HCONV hconv,
2402 HSZ hsz1, HSZ hsz2, HDDEDATA hdata,
2403 ULONG_PTR dwData1, ULONG_PTR dwData2)
2404{
2405 DWORD size, rsize;
2406 char str[MAX_PATH];
2407 static int msg_index = 0;
2408 static HCONV conversation = 0;
2409 static const char test_service [] = "TestDDEService";
2410 static const char test_topic [] = "TestDDETopic";
2411
2412 msg_index++;
2413
2414 switch (uType)
2415 {
2416 case XTYP_REGISTER:
2417 {
2418 ok(msg_index % nb_callbacks == 1, "Expected 1 modulo %u, got %d\n", nb_callbacks, msg_index);
2419 return (HDDEDATA)TRUE;
2420 }
2421
2422 case XTYP_CONNECT:
2423 {
2424 ok(msg_index % nb_callbacks == 2, "Expected 2 modulo %u, got %d\n", nb_callbacks, msg_index);
2425 ok(uFmt == 0, "Expected 0, got %d, msg_index=%d\n", uFmt, msg_index);
2426 ok(hconv == 0, "Expected 0, got %p, msg_index=%d\n", hconv, msg_index);
2427 ok(hdata == 0, "Expected 0, got %p, msg_index=%d\n", hdata, msg_index);
2428 ok(dwData1 != 0, "Expected not 0, got %08lx, msg_index=%d\n", dwData1, msg_index);
2429 ok(dwData2 == FALSE, "Expected FALSE, got %08lx, msg_index=%d\n", dwData2, msg_index);
2430
2432 ok(!lstrcmpA(str, test_topic), "Expected %s, got %s, msg_index=%d\n",
2433 test_topic, str, msg_index);
2434 ok(size == 12, "Expected 12, got %d, msg_index=%d\n", size, msg_index);
2435
2437 ok(!lstrcmpA(str, test_service), "Expected %s, got %s, msg_index=%d\n",
2438 test_service, str, msg_index);
2439 ok(size == 14, "Expected 14, got %d, msg_index=%d\n", size, msg_index);
2440
2441 return (HDDEDATA) TRUE;
2442 }
2444 {
2445 ok(msg_index % nb_callbacks == 3, "Expected 3 modulo %u, got %d\n", nb_callbacks, msg_index);
2446 conversation = hconv;
2447 return (HDDEDATA) TRUE;
2448 }
2449 case XTYP_EXECUTE:
2450 {
2451 BYTE *buffer = NULL;
2452 WCHAR *cmd_w;
2453 char test_cmd_w_to_a[64];
2454 WCHAR test_cmd_a_to_w[64];
2455 DWORD size_a, size_w, size_w_to_a, size_a_to_w;
2456 BOOL unicode_server, unicode_client, str_index;
2457
2458 ok(uFmt == 0, "Expected 0, got %d\n", uFmt);
2459 ok(hconv == conversation, "Expected conversation handle, got %p, msg_index=%d\n",
2460 hconv, msg_index);
2461 ok(dwData1 == 0, "Expected 0, got %08lx, msg_index=%d\n", dwData1, msg_index);
2462 ok(dwData2 == 0, "Expected 0, got %08lx, msg_index=%d\n", dwData2, msg_index);
2463 ok(hsz2 == 0, "Expected 0, got %p, msg_index=%d\n", hsz2, msg_index);
2465 ok(!lstrcmpA(str, test_topic), "Expected %s, got %s, msg_index=%d\n",
2466 test_topic, str, msg_index);
2467 ok(size == 12, "Expected 12, got %d, msg_index=%d\n", size, msg_index);
2468
2469 size = DdeGetData(hdata, NULL, 0, 0);
2470 ok((buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size)) != NULL, "should not be null\n");
2471 rsize = DdeGetData(hdata, buffer, size, 0);
2472 ok(rsize == size, "Incorrect size returned, expected %d got %d, msg_index=%d\n",
2473 size, rsize, msg_index);
2474 trace("msg %u strA \"%s\" strW %s\n", msg_index, buffer, wine_dbgstr_w((WCHAR*)buffer));
2475
2476 unicode_server = (msg_index / nb_callbacks == 1 || msg_index / nb_callbacks == 2);
2477 unicode_client = (msg_index / nb_callbacks == 1 || msg_index / nb_callbacks == 3);
2478 str_index = msg_index % nb_callbacks - 4;
2479 cmd_w = test_cmd_w_to_w[str_index - 1];
2480 size_a = strlen(test_cmd_a_to_a) + 1;
2481 size_w = (lstrlenW(cmd_w) + 1) * sizeof(WCHAR);
2482 size_a_to_w = MultiByteToWideChar( CP_ACP, 0, test_cmd_a_to_a, -1, test_cmd_a_to_w,
2483 ARRAY_SIZE(test_cmd_a_to_w)) * sizeof(WCHAR);
2484 size_w_to_a = WideCharToMultiByte( CP_ACP, 0, cmd_w, -1,
2485 test_cmd_w_to_a, sizeof(test_cmd_w_to_a), NULL, NULL );
2486 switch (str_index)
2487 {
2488 case 0: /* ASCII string */
2489 if (unicode_server)
2490 {
2491 ok(size == size_a_to_w, "Wrong size %d/%d, msg_index=%d\n", size, size_a_to_w, msg_index);
2492 ok(!lstrcmpW((WCHAR*)buffer, test_cmd_a_to_w),
2493 "Expected %s, msg_index=%d\n", wine_dbgstr_w(test_cmd_a_to_w), msg_index);
2494 }
2495 else if (unicode_client)
2496 {
2497 /* ASCII string mapped W->A -> garbage */
2498 }
2499 else
2500 {
2501 ok(size == size_a, "Wrong size %d/%d, msg_index=%d\n", size, size_a, msg_index);
2502 ok(!lstrcmpA((CHAR*)buffer, test_cmd_a_to_a), "Expected %s, got %s, msg_index=%d\n",
2503 test_cmd_a_to_a, buffer, msg_index);
2504 }
2505 break;
2506
2507 case 1: /* Unicode string with only 8-bit chars */
2508 if (unicode_server)
2509 {
2510 ok(size == size_w, "Wrong size %d/%d, msg_index=%d\n", size, size_w, msg_index);
2511 ok(!lstrcmpW((WCHAR*)buffer, cmd_w),
2512 "Expected %s, msg_index=%d\n", wine_dbgstr_w(cmd_w), msg_index);
2513 }
2514 else
2515 {
2516 ok(size == size_w_to_a, "Wrong size %d/%d, msg_index=%d\n",
2517 size, size_w_to_a, msg_index);
2518 ok(!lstrcmpA((CHAR*)buffer, test_cmd_w_to_a), "Expected %s, got %s, msg_index=%d\n",
2519 test_cmd_w_to_a, buffer, msg_index);
2520 }
2521 break;
2522
2523 case 2: /* normal Unicode string */
2524 case 3: /* IsTextUnicode false negative */
2525 case 4: /* Chinese chars */
2526 if (unicode_server)
2527 {
2528 /* double A->W mapping */
2529 /* NT uses the full size, XP+ only until the first null */
2530 DWORD nt_size = MultiByteToWideChar( CP_ACP, 0, (char *)cmd_w, size_w, test_cmd_a_to_w,
2531 ARRAY_SIZE(test_cmd_a_to_w)) * sizeof(WCHAR);
2532 DWORD xp_size = MultiByteToWideChar( CP_ACP, 0, (char *)cmd_w, -1, NULL, 0 ) * sizeof(WCHAR);
2533 ok(size == xp_size || broken(size == nt_size) ||
2534 broken(str_index == 4 && IsDBCSLeadByte(cmd_w[0])) /* East Asian */,
2535 "Wrong size %d/%d, msg_index=%d\n", size, size_a_to_w, msg_index);
2536 ok(!lstrcmpW((WCHAR*)buffer, test_cmd_a_to_w),
2537 "Expected %s, msg_index=%d\n", wine_dbgstr_w(test_cmd_a_to_w), msg_index);
2538 }
2539 else if (unicode_client)
2540 {
2541 ok(size == size_w_to_a, "Wrong size %d/%d, msg_index=%d\n", size, size_w_to_a, msg_index);
2542 ok(!lstrcmpA((CHAR*)buffer, test_cmd_w_to_a), "Expected %s, got %s, msg_index=%d\n",
2543 test_cmd_w_to_a, buffer, msg_index);
2544 }
2545 else
2546 {
2547 ok(size == size_w, "Wrong size %d/%d, msg_index=%d\n", size, size_w, msg_index);
2548 ok(!lstrcmpW((WCHAR*)buffer, cmd_w),
2549 "Expected %s, msg_index=%d\n", wine_dbgstr_w(cmd_w), msg_index);
2550 }
2551 break;
2552 case 5: /* Chinese with latin characters begin */
2553 if (unicode_server && unicode_client)
2554 {
2555 todo_wine ok(size == size_w, "Wrong size %d expected %d, msg_index=%d\n", size, size_w, msg_index);
2556 MultiByteToWideChar(CP_ACP, 0, test_cmd_w_to_a, size_w, test_cmd_a_to_w,
2557 ARRAY_SIZE(test_cmd_a_to_w));
2558 todo_wine ok(!lstrcmpW((WCHAR*)buffer, cmd_w),
2559 "Expected %s got %s, msg_index=%d\n", wine_dbgstr_w(cmd_w), wine_dbgstr_w((WCHAR *)buffer), msg_index);
2560 }
2561 else if (unicode_server)
2562 {
2563 todo_wine ok(size == size_w, "Wrong size %d expected %d, msg_index=%d\n", size, size_w, msg_index);
2564 MultiByteToWideChar(CP_ACP, 0, test_cmd_w_to_a, size_w, test_cmd_a_to_w,
2565 ARRAY_SIZE(test_cmd_a_to_w));
2566 if (!is_cjk())
2567 todo_wine ok(!lstrcmpW((WCHAR*)buffer, test_cmd_a_to_w), "Expected %s, got %s, msg_index=%d\n",
2568 wine_dbgstr_w(test_cmd_a_to_w), wine_dbgstr_w((WCHAR*)buffer), msg_index);
2569 else
2570 todo_wine ok(!lstrcmpW((WCHAR*)buffer, cmd_w),
2571 "Expected %s got %s, msg_index=%d\n", wine_dbgstr_w(cmd_w), wine_dbgstr_w((WCHAR *)buffer), msg_index);
2572 }
2573 else if (unicode_client)
2574 {
2575 ok(size == size_w_to_a, "Wrong size %d expected %d, msg_index=%d\n", size, size_w_to_a, msg_index);
2576 ok(!lstrcmpA((CHAR*)buffer, test_cmd_w_to_a), "Expected %s, got %s, msg_index=%d\n",
2577 test_cmd_w_to_a, buffer, msg_index);
2578 }
2579 else
2580 {
2581 todo_wine ok(size == size_w_to_a || size == (size_w_to_a - 1), "Wrong size %d expected %d or %d, msg_index=%d\n",
2582 size, size_w_to_a, size_w_to_a - 1, msg_index);
2583 todo_wine ok(!lstrcmpA((CHAR*)buffer, test_cmd_w_to_a), "Expected %s, got %s, msg_index=%d\n",
2584 test_cmd_w_to_a, buffer, msg_index);
2585 }
2586 break;
2587
2588 default:
2589 ok( 0, "Invalid message %u\n", msg_index );
2590 break;
2591 }
2593 return (HDDEDATA) DDE_FACK;
2594 }
2595 case XTYP_DISCONNECT:
2596 return (HDDEDATA) TRUE;
2597
2598 default:
2599 ok(FALSE, "Unhandled msg: %08x, msg_index=%d\n", uType, msg_index);
2600 }
2601
2602 return NULL;
2603}
2604
2605static HDDEDATA CALLBACK client_end_to_end_callback(UINT uType, UINT uFmt, HCONV hconv,
2606 HSZ hsz1, HSZ hsz2, HDDEDATA hdata,
2607 ULONG_PTR dwData1, ULONG_PTR dwData2)
2608{
2609 switch (uType)
2610 {
2611 case XTYP_DISCONNECT:
2612 return (HDDEDATA) TRUE;
2613
2614 default:
2615 ok(FALSE, "Unhandled msg: %08x\n", uType);
2616 }
2617
2618 return NULL;
2619}
2620
2621static void test_end_to_end_client(BOOL type_a)
2622{
2623 DWORD i, ret, err;
2624 DWORD client_pid = 0;
2625 HSZ server, topic;
2626 HCONV hconv;
2627 HDDEDATA hdata;
2628 static const char test_service[] = "TestDDEService";
2629 static const WCHAR test_service_w[] = {'T','e','s','t','D','D','E','S','e','r','v','i','c','e',0};
2630 static const char test_topic[] = "TestDDETopic";
2631 static const WCHAR test_topic_w[] = {'T','e','s','t','D','D','E','T','o','p','i','c',0};
2632
2633 trace("Start end to end client %s\n", type_a ? "ASCII" : "UNICODE");
2634
2635 if (type_a)
2637 else
2639 ok(ret == DMLERR_NO_ERROR, "Expected DMLERR_NO_ERROR, got %x\n", ret);
2640
2641 if (type_a)
2642 {
2645 }
2646 else {
2649 }
2650
2653 ok(hconv != NULL, "Expected non-NULL conversation\n");
2655 ok(ret == DMLERR_NO_ERROR, "Expected DMLERR_NO_ERROR, got %x\n", ret);
2657
2658 /* Test both A and W data being passed to DdeClientTransaction */
2660 hconv, (HSZ)0xdead, 0xbeef, XTYP_EXECUTE, 1000, &ret);
2661 ok(hdata != NULL, "DdeClientTransaction failed\n");
2662 ok(ret == DDE_FACK, "wrong status code %x\n", ret);
2664 ok(err == DMLERR_NO_ERROR, "wrong dde error %x\n", err);
2665
2666 for (i = 0; i < ARRAY_SIZE(test_cmd_w_to_w); i++)
2667 {
2669 (lstrlenW(test_cmd_w_to_w[i]) + 1) * sizeof(WCHAR),
2670 hconv, (HSZ)0xdead, 0xbeef, XTYP_EXECUTE, 1000, &ret);
2671 ok(hdata != NULL, "DdeClientTransaction failed\n");
2672 ok(ret == DDE_FACK, "wrong status code %x\n", ret);
2674 ok(err == DMLERR_NO_ERROR, "wrong dde error %x\n", err);
2675 }
2676
2678 ret = DdeDisconnect(hconv);
2679 ok(ret == TRUE, "Expected TRUE, got %x\n", ret);
2680
2682 ok(ret == TRUE, "Expected TRUE, got %x\n", ret);
2683
2684}
2685
2686static void test_end_to_end_server(HANDLE hproc, HANDLE hthread, BOOL type_a)
2687{
2688 MSG msg;
2689 HSZ server;
2690 BOOL ret;
2691 DWORD res;
2692 HDDEDATA hdata;
2693 static const char test_service[] = "TestDDEService";
2694
2695 trace("start end to end server %s\n", type_a ? "ASCII" : "UNICODE");
2696 server_pid = 0;
2697
2698 if (type_a)
2700 else
2702 ok(res == DMLERR_NO_ERROR, "Expected DMLERR_NO_ERROR, got %d\n", res);
2703
2705 ok(server != NULL, "Expected non-NULL string handle\n");
2706
2708 ok(hdata == (HDDEDATA)TRUE, "Expected TRUE, got %p\n", hdata);
2709 ResumeThread( hthread );
2710
2711
2712 while (MsgWaitForMultipleObjects( 1, &hproc, FALSE, INFINITE, QS_ALLINPUT ) != 0)
2713 {
2714 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
2715 }
2716
2718 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
2719 GetExitCodeProcess( hproc, &res );
2720 ok( !res, "client failed with %u error(s)\n", res );
2721}
2722
2724{
2725 int argc;
2726 char **argv;
2727 char buffer[MAX_PATH];
2730 DWORD dde_inst = 0xdeadbeef;
2731
2733 if (argc == 3)
2734 {
2735 if (!lstrcmpA(argv[2], "ddeml"))
2737 else if (!lstrcmpA(argv[2], "msg"))
2739 else if (!lstrcmpA(argv[2], "enda"))
2741 else if (!lstrcmpA(argv[2], "endw"))
2743
2744 return;
2745 }
2746
2748
2749 SetLastError(0xdeadbeef);
2752 {
2753 win_skip("Skipping tests on win9x because of brokenness\n");
2754 return;
2755 }
2756
2757 ZeroMemory(&startup, sizeof(STARTUPINFOA));
2758 sprintf(buffer, "%s dde ddeml", argv[0]);
2759 startup.cb = sizeof(startup);
2760 startup.dwFlags = STARTF_USESHOWWINDOW;
2761 startup.wShowWindow = SW_SHOWNORMAL;
2762
2765
2766 test_msg_server(proc.hProcess, proc.hThread);
2767
2768 sprintf(buffer, "%s dde msg", argv[0]);
2770 0, NULL, NULL, &startup, &proc);
2771
2772 test_ddeml_server(proc.hProcess);
2773
2774 /* Test the combinations of A and W interfaces with A and W data
2775 end to end to ensure that data conversions are accurate */
2776 sprintf(buffer, "%s dde enda", argv[0]);
2779
2780 test_end_to_end_server(proc.hProcess, proc.hThread, TRUE);
2781
2782 /* Don't bother testing W interfaces on Win9x/WinMe */
2783 SetLastError(0xdeadbeef);
2784 lstrcmpW(NULL, NULL);
2786 {
2787 win_skip("Skipping W-interface tests\n");
2788 }
2789 else
2790 {
2791 sprintf(buffer, "%s dde endw", argv[0]);
2794
2795 test_end_to_end_server(proc.hProcess, proc.hThread, FALSE);
2796
2797 sprintf(buffer, "%s dde enda", argv[0]);
2800
2801 test_end_to_end_server(proc.hProcess, proc.hThread, FALSE);
2802
2803 sprintf(buffer, "%s dde endw", argv[0]);
2806
2807 test_end_to_end_server(proc.hProcess, proc.hThread, TRUE);
2808
2813
2817 }
2819
2825}
static int argc
Definition: ServiceArgs.c:12
@ lparam
Definition: SystemMenu.c:31
@ wparam
Definition: SystemMenu.c:30
#define broken(x)
Definition: _sntprintf.h:21
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
static void startup(void)
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define START_TEST(x)
Definition: atltest.h:75
#define msg(x)
Definition: auth_time.c:54
#define CF_TEXT
Definition: constants.h:396
#define ARRAY_SIZE(A)
Definition: main.h:33
INT cmd_type(LPTSTR)
Definition: type.c:221
#define WM_DDE_REQUEST
Definition: dde.h:43
LPARAM WINAPI ReuseDDElParam(LPARAM, UINT, UINT, UINT_PTR, UINT_PTR)
Definition: ddemisc.c:171
BOOL WINAPI UnpackDDElParam(UINT, LPARAM, PUINT_PTR, PUINT_PTR)
Definition: ddemisc.c:105
#define WM_DDE_DATA
Definition: dde.h:42
#define WM_DDE_POKE
Definition: dde.h:44
#define WM_DDE_LAST
Definition: dde.h:46
#define WM_DDE_ADVISE
Definition: dde.h:39
BOOL WINAPI FreeDDElParam(UINT, LPARAM)
Definition: ddemisc.c:147
#define WM_DDE_ACK
Definition: dde.h:41
#define WM_DDE_EXECUTE
Definition: dde.h:45
#define WM_DDE_INITIATE
Definition: dde.h:37
LPARAM WINAPI PackDDElParam(UINT, UINT_PTR, UINT_PTR)
Definition: ddemisc.c:63
#define WM_DDE_UNADVISE
Definition: dde.h:40
#define WM_DDE_TERMINATE
Definition: dde.h:38
#define XTYP_ADVREQ
Definition: ddeml.h:182
HDDEDATA WINAPI DdeClientTransaction(LPBYTE, DWORD, HCONV, HSZ, UINT, UINT, DWORD, LPDWORD)
Definition: ddeclient.c:1122
HSZ WINAPI DdeCreateStringHandleA(DWORD, LPCSTR, INT)
Definition: ddemisc.c:577
UINT WINAPI DdeQueryConvInfo(HCONV, DWORD, PCONVINFO)
Definition: ddemisc.c:2426
#define ST_CONNECTED
Definition: ddeml.h:80
#define ST_CLIENT
Definition: ddeml.h:84
#define XTYP_MONITOR
Definition: ddeml.h:195
#define XTYP_XACT_COMPLETE
Definition: ddeml.h:188
HDDEDATA WINAPI DdeCreateDataHandle(DWORD, LPBYTE, DWORD, DWORD, HSZ, UINT, UINT)
Definition: ddemisc.c:1275
#define DNS_REGISTER
Definition: ddeml.h:152
#define DMLERR_NO_ERROR
Definition: ddeml.h:242
BOOL WINAPI DdeUninitialize(DWORD)
Definition: ddemisc.c:1112
#define XTYP_CONNECT
Definition: ddeml.h:186
#define XTYP_ERROR
Definition: ddeml.h:180
#define DDE_FACK
Definition: ddeml.h:216
#define XTYP_REQUEST
Definition: ddeml.h:191
UINT WINAPI DdeInitializeW(LPDWORD, PFNCALLBACK, DWORD, DWORD)
Definition: ddemisc.c:1095
#define DMLERR_MEMORY_ERROR
Definition: ddeml.h:254
HCONV WINAPI DdeConnect(DWORD, HSZ, HSZ, PCONVCONTEXT)
Definition: ddeclient.c:84
#define XTYP_CONNECT_CONFIRM
Definition: ddeml.h:187
#define DMLERR_NOTPROCESSED
Definition: ddeml.h:255
#define XTYP_UNREGISTER
Definition: ddeml.h:193
UINT WINAPI DdeGetLastError(DWORD)
Definition: ddemisc.c:253
#define XTYP_REGISTER
Definition: ddeml.h:190
HSZ WINAPI DdeCreateStringHandleW(DWORD, LPCWSTR, INT)
Definition: ddemisc.c:608
#define DDE_FNOTPROCESSED
Definition: ddeml.h:223
#define XTYP_SHIFT
Definition: ddeml.h:198
#define XTYP_DISCONNECT
Definition: ddeml.h:192
DWORD WINAPI DdeQueryStringA(DWORD, HSZ, LPSTR, DWORD, INT)
Definition: ddemisc.c:501
#define XTYP_POKE
Definition: ddeml.h:189
DWORD WINAPI DdeQueryStringW(DWORD, HSZ, LPWSTR, DWORD, INT)
Definition: ddemisc.c:525
BOOL WINAPI DdeFreeStringHandle(DWORD, HSZ)
Definition: ddemisc.c:631
BOOL WINAPI DdeDisconnect(HCONV)
Definition: ddeclient.c:1363
#define QID_SYNC
Definition: ddeml.h:40
#define XST_CONNECTED
Definition: ddeml.h:64
#define CP_WINANSI
Definition: ddeml.h:32
#define XTYP_EXECUTE
Definition: ddeml.h:185
HDDEDATA WINAPI DdeNameService(DWORD, HSZ, HSZ, UINT)
Definition: ddeserver.c:154
#define CP_WINUNICODE
Definition: ddeml.h:33
#define DMLERR_NO_CONV_ESTABLISHED
Definition: ddeml.h:256
BOOL WINAPI DdeUnaccessData(HDDEDATA)
Definition: ddemisc.c:1447
#define XTYP_WILDCONNECT
Definition: ddeml.h:194
LPBYTE WINAPI DdeAccessData(HDDEDATA, LPDWORD)
Definition: ddemisc.c:1422
#define XTYP_MASK
Definition: ddeml.h:197
BOOL WINAPI DdeFreeDataHandle(HDDEDATA)
Definition: ddemisc.c:1461
#define APPCMD_CLIENTONLY
Definition: ddeml.h:122
DWORD WINAPI DdeGetData(HDDEDATA, LPBYTE, DWORD, DWORD)
Definition: ddemisc.c:1379
#define DMLERR_INVALIDPARAMETER
Definition: ddeml.h:252
#define APPCLASS_STANDARD
Definition: ddeml.h:130
UINT WINAPI DdeInitializeA(LPDWORD, PFNCALLBACK, DWORD, DWORD)
Definition: ddemisc.c:1075
#define WAIT_TIMEOUT
Definition: dderror.h:14
WORD ATOM
Definition: dimm.idl:113
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
UINT op
Definition: effect.c:236
#define GetProcessHeap()
Definition: compat.h:736
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:102
#define CP_ACP
Definition: compat.h:109
#define SetLastError(x)
Definition: compat.h:752
HANDLE HWND
Definition: compat.h:19
#define HeapAlloc
Definition: compat.h:733
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define CALLBACK
Definition: compat.h:35
#define WideCharToMultiByte
Definition: compat.h:111
#define MultiByteToWideChar
Definition: compat.h:110
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define lstrlenW
Definition: compat.h:750
ATOM WINAPI FindAtomW(LPCWSTR lpString)
Definition: atom.c:566
ATOM WINAPI GlobalFindAtomW(LPCWSTR lpString)
Definition: atom.c:474
ATOM WINAPI FindAtomA(LPCSTR lpString)
Definition: atom.c:556
ATOM WINAPI GlobalAddAtomA(LPCSTR lpString)
Definition: atom.c:434
ATOM WINAPI GlobalFindAtomA(LPCSTR lpString)
Definition: atom.c:464
ATOM WINAPI GlobalDeleteAtom(ATOM nAtom)
Definition: atom.c:454
UINT WINAPI GlobalGetAtomNameA(ATOM nAtom, LPSTR lpBuffer, int nSize)
Definition: atom.c:484
ATOM WINAPI GlobalAddAtomW(LPCWSTR lpString)
Definition: atom.c:444
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
BOOL WINAPI GetExitCodeProcess(IN HANDLE hProcess, IN LPDWORD lpExitCode)
Definition: proc.c:1168
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessA(LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
Definition: proc.c:4741
DWORD WINAPI ResumeThread(IN HANDLE hThread)
Definition: thread.c:567
DWORD WINAPI GetTickCount(VOID)
Definition: time.c:455
BOOL WINAPI IsDBCSLeadByte(BYTE TestByte)
Definition: nls.c:2359
#define INFINITE
Definition: serial.h:102
#define ULONG_PTR
Definition: config.h:101
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLsizeiptr size
Definition: glext.h:5919
GLuint res
Definition: glext.h:9613
GLuint buffer
Definition: glext.h:5915
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLuint GLfloat * val
Definition: glext.h:7180
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
LPVOID NTAPI GlobalLock(HGLOBAL hMem)
Definition: heapmem.c:755
HGLOBAL NTAPI GlobalFree(HGLOBAL hMem)
Definition: heapmem.c:611
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
static DWORD dde_inst
Definition: iexplore.c:59
#define wine_dbgstr_w
Definition: kernel32.h:34
LANGID WINAPI GetUserDefaultLangID(void)
Definition: lang.c:744
LPSTR WINAPI lstrcpyA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:100
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
int WINAPI lstrcmpA(LPCSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:18
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
__u16 time
Definition: mkdosfs.c:8
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
static PVOID ptr
Definition: dispmode.c:27
#define sprintf(buf, format,...)
Definition: sprintf.c:55
#define todo_wine
Definition: custom.c:79
static void test_service(void)
Definition: service.c:441
static void test_PackDDElParam(void)
Definition: dde.c:2118
static void test_ddeml_server(HANDLE hproc)
Definition: dde.c:826
static WCHAR test_cmd_w_to_w[][32]
Definition: dde.c:2392
static LRESULT WINAPI dde_server_wndprocA(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
Definition: dde.c:1233
static LRESULT WINAPI dde_msg_client_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
Definition: dde.c:859
static const DWORD default_timeout
Definition: dde.c:44
static void test_end_to_end_client(BOOL type_a)
Definition: dde.c:2621
static void test_dde_aw_transaction(BOOL client_unicode, BOOL server_unicode)
Definition: dde.c:1570
static void test_DdeCreateStringHandleW(DWORD dde_inst, int codepage)
Definition: dde.c:1786
static HGLOBAL create_poke(void)
Definition: dde.c:1029
static HDDEDATA CALLBACK server_ddeml_callback(UINT uType, UINT uFmt, HCONV hconv, HSZ hsz1, HSZ hsz2, HDDEDATA hdata, ULONG_PTR dwData1, ULONG_PTR dwData2)
Definition: dde.c:590
static void test_DdeCreateDataHandle(void)
Definition: dde.c:1867
static LRESULT WINAPI dde_server_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
Definition: dde.c:95
static void test_DdeCreateStringHandle(void)
Definition: dde.c:2047
static char exec_cmdWA[]
Definition: dde.c:40
static HDDEDATA CALLBACK server_end_to_end_callback(UINT uType, UINT uFmt, HCONV hconv, HSZ hsz1, HSZ hsz2, HDDEDATA hdata, ULONG_PTR dwData1, ULONG_PTR dwData2)
Definition: dde.c:2401
static WCHAR exec_cmdW[]
Definition: dde.c:39
static HWND create_dde_server(BOOL unicode)
Definition: dde.c:1514
static HDDEDATA CALLBACK client_ddeml_callback(UINT uType, UINT uFmt, HCONV hconv, HSZ hsz1, HSZ hsz2, HDDEDATA hdata, ULONG_PTR dwData1, ULONG_PTR dwData2)
Definition: dde.c:275
static HWND client_hwnd
Definition: dde.c:855
static LRESULT WINAPI hook_dde_client_wndprocA(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
Definition: dde.c:1195
static HDDEDATA CALLBACK client_dde_callback(UINT uType, UINT uFmt, HCONV hconv, HSZ hsz1, HSZ hsz2, HDDEDATA hdata, ULONG_PTR dwData1, ULONG_PTR dwData2)
Definition: dde.c:1550
static const int nb_callbacks
Definition: dde.c:2399
static void test_msg_server(HANDLE hproc, HANDLE hthread)
Definition: dde.c:256
static const WCHAR TEST_DDE_SERVICE[]
Definition: dde.c:35
static void flush_events(void)
Definition: dde.c:55
static void test_FreeDDElParam(void)
Definition: dde.c:2069
static HWND server_hwnd
Definition: dde.c:855
static void test_end_to_end_server(HANDLE hproc, HANDLE hthread, BOOL type_a)
Definition: dde.c:2686
static char test_cmd_a_to_a[]
Definition: dde.c:2391
static void test_ddeml_client(void)
Definition: dde.c:283
static HGLOBAL create_execute(LPCSTR command)
Definition: dde.c:1050
static ATOM server
Definition: dde.c:856
static LRESULT WINAPI hook_dde_client_wndprocW(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
Definition: dde.c:1214
static void test_initialisation(void)
Definition: dde.c:1738
static BOOL is_cjk(void)
Definition: dde.c:46
static DWORD server_pid
Definition: dde.c:588
static void test_UnpackDDElParam(void)
Definition: dde.c:2278
static HDDEDATA CALLBACK client_end_to_end_callback(UINT uType, UINT uFmt, HCONV hconv, HSZ hsz1, HSZ hsz2, HDDEDATA hdata, ULONG_PTR dwData1, ULONG_PTR dwData2)
Definition: dde.c:2605
static WNDPROC old_dde_client_wndproc
Definition: dde.c:42
static char exec_cmdA[]
Definition: dde.c:37
static void destroy_dde_window(HWND *hwnd, LPCSTR name)
Definition: dde.c:89
static ATOM topic
Definition: dde.c:856
static void test_msg_client(void)
Definition: dde.c:1065
static HGLOBAL execute_hglobal
Definition: dde.c:857
static ATOM item
Definition: dde.c:856
static void create_dde_window(HWND *hwnd, LPCSTR name, WNDPROC wndproc)
Definition: dde.c:71
static WCHAR exec_cmdAW[]
Definition: dde.c:38
static LRESULT WINAPI dde_server_wndprocW(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
Definition: dde.c:1369
#define argv
Definition: mplay32.c:18
static DWORD client_pid
Definition: msiexec.c:386
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
unsigned int UINT
Definition: ndis.h:50
static HANDLE proc()
Definition: pdb.c:34
#define LOWORD(l)
Definition: pedump.c:82
#define WS_POPUP
Definition: pedump.c:616
#define err(...)
const WCHAR * str
#define LANG_CHINESE
Definition: nls.h:42
#define LANG_JAPANESE
Definition: nls.h:76
#define PRIMARYLANGID(l)
Definition: nls.h:16
#define LANG_KOREAN
Definition: nls.h:84
#define win_skip
Definition: test.h:160
int winetest_get_mainargs(char ***pargv)
#define memset(x, y, z)
Definition: compat.h:39
static FILE * client
Definition: client.c:41
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
Definition: dde.h:72
short cfFormat
Definition: dde.h:74
BYTE Value[1]
Definition: dde.h:75
unsigned short unused
Definition: dde.h:73
unsigned short fReserved
Definition: dde.h:73
unsigned short fRelease
Definition: dde.h:73
HINSTANCE hInstance
Definition: winuser.h:3167
LPCSTR lpszClassName
Definition: winuser.h:3172
WNDPROC lpfnWndProc
Definition: winuser.h:3164
LPCWSTR lpszClassName
Definition: winuser.h:3185
HINSTANCE hInstance
Definition: winuser.h:3180
WNDPROC lpfnWndProc
Definition: winuser.h:3177
Definition: ftp_var.h:139
Definition: name.c:39
Definition: ps.c:97
#define GWLP_WNDPROC
Definition: treelist.c:66
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1829
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
unsigned char * LPBYTE
Definition: typedefs.h:53
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define MAKELONG(a, b)
Definition: typedefs.h:249
#define HIWORD(l)
Definition: typedefs.h:247
int ret
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
int codepage
Definition: win_iconv.c:156
#define ZeroMemory
Definition: winbase.h:1712
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define STARTF_USESHOWWINDOW
Definition: winbase.h:491
#define CREATE_SUSPENDED
Definition: winbase.h:178
#define GMEM_MOVEABLE
Definition: winbase.h:294
#define GMEM_DDESHARE
Definition: winbase.h:298
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
LONG_PTR LPARAM
Definition: windef.h:208
LONG_PTR LRESULT
Definition: windef.h:209
UINT_PTR WPARAM
Definition: windef.h:207
#define WINAPI
Definition: msvc.h:6
#define SW_SHOWNORMAL
Definition: winuser.h:770
LRESULT WINAPI DispatchMessageA(_In_ const MSG *)
#define SetWindowLongPtrA
Definition: winuser.h:5345
HWND WINAPI CreateWindowExA(_In_ DWORD dwExStyle, _In_opt_ LPCSTR lpClassName, _In_opt_ LPCSTR lpWindowName, _In_ DWORD dwStyle, _In_ int X, _In_ int Y, _In_ int nWidth, _In_ int nHeight, _In_opt_ HWND hWndParent, _In_opt_ HMENU hMenu, _In_opt_ HINSTANCE hInstance, _In_opt_ LPVOID lpParam)
BOOL WINAPI UnregisterClassA(_In_ LPCSTR, HINSTANCE)
LRESULT WINAPI DefWindowProcW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
LRESULT WINAPI DefWindowProcA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
BOOL WINAPI PostMessageW(_In_opt_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define HWND_BROADCAST
Definition: winuser.h:1204
ATOM WINAPI RegisterClassW(_In_ CONST WNDCLASSW *)
LRESULT WINAPI SendMessageA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define QS_ALLINPUT
Definition: winuser.h:903
DWORD WINAPI MsgWaitForMultipleObjects(_In_ DWORD nCount, _In_reads_opt_(nCount) CONST HANDLE *pHandles, _In_ BOOL fWaitAll, _In_ DWORD dwMilliseconds, _In_ DWORD dwWakeMask)
HWND WINAPI GetDesktopWindow(void)
Definition: window.c:656
BOOL WINAPI IsWindowUnicode(_In_ HWND)
ATOM WINAPI RegisterClassA(_In_ CONST WNDCLASSA *)
HWND WINAPI CreateWindowExW(_In_ DWORD dwExStyle, _In_opt_ LPCWSTR lpClassName, _In_opt_ LPCWSTR lpWindowName, _In_ DWORD dwStyle, _In_ int X, _In_ int Y, _In_ int nWidth, _In_ int nHeight, _In_opt_ HWND hWndParent, _In_opt_ HMENU hMenu, _In_opt_ HINSTANCE hInstance, _In_opt_ LPVOID lpParam)
#define PM_REMOVE
Definition: winuser.h:1196
#define CW_USEDEFAULT
Definition: winuser.h:225
BOOL WINAPI PeekMessageA(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT, _In_ UINT)
LRESULT(CALLBACK * WNDPROC)(HWND, UINT, WPARAM, LPARAM)
Definition: winuser.h:2906
#define SetWindowLongPtrW
Definition: winuser.h:5346
LRESULT WINAPI CallWindowProcW(_In_ WNDPROC, _In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
BOOL WINAPI DestroyWindow(_In_ HWND)
BOOL WINAPI PostMessageA(_In_opt_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
LRESULT WINAPI CallWindowProcA(_In_ WNDPROC, _In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
const char * LPCSTR
Definition: xmlstorage.h:183
char * LPSTR
Definition: xmlstorage.h:182
__wchar_t WCHAR
Definition: xmlstorage.h:180
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
char CHAR
Definition: xmlstorage.h:175
unsigned char BYTE
Definition: xxhash.c:193