~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/user32/tests/broadcast.c

Version: ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~ [ wine-1.0-rc5 ] ~ [ wine-1.0-rc4 ] ~ [ wine-1.0-rc3 ] ~ [ wine-1.0-rc2 ] ~ [ wine-1.0-rc1 ] ~ [ wine-0.9.61 ] ~ [ wine-0.9.60 ] ~ [ wine-0.9.59 ] ~ [ wine-0.9.58 ] ~ [ wine-0.9.57 ] ~ [ wine-0.9.56 ] ~ [ wine-0.9.55 ] ~ [ wine-0.9.54 ] ~ [ wine-0.9.53 ] ~ [ wine-0.9.52 ] ~ [ wine-0.9.51 ] ~ [ wine-0.9.50 ] ~ [ wine-0.9.49 ] ~ [ wine-0.9.48 ] ~ [ wine-0.9.47 ] ~ [ wine-0.9.46 ] ~ [ wine-0.9.45 ] ~ [ wine-0.9.44 ] ~ [ wine-0.9.43 ] ~ [ wine-0.9.42 ] ~ [ wine-0.9.41 ] ~ [ wine-0.9.40 ] ~ [ wine-0.9.39 ] ~ [ wine-0.9.38 ] ~ [ wine-0.9.37 ] ~ [ wine-0.9.36 ] ~ [ wine-0.9.35 ] ~ [ wine-0.9.34 ] ~ [ wine-0.9.33 ] ~ [ wine-0.9.32 ] ~ [ wine-0.9.31 ] ~ [ wine-0.9.30 ] ~ [ wine-0.9.29 ] ~ [ wine-0.9.28 ] ~ [ wine-0.9.27 ] ~ [ wine-0.9.26 ] ~ [ wine-0.9.25 ] ~ [ wine-0.9.24 ] ~ [ wine-0.9.23 ] ~ [ wine-0.9.22 ] ~ [ wine-0.9.21 ] ~ [ wine-0.9.20 ] ~ [ wine-0.9.19 ] ~ [ wine-0.9.18 ] ~ [ wine-0.9.17 ] ~ [ wine-0.9.16 ] ~ [ wine-0.9.15 ] ~ [ wine-0.9.14 ] ~ [ wine-0.9.13 ] ~ [ wine-0.9.12 ] ~ [ wine-0.9.11 ] ~ [ wine-0.9.10 ] ~ [ wine-0.9.9 ] ~ [ wine-0.9.8 ] ~ [ wine-0.9.7 ] ~ [ wine-0.9.6 ] ~ [ wine-0.9.5 ] ~ [ wine-0.9.4 ] ~ [ wine-0.9.3 ] ~ [ wine-0.9.2 ] ~ [ wine-0.9.1 ] ~ [ wine-0.9 ] ~ [ wine20050930 ] ~ [ wine20050830 ] ~ [ wine20050725 ] ~ [ wine20050628 ] ~ [ wine20050524 ] ~ [ wine20050419 ] ~ [ wine20050310 ] ~ [ wine20050211 ] ~ [ wine20050111 ] ~ [ wine20041201 ] ~ [ wine20041019 ] ~ [ wine20040914 ] ~ [ wine20040813 ] ~ [ wine20040716 ] ~ [ wine20040615 ] ~ [ wine20040505 ] ~ [ wine20040408 ] ~ [ wine20040309 ] ~ [ wine20040213 ] ~ [ wine20040121 ] ~ [ wine20031212 ] ~ [ wine20031118 ] ~ [ wine20031016 ] ~ [ wine20030911 ] ~ [ wine20030813 ] ~ [ wine20030709 ] ~ [ wine20030618 ] ~ [ wine20030508 ] ~ [ wine20030408 ] ~ [ wine20030318 ] ~ [ wine20030219 ] ~ [ wine20030115 ] ~ [ wine20021219 ] ~ [ wine20021125 ] ~ [ wine20021031 ] ~ [ wine20021007 ] ~ [ wine20020904 ] ~ [ wine20020804 ] ~ [ wine20020710 ] ~ [ wine20020605 ] ~ [ wine20020509 ] ~ [ wine20020411 ] ~ [ wine20020310 ] ~ [ wine20020228 ] ~ [ wine20011226 ] ~ [ wine20011108 ] ~ [ wine20011004 ] ~ [ wine20010824 ] ~ [ wine20010731 ] ~ [ wine20010629 ] ~ [ wine20010510 ] ~ [ wine20010418 ] ~ [ wine20010326 ] ~ [ wine20010305 ] ~ [ wine20010216 ] ~ [ wine20010112 ] ~ [ wine20001222 ] ~ [ wine20001202 ] ~ [ wine20001026 ] ~ [ wine20001002 ] ~ [ wine20000909 ] ~ [ wine20000821 ] ~ [ wine20000801 ] ~ [ wine20000716 ] ~ [ wine20000326 ] ~ [ wine20000227 ] ~ [ wine20000130 ] ~ [ wine20000109 ] ~

  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 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.