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
)
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
);
141 recips
= BSM_APPLICATIONS
;
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");
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");
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");
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");
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");
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
)
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
);
220 recips
= BSM_APPLICATIONS
;
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");
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");
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");
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");
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");
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");
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");
269 if (!pAdjustTokenPrivileges(token
, TRUE
, NULL
, 0, NULL
, NULL
))
271 skip("Can't adjust security token for process\n");
275 trace("Trying privileged edition!\n");
276 SetLastError(0xcafebabe);
277 recips
= BSM_ALLDESKTOPS
;
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
);
286 /* Wine sets last error to 0, so just use that one as token here so it doesn't fail */
288 recips
= BSM_ALLCOMPONENTS
;
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
);
297 SetLastError(0xcafebabe);
298 recips
= BSM_ALLDESKTOPS
|BSM_APPLICATIONS
;
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
);
307 SetLastError(0xcafebabe);
308 recips
= BSM_ALLDESKTOPS
|BSM_APPLICATIONS
;
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
);
318 START_TEST(broadcast
)
323 trace("Running BroadcastSystemMessageA tests\n");
324 test_parameters(pBroadcastA
);
327 trace("Running BroadcastSystemMessageW tests\n");
328 test_parameters(pBroadcastW
);
331 skip("No BroadcastSystemMessageW, skipping\n");
334 trace("Running BroadcastSystemMessageExA tests\n");
335 test_parametersEx(pBroadcastExA
);
338 skip("No BroadcastSystemMessageExA, skipping\n");
341 trace("Running BroadcastSystemMessageExW tests\n");
342 test_parametersEx(pBroadcastExW
);
343 trace("Attempting privileges checking tests\n");
347 skip("No BroadcastSystemMessageExW, skipping\n");