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