2 * Unit tests for window stations and desktops
4 * Copyright 2002 Alexandre Julliard
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
21 #include "wine/test.h"
28 static NTSTATUS (WINAPI
*pNtQueryObject
)(HANDLE
, OBJECT_INFORMATION_CLASS
, PVOID
, ULONG
, PULONG
);
30 #define DESKTOP_ALL_ACCESS 0x01ff
32 static void print_object( HANDLE obj
)
37 strcpy( buffer
, "foobar" );
38 if (!GetUserObjectInformationA( obj
, UOI_NAME
, buffer
, sizeof(buffer
), &size
))
39 trace( "could not get info for %p\n", obj
);
41 trace( "obj %p name '%s'\n", obj
, buffer
);
42 strcpy( buffer
, "foobar" );
43 if (!GetUserObjectInformationA( obj
, UOI_TYPE
, buffer
, sizeof(buffer
), &size
))
44 trace( "could not get type for %p\n", obj
);
46 trace( "obj %p type '%s'\n", obj
, buffer
);
49 static void register_class(void)
53 cls
.style
= CS_DBLCLKS
;
54 cls
.lpfnWndProc
= DefWindowProcA
;
57 cls
.hInstance
= GetModuleHandleA(0);
59 cls
.hCursor
= LoadCursorA(0, (LPCSTR
)IDC_ARROW
);
60 cls
.hbrBackground
= GetStockObject(WHITE_BRUSH
);
61 cls
.lpszMenuName
= NULL
;
62 cls
.lpszClassName
= "WinStationClass";
66 static HDESK initial_desktop
;
68 static DWORD CALLBACK
thread( LPVOID arg
)
71 HWND hwnd
= CreateWindowExA(0,"WinStationClass","test",WS_POPUP
,0,0,100,100,GetDesktopWindow(),0,0,0);
72 ok( hwnd
!= 0, "CreateWindow failed\n" );
73 d1
= GetThreadDesktop(GetCurrentThreadId());
74 trace( "thread %p desktop: %p\n", arg
, d1
);
75 ok( d1
== initial_desktop
, "thread %p doesn't use initial desktop\n", arg
);
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() );
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" );
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() );
94 DestroyWindow( hwnd
);
95 ok( SetThreadDesktop( d2
), "set thread desktop failed\n" );
96 d1
= GetThreadDesktop(GetCurrentThreadId());
97 ok( d1
== d2
, "GetThreadDesktop did not return set desktop %p/%p\n", d1
, d2
);
101 HANDLE hthread
= CreateThread( NULL
, 0, thread
, (char *)arg
+ 1, 0, NULL
);
103 WaitForSingleObject( hthread
, INFINITE
);
104 CloseHandle( hthread
);
109 static void test_handles(void)
122 w1
= GetProcessWindowStation();
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() );
131 ok( GetHandleInformation( w1
, &flags
), "GetHandleInformation failed\n" );
132 ok( !(flags
& HANDLE_FLAG_PROTECT_FROM_CLOSE
) ||
133 broken(flags
& HANDLE_FLAG_PROTECT_FROM_CLOSE
), /* set on nt4 */
134 "handle %p PROTECT_FROM_CLOSE set\n", w1
);
136 ok( DuplicateHandle( GetCurrentProcess(), w1
, GetCurrentProcess(), (PHANDLE
)&w2
, 0,
137 TRUE
, DUPLICATE_SAME_ACCESS
), "DuplicateHandle failed\n" );
138 ok( CloseWindowStation(w2
), "closing dup win station failed\n" );
140 ok( DuplicateHandle( GetCurrentProcess(), w1
, GetCurrentProcess(), (PHANDLE
)&w2
, 0,
141 TRUE
, DUPLICATE_SAME_ACCESS
), "DuplicateHandle failed\n" );
142 ok( CloseHandle(w2
), "closing dup win station handle failed\n" );
144 w2
= CreateWindowStationA("WinSta0", 0, WINSTA_ALL_ACCESS
, NULL
);
146 ok( w2
!= 0 || le
== ERROR_ACCESS_DENIED
, "CreateWindowStation failed (%u)\n", le
);
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" );
156 w2
= CreateWindowStationA("WinSta0", 0, WINSTA_ALL_ACCESS
, NULL
);
157 ok( CloseHandle( w2
), "CloseHandle failed\n" );
159 else if (le
== ERROR_ACCESS_DENIED
)
160 win_skip( "Not enough privileges for CreateWindowStation\n" );
162 w2
= OpenWindowStationA("winsta0", TRUE
, WINSTA_ALL_ACCESS
);
163 ok( w2
!= 0, "OpenWindowStation failed\n" );
164 ok( w2
!= w1
, "OpenWindowStation returned default handle\n" );
165 ok( CloseWindowStation( w2
), "CloseWindowStation failed\n" );
167 w2
= OpenWindowStationA("dummy name", TRUE
, WINSTA_ALL_ACCESS
);
168 ok( !w2
, "open dummy win station succeeded\n" );
170 CreateMutexA( NULL
, 0, "foobar" );
171 w2
= CreateWindowStationA("foobar", 0, WINSTA_ALL_ACCESS
, NULL
);
173 ok( w2
!= 0 || le
== ERROR_ACCESS_DENIED
, "create foobar station failed (%u)\n", le
);
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" );
183 w3
= OpenWindowStationA("foobar", TRUE
, WINSTA_ALL_ACCESS
);
184 ok( !w3
, "open foobar station succeeded\n" );
186 w2
= CreateWindowStationA("foobar1", 0, WINSTA_ALL_ACCESS
, NULL
);
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" );
193 SetProcessWindowStation( w2
);
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
);
198 ok( !CloseWindowStation( w2
), "CloseWindowStation succeeded\n" );
199 ok( GetHandleInformation( w2
, &flags
), "GetHandleInformation failed\n" );
201 SetProcessWindowStation( w3
);
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
);
207 else if (le
== ERROR_ACCESS_DENIED
)
208 win_skip( "Not enough privileges for CreateWindowStation\n" );
210 SetLastError( 0xdeadbeef );
211 w2
= OpenWindowStationA( "", TRUE
, WINSTA_ALL_ACCESS
);
212 ok( !w2
, "open station succeeded\n" );
214 ok( GetLastError() == ERROR_FILE_NOT_FOUND
, "wrong error %u\n", GetLastError() );
216 SetLastError( 0xdeadbeef );
217 w2
= CreateWindowStationA( "", 0, WINSTA_ALL_ACCESS
, NULL
);
218 ok( w2
!= 0, "create station failed err %u\n", GetLastError() );
220 memset( buffer
, 0, sizeof(buffer
) );
221 ret
= GetUserObjectInformationA( w2
, UOI_NAME
, buffer
, sizeof(buffer
), &size
);
222 ok( ret
, "GetUserObjectInformationA failed with error %u\n", GetLastError() );
223 todo_wine
ok( !memcmp(buffer
, "Service-0x0-", 12), "unexpected window station name '%s'\n", buffer
);
224 todo_wine
ok( buffer
[strlen(buffer
) - 1] == '$', "unexpected window station name '%s'\n", buffer
);
226 SetLastError( 0xdeadbeef );
227 w3
= OpenWindowStationA( "", TRUE
, WINSTA_ALL_ACCESS
);
229 ok( w3
!= 0, "open station failed err %u\n", GetLastError() );
230 CloseWindowStation( w3
);
231 CloseWindowStation( w2
);
233 SetLastError( 0xdeadbeef );
234 w2
= CreateWindowStationA( "foo\\bar", 0, WINSTA_ALL_ACCESS
, NULL
);
235 ok( !w2
, "create station succeeded\n" );
236 ok( GetLastError() == ERROR_PATH_NOT_FOUND
|| GetLastError() == ERROR_ACCESS_DENIED
,
237 "wrong error %u\n", GetLastError() );
239 SetLastError( 0xdeadbeef );
240 w2
= OpenWindowStationA( "foo\\bar", TRUE
, WINSTA_ALL_ACCESS
);
241 ok( !w2
, "create station succeeded\n" );
242 ok( GetLastError() == ERROR_PATH_NOT_FOUND
, "wrong error %u\n", GetLastError() );
245 d1
= GetThreadDesktop(GetCurrentThreadId());
246 initial_desktop
= d1
;
247 ok( GetThreadDesktop(GetCurrentThreadId()) == d1
,
248 "GetThreadDesktop returned different handles\n" );
251 ok( GetHandleInformation( d1
, &flags
), "GetHandleInformation failed\n" );
252 ok( !(flags
& HANDLE_FLAG_PROTECT_FROM_CLOSE
), "handle %p PROTECT_FROM_CLOSE set\n", d1
);
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() );
259 SetLastError( 0xdeadbeef );
260 if (CloseHandle( d1
)) /* succeeds on nt4 */
262 win_skip( "NT4 desktop handle management is completely different\n" );
265 ok( GetLastError() == ERROR_INVALID_HANDLE
, "bad last error %d\n", GetLastError() );
267 ok( DuplicateHandle( GetCurrentProcess(), d1
, GetCurrentProcess(), (PHANDLE
)&d2
, 0,
268 TRUE
, DUPLICATE_SAME_ACCESS
), "DuplicateHandle failed\n" );
269 ok( CloseDesktop(d2
), "closing dup desktop failed\n" );
271 ok( DuplicateHandle( GetCurrentProcess(), d1
, GetCurrentProcess(), (PHANDLE
)&d2
, 0,
272 TRUE
, DUPLICATE_SAME_ACCESS
), "DuplicateHandle failed\n" );
273 ok( CloseHandle(d2
), "closing dup desktop handle failed\n" );
275 d2
= OpenDesktopA( "dummy name", 0, TRUE
, DESKTOP_ALL_ACCESS
);
276 ok( !d2
, "open dummy desktop succeeded\n" );
278 SetLastError( 0xdeadbeef );
279 d2
= CreateDesktopA( "", NULL
, NULL
, 0, DESKTOP_ALL_ACCESS
, NULL
);
281 ok( !d2
, "create empty desktop succeeded\n" );
283 ok( GetLastError() == ERROR_INVALID_HANDLE
, "wrong error %u\n", GetLastError() );
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() );
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() );
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() );
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() );
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" );
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" );
319 d3
= OpenDesktopA( "foobar", 0, TRUE
, DESKTOP_ALL_ACCESS
);
320 ok( !d3
, "open foobar desktop succeeded\n" );
322 ok( !CloseHandle(d1
), "closing thread desktop handle succeeded\n" );
323 d2
= GetThreadDesktop(GetCurrentThreadId());
324 ok( d1
== d2
, "got different handles after close\n" );
327 trace( "thread 1 desktop: %p\n", d1
);
329 hthread
= CreateThread( NULL
, 0, thread
, (LPVOID
)2, 0, &id
);
331 trace( "get other thread desktop: %p\n", GetThreadDesktop(id
) );
332 WaitForSingleObject( hthread
, INFINITE
);
333 CloseHandle( hthread
);
335 /* clean side effect */
336 SetProcessWindowStation( w1
);
339 /* Enumeration tests */
341 static BOOL CALLBACK
window_station_callbackA(LPSTR winsta
, LPARAM lp
)
343 trace("window_station_callbackA called with argument %s\n", winsta
);
347 static BOOL CALLBACK
open_window_station_callbackA(LPSTR winsta
, LPARAM lp
)
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
);
355 CloseWindowStation(hwinsta
);
359 static void test_enumstations(void)
364 if (0) /* Crashes instead */
366 SetLastError(0xbabefeed);
367 ret
= EnumWindowStationsA(NULL
, 0);
368 ok(!ret
, "EnumWindowStationsA returned successfully!\n");
369 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "LastError is set to %08x\n", GetLastError());
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
);
377 win_skip("Not enough privileges for CreateWindowStation\n");
381 SetLastError(0xdeadbeef);
382 ret
= EnumWindowStationsA(open_window_station_callbackA
, 0x12345);
383 ok(ret
== 0x12345, "EnumWindowStationsA returned %x\n", ret
);
384 ok(GetLastError() == 0xdeadbeef, "LastError is set to %08x\n", GetLastError());
386 SetLastError(0xdeadbeef);
387 ret
= EnumWindowStationsA(window_station_callbackA
, 0);
388 ok(!ret
, "EnumWindowStationsA returned %x\n", ret
);
389 ok(GetLastError() == 0xdeadbeef, "LastError is set to %08x\n", GetLastError());
392 static BOOL CALLBACK
desktop_callbackA(LPSTR desktop
, LPARAM lp
)
394 trace("desktop_callbackA called with argument %s\n", desktop
);
398 static BOOL CALLBACK
open_desktop_callbackA(LPSTR desktop
, LPARAM lp
)
403 trace("open_desktop_callbackA called with argument %s\n", desktop
);
404 /* Only try to open one desktop */
408 hdesk
= OpenDesktopA(desktop
, 0, FALSE
, DESKTOP_ENUMERATE
);
409 ok(hdesk
!= NULL
, "Could not open desktop %s!\n", desktop
);
415 static void test_enumdesktops(void)
419 if (0) /* Crashes instead */
421 SetLastError(0xbabefeed);
422 ret
= EnumDesktopsA(GetProcessWindowStation(), NULL
, 0);
423 ok(!ret
, "EnumDesktopsA returned successfully!\n");
424 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "LastError is set to %08x\n", GetLastError());
427 SetLastError(0xdeadbeef);
428 ret
= EnumDesktopsA(NULL
, desktop_callbackA
, 0x12345);
429 ok(ret
== 0x12345, "EnumDesktopsA returned %x\n", ret
);
430 ok(GetLastError() == 0xdeadbeef, "LastError is set to %08x\n", GetLastError());
432 SetLastError(0xdeadbeef);
433 ret
= EnumDesktopsA(GetProcessWindowStation(), open_desktop_callbackA
, 0x12345);
434 ok(ret
== 0x12345, "EnumDesktopsA returned %x\n", ret
);
435 ok(GetLastError() == 0xdeadbeef, "LastError is set to %08x\n", GetLastError());
437 SetLastError(0xdeadbeef);
438 ret
= EnumDesktopsA(INVALID_HANDLE_VALUE
, desktop_callbackA
, 0x12345);
439 ok(!ret
, "EnumDesktopsA returned %x\n", ret
);
440 ok(GetLastError() == ERROR_INVALID_HANDLE
, "LastError is set to %08x\n", GetLastError());
442 SetLastError(0xdeadbeef);
443 ret
= EnumDesktopsA(GetProcessWindowStation(), desktop_callbackA
, 0);
444 ok(!ret
, "EnumDesktopsA returned %x\n", ret
);
445 ok(GetLastError() == 0xdeadbeef, "LastError is set to %08x\n", GetLastError());
448 /* Miscellaneous tests */
450 static void test_getuserobjectinformation(void)
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
;
462 desk
= CreateDesktopA("foobarTest", NULL
, NULL
, 0, DESKTOP_ALL_ACCESS
, NULL
);
463 ok(desk
!= 0, "open foobarTest desktop failed\n");
465 strcpy(buffer
, "blahblah");
467 /** Tests for UOI_NAME **/
469 /* Get size, test size and return value/error code */
470 SetLastError(0xdeadbeef);
472 ret
= GetUserObjectInformationA(desk
, UOI_NAME
, NULL
, 0, &size
);
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) */
479 SetLastError(0xdeadbeef);
481 ret
= GetUserObjectInformationA(desk
, UOI_NAME
, buffer
, sizeof(buffer
), &size
);
483 ok(ret
, "GetUserObjectInformationA returned %x\n", ret
);
484 ok(GetLastError() == 0xdeadbeef, "LastError is set to %08x\n", GetLastError());
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' */
489 /* Get size, test size and return value/error code (Unicode) */
490 SetLastError(0xdeadbeef);
492 ret
= GetUserObjectInformationW(desk
, UOI_NAME
, NULL
, 0, &size
);
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 */
498 /* Get string (Unicode) */
499 SetLastError(0xdeadbeef);
501 ret
= GetUserObjectInformationW(desk
, UOI_NAME
, bufferW
, sizeof(bufferW
), &size
);
503 ok(ret
, "GetUserObjectInformationW returned %x\n", ret
);
504 ok(GetLastError() == 0xdeadbeef, "LastError is set to %08x\n", GetLastError());
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 */
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
));
516 /** Tests for UOI_TYPE **/
518 /* Get size, test size and return value/error code */
519 SetLastError(0xdeadbeef);
521 ret
= GetUserObjectInformationA(desk
, UOI_TYPE
, NULL
, 0, &size
);
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) */
528 SetLastError(0xdeadbeef);
530 ret
= GetUserObjectInformationA(desk
, UOI_TYPE
, buffer
, sizeof(buffer
), &size
);
532 ok(ret
, "GetUserObjectInformationA returned %x\n", ret
);
533 ok(GetLastError() == 0xdeadbeef, "LastError is set to %08x\n", GetLastError());
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' */
538 /* Get size, test size and return value/error code (Unicode) */
540 SetLastError(0xdeadbeef);
541 ret
= GetUserObjectInformationW(desk
, UOI_TYPE
, NULL
, 0, &size
);
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 */
547 /* Get string (Unicode) */
548 SetLastError(0xdeadbeef);
550 ret
= GetUserObjectInformationW(desk
, UOI_TYPE
, bufferW
, sizeof(bufferW
), &size
);
552 ok(ret
, "GetUserObjectInformationW returned %x\n", ret
);
553 ok(GetLastError() == 0xdeadbeef, "LastError is set to %08x\n", GetLastError());
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 */
558 ok(CloseDesktop(desk
), "CloseDesktop failed\n");
561 static void test_inputdesktop(void)
563 HDESK input_desk
, old_input_desk
, thread_desk
, old_thread_desk
, new_desk
;
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
;
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
);
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
);
588 ok(old_input_desk
!= input_desk
, "returned the same handle!\n");
589 ret
= CloseDesktop(input_desk
);
590 ok(ret
, "CloseDesktop failed!\n");
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
);
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
);
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
);
615 SetLastError(0xdeadbeef);
616 ret
= SendInput(1, inputs
, sizeof(INPUT
));
617 if(broken(GetLastError() == 0xdeadbeef))
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");
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
);
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
);
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
);
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
);
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
);
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");
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
);
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
);
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
);
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
);
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
);
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
);
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");
725 static void test_inputdesktop2(void)
728 HDESK thread_desk
, new_desk
, input_desk
, hdesk
;
731 thread_desk
= GetThreadDesktop(GetCurrentThreadId());
732 ok(thread_desk
!= NULL
, "GetThreadDesktop failed!\n");
733 w1
= GetProcessWindowStation();
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
);
741 win_skip("Not enough privileges for CreateWindowStation\n");
745 ret
= EnumDesktopsA(GetProcessWindowStation(), desktop_callbackA
, 0);
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");
752 ret
= SetProcessWindowStation(w2
);
753 ok(ret
, "SetProcessWindowStation failed!\n");
754 hdesk
= GetThreadDesktop(GetCurrentThreadId());
755 ok(hdesk
!= NULL
, "GetThreadDesktop failed!\n");
756 ok(hdesk
== thread_desk
, "thread desktop should not change after winstation changed!\n");
757 ret
= EnumDesktopsA(GetProcessWindowStation(), desktop_callbackA
, 0);
759 new_desk
= CreateDesktopA("desk_test", NULL
, NULL
, 0, DESKTOP_ALL_ACCESS
, NULL
);
760 ok(new_desk
!= NULL
, "CreateDesktop failed!\n");
761 ret
= EnumDesktopsA(GetProcessWindowStation(), desktop_callbackA
, 0);
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());
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");
779 /* clean side effect */
780 ret
= SetThreadDesktop(thread_desk
);
782 ok(ret
, "SetThreadDesktop should success even desktop is not belong to process winstation!\n");
783 ret
= SetProcessWindowStation(w1
);
784 ok(ret
, "SetProcessWindowStation failed!\n");
785 ret
= SetThreadDesktop(thread_desk
);
786 ok(ret
, "SetThreadDesktop failed!\n");
787 ret
= CloseWindowStation(w2
);
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");
795 static LRESULT CALLBACK
WndProc(HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
797 if (msg
== WM_DESTROY
)
799 trace("destroying hwnd %p\n", hWnd
);
803 return DefWindowProcA( hWnd
, msg
, wParam
, lParam
);
806 typedef struct tag_wnd_param
808 const char *wnd_name
;
814 static DWORD WINAPI
create_window(LPVOID param
)
816 wnd_param
*param1
= param
;
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");
827 while (GetMessageA(&msg
, 0, 0, 0))
829 TranslateMessage(&msg
);
830 DispatchMessageA(&msg
);
836 static DWORD
set_foreground(HWND hwnd
)
839 DWORD set_id
, fore_id
, ret
;
842 hwnd_fore
= GetForegroundWindow();
843 GetWindowTextA(hwnd_fore
, win_text
, 1024);
844 set_id
= GetWindowThreadProcessId(hwnd
, NULL
);
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
);
849 ret
= ShowWindow(hwnd
, SW_SHOWNORMAL
);
850 trace("ShowWindow returned %08x\n", ret
);
851 ret
= SetWindowPos(hwnd
, HWND_TOPMOST
, 0,0,0,0, SWP_NOSIZE
|SWP_NOMOVE
);
852 trace("set topmost returned %08x\n", ret
);
853 ret
= SetWindowPos(hwnd
, HWND_NOTOPMOST
, 0,0,0,0, SWP_NOSIZE
|SWP_NOMOVE
);
854 trace("set notopmost returned %08x\n", ret
);
855 ret
= SetForegroundWindow(hwnd
);
856 trace("SetForegroundWindow returned %08x\n", ret
);
858 AttachThreadInput(set_id
, fore_id
, FALSE
);
862 static void test_foregroundwindow(void)
864 HWND hwnd
, hwnd_test
, partners
[2], hwnds
[2];
866 int thread_desk_id
, input_desk_id
, hwnd_id
;
869 DWORD ret
, timeout
, timeout_old
;
874 memset( &wclass
, 0, sizeof(wclass
) );
875 wclass
.lpszClassName
= "test_class";
876 wclass
.lpfnWndProc
= WndProc
;
877 RegisterClassA(&wclass
);
878 param
.wnd_name
= "win_name";
880 hdesks
[0] = GetThreadDesktop(GetCurrentThreadId());
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
);
888 win_skip("Not enough privileges for CreateDesktop\n");
892 ret
= SystemParametersInfoA(SPI_GETFOREGROUNDLOCKTIMEOUT
, 0, &timeout_old
, 0);
895 win_skip("Skip tests on NT4\n");
896 CloseDesktop(hdesks
[1]);
899 trace("old timeout %d\n", timeout_old
);
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
);
907 for (thread_desk_id
= 0; thread_desk_id
< DESKTOPS
; thread_desk_id
++)
909 param
.hdesk
= hdesks
[thread_desk_id
];
910 param
.hevent
= CreateEventA(NULL
, TRUE
, FALSE
, NULL
);
911 CreateThread(NULL
, 0, create_window
, ¶m
, 0, NULL
);
912 ret
= WaitForSingleObject(param
.hevent
, INFINITE
);
913 ok(ret
== WAIT_OBJECT_0
, "wait failed!\n");
914 hwnds
[thread_desk_id
] = param
.hwnd
;
917 for (thread_desk_id
= 0; thread_desk_id
< DESKTOPS
; thread_desk_id
++)
919 param
.hdesk
= hdesks
[thread_desk_id
];
920 param
.hevent
= CreateEventA(NULL
, TRUE
, FALSE
, NULL
);
921 CreateThread(NULL
, 0, create_window
, ¶m
, 0, NULL
);
922 ret
= WaitForSingleObject(param
.hevent
, INFINITE
);
923 ok(ret
== WAIT_OBJECT_0
, "wait failed!\n");
924 partners
[thread_desk_id
] = param
.hwnd
;
927 trace("hwnd0 %p hwnd1 %p partner0 %p partner1 %p\n", hwnds
[0], hwnds
[1], partners
[0], partners
[1]);
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
++)
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]);
942 hwnd
= GetForegroundWindow();
943 ok(hwnd
!= hwnd_test
, "unexpected foreground window %p\n", hwnd
);
944 ret
= set_foreground(hwnd_test
);
945 hwnd
= GetForegroundWindow();
946 GetWindowTextA(hwnd
, win_text
, 1024);
947 trace("hwnd %p name %s\n", hwnd
, win_text
);
948 if (input_desk_id
== hwnd_id
)
950 if (input_desk_id
== thread_desk_id
)
952 ok(ret
, "SetForegroundWindow failed!\n");
954 ok(hwnd
== hwnd_test
, "unexpected foreground window %p\n", hwnd
);
958 todo_wine
ok(ret
, "SetForegroundWindow failed!\n");
959 todo_wine
ok(hwnd
== 0, "unexpected foreground window %p\n", hwnd
);
964 if (input_desk_id
== thread_desk_id
)
966 ok(!ret
, "SetForegroundWindow should fail!\n");
968 ok(hwnd
== partners
[input_desk_id
] , "unexpected foreground window %p\n", hwnd
);
972 todo_wine
ok(!ret
, "SetForegroundWindow should fail!\n");
974 ok(hwnd
== 0, "unexpected foreground window %p\n", hwnd
);
981 for (thread_desk_id
= DESKTOPS
- 1; thread_desk_id
>= 0; thread_desk_id
--)
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);
989 ret
= SwitchDesktop(hdesks
[0]);
990 ok(ret
, "switch desktop failed!\n");
991 CloseDesktop(hdesks
[1]);
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
);
1000 START_TEST(winstation
)
1002 HMODULE hntdll
= GetModuleHandleA("ntdll.dll");
1003 pNtQueryObject
= (void *)GetProcAddress(hntdll
, "NtQueryObject");
1005 /* Check whether this platform supports WindowStation calls */
1007 SetLastError( 0xdeadbeef );
1008 GetProcessWindowStation();
1009 if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
)
1011 win_skip("WindowStation calls not supported on this platform\n");
1015 test_inputdesktop();
1016 test_inputdesktop2();
1017 test_enumstations();
1018 test_enumdesktops();
1020 test_getuserobjectinformation();
1021 test_foregroundwindow();