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 #ifndef __REACTOS__ 22 #define _WIN32_WINNT 0x0501 23 #endif 24 25 #include <stdarg.h> 26 #include <stdio.h> 27 28 #include "windef.h" 29 #include "winbase.h" 30 #include "wingdi.h" 31 #include "winuser.h" 32 #include "winnls.h" 33 34 #include "wine/test.h" 35 36 typedef LONG (WINAPI *PBROADCAST)( DWORD,LPDWORD,UINT,WPARAM,LPARAM ); 37 typedef LONG (WINAPI *PBROADCASTEX)( DWORD,LPDWORD,UINT,WPARAM,LPARAM,PBSMINFO ); 38 static HANDLE hevent; 39 40 static LRESULT WINAPI main_window_procA(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) 41 { 42 if (msg == WM_NULL) 43 { 44 trace("main_window_procA: Sleeping for %lu ms\n", wparam); 45 if (wparam) 46 { 47 if (WaitForSingleObject(hevent, wparam) == WAIT_TIMEOUT) 48 SetEvent(hevent); 49 } 50 trace("main_window_procA: Returning WM_NULL with parameter %08lx\n", lparam); 51 return lparam; 52 } 53 54 return DefWindowProcA(hwnd, msg, wparam, lparam); 55 } 56 57 static BOOL init_procs(void) 58 { 59 WNDCLASSA cls; 60 61 hevent = CreateEventA(NULL, TRUE, FALSE, "Asynchronous checking event"); 62 63 cls.style = CS_DBLCLKS; 64 cls.lpfnWndProc = main_window_procA; 65 cls.cbClsExtra = 0; 66 cls.cbWndExtra = 0; 67 cls.hInstance = GetModuleHandleA(0); 68 cls.hIcon = 0; 69 cls.hCursor = LoadCursorA(0, (LPCSTR)IDC_ARROW); 70 cls.hbrBackground = GetStockObject(WHITE_BRUSH); 71 cls.lpszMenuName = NULL; 72 cls.lpszClassName = "MainWindowClass"; 73 74 if (!RegisterClassA(&cls)) 75 return FALSE; 76 77 if (!CreateWindowExA(0, "MainWindowClass", "Main window", WS_CAPTION | WS_SYSMENU | 78 WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP, 100, 100, 200, 79 200, 0, 0, GetModuleHandleA(NULL), NULL)) 80 return FALSE; 81 return TRUE; 82 } 83 84 static void test_parameters(PBROADCAST broadcast, const char *functionname) 85 { 86 LONG ret; 87 DWORD recips; 88 89 SetLastError(0xcafebabe); 90 recips = BSM_APPLICATIONS; 91 ret = broadcast( 0x80000000, &recips, WM_NULL, 0, 0 ); 92 if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) 93 { 94 win_skip("%s is not implemented\n", functionname); 95 return; 96 } 97 ok(!ret || broken(ret), "Returned: %d\n", ret); 98 if (!ret) ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error: %08x\n", GetLastError()); 99 100 SetLastError(0xcafebabe); 101 recips = BSM_APPLICATIONS; 102 ret = broadcast( 0x80000000, &recips, WM_NULL, 0, 0 ); 103 ok(!ret || broken(ret), "Returned: %d\n", ret); 104 if (!ret) ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error: %08x\n", GetLastError()); 105 106 if (0) /* TODO: Check the hang flags */ 107 { 108 SetLastError(0xcafebabe); 109 recips = BSM_APPLICATIONS; 110 ret = broadcast( BSF_QUERY|(BSF_NOHANG|BSF_FORCEIFHUNG), &recips, WM_NULL, 30000, 0 ); 111 ok(0, "Last error: %08x\n", GetLastError()); 112 ok(0, "Returned: %d\n", ret); 113 114 SetLastError(0xcafebabe); 115 recips = BSM_APPLICATIONS; 116 ret = broadcast( BSF_QUERY|(BSF_NOHANG|BSF_NOTIMEOUTIFNOTHUNG), &recips, WM_NULL, 30000, 0 ); 117 ok(0, "Last error: %08x\n", GetLastError()); 118 ok(0, "Returned: %d\n", ret); 119 120 SetLastError(0xcafebabe); 121 recips = BSM_APPLICATIONS; 122 ret = broadcast( BSF_QUERY|(BSF_NOTIMEOUTIFNOTHUNG|BSF_FORCEIFHUNG), &recips, WM_NULL, 30000, 0 ); 123 ok(0, "Last error: %08x\n", GetLastError()); 124 ok(0, "Returned: %d\n", ret); 125 126 SetLastError(0xcafebabe); 127 recips = BSM_APPLICATIONS; 128 ret = broadcast( BSF_POSTMESSAGE|(BSF_NOTIMEOUTIFNOTHUNG|BSF_FORCEIFHUNG), &recips, WM_NULL, 30000, 0 ); 129 ok(0, "Last error: %08x\n", GetLastError()); 130 ok(0, "Returned: %d\n", ret); 131 } 132 133 SetLastError( 0xdeadbeef ); 134 recips = BSM_APPLICATIONS; 135 ret = broadcast( BSF_POSTMESSAGE|BSF_SENDNOTIFYMESSAGE, &recips, WM_NULL, 100, 0 ); 136 ok(ret==1, "Returned: %d\n", ret); 137 ok(WaitForSingleObject(hevent, 0) != WAIT_OBJECT_0, "Synchronous message sent instead\n"); 138 PulseEvent(hevent); 139 140 recips = BSM_APPLICATIONS; 141 ret = broadcast( BSF_SENDNOTIFYMESSAGE, &recips, WM_NULL, 100, BROADCAST_QUERY_DENY ); 142 ok(ret==1, "Returned: %d\n", ret); 143 ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n"); 144 PulseEvent(hevent); 145 } 146 147 /* BSF_SENDNOTIFYMESSAGE and BSF_QUERY are both synchronous within the same process 148 * However you should be able to distinguish them by sending the BROADCAST_QUERY_DENY flag 149 */ 150 151 static void test_parametersEx(PBROADCASTEX broadcastex) 152 { 153 LONG ret; 154 DWORD recips; 155 156 SetLastError(0xcafebabe); 157 recips = BSM_APPLICATIONS; 158 ret = broadcastex( 0x80000000, &recips, WM_NULL, 0, 0, NULL ); 159 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error: %08x\n", GetLastError()); 160 ok(!ret, "Returned: %d\n", ret); 161 162 SetLastError(0xcafebabe); 163 recips = BSM_APPLICATIONS; 164 ret = broadcastex( 0x80000000, &recips, WM_NULL, 0, 0, NULL ); 165 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error: %08x\n", GetLastError()); 166 ok(!ret, "Returned: %d\n", ret); 167 168 if (0) /* TODO: Check the hang flags */ 169 { 170 SetLastError(0xcafebabe); 171 recips = BSM_APPLICATIONS; 172 ret = broadcastex( BSF_QUERY|(BSF_NOHANG|BSF_FORCEIFHUNG), &recips, WM_NULL, 30000, 0, NULL ); 173 ok(0, "Last error: %08x\n", GetLastError()); 174 ok(0, "Returned: %d\n", ret); 175 176 SetLastError(0xcafebabe); 177 recips = BSM_APPLICATIONS; 178 ret = broadcastex( BSF_QUERY|(BSF_NOHANG|BSF_NOTIMEOUTIFNOTHUNG), &recips, WM_NULL, 30000, 0, NULL ); 179 ok(0, "Last error: %08x\n", GetLastError()); 180 ok(0, "Returned: %d\n", ret); 181 182 SetLastError(0xcafebabe); 183 recips = BSM_APPLICATIONS; 184 ret = broadcastex( BSF_QUERY|(BSF_NOTIMEOUTIFNOTHUNG|BSF_FORCEIFHUNG), &recips, WM_NULL, 30000, 0, NULL ); 185 ok(0, "Last error: %08x\n", GetLastError()); 186 ok(0, "Returned: %d\n", ret); 187 188 SetLastError(0xcafebabe); 189 recips = BSM_APPLICATIONS; 190 ret = broadcastex( BSF_POSTMESSAGE|(BSF_NOTIMEOUTIFNOTHUNG|BSF_FORCEIFHUNG), &recips, WM_NULL, 30000, 0, NULL ); 191 ok(0, "Last error: %08x\n", GetLastError()); 192 ok(0, "Returned: %d\n", ret); 193 } 194 195 recips = BSM_APPLICATIONS; 196 ret = broadcastex( BSF_POSTMESSAGE|BSF_SENDNOTIFYMESSAGE, &recips, WM_NULL, 100, 0, NULL ); 197 ok(ret==1, "Returned: %d\n", ret); 198 ok(WaitForSingleObject(hevent, 0) != WAIT_OBJECT_0, "Synchronous message sent instead\n"); 199 PulseEvent(hevent); 200 201 recips = BSM_APPLICATIONS; 202 ret = broadcastex( BSF_SENDNOTIFYMESSAGE, &recips, WM_NULL, 100, BROADCAST_QUERY_DENY, NULL ); 203 ok(ret==1, "Returned: %d\n", ret); 204 ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n"); 205 PulseEvent(hevent); 206 } 207 208 START_TEST(broadcast) 209 { 210 if (!init_procs()) 211 return; 212 213 trace("Running BroadcastSystemMessageA tests\n"); 214 test_parameters(BroadcastSystemMessageA, "BroadcastSystemMessageA"); 215 216 trace("Running BroadcastSystemMessageW tests\n"); 217 test_parameters(BroadcastSystemMessageW, "BroadcastSystemMessageW"); 218 219 trace("Running BroadcastSystemMessageExA tests\n"); 220 test_parametersEx(BroadcastSystemMessageExA); 221 222 trace("Running BroadcastSystemMessageExW tests\n"); 223 test_parametersEx(BroadcastSystemMessageExW); 224 } 225