[USER32_WINETEST] Sync everything except win.c with Wine Staging 3.3. CORE-14434
[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 #ifndef __REACTOS__
22 #define _WIN32_WINNT 0x0501
23 #endif
24
25 #include <stdarg.h>
26 #include <stdio.h>
27
28 #include "windef.h"
29 #include "winbase.h"
30 #include "wingdi.h"
31 #include "winuser.h"
32 #include "winnls.h"
33
34 #include "wine/test.h"
35
36 typedef LONG (WINAPI *PBROADCAST)( DWORD,LPDWORD,UINT,WPARAM,LPARAM );
37 typedef LONG (WINAPI *PBROADCASTEX)( DWORD,LPDWORD,UINT,WPARAM,LPARAM,PBSMINFO );
38 static HANDLE hevent;
39
40 static LRESULT WINAPI main_window_procA(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
41 {
42 if (msg == WM_NULL)
43 {
44 trace("main_window_procA: Sleeping for %lu ms\n", wparam);
45 if (wparam)
46 {
47 if (WaitForSingleObject(hevent, wparam) == WAIT_TIMEOUT)
48 SetEvent(hevent);
49 }
50 trace("main_window_procA: Returning WM_NULL with parameter %08lx\n", lparam);
51 return lparam;
52 }
53
54 return DefWindowProcA(hwnd, msg, wparam, lparam);
55 }
56
57 static BOOL init_procs(void)
58 {
59 WNDCLASSA cls;
60
61 hevent = CreateEventA(NULL, TRUE, FALSE, "Asynchronous checking event");
62
63 cls.style = CS_DBLCLKS;
64 cls.lpfnWndProc = main_window_procA;
65 cls.cbClsExtra = 0;
66 cls.cbWndExtra = 0;
67 cls.hInstance = GetModuleHandleA(0);
68 cls.hIcon = 0;
69 cls.hCursor = LoadCursorA(0, (LPCSTR)IDC_ARROW);
70 cls.hbrBackground = GetStockObject(WHITE_BRUSH);
71 cls.lpszMenuName = NULL;
72 cls.lpszClassName = "MainWindowClass";
73
74 if (!RegisterClassA(&cls))
75 return FALSE;
76
77 if (!CreateWindowExA(0, "MainWindowClass", "Main window", WS_CAPTION | WS_SYSMENU |
78 WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP, 100, 100, 200,
79 200, 0, 0, GetModuleHandleA(NULL), NULL))
80 return FALSE;
81 return TRUE;
82 }
83
84 static void test_parameters(PBROADCAST broadcast, const char *functionname)
85 {
86 LONG ret;
87 DWORD recips;
88
89 SetLastError(0xcafebabe);
90 recips = BSM_APPLICATIONS;
91 ret = broadcast( 0x80000000, &recips, WM_NULL, 0, 0 );
92 if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
93 {
94 win_skip("%s is not implemented\n", functionname);
95 return;
96 }
97 ok(!ret || broken(ret), "Returned: %d\n", ret);
98 if (!ret) ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error: %08x\n", GetLastError());
99
100 SetLastError(0xcafebabe);
101 recips = BSM_APPLICATIONS;
102 ret = broadcast( 0x80000000, &recips, WM_NULL, 0, 0 );
103 ok(!ret || broken(ret), "Returned: %d\n", ret);
104 if (!ret) ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error: %08x\n", GetLastError());
105
106 if (0) /* TODO: Check the hang flags */
107 {
108 SetLastError(0xcafebabe);
109 recips = BSM_APPLICATIONS;
110 ret = broadcast( BSF_QUERY|(BSF_NOHANG|BSF_FORCEIFHUNG), &recips, WM_NULL, 30000, 0 );
111 ok(0, "Last error: %08x\n", GetLastError());
112 ok(0, "Returned: %d\n", ret);
113
114 SetLastError(0xcafebabe);
115 recips = BSM_APPLICATIONS;
116 ret = broadcast( BSF_QUERY|(BSF_NOHANG|BSF_NOTIMEOUTIFNOTHUNG), &recips, WM_NULL, 30000, 0 );
117 ok(0, "Last error: %08x\n", GetLastError());
118 ok(0, "Returned: %d\n", ret);
119
120 SetLastError(0xcafebabe);
121 recips = BSM_APPLICATIONS;
122 ret = broadcast( BSF_QUERY|(BSF_NOTIMEOUTIFNOTHUNG|BSF_FORCEIFHUNG), &recips, WM_NULL, 30000, 0 );
123 ok(0, "Last error: %08x\n", GetLastError());
124 ok(0, "Returned: %d\n", ret);
125
126 SetLastError(0xcafebabe);
127 recips = BSM_APPLICATIONS;
128 ret = broadcast( BSF_POSTMESSAGE|(BSF_NOTIMEOUTIFNOTHUNG|BSF_FORCEIFHUNG), &recips, WM_NULL, 30000, 0 );
129 ok(0, "Last error: %08x\n", GetLastError());
130 ok(0, "Returned: %d\n", ret);
131 }
132
133 recips = BSM_APPLICATIONS;
134 ResetEvent(hevent);
135 ret = broadcast( BSF_POSTMESSAGE|BSF_QUERY, &recips, WM_NULL, 100, 0 );
136 ok(ret==1, "Returned: %d\n", ret);
137 ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
138 PulseEvent(hevent);
139
140 SetLastError( 0xdeadbeef );
141 recips = BSM_APPLICATIONS;
142 ret = broadcast( BSF_POSTMESSAGE|BSF_SENDNOTIFYMESSAGE, &recips, WM_NULL, 100, 0 );
143 if (ret)
144 {
145 ok(ret==1, "Returned: %d\n", ret);
146 ok(WaitForSingleObject(hevent, 0) != WAIT_OBJECT_0, "Synchronous message sent instead\n");
147 PulseEvent(hevent);
148
149 recips = BSM_APPLICATIONS;
150 ret = broadcast( BSF_SENDNOTIFYMESSAGE, &recips, WM_NULL, 100, BROADCAST_QUERY_DENY );
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 recips = BSM_APPLICATIONS;
156 ret = broadcast( BSF_SENDNOTIFYMESSAGE|BSF_QUERY, &recips, WM_NULL, 100, BROADCAST_QUERY_DENY );
157 ok(!ret, "Returned: %d\n", ret);
158 ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
159 PulseEvent(hevent);
160 }
161 else /* BSF_SENDNOTIFYMESSAGE not supported on NT4 */
162 ok( GetLastError() == ERROR_INVALID_PARAMETER, "failed with err %u\n", GetLastError() );
163
164 recips = BSM_APPLICATIONS;
165 ret = broadcast( 0, &recips, WM_NULL, 100, 0 );
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
171 /* BSF_SENDNOTIFYMESSAGE and BSF_QUERY are both synchronous within the same process
172 * However you should be able to distinguish them by sending the BROADCAST_QUERY_DENY flag
173 */
174
175 static void test_parametersEx(PBROADCASTEX broadcastex)
176 {
177 LONG ret;
178 DWORD recips;
179
180 SetLastError(0xcafebabe);
181 recips = BSM_APPLICATIONS;
182 ret = broadcastex( 0x80000000, &recips, WM_NULL, 0, 0, NULL );
183 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error: %08x\n", GetLastError());
184 ok(!ret, "Returned: %d\n", ret);
185
186 SetLastError(0xcafebabe);
187 recips = BSM_APPLICATIONS;
188 ret = broadcastex( 0x80000000, &recips, WM_NULL, 0, 0, NULL );
189 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error: %08x\n", GetLastError());
190 ok(!ret, "Returned: %d\n", ret);
191
192 if (0) /* TODO: Check the hang flags */
193 {
194 SetLastError(0xcafebabe);
195 recips = BSM_APPLICATIONS;
196 ret = broadcastex( BSF_QUERY|(BSF_NOHANG|BSF_FORCEIFHUNG), &recips, WM_NULL, 30000, 0, NULL );
197 ok(0, "Last error: %08x\n", GetLastError());
198 ok(0, "Returned: %d\n", ret);
199
200 SetLastError(0xcafebabe);
201 recips = BSM_APPLICATIONS;
202 ret = broadcastex( BSF_QUERY|(BSF_NOHANG|BSF_NOTIMEOUTIFNOTHUNG), &recips, WM_NULL, 30000, 0, NULL );
203 ok(0, "Last error: %08x\n", GetLastError());
204 ok(0, "Returned: %d\n", ret);
205
206 SetLastError(0xcafebabe);
207 recips = BSM_APPLICATIONS;
208 ret = broadcastex( BSF_QUERY|(BSF_NOTIMEOUTIFNOTHUNG|BSF_FORCEIFHUNG), &recips, WM_NULL, 30000, 0, NULL );
209 ok(0, "Last error: %08x\n", GetLastError());
210 ok(0, "Returned: %d\n", ret);
211
212 SetLastError(0xcafebabe);
213 recips = BSM_APPLICATIONS;
214 ret = broadcastex( BSF_POSTMESSAGE|(BSF_NOTIMEOUTIFNOTHUNG|BSF_FORCEIFHUNG), &recips, WM_NULL, 30000, 0, NULL );
215 ok(0, "Last error: %08x\n", GetLastError());
216 ok(0, "Returned: %d\n", ret);
217 }
218
219 recips = BSM_APPLICATIONS;
220 ResetEvent(hevent);
221 ret = broadcastex( BSF_POSTMESSAGE|BSF_QUERY, &recips, WM_NULL, 100, 0, NULL );
222 ok(ret==1, "Returned: %d\n", ret);
223 ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
224 PulseEvent(hevent);
225
226 recips = BSM_APPLICATIONS;
227 ret = broadcastex( BSF_POSTMESSAGE|BSF_SENDNOTIFYMESSAGE, &recips, WM_NULL, 100, 0, NULL );
228 ok(ret==1, "Returned: %d\n", ret);
229 ok(WaitForSingleObject(hevent, 0) != WAIT_OBJECT_0, "Synchronous message sent instead\n");
230 PulseEvent(hevent);
231
232 recips = BSM_APPLICATIONS;
233 ret = broadcastex( BSF_SENDNOTIFYMESSAGE, &recips, WM_NULL, 100, BROADCAST_QUERY_DENY, NULL );
234 ok(ret==1, "Returned: %d\n", ret);
235 ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
236 PulseEvent(hevent);
237
238 recips = BSM_APPLICATIONS;
239 ret = broadcastex( BSF_SENDNOTIFYMESSAGE|BSF_QUERY, &recips, WM_NULL, 100, BROADCAST_QUERY_DENY, NULL );
240 ok(!ret, "Returned: %d\n", ret);
241 ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
242 PulseEvent(hevent);
243
244 recips = BSM_APPLICATIONS;
245 ret = broadcastex( 0, &recips, WM_NULL, 100, 0, NULL );
246 ok(ret==1, "Returned: %d\n", ret);
247 ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
248 PulseEvent(hevent);
249 }
250
251 static void test_noprivileges(void)
252 {
253 HANDLE token;
254 DWORD recips;
255 BOOL ret;
256
257 static const DWORD BSM_ALL_RECIPS = BSM_VXDS | BSM_NETDRIVER |
258 BSM_INSTALLABLEDRIVERS | BSM_APPLICATIONS;
259
260 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token))
261 {
262 skip("Can't open security token for process\n");
263 return;
264 }
265 if (!AdjustTokenPrivileges(token, TRUE, NULL, 0, NULL, NULL))
266 {
267 skip("Can't adjust security token for process\n");
268 return;
269 }
270
271 trace("Trying privileged edition!\n");
272 SetLastError(0xcafebabe);
273 recips = BSM_ALLDESKTOPS;
274 ResetEvent(hevent);
275 ret = BroadcastSystemMessageExW( BSF_QUERY, &recips, WM_NULL, 100, 0, NULL );
276 ok(ret==1, "Returned: %d error %u\n", ret, GetLastError());
277 ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
278 ok(recips == BSM_ALLDESKTOPS ||
279 recips == BSM_ALL_RECIPS, /* win2k3 */
280 "Received by: %08x\n", recips);
281 PulseEvent(hevent);
282
283 SetLastError(0xcafebabe);
284 recips = BSM_ALLCOMPONENTS;
285 ResetEvent(hevent);
286 ret = BroadcastSystemMessageExW( BSF_QUERY, &recips, WM_NULL, 100, 0, NULL );
287 ok(ret==1, "Returned: %d error %u\n", ret, GetLastError());
288 ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
289 ok(recips == BSM_ALLCOMPONENTS ||
290 recips == BSM_ALL_RECIPS, /* win2k3 */
291 "Received by: %08x\n", recips);
292 PulseEvent(hevent);
293
294 SetLastError(0xcafebabe);
295 recips = BSM_ALLDESKTOPS|BSM_APPLICATIONS;
296 ResetEvent(hevent);
297 ret = BroadcastSystemMessageExW( 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|BSM_APPLICATIONS) ||
301 recips == BSM_APPLICATIONS, /* win2k3 */
302 "Received by: %08x\n", recips);
303 PulseEvent(hevent);
304
305 SetLastError(0xcafebabe);
306 recips = BSM_ALLDESKTOPS|BSM_APPLICATIONS;
307 ResetEvent(hevent);
308 ret = BroadcastSystemMessageExW( BSF_QUERY, &recips, WM_NULL, 100, BROADCAST_QUERY_DENY, NULL );
309 ok(!ret, "Returned: %d\n", ret);
310 ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
311 ok(recips == (BSM_ALLDESKTOPS|BSM_APPLICATIONS) ||
312 recips == BSM_APPLICATIONS, /* win2k3 */
313 "Received by: %08x\n", recips);
314 PulseEvent(hevent);
315 }
316
317 START_TEST(broadcast)
318 {
319 if (!init_procs())
320 return;
321
322 trace("Running BroadcastSystemMessageA tests\n");
323 test_parameters(BroadcastSystemMessageA, "BroadcastSystemMessageA");
324
325 trace("Running BroadcastSystemMessageW tests\n");
326 test_parameters(BroadcastSystemMessageW, "BroadcastSystemMessageW");
327
328 trace("Running BroadcastSystemMessageExA tests\n");
329 test_parametersEx(BroadcastSystemMessageExA);
330
331 trace("Running BroadcastSystemMessageExW tests\n");
332 test_parametersEx(BroadcastSystemMessageExW);
333
334 trace("Attempting privileges checking tests\n");
335 test_noprivileges();
336 }