Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers...
[reactos.git] / modules / rostests / winetests / user32 / 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 = GetModuleHandleA("user32.dll");
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, (LPCSTR)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, GetModuleHandleA(NULL), 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 {
124 SetLastError(0xcafebabe);
125 recips = BSM_APPLICATIONS;
126 ret = broadcast( BSF_QUERY|(BSF_NOHANG|BSF_FORCEIFHUNG), &recips, WM_NULL, 30000, 0 );
127 ok(0, "Last error: %08x\n", GetLastError());
128 ok(0, "Returned: %d\n", ret);
129
130 SetLastError(0xcafebabe);
131 recips = BSM_APPLICATIONS;
132 ret = broadcast( BSF_QUERY|(BSF_NOHANG|BSF_NOTIMEOUTIFNOTHUNG), &recips, WM_NULL, 30000, 0 );
133 ok(0, "Last error: %08x\n", GetLastError());
134 ok(0, "Returned: %d\n", ret);
135
136 SetLastError(0xcafebabe);
137 recips = BSM_APPLICATIONS;
138 ret = broadcast( BSF_QUERY|(BSF_NOTIMEOUTIFNOTHUNG|BSF_FORCEIFHUNG), &recips, WM_NULL, 30000, 0 );
139 ok(0, "Last error: %08x\n", GetLastError());
140 ok(0, "Returned: %d\n", ret);
141
142 SetLastError(0xcafebabe);
143 recips = BSM_APPLICATIONS;
144 ret = broadcast( BSF_POSTMESSAGE|(BSF_NOTIMEOUTIFNOTHUNG|BSF_FORCEIFHUNG), &recips, WM_NULL, 30000, 0 );
145 ok(0, "Last error: %08x\n", GetLastError());
146 ok(0, "Returned: %d\n", ret);
147 }
148
149 recips = BSM_APPLICATIONS;
150 ResetEvent(hevent);
151 ret = broadcast( BSF_POSTMESSAGE|BSF_QUERY, &recips, WM_NULL, 100, 0 );
152 ok(ret==1, "Returned: %d\n", ret);
153 ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
154 PulseEvent(hevent);
155
156 SetLastError( 0xdeadbeef );
157 recips = BSM_APPLICATIONS;
158 ret = broadcast( BSF_POSTMESSAGE|BSF_SENDNOTIFYMESSAGE, &recips, WM_NULL, 100, 0 );
159 if (ret)
160 {
161 ok(ret==1, "Returned: %d\n", ret);
162 ok(WaitForSingleObject(hevent, 0) != WAIT_OBJECT_0, "Synchronous message sent instead\n");
163 PulseEvent(hevent);
164
165 recips = BSM_APPLICATIONS;
166 ret = broadcast( BSF_SENDNOTIFYMESSAGE, &recips, WM_NULL, 100, BROADCAST_QUERY_DENY );
167 ok(ret==1, "Returned: %d\n", ret);
168 ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
169 PulseEvent(hevent);
170
171 recips = BSM_APPLICATIONS;
172 ret = broadcast( BSF_SENDNOTIFYMESSAGE|BSF_QUERY, &recips, WM_NULL, 100, BROADCAST_QUERY_DENY );
173 ok(!ret, "Returned: %d\n", ret);
174 ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
175 PulseEvent(hevent);
176 }
177 else /* BSF_SENDNOTIFYMESSAGE not supported on NT4 */
178 ok( GetLastError() == ERROR_INVALID_PARAMETER, "failed with err %u\n", GetLastError() );
179
180 recips = BSM_APPLICATIONS;
181 ret = broadcast( 0, &recips, WM_NULL, 100, 0 );
182 ok(ret==1, "Returned: %d\n", ret);
183 ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
184 PulseEvent(hevent);
185 }
186
187 /* BSF_SENDNOTIFYMESSAGE and BSF_QUERY are both synchronous within the same process
188 * However you should be able to distinguish them by sending the BROADCAST_QUERY_DENY flag
189 */
190
191 static void test_parametersEx(PBROADCASTEX broadcastex)
192 {
193 LONG ret;
194 DWORD recips;
195
196 SetLastError(0xcafebabe);
197 recips = BSM_APPLICATIONS;
198 ret = broadcastex( 0x80000000, &recips, WM_NULL, 0, 0, NULL );
199 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error: %08x\n", GetLastError());
200 ok(!ret, "Returned: %d\n", ret);
201
202 SetLastError(0xcafebabe);
203 recips = BSM_APPLICATIONS;
204 ret = broadcastex( 0x80000000, &recips, WM_NULL, 0, 0, NULL );
205 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error: %08x\n", GetLastError());
206 ok(!ret, "Returned: %d\n", ret);
207
208 if (0) /* TODO: Check the hang flags */
209 {
210 SetLastError(0xcafebabe);
211 recips = BSM_APPLICATIONS;
212 ret = broadcastex( BSF_QUERY|(BSF_NOHANG|BSF_FORCEIFHUNG), &recips, WM_NULL, 30000, 0, NULL );
213 ok(0, "Last error: %08x\n", GetLastError());
214 ok(0, "Returned: %d\n", ret);
215
216 SetLastError(0xcafebabe);
217 recips = BSM_APPLICATIONS;
218 ret = broadcastex( BSF_QUERY|(BSF_NOHANG|BSF_NOTIMEOUTIFNOTHUNG), &recips, WM_NULL, 30000, 0, NULL );
219 ok(0, "Last error: %08x\n", GetLastError());
220 ok(0, "Returned: %d\n", ret);
221
222 SetLastError(0xcafebabe);
223 recips = BSM_APPLICATIONS;
224 ret = broadcastex( BSF_QUERY|(BSF_NOTIMEOUTIFNOTHUNG|BSF_FORCEIFHUNG), &recips, WM_NULL, 30000, 0, NULL );
225 ok(0, "Last error: %08x\n", GetLastError());
226 ok(0, "Returned: %d\n", ret);
227
228 SetLastError(0xcafebabe);
229 recips = BSM_APPLICATIONS;
230 ret = broadcastex( BSF_POSTMESSAGE|(BSF_NOTIMEOUTIFNOTHUNG|BSF_FORCEIFHUNG), &recips, WM_NULL, 30000, 0, NULL );
231 ok(0, "Last error: %08x\n", GetLastError());
232 ok(0, "Returned: %d\n", ret);
233 }
234
235 recips = BSM_APPLICATIONS;
236 ResetEvent(hevent);
237 ret = broadcastex( BSF_POSTMESSAGE|BSF_QUERY, &recips, WM_NULL, 100, 0, NULL );
238 ok(ret==1, "Returned: %d\n", ret);
239 ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
240 PulseEvent(hevent);
241
242 recips = BSM_APPLICATIONS;
243 ret = broadcastex( BSF_POSTMESSAGE|BSF_SENDNOTIFYMESSAGE, &recips, WM_NULL, 100, 0, NULL );
244 ok(ret==1, "Returned: %d\n", ret);
245 ok(WaitForSingleObject(hevent, 0) != WAIT_OBJECT_0, "Synchronous message sent instead\n");
246 PulseEvent(hevent);
247
248 recips = BSM_APPLICATIONS;
249 ret = broadcastex( BSF_SENDNOTIFYMESSAGE, &recips, WM_NULL, 100, BROADCAST_QUERY_DENY, NULL );
250 ok(ret==1, "Returned: %d\n", ret);
251 ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
252 PulseEvent(hevent);
253
254 recips = BSM_APPLICATIONS;
255 ret = broadcastex( BSF_SENDNOTIFYMESSAGE|BSF_QUERY, &recips, WM_NULL, 100, BROADCAST_QUERY_DENY, NULL );
256 ok(!ret, "Returned: %d\n", ret);
257 ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
258 PulseEvent(hevent);
259
260 recips = BSM_APPLICATIONS;
261 ret = broadcastex( 0, &recips, WM_NULL, 100, 0, NULL );
262 ok(ret==1, "Returned: %d\n", ret);
263 ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
264 PulseEvent(hevent);
265 }
266
267 static BOOL (WINAPI *pOpenProcessToken)(HANDLE, DWORD, HANDLE*);
268 static BOOL (WINAPI *pAdjustTokenPrivileges)(HANDLE, BOOL, PTOKEN_PRIVILEGES, DWORD, PTOKEN_PRIVILEGES, PDWORD);
269
270 static void test_noprivileges(void)
271 {
272 HANDLE advapi32 = GetModuleHandleA("advapi32");
273 HANDLE token;
274 DWORD recips;
275 BOOL ret;
276
277 static const DWORD BSM_ALL_RECIPS = BSM_VXDS | BSM_NETDRIVER |
278 BSM_INSTALLABLEDRIVERS | BSM_APPLICATIONS;
279
280 pOpenProcessToken = (void *)GetProcAddress(advapi32, "OpenProcessToken");
281 pAdjustTokenPrivileges = (void *)GetProcAddress(advapi32, "AdjustTokenPrivileges");
282 if (!pOpenProcessToken || !pAdjustTokenPrivileges || !pOpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token))
283 {
284 skip("Can't open security token for process\n");
285 return;
286 }
287 if (!pAdjustTokenPrivileges(token, TRUE, NULL, 0, NULL, NULL))
288 {
289 skip("Can't adjust security token for process\n");
290 return;
291 }
292
293 trace("Trying privileged edition!\n");
294 SetLastError(0xcafebabe);
295 recips = BSM_ALLDESKTOPS;
296 ResetEvent(hevent);
297 ret = pBroadcastExW( BSF_QUERY, &recips, WM_NULL, 100, 0, NULL );
298 ok(ret==1, "Returned: %d error %u\n", ret, GetLastError());
299 ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
300 ok(recips == BSM_ALLDESKTOPS ||
301 recips == BSM_ALL_RECIPS, /* win2k3 */
302 "Received by: %08x\n", recips);
303 PulseEvent(hevent);
304
305 SetLastError(0xcafebabe);
306 recips = BSM_ALLCOMPONENTS;
307 ResetEvent(hevent);
308 ret = pBroadcastExW( BSF_QUERY, &recips, WM_NULL, 100, 0, NULL );
309 ok(ret==1, "Returned: %d error %u\n", ret, GetLastError());
310 ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
311 ok(recips == BSM_ALLCOMPONENTS ||
312 recips == BSM_ALL_RECIPS, /* win2k3 */
313 "Received by: %08x\n", recips);
314 PulseEvent(hevent);
315
316 SetLastError(0xcafebabe);
317 recips = BSM_ALLDESKTOPS|BSM_APPLICATIONS;
318 ResetEvent(hevent);
319 ret = pBroadcastExW( BSF_QUERY, &recips, WM_NULL, 100, 0, NULL );
320 ok(ret==1, "Returned: %d error %u\n", ret, GetLastError());
321 ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
322 ok(recips == (BSM_ALLDESKTOPS|BSM_APPLICATIONS) ||
323 recips == BSM_APPLICATIONS, /* win2k3 */
324 "Received by: %08x\n", recips);
325 PulseEvent(hevent);
326
327 SetLastError(0xcafebabe);
328 recips = BSM_ALLDESKTOPS|BSM_APPLICATIONS;
329 ResetEvent(hevent);
330 ret = pBroadcastExW( BSF_QUERY, &recips, WM_NULL, 100, BROADCAST_QUERY_DENY, NULL );
331 ok(!ret, "Returned: %d\n", ret);
332 ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
333 ok(recips == (BSM_ALLDESKTOPS|BSM_APPLICATIONS) ||
334 recips == BSM_APPLICATIONS, /* win2k3 */
335 "Received by: %08x\n", recips);
336 PulseEvent(hevent);
337 }
338
339 START_TEST(broadcast)
340 {
341 if (!init_procs())
342 return;
343
344 trace("Running BroadcastSystemMessageA tests\n");
345 test_parameters(pBroadcastA, "BroadcastSystemMessageA");
346 if (pBroadcastW)
347 {
348 trace("Running BroadcastSystemMessageW tests\n");
349 test_parameters(pBroadcastW, "BroadcastSystemMessageW");
350 }
351 else
352 win_skip("No BroadcastSystemMessageW, skipping\n");
353 if (pBroadcastExA)
354 {
355 trace("Running BroadcastSystemMessageExA tests\n");
356 test_parametersEx(pBroadcastExA);
357 }
358 else
359 win_skip("No BroadcastSystemMessageExA, skipping\n");
360 if (pBroadcastExW)
361 {
362 trace("Running BroadcastSystemMessageExW tests\n");
363 test_parametersEx(pBroadcastExW);
364 trace("Attempting privileges checking tests\n");
365 test_noprivileges();
366 }
367 else
368 win_skip("No BroadcastSystemMessageExW, skipping\n");
369 }