ReactOS 0.4.15-dev-8096-ga0eec98
winstation.c
Go to the documentation of this file.
1/*
2 * Unit tests for window stations and desktops
3 *
4 * Copyright 2002 Alexandre Julliard
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 "wine/test.h"
22#include "winbase.h"
23#include "wingdi.h"
24#include "winuser.h"
25#include "winnls.h"
26#include "wine/winternl.h"
27
29
30#define DESKTOP_ALL_ACCESS 0x01ff
31
32static void print_object( HANDLE obj )
33{
34 char buffer[100];
35 DWORD size;
36
37 strcpy( buffer, "foobar" );
39 trace( "could not get info for %p\n", obj );
40 else
41 trace( "obj %p name '%s'\n", obj, buffer );
42 strcpy( buffer, "foobar" );
44 trace( "could not get type for %p\n", obj );
45 else
46 trace( "obj %p type '%s'\n", obj, buffer );
47}
48
49static void register_class(void)
50{
51 WNDCLASSA cls;
52
53 cls.style = CS_DBLCLKS;
55 cls.cbClsExtra = 0;
56 cls.cbWndExtra = 0;
58 cls.hIcon = 0;
61 cls.lpszMenuName = NULL;
62 cls.lpszClassName = "WinStationClass";
63 RegisterClassA(&cls);
64}
65
66static HDESK initial_desktop;
67
69{
70 HDESK d1, d2;
71 HWND hwnd = CreateWindowExA(0,"WinStationClass","test",WS_POPUP,0,0,100,100,GetDesktopWindow(),0,0,0);
72 ok( hwnd != 0, "CreateWindow failed\n" );
74 trace( "thread %p desktop: %p\n", arg, d1 );
75 ok( d1 == initial_desktop, "thread %p doesn't use initial desktop\n", arg );
76
77 SetLastError( 0xdeadbeef );
78 ok( !CloseHandle( d1 ), "CloseHandle succeeded\n" );
79 ok( GetLastError() == ERROR_INVALID_HANDLE, "bad last error %d\n", GetLastError() );
80 SetLastError( 0xdeadbeef );
81 ok( !CloseDesktop( d1 ), "CloseDesktop succeeded\n" );
82 ok( GetLastError() == ERROR_BUSY || broken(GetLastError() == 0xdeadbeef), /* wow64 */
83 "bad last error %d\n", GetLastError() );
84 print_object( d1 );
85 d2 = CreateDesktopA( "foobar2", NULL, NULL, 0, DESKTOP_ALL_ACCESS, NULL );
86 trace( "created desktop %p\n", d2 );
87 ok( d2 != 0, "CreateDesktop failed\n" );
88
89 SetLastError( 0xdeadbeef );
90 ok( !SetThreadDesktop( d2 ), "set thread desktop succeeded with existing window\n" );
91 ok( GetLastError() == ERROR_BUSY || broken(GetLastError() == 0xdeadbeef), /* wow64 */
92 "bad last error %d\n", GetLastError() );
93
95 ok( SetThreadDesktop( d2 ), "set thread desktop failed\n" );
97 ok( d1 == d2, "GetThreadDesktop did not return set desktop %p/%p\n", d1, d2 );
98 print_object( d2 );
99 if (arg < (LPVOID)5)
100 {
101 HANDLE hthread = CreateThread( NULL, 0, thread, (char *)arg + 1, 0, NULL );
102 Sleep(1000);
103 WaitForSingleObject( hthread, INFINITE );
104 CloseHandle( hthread );
105 }
106 return 0;
107}
108
109static void test_handles(void)
110{
111 HWINSTA w1, w2, w3;
112 HDESK d1, d2, d3;
113 HANDLE hthread;
114 DWORD id, flags, le;
115 ATOM atom;
116 char buffer[20];
117 DWORD size;
118 BOOL ret;
119
120 /* win stations */
121
123 ok( GetProcessWindowStation() == w1, "GetProcessWindowStation returned different handles\n" );
124 ok( !CloseWindowStation(w1), "closing process win station succeeded\n" );
125 SetLastError( 0xdeadbeef );
126 ok( !CloseHandle(w1), "closing process win station handle succeeded\n" );
127 ok( GetLastError() == ERROR_INVALID_HANDLE, "bad last error %d\n", GetLastError() );
128 print_object( w1 );
129
130 flags = 0;
131 ok( GetHandleInformation( w1, &flags ), "GetHandleInformation failed\n" );
133 broken(flags & HANDLE_FLAG_PROTECT_FROM_CLOSE), /* set on nt4 */
134 "handle %p PROTECT_FROM_CLOSE set\n", w1 );
135
137 TRUE, DUPLICATE_SAME_ACCESS ), "DuplicateHandle failed\n" );
138 ok( CloseWindowStation(w2), "closing dup win station failed\n" );
139
141 TRUE, DUPLICATE_SAME_ACCESS ), "DuplicateHandle failed\n" );
142 ok( CloseHandle(w2), "closing dup win station handle failed\n" );
143
145 le = GetLastError();
146 ok( w2 != 0 || le == ERROR_ACCESS_DENIED, "CreateWindowStation failed (%u)\n", le );
147 if (w2 != 0)
148 {
149 ok( w2 != w1, "CreateWindowStation returned default handle\n" );
150 SetLastError( 0xdeadbeef );
151 ok( !CloseDesktop( (HDESK)w2 ), "CloseDesktop succeeded on win station\n" );
152 ok( GetLastError() == ERROR_INVALID_HANDLE || broken(GetLastError() == 0xdeadbeef), /* wow64 */
153 "bad last error %d\n", GetLastError() );
154 ok( CloseWindowStation( w2 ), "CloseWindowStation failed\n" );
155
157 ok( CloseHandle( w2 ), "CloseHandle failed\n" );
158 }
159 else if (le == ERROR_ACCESS_DENIED)
160 win_skip( "Not enough privileges for CreateWindowStation\n" );
161
163 ok( w2 != 0, "OpenWindowStation failed\n" );
164 ok( w2 != w1, "OpenWindowStation returned default handle\n" );
165 ok( CloseWindowStation( w2 ), "CloseWindowStation failed\n" );
166
167 w2 = OpenWindowStationA("dummy name", TRUE, WINSTA_ALL_ACCESS );
168 ok( !w2, "open dummy win station succeeded\n" );
169
170 CreateMutexA( NULL, 0, "foobar" );
172 le = GetLastError();
173 ok( w2 != 0 || le == ERROR_ACCESS_DENIED, "create foobar station failed (%u)\n", le );
174
175 if (w2 != 0)
176 {
177 w3 = OpenWindowStationA("foobar", TRUE, WINSTA_ALL_ACCESS );
178 ok( w3 != 0, "open foobar station failed\n" );
179 ok( w3 != w2, "open foobar station returned same handle\n" );
180 ok( CloseWindowStation( w2 ), "CloseWindowStation failed\n" );
181 ok( CloseWindowStation( w3 ), "CloseWindowStation failed\n" );
182
183 w3 = OpenWindowStationA("foobar", TRUE, WINSTA_ALL_ACCESS );
184 ok( !w3, "open foobar station succeeded\n" );
185
187 ok( w2 != 0, "create foobar station failed\n" );
188 w3 = CreateWindowStationA("foobar2", 0, WINSTA_ALL_ACCESS, NULL );
189 ok( w3 != 0, "create foobar station failed\n" );
190 ok( GetHandleInformation( w2, &flags ), "GetHandleInformation failed\n" );
191 ok( GetHandleInformation( w3, &flags ), "GetHandleInformation failed\n" );
192
194 atom = GlobalAddAtomA("foo");
195 ok( GlobalGetAtomNameA( atom, buffer, sizeof(buffer) ) == 3, "GlobalGetAtomName failed\n" );
196 ok( !lstrcmpiA( buffer, "foo" ), "bad atom value %s\n", buffer );
197
198 ok( !CloseWindowStation( w2 ), "CloseWindowStation succeeded\n" );
199 ok( GetHandleInformation( w2, &flags ), "GetHandleInformation failed\n" );
200
202 ok( GetHandleInformation( w2, &flags ), "GetHandleInformation failed\n" );
203 ok( CloseWindowStation( w2 ), "CloseWindowStation failed\n" );
204 ok( GlobalGetAtomNameA( atom, buffer, sizeof(buffer) ) == 3, "GlobalGetAtomName failed\n" );
205 ok( !lstrcmpiA( buffer, "foo" ), "bad atom value %s\n", buffer );
206 }
207 else if (le == ERROR_ACCESS_DENIED)
208 win_skip( "Not enough privileges for CreateWindowStation\n" );
209
210 SetLastError( 0xdeadbeef );
212 ok( !w2, "open station succeeded\n" );
214 ok( GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError() );
215
216 SetLastError( 0xdeadbeef );
218 ok( w2 != 0, "create station failed err %u\n", GetLastError() );
219
220 memset( buffer, 0, sizeof(buffer) );
222 ok( ret, "GetUserObjectInformationA failed with error %u\n", GetLastError() );
223 ok( !memcmp(buffer, "Service-0x0-", 12), "unexpected window station name '%s'\n", buffer );
224 ok( buffer[strlen(buffer) - 1] == '$', "unexpected window station name '%s'\n", buffer );
225
226 SetLastError( 0xdeadbeef );
229 ok( w3 != 0, "open station failed err %u\n", GetLastError() );
230 CloseWindowStation( w3 );
232
233 SetLastError( 0xdeadbeef );
234 w2 = CreateWindowStationA( "foo\\bar", 0, WINSTA_ALL_ACCESS, NULL );
235 ok( !w2, "create station succeeded\n" );
237 "wrong error %u\n", GetLastError() );
238
239 SetLastError( 0xdeadbeef );
241 ok( !w2, "create station succeeded\n" );
242 ok( GetLastError() == ERROR_PATH_NOT_FOUND, "wrong error %u\n", GetLastError() );
243
244 /* desktops */
246 initial_desktop = d1;
248 "GetThreadDesktop returned different handles\n" );
249
250 flags = 0;
251 ok( GetHandleInformation( d1, &flags ), "GetHandleInformation failed\n" );
252 ok( !(flags & HANDLE_FLAG_PROTECT_FROM_CLOSE), "handle %p PROTECT_FROM_CLOSE set\n", d1 );
253
254 SetLastError( 0xdeadbeef );
255 ok( !CloseDesktop(d1), "closing thread desktop succeeded\n" );
256 ok( GetLastError() == ERROR_BUSY || broken(GetLastError() == 0xdeadbeef), /* wow64 */
257 "bad last error %d\n", GetLastError() );
258
259 SetLastError( 0xdeadbeef );
260 if (CloseHandle( d1 )) /* succeeds on nt4 */
261 {
262 win_skip( "NT4 desktop handle management is completely different\n" );
263 return;
264 }
265 ok( GetLastError() == ERROR_INVALID_HANDLE, "bad last error %d\n", GetLastError() );
266
268 TRUE, DUPLICATE_SAME_ACCESS ), "DuplicateHandle failed\n" );
269 ok( CloseDesktop(d2), "closing dup desktop failed\n" );
270
272 TRUE, DUPLICATE_SAME_ACCESS ), "DuplicateHandle failed\n" );
273 ok( CloseHandle(d2), "closing dup desktop handle failed\n" );
274
275 d2 = OpenDesktopA( "dummy name", 0, TRUE, DESKTOP_ALL_ACCESS );
276 ok( !d2, "open dummy desktop succeeded\n" );
277
278 SetLastError( 0xdeadbeef );
281 ok( !d2, "create empty desktop succeeded\n" );
283 ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError() );
284
285 SetLastError( 0xdeadbeef );
286 d2 = OpenDesktopA( "", 0, TRUE, DESKTOP_ALL_ACCESS );
287 ok( !d2, "open empty desktop succeeded\n" );
288 ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError() );
289
290 SetLastError( 0xdeadbeef );
291 d2 = CreateDesktopA( "foo\\bar", NULL, NULL, 0, DESKTOP_ALL_ACCESS, NULL );
292 ok( !d2, "create desktop succeeded\n" );
293 ok( GetLastError() == ERROR_BAD_PATHNAME, "wrong error %u\n", GetLastError() );
294
295 SetLastError( 0xdeadbeef );
296 d2 = OpenDesktopA( "foo\\bar", 0, TRUE, DESKTOP_ALL_ACCESS );
297 ok( !d2, "open desktop succeeded\n" );
298 ok( GetLastError() == ERROR_BAD_PATHNAME, "wrong error %u\n", GetLastError() );
299
300 d2 = CreateDesktopA( "foobar", NULL, NULL, 0, DESKTOP_ALL_ACCESS, NULL );
301 ok( d2 != 0, "create foobar desktop failed\n" );
302 SetLastError( 0xdeadbeef );
303 ok( !CloseWindowStation( (HWINSTA)d2 ), "CloseWindowStation succeeded on desktop\n" );
304 ok( GetLastError() == ERROR_INVALID_HANDLE || broken(GetLastError() == 0xdeadbeef), /* wow64 */
305 "bad last error %d\n", GetLastError() );
306
307 SetLastError( 0xdeadbeef );
308 d3 = CreateDesktopA( "foobar", NULL, NULL, 0, DESKTOP_ALL_ACCESS, NULL );
309 ok( d3 != 0, "create foobar desktop again failed\n" );
310 ok( GetLastError() == 0xdeadbeef, "bad last error %d\n", GetLastError() );
311 ok( CloseDesktop( d3 ), "CloseDesktop failed\n" );
312
313 d3 = OpenDesktopA( "foobar", 0, TRUE, DESKTOP_ALL_ACCESS );
314 ok( d3 != 0, "open foobar desktop failed\n" );
315 ok( d3 != d2, "open foobar desktop returned same handle\n" );
316 ok( CloseDesktop( d2 ), "CloseDesktop failed\n" );
317 ok( CloseDesktop( d3 ), "CloseDesktop failed\n" );
318
319 d3 = OpenDesktopA( "foobar", 0, TRUE, DESKTOP_ALL_ACCESS );
320 ok( !d3, "open foobar desktop succeeded\n" );
321
322 ok( !CloseHandle(d1), "closing thread desktop handle succeeded\n" );
324 ok( d1 == d2, "got different handles after close\n" );
325
327 trace( "thread 1 desktop: %p\n", d1 );
328 print_object( d1 );
329 hthread = CreateThread( NULL, 0, thread, (LPVOID)2, 0, &id );
330 Sleep(1000);
331 trace( "get other thread desktop: %p\n", GetThreadDesktop(id) );
332 WaitForSingleObject( hthread, INFINITE );
333 CloseHandle( hthread );
334
335 /* clean side effect */
337}
338
339/* Enumeration tests */
340
342{
343 trace("window_station_callbackA called with argument %s\n", winsta);
344 return lp;
345}
346
348{
349 HWINSTA hwinsta;
350
351 trace("open_window_station_callbackA called with argument %s\n", winsta);
352 hwinsta = OpenWindowStationA(winsta, FALSE, WINSTA_ENUMERATE);
353 ok(hwinsta != NULL, "Could not open desktop %s!\n", winsta);
354 if (hwinsta)
355 CloseWindowStation(hwinsta);
356 return lp;
357}
358
359static void test_enumstations(void)
360{
361 DWORD ret;
362 HWINSTA hwinsta;
363
364 if (0) /* Crashes instead */
365 {
366 SetLastError(0xbabefeed);
368 ok(!ret, "EnumWindowStationsA returned successfully!\n");
369 ok(GetLastError() == ERROR_INVALID_PARAMETER, "LastError is set to %08x\n", GetLastError());
370 }
371
372 hwinsta = CreateWindowStationA("winsta_test", 0, WINSTA_ALL_ACCESS, NULL);
373 ret = GetLastError();
374 ok(hwinsta != NULL || ret == ERROR_ACCESS_DENIED, "CreateWindowStation failed (%u)\n", ret);
375 if (!hwinsta)
376 {
377 win_skip("Not enough privileges for CreateWindowStation\n");
378 return;
379 }
380
381 SetLastError(0xdeadbeef);
383 ok(ret == 0x12345, "EnumWindowStationsA returned %x\n", ret);
384 ok(GetLastError() == 0xdeadbeef, "LastError is set to %08x\n", GetLastError());
385
386 SetLastError(0xdeadbeef);
388 ok(!ret, "EnumWindowStationsA returned %x\n", ret);
389 ok(GetLastError() == 0xdeadbeef, "LastError is set to %08x\n", GetLastError());
390}
391
393{
394 trace("desktop_callbackA called with argument %s\n", desktop);
395 return lp;
396}
397
399{
400 HDESK hdesk;
401 static int once;
402
403 trace("open_desktop_callbackA called with argument %s\n", desktop);
404 /* Only try to open one desktop */
405 if (once++)
406 return lp;
407
408 hdesk = OpenDesktopA(desktop, 0, FALSE, DESKTOP_ENUMERATE);
409 ok(hdesk != NULL, "Could not open desktop %s!\n", desktop);
410 if (hdesk)
411 CloseDesktop(hdesk);
412 return lp;
413}
414
415static void test_enumdesktops(void)
416{
417 BOOL ret;
418
419 if (0) /* Crashes instead */
420 {
421 SetLastError(0xbabefeed);
423 ok(!ret, "EnumDesktopsA returned successfully!\n");
424 ok(GetLastError() == ERROR_INVALID_PARAMETER, "LastError is set to %08x\n", GetLastError());
425 }
426
427 SetLastError(0xdeadbeef);
429 ok(ret == 0x12345, "EnumDesktopsA returned %x\n", ret);
430 ok(GetLastError() == 0xdeadbeef, "LastError is set to %08x\n", GetLastError());
431
432 SetLastError(0xdeadbeef);
434 ok(ret == 0x12345, "EnumDesktopsA returned %x\n", ret);
435 ok(GetLastError() == 0xdeadbeef, "LastError is set to %08x\n", GetLastError());
436
437 SetLastError(0xdeadbeef);
439 ok(!ret, "EnumDesktopsA returned %x\n", ret);
440 ok(GetLastError() == ERROR_INVALID_HANDLE, "LastError is set to %08x\n", GetLastError());
441
442 SetLastError(0xdeadbeef);
444 ok(!ret, "EnumDesktopsA returned %x\n", ret);
445 ok(GetLastError() == 0xdeadbeef, "LastError is set to %08x\n", GetLastError());
446}
447
448/* Miscellaneous tests */
449
451{
452 WCHAR foobarTestW[] = {'\\','f','o','o','b','a','r','T','e','s','t',0};
453 WCHAR DesktopW[] = {'D','e','s','k','t','o','p',0};
454 OBJECT_NAME_INFORMATION *name_info;
455 WCHAR bufferW[20];
456 char buffer[64];
458 DWORD size;
459 HDESK desk;
460 BOOL ret;
461
462 desk = CreateDesktopA("foobarTest", NULL, NULL, 0, DESKTOP_ALL_ACCESS, NULL);
463 ok(desk != 0, "open foobarTest desktop failed\n");
464
465 strcpy(buffer, "blahblah");
466
469 /* Get size, test size and return value/error code */
470 SetLastError(0xdeadbeef);
471 size = 0xdeadbeef;
473
474 ok(!ret, "GetUserObjectInformationA returned %x\n", ret);
475 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "LastError is set to %08x\n", GetLastError());
476 ok(size == 22, "size is set to %d\n", size); /* Windows returns Unicode length (11*2) */
477
478 /* Get string */
479 SetLastError(0xdeadbeef);
480 size = 0xdeadbeef;
482
483 ok(ret, "GetUserObjectInformationA returned %x\n", ret);
484 ok(GetLastError() == 0xdeadbeef, "LastError is set to %08x\n", GetLastError());
485
486 ok(strcmp(buffer, "foobarTest") == 0, "Buffer is set to '%s'\n", buffer);
487 ok(size == 11, "size is set to %d\n", size); /* 11 bytes in 'foobarTest\0' */
488
489 /* Get size, test size and return value/error code (Unicode) */
490 SetLastError(0xdeadbeef);
491 size = 0xdeadbeef;
493
494 ok(!ret, "GetUserObjectInformationW returned %x\n", ret);
495 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "LastError is set to %08x\n", GetLastError());
496 ok(size == 22, "size is set to %d\n", size); /* 22 bytes in 'foobarTest\0' in Unicode */
497
498 /* Get string (Unicode) */
499 SetLastError(0xdeadbeef);
500 size = 0xdeadbeef;
501 ret = GetUserObjectInformationW(desk, UOI_NAME, bufferW, sizeof(bufferW), &size);
502
503 ok(ret, "GetUserObjectInformationW returned %x\n", ret);
504 ok(GetLastError() == 0xdeadbeef, "LastError is set to %08x\n", GetLastError());
505
506 ok(lstrcmpW(bufferW, foobarTestW + 1) == 0, "Buffer is not set to 'foobarTest'\n");
507 ok(size == 22, "size is set to %d\n", size); /* 22 bytes in 'foobarTest\0' in Unicode */
508
509 /* ObjectNameInformation does not return the full desktop name */
510 name_info = (OBJECT_NAME_INFORMATION *)buffer;
511 status = pNtQueryObject(desk, ObjectNameInformation, name_info, sizeof(buffer), NULL);
512 ok(!status, "expected STATUS_SUCCESS, got %08x\n", status);
513 ok(lstrcmpW(name_info->Name.Buffer, foobarTestW) == 0,
514 "expected '\\foobarTest', got %s\n", wine_dbgstr_w(name_info->Name.Buffer));
515
518 /* Get size, test size and return value/error code */
519 SetLastError(0xdeadbeef);
520 size = 0xdeadbeef;
522
523 ok(!ret, "GetUserObjectInformationA returned %x\n", ret);
524 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "LastError is set to %08x\n", GetLastError());
525 ok(size == 16, "size is set to %d\n", size); /* Windows returns Unicode length (8*2) */
526
527 /* Get string */
528 SetLastError(0xdeadbeef);
529 size = 0xdeadbeef;
531
532 ok(ret, "GetUserObjectInformationA returned %x\n", ret);
533 ok(GetLastError() == 0xdeadbeef, "LastError is set to %08x\n", GetLastError());
534
535 ok(strcmp(buffer, "Desktop") == 0, "Buffer is set to '%s'\n", buffer);
536 ok(size == 8, "size is set to %d\n", size); /* 8 bytes in 'Desktop\0' */
537
538 /* Get size, test size and return value/error code (Unicode) */
539 size = 0xdeadbeef;
540 SetLastError(0xdeadbeef);
542
543 ok(!ret, "GetUserObjectInformationW returned %x\n", ret);
544 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "LastError is set to %08x\n", GetLastError());
545 ok(size == 16, "size is set to %d\n", size); /* 16 bytes in 'Desktop\0' in Unicode */
546
547 /* Get string (Unicode) */
548 SetLastError(0xdeadbeef);
549 size = 0xdeadbeef;
550 ret = GetUserObjectInformationW(desk, UOI_TYPE, bufferW, sizeof(bufferW), &size);
551
552 ok(ret, "GetUserObjectInformationW returned %x\n", ret);
553 ok(GetLastError() == 0xdeadbeef, "LastError is set to %08x\n", GetLastError());
554
555 ok(lstrcmpW(bufferW, DesktopW) == 0, "Buffer is not set to 'Desktop'\n");
556 ok(size == 16, "size is set to %d\n", size); /* 16 bytes in 'Desktop\0' in Unicode */
557
558 ok(CloseDesktop(desk), "CloseDesktop failed\n");
559}
560
561static void test_inputdesktop(void)
562{
563 HDESK input_desk, old_input_desk, thread_desk, old_thread_desk, new_desk;
564 DWORD ret;
565 CHAR name[1024];
566 INPUT inputs[1];
567
568 inputs[0].type = INPUT_KEYBOARD;
569 U(inputs[0]).ki.wVk = 0;
570 U(inputs[0]).ki.wScan = 0x3c0;
571 U(inputs[0]).ki.dwFlags = KEYEVENTF_UNICODE;
572
573 /* OpenInputDesktop creates new handles for each calls */
574 old_input_desk = OpenInputDesktop(0, FALSE, DESKTOP_ALL_ACCESS);
575 ok(old_input_desk != NULL, "OpenInputDesktop failed!\n");
576 memset(name, 0, sizeof(name));
577 ret = GetUserObjectInformationA(old_input_desk, UOI_NAME, name, 1024, NULL);
578 ok(ret, "GetUserObjectInformation failed!\n");
579 ok(!strcmp(name, "Default"), "unexpected desktop %s\n", name);
580
581 input_desk = OpenInputDesktop(0, FALSE, DESKTOP_ALL_ACCESS);
582 ok(input_desk != NULL, "OpenInputDesktop failed!\n");
583 memset(name, 0, sizeof(name));
584 ret = GetUserObjectInformationA(input_desk, UOI_NAME, name, 1024, NULL);
585 ok(ret, "GetUserObjectInformation failed!\n");
586 ok(!strcmp(name, "Default"), "unexpected desktop %s\n", name);
587
588 ok(old_input_desk != input_desk, "returned the same handle!\n");
589 ret = CloseDesktop(input_desk);
590 ok(ret, "CloseDesktop failed!\n");
591
592 /* by default, GetThreadDesktop is the input desktop, SendInput should succeed. */
593 old_thread_desk = GetThreadDesktop(GetCurrentThreadId());
594 ok(old_thread_desk != NULL, "GetThreadDesktop faile!\n");
595 memset(name, 0, sizeof(name));
596 ret = GetUserObjectInformationA(old_thread_desk, UOI_NAME, name, 1024, NULL);
597 ok(!strcmp(name, "Default"), "unexpected desktop %s\n", name);
598
599 SetLastError(0xdeadbeef);
600 ret = SendInput(1, inputs, sizeof(INPUT));
601 ok(GetLastError() == 0xdeadbeef, "unexpected last error %08x\n", GetLastError());
602 ok(ret == 1, "unexpected return count %d\n", ret);
603
604 /* Set thread desktop to the new desktop, SendInput should fail. */
605 new_desk = CreateDesktopA("new_desk", NULL, NULL, 0, DESKTOP_ALL_ACCESS, NULL);
606 ok(new_desk != NULL, "CreateDesktop failed!\n");
607 ret = SetThreadDesktop(new_desk);
608 ok(ret, "SetThreadDesktop failed!\n");
609 thread_desk = GetThreadDesktop(GetCurrentThreadId());
610 ok(thread_desk == new_desk, "thread desktop doesn't match!\n");
611 memset(name, 0, sizeof(name));
612 ret = GetUserObjectInformationA(thread_desk, UOI_NAME, name, 1024, NULL);
613 ok(!strcmp(name, "new_desk"), "unexpected desktop %s\n", name);
614
615 SetLastError(0xdeadbeef);
616 ret = SendInput(1, inputs, sizeof(INPUT));
617 if(broken(GetLastError() == 0xdeadbeef))
618 {
619 SetThreadDesktop(old_thread_desk);
620 CloseDesktop(old_input_desk);
621 CloseDesktop(input_desk);
622 CloseDesktop(new_desk);
623 win_skip("Skip tests on NT4\n");
624 return;
625 }
627 ok(GetLastError() == ERROR_ACCESS_DENIED, "unexpected last error %08x\n", GetLastError());
628 ok(ret == 1 || broken(ret == 0) /* Win64 */, "unexpected return count %d\n", ret);
629
630 /* Set thread desktop back to the old thread desktop, SendInput should success. */
631 ret = SetThreadDesktop(old_thread_desk);
632 ok(ret, "SetThreadDesktop failed!\n");
633 thread_desk = GetThreadDesktop(GetCurrentThreadId());
634 ok(thread_desk == old_thread_desk, "thread desktop doesn't match!\n");
635 memset(name, 0, sizeof(name));
636 ret = GetUserObjectInformationA(thread_desk, UOI_NAME, name, 1024, NULL);
637 ok(!strcmp(name, "Default"), "unexpected desktop %s\n", name);
638
639 SetLastError(0xdeadbeef);
640 ret = SendInput(1, inputs, sizeof(INPUT));
641 ok(GetLastError() == 0xdeadbeef, "unexpected last error %08x\n", GetLastError());
642 ok(ret == 1, "unexpected return count %d\n", ret);
643
644 /* Set thread desktop to the input desktop, SendInput should success. */
645 ret = SetThreadDesktop(old_input_desk);
646 ok(ret, "SetThreadDesktop failed!\n");
647 thread_desk = GetThreadDesktop(GetCurrentThreadId());
648 ok(thread_desk == old_input_desk, "thread desktop doesn't match!\n");
649 memset(name, 0, sizeof(name));
650 ret = GetUserObjectInformationA(thread_desk, UOI_NAME, name, 1024, NULL);
651 ok(!strcmp(name, "Default"), "unexpected desktop %s\n", name);
652
653 SetLastError(0xdeadbeef);
654 ret = SendInput(1, inputs, sizeof(INPUT));
655 ok(GetLastError() == 0xdeadbeef, "unexpected last error %08x\n", GetLastError());
656 ok(ret == 1, "unexpected return count %d\n", ret);
657
658 /* Switch input desktop to the new desktop, SendInput should fail. */
659 ret = SwitchDesktop(new_desk);
660 ok(ret, "SwitchDesktop failed!\n");
661 input_desk = OpenInputDesktop(0, FALSE, DESKTOP_ALL_ACCESS);
662 ok(input_desk != NULL, "OpenInputDesktop failed!\n");
663 ok(input_desk != new_desk, "returned the same handle!\n");
664 memset(name, 0, sizeof(name));
665 ret = GetUserObjectInformationA(input_desk, UOI_NAME, name, 1024, NULL);
666 ok(ret, "GetUserObjectInformation failed!\n");
668 ok(!strcmp(name, "new_desk"), "unexpected desktop %s\n", name);
669 ret = CloseDesktop(input_desk);
670 ok(ret, "CloseDesktop failed!\n");
671
672 SetLastError(0xdeadbeef);
673 ret = SendInput(1, inputs, sizeof(INPUT));
675 ok(GetLastError() == ERROR_ACCESS_DENIED, "unexpected last error %08x\n", GetLastError());
676 ok(ret == 1 || broken(ret == 0) /* Win64 */, "unexpected return count %d\n", ret);
677
678 /* Set thread desktop to the new desktop, SendInput should success. */
679 ret = SetThreadDesktop(new_desk);
680 ok(ret, "SetThreadDesktop failed!\n");
681 thread_desk = GetThreadDesktop(GetCurrentThreadId());
682 ok(thread_desk == new_desk, "thread desktop doesn't match!\n");
683 memset(name, 0, sizeof(name));
684 ret = GetUserObjectInformationA(thread_desk, UOI_NAME, name, 1024, NULL);
685 ok(!strcmp(name, "new_desk"), "unexpected desktop %s\n", name);
686
687 SetLastError(0xdeadbeef);
688 ret = SendInput(1, inputs, sizeof(INPUT));
689 ok(GetLastError() == 0xdeadbeef, "unexpected last error %08x\n", GetLastError());
690 ok(ret == 1, "unexpected return count %d\n", ret);
691
692 /* Switch input desktop to the old input desktop, set thread desktop to the old
693 * thread desktop, clean side effects. SendInput should success. */
694 ret = SwitchDesktop(old_input_desk);
695 input_desk = OpenInputDesktop(0, FALSE, DESKTOP_ALL_ACCESS);
696 ok(input_desk != NULL, "OpenInputDesktop failed!\n");
697 ok(input_desk != old_input_desk, "returned the same handle!\n");
698 memset(name, 0, sizeof(name));
699 ret = GetUserObjectInformationA(input_desk, UOI_NAME, name, 1024, NULL);
700 ok(ret, "GetUserObjectInformation failed!\n");
701 ok(!strcmp(name, "Default"), "unexpected desktop %s\n", name);
702
703 ret = SetThreadDesktop(old_thread_desk);
704 ok(ret, "SetThreadDesktop failed!\n");
705 thread_desk = GetThreadDesktop(GetCurrentThreadId());
706 ok(thread_desk == old_thread_desk, "thread desktop doesn't match!\n");
707 memset(name, 0, sizeof(name));
708 ret = GetUserObjectInformationA(thread_desk, UOI_NAME, name, 1024, NULL);
709 ok(!strcmp(name, "Default"), "unexpected desktop %s\n", name);
710
711 SetLastError(0xdeadbeef);
712 ret = SendInput(1, inputs, sizeof(INPUT));
713 ok(GetLastError() == 0xdeadbeef, "unexpected last error %08x\n", GetLastError());
714 ok(ret == 1, "unexpected return count %d\n", ret);
715
716 /* free resources */
717 ret = CloseDesktop(input_desk);
718 ok(ret, "CloseDesktop failed!\n");
719 ret = CloseDesktop(old_input_desk);
720 ok(ret, "CloseDesktop failed!\n");
721 ret = CloseDesktop(new_desk);
722 ok(ret, "CloseDesktop failed!\n");
723}
724
725static void test_inputdesktop2(void)
726{
727 HWINSTA w1, w2;
728 HDESK thread_desk, new_desk, input_desk, hdesk;
729 DWORD ret;
730
731 thread_desk = GetThreadDesktop(GetCurrentThreadId());
732 ok(thread_desk != NULL, "GetThreadDesktop failed!\n");
734 ok(w1 != NULL, "GetProcessWindowStation failed!\n");
735 SetLastError(0xdeadbeef);
736 w2 = CreateWindowStationA("winsta_test", 0, WINSTA_ALL_ACCESS, NULL);
737 ret = GetLastError();
738 ok(w2 != NULL || ret == ERROR_ACCESS_DENIED, "CreateWindowStation failed (%u)\n", ret);
739 if (!w2)
740 {
741 win_skip("Not enough privileges for CreateWindowStation\n");
742 return;
743 }
744
746 ok(!ret, "EnumDesktopsA failed!\n");
747 input_desk = OpenInputDesktop(0, FALSE, DESKTOP_ALL_ACCESS);
748 ok(input_desk != NULL, "OpenInputDesktop failed!\n");
749 ret = CloseDesktop(input_desk);
750 ok(ret, "CloseDesktop failed!\n");
751
753 ok(ret, "SetProcessWindowStation failed!\n");
755 ok(hdesk != NULL, "GetThreadDesktop failed!\n");
756 ok(hdesk == thread_desk, "thread desktop should not change after winstation changed!\n");
758
759 new_desk = CreateDesktopA("desk_test", NULL, NULL, 0, DESKTOP_ALL_ACCESS, NULL);
760 ok(new_desk != NULL, "CreateDesktop failed!\n");
762 ok(!ret, "EnumDesktopsA failed!\n");
763 SetLastError(0xdeadbeef);
764 input_desk = OpenInputDesktop(0, FALSE, DESKTOP_ALL_ACCESS);
765 ok(input_desk == NULL, "OpenInputDesktop should fail on non default winstation!\n");
766 ok(GetLastError() == ERROR_INVALID_FUNCTION || broken(GetLastError() == 0xdeadbeef), "last error %08x\n", GetLastError());
767
768 hdesk = OpenDesktopA("desk_test", 0, TRUE, DESKTOP_ALL_ACCESS);
769 ok(hdesk != NULL, "OpenDesktop failed!\n");
770 SetLastError(0xdeadbeef);
771 ret = SwitchDesktop(hdesk);
773 ok(!ret, "Switch to desktop belong to non default winstation should fail!\n");
775 ok(GetLastError() == ERROR_ACCESS_DENIED || broken(GetLastError() == 0xdeadbeef), "last error %08x\n", GetLastError());
776 ret = SetThreadDesktop(hdesk);
777 ok(ret, "SetThreadDesktop failed!\n");
778
779 /* clean side effect */
780 ret = SetThreadDesktop(thread_desk);
782 ok(ret, "SetThreadDesktop should success even desktop is not belong to process winstation!\n");
784 ok(ret, "SetProcessWindowStation failed!\n");
785 ret = SetThreadDesktop(thread_desk);
786 ok(ret, "SetThreadDesktop failed!\n");
788 ok(ret, "CloseWindowStation failed!\n");
789 ret = CloseDesktop(new_desk);
790 ok(ret, "CloseDesktop failed!\n");
791 ret = CloseDesktop(hdesk);
792 ok(ret, "CloseDesktop failed!\n");
793}
794
796{
797 if (msg == WM_DESTROY)
798 {
799 trace("destroying hwnd %p\n", hWnd);
801 return 0;
802 }
803 return DefWindowProcA( hWnd, msg, wParam, lParam );
804}
805
806typedef struct tag_wnd_param
807{
808 const char *wnd_name;
810 HDESK hdesk;
813
815{
816 wnd_param *param1 = param;
817 DWORD ret;
818 MSG msg;
819
820 ret = SetThreadDesktop(param1->hdesk);
821 ok(ret, "SetThreadDesktop failed!\n");
822 param1->hwnd = CreateWindowA("test_class", param1->wnd_name, WS_POPUP, 0, 0, 100, 100, NULL, NULL, NULL, NULL);
823 ok(param1->hwnd != 0, "CreateWindowA failed!\n");
824 ret = SetEvent(param1->hevent);
825 ok(ret, "SetEvent failed!\n");
826
827 while (GetMessageA(&msg, 0, 0, 0))
828 {
831 }
832
833 return 0;
834}
835
837{
838 HWND hwnd_fore;
839 DWORD set_id, fore_id, ret;
840 char win_text[1024];
841
842 hwnd_fore = GetForegroundWindow();
843 GetWindowTextA(hwnd_fore, win_text, 1024);
845 fore_id = GetWindowThreadProcessId(hwnd_fore, NULL);
846 trace("\"%s\" %p %08x hwnd %p %08x\n", win_text, hwnd_fore, fore_id, hwnd, set_id);
847 ret = AttachThreadInput(set_id, fore_id, TRUE);
848 trace("AttachThreadInput returned %08x\n", ret);
850 trace("ShowWindow returned %08x\n", ret);
852 trace("set topmost returned %08x\n", ret);
854 trace("set notopmost returned %08x\n", ret);
856 trace("SetForegroundWindow returned %08x\n", ret);
857 Sleep(250);
858 AttachThreadInput(set_id, fore_id, FALSE);
859 return ret;
860}
861
862static void test_foregroundwindow(void)
863{
864 HWND hwnd, hwnd_test, partners[2], hwnds[2];
865 HDESK hdesks[2];
866 int thread_desk_id, input_desk_id, hwnd_id;
867 WNDCLASSA wclass;
869 DWORD ret, timeout, timeout_old;
870 char win_text[1024];
871
872#define DESKTOPS 2
873
874 memset( &wclass, 0, sizeof(wclass) );
875 wclass.lpszClassName = "test_class";
876 wclass.lpfnWndProc = WndProc;
877 RegisterClassA(&wclass);
878 param.wnd_name = "win_name";
879
881 ok(hdesks[0] != NULL, "OpenDesktop failed!\n");
882 SetLastError(0xdeadbeef);
883 hdesks[1] = CreateDesktopA("desk2", NULL, NULL, 0, DESKTOP_ALL_ACCESS, NULL);
884 ret = GetLastError();
885 ok(hdesks[1] != NULL || ret == ERROR_ACCESS_DENIED, "CreateDesktop failed (%u)\n", ret);
886 if(!hdesks[1])
887 {
888 win_skip("Not enough privileges for CreateDesktop\n");
889 return;
890 }
891
892 ret = SystemParametersInfoA(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, &timeout_old, 0);
893 if(!ret)
894 {
895 win_skip("Skip tests on NT4\n");
896 CloseDesktop(hdesks[1]);
897 return;
898 }
899 trace("old timeout %d\n", timeout_old);
900 timeout = 0;
901 ret = SystemParametersInfoA(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, 0, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
902 ok(ret, "set foreground lock timeout failed!\n");
903 ret = SystemParametersInfoA(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, &timeout, 0);
904 ok(ret, "get foreground lock timeout failed!\n");
905 ok(timeout == 0, "unexpected timeout %d\n", timeout);
906
907 for (thread_desk_id = 0; thread_desk_id < DESKTOPS; thread_desk_id++)
908 {
909 param.hdesk = hdesks[thread_desk_id];
910 param.hevent = CreateEventA(NULL, TRUE, FALSE, NULL);
913 ok(ret == WAIT_OBJECT_0, "wait failed!\n");
914 hwnds[thread_desk_id] = param.hwnd;
915 }
916
917 for (thread_desk_id = 0; thread_desk_id < DESKTOPS; thread_desk_id++)
918 {
919 param.hdesk = hdesks[thread_desk_id];
920 param.hevent = CreateEventA(NULL, TRUE, FALSE, NULL);
923 ok(ret == WAIT_OBJECT_0, "wait failed!\n");
924 partners[thread_desk_id] = param.hwnd;
925 }
926
927 trace("hwnd0 %p hwnd1 %p partner0 %p partner1 %p\n", hwnds[0], hwnds[1], partners[0], partners[1]);
928
929 for (hwnd_id = 0; hwnd_id < DESKTOPS; hwnd_id++)
930 for (thread_desk_id = 0; thread_desk_id < DESKTOPS; thread_desk_id++)
931 for (input_desk_id = 0; input_desk_id < DESKTOPS; input_desk_id++)
932 {
933 trace("testing thread_desk %d input_desk %d hwnd %d\n",
934 thread_desk_id, input_desk_id, hwnd_id);
935 hwnd_test = hwnds[hwnd_id];
936 ret = SetThreadDesktop(hdesks[thread_desk_id]);
937 ok(ret, "set thread desktop failed!\n");
938 ret = SwitchDesktop(hdesks[input_desk_id]);
939 ok(ret, "switch desktop failed!\n");
940 set_foreground(partners[0]);
941 set_foreground(partners[1]);
943 ok(hwnd != hwnd_test, "unexpected foreground window %p\n", hwnd);
944 ret = set_foreground(hwnd_test);
946 GetWindowTextA(hwnd, win_text, 1024);
947 trace("hwnd %p name %s\n", hwnd, win_text);
948 if (input_desk_id == hwnd_id)
949 {
950 if (input_desk_id == thread_desk_id)
951 {
952 ok(ret, "SetForegroundWindow failed!\n");
954 ok(hwnd == hwnd_test , "unexpected foreground window %p\n", hwnd);
955 }
956 else
957 {
958 todo_wine ok(ret, "SetForegroundWindow failed!\n");
959 todo_wine ok(hwnd == 0, "unexpected foreground window %p\n", hwnd);
960 }
961 }
962 else
963 {
964 if (input_desk_id == thread_desk_id)
965 {
966 ok(!ret, "SetForegroundWindow should fail!\n");
968 ok(hwnd == partners[input_desk_id] , "unexpected foreground window %p\n", hwnd);
969 }
970 else
971 {
972 todo_wine ok(!ret, "SetForegroundWindow should fail!\n");
974 ok(hwnd == 0, "unexpected foreground window %p\n", hwnd);
975 }
976 }
977 }
978
979 /* Clean up */
980
981 for (thread_desk_id = DESKTOPS - 1; thread_desk_id >= 0; thread_desk_id--)
982 {
983 ret = SetThreadDesktop(hdesks[thread_desk_id]);
984 ok(ret, "set thread desktop failed!\n");
985 SendMessageA(hwnds[thread_desk_id], WM_DESTROY, 0, 0);
986 SendMessageA(partners[thread_desk_id], WM_DESTROY, 0, 0);
987 }
988
989 ret = SwitchDesktop(hdesks[0]);
990 ok(ret, "switch desktop failed!\n");
991 CloseDesktop(hdesks[1]);
992
993 ret = SystemParametersInfoA(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, UlongToPtr(timeout_old), SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
994 ok(ret, "set foreground lock timeout failed!\n");
995 ret = SystemParametersInfoA(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, &timeout, 0);
996 ok(ret, "get foreground lock timeout failed!\n");
997 ok(timeout == timeout_old, "unexpected timeout %d\n", timeout);
998}
999
1000START_TEST(winstation)
1001{
1002 HMODULE hntdll = GetModuleHandleA("ntdll.dll");
1003 pNtQueryObject = (void *)GetProcAddress(hntdll, "NtQueryObject");
1004
1005 /* Check whether this platform supports WindowStation calls */
1006
1007 SetLastError( 0xdeadbeef );
1010 {
1011 win_skip("WindowStation calls not supported on this platform\n");
1012 return;
1013 }
1014
1019 test_handles();
1022}
@ ObjectNameInformation
Definition: DriverTester.h:55
#define broken(x)
Definition: _sntprintf.h:21
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define START_TEST(x)
Definition: atltest.h:75
#define msg(x)
Definition: auth_time.c:54
HWND hWnd
Definition: settings.c:17
LONG NTSTATUS
Definition: precomp.h:26
#define U(x)
Definition: wordpad.c:45
static HANDLE thread
Definition: service.c:33
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define ERROR_BUSY
Definition: dderror.h:12
#define ERROR_INVALID_FUNCTION
Definition: dderror.h:6
WORD ATOM
Definition: dimm.idl:113
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NTSTATUS
Definition: precomp.h:21
#define CloseHandle
Definition: compat.h:739
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:102
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define SetLastError(x)
Definition: compat.h:752
#define GetProcAddress(x, y)
Definition: compat.h:753
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define GetCurrentProcess()
Definition: compat.h:759
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
#define CALLBACK
Definition: compat.h:35
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
ATOM WINAPI GlobalAddAtomA(LPCSTR lpString)
Definition: atom.c:434
UINT WINAPI GlobalGetAtomNameA(ATOM nAtom, LPSTR lpBuffer, int nSize)
Definition: atom.c:484
BOOL WINAPI GetHandleInformation(IN HANDLE hObject, OUT LPDWORD lpdwFlags)
Definition: handle.c:40
BOOL WINAPI DuplicateHandle(IN HANDLE hSourceProcessHandle, IN HANDLE hSourceHandle, IN HANDLE hTargetProcessHandle, OUT LPHANDLE lpTargetHandle, IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN DWORD dwOptions)
Definition: handle.c:149
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:137
int WINAPI lstrcmpW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4242
int WINAPI lstrcmpiA(LPCSTR str1, LPCSTR str2)
Definition: locale.c:4223
#define INFINITE
Definition: serial.h:102
#define UlongToPtr(u)
Definition: config.h:106
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLsizeiptr size
Definition: glext.h:5919
GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint GLdouble GLdouble w2
Definition: glext.h:8308
GLuint buffer
Definition: glext.h:5915
GLbitfield flags
Definition: glext.h:7161
GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint GLdouble w1
Definition: glext.h:8308
GLfloat param
Definition: glext.h:5796
GLuint id
Definition: glext.h:5910
#define wine_dbgstr_w
Definition: kernel32.h:34
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
static HWND create_window(void)
Definition: imagelist.c:163
static HINSTANCE hntdll
Definition: process.c:66
#define todo_wine_if(is_todo)
Definition: custom.c:76
#define todo_wine
Definition: custom.c:79
unsigned int UINT
Definition: ndis.h:50
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
#define WS_POPUP
Definition: pedump.c:616
#define win_skip
Definition: test.h:163
#define memset(x, y, z)
Definition: compat.h:39
UNICODE_STRING Name
Definition: nt_native.h:1270
HBRUSH hbrBackground
Definition: winuser.h:3170
HICON hIcon
Definition: winuser.h:3168
HINSTANCE hInstance
Definition: winuser.h:3167
HCURSOR hCursor
Definition: winuser.h:3169
int cbWndExtra
Definition: winuser.h:3166
UINT style
Definition: winuser.h:3163
LPCSTR lpszMenuName
Definition: winuser.h:3171
LPCSTR lpszClassName
Definition: winuser.h:3172
WNDPROC lpfnWndProc
Definition: winuser.h:3164
int cbClsExtra
Definition: winuser.h:3165
Definition: name.c:39
Definition: ps.c:97
DWORD type
Definition: winable.h:59
const char * wnd_name
Definition: winstation.c:808
HANDLE hevent
Definition: winstation.c:811
Definition: dhcpd.h:245
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventA(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCSTR lpName OPTIONAL)
Definition: synch.c:637
HANDLE WINAPI DECLSPEC_HOTPATCH CreateMutexA(IN LPSECURITY_ATTRIBUTES lpMutexAttributes OPTIONAL, IN BOOL bInitialOwner, IN LPCSTR lpName OPTIONAL)
Definition: synch.c:563
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1829
PVOID HANDLE
Definition: typedefs.h:73
int ret
HDESK WINAPI CreateDesktopA(LPCSTR lpszDesktop, LPCSTR lpszDevice, LPDEVMODEA pDevmode, DWORD dwFlags, ACCESS_MASK dwDesiredAccess, LPSECURITY_ATTRIBUTES lpsa)
Definition: desktop.c:431
int WINAPI GetWindowTextA(HWND hWnd, LPSTR lpString, int nMaxCount)
Definition: window.c:1330
UINT WINAPI SendInput(UINT, LPINPUT, int)
Definition: ntwrapper.h:344
#define INPUT_KEYBOARD
Definition: winable.h:10
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
DWORD WINAPI GetCurrentThreadId(void)
Definition: thread.c:459
#define HANDLE_FLAG_PROTECT_FROM_CLOSE
Definition: winbase.h:265
DWORD WINAPI GetWindowThreadProcessId(HWND hWnd, PDWORD lpdwProcessId)
HWINSTA WINAPI GetProcessWindowStation(void)
Definition: ntwrapper.h:124
#define WAIT_OBJECT_0
Definition: winbase.h:406
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
LONG_PTR LPARAM
Definition: windef.h:208
LONG_PTR LRESULT
Definition: windef.h:209
UINT_PTR WPARAM
Definition: windef.h:207
#define WINAPI
Definition: msvc.h:6
#define ERROR_PATH_NOT_FOUND
Definition: winerror.h:106
#define ERROR_BAD_PATHNAME
Definition: winerror.h:233
static void register_class(void)
Definition: winstation.c:49
static BOOL CALLBACK desktop_callbackA(LPSTR desktop, LPARAM lp)
Definition: winstation.c:392
static void test_inputdesktop(void)
Definition: winstation.c:561
#define DESKTOPS
static void test_foregroundwindow(void)
Definition: winstation.c:862
static BOOL CALLBACK window_station_callbackA(LPSTR winsta, LPARAM lp)
Definition: winstation.c:341
static DWORD set_foreground(HWND hwnd)
Definition: winstation.c:836
static void test_enumdesktops(void)
Definition: winstation.c:415
static ULONG
Definition: winstation.c:28
static void test_getuserobjectinformation(void)
Definition: winstation.c:450
static BOOL CALLBACK open_window_station_callbackA(LPSTR winsta, LPARAM lp)
Definition: winstation.c:347
static void test_inputdesktop2(void)
Definition: winstation.c:725
static void test_enumstations(void)
Definition: winstation.c:359
static PVOID
Definition: winstation.c:28
struct tag_wnd_param wnd_param
#define DESKTOP_ALL_ACCESS
Definition: winstation.c:30
static OBJECT_INFORMATION_CLASS
Definition: winstation.c:28
static void print_object(HANDLE obj)
Definition: winstation.c:32
static LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
Definition: winstation.c:795
static BOOL CALLBACK open_desktop_callbackA(LPSTR desktop, LPARAM lp)
Definition: winstation.c:398
static PULONG
Definition: winstation.c:28
static HDESK initial_desktop
Definition: winstation.c:66
static void test_handles(void)
Definition: winstation.c:109
HGDIOBJ WINAPI GetStockObject(_In_ int)
#define WHITE_BRUSH
Definition: wingdi.h:902
#define SW_SHOWNORMAL
Definition: winuser.h:770
HDESK WINAPI GetThreadDesktop(_In_ DWORD)
LRESULT WINAPI DispatchMessageA(_In_ const MSG *)
BOOL WINAPI TranslateMessage(_In_ const MSG *)
HWND WINAPI CreateWindowExA(_In_ DWORD dwExStyle, _In_opt_ LPCSTR lpClassName, _In_opt_ LPCSTR lpWindowName, _In_ DWORD dwStyle, _In_ int X, _In_ int Y, _In_ int nWidth, _In_ int nHeight, _In_opt_ HWND hWndParent, _In_opt_ HMENU hMenu, _In_opt_ HINSTANCE hInstance, _In_opt_ LPVOID lpParam)
BOOL WINAPI ShowWindow(_In_ HWND, _In_ int)
HWND WINAPI GetForegroundWindow(void)
Definition: ntwrapper.h:392
BOOL WINAPI SwitchDesktop(_In_ HDESK)
HWINSTA WINAPI OpenWindowStationA(_In_ LPCSTR, _In_ BOOL, _In_ DWORD)
#define HWND_TOPMOST
Definition: winuser.h:1208
BOOL WINAPI AttachThreadInput(_In_ DWORD, _In_ DWORD, _In_ BOOL)
LRESULT WINAPI DefWindowProcA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
BOOL WINAPI SetThreadDesktop(_In_ HDESK)
#define CreateWindowA(a, b, c, d, e, f, g, h, i, j, k)
Definition: winuser.h:4315
BOOL WINAPI SetWindowPos(_In_ HWND, _In_opt_ HWND, _In_ int, _In_ int, _In_ int, _In_ int, _In_ UINT)
#define UOI_NAME
Definition: winuser.h:1084
__analysis_noreturn void WINAPI PostQuitMessage(_In_ int)
HDESK WINAPI OpenInputDesktop(_In_ DWORD, _In_ BOOL, _In_ DWORD)
HDESK WINAPI OpenDesktopA(_In_ LPCSTR, _In_ DWORD, _In_ BOOL, _In_ DWORD)
#define SWP_NOMOVE
Definition: winuser.h:1244
#define DESKTOP_ENUMERATE
Definition: winuser.h:218
BOOL WINAPI SetForegroundWindow(_In_ HWND)
#define IDC_ARROW
Definition: winuser.h:687
#define UOI_TYPE
Definition: winuser.h:1085
LRESULT WINAPI SendMessageA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
HWINSTA WINAPI CreateWindowStationA(_In_opt_ LPCSTR lpwinsta, _In_ DWORD dwFlags, _In_ ACCESS_MASK dwDesiredAccess, _In_opt_ LPSECURITY_ATTRIBUTES lpsa)
#define SWP_NOSIZE
Definition: winuser.h:1245
BOOL WINAPI CloseWindowStation(_In_ HWINSTA)
#define CS_DBLCLKS
Definition: winuser.h:651
BOOL WINAPI EnumWindowStationsA(_In_ WINSTAENUMPROCA, _In_ LPARAM lParam)
BOOL WINAPI SetProcessWindowStation(_In_ HWINSTA)
#define SPIF_SENDCHANGE
Definition: winuser.h:1572
HWND WINAPI GetDesktopWindow(void)
Definition: window.c:656
#define WINSTA_ALL_ACCESS
Definition: winuser.h:417
#define SPIF_UPDATEINIFILE
Definition: winuser.h:1571
ATOM WINAPI RegisterClassA(_In_ CONST WNDCLASSA *)
#define WINSTA_ENUMERATE
Definition: winuser.h:412
BOOL WINAPI GetUserObjectInformationW(_In_ HANDLE hObj, _In_ int nIndex, _Out_writes_bytes_opt_(nLength) PVOID pvInfo, _In_ DWORD nLength, _Out_opt_ LPDWORD lpnLengthNeeded)
BOOL WINAPI GetUserObjectInformationA(_In_ HANDLE hObj, _In_ int nIndex, _Out_writes_bytes_opt_(nLength) PVOID pvInfo, _In_ DWORD nLength, _Out_opt_ LPDWORD lpnLengthNeeded)
BOOL WINAPI SystemParametersInfoA(_In_ UINT uiAction, _In_ UINT uiParam, _Inout_opt_ PVOID pvParam, _In_ UINT fWinIni)
#define WM_DESTROY
Definition: winuser.h:1609
BOOL WINAPI CloseDesktop(_In_ HDESK)
BOOL WINAPI GetMessageA(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT)
#define HWND_NOTOPMOST
Definition: winuser.h:1206
BOOL WINAPI DestroyWindow(_In_ HWND)
HCURSOR WINAPI LoadCursorA(_In_opt_ HINSTANCE, _In_ LPCSTR)
Definition: cursoricon.c:2121
BOOL WINAPI EnumDesktopsA(_In_opt_ HWINSTA, _In_ DESKTOPENUMPROCA, _In_ LPARAM)
#define DUPLICATE_SAME_ACCESS
const char * LPCSTR
Definition: xmlstorage.h:183
char * LPSTR
Definition: xmlstorage.h:182
__wchar_t WCHAR
Definition: xmlstorage.h:180
char CHAR
Definition: xmlstorage.h:175