ReactOS  0.4.14-dev-49-gfb4591c
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 
35 static const WCHAR TEST_DDE_SERVICE[] = {'T','e','s','t','D','D','E','S','e','r','v','i','c','e',0};
36 
37 static char exec_cmdA[] = "ANSI dde command";
38 static WCHAR exec_cmdAW[] = {'A','N','S','I',' ','d','d','e',' ','c','o','m','m','a','n','d',0};
39 static WCHAR exec_cmdW[] = {'u','n','i','c','o','d','e',' ','d','d','e',' ','c','o','m','m','a','n','d',0};
40 static char exec_cmdWA[] = "unicode dde command";
41 
43 
44 static const DWORD default_timeout = 200;
45 
46 static 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 
55 static 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 
71 static void create_dde_window(HWND *hwnd, LPCSTR name, WNDPROC wndproc)
72 {
73  WNDCLASSA wcA;
74  ATOM aclass;
75 
76  memset(&wcA, 0, sizeof(wcA));
77  wcA.lpfnWndProc = wndproc;
78  wcA.lpszClassName = name;
79  wcA.hInstance = GetModuleHandleA(0);
80  aclass = RegisterClassA(&wcA);
81  ok (aclass, "RegisterClass failed\n");
82 
84  500, 500, CW_USEDEFAULT, CW_USEDEFAULT,
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)
109  return DefWindowProcA(hwnd, msg, wparam, lparam);
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);
160  ZeroMemory(data, size);
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 
187  UnpackDDElParam(WM_DDE_POKE, lparam, &lo, &hi);
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 
208  GlobalUnlock((HGLOBAL)lo);
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 
253  return DefWindowProcA(hwnd, msg, wparam, lparam);
254 }
255 
256 static void test_msg_server(HANDLE hproc, HANDLE hthread)
257 {
258  MSG msg;
259  HWND hwnd;
260  DWORD res;
261 
262  create_dde_window(&hwnd, "dde_server", dde_server_wndproc);
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 
275 static 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 
283 static 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;
291  DWORD client_pid;
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 
300  server = DdeCreateStringHandleA(client_pid, "TestDDEService", CP_WINANSI);
301  topic = DdeCreateStringHandleA(client_pid, "TestDDETopic", CP_WINANSI);
302 
303  DdeGetLastError(client_pid);
304  conversation = DdeConnect(client_pid, server, topic, NULL);
305  ok(conversation != NULL, "Expected non-NULL conversation\n");
306  ret = DdeGetLastError(client_pid);
307  ok(ret == DMLERR_NO_ERROR, "Expected DMLERR_NO_ERROR, got %d\n", ret);
308 
309  DdeFreeStringHandle(client_pid, server);
310 
311  item = DdeCreateStringHandleA(client_pid, "request", CP_WINANSI);
312 
313  /* XTYP_REQUEST, fRelease = TRUE */
314  res = 0xdeadbeef;
315  DdeGetLastError(client_pid);
316  hdata = DdeClientTransaction(NULL, 0, conversation, item, CF_TEXT, XTYP_REQUEST, default_timeout, &res);
317  ret = DdeGetLastError(client_pid);
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;
334  DdeGetLastError(client_pid);
335  hdata = DdeClientTransaction(NULL, 0, conversation, item, CF_TEXT, XTYP_REQUEST, default_timeout, &res);
336  ret = DdeGetLastError(client_pid);
337  ok(res == DDE_FNOTPROCESSED || broken(res == 0xdeadbeef), /* win9x */
338  "Expected DDE_FNOTPROCESSED, got %x\n", res);
339 todo_wine
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;
355  DdeGetLastError(client_pid);
356  hdata = DdeClientTransaction(NULL, 0, conversation, item, CF_TEXT, XTYP_REQUEST, default_timeout, &res);
357  ret = DdeGetLastError(client_pid);
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;
375  DdeGetLastError(client_pid);
376  hdata = DdeClientTransaction(NULL, 0, conversation, 0, CF_TEXT, XTYP_REQUEST, default_timeout, &res);
377  ret = DdeGetLastError(client_pid);
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 
382  DdeFreeStringHandle(client_pid, item);
383 
384  item = DdeCreateStringHandleA(client_pid, "poker", CP_WINANSI);
385 
386  lstrcpyA(buffer, "poke data\r\n");
387  hdata = DdeCreateDataHandle(client_pid, (LPBYTE)buffer, lstrlenA(buffer) + 1,
388  0, item, CF_TEXT, 0);
389  ok(hdata != NULL, "Expected non-NULL hdata\n");
390 
391  /* XTYP_POKE, no item */
392  res = 0xdeadbeef;
393  DdeGetLastError(client_pid);
394  op = DdeClientTransaction((LPBYTE)hdata, -1, conversation, 0, CF_TEXT, XTYP_POKE, default_timeout, &res);
395  ret = DdeGetLastError(client_pid);
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;
402  DdeGetLastError(client_pid);
403  op = DdeClientTransaction(NULL, 0, conversation, 0, CF_TEXT, XTYP_POKE, default_timeout, &res);
404  ret = DdeGetLastError(client_pid);
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;
411  DdeGetLastError(client_pid);
412  op = DdeClientTransaction((LPBYTE)hdata, 0, conversation, item, CF_TEXT, XTYP_POKE, default_timeout, &res);
413  ret = DdeGetLastError(client_pid);
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;
421  DdeGetLastError(client_pid);
422  op = DdeClientTransaction((LPBYTE)hdata, -1, conversation, item, CF_TEXT, XTYP_POKE, default_timeout, &res);
423  ret = DdeGetLastError(client_pid);
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)]");
432  hdata = DdeCreateDataHandle(client_pid, (LPBYTE)buffer, lstrlenA(buffer) + 1,
433  0, NULL, CF_TEXT, 0);
434  ok(hdata != NULL, "Expected non-NULL hdata\n");
435 
436  /* XTYP_EXECUTE, correct params */
437  res = 0xdeadbeef;
438  DdeGetLastError(client_pid);
439  op = DdeClientTransaction((LPBYTE)hdata, -1, conversation, NULL, 0, XTYP_EXECUTE, default_timeout, &res);
440  ret = DdeGetLastError(client_pid);
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;
448  DdeGetLastError(client_pid);
449  op = DdeClientTransaction(NULL, 0, conversation, NULL, 0, XTYP_EXECUTE, default_timeout, &res);
450  ret = DdeGetLastError(client_pid);
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;
465  DdeGetLastError(client_pid);
466  op = DdeClientTransaction(NULL, -1, conversation, NULL, 0, XTYP_EXECUTE, default_timeout, &res);
467  ret = DdeGetLastError(client_pid);
468  ok(op == NULL, "Expected NULL, got %p\n", op);
469  ok(res == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", res);
470  ok(ret == DMLERR_INVALIDPARAMETER || broken(ret == DMLERR_NO_ERROR), /* win9x */
471  "Expected DMLERR_INVALIDPARAMETER, got %d\n", ret);
472 
473  DdeFreeStringHandle(client_pid, topic);
474  DdeFreeDataHandle(hdata);
475 
476  item = DdeCreateStringHandleA(client_pid, "executed", CP_WINANSI);
477 
478  /* verify the execute */
479  res = 0xdeadbeef;
480  DdeGetLastError(client_pid);
481  hdata = DdeClientTransaction(NULL, 0, conversation, item, CF_TEXT, XTYP_REQUEST, default_timeout, &res);
482  ret = DdeGetLastError(client_pid);
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;
500  DdeGetLastError(client_pid);
502  ret = DdeGetLastError(client_pid);
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;
508  DdeGetLastError(client_pid);
510  ret = DdeGetLastError(client_pid);
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;
516  DdeGetLastError(client_pid);
518  ret = DdeGetLastError(client_pid);
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;
524  DdeGetLastError(client_pid);
526  ret = DdeGetLastError(client_pid);
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;
532  DdeGetLastError(client_pid);
534  ret = DdeGetLastError(client_pid);
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;
540  DdeGetLastError(client_pid);
542  ret = DdeGetLastError(client_pid);
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;
548  DdeGetLastError(client_pid);
550  ret = DdeGetLastError(client_pid);
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;
556  DdeGetLastError(client_pid);
558  ret = DdeGetLastError(client_pid);
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;
564  DdeGetLastError(client_pid);
566  ret = DdeGetLastError(client_pid);
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;
572  DdeGetLastError(client_pid);
574  ret = DdeGetLastError(client_pid);
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 
579  DdeFreeStringHandle(client_pid, item);
580 
581  ret = DdeDisconnect(conversation);
582  ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
583 
584  ret = DdeUninitialize(client_pid);
585  ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
586 }
587 
589 
590 static 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);
791  ptr = HeapAlloc(GetProcessHeap(), 0, 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 
800  HeapFree(GetProcessHeap(), 0, ptr);
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 
826 static 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 
839  server = DdeCreateStringHandleA(server_pid, "TestDDEServer", CP_WINANSI);
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)
871  return DefWindowProcA(hwnd, msg, wparam, lparam);
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 
919  UnpackDDElParam(WM_DDE_ACK, lparam, &lo, &hi);
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 
944  GlobalUnlock((HGLOBAL)hi);
945  }
946  else
947  {
948  ok(wparam == (WPARAM)server_hwnd, "Expected server hwnd, got %08lx\n", wparam);
949 
950  UnpackDDElParam(WM_DDE_ACK, lparam, &lo, &hi);
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 
996  UnpackDDElParam(WM_DDE_DATA, lparam, &lo, &hi);
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 
1029 static HGLOBAL create_poke(void)
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);
1059  lstrcpyA(ptr, command);
1060  GlobalUnlock(hglobal);
1061 
1062  return hglobal;
1063 }
1064 
1065 static 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  {
1242  ATOM aService = GlobalAddAtomW(TEST_DDE_SERVICE);
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  {
1378  ATOM aService = GlobalAddAtomW(TEST_DDE_SERVICE);
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 
1514 static 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 
1550 static 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 
1570 static void test_dde_aw_transaction( BOOL client_unicode, BOOL server_unicode )
1571 {
1572  HSZ hsz_server;
1573  DWORD dde_inst, ret, err;
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);
1605 todo_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;
1649  hdata = DdeClientTransaction((LPBYTE)exec_cmdAW, (lstrlenW(exec_cmdAW) + 1) * sizeof(WCHAR),
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");
1725 todo_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 
1738 static void test_initialisation(void)
1739 {
1740  UINT ret;
1741  DWORD res;
1742  HDDEDATA hdata;
1743  HSZ server, topic, item;
1744  DWORD client_pid;
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);
1754  topic = DdeCreateStringHandleA(client_pid, "TestDDETopic", CP_WINANSI);
1755 
1756  DdeGetLastError(client_pid);
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);
1761  ret = DdeGetLastError(client_pid);
1762  ok(ret == DMLERR_NO_CONV_ESTABLISHED, "Expected DMLERR_NO_CONV_ESTABLISHED, got %d\n", ret);
1763 
1764  DdeFreeStringHandle(client_pid, server);
1765 
1766  item = DdeCreateStringHandleA(client_pid, "request", CP_WINANSI);
1767 
1768  /* There is no conversation so an invalid parameter results */
1769  res = 0xdeadbeef;
1770  DdeGetLastError(client_pid);
1771  hdata = DdeClientTransaction(NULL, 0, conversation, item, CF_TEXT, XTYP_REQUEST, default_timeout, &res);
1772  ok(hdata == NULL, "Expected NULL, got %p\n", hdata);
1773  ret = DdeGetLastError(client_pid);
1774 todo_wine
1775  ok(ret == DMLERR_INVALIDPARAMETER, "Expected DMLERR_INVALIDPARAMETER, got %d\n", ret);
1776  ok(res == 0xdeadbeef, "Expected 0xdeadbeef, got %08x\n", res);
1777 
1778  DdeFreeStringHandle(client_pid, server);
1779  ret = DdeDisconnect(conversation);
1780  ok(ret == FALSE, "Expected FALSE, got %d\n", ret);
1781 
1782  ret = DdeUninitialize(client_pid);
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 
1867 static void test_DdeCreateDataHandle(void)
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  */
1892  item = DdeCreateStringHandleA(0, "item", CP_WINANSI);
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);
1898  item = DdeCreateStringHandleW(0, item_str, CP_WINUNICODE);
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 {
2049  DWORD dde_inst, ret;
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 
2069 static 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);
2078  ret = FreeDDElParam(WM_DDE_INITIATE, (LPARAM)hglobal);
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);
2084  ret = FreeDDElParam(WM_DDE_ADVISE, (LPARAM)hglobal);
2085  ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
2086 
2087  hglobal = GlobalAlloc(GMEM_DDESHARE, 100);
2088  ret = FreeDDElParam(WM_DDE_UNADVISE, (LPARAM)hglobal);
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);
2102  ret = FreeDDElParam(WM_DDE_REQUEST, (LPARAM)hglobal);
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);
2112  ret = FreeDDElParam(WM_DDE_EXECUTE, (LPARAM)hglobal);
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 
2118 static 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;
2129  ret = UnpackDDElParam(WM_DDE_INITIATE, lparam, &lo, &hi);
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;
2161  ret = UnpackDDElParam(WM_DDE_ADVISE, lparam, &lo, &hi);
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;
2176  ret = UnpackDDElParam(WM_DDE_UNADVISE, lparam, &lo, &hi);
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;
2234  ret = UnpackDDElParam(WM_DDE_REQUEST, lparam, &lo, &hi);
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;
2269  ret = UnpackDDElParam(WM_DDE_EXECUTE, lparam, &lo, &hi);
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 
2278 static 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 
2391 static char test_cmd_a_to_a[] = "Test dde command";
2392 static 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 };
2399 static const int nb_callbacks = 5 + sizeof(test_cmd_w_to_w)/sizeof(test_cmd_w_to_w[0]);
2400 
2401 static 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  }
2443  case XTYP_CONNECT_CONFIRM:
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  sizeof(test_cmd_a_to_w)/sizeof(WCHAR) ) * 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  sizeof(test_cmd_a_to_w)/sizeof(WCHAR) ) * 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  sizeof(test_cmd_a_to_w)/sizeof(WCHAR));
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  sizeof(test_cmd_a_to_w)/sizeof(WCHAR));
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 
2605 static 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 
2621 static 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  {
2644  topic = DdeCreateStringHandleA(client_pid, test_topic, CP_WINANSI);
2645  }
2646  else {
2647  server = DdeCreateStringHandleW(client_pid, test_service_w, CP_WINUNICODE);
2648  topic = DdeCreateStringHandleW(client_pid, test_topic_w, CP_WINUNICODE);
2649  }
2650 
2651  DdeGetLastError(client_pid);
2652  hconv = DdeConnect(client_pid, server, topic, NULL);
2653  ok(hconv != NULL, "Expected non-NULL conversation\n");
2654  ret = DdeGetLastError(client_pid);
2655  ok(ret == DMLERR_NO_ERROR, "Expected DMLERR_NO_ERROR, got %x\n", ret);
2656  DdeFreeStringHandle(client_pid, server);
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);
2663  err = DdeGetLastError(client_pid);
2664  ok(err == DMLERR_NO_ERROR, "wrong dde error %x\n", err);
2665 
2666  for (i = 0; i < sizeof(test_cmd_w_to_w)/sizeof(test_cmd_w_to_w[0]); 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);
2673  err = DdeGetLastError(client_pid);
2674  ok(err == DMLERR_NO_ERROR, "wrong dde error %x\n", err);
2675  }
2676 
2677  DdeFreeStringHandle(client_pid, topic);
2678  ret = DdeDisconnect(hconv);
2679  ok(ret == TRUE, "Expected TRUE, got %x\n", ret);
2680 
2681  ret = DdeUninitialize(client_pid);
2682  ok(ret == TRUE, "Expected TRUE, got %x\n", ret);
2683 
2684 }
2685 
2686 static 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"))
2738  test_msg_client();
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 ATOM topic
Definition: dde.c:856
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2343
HDDEDATA WINAPI DdeCreateDataHandle(DWORD, LPBYTE, DWORD, DWORD, HSZ, UINT, UINT)
Definition: ddemisc.c:1275
ATOM WINAPI GlobalDeleteAtom(ATOM nAtom)
Definition: atom.c:454
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
static int argc
Definition: ServiceArgs.c:12
static void test_dde_aw_transaction(BOOL client_unicode, BOOL server_unicode)
Definition: dde.c:1570
#define XTYP_REQUEST
Definition: ddeml.h:191
static HWND client_hwnd
Definition: dde.c:855
LRESULT WINAPI DispatchMessageA(_In_ const MSG *)
static LRESULT WINAPI dde_server_wndprocA(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
Definition: dde.c:1233
#define TRUE
Definition: types.h:120
HGLOBAL NTAPI GlobalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:368
HCONV WINAPI DdeConnect(DWORD, HSZ, HSZ, PCONVCONTEXT)
Definition: ddeclient.c:84
static char exec_cmdWA[]
Definition: dde.c:40
#define WM_DDE_UNADVISE
Definition: dde.h:40
static HWND server_hwnd
Definition: dde.c:855
#define ST_CLIENT
Definition: ddeml.h:84
#define WideCharToMultiByte
Definition: compat.h:101
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
#define XST_CONNECTED
Definition: ddeml.h:64
UINT WINAPI DdeGetLastError(DWORD)
Definition: ddemisc.c:253
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
unsigned short bAppReturnCode
Definition: dde.h:52
WORD ATOM
Definition: dimm.idl:113
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define XTYP_ERROR
Definition: ddeml.h:180
Definition: ftp_var.h:139
BOOL WINAPI PostMessageA(_In_opt_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
LPBYTE WINAPI DdeAccessData(HDDEDATA, LPDWORD)
Definition: ddemisc.c:1422
LRESULT WINAPI SendMessageA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
char * wine_dbgstr_w(const wchar_t *wstr)
Definition: atltest.h:87
BOOL WINAPI GetExitCodeProcess(IN HANDLE hProcess, IN LPDWORD lpExitCode)
Definition: proc.c:1168
#define CP_ACP
Definition: compat.h:99
unsigned short unused
Definition: dde.h:73
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
char CHAR
Definition: xmlstorage.h:175
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1827
Definition: dde.h:71
#define XTYP_EXECUTE
Definition: ddeml.h:185
unsigned short fRelease
Definition: dde.h:73
#define CALLBACK
Definition: compat.h:27
#define DMLERR_MEMORY_ERROR
Definition: ddeml.h:254
DWORD WINAPI GetTickCount(VOID)
Definition: time.c:445
HANDLE HWND
Definition: compat.h:13
ATOM WINAPI GlobalAddAtomA(LPCSTR lpString)
Definition: atom.c:434
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
int WINAPI lstrcmpA(LPCSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:18
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
#define XTYP_CONNECT_CONFIRM
Definition: ddeml.h:187
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define ZeroMemory
Definition: winbase.h:1635
GLuint buffer
Definition: glext.h:5915
int startup(int argc, const char *argv[])
Definition: startup.c:430
#define ST_CONNECTED
Definition: ddeml.h:80
char * cmd
Definition: vfdcmd.c:85
ATOM WINAPI GlobalFindAtomW(LPCWSTR lpString)
Definition: atom.c:474
LPARAM WINAPI PackDDElParam(UINT, UINT_PTR, UINT_PTR)
Definition: ddemisc.c:63
UINT_PTR WPARAM
Definition: windef.h:207
static const WCHAR TEST_DDE_SERVICE[]
Definition: dde.c:35
static HANDLE proc()
Definition: pdb.c:32
static void test_initialisation(void)
Definition: dde.c:1738
static ATOM server
Definition: dde.c:856
#define DDE_FNOTPROCESSED
Definition: ddeml.h:223
#define APPCLASS_STANDARD
Definition: ddeml.h:130
__u16 time
Definition: mkdosfs.c:366
INT cmd_type(LPTSTR)
Definition: type.c:34
BOOL WINAPI PeekMessageA(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT, _In_ UINT)
static void test_end_to_end_server(HANDLE hproc, HANDLE hthread, BOOL type_a)
Definition: dde.c:2686
#define argv
Definition: mplay32.c:18
char * LPSTR
Definition: xmlstorage.h:182
BOOL WINAPI DdeFreeDataHandle(HDDEDATA)
Definition: ddemisc.c:1461
static LRESULT WINAPI hook_dde_client_wndprocA(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
Definition: dde.c:1195
#define WM_DDE_REQUEST
Definition: dde.h:43
#define lstrlenW
Definition: compat.h:407
BOOL WINAPI DestroyWindow(_In_ HWND)
HDDEDATA WINAPI DdeClientTransaction(LPBYTE, DWORD, HCONV, HSZ, UINT, UINT, DWORD, LPDWORD)
Definition: ddeclient.c:1122
static WCHAR exec_cmdW[]
Definition: dde.c:39
#define DNS_REGISTER
Definition: ddeml.h:152
static LRESULT WINAPI dde_server_wndprocW(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
Definition: dde.c:1369
short cfFormat
Definition: dde.h:74
Definition: dde.h:50
LRESULT WINAPI DefWindowProcW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define DMLERR_NOTPROCESSED
Definition: ddeml.h:255
static const int nb_callbacks
Definition: dde.c:2399
LRESULT WINAPI CallWindowProcA(_In_ WNDPROC, _In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
struct _test_info info[]
Definition: SetCursorPos.c:19
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define sprintf(buf, format,...)
Definition: sprintf.c:55
SIZE_T NTAPI GlobalSize(HGLOBAL hMem)
Definition: heapmem.c:1090
ATOM WINAPI RegisterClassW(_In_ CONST WNDCLASSW *)
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
#define CREATE_SUSPENDED
Definition: winbase.h:178
unsigned char * LPBYTE
Definition: typedefs.h:52
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 void create_dde_window(HWND *hwnd, LPCSTR name, WNDPROC wndproc)
Definition: dde.c:71
static LRESULT WINAPI dde_msg_client_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
Definition: dde.c:859
#define LANG_JAPANESE
Definition: nls.h:76
static void test_PackDDElParam(void)
Definition: dde.c:2118
unsigned int BOOL
Definition: ntddk_ex.h:94
#define XTYP_POKE
Definition: ddeml.h:189
unsigned short fAck
Definition: dde.h:52
#define WM_DDE_TERMINATE
Definition: dde.h:38
#define WM_DDE_DATA
Definition: dde.h:42
static WNDPROC old_dde_client_wndproc
Definition: dde.c:42
static char test_cmd_a_to_a[]
Definition: dde.c:2391
static UINT WPARAM LPARAM lparam
Definition: combo.c:716
#define XTYP_XACT_COMPLETE
Definition: ddeml.h:188
#define XTYP_SHIFT
Definition: ddeml.h:198
#define DMLERR_NO_ERROR
Definition: ddeml.h:242
WNDPROC lpfnWndProc
Definition: winuser.h:3151
static PVOID ptr
Definition: dispmode.c:27
DWORD WINAPI DdeQueryStringA(DWORD, HSZ, LPSTR, DWORD, INT)
Definition: ddemisc.c:501
int codepage
Definition: win_iconv.c:156
static void test_DdeCreateStringHandleW(DWORD dde_inst, int codepage)
Definition: dde.c:1786
#define CW_USEDEFAULT
Definition: winuser.h:225
const WCHAR * str
BOOL WINAPI DdeUninitialize(DWORD)
Definition: ddemisc.c:1112
#define MAKELONG(a, b)
Definition: typedefs.h:248
smooth NULL
Definition: ftsmooth.c:416
HWND WINAPI GetDesktopWindow(void)
Definition: window.c:652
#define XTYP_WILDCONNECT
Definition: ddeml.h:194
BOOL WINAPI IsDBCSLeadByte(BYTE TestByte)
Definition: nls.c:2221
LPCWSTR lpszClassName
Definition: winuser.h:3159
LONG_PTR LPARAM
Definition: windef.h:208
unsigned short reserved
Definition: dde.h:52
const char * LPCSTR
Definition: xmlstorage.h:183
#define STARTF_USESHOWWINDOW
Definition: winbase.h:472
BOOL WINAPI IsWindowUnicode(_In_ HWND)
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
BYTE Value[1]
Definition: dde.h:75
static HGLOBAL execute_hglobal
Definition: dde.c:857
#define CF_TEXT
Definition: constants.h:396
GLuint GLfloat * val
Definition: glext.h:7180
#define XTYP_MONITOR
Definition: ddeml.h:195
Definition: dde.h:56
static DWORD dde_inst
Definition: iexplore.c:59
static void test_DdeCreateStringHandle(void)
Definition: dde.c:2047
static void test_msg_client(void)
Definition: dde.c:1065
#define XTYP_ADVREQ
Definition: ddeml.h:182
#define XTYP_CONNECT
Definition: ddeml.h:186
BOOL WINAPI DdeDisconnect(HCONV)
Definition: ddeclient.c:1363
GLsizeiptr size
Definition: glext.h:5919
#define GetProcessHeap()
Definition: compat.h:395
#define trace
Definition: atltest.h:70
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
BOOL WINAPI DdeFreeStringHandle(DWORD, HSZ)
Definition: ddemisc.c:631
#define XTYP_MASK
Definition: ddeml.h:197
#define APPCMD_CLIENTONLY
Definition: ddeml.h:122
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define XTYP_REGISTER
Definition: ddeml.h:190
ATOM WINAPI FindAtomW(LPCWSTR lpString)
Definition: atom.c:566
static void flush_events(void)
Definition: dde.c:55
static BOOL is_cjk(void)
Definition: dde.c:46
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:4742
#define MAX_PATH
Definition: compat.h:26
static void test_FreeDDElParam(void)
Definition: dde.c:2069
#define WINAPI
Definition: msvc.h:8
#define DDE_FACK
Definition: ddeml.h:216
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
static FILE * client
Definition: client.c:41
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
static WCHAR test_cmd_w_to_w[][32]
Definition: dde.c:2392
HGLOBAL NTAPI GlobalFree(HGLOBAL hMem)
Definition: heapmem.c:611
#define SetLastError(x)
Definition: compat.h:409
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
LPSTR WINAPI lstrcpyA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:100
int winetest_get_mainargs(char ***pargv)
static void test_end_to_end_client(BOOL type_a)
Definition: dde.c:2621
#define WAIT_TIMEOUT
Definition: dderror.h:14
DWORD WINAPI MsgWaitForMultipleObjects(_In_ DWORD nCount, _In_reads_opt_(nCount) CONST HANDLE *pHandles, _In_ BOOL fWaitAll, _In_ DWORD dwMilliseconds, _In_ DWORD dwWakeMask)
static void test_UnpackDDElParam(void)
Definition: dde.c:2278
#define WM_DDE_LAST
Definition: dde.h:46
int ret
static HWND create_dde_server(BOOL unicode)
Definition: dde.c:1514
#define WM_DDE_POKE
Definition: dde.h:44
LPVOID NTAPI GlobalLock(HGLOBAL hMem)
Definition: heapmem.c:755
#define todo_wine
Definition: test.h:154
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)
BOOL WINAPI FreeDDElParam(UINT, LPARAM)
Definition: ddemisc.c:147
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
ATOM WINAPI GlobalFindAtomA(LPCSTR lpString)
Definition: atom.c:464
#define SetWindowLongPtrA
Definition: winuser.h:5246
unsigned char BYTE
Definition: mem.h:68
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:821
#define err(...)
LRESULT WINAPI DefWindowProcA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
UINT WINAPI DdeQueryConvInfo(HCONV, DWORD, PCONVINFO)
Definition: ddemisc.c:2426
LPCSTR lpszClassName
Definition: winuser.h:3146
static void destroy_dde_window(HWND *hwnd, LPCSTR name)
Definition: dde.c:89
LPARAM WINAPI ReuseDDElParam(LPARAM, UINT, UINT, UINT_PTR, UINT_PTR)
Definition: ddemisc.c:171
#define GWLP_WNDPROC
Definition: treelist.c:66
#define broken(x)
Definition: _sntprintf.h:21
BOOL WINAPI UnpackDDElParam(UINT, LPARAM, PUINT_PTR, PUINT_PTR)
Definition: ddemisc.c:105
LRESULT(CALLBACK * WNDPROC)(HWND, UINT, WPARAM, LPARAM)
Definition: winuser.h:2880
#define DMLERR_INVALIDPARAMETER
Definition: ddeml.h:252
#define XTYP_DISCONNECT
Definition: ddeml.h:192
#define SW_SHOWNORMAL
Definition: winuser.h:764
#define CP_WINANSI
Definition: ddeml.h:32
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
static ATOM item
Definition: dde.c:856
static WCHAR exec_cmdAW[]
Definition: dde.c:38
HINSTANCE hInstance
Definition: winuser.h:3141
#define QS_ALLINPUT
Definition: winuser.h:874
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define ok(value,...)
Definition: atltest.h:57
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
#define CP_WINUNICODE
Definition: ddeml.h:33
#define WS_POPUP
Definition: pedump.c:616
DWORD WINAPI DdeGetData(HDDEDATA, LPBYTE, DWORD, DWORD)
Definition: ddemisc.c:1379
unsigned int UINT
Definition: ndis.h:50
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
HDDEDATA WINAPI DdeNameService(DWORD, HSZ, HSZ, UINT)
Definition: ddeserver.c:154
#define QID_SYNC
Definition: ddeml.h:40
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
unsigned short fBusy
Definition: dde.h:52
ATOM WINAPI GlobalAddAtomW(LPCWSTR lpString)
Definition: atom.c:444
static HGLOBAL create_execute(LPCSTR command)
Definition: dde.c:1050
#define MultiByteToWideChar
Definition: compat.h:100
static char exec_cmdA[]
Definition: dde.c:37
#define GMEM_DDESHARE
Definition: winbase.h:295
WNDPROC lpfnWndProc
Definition: winuser.h:3138
static void test_msg_server(HANDLE hproc, HANDLE hthread)
Definition: dde.c:256
HINSTANCE hInstance
Definition: winuser.h:3154
static LRESULT WINAPI hook_dde_client_wndprocW(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
Definition: dde.c:1214
#define WM_DDE_INITIATE
Definition: dde.h:37
#define msg(x)
Definition: auth_time.c:54
static void test_ddeml_client(void)
Definition: dde.c:283
BOOL WINAPI PostMessageW(_In_opt_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
Definition: name.c:36
GLuint res
Definition: glext.h:9613
#define LANG_CHINESE
Definition: nls.h:42
static void test_ddeml_server(HANDLE hproc)
Definition: dde.c:826
LRESULT WINAPI CallWindowProcW(_In_ WNDPROC, _In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
DWORD WINAPI ResumeThread(IN HANDLE hThread)
Definition: thread.c:566
#define WM_DDE_ACK
Definition: dde.h:41
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)
HSZ WINAPI DdeCreateStringHandleA(DWORD, LPCSTR, INT)
Definition: ddemisc.c:577
BOOL WINAPI DdeUnaccessData(HDDEDATA)
Definition: ddemisc.c:1447
#define HIWORD(l)
Definition: typedefs.h:246
static void test_service(void)
Definition: service.c:441
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:92
#define ULONG_PTR
Definition: config.h:101
#define LANG_KOREAN
Definition: nls.h:84
static void test_DdeCreateDataHandle(void)
Definition: dde.c:1867
LANGID WINAPI GetUserDefaultLangID(void)
Definition: lang.c:734
UINT op
Definition: effect.c:223
#define SetWindowLongPtrW
Definition: winuser.h:5247
BOOL WINAPI UnregisterClassA(_In_ LPCSTR, HINSTANCE)
UINT WINAPI GlobalGetAtomNameA(ATOM nAtom, LPSTR lpBuffer, int nSize)
Definition: atom.c:484
ATOM WINAPI FindAtomA(LPCSTR lpString)
Definition: atom.c:556
DWORD WINAPI DdeQueryStringW(DWORD, HSZ, LPWSTR, DWORD, INT)
Definition: ddemisc.c:525
#define PM_REMOVE
Definition: winuser.h:1182
#define WM_DDE_ADVISE
Definition: dde.h:39
HSZ WINAPI DdeCreateStringHandleW(DWORD, LPCWSTR, INT)
Definition: ddemisc.c:608
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
LONG_PTR LRESULT
Definition: windef.h:209
#define DMLERR_NO_CONV_ESTABLISHED
Definition: ddeml.h:256
#define INFINITE
Definition: serial.h:102
UINT WINAPI DdeInitializeW(LPDWORD, PFNCALLBACK, DWORD, DWORD)
Definition: ddemisc.c:1095
#define memset(x, y, z)
Definition: compat.h:39
#define HWND_BROADCAST
Definition: winuser.h:1190
static SERVICE_STATUS status
Definition: service.c:31
#define WM_DDE_EXECUTE
Definition: dde.h:45
#define win_skip
Definition: test.h:141
#define LOWORD(l)
Definition: pedump.c:82
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 DWORD server_pid
Definition: dde.c:588
static const DWORD default_timeout
Definition: dde.c:44
#define HeapFree(x, y, z)
Definition: compat.h:394
ATOM WINAPI RegisterClassA(_In_ CONST WNDCLASSA *)
#define GMEM_MOVEABLE
Definition: winbase.h:291
UINT WINAPI DdeInitializeA(LPDWORD, PFNCALLBACK, DWORD, DWORD)
Definition: ddemisc.c:1075
START_TEST(dde)
Definition: dde.c:2723
static HGLOBAL create_poke(void)
Definition: dde.c:1029
static LRESULT WINAPI dde_server_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
Definition: dde.c:95
static UINT WPARAM wparam
Definition: combo.c:716
#define XTYP_UNREGISTER
Definition: ddeml.h:193
#define PRIMARYLANGID(l)
Definition: nls.h:16
Definition: ps.c:97
GLuint const GLchar * name
Definition: glext.h:6031
unsigned short fReserved
Definition: dde.h:73