wined3d: Default to GLSL. This is safe because we now have proper ps2.0/vs2.0 detection.
[wine] / dlls / user32 / tests / dde.c
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 <assert.h>
23 #include <stdarg.h>
24 #include <stdio.h>
25
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winuser.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_cmdW[] = {'u','n','i','c','o','d','e',' ','d','d','e',' ','c','o','m','m','a','n','d',0};
39
40 static WNDPROC old_dde_client_wndproc;
41
42 static const DWORD default_timeout = 200;
43
44 static void flush_events(void)
45 {
46     MSG msg;
47     int diff = default_timeout;
48     DWORD time = GetTickCount() + diff;
49
50     while (diff > 0)
51     {
52         if (MsgWaitForMultipleObjects( 0, NULL, FALSE, min(10,diff), QS_ALLINPUT ) == WAIT_TIMEOUT) break;
53         while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage( &msg );
54         diff = time - GetTickCount();
55     }
56 }
57
58 static void create_dde_window(HWND *hwnd, LPCSTR name, WNDPROC wndproc)
59 {
60     WNDCLASSA wcA;
61
62     memset(&wcA, 0, sizeof(wcA));
63     wcA.lpfnWndProc = wndproc;
64     wcA.lpszClassName = name;
65     wcA.hInstance = GetModuleHandleA(0);
66     assert(RegisterClassA(&wcA));
67
68     *hwnd = CreateWindowExA(0, name, NULL, WS_POPUP,
69                             500, 500, CW_USEDEFAULT, CW_USEDEFAULT,
70                             GetDesktopWindow(), 0, GetModuleHandleA(0), NULL);
71     assert(*hwnd);
72 }
73
74 static LRESULT WINAPI dde_server_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
75 {
76     UINT_PTR lo, hi;
77     char str[MAX_PATH], *ptr;
78     HGLOBAL hglobal;
79     DDEDATA *data;
80     DDEPOKE *poke;
81     DWORD size;
82
83     static int msg_index = 0;
84     static HWND client = 0;
85     static BOOL executed = FALSE;
86
87     if (msg < WM_DDE_FIRST || msg > WM_DDE_LAST)
88         return DefWindowProcA(hwnd, msg, wparam, lparam);
89
90     msg_index++;
91
92     switch (msg)
93     {
94     case WM_DDE_INITIATE:
95     {
96         client = (HWND)wparam;
97         ok(msg_index == 1, "Expected 1, got %d\n", msg_index);
98
99         GlobalGetAtomNameA(LOWORD(lparam), str, MAX_PATH);
100         ok(!lstrcmpA(str, "TestDDEService"), "Expected TestDDEService, got %s\n", str);
101
102         GlobalGetAtomNameA(HIWORD(lparam), str, MAX_PATH);
103         ok(!lstrcmpA(str, "TestDDETopic"), "Expected TestDDETopic, got %s\n", str);
104
105         SendMessageA(client, WM_DDE_ACK, (WPARAM)hwnd, lparam);
106
107         break;
108     }
109
110     case WM_DDE_REQUEST:
111     {
112         ok((msg_index >= 2 && msg_index <= 4) ||
113            (msg_index >= 7 && msg_index <= 8),
114            "Expected 2, 3, 4, 7 or 8, got %d\n", msg_index);
115         ok(wparam == (WPARAM)client, "Expected client hwnd, got %08lx\n", wparam);
116         ok(LOWORD(lparam) == CF_TEXT, "Expected CF_TEXT, got %d\n", LOWORD(lparam));
117
118         GlobalGetAtomNameA(HIWORD(lparam), str, MAX_PATH);
119         if (msg_index < 8)
120             ok(!lstrcmpA(str, "request"), "Expected request, got %s\n", str);
121         else
122             ok(!lstrcmpA(str, "executed"), "Expected executed, got %s\n", str);
123
124         if (msg_index == 8)
125         {
126             if (executed)
127                 lstrcpyA(str, "command executed\r\n");
128             else
129                 lstrcpyA(str, "command not executed\r\n");
130         }
131         else
132             lstrcpyA(str, "requested data\r\n");
133
134         size = sizeof(DDEDATA) + lstrlenA(str) + 1;
135         hglobal = GlobalAlloc(GMEM_MOVEABLE, size);
136         ok(hglobal != NULL, "Expected non-NULL hglobal\n");
137
138         data = GlobalLock(hglobal);
139         ZeroMemory(data, size);
140
141         /* setting fResponse to FALSE at this point destroys
142          * the internal messaging state of native dde
143          */
144         data->fResponse = TRUE;
145
146         if (msg_index == 2)
147             data->fRelease = TRUE;
148         else if (msg_index == 3)
149             data->fAckReq = TRUE;
150
151         data->cfFormat = CF_TEXT;
152         lstrcpyA((LPSTR)data->Value, str);
153         GlobalUnlock(hglobal);
154
155         lparam = PackDDElParam(WM_DDE_ACK, (UINT)hglobal, HIWORD(lparam));
156         PostMessageA(client, WM_DDE_DATA, (WPARAM)hwnd, lparam);
157
158         break;
159     }
160
161     case WM_DDE_POKE:
162     {
163         ok(msg_index == 5 || msg_index == 6, "Expected 5 or 6, got %d\n", msg_index);
164         ok(wparam == (WPARAM)client, "Expected client hwnd, got %08lx\n", wparam);
165
166         UnpackDDElParam(WM_DDE_POKE, lparam, &lo, &hi);
167
168         GlobalGetAtomNameA(hi, str, MAX_PATH);
169         ok(!lstrcmpA(str, "poker"), "Expected poker, got %s\n", str);
170
171         poke = GlobalLock((HGLOBAL)lo);
172         ok(poke != NULL, "Expected non-NULL poke\n");
173         ok(poke->fReserved == 0, "Expected 0, got %d\n", poke->fReserved);
174         ok(poke->unused == 0, "Expected 0, got %d\n", poke->unused);
175         ok(poke->fRelease == TRUE, "Expected TRUE, got %d\n", poke->fRelease);
176         ok(poke->cfFormat == CF_TEXT, "Expected CF_TEXT, got %d\n", poke->cfFormat);
177
178         if (msg_index == 5)
179             ok(lstrcmpA((LPSTR)poke->Value, "poke data\r\n"),
180                "Expected 'poke data\\r\\n', got %s\n", poke->Value);
181         else
182             ok(!lstrcmpA((LPSTR)poke->Value, "poke data\r\n"),
183                "Expected 'poke data\\r\\n', got %s\n", poke->Value);
184
185         GlobalUnlock((HGLOBAL)lo);
186
187         lparam = PackDDElParam(WM_DDE_ACK, DDE_FACK, hi);
188         PostMessageA(client, WM_DDE_ACK, (WPARAM)hwnd, lparam);
189
190         break;
191     }
192
193     case WM_DDE_EXECUTE:
194     {
195         ok(msg_index == 7, "Expected 7, got %d\n", msg_index);
196         ok(wparam == (WPARAM)client, "Expected client hwnd, got %08lx\n", wparam);
197
198         ptr = GlobalLock((HGLOBAL)lparam);
199         ok(!lstrcmpA(ptr, "[Command(Var)]"), "Expected [Command(Var)], got %s\n", ptr);
200         GlobalUnlock((HGLOBAL)lparam);
201
202         executed = TRUE;
203
204         lparam = ReuseDDElParam(lparam, WM_DDE_EXECUTE, WM_DDE_ACK, DDE_FACK, HIWORD(lparam));
205         PostMessageA(client, WM_DDE_ACK, (WPARAM)hwnd, lparam);
206
207         break;
208     }
209
210     case WM_DDE_TERMINATE:
211     {
212         ok(msg_index == 9, "Expected 9, got %d\n", msg_index);
213         ok(wparam == (WPARAM)client, "Expected client hwnd, got %08lx\n", wparam);
214         ok(lparam == 0, "Expected 0, got %08lx\n", lparam);
215
216         PostMessageA(client, WM_DDE_TERMINATE, (WPARAM)hwnd, 0);
217
218         break;
219     }
220
221     default:
222         ok(FALSE, "Unhandled msg: %08x\n", msg);
223     }
224
225     return DefWindowProcA(hwnd, msg, wparam, lparam);
226 }
227
228 static void test_msg_server(HANDLE hproc)
229 {
230     MSG msg;
231     HWND hwnd;
232     DWORD res;
233
234     create_dde_window(&hwnd, "dde_server", dde_server_wndproc);
235
236     while (MsgWaitForMultipleObjects( 1, &hproc, FALSE, INFINITE, QS_ALLINPUT ) != 0)
237     {
238         while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
239     }
240
241     DestroyWindow(hwnd);
242     GetExitCodeProcess( hproc, &res );
243     ok( !res, "client failed with %u error(s)\n", res );
244 }
245
246 static HDDEDATA CALLBACK client_ddeml_callback(UINT uType, UINT uFmt, HCONV hconv,
247                                                HSZ hsz1, HSZ hsz2, HDDEDATA hdata,
248                                                ULONG_PTR dwData1, ULONG_PTR dwData2)
249 {
250     ok(FALSE, "Unhandled msg: %08x\n", uType);
251     return 0;
252 }
253
254 static void test_ddeml_client(void)
255 {
256     UINT ret;
257     LPSTR str;
258     DWORD size, res;
259     HDDEDATA hdata, op;
260     HSZ server, topic, item;
261     DWORD client_pid;
262     HCONV conversation;
263
264     client_pid = 0;
265     ret = DdeInitializeA(&client_pid, client_ddeml_callback, APPCMD_CLIENTONLY, 0);
266     ok(ret == DMLERR_NO_ERROR, "Expected DMLERR_NO_ERROR, got %d\n", ret);
267
268     /* FIXME: make these atoms global and check them in the server */
269
270     server = DdeCreateStringHandleA(client_pid, "TestDDEService", CP_WINANSI);
271     topic = DdeCreateStringHandleA(client_pid, "TestDDETopic", CP_WINANSI);
272
273     DdeGetLastError(client_pid);
274     conversation = DdeConnect(client_pid, server, topic, NULL);
275     ok(conversation != NULL, "Expected non-NULL conversation\n");
276     ret = DdeGetLastError(client_pid);
277     ok(ret == DMLERR_NO_ERROR, "Expected DMLERR_NO_ERROR, got %d\n", ret);
278
279     DdeFreeStringHandle(client_pid, server);
280
281     item = DdeCreateStringHandleA(client_pid, "request", CP_WINANSI);
282
283     /* XTYP_REQUEST, fRelease = TRUE */
284     res = 0xdeadbeef;
285     DdeGetLastError(client_pid);
286     hdata = DdeClientTransaction(NULL, 0, conversation, item, CF_TEXT, XTYP_REQUEST, default_timeout, &res);
287     ret = DdeGetLastError(client_pid);
288     ok(hdata != NULL, "Expected non-NULL hdata, got %p\n", hdata);
289     ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret);
290     todo_wine
291     {
292         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %08x\n", res);
293     }
294
295     str = (LPSTR)DdeAccessData(hdata, &size);
296     ok(!lstrcmpA(str, "requested data\r\n"), "Expected 'requested data\\r\\n', got %s\n", str);
297     ok(size == 19, "Expected 19, got %d\n", size);
298
299     ret = DdeUnaccessData(hdata);
300     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
301
302     /* XTYP_REQUEST, fAckReq = TRUE */
303     res = 0xdeadbeef;
304     DdeGetLastError(client_pid);
305     hdata = DdeClientTransaction(NULL, 0, conversation, item, CF_TEXT, XTYP_REQUEST, default_timeout, &res);
306     ret = DdeGetLastError(client_pid);
307     ok(hdata != NULL, "Expected non-NULL hdata\n");
308     todo_wine
309     {
310         ok(res == DDE_FNOTPROCESSED, "Expected DDE_FNOTPROCESSED, got %d\n", res);
311         ok(ret == DMLERR_MEMORY_ERROR, "Expected DMLERR_MEMORY_ERROR, got %d\n", ret);
312     }
313
314     str = (LPSTR)DdeAccessData(hdata, &size);
315     ok(!lstrcmpA(str, "requested data\r\n"), "Expected 'requested data\\r\\n', got %s\n", str);
316     ok(size == 19, "Expected 19, got %d\n", size);
317
318     ret = DdeUnaccessData(hdata);
319     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
320
321     /* XTYP_REQUEST, all params normal */
322     res = 0xdeadbeef;
323     DdeGetLastError(client_pid);
324     hdata = DdeClientTransaction(NULL, 0, conversation, item, CF_TEXT, XTYP_REQUEST, default_timeout, &res);
325     ret = DdeGetLastError(client_pid);
326     ok(hdata != NULL, "Expected non-NULL hdata\n");
327     ok(ret == DMLERR_NO_ERROR, "Expected DMLERR_NO_ERROR, got %d\n", ret);
328     todo_wine
329     {
330         ok(res == DDE_FNOTPROCESSED, "Expected DDE_FNOTPROCESSED, got %d\n", res);
331     }
332
333     str = (LPSTR)DdeAccessData(hdata, &size);
334     ok(!lstrcmpA(str, "requested data\r\n"), "Expected 'requested data\\r\\n', got %s\n", str);
335     ok(size == 19, "Expected 19, got %d\n", size);
336
337     ret = DdeUnaccessData(hdata);
338     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
339
340     /* XTYP_REQUEST, no item */
341     res = 0xdeadbeef;
342     DdeGetLastError(client_pid);
343     hdata = DdeClientTransaction(NULL, 0, conversation, 0, CF_TEXT, XTYP_REQUEST, default_timeout, &res);
344     ret = DdeGetLastError(client_pid);
345     ok(hdata == NULL, "Expected NULL hdata, got %p\n", hdata);
346     ok(res == 0xdeadbeef, "Expected 0xdeadbeef, got %08x\n", res);
347     ok(ret == DMLERR_INVALIDPARAMETER, "Expected DMLERR_INVALIDPARAMETER, got %d\n", ret);
348
349     DdeFreeStringHandle(client_pid, item);
350
351     item = DdeCreateStringHandleA(client_pid, "poker", CP_WINANSI);
352
353     lstrcpyA(str, "poke data\r\n");
354     hdata = DdeCreateDataHandle(client_pid, (LPBYTE)str, lstrlenA(str) + 1,
355                                 0, item, CF_TEXT, 0);
356     ok(hdata != NULL, "Expected non-NULL hdata\n");
357
358     /* XTYP_POKE, no item */
359     res = 0xdeadbeef;
360     DdeGetLastError(client_pid);
361     op = DdeClientTransaction((LPBYTE)hdata, -1, conversation, 0, CF_TEXT, XTYP_POKE, default_timeout, &res);
362     ret = DdeGetLastError(client_pid);
363     ok(op == NULL, "Expected NULL, got %p\n", op);
364     ok(res == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", res);
365     ok(ret == DMLERR_INVALIDPARAMETER, "Expected DMLERR_INVALIDPARAMETER, got %d\n", ret);
366
367     /* XTYP_POKE, no data */
368     res = 0xdeadbeef;
369     DdeGetLastError(client_pid);
370     op = DdeClientTransaction(NULL, 0, conversation, 0, CF_TEXT, XTYP_POKE, default_timeout, &res);
371     ret = DdeGetLastError(client_pid);
372     ok(op == NULL, "Expected NULL, got %p\n", op);
373     ok(res == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", res);
374     ok(ret == DMLERR_INVALIDPARAMETER, "Expected DMLERR_INVALIDPARAMETER, got %d\n", ret);
375
376     /* XTYP_POKE, wrong size */
377     res = 0xdeadbeef;
378     DdeGetLastError(client_pid);
379     op = DdeClientTransaction((LPBYTE)hdata, 0, conversation, item, CF_TEXT, XTYP_POKE, default_timeout, &res);
380     ret = DdeGetLastError(client_pid);
381     ok(op == (HDDEDATA)TRUE, "Expected TRUE, got %p\n", op);
382     ok(res == DDE_FACK, "Expected DDE_FACK, got %d\n", res);
383     ok(ret == DMLERR_NO_ERROR, "Expected DMLERR_NO_ERROR, got %d\n", ret);
384
385     /* XTYP_POKE, correct params */
386     res = 0xdeadbeef;
387     DdeGetLastError(client_pid);
388     op = DdeClientTransaction((LPBYTE)hdata, -1, conversation, item, CF_TEXT, XTYP_POKE, default_timeout, &res);
389     ret = DdeGetLastError(client_pid);
390     ok(op == (HDDEDATA)TRUE, "Expected TRUE, got %p\n", op);
391     ok(res == DDE_FACK, "Expected DDE_FACK, got %d\n", res);
392     ok(ret == DMLERR_NO_ERROR, "Expected DMLERR_NO_ERROR, got %d\n", ret);
393
394     DdeFreeDataHandle(hdata);
395
396     lstrcpyA(str, "[Command(Var)]");
397     hdata = DdeCreateDataHandle(client_pid, (LPBYTE)str, lstrlenA(str) + 1,
398                                 0, NULL, CF_TEXT, 0);
399     ok(hdata != NULL, "Expected non-NULL hdata\n");
400
401     /* XTYP_EXECUTE, correct params */
402     res = 0xdeadbeef;
403     DdeGetLastError(client_pid);
404     op = DdeClientTransaction((LPBYTE)hdata, -1, conversation, NULL, 0, XTYP_EXECUTE, default_timeout, &res);
405     ret = DdeGetLastError(client_pid);
406     ok(ret == DMLERR_NO_ERROR, "Expected DMLERR_NO_ERROR, got %d\n", ret);
407     todo_wine
408     {
409         ok(op == (HDDEDATA)TRUE, "Expected TRUE, got %p\n", op);
410         ok(res == DDE_FACK, "Expected DDE_FACK, got %d\n", res);
411     }
412
413     /* XTYP_EXECUTE, no data */
414     res = 0xdeadbeef;
415     DdeGetLastError(client_pid);
416     op = DdeClientTransaction(NULL, 0, conversation, NULL, 0, XTYP_EXECUTE, default_timeout, &res);
417     ret = DdeGetLastError(client_pid);
418     ok(op == NULL, "Expected NULL, got %p\n", op);
419     ok(res == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", res);
420     todo_wine
421     {
422         ok(ret == DMLERR_MEMORY_ERROR, "Expected DMLERR_MEMORY_ERROR, got %d\n", ret);
423     }
424
425     /* XTYP_EXECUTE, no data, -1 size */
426     res = 0xdeadbeef;
427     DdeGetLastError(client_pid);
428     op = DdeClientTransaction(NULL, -1, conversation, NULL, 0, XTYP_EXECUTE, default_timeout, &res);
429     ret = DdeGetLastError(client_pid);
430     ok(op == NULL, "Expected NULL, got %p\n", op);
431     ok(res == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", res);
432     todo_wine
433     {
434         ok(ret == DMLERR_INVALIDPARAMETER, "Expected DMLERR_INVALIDPARAMETER, got %d\n", ret);
435     }
436
437     DdeFreeStringHandle(client_pid, topic);
438     DdeFreeDataHandle(hdata);
439
440     item = DdeCreateStringHandleA(client_pid, "executed", CP_WINANSI);
441
442     /* verify the execute */
443     res = 0xdeadbeef;
444     DdeGetLastError(client_pid);
445     hdata = DdeClientTransaction(NULL, 0, conversation, item, CF_TEXT, XTYP_REQUEST, default_timeout, &res);
446     ret = DdeGetLastError(client_pid);
447     ok(hdata != NULL, "Expected non-NULL hdata\n");
448     ok(ret == DMLERR_NO_ERROR, "Expected DMLERR_NO_ERROR, got %d\n", ret);
449     todo_wine
450     {
451         ok(res == DDE_FNOTPROCESSED, "Expected DDE_FNOTPROCESSED, got %d\n", res);
452     }
453
454     str = (LPSTR)DdeAccessData(hdata, &size);
455     ok(!lstrcmpA(str, "command executed\r\n"), "Expected 'command executed\\r\\n', got %s\n", str);
456     ok(size == 21, "Expected 21, got %d\n", size);
457
458     ret = DdeUnaccessData(hdata);
459     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
460
461     /* invalid transactions */
462
463     res = 0xdeadbeef;
464     DdeGetLastError(client_pid);
465     op = DdeClientTransaction(NULL, 0, conversation, item, CF_TEXT, XTYP_ADVREQ, default_timeout, &res);
466     ret = DdeGetLastError(client_pid);
467     ok(op == NULL, "Expected NULL, got %p\n", op);
468     ok(res == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", res);
469     ok(ret == DMLERR_INVALIDPARAMETER, "Expected DMLERR_INVALIDPARAMETER, got %d\n", ret);
470
471     res = 0xdeadbeef;
472     DdeGetLastError(client_pid);
473     op = DdeClientTransaction(NULL, 0, conversation, item, CF_TEXT, XTYP_CONNECT, default_timeout, &res);
474     ret = DdeGetLastError(client_pid);
475     ok(op == NULL, "Expected NULL, got %p\n", op);
476     ok(res == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", res);
477     ok(ret == DMLERR_INVALIDPARAMETER, "Expected DMLERR_INVALIDPARAMETER, got %d\n", ret);
478
479     res = 0xdeadbeef;
480     DdeGetLastError(client_pid);
481     op = DdeClientTransaction(NULL, 0, conversation, item, CF_TEXT, XTYP_CONNECT_CONFIRM, default_timeout, &res);
482     ret = DdeGetLastError(client_pid);
483     ok(op == NULL, "Expected NULL, got %p\n", op);
484     ok(res == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", res);
485     ok(ret == DMLERR_INVALIDPARAMETER, "Expected DMLERR_INVALIDPARAMETER, got %d\n", ret);
486
487     res = 0xdeadbeef;
488     DdeGetLastError(client_pid);
489     op = DdeClientTransaction(NULL, 0, conversation, item, CF_TEXT, XTYP_DISCONNECT, default_timeout, &res);
490     ret = DdeGetLastError(client_pid);
491     ok(op == NULL, "Expected NULL, got %p\n", op);
492     ok(res == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", res);
493     ok(ret == DMLERR_INVALIDPARAMETER, "Expected DMLERR_INVALIDPARAMETER, got %d\n", ret);
494
495     res = 0xdeadbeef;
496     DdeGetLastError(client_pid);
497     op = DdeClientTransaction(NULL, 0, conversation, item, CF_TEXT, XTYP_ERROR, default_timeout, &res);
498     ret = DdeGetLastError(client_pid);
499     ok(op == NULL, "Expected NULL, got %p\n", op);
500     ok(res == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", res);
501     ok(ret == DMLERR_INVALIDPARAMETER, "Expected DMLERR_INVALIDPARAMETER, got %d\n", ret);
502
503     res = 0xdeadbeef;
504     DdeGetLastError(client_pid);
505     op = DdeClientTransaction(NULL, 0, conversation, item, CF_TEXT, XTYP_MONITOR, default_timeout, &res);
506     ret = DdeGetLastError(client_pid);
507     ok(op == NULL, "Expected NULL, got %p\n", op);
508     ok(res == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", res);
509     ok(ret == DMLERR_INVALIDPARAMETER, "Expected DMLERR_INVALIDPARAMETER, got %d\n", ret);
510
511     res = 0xdeadbeef;
512     DdeGetLastError(client_pid);
513     op = DdeClientTransaction(NULL, 0, conversation, item, CF_TEXT, XTYP_REGISTER, default_timeout, &res);
514     ret = DdeGetLastError(client_pid);
515     ok(op == NULL, "Expected NULL, got %p\n", op);
516     ok(res == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", res);
517     ok(ret == DMLERR_INVALIDPARAMETER, "Expected DMLERR_INVALIDPARAMETER, got %d\n", ret);
518
519     res = 0xdeadbeef;
520     DdeGetLastError(client_pid);
521     op = DdeClientTransaction(NULL, 0, conversation, item, CF_TEXT, XTYP_UNREGISTER, default_timeout, &res);
522     ret = DdeGetLastError(client_pid);
523     ok(op == NULL, "Expected NULL, got %p\n", op);
524     ok(res == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", res);
525     ok(ret == DMLERR_INVALIDPARAMETER, "Expected DMLERR_INVALIDPARAMETER, got %d\n", ret);
526
527     res = 0xdeadbeef;
528     DdeGetLastError(client_pid);
529     op = DdeClientTransaction(NULL, 0, conversation, item, CF_TEXT, XTYP_WILDCONNECT, default_timeout, &res);
530     ret = DdeGetLastError(client_pid);
531     ok(op == NULL, "Expected NULL, got %p\n", op);
532     ok(res == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", res);
533     ok(ret == DMLERR_INVALIDPARAMETER, "Expected DMLERR_INVALIDPARAMETER, got %d\n", ret);
534
535     res = 0xdeadbeef;
536     DdeGetLastError(client_pid);
537     op = DdeClientTransaction(NULL, 0, conversation, item, CF_TEXT, XTYP_XACT_COMPLETE, default_timeout, &res);
538     ret = DdeGetLastError(client_pid);
539     ok(op == NULL, "Expected NULL, got %p\n", op);
540     ok(res == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", res);
541     ok(ret == DMLERR_INVALIDPARAMETER, "Expected DMLERR_INVALIDPARAMETER, got %d\n", ret);
542
543     DdeFreeStringHandle(client_pid, item);
544
545     ret = DdeDisconnect(conversation);
546     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
547
548     ret = DdeUninitialize(client_pid);
549     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
550 }
551
552 static DWORD server_pid;
553
554 static HDDEDATA CALLBACK server_ddeml_callback(UINT uType, UINT uFmt, HCONV hconv,
555                                                HSZ hsz1, HSZ hsz2, HDDEDATA hdata,
556                                                ULONG_PTR dwData1, ULONG_PTR dwData2)
557 {
558     char str[MAX_PATH], *ptr;
559     HDDEDATA ret;
560     DWORD size;
561
562     static int msg_index = 0;
563     static HCONV conversation = 0;
564
565     msg_index++;
566
567     switch (uType)
568     {
569     case XTYP_REGISTER:
570     {
571         ok(msg_index == 1, "Expected 1, got %d\n", msg_index);
572         ok(uFmt == 0, "Expected 0, got %d\n", uFmt);
573         ok(hconv == 0, "Expected 0, got %p\n", hconv);
574         ok(hdata == 0, "Expected 0, got %p\n", hdata);
575         ok(dwData1 == 0, "Expected 0, got %08lx\n", dwData1);
576         ok(dwData2 == 0, "Expected 0, got %08lx\n", dwData2);
577
578         size = DdeQueryStringA(server_pid, hsz1, str, MAX_PATH, CP_WINANSI);
579         ok(!lstrcmpA(str, "TestDDEServer"), "Expected TestDDEServer, got %s\n", str);
580         ok(size == 13, "Expected 13, got %d\n", size);
581
582         size = DdeQueryStringA(server_pid, hsz2, str, MAX_PATH, CP_WINANSI);
583         ok(!strncmp(str, "TestDDEServer(", 14), "Expected TestDDEServer(, got %s\n", str);
584         ok(str[size - 1] == ')', "Expected ')', got %c\n", str[size - 1]);
585         ok(size == 25, "Expected 25, got %d\n", size);
586
587         return (HDDEDATA)TRUE;
588     }
589
590     case XTYP_CONNECT:
591     {
592         ok(msg_index == 2, "Expected 2, got %d\n", msg_index);
593         ok(uFmt == 0, "Expected 0, got %d\n", uFmt);
594         ok(hconv == 0, "Expected 0, got %p\n", hconv);
595         ok(hdata == 0, "Expected 0, got %p\n", hdata);
596         ok(dwData1 == 0, "Expected 0, got %08lx\n", dwData1);
597         ok(dwData2 == FALSE, "Expected FALSE, got %08lx\n", dwData2);
598
599         size = DdeQueryStringA(server_pid, hsz1, str, MAX_PATH, CP_WINANSI);
600         ok(!lstrcmpA(str, "TestDDETopic"), "Expected TestDDETopic, got %s\n", str);
601         ok(size == 12, "Expected 12, got %d\n", size);
602
603         size = DdeQueryStringA(server_pid, hsz2, str, MAX_PATH, CP_WINANSI);
604         ok(!lstrcmpA(str, "TestDDEServer"), "Expected TestDDEServer, got %s\n", str);
605         ok(size == 13, "Expected 13, got %d\n", size);
606
607         return (HDDEDATA)TRUE;
608     }
609
610     case XTYP_CONNECT_CONFIRM:
611     {
612         conversation = hconv;
613
614         ok(msg_index == 3, "Expected 3, got %d\n", msg_index);
615         ok(uFmt == 0, "Expected 0, got %d\n", uFmt);
616         ok(hconv != NULL, "Expected non-NULL hconv\n");
617         ok(hdata == 0, "Expected 0, got %p\n", hdata);
618         ok(dwData1 == 0, "Expected 0, got %08lx\n", dwData1);
619         ok(dwData2 == FALSE, "Expected FALSE, got %08lx\n", dwData2);
620
621         size = DdeQueryStringA(server_pid, hsz1, str, MAX_PATH, CP_WINANSI);
622         ok(!lstrcmpA(str, "TestDDETopic"), "Expected TestDDETopic, got %s\n", str);
623         ok(size == 12, "Expected 12, got %d\n", size);
624
625         size = DdeQueryStringA(server_pid, hsz2, str, MAX_PATH, CP_WINANSI);
626         ok(!lstrcmpA(str, "TestDDEServer"), "Expected TestDDEServer, got %s\n", str);
627         ok(size == 13, "Expected 13, got %d\n", size);
628
629         return (HDDEDATA)TRUE;
630     }
631
632     case XTYP_REQUEST:
633     {
634         ok(msg_index == 4 || msg_index == 5 || msg_index == 6,
635            "Expected 4, 5 or 6, got %d\n", msg_index);
636         ok(hconv == conversation, "Expected conversation handle, got %p\n", hconv);
637         ok(hdata == 0, "Expected 0, got %p\n", hdata);
638         ok(dwData1 == 0, "Expected 0, got %08lx\n", dwData1);
639         ok(dwData2 == 0, "Expected 0, got %08lx\n", dwData2);
640
641         if (msg_index == 4)
642             ok(uFmt == 0xbeef, "Expected 0xbeef, got %08x\n", uFmt);
643         else
644             ok(uFmt == CF_TEXT, "Expected CF_TEXT, got %08x\n", uFmt);
645
646         size = DdeQueryStringA(server_pid, hsz1, str, MAX_PATH, CP_WINANSI);
647         ok(!lstrcmpA(str, "TestDDETopic"), "Expected TestDDETopic, got %s\n", str);
648         ok(size == 12, "Expected 12, got %d\n", size);
649
650         size = DdeQueryStringA(server_pid, hsz2, str, MAX_PATH, CP_WINANSI);
651
652         if (msg_index == 5)
653         {
654             todo_wine
655             {
656                 ok(!lstrcmpA(str, ""), "Expected empty string, got %s\n", str);
657                 ok(size == 1, "Expected 1, got %d\n", size);
658             }
659         }
660         else if (msg_index == 6)
661         {
662             ok(!lstrcmpA(str, "request"), "Expected request, got %s\n", str);
663             ok(size == 7, "Expected 7, got %d\n", size);
664         }
665
666         if (msg_index == 6)
667         {
668             lstrcpyA(str, "requested data\r\n");
669             return DdeCreateDataHandle(server_pid, (LPBYTE)str, lstrlenA(str) + 1,
670                                         0, hsz2, CF_TEXT, 0);
671         }
672
673         return NULL;
674     }
675
676     case XTYP_POKE:
677     {
678         ok(msg_index == 7 || msg_index == 8, "Expected 7 or 8, got %d\n", msg_index);
679         ok(uFmt == CF_TEXT, "Expected CF_TEXT, got %d\n", uFmt);
680         ok(hconv == conversation, "Expected conversation handle, got %p\n", hconv);
681         ok(dwData1 == 0, "Expected 0, got %08lx\n", dwData1);
682         ok(dwData2 == 0, "Expected 0, got %08lx\n", dwData2);
683
684         size = DdeQueryStringA(server_pid, hsz1, str, MAX_PATH, CP_WINANSI);
685         ok(!lstrcmpA(str, "TestDDETopic"), "Expected TestDDETopic, got %s\n", str);
686         ok(size == 12, "Expected 12, got %d\n", size);
687
688         ptr = (LPSTR)DdeAccessData(hdata, &size);
689         ok(!lstrcmpA(ptr, "poke data\r\n"), "Expected 'poke data\\r\\n', got %s\n", ptr);
690         todo_wine
691         {
692             ok(size == 14, "Expected 14, got %d\n", size);
693         }
694         DdeUnaccessData(hdata);
695
696         size = DdeQueryStringA(server_pid, hsz2, str, MAX_PATH, CP_WINANSI);
697         if (msg_index == 7)
698         {
699             todo_wine
700             {
701                 ok(!lstrcmpA(str, ""), "Expected empty string, got %s\n", str);
702                 ok(size == 1, "Expected 1, got %d\n", size);
703             }
704         }
705         else
706         {
707             ok(!lstrcmpA(str, "poke"), "Expected poke, got %s\n", str);
708             ok(size == 4, "Expected 4, got %d\n", size);
709         }
710
711         return (HDDEDATA)DDE_FACK;
712     }
713
714     case XTYP_EXECUTE:
715     {
716         ok(msg_index == 9 || msg_index == 10, "Expected 9 or 10, got %d\n", msg_index);
717         ok(uFmt == 0, "Expected 0, got %d\n", uFmt);
718         ok(hconv == conversation, "Expected conversation handle, got %p\n", hconv);
719         ok(dwData1 == 0, "Expected 0, got %08lx\n", dwData1);
720         ok(dwData2 == 0, "Expected 0, got %08lx\n", dwData2);
721         ok(hsz2 == 0, "Expected 0, got %p\n", hsz2);
722
723         size = DdeQueryStringA(server_pid, hsz1, str, MAX_PATH, CP_WINANSI);
724         ok(!lstrcmpA(str, "TestDDETopic"), "Expected TestDDETopic, got %s\n", str);
725         ok(size == 12, "Expected 12, got %d\n", size);
726
727         ptr = (LPSTR)DdeAccessData(hdata, &size);
728
729         if (msg_index == 9)
730         {
731             ok(!lstrcmpA(ptr, "[Command(Var)]"), "Expected '[Command(Var)]', got %s\n", ptr);
732             ok(size == 15, "Expected 15, got %d\n", size);
733             ret = (HDDEDATA)DDE_FACK;
734         }
735         else
736         {
737             ok(!lstrcmpA(ptr, "[BadCommand(Var)]"), "Expected '[BadCommand(Var)]', got %s\n", ptr);
738             ok(size == 18, "Expected 18, got %d\n", size);
739             ret = (HDDEDATA)DDE_FNOTPROCESSED;
740         }
741
742         DdeUnaccessData(hdata);
743
744         return ret;
745     }
746
747     case XTYP_DISCONNECT:
748     {
749         ok(msg_index == 11, "Expected 11, got %d\n", msg_index);
750         ok(uFmt == 0, "Expected 0, got %d\n", uFmt);
751         ok(hconv == conversation, "Expected conversation handle, got %p\n", hconv);
752         ok(dwData1 == 0, "Expected 0, got %08lx\n", dwData1);
753         ok(dwData2 == 0, "Expected 0, got %08lx\n", dwData2);
754         ok(hsz1 == 0, "Expected 0, got %p\n", hsz2);
755         ok(hsz2 == 0, "Expected 0, got %p\n", hsz2);
756
757         return 0;
758     }
759
760     default:
761         ok(FALSE, "Unhandled msg: %08x\n", uType);
762     }
763
764     return 0;
765 }
766
767 static void test_ddeml_server(HANDLE hproc)
768 {
769     MSG msg;
770     UINT res;
771     BOOL ret;
772     HSZ server;
773     HDDEDATA hdata;
774
775     /* set up DDE server */
776     server_pid = 0;
777     res = DdeInitialize(&server_pid, server_ddeml_callback, APPCLASS_STANDARD, 0);
778     ok(res == DMLERR_NO_ERROR, "Expected DMLERR_NO_ERROR, got %d\n", res);
779
780     server = DdeCreateStringHandle(server_pid, "TestDDEServer", CP_WINANSI);
781     ok(server != NULL, "Expected non-NULL string handle\n");
782
783     hdata = DdeNameService(server_pid, server, 0, DNS_REGISTER);
784     ok(hdata == (HDDEDATA)TRUE, "Expected TRUE, got %p\n", hdata);
785
786     while (MsgWaitForMultipleObjects( 1, &hproc, FALSE, INFINITE, QS_ALLINPUT ) != 0)
787     {
788         while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
789     }
790     ret = DdeUninitialize(server_pid);
791     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
792     GetExitCodeProcess( hproc, &res );
793     ok( !res, "client failed with %u error(s)\n", res );
794 }
795
796 static HWND client_hwnd, server_hwnd;
797 static ATOM server, topic, item;
798 static HGLOBAL execute_hglobal;
799
800 static LRESULT WINAPI dde_msg_client_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
801 {
802     char str[MAX_PATH];
803     UINT_PTR lo, hi;
804     DDEDATA *data;
805     DDEACK *ack;
806     DWORD size;
807     LPSTR ptr;
808
809     static int msg_index = 0;
810
811     if (msg < WM_DDE_FIRST || msg > WM_DDE_LAST)
812         return DefWindowProcA(hwnd, msg, wparam, lparam);
813
814     msg_index++;
815
816     switch (msg)
817     {
818     case WM_DDE_INITIATE:
819     {
820         ok(msg_index == 1, "Expected 1, got %d\n", msg_index);
821         ok(wparam == (WPARAM)client_hwnd, "Expected client hwnd, got %08lx\n", wparam);
822
823         size = GlobalGetAtomNameA(LOWORD(lparam), str, MAX_PATH);
824         ok(LOWORD(lparam) == server, "Expected server atom, got %08x\n", LOWORD(lparam));
825         ok(!lstrcmpA(str, "TestDDEServer"), "Expected TestDDEServer, got %s\n", str);
826         ok(size == 13, "Expected 13, got %d\n", size);
827
828         size = GlobalGetAtomNameA(HIWORD(lparam), str, MAX_PATH);
829         ok(HIWORD(lparam) == topic, "Expected topic atom, got %08x\n", HIWORD(lparam));
830         ok(!lstrcmpA(str, "TestDDETopic"), "Expected TestDDETopic, got %s\n", str);
831         ok(size == 12, "Expected 12, got %d\n", size);
832
833         break;
834     }
835
836     case WM_DDE_ACK:
837     {
838         ok((msg_index >= 2 && msg_index <= 4) || (msg_index >= 6 && msg_index <= 10),
839            "Expected 2, 3, 4, 6, 7, 8, 9 or 10, got %d\n", msg_index);
840
841         if (msg_index == 2)
842         {
843             server_hwnd = (HWND)wparam;
844             ok(wparam != 0, "Expected non-NULL wparam, got %08lx\n", wparam);
845
846             size = GlobalGetAtomNameA(LOWORD(lparam), str, MAX_PATH);
847             ok(LOWORD(lparam) == server, "Expected server atom, got %08x\n", LOWORD(lparam));
848             ok(!lstrcmpA(str, "TestDDEServer"), "Expected TestDDEServer, got %s\n", str);
849             ok(size == 13, "Expected 13, got %d\n", size);
850
851             size = GlobalGetAtomNameA(HIWORD(lparam), str, MAX_PATH);
852             ok(HIWORD(lparam) == topic, "Expected topic atom, got %08x\n", HIWORD(lparam));
853             ok(!lstrcmpA(str, "TestDDETopic"), "Expected TestDDETopic, got %s\n", str);
854             ok(size == 12, "Expected 12, got %d\n", size);
855         }
856         else if (msg_index == 9 || msg_index == 10)
857         {
858             ok(wparam == (WPARAM)server_hwnd, "Expected server hwnd, got %08lx\n", wparam);
859
860             UnpackDDElParam(WM_DDE_ACK, lparam, &lo, &hi);
861
862             ack = (DDEACK *)&lo;
863             ok(ack->bAppReturnCode == 0, "Expected 0, got %d\n", ack->bAppReturnCode);
864             ok(ack->reserved == 0, "Expected 0, got %d\n", ack->reserved);
865             ok(ack->fBusy == FALSE, "Expected FALSE, got %d\n", ack->fBusy);
866
867             ok(hi == (UINT_PTR)execute_hglobal, "Execpted execute hglobal, got %08lx\n", hi);
868             ptr = GlobalLock((HGLOBAL)hi);
869
870             if (msg_index == 9)
871             {
872                 ok(ack->fAck == TRUE, "Expected TRUE, got %d\n", ack->fAck);
873                 ok(!lstrcmpA(ptr, "[Command(Var)]"), "Expected '[Command(Var)]', got %s\n", ptr);
874             }
875             else
876             {
877                 ok(ack->fAck == FALSE, "Expected FALSE, got %d\n", ack->fAck);
878                 ok(!lstrcmpA(ptr, "[BadCommand(Var)]"), "Expected '[BadCommand(Var)]', got %s\n", ptr);
879             }
880
881             GlobalUnlock((HGLOBAL)hi);
882         }
883         else
884         {
885             ok(wparam == (WPARAM)server_hwnd, "Expected server hwnd, got %08lx\n", wparam);
886
887             UnpackDDElParam(WM_DDE_ACK, lparam, &lo, &hi);
888
889             ack = (DDEACK *)&lo;
890             ok(ack->bAppReturnCode == 0, "Expected 0, got %d\n", ack->bAppReturnCode);
891             ok(ack->reserved == 0, "Expected 0, got %d\n", ack->reserved);
892             ok(ack->fBusy == FALSE, "Expected FALSE, got %d\n", ack->fBusy);
893
894             if (msg_index >= 7)
895                 ok(ack->fAck == TRUE, "Expected TRUE, got %d\n", ack->fAck);
896             else
897             {
898                 if (msg_index == 6) todo_wine
899                 ok(ack->fAck == FALSE, "Expected FALSE, got %d\n", ack->fAck);
900             }
901
902             size = GlobalGetAtomNameA(hi, str, MAX_PATH);
903             if (msg_index == 3)
904             {
905                 ok(hi == item, "Expected item atom, got %08lx\n", hi);
906                 ok(!lstrcmpA(str, "request"), "Expected request, got %s\n", str);
907                 ok(size == 7, "Expected 7, got %d\n", size);
908             }
909             else if (msg_index == 4 || msg_index == 7)
910             {
911                 ok(hi == 0, "Expected 0, got %08lx\n", hi);
912                 ok(size == 0, "Expected empty string, got %d\n", size);
913             }
914             else
915             {
916                 ok(hi == item, "Expected item atom, got %08lx\n", hi);
917                 if (msg_index == 6) todo_wine
918                 {
919                     ok(!lstrcmpA(str, "poke"), "Expected poke, got %s\n", str);
920                     ok(size == 4, "Expected 4, got %d\n", size);
921                 }
922             }
923         }
924
925         break;
926     }
927
928     case WM_DDE_DATA:
929     {
930         ok(msg_index == 5, "Expected 5, got %d\n", msg_index);
931         ok(wparam == (WPARAM)server_hwnd, "Expected server hwnd, got %08lx\n", wparam);
932
933         UnpackDDElParam(WM_DDE_DATA, lparam, &lo, &hi);
934
935         data = GlobalLock((HGLOBAL)lo);
936         ok(data->unused == 0, "Expected 0, got %d\n", data->unused);
937         ok(data->fResponse == TRUE, "Expected TRUE, got %d\n", data->fResponse);
938         todo_wine
939         {
940             ok(data->fRelease == TRUE, "Expected TRUE, got %d\n", data->fRelease);
941         }
942         ok(data->fAckReq == 0, "Expected 0, got %d\n", data->fAckReq);
943         ok(data->cfFormat == CF_TEXT, "Expected CF_TEXT, got %d\n", data->cfFormat);
944         ok(!lstrcmpA((LPSTR)data->Value, "requested data\r\n"),
945            "Expeted 'requested data\\r\\n', got %s\n", data->Value);
946         GlobalUnlock((HGLOBAL)lo);
947
948         size = GlobalGetAtomNameA(hi, str, MAX_PATH);
949         ok(hi == item, "Expected item atom, got %08x\n", HIWORD(lparam));
950         ok(!lstrcmpA(str, "request"), "Expected request, got %s\n", str);
951         ok(size == 7, "Expected 7, got %d\n", size);
952
953         GlobalFree((HGLOBAL)lo);
954         GlobalDeleteAtom(hi);
955
956         break;
957     }
958
959     default:
960         ok(FALSE, "Unhandled msg: %08x\n", msg);
961     }
962
963     return DefWindowProcA(hwnd, msg, wparam, lparam);
964 }
965
966 static HGLOBAL create_poke()
967 {
968     HGLOBAL hglobal;
969     DDEPOKE *poke;
970     DWORD size;
971
972     size = sizeof(DDEPOKE) + lstrlenA("poke data\r\n") + 1;
973     hglobal = GlobalAlloc(GMEM_DDESHARE, size);
974     ok(hglobal != 0, "Expected non-NULL hglobal\n");
975
976     poke = GlobalLock(hglobal);
977     poke->unused = 0;
978     poke->fRelease = TRUE;
979     poke->fReserved = TRUE;
980     poke->cfFormat = CF_TEXT;
981     lstrcpyA((LPSTR)poke->Value, "poke data\r\n");
982     GlobalUnlock(hglobal);
983
984     return hglobal;
985 }
986
987 static HGLOBAL create_execute(LPCSTR command)
988 {
989     HGLOBAL hglobal;
990     LPSTR ptr;
991
992     hglobal = GlobalAlloc(GMEM_DDESHARE, lstrlenA(command) + 1);
993     ok(hglobal != 0, "Expected non-NULL hglobal\n");
994
995     ptr = GlobalLock(hglobal);
996     lstrcpyA(ptr, command);
997     GlobalUnlock(hglobal);
998
999     return hglobal;
1000 }
1001
1002 static void test_msg_client()
1003 {
1004     HGLOBAL hglobal;
1005     LPARAM lparam;
1006
1007     create_dde_window(&client_hwnd, "dde_client", dde_msg_client_wndproc);
1008
1009     server = GlobalAddAtomA("TestDDEServer");
1010     ok(server != 0, "Expected non-NULL server\n");
1011
1012     topic = GlobalAddAtomA("TestDDETopic");
1013     ok(topic != 0, "Expected non-NULL topic\n");
1014
1015     SendMessageA(HWND_BROADCAST, WM_DDE_INITIATE, (WPARAM)client_hwnd, MAKELONG(server, topic));
1016
1017     GlobalDeleteAtom(server);
1018     GlobalDeleteAtom(topic);
1019
1020     flush_events();
1021
1022     item = GlobalAddAtom("request");
1023     ok(item != 0, "Expected non-NULL item\n");
1024
1025     /* WM_DDE_REQUEST, bad clipboard format */
1026     lparam = PackDDElParam(WM_DDE_REQUEST, 0xdeadbeef, item);
1027     PostMessageA(server_hwnd, WM_DDE_REQUEST, (WPARAM)client_hwnd, lparam);
1028
1029     flush_events();
1030
1031     /* WM_DDE_REQUEST, no item */
1032     lparam = PackDDElParam(WM_DDE_REQUEST, CF_TEXT, 0);
1033     PostMessageA(server_hwnd, WM_DDE_REQUEST, (WPARAM)client_hwnd, lparam);
1034
1035     flush_events();
1036
1037     /* WM_DDE_REQUEST, no client hwnd */
1038     lparam = PackDDElParam(WM_DDE_REQUEST, CF_TEXT, item);
1039     PostMessageA(server_hwnd, WM_DDE_REQUEST, 0, lparam);
1040
1041     flush_events();
1042
1043     /* WM_DDE_REQUEST, correct params */
1044     lparam = PackDDElParam(WM_DDE_REQUEST, CF_TEXT, item);
1045     PostMessageA(server_hwnd, WM_DDE_REQUEST, (WPARAM)client_hwnd, lparam);
1046
1047     flush_events();
1048
1049     GlobalDeleteAtom(item);
1050     item = GlobalAddAtomA("poke");
1051     ok(item != 0, "Expected non-NULL item\n");
1052
1053     hglobal = create_poke();
1054
1055     /* WM_DDE_POKE, no ddepoke */
1056     lparam = PackDDElParam(WM_DDE_POKE, 0, item);
1057     PostMessageA(server_hwnd, WM_DDE_POKE, (WPARAM)client_hwnd, lparam);
1058
1059     flush_events();
1060
1061     /* WM_DDE_POKE, no item */
1062     lparam = PackDDElParam(WM_DDE_POKE, (UINT_PTR)hglobal, 0);
1063     PostMessageA(server_hwnd, WM_DDE_POKE, (WPARAM)client_hwnd, lparam);
1064
1065     flush_events();
1066
1067     hglobal = create_poke();
1068
1069     /* WM_DDE_POKE, no client hwnd */
1070     lparam = PackDDElParam(WM_DDE_POKE, (UINT_PTR)hglobal, item);
1071     PostMessageA(server_hwnd, WM_DDE_POKE, 0, lparam);
1072
1073     flush_events();
1074
1075     /* WM_DDE_POKE, all params correct */
1076     lparam = PackDDElParam(WM_DDE_POKE, (UINT_PTR)hglobal, item);
1077     PostMessageA(server_hwnd, WM_DDE_POKE, (WPARAM)client_hwnd, lparam);
1078
1079     flush_events();
1080
1081     execute_hglobal = create_execute("[Command(Var)]");
1082
1083     /* WM_DDE_EXECUTE, no lparam */
1084     PostMessageA(server_hwnd, WM_DDE_EXECUTE, (WPARAM)client_hwnd, 0);
1085
1086     flush_events();
1087
1088     /* WM_DDE_EXECUTE, no hglobal */
1089     lparam = PackDDElParam(WM_DDE_EXECUTE, 0, 0);
1090     PostMessageA(server_hwnd, WM_DDE_EXECUTE, (WPARAM)client_hwnd, lparam);
1091
1092     flush_events();
1093
1094     /* WM_DDE_EXECUTE, no client hwnd */
1095     lparam = PackDDElParam(WM_DDE_EXECUTE, 0, (UINT_PTR)execute_hglobal);
1096     PostMessageA(server_hwnd, WM_DDE_EXECUTE, 0, lparam);
1097
1098     flush_events();
1099
1100     /* WM_DDE_EXECUTE, all params correct */
1101     lparam = PackDDElParam(WM_DDE_EXECUTE, 0, (UINT_PTR)execute_hglobal);
1102     PostMessageA(server_hwnd, WM_DDE_EXECUTE, (WPARAM)client_hwnd, lparam);
1103
1104     flush_events();
1105
1106     GlobalFree(execute_hglobal);
1107     execute_hglobal = create_execute("[BadCommand(Var)]");
1108
1109     /* WM_DDE_EXECUTE that will get rejected */
1110     lparam = PackDDElParam(WM_DDE_EXECUTE, 0, (UINT_PTR)execute_hglobal);
1111     PostMessageA(server_hwnd, WM_DDE_EXECUTE, (WPARAM)client_hwnd, lparam);
1112
1113     flush_events();
1114
1115     DestroyWindow(client_hwnd);
1116 }
1117
1118 static LRESULT WINAPI hook_dde_client_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
1119 {
1120     UINT_PTR lo, hi;
1121
1122     trace("hook_dde_client_wndproc: %p %04x %08lx %08lx\n", hwnd, msg, wparam, lparam);
1123
1124     switch (msg)
1125     {
1126     case WM_DDE_ACK:
1127         UnpackDDElParam(WM_DDE_ACK, lparam, &lo, &hi);
1128         trace("WM_DDE_ACK: status %04lx hglobal %p\n", lo, (HGLOBAL)hi);
1129         break;
1130
1131     default:
1132         break;
1133     }
1134     return CallWindowProcA(old_dde_client_wndproc, hwnd, msg, wparam, lparam);
1135 }
1136
1137 static LRESULT WINAPI dde_server_wndprocW(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
1138 {
1139     trace("dde_server_wndprocW: %p %04x %08lx %08lx\n", hwnd, msg, wparam, lparam);
1140
1141     switch (msg)
1142     {
1143     case WM_DDE_INITIATE:
1144     {
1145         ATOM aService = GlobalAddAtomW(TEST_DDE_SERVICE);
1146
1147         trace("server: got WM_DDE_INITIATE from %p with %08lx\n", (HWND)wparam, lparam);
1148
1149         if (LOWORD(lparam) == aService)
1150         {
1151             ok(!IsWindowUnicode((HWND)wparam), "client should be an ANSI window\n");
1152             old_dde_client_wndproc = (WNDPROC)SetWindowLongPtrA((HWND)wparam, GWLP_WNDPROC, (ULONG_PTR)hook_dde_client_wndproc);
1153             trace("server: sending WM_DDE_ACK to %p\n", (HWND)wparam);
1154             SendMessageW((HWND)wparam, WM_DDE_ACK, (WPARAM)hwnd, MAKELPARAM(aService, 0));
1155         }
1156         else
1157             GlobalDeleteAtom(aService);
1158         return 0;
1159     }
1160
1161     case WM_DDE_EXECUTE:
1162     {
1163         DDEACK ack;
1164         WORD status;
1165         LPCSTR cmd;
1166         UINT_PTR lo, hi;
1167
1168         trace("server: got WM_DDE_EXECUTE from %p with %08lx\n", (HWND)wparam, lparam);
1169
1170         UnpackDDElParam(WM_DDE_EXECUTE, lparam, &lo, &hi);
1171         trace("%08lx => lo %04lx hi %04lx\n", lparam, lo, hi);
1172
1173         ack.bAppReturnCode = 0;
1174         ack.reserved = 0;
1175         ack.fBusy = 0;
1176
1177         cmd = GlobalLock((HGLOBAL)hi);
1178
1179         if (!cmd || (lstrcmpA(cmd, exec_cmdA) && lstrcmpW((LPCWSTR)cmd, exec_cmdW)))
1180         {
1181             trace("ignoring unknown WM_DDE_EXECUTE command\n");
1182             /* We have to send a negative acknowledge even if we don't
1183              * accept the command, otherwise Windows goes mad and next time
1184              * we send an acknowledge DDEML drops the connection.
1185              * Not sure how to call it: a bug or a feature.
1186              */
1187             ack.fAck = 0;
1188         }
1189         else
1190             ack.fAck = 1;
1191         GlobalUnlock((HGLOBAL)hi);
1192
1193         trace("server: posting %s WM_DDE_ACK to %p\n", ack.fAck ? "POSITIVE" : "NEGATIVE", (HWND)wparam);
1194
1195         status = *((WORD *)&ack);
1196         lparam = ReuseDDElParam(lparam, WM_DDE_EXECUTE, WM_DDE_ACK, status, hi);
1197
1198         PostMessageW((HWND)wparam, WM_DDE_ACK, (WPARAM)hwnd, lparam);
1199         return 0;
1200     }
1201
1202     case WM_DDE_TERMINATE:
1203     {
1204         DDEACK ack;
1205         WORD status;
1206
1207         trace("server: got WM_DDE_TERMINATE from %p with %08lx\n", (HWND)wparam, lparam);
1208
1209         ack.bAppReturnCode = 0;
1210         ack.reserved = 0;
1211         ack.fBusy = 0;
1212         ack.fAck = 1;
1213
1214         trace("server: posting %s WM_DDE_ACK to %p\n", ack.fAck ? "POSITIVE" : "NEGATIVE", (HWND)wparam);
1215
1216         status = *((WORD *)&ack);
1217         lparam = PackDDElParam(WM_DDE_ACK, status, 0);
1218
1219         PostMessageW((HWND)wparam, WM_DDE_ACK, (WPARAM)hwnd, lparam);
1220         return 0;
1221     }
1222
1223     default:
1224         break;
1225     }
1226
1227     return DefWindowProcW(hwnd, msg, wparam, lparam);
1228 }
1229
1230 static LRESULT WINAPI dde_client_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
1231 {
1232     return DefWindowProcA(hwnd, msg, wparam, lparam);
1233 }
1234
1235 static BOOL create_dde_windows(HWND *client, HWND *server)
1236 {
1237     WNDCLASSA wcA;
1238     WNDCLASSW wcW;
1239     static const WCHAR server_class_name[] = {'d','d','e','_','s','e','r','v','e','r','_','w','i','n','d','o','w',0};
1240     static const char client_class_name[] = "dde_client_window";
1241
1242     memset(&wcW, 0, sizeof(wcW));
1243     wcW.lpfnWndProc = dde_server_wndprocW;
1244     wcW.lpszClassName = server_class_name;
1245     wcW.hInstance = GetModuleHandleA(0);
1246     if (!RegisterClassW(&wcW)) return FALSE;
1247
1248     memset(&wcA, 0, sizeof(wcA));
1249     wcA.lpfnWndProc = dde_client_wndproc;
1250     wcA.lpszClassName = client_class_name;
1251     wcA.hInstance = GetModuleHandleA(0);
1252     assert(RegisterClassA(&wcA));
1253
1254     *server = CreateWindowExW(0, server_class_name, NULL,
1255                               WS_POPUP,
1256                               100, 100, CW_USEDEFAULT, CW_USEDEFAULT,
1257                               GetDesktopWindow(), 0,
1258                               GetModuleHandleA(0), NULL);
1259     assert(*server);
1260
1261     *client = CreateWindowExA(0, client_class_name, NULL,
1262                               WS_POPUP,
1263                               100, 100, CW_USEDEFAULT, CW_USEDEFAULT,
1264                               GetDesktopWindow(), 0,
1265                               GetModuleHandleA(0), NULL);
1266     assert(*client);
1267
1268     trace("server hwnd %p, client hwnd %p\n", *server, *client);
1269
1270     ok(IsWindowUnicode(*server), "server has to be a unicode window\n");
1271     ok(!IsWindowUnicode(*client), "client has to be an ANSI window\n");
1272
1273     return TRUE;
1274 }
1275
1276 static HDDEDATA CALLBACK client_dde_callback(UINT uType, UINT uFmt, HCONV hconv,
1277                                      HSZ hsz1, HSZ hsz2, HDDEDATA hdata,
1278                                      ULONG_PTR dwData1, ULONG_PTR dwData2)
1279 {
1280     static const char * const cmd_type[15] = {
1281         "XTYP_ERROR", "XTYP_ADVDATA", "XTYP_ADVREQ", "XTYP_ADVSTART",
1282         "XTYP_ADVSTOP", "XTYP_EXECUTE", "XTYP_CONNECT", "XTYP_CONNECT_CONFIRM",
1283         "XTYP_XACT_COMPLETE", "XTYP_POKE", "XTYP_REGISTER", "XTYP_REQUEST",
1284         "XTYP_DISCONNECT", "XTYP_UNREGISTER", "XTYP_WILDCONNECT" };
1285     UINT type;
1286     const char *cmd_name;
1287
1288     type = (uType & XTYP_MASK) >> XTYP_SHIFT;
1289     cmd_name = (type >= 0 && type <= 14) ? cmd_type[type] : "unknown";
1290
1291     trace("client_dde_callback: %04x (%s) %d %p %p %p %p %08lx %08lx\n",
1292           uType, cmd_name, uFmt, hconv, hsz1, hsz2, hdata, dwData1, dwData2);
1293     return 0;
1294 }
1295
1296 static void test_dde_aw_transaction(void)
1297 {
1298     HSZ hsz_server;
1299     DWORD dde_inst, ret, err;
1300     HCONV hconv;
1301     HWND hwnd_client, hwnd_server;
1302     CONVINFO info;
1303     HDDEDATA hdata;
1304     static char test_cmd[] = "test dde command";
1305
1306     /* server: unicode, client: ansi */
1307     if (!create_dde_windows(&hwnd_client, &hwnd_server)) return;
1308
1309     dde_inst = 0;
1310     ret = DdeInitializeA(&dde_inst, client_dde_callback, APPCMD_CLIENTONLY, 0);
1311     ok(ret == DMLERR_NO_ERROR, "DdeInitializeW failed with error %04x (%x)\n",
1312        ret, DdeGetLastError(dde_inst));
1313
1314     hsz_server = DdeCreateStringHandleW(dde_inst, TEST_DDE_SERVICE, CP_WINUNICODE);
1315
1316     hconv = DdeConnect(dde_inst, hsz_server, 0, NULL);
1317     ok(hconv != 0, "DdeConnect error %x\n", DdeGetLastError(dde_inst));
1318     err = DdeGetLastError(dde_inst);
1319     ok(err == DMLERR_NO_ERROR, "wrong dde error %x\n", err);
1320
1321     info.cb = sizeof(info);
1322     ret = DdeQueryConvInfo(hconv, QID_SYNC, &info);
1323     ok(ret, "wrong info size %d, DdeQueryConvInfo error %x\n", ret, DdeGetLastError(dde_inst));
1324     /* should be CP_WINANSI since we used DdeInitializeA */
1325     ok(info.ConvCtxt.iCodePage == CP_WINANSI, "wrong iCodePage %d\n", info.ConvCtxt.iCodePage);
1326     ok(!info.hConvPartner, "unexpected info.hConvPartner: %p\n", info.hConvPartner);
1327 todo_wine {
1328     ok((info.wStatus & DDE_FACK), "unexpected info.wStatus: %04x\n", info.wStatus);
1329 }
1330     ok((info.wStatus & (ST_CONNECTED | ST_CLIENT)) == (ST_CONNECTED | ST_CLIENT), "unexpected info.wStatus: %04x\n", info.wStatus);
1331     ok(info.wConvst == XST_CONNECTED, "unexpected info.wConvst: %04x\n", info.wConvst);
1332     ok(info.wType == 0, "unexpected info.wType: %04x\n", info.wType);
1333
1334     trace("hwnd %p, hwndPartner %p\n", info.hwnd, info.hwndPartner);
1335
1336     trace("sending test client transaction command\n");
1337     ret = 0xdeadbeef;
1338     hdata = DdeClientTransaction((LPBYTE)test_cmd, strlen(test_cmd) + 1, hconv, (HSZ)0xdead, 0xbeef, XTYP_EXECUTE, 1000, &ret);
1339     ok(!hdata, "DdeClientTransaction succeeded\n");
1340     ok(ret == DDE_FNOTPROCESSED, "wrong status code %04x\n", ret);
1341     err = DdeGetLastError(dde_inst);
1342     ok(err == DMLERR_NOTPROCESSED, "wrong dde error %x\n", err);
1343
1344     trace("sending ANSI client transaction command\n");
1345     ret = 0xdeadbeef;
1346     hdata = DdeClientTransaction((LPBYTE)exec_cmdA, lstrlenA(exec_cmdA) + 1, hconv, 0, 0, XTYP_EXECUTE, 1000, &ret);
1347     ok(hdata != 0, "DdeClientTransaction returned %p, error %x\n", hdata, DdeGetLastError(dde_inst));
1348     ok(ret == DDE_FACK, "wrong status code %04x\n", ret);
1349
1350     err = DdeGetLastError(dde_inst);
1351     ok(err == DMLERR_NO_ERROR, "wrong dde error %x\n", err);
1352
1353     trace("sending unicode client transaction command\n");
1354     ret = 0xdeadbeef;
1355     hdata = DdeClientTransaction((LPBYTE)exec_cmdW, (lstrlenW(exec_cmdW) + 1) * sizeof(WCHAR), hconv, 0, 0, XTYP_EXECUTE, 1000, &ret);
1356     ok(hdata != 0, "DdeClientTransaction returned %p, error %x\n", hdata, DdeGetLastError(dde_inst));
1357     ok(ret == DDE_FACK, "wrong status code %04x\n", ret);
1358     err = DdeGetLastError(dde_inst);
1359     ok(err == DMLERR_NO_ERROR, "wrong dde error %x\n", err);
1360
1361     ok(DdeDisconnect(hconv), "DdeDisconnect error %x\n", DdeGetLastError(dde_inst));
1362
1363     info.cb = sizeof(info);
1364     ret = DdeQueryConvInfo(hconv, QID_SYNC, &info);
1365     ok(!ret, "DdeQueryConvInfo should fail\n");
1366     err = DdeGetLastError(dde_inst);
1367 todo_wine {
1368     ok(err == DMLERR_INVALIDPARAMETER, "wrong dde error %x\n", err);
1369 }
1370
1371     ok(DdeFreeStringHandle(dde_inst, hsz_server), "DdeFreeStringHandle error %x\n", DdeGetLastError(dde_inst));
1372
1373     /* This call hangs on win2k SP4 and XP SP1.
1374     DdeUninitialize(dde_inst);*/
1375
1376     DestroyWindow(hwnd_client);
1377     DestroyWindow(hwnd_server);
1378 }
1379
1380 static void test_DdeCreateStringHandleW(DWORD dde_inst, int codepage)
1381 {
1382     static const WCHAR dde_string[] = {'D','D','E',' ','S','t','r','i','n','g',0};
1383     HSZ str_handle;
1384     WCHAR bufW[256];
1385     char buf[256];
1386     ATOM atom;
1387     int ret;
1388
1389     str_handle = DdeCreateStringHandleW(dde_inst, dde_string, codepage);
1390     ok(str_handle != 0, "DdeCreateStringHandleW failed with error %08x\n",
1391        DdeGetLastError(dde_inst));
1392
1393     ret = DdeQueryStringW(dde_inst, str_handle, NULL, 0, codepage);
1394     if (codepage == CP_WINANSI)
1395         ok(ret == 1, "DdeQueryStringW returned wrong length %d\n", ret);
1396     else
1397         ok(ret == lstrlenW(dde_string), "DdeQueryStringW returned wrong length %d\n", ret);
1398
1399     ret = DdeQueryStringW(dde_inst, str_handle, bufW, 256, codepage);
1400     if (codepage == CP_WINANSI)
1401     {
1402         ok(ret == 1, "DdeQueryStringW returned wrong length %d\n", ret);
1403         ok(!lstrcmpA("D", (LPCSTR)bufW), "DdeQueryStringW returned wrong string\n");
1404     }
1405     else
1406     {
1407         ok(ret == lstrlenW(dde_string), "DdeQueryStringW returned wrong length %d\n", ret);
1408         ok(!lstrcmpW(dde_string, bufW), "DdeQueryStringW returned wrong string\n");
1409     }
1410
1411     ret = DdeQueryStringA(dde_inst, str_handle, buf, 256, CP_WINANSI);
1412     if (codepage == CP_WINANSI)
1413     {
1414         ok(ret == 1, "DdeQueryStringA returned wrong length %d\n", ret);
1415         ok(!lstrcmpA("D", buf), "DdeQueryStringW returned wrong string\n");
1416     }
1417     else
1418     {
1419         ok(ret == lstrlenA("DDE String"), "DdeQueryStringA returned wrong length %d\n", ret);
1420         ok(!lstrcmpA("DDE String", buf), "DdeQueryStringA returned wrong string %s\n", buf);
1421     }
1422
1423     ret = DdeQueryStringA(dde_inst, str_handle, buf, 256, CP_WINUNICODE);
1424     if (codepage == CP_WINANSI)
1425     {
1426         ok(ret == 1, "DdeQueryStringA returned wrong length %d\n", ret);
1427         ok(!lstrcmpA("D", buf), "DdeQueryStringA returned wrong string %s\n", buf);
1428     }
1429     else
1430     {
1431         ok(ret == lstrlenA("DDE String"), "DdeQueryStringA returned wrong length %d\n", ret);
1432         ok(!lstrcmpW(dde_string, (LPCWSTR)buf), "DdeQueryStringW returned wrong string\n");
1433     }
1434
1435     if (codepage == CP_WINANSI)
1436     {
1437         atom = FindAtomA((LPSTR)dde_string);
1438         ok(atom != 0, "Expected a valid atom\n");
1439
1440         SetLastError(0xdeadbeef);
1441         atom = GlobalFindAtomA((LPSTR)dde_string);
1442         ok(atom == 0, "Expected 0, got %d\n", atom);
1443         ok(GetLastError() == ERROR_FILE_NOT_FOUND,
1444            "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
1445     }
1446     else
1447     {
1448         atom = FindAtomW(dde_string);
1449         ok(atom != 0, "Expected a valid atom\n");
1450
1451         SetLastError(0xdeadbeef);
1452         atom = GlobalFindAtomW(dde_string);
1453         ok(atom == 0, "Expected 0, got %d\n", atom);
1454         ok(GetLastError() == ERROR_FILE_NOT_FOUND,
1455            "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
1456     }
1457
1458     ok(DdeFreeStringHandle(dde_inst, str_handle), "DdeFreeStringHandle failed\n");
1459 }
1460
1461 static void test_DdeCreateDataHandle(void)
1462 {
1463     HDDEDATA hdata;
1464     DWORD dde_inst;
1465     DWORD size;
1466     UINT res, err;
1467     BOOL ret;
1468     HSZ item;
1469     LPBYTE ptr;
1470
1471     dde_inst = 0;
1472     res = DdeInitializeA(&dde_inst, client_ddeml_callback, APPCMD_CLIENTONLY, 0);
1473     ok(res == DMLERR_NO_ERROR, "Expected DMLERR_NO_ERROR, got %d\n", res);
1474
1475     item = DdeCreateStringHandleA(dde_inst, "item", CP_WINANSI);
1476     ok(item != NULL, "Expected non-NULL hsz\n");
1477
1478     /* invalid instance id */
1479     DdeGetLastError(dde_inst);
1480     hdata = DdeCreateDataHandle(0xdeadbeef, (LPBYTE)"data", MAX_PATH, 0, item, CF_TEXT, 0);
1481     err = DdeGetLastError(dde_inst);
1482     todo_wine
1483     {
1484         ok(hdata == NULL, "Expected NULL, got %p\n", hdata);
1485         ok(err == DMLERR_INVALIDPARAMETER,
1486            "Expected DMLERR_INVALIDPARAMETER, got %d\n", err);
1487     }
1488
1489     /* 0 instance id */
1490     DdeGetLastError(dde_inst);
1491     hdata = DdeCreateDataHandle(0, (LPBYTE)"data", MAX_PATH, 0, item, CF_TEXT, 0);
1492     err = DdeGetLastError(dde_inst);
1493     todo_wine
1494     {
1495         ok(hdata == NULL, "Expected NULL, got %p\n", hdata);
1496         ok(err == DMLERR_INVALIDPARAMETER,
1497            "Expected DMLERR_INVALIDPARAMETER, got %d\n", err);
1498     }
1499
1500     /* NULL pSrc */
1501     DdeGetLastError(dde_inst);
1502     hdata = DdeCreateDataHandle(dde_inst, NULL, MAX_PATH, 0, item, CF_TEXT, 0);
1503     err = DdeGetLastError(dde_inst);
1504     ok(hdata != NULL, "Expected non-NULL hdata\n");
1505     ok(err == DMLERR_NO_ERROR, "Expected DMLERR_NO_ERROR, got %d\n", err);
1506
1507     ptr = GlobalLock(hdata);
1508     todo_wine
1509     {
1510         ok(ptr == NULL, "Expected NULL, got %p\n", ptr);
1511     }
1512
1513     ptr = DdeAccessData(hdata, &size);
1514     ok(ptr != NULL, "Expected non-NULL ptr\n");
1515     ok(lstrlenA((LPSTR)ptr) == 0, "Expected 0, got %d\n", lstrlenA((LPSTR)ptr));
1516     ok(size == 260, "Expected 260, got %d\n", size);
1517
1518     ret = DdeUnaccessData(hdata);
1519     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1520
1521     ret = DdeFreeDataHandle(hdata);
1522     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1523
1524     /* cb is zero */
1525     DdeGetLastError(dde_inst);
1526     hdata = DdeCreateDataHandle(dde_inst, (LPBYTE)"data", 0, 0, item, CF_TEXT, 0);
1527     err = DdeGetLastError(dde_inst);
1528     ok(hdata != NULL, "Expected non-NULL hdata\n");
1529     ok(err == DMLERR_NO_ERROR, "Expected DMLERR_NO_ERROR, got %d\n", err);
1530
1531     ptr = GlobalLock(hdata);
1532     todo_wine
1533     {
1534         ok(ptr == NULL, "Expected NULL, got %p\n", ptr);
1535     }
1536
1537     ptr = DdeAccessData(hdata, &size);
1538     ok(ptr != NULL, "Expected non-NULL ptr\n");
1539     ok(lstrlenA((LPSTR)ptr) != 0, "Expected non-empty string\n");
1540     ok(lstrcmpA((LPSTR)ptr, "data"), "Did not expect data\n");
1541     ok(size == 0, "Expected 0, got %d\n", size);
1542
1543     ret = DdeUnaccessData(hdata);
1544     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1545
1546     ret = DdeFreeDataHandle(hdata);
1547     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1548
1549     /* cbOff is non-zero */
1550     DdeGetLastError(dde_inst);
1551     hdata = DdeCreateDataHandle(dde_inst, (LPBYTE)"data", MAX_PATH, 2, item, CF_TEXT, 0);
1552     err = DdeGetLastError(dde_inst);
1553     ok(hdata != NULL, "Expected non-NULL hdata\n");
1554     ok(err == DMLERR_NO_ERROR, "Expected DMLERR_NO_ERROR, got %d\n", err);
1555
1556     ptr = GlobalLock(hdata);
1557     todo_wine
1558     {
1559         ok(ptr == NULL, "Expected NULL, got %p\n", ptr);
1560     }
1561
1562     ptr = DdeAccessData(hdata, &size);
1563     ok(ptr != NULL, "Expected non-NULL ptr\n");
1564     ok(size == 262, "Expected 262, got %d\n", size);
1565     todo_wine
1566     {
1567         ok(lstrlenA((LPSTR)ptr) == 0, "Expected 0, got %d\n", lstrlenA((LPSTR)ptr));
1568     }
1569
1570     ret = DdeUnaccessData(hdata);
1571     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1572
1573     ret = DdeFreeDataHandle(hdata);
1574     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1575
1576     /* NULL item */
1577     DdeGetLastError(dde_inst);
1578     hdata = DdeCreateDataHandle(dde_inst, (LPBYTE)"data", MAX_PATH, 0, 0, CF_TEXT, 0);
1579     err = DdeGetLastError(dde_inst);
1580     ok(hdata != NULL, "Expected non-NULL hdata\n");
1581     ok(err == DMLERR_NO_ERROR, "Expected DMLERR_NO_ERROR, got %d\n", err);
1582
1583     ptr = GlobalLock(hdata);
1584     todo_wine
1585     {
1586         ok(ptr == NULL, "Expected NULL, got %p\n", ptr);
1587     }
1588
1589     ptr = DdeAccessData(hdata, &size);
1590     ok(ptr != NULL, "Expected non-NULL ptr\n");
1591     ok(!lstrcmpA((LPSTR)ptr, "data"), "Expected data, got %s\n", ptr);
1592     ok(size == 260, "Expected 260, got %d\n", size);
1593
1594     ret = DdeUnaccessData(hdata);
1595     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1596
1597     ret = DdeFreeDataHandle(hdata);
1598     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1599
1600     /* NULL item */
1601     DdeGetLastError(dde_inst);
1602     hdata = DdeCreateDataHandle(dde_inst, (LPBYTE)"data", MAX_PATH, 0, (HSZ)0xdeadbeef, CF_TEXT, 0);
1603     err = DdeGetLastError(dde_inst);
1604     ok(hdata != NULL, "Expected non-NULL hdata\n");
1605     ok(err == DMLERR_NO_ERROR, "Expected DMLERR_NO_ERROR, got %d\n", err);
1606
1607     ptr = GlobalLock(hdata);
1608     todo_wine
1609     {
1610         ok(ptr == NULL, "Expected NULL, got %p\n", ptr);
1611     }
1612
1613     ptr = DdeAccessData(hdata, &size);
1614     ok(ptr != NULL, "Expected non-NULL ptr\n");
1615     ok(!lstrcmpA((LPSTR)ptr, "data"), "Expected data, got %s\n", ptr);
1616     ok(size == 260, "Expected 260, got %d\n", size);
1617
1618     ret = DdeUnaccessData(hdata);
1619     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1620
1621     ret = DdeFreeDataHandle(hdata);
1622     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1623
1624     /* invalid clipboard format */
1625     DdeGetLastError(dde_inst);
1626     hdata = DdeCreateDataHandle(dde_inst, (LPBYTE)"data", MAX_PATH, 0, item, 0xdeadbeef, 0);
1627     err = DdeGetLastError(dde_inst);
1628     ok(hdata != NULL, "Expected non-NULL hdata\n");
1629     ok(err == DMLERR_NO_ERROR, "Expected DMLERR_NO_ERROR, got %d\n", err);
1630
1631     ptr = GlobalLock(hdata);
1632     todo_wine
1633     {
1634         ok(ptr == NULL, "Expected NULL, got %p\n", ptr);
1635     }
1636
1637     ptr = DdeAccessData(hdata, &size);
1638     ok(ptr != NULL, "Expected non-NULL ptr\n");
1639     ok(!lstrcmpA((LPSTR)ptr, "data"), "Expected data, got %s\n", ptr);
1640     ok(size == 260, "Expected 260, got %d\n", size);
1641
1642     ret = DdeUnaccessData(hdata);
1643     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1644
1645     ret = DdeFreeDataHandle(hdata);
1646     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1647
1648     ret = DdeUninitialize(dde_inst);
1649     ok(res == DMLERR_NO_ERROR, "Expected DMLERR_NO_ERROR, got %d\n", res);
1650 }
1651
1652 static void test_DdeCreateStringHandle(void)
1653 {
1654     DWORD dde_inst, ret;
1655
1656     dde_inst = 0xdeadbeef;
1657     SetLastError(0xdeadbeef);
1658     ret = DdeInitializeW(&dde_inst, client_ddeml_callback, APPCMD_CLIENTONLY, 0);
1659     if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
1660     {
1661         trace("Skipping the DDE test on a Win9x platform\n");
1662         return;
1663     }
1664
1665     ok(ret == DMLERR_INVALIDPARAMETER, "DdeInitializeW should fail, but got %04x instead\n", ret);
1666     ok(DdeGetLastError(dde_inst) == DMLERR_INVALIDPARAMETER, "expected DMLERR_INVALIDPARAMETER\n");
1667
1668     dde_inst = 0;
1669     ret = DdeInitializeW(&dde_inst, client_ddeml_callback, APPCMD_CLIENTONLY, 0);
1670     ok(ret == DMLERR_NO_ERROR, "DdeInitializeW failed with error %04x (%08x)\n",
1671        ret, DdeGetLastError(dde_inst));
1672
1673     test_DdeCreateStringHandleW(dde_inst, 0);
1674     test_DdeCreateStringHandleW(dde_inst, CP_WINUNICODE);
1675     test_DdeCreateStringHandleW(dde_inst, CP_WINANSI);
1676
1677     ok(DdeUninitialize(dde_inst), "DdeUninitialize failed\n");
1678 }
1679
1680 static void test_FreeDDElParam(void)
1681 {
1682     HGLOBAL val, hglobal;
1683     BOOL ret;
1684
1685     ret = FreeDDElParam(WM_DDE_INITIATE, (LPARAM)NULL);
1686     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1687
1688     hglobal = GlobalAlloc(GMEM_DDESHARE, 100);
1689     ret = FreeDDElParam(WM_DDE_INITIATE, (LPARAM)hglobal);
1690     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1691     val = GlobalFree(hglobal);
1692     ok(val == NULL, "Expected NULL, got %p\n", val);
1693
1694     hglobal = GlobalAlloc(GMEM_DDESHARE, 100);
1695     ret = FreeDDElParam(WM_DDE_ADVISE, (LPARAM)hglobal);
1696     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1697     val = GlobalFree(hglobal);
1698     ok(val == hglobal, "Expected hglobal, got %p\n", val);
1699     ok(GetLastError() == ERROR_INVALID_HANDLE,
1700        "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1701
1702     hglobal = GlobalAlloc(GMEM_DDESHARE, 100);
1703     ret = FreeDDElParam(WM_DDE_UNADVISE, (LPARAM)hglobal);
1704     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1705     val = GlobalFree(hglobal);
1706     ok(val == NULL, "Expected NULL, got %p\n", val);
1707
1708     hglobal = GlobalAlloc(GMEM_DDESHARE, 100);
1709     ret = FreeDDElParam(WM_DDE_ACK, (LPARAM)hglobal);
1710     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1711     val = GlobalFree(hglobal);
1712     ok(val == hglobal, "Expected hglobal, got %p\n", val);
1713     ok(GetLastError() == ERROR_INVALID_HANDLE,
1714        "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1715
1716     hglobal = GlobalAlloc(GMEM_DDESHARE, 100);
1717     ret = FreeDDElParam(WM_DDE_DATA, (LPARAM)hglobal);
1718     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1719     val = GlobalFree(hglobal);
1720     ok(val == hglobal, "Expected hglobal, got %p\n", val);
1721     ok(GetLastError() == ERROR_INVALID_HANDLE,
1722        "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1723
1724     hglobal = GlobalAlloc(GMEM_DDESHARE, 100);
1725     ret = FreeDDElParam(WM_DDE_REQUEST, (LPARAM)hglobal);
1726     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1727     val = GlobalFree(hglobal);
1728     ok(val == NULL, "Expected NULL, got %p\n", val);
1729
1730     hglobal = GlobalAlloc(GMEM_DDESHARE, 100);
1731     ret = FreeDDElParam(WM_DDE_POKE, (LPARAM)hglobal);
1732     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1733     val = GlobalFree(hglobal);
1734     ok(val == hglobal, "Expected hglobal, got %p\n", val);
1735     ok(GetLastError() == ERROR_INVALID_HANDLE,
1736        "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1737
1738     hglobal = GlobalAlloc(GMEM_DDESHARE, 100);
1739     ret = FreeDDElParam(WM_DDE_EXECUTE, (LPARAM)hglobal);
1740     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1741     val = GlobalFree(hglobal);
1742     ok(val == NULL, "Expected NULL, got %p\n", val);
1743 }
1744
1745 static void test_PackDDElParam(void)
1746 {
1747     UINT_PTR lo, hi, *ptr;
1748     HGLOBAL hglobal;
1749     LPARAM lparam;
1750     BOOL ret;
1751
1752     lparam = PackDDElParam(WM_DDE_INITIATE, 0xcafe, 0xbeef);
1753     ok(lparam == 0xbeefcafe, "Expected 0xbeefcafe, got %08lx\n", lparam);
1754     ok(GlobalLock((HGLOBAL)lparam) == NULL,
1755        "Expected NULL, got %p\n", GlobalLock((HGLOBAL)lparam));
1756     ok(GetLastError() == ERROR_INVALID_HANDLE,
1757        "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1758
1759     lo = hi = 0;
1760     ret = UnpackDDElParam(WM_DDE_INITIATE, lparam, &lo, &hi);
1761     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1762     ok(lo == 0xcafe, "Expected 0xcafe, got %08lx\n", lo);
1763     ok(hi == 0xbeef, "Expected 0xbeef, got %08lx\n", hi);
1764
1765     ret = FreeDDElParam(WM_DDE_INITIATE, lparam);
1766     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1767
1768     lparam = PackDDElParam(WM_DDE_TERMINATE, 0xcafe, 0xbeef);
1769     ok(lparam == 0xbeefcafe, "Expected 0xbeefcafe, got %08lx\n", lparam);
1770     ok(GlobalLock((HGLOBAL)lparam) == NULL,
1771        "Expected NULL, got %p\n", GlobalLock((HGLOBAL)lparam));
1772     ok(GetLastError() == ERROR_INVALID_HANDLE,
1773        "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1774
1775     lo = hi = 0;
1776     ret = UnpackDDElParam(WM_DDE_TERMINATE, lparam, &lo, &hi);
1777     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1778     ok(lo == 0xcafe, "Expected 0xcafe, got %08lx\n", lo);
1779     ok(hi == 0xbeef, "Expected 0xbeef, got %08lx\n", hi);
1780
1781     ret = FreeDDElParam(WM_DDE_TERMINATE, lparam);
1782     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1783
1784     lparam = PackDDElParam(WM_DDE_ADVISE, 0xcafe, 0xbeef);
1785     ptr = GlobalLock((HGLOBAL)lparam);
1786     ok(ptr != NULL, "Expected non-NULL ptr\n");
1787     ok(ptr[0] == 0xcafe, "Expected 0xcafe, got %08lx\n", ptr[0]);
1788     ok(ptr[1] == 0xbeef, "Expected 0xbeef, got %08lx\n", ptr[1]);
1789
1790     ret = GlobalUnlock((HGLOBAL)lparam);
1791     ok(ret == 1, "Expected 1, got %d\n", ret);
1792
1793     lo = hi = 0;
1794     ret = UnpackDDElParam(WM_DDE_ADVISE, lparam, &lo, &hi);
1795     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1796     ok(lo == 0xcafe, "Expected 0xcafe, got %08lx\n", lo);
1797     ok(hi == 0xbeef, "Expected 0xbeef, got %08lx\n", hi);
1798
1799     ret = FreeDDElParam(WM_DDE_ADVISE, lparam);
1800     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1801
1802     hglobal = GlobalFree((HGLOBAL)lparam);
1803     ok(hglobal == (HGLOBAL)lparam, "Expected lparam, got %d\n", ret);
1804     ok(GetLastError() == ERROR_INVALID_HANDLE,
1805        "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1806
1807     lparam = PackDDElParam(WM_DDE_UNADVISE, 0xcafe, 0xbeef);
1808     ok(lparam == 0xbeefcafe, "Expected 0xbeefcafe, got %08lx\n", lparam);
1809     ok(GlobalLock((HGLOBAL)lparam) == NULL,
1810        "Expected NULL, got %p\n", GlobalLock((HGLOBAL)lparam));
1811     ok(GetLastError() == ERROR_INVALID_HANDLE,
1812        "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1813
1814     lo = hi = 0;
1815     ret = UnpackDDElParam(WM_DDE_UNADVISE, lparam, &lo, &hi);
1816     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1817     ok(lo == 0xcafe, "Expected 0xcafe, got %08lx\n", lo);
1818     ok(hi == 0xbeef, "Expected 0xbeef, got %08lx\n", hi);
1819
1820     ret = FreeDDElParam(WM_DDE_UNADVISE, lparam);
1821     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1822
1823     lparam = PackDDElParam(WM_DDE_ACK, 0xcafe, 0xbeef);
1824     ptr = GlobalLock((HGLOBAL)lparam);
1825     ok(ptr != NULL, "Expected non-NULL ptr\n");
1826     ok(ptr[0] == 0xcafe, "Expected 0xcafe, got %08lx\n", ptr[0]);
1827     ok(ptr[1] == 0xbeef, "Expected 0xbeef, got %08lx\n", ptr[1]);
1828
1829     ret = GlobalUnlock((HGLOBAL)lparam);
1830     ok(ret == 1, "Expected 1, got %d\n", ret);
1831
1832     lo = hi = 0;
1833     ret = UnpackDDElParam(WM_DDE_ACK, lparam, &lo, &hi);
1834     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1835     ok(lo == 0xcafe, "Expected 0xcafe, got %08lx\n", lo);
1836     ok(hi == 0xbeef, "Expected 0xbeef, got %08lx\n", hi);
1837
1838     ret = FreeDDElParam(WM_DDE_ACK, lparam);
1839     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1840
1841     hglobal = GlobalFree((HGLOBAL)lparam);
1842     ok(hglobal == (HGLOBAL)lparam, "Expected lparam, got %d\n", ret);
1843     ok(GetLastError() == ERROR_INVALID_HANDLE,
1844        "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1845
1846     lparam = PackDDElParam(WM_DDE_DATA, 0xcafe, 0xbeef);
1847     ptr = GlobalLock((HGLOBAL)lparam);
1848     ok(ptr != NULL, "Expected non-NULL ptr\n");
1849     ok(ptr[0] == 0xcafe, "Expected 0xcafe, got %08lx\n", ptr[0]);
1850     ok(ptr[1] == 0xbeef, "Expected 0xbeef, got %08lx\n", ptr[1]);
1851
1852     ret = GlobalUnlock((HGLOBAL)lparam);
1853     ok(ret == 1, "Expected 1, got %d\n", ret);
1854
1855     lo = hi = 0;
1856     ret = UnpackDDElParam(WM_DDE_DATA, lparam, &lo, &hi);
1857     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1858     ok(lo == 0xcafe, "Expected 0xcafe, got %08lx\n", lo);
1859     ok(hi == 0xbeef, "Expected 0xbeef, got %08lx\n", hi);
1860
1861     ret = FreeDDElParam(WM_DDE_DATA, lparam);
1862     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1863
1864     hglobal = GlobalFree((HGLOBAL)lparam);
1865     ok(hglobal == (HGLOBAL)lparam, "Expected lparam, got %d\n", ret);
1866     ok(GetLastError() == ERROR_INVALID_HANDLE,
1867        "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1868
1869     lparam = PackDDElParam(WM_DDE_REQUEST, 0xcafe, 0xbeef);
1870     ok(lparam == 0xbeefcafe, "Expected 0xbeefcafe, got %08lx\n", lparam);
1871     ok(GlobalLock((HGLOBAL)lparam) == NULL,
1872        "Expected NULL, got %p\n", GlobalLock((HGLOBAL)lparam));
1873     ok(GetLastError() == ERROR_INVALID_HANDLE,
1874        "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1875
1876     lo = hi = 0;
1877     ret = UnpackDDElParam(WM_DDE_REQUEST, lparam, &lo, &hi);
1878     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1879     ok(lo == 0xcafe, "Expected 0xcafe, got %08lx\n", lo);
1880     ok(hi == 0xbeef, "Expected 0xbeef, got %08lx\n", hi);
1881
1882     ret = FreeDDElParam(WM_DDE_REQUEST, lparam);
1883     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1884
1885     lparam = PackDDElParam(WM_DDE_POKE, 0xcafe, 0xbeef);
1886     ptr = GlobalLock((HGLOBAL)lparam);
1887     ok(ptr != NULL, "Expected non-NULL ptr\n");
1888     ok(ptr[0] == 0xcafe, "Expected 0xcafe, got %08lx\n", ptr[0]);
1889     ok(ptr[1] == 0xbeef, "Expected 0xbeef, got %08lx\n", ptr[1]);
1890
1891     ret = GlobalUnlock((HGLOBAL)lparam);
1892     ok(ret == 1, "Expected 1, got %d\n", ret);
1893
1894     lo = hi = 0;
1895     ret = UnpackDDElParam(WM_DDE_POKE, lparam, &lo, &hi);
1896     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1897     ok(lo == 0xcafe, "Expected 0xcafe, got %08lx\n", lo);
1898     ok(hi == 0xbeef, "Expected 0xbeef, got %08lx\n", hi);
1899
1900     ret = FreeDDElParam(WM_DDE_POKE, lparam);
1901     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1902
1903     hglobal = GlobalFree((HGLOBAL)lparam);
1904     ok(hglobal == (HGLOBAL)lparam, "Expected lparam, got %d\n", ret);
1905     ok(GetLastError() == ERROR_INVALID_HANDLE,
1906        "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1907
1908     lparam = PackDDElParam(WM_DDE_EXECUTE, 0xcafe, 0xbeef);
1909     ok(lparam == 0xbeef, "Expected 0xbeef, got %08lx\n", lparam);
1910     ok(GlobalLock((HGLOBAL)lparam) == NULL,
1911        "Expected NULL, got %p\n", GlobalLock((HGLOBAL)lparam));
1912     ok(GetLastError() == ERROR_INVALID_HANDLE,
1913        "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1914
1915     lo = hi = 0;
1916     ret = UnpackDDElParam(WM_DDE_EXECUTE, lparam, &lo, &hi);
1917     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1918     ok(lo == 0, "Expected 0, got %08lx\n", lo);
1919     ok(hi == 0xbeef, "Expected 0xbeef, got %08lx\n", hi);
1920
1921     ret = FreeDDElParam(WM_DDE_EXECUTE, lparam);
1922     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1923 }
1924
1925 static void test_UnpackDDElParam(void)
1926 {
1927     UINT_PTR lo, hi, *ptr;
1928     HGLOBAL hglobal;
1929     BOOL ret;
1930
1931     /* NULL lParam */
1932     lo = 0xdead;
1933     hi = 0xbeef;
1934     ret = UnpackDDElParam(WM_DDE_INITIATE, (LPARAM)NULL, &lo, &hi);
1935     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1936     ok(lo == 0, "Expected 0, got %08lx\n", lo);
1937     ok(hi == 0, "Expected 0, got %08lx\n", hi);
1938
1939     /* NULL lo */
1940     lo = 0xdead;
1941     hi = 0xbeef;
1942     ret = UnpackDDElParam(WM_DDE_INITIATE, 0xcafebabe, NULL, &hi);
1943     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1944     ok(lo == 0xdead, "Expected 0xdead, got %08lx\n", lo);
1945     ok(hi == 0xcafe, "Expected 0xcafe, got %08lx\n", hi);
1946
1947     /* NULL hi */
1948     lo = 0xdead;
1949     hi = 0xbeef;
1950     ret = UnpackDDElParam(WM_DDE_INITIATE, 0xcafebabe, &lo, NULL);
1951     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1952     ok(lo == 0xbabe, "Expected 0xbabe, got %08lx\n", lo);
1953     ok(hi == 0xbeef, "Expected 0xbeef, got %08lx\n", hi);
1954
1955     lo = 0xdead;
1956     hi = 0xbeef;
1957     ret = UnpackDDElParam(WM_DDE_INITIATE, 0xcafebabe, &lo, &hi);
1958     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1959     ok(lo == 0xbabe, "Expected 0xbabe, got %08lx\n", lo);
1960     ok(hi == 0xcafe, "Expected 0xcafe, got %08lx\n", hi);
1961
1962     lo = 0xdead;
1963     hi = 0xbeef;
1964     ret = UnpackDDElParam(WM_DDE_TERMINATE, 0xcafebabe, &lo, &hi);
1965     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1966     ok(lo == 0xbabe, "Expected 0xbabe, got %08lx\n", lo);
1967     ok(hi == 0xcafe, "Expected 0xcafe, got %08lx\n", hi);
1968
1969     lo = 0xdead;
1970     hi = 0xbeef;
1971     ret = UnpackDDElParam(WM_DDE_ADVISE, (LPARAM)NULL, &lo, &hi);
1972     ok(ret == FALSE, "Expected FALSE, got %d\n", ret);
1973     ok(lo == 0, "Expected 0, got %08lx\n", lo);
1974     ok(hi == 0, "Expected 0, got %08lx\n", hi);
1975
1976     lo = 0xdead;
1977     hi = 0xbeef;
1978     ret = UnpackDDElParam(WM_DDE_ADVISE, 0xcafebabe, &lo, &hi);
1979     ok(ret == FALSE, "Expected FALSE, got %d\n", ret);
1980     ok(lo == 0, "Expected 0, got %08lx\n", lo);
1981     ok(hi == 0, "Expected 0, got %08lx\n", hi);
1982
1983     hglobal = GlobalAlloc(GMEM_DDESHARE, 2);
1984     ptr = GlobalLock(hglobal);
1985     ptr[0] = 0xcafebabe;
1986     ptr[1] = 0xdeadbeef;
1987     GlobalUnlock(hglobal);
1988
1989     lo = 0xdead;
1990     hi = 0xbeef;
1991     ret = UnpackDDElParam(WM_DDE_ADVISE, (LPARAM)hglobal, &lo, &hi);
1992     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1993     ok(lo == 0xcafebabe, "Expected 0xcafebabe, got %08lx\n", lo);
1994     ok(hi == 0xdeadbeef, "Expected 0xdeadbeef, got %08lx\n", hi);
1995
1996     lo = 0xdead;
1997     hi = 0xbeef;
1998     ret = UnpackDDElParam(WM_DDE_UNADVISE, 0xcafebabe, &lo, &hi);
1999     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
2000     ok(lo == 0xbabe, "Expected 0xbabe, got %08lx\n", lo);
2001     ok(hi == 0xcafe, "Expected 0xcafe, got %08lx\n", hi);
2002
2003     lo = 0xdead;
2004     hi = 0xbeef;
2005     ret = UnpackDDElParam(WM_DDE_ACK, 0xcafebabe, &lo, &hi);
2006     ok(ret == FALSE, "Expected FALSE, got %d\n", ret);
2007     ok(lo == 0, "Expected 0, got %08lx\n", lo);
2008     ok(hi == 0, "Expected 0, got %08lx\n", hi);
2009
2010     lo = 0xdead;
2011     hi = 0xbeef;
2012     ret = UnpackDDElParam(WM_DDE_ACK, (LPARAM)hglobal, &lo, &hi);
2013     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
2014     ok(lo == 0xcafebabe, "Expected 0xcafebabe, got %08lx\n", lo);
2015     ok(hi == 0xdeadbeef, "Expected 0xdeadbeef, got %08lx\n", hi);
2016
2017     lo = 0xdead;
2018     hi = 0xbeef;
2019     ret = UnpackDDElParam(WM_DDE_DATA, 0xcafebabe, &lo, &hi);
2020     ok(ret == FALSE, "Expected FALSE, got %d\n", ret);
2021     ok(lo == 0, "Expected 0, got %08lx\n", lo);
2022     ok(hi == 0, "Expected 0, got %08lx\n", hi);
2023
2024     lo = 0xdead;
2025     hi = 0xbeef;
2026     ret = UnpackDDElParam(WM_DDE_DATA, (LPARAM)hglobal, &lo, &hi);
2027     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
2028     ok(lo == 0xcafebabe, "Expected 0xcafebabe, got %08lx\n", lo);
2029     ok(hi == 0xdeadbeef, "Expected 0xdeadbeef, got %08lx\n", hi);
2030
2031     lo = 0xdead;
2032     hi = 0xbeef;
2033     ret = UnpackDDElParam(WM_DDE_REQUEST, 0xcafebabe, &lo, &hi);
2034     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
2035     ok(lo == 0xbabe, "Expected 0xbabe, got %08lx\n", lo);
2036     ok(hi == 0xcafe, "Expected 0xcafe, got %08lx\n", hi);
2037
2038     lo = 0xdead;
2039     hi = 0xbeef;
2040     ret = UnpackDDElParam(WM_DDE_POKE, 0xcafebabe, &lo, &hi);
2041     ok(ret == FALSE, "Expected FALSE, got %d\n", ret);
2042     ok(lo == 0, "Expected 0, got %08lx\n", lo);
2043     ok(hi == 0, "Expected 0, got %08lx\n", hi);
2044
2045     lo = 0xdead;
2046     hi = 0xbeef;
2047     ret = UnpackDDElParam(WM_DDE_POKE, (LPARAM)hglobal, &lo, &hi);
2048     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
2049     ok(lo == 0xcafebabe, "Expected 0xcafebabe, got %08lx\n", lo);
2050     ok(hi == 0xdeadbeef, "Expected 0xdeadbeef, got %08lx\n", hi);
2051
2052     lo = 0xdead;
2053     hi = 0xbeef;
2054     ret = UnpackDDElParam(WM_DDE_EXECUTE, 0xcafebabe, &lo, &hi);
2055     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
2056     ok(lo == 0, "Expected 0, got %08lx\n", lo);
2057     ok(hi == 0xcafebabe, "Expected 0xcafebabe, got %08lx\n", hi);
2058 }
2059
2060 START_TEST(dde)
2061 {
2062     int argc;
2063     char **argv;
2064     char buffer[MAX_PATH];
2065     STARTUPINFO startup;
2066     PROCESS_INFORMATION proc;
2067
2068     argc = winetest_get_mainargs(&argv);
2069     if (argc == 3)
2070     {
2071         if (!lstrcmpA(argv[2], "ddeml"))
2072             test_ddeml_client();
2073         else if (!lstrcmpA(argv[2], "msg"))
2074             test_msg_client();
2075
2076         return;
2077     }
2078
2079     ZeroMemory(&startup, sizeof(STARTUPINFO));
2080     sprintf(buffer, "%s dde ddeml", argv[0]);
2081     startup.cb = sizeof(startup);
2082     startup.dwFlags = STARTF_USESHOWWINDOW;
2083     startup.wShowWindow = SW_SHOWNORMAL;
2084
2085     CreateProcessA(NULL, buffer, NULL, NULL, FALSE,
2086                    0, NULL, NULL, &startup, &proc);
2087
2088     test_msg_server(proc.hProcess);
2089
2090     sprintf(buffer, "%s dde msg", argv[0]);
2091     CreateProcessA(NULL, buffer, NULL, NULL, FALSE,
2092                    0, NULL, NULL, &startup, &proc);
2093
2094     test_ddeml_server(proc.hProcess);
2095
2096     test_dde_aw_transaction();
2097
2098     test_DdeCreateDataHandle();
2099     test_DdeCreateStringHandle();
2100     test_FreeDDElParam();
2101     test_PackDDElParam();
2102     test_UnpackDDElParam();
2103 }