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
25 #define _WIN32_WINNT 0x0501
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
;
43 static LRESULT WINAPI
main_window_procA(HWND hwnd
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
47 trace("main_window_procA: Sleeping for %lu ms\n", wparam
);
50 if (WaitForSingleObject(hevent
, wparam
) == WAIT_TIMEOUT
)
53 trace("main_window_procA: Returning WM_NULL with parameter %08lx\n", lparam
);
57 return DefWindowProcA(hwnd
, msg
, wparam
, lparam
);
60 static BOOL
init_procs(void)
63 HANDLE user32
= GetModuleHandle("user32");
64 pBroadcastA
= (PBROADCAST
)GetProcAddress(user32
, "BroadcastSystemMessageA");
66 pBroadcastA
= (PBROADCAST
)GetProcAddress(user32
, "BroadcastSystemMessage");
67 ok(pBroadcastA
!= NULL
, "No BroadcastSystemMessage found\n");
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
;
81 cls
.hInstance
= GetModuleHandleA(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
))
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
))
98 static void test_parameters(PBROADCAST broadcast
, const char *functionname
)
103 SetLastError(0xcafebabe);
104 recips
= BSM_APPLICATIONS
;
105 ret
= broadcast( 0x80000000, &recips
, WM_NULL
, 0, 0 );
106 if (!ret
&& GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
)
108 skip("%s is not implemented\n", functionname
);
111 ok(!ret
|| broken(ret
), "Returned: %d\n", ret
);
112 if (!ret
) ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Last error: %08x\n", GetLastError());
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());
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
);
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
);
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
);
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
);
146 recips
= BSM_APPLICATIONS
;
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");
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");
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");
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");
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");
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
182 static void test_parametersEx(PBROADCASTEX broadcastex
)
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
);
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
);
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
);
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
);
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
);
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
);
225 recips
= BSM_APPLICATIONS
;
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");
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");
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");
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");
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");
257 static BOOL (WINAPI
*pOpenProcessToken
)(HANDLE
, DWORD
, HANDLE
*);
258 static BOOL (WINAPI
*pAdjustTokenPrivileges
)(HANDLE
, BOOL
, PTOKEN_PRIVILEGES
, DWORD
, PTOKEN_PRIVILEGES
, PDWORD
);
260 static void test_noprivileges(void)
262 HANDLE advapi32
= GetModuleHandleA("advapi32");
267 static const DWORD BSM_ALL_RECIPS
= BSM_VXDS
| BSM_NETDRIVER
|
268 BSM_INSTALLABLEDRIVERS
| BSM_APPLICATIONS
;
270 pOpenProcessToken
= (void *)GetProcAddress(advapi32
, "OpenProcessToken");
271 pAdjustTokenPrivileges
= (void *)GetProcAddress(advapi32
, "AdjustTokenPrivileges");
272 if (!pOpenProcessToken
|| !pAdjustTokenPrivileges
|| !pOpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES
, &token
))
274 skip("Can't open security token for process\n");
277 if (!pAdjustTokenPrivileges(token
, TRUE
, NULL
, 0, NULL
, NULL
))
279 skip("Can't adjust security token for process\n");
283 trace("Trying privileged edition!\n");
284 SetLastError(0xcafebabe);
285 recips
= BSM_ALLDESKTOPS
;
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
);
295 SetLastError(0xcafebabe);
296 recips
= BSM_ALLCOMPONENTS
;
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
);
306 SetLastError(0xcafebabe);
307 recips
= BSM_ALLDESKTOPS
|BSM_APPLICATIONS
;
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
);
317 SetLastError(0xcafebabe);
318 recips
= BSM_ALLDESKTOPS
|BSM_APPLICATIONS
;
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
);
329 START_TEST(broadcast
)
334 trace("Running BroadcastSystemMessageA tests\n");
335 test_parameters(pBroadcastA
, "BroadcastSystemMessageA");
338 trace("Running BroadcastSystemMessageW tests\n");
339 test_parameters(pBroadcastW
, "BroadcastSystemMessageW");
342 skip("No BroadcastSystemMessageW, skipping\n");
345 trace("Running BroadcastSystemMessageExA tests\n");
346 test_parametersEx(pBroadcastExA
);
349 skip("No BroadcastSystemMessageExA, skipping\n");
352 trace("Running BroadcastSystemMessageExW tests\n");
353 test_parametersEx(pBroadcastExW
);
354 trace("Attempting privileges checking tests\n");
358 skip("No BroadcastSystemMessageExW, skipping\n");