dmusic: Set instrument stream position where the instrument begins, not at the beginn...
[wine] / dlls / user32 / tests / broadcast.c
1 /*
2  * Unit tests for BroadcastSystemMessage
3  *
4  * Copyright 2008 Maarten Lankhorst
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #define _WIN32_WINNT 0x0501
22
23 #include <stdarg.h>
24 #include <stdio.h>
25
26 #include "windef.h"
27 #include "winbase.h"
28 #include "wingdi.h"
29 #include "winuser.h"
30 #include "winnls.h"
31
32 #include "wine/test.h"
33
34 typedef LONG (WINAPI *PBROADCAST)( DWORD,LPDWORD,UINT,WPARAM,LPARAM );
35 typedef LONG (WINAPI *PBROADCASTEX)( DWORD,LPDWORD,UINT,WPARAM,LPARAM,PBSMINFO );
36 static PBROADCAST pBroadcastA;
37 static PBROADCAST pBroadcastW;
38 static PBROADCASTEX pBroadcastExA;
39 static PBROADCASTEX pBroadcastExW;
40 static HANDLE hevent;
41
42 static LRESULT WINAPI main_window_procA(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
43 {
44     if (msg == WM_NULL)
45     {
46         trace("main_window_procA: Sleeping for %lu ms\n", wparam);
47         if (wparam)
48         {
49             if (WaitForSingleObject(hevent, wparam) == WAIT_TIMEOUT)
50                 SetEvent(hevent);
51         }
52         trace("main_window_procA: Returning WM_NULL with parameter %08lx\n", lparam);
53         return lparam;
54     }
55
56     return DefWindowProcA(hwnd, msg, wparam, lparam);
57 }
58
59 static BOOL init_procs(void)
60 {
61     WNDCLASSA cls;
62     HANDLE user32 = GetModuleHandle("user32");
63     pBroadcastA = (PBROADCAST)GetProcAddress(user32, "BroadcastSystemMessageA");
64     if (!pBroadcastA)
65         pBroadcastA = (PBROADCAST)GetProcAddress(user32, "BroadcastSystemMessage");
66     ok(pBroadcastA != NULL, "No BroadcastSystemMessage found\n");
67     if (!pBroadcastA)
68     {
69         win_skip("BroadcastA is not available\n");
70         return FALSE;
71     }
72
73     pBroadcastW = (PBROADCAST)GetProcAddress(user32, "BroadcastSystemMessageW");
74     pBroadcastExA = (PBROADCASTEX)GetProcAddress(user32, "BroadcastSystemMessageExA");
75     pBroadcastExW = (PBROADCASTEX)GetProcAddress(user32, "BroadcastSystemMessageExW");
76
77     hevent = CreateEventA(NULL, TRUE, FALSE, "Asynchronous checking event");
78
79     cls.style = CS_DBLCLKS;
80     cls.lpfnWndProc = main_window_procA;
81     cls.cbClsExtra = 0;
82     cls.cbWndExtra = 0;
83     cls.hInstance = GetModuleHandleA(0);
84     cls.hIcon = 0;
85     cls.hCursor = LoadCursorA(0, IDC_ARROW);
86     cls.hbrBackground = GetStockObject(WHITE_BRUSH);
87     cls.lpszMenuName = NULL;
88     cls.lpszClassName = "MainWindowClass";
89
90     if (!RegisterClassA(&cls))
91         return FALSE;
92
93     if (!CreateWindowExA(0, "MainWindowClass", "Main window", WS_CAPTION | WS_SYSMENU |
94                                WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP, 100, 100, 200,
95                                200, 0, 0, GetModuleHandle(0), NULL))
96         return FALSE;
97     return TRUE;
98 }
99
100 static void test_parameters(PBROADCAST broadcast, const char *functionname)
101 {
102     LONG ret;
103     DWORD recips;
104
105     SetLastError(0xcafebabe);
106     recips = BSM_APPLICATIONS;
107     ret = broadcast( 0x80000000, &recips, WM_NULL, 0, 0 );
108     if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
109     {
110         win_skip("%s is not implemented\n", functionname);
111         return;
112     }
113     ok(!ret || broken(ret), "Returned: %d\n", ret);
114     if (!ret) ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error: %08x\n", GetLastError());
115
116     SetLastError(0xcafebabe);
117     recips = BSM_APPLICATIONS;
118     ret = broadcast( 0x80000000, &recips, WM_NULL, 0, 0 );
119     ok(!ret || broken(ret), "Returned: %d\n", ret);
120     if (!ret) ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error: %08x\n", GetLastError());
121
122 #if 0 /* TODO: Check the hang flags */
123     SetLastError(0xcafebabe);
124     recips = BSM_APPLICATIONS;
125     ret = broadcast( BSF_QUERY|(BSF_NOHANG|BSF_FORCEIFHUNG), &recips, WM_NULL, 30000, 0 );
126     ok(0, "Last error: %08x\n", GetLastError());
127     ok(0, "Returned: %d\n", ret);
128
129     SetLastError(0xcafebabe);
130     recips = BSM_APPLICATIONS;
131     ret = broadcast( BSF_QUERY|(BSF_NOHANG|BSF_NOTIMEOUTIFNOTHUNG), &recips, WM_NULL, 30000, 0 );
132     ok(0, "Last error: %08x\n", GetLastError());
133     ok(0, "Returned: %d\n", ret);
134
135     SetLastError(0xcafebabe);
136     recips = BSM_APPLICATIONS;
137     ret = broadcast( BSF_QUERY|(BSF_NOTIMEOUTIFNOTHUNG|BSF_FORCEIFHUNG), &recips, WM_NULL, 30000, 0 );
138     ok(0, "Last error: %08x\n", GetLastError());
139     ok(0, "Returned: %d\n", ret);
140
141     SetLastError(0xcafebabe);
142     recips = BSM_APPLICATIONS;
143     ret = broadcast( BSF_POSTMESSAGE|(BSF_NOTIMEOUTIFNOTHUNG|BSF_FORCEIFHUNG), &recips, WM_NULL, 30000, 0 );
144     ok(0, "Last error: %08x\n", GetLastError());
145     ok(0, "Returned: %d\n", ret);
146 #endif
147
148     recips = BSM_APPLICATIONS;
149     ResetEvent(hevent);
150     ret = broadcast( BSF_POSTMESSAGE|BSF_QUERY, &recips, WM_NULL, 100, 0 );
151     ok(ret==1, "Returned: %d\n", ret);
152     ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
153     PulseEvent(hevent);
154
155     SetLastError( 0xdeadbeef );
156     recips = BSM_APPLICATIONS;
157     ret = broadcast( BSF_POSTMESSAGE|BSF_SENDNOTIFYMESSAGE, &recips, WM_NULL, 100, 0 );
158     if (ret)
159     {
160         ok(ret==1, "Returned: %d\n", ret);
161         ok(WaitForSingleObject(hevent, 0) != WAIT_OBJECT_0, "Synchronous message sent instead\n");
162         PulseEvent(hevent);
163
164         recips = BSM_APPLICATIONS;
165         ret = broadcast( BSF_SENDNOTIFYMESSAGE, &recips, WM_NULL, 100, BROADCAST_QUERY_DENY );
166         ok(ret==1, "Returned: %d\n", ret);
167         ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
168         PulseEvent(hevent);
169
170         recips = BSM_APPLICATIONS;
171         ret = broadcast( BSF_SENDNOTIFYMESSAGE|BSF_QUERY, &recips, WM_NULL, 100, BROADCAST_QUERY_DENY );
172         ok(!ret, "Returned: %d\n", ret);
173         ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
174         PulseEvent(hevent);
175     }
176     else  /* BSF_SENDNOTIFYMESSAGE not supported on NT4 */
177         ok( GetLastError() == ERROR_INVALID_PARAMETER, "failed with err %u\n", GetLastError() );
178
179     recips = BSM_APPLICATIONS;
180     ret = broadcast( 0, &recips, WM_NULL, 100, 0 );
181     ok(ret==1, "Returned: %d\n", ret);
182     ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
183     PulseEvent(hevent);
184 }
185
186 /* BSF_SENDNOTIFYMESSAGE and BSF_QUERY are both synchronous within the same process
187  * However you should be able to distinguish them by sending the BROADCAST_QUERY_DENY flag
188  */
189
190 static void test_parametersEx(PBROADCASTEX broadcastex)
191 {
192     LONG ret;
193     DWORD recips;
194
195     SetLastError(0xcafebabe);
196     recips = BSM_APPLICATIONS;
197     ret = broadcastex( 0x80000000, &recips, WM_NULL, 0, 0, NULL );
198     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error: %08x\n", GetLastError());
199     ok(!ret, "Returned: %d\n", ret);
200
201     SetLastError(0xcafebabe);
202     recips = BSM_APPLICATIONS;
203     ret = broadcastex( 0x80000000, &recips, WM_NULL, 0, 0, NULL );
204     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error: %08x\n", GetLastError());
205     ok(!ret, "Returned: %d\n", ret);
206
207 #if 0 /* TODO: Check the hang flags */
208     SetLastError(0xcafebabe);
209     recips = BSM_APPLICATIONS;
210     ret = broadcast( BSF_QUERY|(BSF_NOHANG|BSF_FORCEIFHUNG), &recips, WM_NULL, 30000, 0, NULL );
211     ok(0, "Last error: %08x\n", GetLastError());
212     ok(0, "Returned: %d\n", ret);
213
214     SetLastError(0xcafebabe);
215     recips = BSM_APPLICATIONS;
216     ret = broadcast( BSF_QUERY|(BSF_NOHANG|BSF_NOTIMEOUTIFNOTHUNG), &recips, WM_NULL, 30000, 0, NULL );
217     ok(0, "Last error: %08x\n", GetLastError());
218     ok(0, "Returned: %d\n", ret);
219
220     SetLastError(0xcafebabe);
221     recips = BSM_APPLICATIONS;
222     ret = broadcast( BSF_QUERY|(BSF_NOTIMEOUTIFNOTHUNG|BSF_FORCEIFHUNG), &recips, WM_NULL, 30000, 0, NULL );
223     ok(0, "Last error: %08x\n", GetLastError());
224     ok(0, "Returned: %d\n", ret);
225
226     SetLastError(0xcafebabe);
227     recips = BSM_APPLICATIONS;
228     ret = broadcast( BSF_POSTMESSAGE|(BSF_NOTIMEOUTIFNOTHUNG|BSF_FORCEIFHUNG), &recips, WM_NULL, 30000, 0, NULL );
229     ok(0, "Last error: %08x\n", GetLastError());
230     ok(0, "Returned: %d\n", ret);
231 #endif
232
233     recips = BSM_APPLICATIONS;
234     ResetEvent(hevent);
235     ret = broadcastex( BSF_POSTMESSAGE|BSF_QUERY, &recips, WM_NULL, 100, 0, NULL );
236     ok(ret==1, "Returned: %d\n", ret);
237     ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
238     PulseEvent(hevent);
239
240     recips = BSM_APPLICATIONS;
241     ret = broadcastex( BSF_POSTMESSAGE|BSF_SENDNOTIFYMESSAGE, &recips, WM_NULL, 100, 0, NULL );
242     ok(ret==1, "Returned: %d\n", ret);
243     ok(WaitForSingleObject(hevent, 0) != WAIT_OBJECT_0, "Synchronous message sent instead\n");
244     PulseEvent(hevent);
245
246     recips = BSM_APPLICATIONS;
247     ret = broadcastex( BSF_SENDNOTIFYMESSAGE, &recips, WM_NULL, 100, BROADCAST_QUERY_DENY, NULL );
248     ok(ret==1, "Returned: %d\n", ret);
249     ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
250     PulseEvent(hevent);
251
252     recips = BSM_APPLICATIONS;
253     ret = broadcastex( BSF_SENDNOTIFYMESSAGE|BSF_QUERY, &recips, WM_NULL, 100, BROADCAST_QUERY_DENY, NULL );
254     ok(!ret, "Returned: %d\n", ret);
255     ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
256     PulseEvent(hevent);
257
258     recips = BSM_APPLICATIONS;
259     ret = broadcastex( 0, &recips, WM_NULL, 100, 0, NULL );
260     ok(ret==1, "Returned: %d\n", ret);
261     ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
262     PulseEvent(hevent);
263 }
264
265 static BOOL (WINAPI *pOpenProcessToken)(HANDLE, DWORD, HANDLE*);
266 static BOOL (WINAPI *pAdjustTokenPrivileges)(HANDLE, BOOL, PTOKEN_PRIVILEGES, DWORD, PTOKEN_PRIVILEGES, PDWORD);
267
268 static void test_noprivileges(void)
269 {
270     HANDLE advapi32 = GetModuleHandleA("advapi32");
271     HANDLE token;
272     DWORD recips;
273     BOOL ret;
274
275     static const DWORD BSM_ALL_RECIPS = BSM_VXDS | BSM_NETDRIVER |
276                                         BSM_INSTALLABLEDRIVERS | BSM_APPLICATIONS;
277
278     pOpenProcessToken = (void *)GetProcAddress(advapi32, "OpenProcessToken");
279     pAdjustTokenPrivileges = (void *)GetProcAddress(advapi32, "AdjustTokenPrivileges");
280     if (!pOpenProcessToken || !pAdjustTokenPrivileges || !pOpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token))
281     {
282         skip("Can't open security token for process\n");
283         return;
284     }
285     if (!pAdjustTokenPrivileges(token, TRUE, NULL, 0, NULL, NULL))
286     {
287         skip("Can't adjust security token for process\n");
288         return;
289     }
290
291     trace("Trying privileged edition!\n");
292     SetLastError(0xcafebabe);
293     recips = BSM_ALLDESKTOPS;
294     ResetEvent(hevent);
295     ret = pBroadcastExW( BSF_QUERY, &recips, WM_NULL, 100, 0, NULL );
296     ok(ret==1, "Returned: %d error %u\n", ret, GetLastError());
297     ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
298     ok(recips == BSM_ALLDESKTOPS ||
299        recips == BSM_ALL_RECIPS, /* win2k3 */
300        "Received by: %08x\n", recips);
301     PulseEvent(hevent);
302
303     SetLastError(0xcafebabe);
304     recips = BSM_ALLCOMPONENTS;
305     ResetEvent(hevent);
306     ret = pBroadcastExW( BSF_QUERY, &recips, WM_NULL, 100, 0, NULL );
307     ok(ret==1, "Returned: %d error %u\n", ret, GetLastError());
308     ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
309     ok(recips == BSM_ALLCOMPONENTS ||
310        recips == BSM_ALL_RECIPS, /* win2k3 */
311        "Received by: %08x\n", recips);
312     PulseEvent(hevent);
313
314     SetLastError(0xcafebabe);
315     recips = BSM_ALLDESKTOPS|BSM_APPLICATIONS;
316     ResetEvent(hevent);
317     ret = pBroadcastExW( BSF_QUERY, &recips, WM_NULL, 100, 0, NULL );
318     ok(ret==1, "Returned: %d error %u\n", ret, GetLastError());
319     ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
320     ok(recips == (BSM_ALLDESKTOPS|BSM_APPLICATIONS) ||
321        recips == BSM_APPLICATIONS, /* win2k3 */
322        "Received by: %08x\n", recips);
323     PulseEvent(hevent);
324
325     SetLastError(0xcafebabe);
326     recips = BSM_ALLDESKTOPS|BSM_APPLICATIONS;
327     ResetEvent(hevent);
328     ret = pBroadcastExW( BSF_QUERY, &recips, WM_NULL, 100, BROADCAST_QUERY_DENY, NULL );
329     ok(!ret, "Returned: %d\n", ret);
330     ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
331     ok(recips == (BSM_ALLDESKTOPS|BSM_APPLICATIONS) ||
332        recips == BSM_APPLICATIONS, /* win2k3 */
333        "Received by: %08x\n", recips);
334     PulseEvent(hevent);
335 }
336
337 START_TEST(broadcast)
338 {
339     if (!init_procs())
340         return;
341
342     trace("Running BroadcastSystemMessageA tests\n");
343     test_parameters(pBroadcastA, "BroadcastSystemMessageA");
344     if (pBroadcastW)
345     {
346         trace("Running BroadcastSystemMessageW tests\n");
347         test_parameters(pBroadcastW, "BroadcastSystemMessageW");
348     }
349     else
350         win_skip("No BroadcastSystemMessageW, skipping\n");
351     if (pBroadcastExA)
352     {
353         trace("Running BroadcastSystemMessageExA tests\n");
354         test_parametersEx(pBroadcastExA);
355     }
356     else
357         win_skip("No BroadcastSystemMessageExA, skipping\n");
358     if (pBroadcastExW)
359     {
360         trace("Running BroadcastSystemMessageExW tests\n");
361         test_parametersEx(pBroadcastExW);
362         trace("Attempting privileges checking tests\n");
363         test_noprivileges();
364     }
365     else
366         win_skip("No BroadcastSystemMessageExW, skipping\n");
367 }