user32: Implement BroadcastSystemMessage.
[wine.git] / dlls / user32 / tests / broadcast.c
blob5806ed99e98912dd630f107d9adb40f3516d6f36
1 /*
2 * Unit tests for BroadcastSystemMessage
4 * Copyright 2008 Maarten Lankhorst
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.
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.
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
21 #include <assert.h>
22 #include <stdarg.h>
23 #include <stdio.h>
25 #define _WIN32_WINNT 0x0501
27 #include "windef.h"
28 #include "winbase.h"
29 #include "wingdi.h"
30 #include "winuser.h"
31 #include "winnls.h"
33 #include "wine/test.h"
35 typedef LONG WINAPI (*PBROADCAST)( DWORD,LPDWORD,UINT,WPARAM,LPARAM );
36 typedef LONG WINAPI (*PBROADCASTEX)( DWORD,LPDWORD,UINT,WPARAM,LPARAM,PBSMINFO );
37 static PBROADCAST pBroadcastA;
38 static PBROADCAST pBroadcastW;
39 static PBROADCASTEX pBroadcastExA;
40 static PBROADCASTEX pBroadcastExW;
41 static HANDLE hevent;
43 static LRESULT WINAPI main_window_procA(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
45 if (msg == WM_NULL)
47 trace("main_window_procA: Sleeping for %lu ms\n", wparam);
48 if (wparam)
50 if (WaitForSingleObject(hevent, wparam) == WAIT_TIMEOUT)
51 SetEvent(hevent);
53 trace("main_window_procA: Returning WM_NULL with parameter %08lx\n", lparam);
54 return lparam;
57 return DefWindowProcA(hwnd, msg, wparam, lparam);
60 static BOOL init_procs(void)
62 WNDCLASSA cls;
63 HANDLE user32 = GetModuleHandle("user32");
64 pBroadcastA = (PBROADCAST)GetProcAddress(user32, "BroadcastSystemMessageA");
65 if (!pBroadcastA)
66 pBroadcastA = (PBROADCAST)GetProcAddress(user32, "BroadcastSystemMessage");
67 ok(pBroadcastA != NULL, "No BroadcastSystemMessage found\n");
68 if (!pBroadcastA)
69 return FALSE;
71 pBroadcastW = (PBROADCAST)GetProcAddress(user32, "BroadcastSystemMessageW");
72 pBroadcastExA = (PBROADCASTEX)GetProcAddress(user32, "BroadcastSystemMessageExA");
73 pBroadcastExW = (PBROADCASTEX)GetProcAddress(user32, "BroadcastSystemMessageExW");
75 hevent = CreateEventA(NULL, TRUE, FALSE, "Asynchronous checking event");
77 cls.style = CS_DBLCLKS;
78 cls.lpfnWndProc = main_window_procA;
79 cls.cbClsExtra = 0;
80 cls.cbWndExtra = 0;
81 cls.hInstance = GetModuleHandleA(0);
82 cls.hIcon = 0;
83 cls.hCursor = LoadCursorA(0, (LPSTR)IDC_ARROW);
84 cls.hbrBackground = GetStockObject(WHITE_BRUSH);
85 cls.lpszMenuName = NULL;
86 cls.lpszClassName = "MainWindowClass";
88 if (!RegisterClassA(&cls))
89 return 0;
91 if (!CreateWindowExA(0, "MainWindowClass", "Main window", WS_CAPTION | WS_SYSMENU |
92 WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP, 100, 100, 200,
93 200, 0, 0, GetModuleHandle(0), NULL))
94 return FALSE;
95 return TRUE;
98 static void test_parameters(PBROADCAST broadcast)
100 LONG ret;
101 DWORD recips;
103 SetLastError(0xcafebabe);
104 recips = BSM_APPLICATIONS;
105 ret = broadcast( 0x80000000, &recips, WM_NULL, 0, 0 );
106 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error: %08x\n", GetLastError());
107 ok(!ret, "Returned: %d\n", ret);
109 SetLastError(0xcafebabe);
110 recips = BSM_APPLICATIONS;
111 ret = broadcast( 0x80000000, &recips, WM_NULL, 0, 0 );
112 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error: %08x\n", GetLastError());
113 ok(!ret, "Returned: %d\n", ret);
115 #if 0 /* TODO: Check the hang flags */
116 SetLastError(0xcafebabe);
117 recips = BSM_APPLICATIONS;
118 ret = broadcast( BSF_QUERY|(BSF_NOHANG|BSF_FORCEIFHUNG), &recips, WM_NULL, 30000, 0 );
119 ok(0, "Last error: %08x\n", GetLastError());
120 ok(0, "Returned: %d\n", ret);
122 SetLastError(0xcafebabe);
123 recips = BSM_APPLICATIONS;
124 ret = broadcast( BSF_QUERY|(BSF_NOHANG|BSF_NOTIMEOUTIFNOTHUNG), &recips, WM_NULL, 30000, 0 );
125 ok(0, "Last error: %08x\n", GetLastError());
126 ok(0, "Returned: %d\n", ret);
128 SetLastError(0xcafebabe);
129 recips = BSM_APPLICATIONS;
130 ret = broadcast( BSF_QUERY|(BSF_NOTIMEOUTIFNOTHUNG|BSF_FORCEIFHUNG), &recips, WM_NULL, 30000, 0 );
131 ok(0, "Last error: %08x\n", GetLastError());
132 ok(0, "Returned: %d\n", ret);
134 SetLastError(0xcafebabe);
135 recips = BSM_APPLICATIONS;
136 ret = broadcast( BSF_POSTMESSAGE|(BSF_NOTIMEOUTIFNOTHUNG|BSF_FORCEIFHUNG), &recips, WM_NULL, 30000, 0 );
137 ok(0, "Last error: %08x\n", GetLastError());
138 ok(0, "Returned: %d\n", ret);
139 #endif
141 recips = BSM_APPLICATIONS;
142 ResetEvent(hevent);
143 ret = broadcast( BSF_POSTMESSAGE|BSF_QUERY, &recips, WM_NULL, 100, 0 );
144 ok(ret==1, "Returned: %d\n", ret);
145 ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
146 PulseEvent(hevent);
148 recips = BSM_APPLICATIONS;
149 ret = broadcast( BSF_POSTMESSAGE|BSF_SENDNOTIFYMESSAGE, &recips, WM_NULL, 100, 0 );
150 ok(ret==1, "Returned: %d\n", ret);
151 ok(WaitForSingleObject(hevent, 0) != WAIT_OBJECT_0, "Synchronous message sent instead\n");
152 PulseEvent(hevent);
154 recips = BSM_APPLICATIONS;
155 ret = broadcast( BSF_SENDNOTIFYMESSAGE, &recips, WM_NULL, 100, BROADCAST_QUERY_DENY );
156 ok(ret==1, "Returned: %d\n", ret);
157 ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
158 PulseEvent(hevent);
160 recips = BSM_APPLICATIONS;
161 ret = broadcast( BSF_SENDNOTIFYMESSAGE|BSF_QUERY, &recips, WM_NULL, 100, BROADCAST_QUERY_DENY );
162 ok(!ret, "Returned: %d\n", ret);
163 ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
164 PulseEvent(hevent);
166 recips = BSM_APPLICATIONS;
167 ret = broadcast( 0, &recips, WM_NULL, 100, 0 );
168 ok(ret==1, "Returned: %d\n", ret);
169 ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
170 PulseEvent(hevent);
173 /* BSF_SENDNOTIFYMESSAGE and BSF_QUERY are both synchronous within the same process
174 * However you should be able to distinguish them by sending the BROADCAST_QUERY_DENY flag
177 static void test_parametersEx(PBROADCASTEX broadcastex)
179 LONG ret;
180 DWORD recips;
182 SetLastError(0xcafebabe);
183 recips = BSM_APPLICATIONS;
184 ret = broadcastex( 0x80000000, &recips, WM_NULL, 0, 0, NULL );
185 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error: %08x\n", GetLastError());
186 ok(!ret, "Returned: %d\n", ret);
188 SetLastError(0xcafebabe);
189 recips = BSM_APPLICATIONS;
190 ret = broadcastex( 0x80000000, &recips, WM_NULL, 0, 0, NULL );
191 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error: %08x\n", GetLastError());
192 ok(!ret, "Returned: %d\n", ret);
194 #if 0 /* TODO: Check the hang flags */
195 SetLastError(0xcafebabe);
196 recips = BSM_APPLICATIONS;
197 ret = broadcast( BSF_QUERY|(BSF_NOHANG|BSF_FORCEIFHUNG), &recips, WM_NULL, 30000, 0, NULL );
198 ok(0, "Last error: %08x\n", GetLastError());
199 ok(0, "Returned: %d\n", ret);
201 SetLastError(0xcafebabe);
202 recips = BSM_APPLICATIONS;
203 ret = broadcast( BSF_QUERY|(BSF_NOHANG|BSF_NOTIMEOUTIFNOTHUNG), &recips, WM_NULL, 30000, 0, NULL );
204 ok(0, "Last error: %08x\n", GetLastError());
205 ok(0, "Returned: %d\n", ret);
207 SetLastError(0xcafebabe);
208 recips = BSM_APPLICATIONS;
209 ret = broadcast( BSF_QUERY|(BSF_NOTIMEOUTIFNOTHUNG|BSF_FORCEIFHUNG), &recips, WM_NULL, 30000, 0, NULL );
210 ok(0, "Last error: %08x\n", GetLastError());
211 ok(0, "Returned: %d\n", ret);
213 SetLastError(0xcafebabe);
214 recips = BSM_APPLICATIONS;
215 ret = broadcast( BSF_POSTMESSAGE|(BSF_NOTIMEOUTIFNOTHUNG|BSF_FORCEIFHUNG), &recips, WM_NULL, 30000, 0, NULL );
216 ok(0, "Last error: %08x\n", GetLastError());
217 ok(0, "Returned: %d\n", ret);
218 #endif
220 recips = BSM_APPLICATIONS;
221 ResetEvent(hevent);
222 ret = broadcastex( BSF_POSTMESSAGE|BSF_QUERY, &recips, WM_NULL, 100, 0, NULL );
223 ok(ret==1, "Returned: %d\n", ret);
224 ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
225 PulseEvent(hevent);
227 recips = BSM_APPLICATIONS;
228 ret = broadcastex( BSF_POSTMESSAGE|BSF_SENDNOTIFYMESSAGE, &recips, WM_NULL, 100, 0, NULL );
229 ok(ret==1, "Returned: %d\n", ret);
230 ok(WaitForSingleObject(hevent, 0) != WAIT_OBJECT_0, "Synchronous message sent instead\n");
231 PulseEvent(hevent);
233 recips = BSM_APPLICATIONS;
234 ret = broadcastex( BSF_SENDNOTIFYMESSAGE, &recips, WM_NULL, 100, BROADCAST_QUERY_DENY, NULL );
235 ok(ret==1, "Returned: %d\n", ret);
236 ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
237 PulseEvent(hevent);
239 recips = BSM_APPLICATIONS;
240 ret = broadcastex( BSF_SENDNOTIFYMESSAGE|BSF_QUERY, &recips, WM_NULL, 100, BROADCAST_QUERY_DENY, NULL );
241 ok(!ret, "Returned: %d\n", ret);
242 ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
243 PulseEvent(hevent);
245 recips = BSM_APPLICATIONS;
246 ret = broadcastex( 0, &recips, WM_NULL, 100, 0, NULL );
247 ok(ret==1, "Returned: %d\n", ret);
248 ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
249 PulseEvent(hevent);
252 static BOOL WINAPI (*pOpenProcessToken)(HANDLE, DWORD, HANDLE*);
253 static BOOL WINAPI (*pAdjustTokenPrivileges)(HANDLE, BOOL, PTOKEN_PRIVILEGES, DWORD, PTOKEN_PRIVILEGES, PDWORD);
255 static void test_noprivileges(void)
257 HANDLE advapi32 = GetModuleHandleA("advapi32");
258 HANDLE token;
259 DWORD recips;
260 BOOL ret;
262 pOpenProcessToken = (void *)GetProcAddress(advapi32, "OpenProcessToken");
263 pAdjustTokenPrivileges = (void *)GetProcAddress(advapi32, "AdjustTokenPrivileges");
264 if (!pOpenProcessToken || !pAdjustTokenPrivileges || !pOpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token))
266 skip("Can't open security token for process\n");
267 return;
269 if (!pAdjustTokenPrivileges(token, TRUE, NULL, 0, NULL, NULL))
271 skip("Can't adjust security token for process\n");
272 return;
275 trace("Trying privileged edition!\n");
276 SetLastError(0xcafebabe);
277 recips = BSM_ALLDESKTOPS;
278 ResetEvent(hevent);
279 ret = pBroadcastExW( BSF_QUERY, &recips, WM_NULL, 100, 0, NULL );
280 todo_wine ok(GetLastError() == ERROR_PRIVILEGE_NOT_HELD, "Last error: %08x\n", GetLastError());
281 ok(ret==1, "Returned: %d\n", ret);
282 ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
283 ok(recips == BSM_ALLDESKTOPS, "Received by: %08x\n", recips);
284 PulseEvent(hevent);
286 /* Wine sets last error to 0, so just use that one as token here so it doesn't fail */
287 SetLastError(0);
288 recips = BSM_ALLCOMPONENTS;
289 ResetEvent(hevent);
290 ret = pBroadcastExW( BSF_QUERY, &recips, WM_NULL, 100, 0, NULL );
291 ok(!GetLastError(), "Last error: %08x\n", GetLastError());
292 ok(ret==1, "Returned: %d\n", ret);
293 ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
294 ok(recips == BSM_ALLCOMPONENTS, "Received by: %08x\n", recips);
295 PulseEvent(hevent);
297 SetLastError(0xcafebabe);
298 recips = BSM_ALLDESKTOPS|BSM_APPLICATIONS;
299 ResetEvent(hevent);
300 ret = pBroadcastExW( BSF_QUERY, &recips, WM_NULL, 100, 0, NULL );
301 todo_wine ok(GetLastError() == ERROR_PRIVILEGE_NOT_HELD, "Last error: %08x\n", GetLastError());
302 ok(ret==1, "Returned: %d\n", ret);
303 ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
304 ok(recips == (BSM_ALLDESKTOPS|BSM_APPLICATIONS), "Received by: %08x\n", recips);
305 PulseEvent(hevent);
307 SetLastError(0xcafebabe);
308 recips = BSM_ALLDESKTOPS|BSM_APPLICATIONS;
309 ResetEvent(hevent);
310 ret = pBroadcastExW( BSF_QUERY, &recips, WM_NULL, 100, BROADCAST_QUERY_DENY, NULL );
311 todo_wine ok(GetLastError() == ERROR_PRIVILEGE_NOT_HELD, "Last error: %08x\n", GetLastError());
312 ok(!ret, "Returned: %d\n", ret);
313 ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
314 ok(recips == (BSM_ALLDESKTOPS|BSM_APPLICATIONS), "Received by: %08x\n", recips);
315 PulseEvent(hevent);
318 START_TEST(broadcast)
320 if (!init_procs())
321 return;
323 trace("Running BroadcastSystemMessageA tests\n");
324 test_parameters(pBroadcastA);
325 if (pBroadcastW)
327 trace("Running BroadcastSystemMessageW tests\n");
328 test_parameters(pBroadcastW);
330 else
331 skip("No BroadcastSystemMessageW, skipping\n");
332 if (pBroadcastExA)
334 trace("Running BroadcastSystemMessageExA tests\n");
335 test_parametersEx(pBroadcastExA);
337 else
338 skip("No BroadcastSystemMessageExA, skipping\n");
339 if (pBroadcastExW)
341 trace("Running BroadcastSystemMessageExW tests\n");
342 test_parametersEx(pBroadcastExW);
343 trace("Attempting privileges checking tests\n");
344 test_noprivileges();
346 else
347 skip("No BroadcastSystemMessageExW, skipping\n");