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 #include <assert.h>
22 #include <stdarg.h>
23 #include <stdio.h>
24
25 #define _WIN32_WINNT 0x0501
26
27 #include "windef.h"
28 #include "winbase.h"
29 #include "wingdi.h"
30 #include "winuser.h"
31 #include "winnls.h"
32
33 #include "wine/test.h"
34
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;
42
43 static LRESULT WINAPI main_window_procA(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
44 {
45 if (msg == WM_NULL)
46 {
47 trace("main_window_procA: Sleeping for %lu ms\n", wparam);
48 if (wparam)
49 {
50 if (WaitForSingleObject(hevent, wparam) == WAIT_TIMEOUT)
51 SetEvent(hevent);
52 }
53 trace("main_window_procA: Returning WM_NULL with parameter %08lx\n", lparam);
54 return lparam;
55 }
56
57 return DefWindowProcA(hwnd, msg, wparam, lparam);
58 }
59
60 static BOOL init_procs(void)
61 {
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;
70
71 pBroadcastW = (PBROADCAST)GetProcAddress(user32, "BroadcastSystemMessageW");
72 pBroadcastExA = (PBROADCASTEX)GetProcAddress(user32, "BroadcastSystemMessageExA");
73 pBroadcastExW = (PBROADCASTEX)GetProcAddress(user32, "BroadcastSystemMessageExW");
74
75 hevent = CreateEventA(NULL, TRUE, FALSE, "Asynchronous checking event");
76
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";
87
88 if (!RegisterClassA(&cls))
89 return 0;
90
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;
96 }
97
98 static void test_parameters(PBROADCAST broadcast, const char *functionname)
99 {
100 LONG ret;
101 DWORD recips;
102
103 SetLastError(0xcafebabe);
104 recips = BSM_APPLICATIONS;
105 ret = broadcast( 0x80000000, &recips, WM_NULL, 0, 0 );
106 if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
107 {
108 skip("%s is not implemented\n", functionname);
109 return;
110 }
111 ok(!ret || broken(ret), "Returned: %d\n", ret);
112 if (!ret) ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error: %08x\n", GetLastError());
113
114 SetLastError(0xcafebabe);
115 recips = BSM_APPLICATIONS;
116 ret = broadcast( 0x80000000, &recips, WM_NULL, 0, 0 );
117 ok(!ret || broken(ret), "Returned: %d\n", ret);
118 if (!ret) ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error: %08x\n", GetLastError());
119
120 #if 0 /* TODO: Check the hang flags */
121 SetLastError(0xcafebabe);
122 recips = BSM_APPLICATIONS;
123 ret = broadcast( BSF_QUERY|(BSF_NOHANG|BSF_FORCEIFHUNG), &recips, WM_NULL, 30000, 0 );
124 ok(0, "Last error: %08x\n", GetLastError());
125 ok(0, "Returned: %d\n", ret);
126
127 SetLastError(0xcafebabe);
128 recips = BSM_APPLICATIONS;
129 ret = broadcast( BSF_QUERY|(BSF_NOHANG|BSF_NOTIMEOUTIFNOTHUNG), &recips, WM_NULL, 30000, 0 );
130 ok(0, "Last error: %08x\n", GetLastError());
131 ok(0, "Returned: %d\n", ret);
132
133 SetLastError(0xcafebabe);
134 recips = BSM_APPLICATIONS;
135 ret = broadcast( BSF_QUERY|(BSF_NOTIMEOUTIFNOTHUNG|BSF_FORCEIFHUNG), &recips, WM_NULL, 30000, 0 );
136 ok(0, "Last error: %08x\n", GetLastError());
137 ok(0, "Returned: %d\n", ret);
138
139 SetLastError(0xcafebabe);
140 recips = BSM_APPLICATIONS;
141 ret = broadcast( BSF_POSTMESSAGE|(BSF_NOTIMEOUTIFNOTHUNG|BSF_FORCEIFHUNG), &recips, WM_NULL, 30000, 0 );
142 ok(0, "Last error: %08x\n", GetLastError());
143 ok(0, "Returned: %d\n", ret);
144 #endif
145
146 recips = BSM_APPLICATIONS;
147 ResetEvent(hevent);
148 ret = broadcast( BSF_POSTMESSAGE|BSF_QUERY, &recips, WM_NULL, 100, 0 );
149 ok(ret==1, "Returned: %d\n", ret);
150 ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
151 PulseEvent(hevent);
152
153 recips = BSM_APPLICATIONS;
154 ret = broadcast( BSF_POSTMESSAGE|BSF_SENDNOTIFYMESSAGE, &recips, WM_NULL, 100, 0 );
155 ok(ret==1, "Returned: %d\n", ret);
156 ok(WaitForSingleObject(hevent, 0) != WAIT_OBJECT_0, "Synchronous message sent instead\n");
157 PulseEvent(hevent);
158
159 recips = BSM_APPLICATIONS;
160 ret = broadcast( BSF_SENDNOTIFYMESSAGE, &recips, WM_NULL, 100, BROADCAST_QUERY_DENY );
161 ok(ret==1, "Returned: %d\n", ret);
162 ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
163 PulseEvent(hevent);
164
165 recips = BSM_APPLICATIONS;
166 ret = broadcast( BSF_SENDNOTIFYMESSAGE|BSF_QUERY, &recips, WM_NULL, 100, BROADCAST_QUERY_DENY );
167 ok(!ret, "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( 0, &recips, WM_NULL, 100, 0 );
173 ok(ret==1, "Returned: %d\n", ret);
174 ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
175 PulseEvent(hevent);
176 }
177
178 /* BSF_SENDNOTIFYMESSAGE and BSF_QUERY are both synchronous within the same process
179 * However you should be able to distinguish them by sending the BROADCAST_QUERY_DENY flag
180 */
181
182 static void test_parametersEx(PBROADCASTEX broadcastex)
183 {
184 LONG ret;
185 DWORD recips;
186
187 SetLastError(0xcafebabe);
188 recips = BSM_APPLICATIONS;
189 ret = broadcastex( 0x80000000, &recips, WM_NULL, 0, 0, NULL );
190 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error: %08x\n", GetLastError());
191 ok(!ret, "Returned: %d\n", ret);
192
193 SetLastError(0xcafebabe);
194 recips = BSM_APPLICATIONS;
195 ret = broadcastex( 0x80000000, &recips, WM_NULL, 0, 0, NULL );
196 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error: %08x\n", GetLastError());
197 ok(!ret, "Returned: %d\n", ret);
198
199 #if 0 /* TODO: Check the hang flags */
200 SetLastError(0xcafebabe);
201 recips = BSM_APPLICATIONS;
202 ret = broadcast( BSF_QUERY|(BSF_NOHANG|BSF_FORCEIFHUNG), &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 = broadcast( BSF_QUERY|(BSF_NOHANG|BSF_NOTIMEOUTIFNOTHUNG), &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 = broadcast( BSF_QUERY|(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 SetLastError(0xcafebabe);
219 recips = BSM_APPLICATIONS;
220 ret = broadcast( BSF_POSTMESSAGE|(BSF_NOTIMEOUTIFNOTHUNG|BSF_FORCEIFHUNG), &recips, WM_NULL, 30000, 0, NULL );
221 ok(0, "Last error: %08x\n", GetLastError());
222 ok(0, "Returned: %d\n", ret);
223 #endif
224
225 recips = BSM_APPLICATIONS;
226 ResetEvent(hevent);
227 ret = broadcastex( BSF_POSTMESSAGE|BSF_QUERY, &recips, WM_NULL, 100, 0, NULL );
228 ok(ret==1, "Returned: %d\n", ret);
229 ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
230 PulseEvent(hevent);
231
232 recips = BSM_APPLICATIONS;
233 ret = broadcastex( BSF_POSTMESSAGE|BSF_SENDNOTIFYMESSAGE, &recips, WM_NULL, 100, 0, NULL );
234 ok(ret==1, "Returned: %d\n", ret);
235 ok(WaitForSingleObject(hevent, 0) != WAIT_OBJECT_0, "Synchronous message sent instead\n");
236 PulseEvent(hevent);
237
238 recips = BSM_APPLICATIONS;
239 ret = broadcastex( BSF_SENDNOTIFYMESSAGE, &recips, WM_NULL, 100, BROADCAST_QUERY_DENY, NULL );
240 ok(ret==1, "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( BSF_SENDNOTIFYMESSAGE|BSF_QUERY, &recips, WM_NULL, 100, BROADCAST_QUERY_DENY, NULL );
246 ok(!ret, "Returned: %d\n", ret);
247 ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
248 PulseEvent(hevent);
249
250 recips = BSM_APPLICATIONS;
251 ret = broadcastex( 0, &recips, WM_NULL, 100, 0, NULL );
252 ok(ret==1, "Returned: %d\n", ret);
253 ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
254 PulseEvent(hevent);
255 }
256
257 static BOOL (WINAPI *pOpenProcessToken)(HANDLE, DWORD, HANDLE*);
258 static BOOL (WINAPI *pAdjustTokenPrivileges)(HANDLE, BOOL, PTOKEN_PRIVILEGES, DWORD, PTOKEN_PRIVILEGES, PDWORD);
259
260 static void test_noprivileges(void)
261 {
262 HANDLE advapi32 = GetModuleHandleA("advapi32");
263 HANDLE token;
264 DWORD recips;
265 BOOL ret;
266
267 static const DWORD BSM_ALL_RECIPS = BSM_VXDS | BSM_NETDRIVER |
268 BSM_INSTALLABLEDRIVERS | BSM_APPLICATIONS;
269
270 pOpenProcessToken = (void *)GetProcAddress(advapi32, "OpenProcessToken");
271 pAdjustTokenPrivileges = (void *)GetProcAddress(advapi32, "AdjustTokenPrivileges");
272 if (!pOpenProcessToken || !pAdjustTokenPrivileges || !pOpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token))
273 {
274 skip("Can't open security token for process\n");
275 return;
276 }
277 if (!pAdjustTokenPrivileges(token, TRUE, NULL, 0, NULL, NULL))
278 {
279 skip("Can't adjust security token for process\n");
280 return;
281 }
282
283 trace("Trying privileged edition!\n");
284 SetLastError(0xcafebabe);
285 recips = BSM_ALLDESKTOPS;
286 ResetEvent(hevent);
287 ret = pBroadcastExW( BSF_QUERY, &recips, WM_NULL, 100, 0, NULL );
288 ok(ret==1, "Returned: %d error %u\n", ret, GetLastError());
289 ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
290 ok(recips == BSM_ALLDESKTOPS ||
291 recips == BSM_ALL_RECIPS, /* win2k3 */
292 "Received by: %08x\n", recips);
293 PulseEvent(hevent);
294
295 SetLastError(0xcafebabe);
296 recips = BSM_ALLCOMPONENTS;
297 ResetEvent(hevent);
298 ret = pBroadcastExW( BSF_QUERY, &recips, WM_NULL, 100, 0, NULL );
299 ok(ret==1, "Returned: %d error %u\n", ret, GetLastError());
300 ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
301 ok(recips == BSM_ALLCOMPONENTS ||
302 recips == BSM_ALL_RECIPS, /* win2k3 */
303 "Received by: %08x\n", recips);
304 PulseEvent(hevent);
305
306 SetLastError(0xcafebabe);
307 recips = BSM_ALLDESKTOPS|BSM_APPLICATIONS;
308 ResetEvent(hevent);
309 ret = pBroadcastExW( BSF_QUERY, &recips, WM_NULL, 100, 0, NULL );
310 ok(ret==1, "Returned: %d error %u\n", ret, GetLastError());
311 ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
312 ok(recips == (BSM_ALLDESKTOPS|BSM_APPLICATIONS) ||
313 recips == BSM_APPLICATIONS, /* win2k3 */
314 "Received by: %08x\n", recips);
315 PulseEvent(hevent);
316
317 SetLastError(0xcafebabe);
318 recips = BSM_ALLDESKTOPS|BSM_APPLICATIONS;
319 ResetEvent(hevent);
320 ret = pBroadcastExW( BSF_QUERY, &recips, WM_NULL, 100, BROADCAST_QUERY_DENY, NULL );
321 ok(!ret, "Returned: %d\n", ret);
322 ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
323 ok(recips == (BSM_ALLDESKTOPS|BSM_APPLICATIONS) ||
324 recips == BSM_APPLICATIONS, /* win2k3 */
325 "Received by: %08x\n", recips);
326 PulseEvent(hevent);
327 }
328
329 START_TEST(broadcast)
330 {
331 if (!init_procs())
332 return;
333
334 trace("Running BroadcastSystemMessageA tests\n");
335 test_parameters(pBroadcastA, "BroadcastSystemMessageA");
336 if (pBroadcastW)
337 {
338 trace("Running BroadcastSystemMessageW tests\n");
339 test_parameters(pBroadcastW, "BroadcastSystemMessageW");
340 }
341 else
342 skip("No BroadcastSystemMessageW, skipping\n");
343 if (pBroadcastExA)
344 {
345 trace("Running BroadcastSystemMessageExA tests\n");
346 test_parametersEx(pBroadcastExA);
347 }
348 else
349 skip("No BroadcastSystemMessageExA, skipping\n");
350 if (pBroadcastExW)
351 {
352 trace("Running BroadcastSystemMessageExW tests\n");
353 test_parametersEx(pBroadcastExW);
354 trace("Attempting privileges checking tests\n");
355 test_noprivileges();
356 }
357 else
358 skip("No BroadcastSystemMessageExW, skipping\n");
359 }
360
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.