static BOOL CALLBACK open_desktop_callbackA(LPSTR desktop, LPARAM lp) { HDESK hdesk; static int once; trace("open_desktop_callbackA called with argument %s\n", desktop); /* Only try to open one desktop */ if (once++) return lp; hdesk = OpenDesktopA(desktop, 0, FALSE, DESKTOP_ENUMERATE); ok(hdesk != NULL, "Could not open desktop %s!\n", desktop); if (hdesk) CloseDesktop(hdesk); return lp; }
static void test_inputdesktop2(void) { HWINSTA w1, w2; HDESK thread_desk, new_desk, input_desk, hdesk; DWORD ret; thread_desk = GetThreadDesktop(GetCurrentThreadId()); ok(thread_desk != NULL, "GetThreadDesktop failed!\n"); w1 = GetProcessWindowStation(); ok(w1 != NULL, "GetProcessWindowStation failed!\n"); SetLastError(0xdeadbeef); w2 = CreateWindowStationA("winsta_test", 0, WINSTA_ALL_ACCESS, NULL); ret = GetLastError(); ok(w2 != NULL || ret == ERROR_ACCESS_DENIED, "CreateWindowStation failed (%u)\n", ret); if (!w2) { win_skip("Not enough privileges for CreateWindowStation\n"); return; } ret = EnumDesktopsA(GetProcessWindowStation(), desktop_callbackA, 0); ok(!ret, "EnumDesktopsA failed!\n"); input_desk = OpenInputDesktop(0, FALSE, DESKTOP_ALL_ACCESS); ok(input_desk != NULL, "OpenInputDesktop failed!\n"); ret = CloseDesktop(input_desk); ok(ret, "CloseDesktop failed!\n"); ret = SetProcessWindowStation(w2); ok(ret, "SetProcessWindowStation failed!\n"); hdesk = GetThreadDesktop(GetCurrentThreadId()); ok(hdesk != NULL, "GetThreadDesktop failed!\n"); ok(hdesk == thread_desk, "thread desktop should not change after winstation changed!\n"); ret = EnumDesktopsA(GetProcessWindowStation(), desktop_callbackA, 0); new_desk = CreateDesktopA("desk_test", NULL, NULL, 0, DESKTOP_ALL_ACCESS, NULL); ok(new_desk != NULL, "CreateDesktop failed!\n"); ret = EnumDesktopsA(GetProcessWindowStation(), desktop_callbackA, 0); ok(!ret, "EnumDesktopsA failed!\n"); SetLastError(0xdeadbeef); input_desk = OpenInputDesktop(0, FALSE, DESKTOP_ALL_ACCESS); ok(input_desk == NULL, "OpenInputDesktop should fail on non default winstation!\n"); ok(GetLastError() == ERROR_INVALID_FUNCTION || broken(GetLastError() == 0xdeadbeef), "last error %08x\n", GetLastError()); hdesk = OpenDesktopA("desk_test", 0, TRUE, DESKTOP_ALL_ACCESS); ok(hdesk != NULL, "OpenDesktop failed!\n"); SetLastError(0xdeadbeef); ret = SwitchDesktop(hdesk); todo_wine ok(!ret, "Switch to desktop belong to non default winstation should fail!\n"); todo_wine ok(GetLastError() == ERROR_ACCESS_DENIED || broken(GetLastError() == 0xdeadbeef), "last error %08x\n", GetLastError()); ret = SetThreadDesktop(hdesk); ok(ret, "SetThreadDesktop failed!\n"); /* clean side effect */ ret = SetThreadDesktop(thread_desk); todo_wine ok(ret, "SetThreadDesktop should success even desktop is not belong to process winstation!\n"); ret = SetProcessWindowStation(w1); ok(ret, "SetProcessWindowStation failed!\n"); ret = SetThreadDesktop(thread_desk); ok(ret, "SetThreadDesktop failed!\n"); ret = CloseWindowStation(w2); ok(ret, "CloseWindowStation failed!\n"); ret = CloseDesktop(new_desk); ok(ret, "CloseDesktop failed!\n"); ret = CloseDesktop(hdesk); ok(ret, "CloseDesktop failed!\n"); }
static void test_handles(void) { HWINSTA w1, w2, w3; HDESK d1, d2, d3; HANDLE hthread; DWORD id, flags, le; ATOM atom; char buffer[20]; /* win stations */ w1 = GetProcessWindowStation(); ok( GetProcessWindowStation() == w1, "GetProcessWindowStation returned different handles\n" ); ok( !CloseWindowStation(w1), "closing process win station succeeded\n" ); SetLastError( 0xdeadbeef ); ok( !CloseHandle(w1), "closing process win station handle succeeded\n" ); ok( GetLastError() == ERROR_INVALID_HANDLE, "bad last error %d\n", GetLastError() ); print_object( w1 ); flags = 0; ok( GetHandleInformation( w1, &flags ), "GetHandleInformation failed\n" ); ok( !(flags & HANDLE_FLAG_PROTECT_FROM_CLOSE) || broken(flags & HANDLE_FLAG_PROTECT_FROM_CLOSE), /* set on nt4 */ "handle %p PROTECT_FROM_CLOSE set\n", w1 ); ok( DuplicateHandle( GetCurrentProcess(), w1, GetCurrentProcess(), (PHANDLE)&w2, 0, TRUE, DUPLICATE_SAME_ACCESS ), "DuplicateHandle failed\n" ); ok( CloseWindowStation(w2), "closing dup win station failed\n" ); ok( DuplicateHandle( GetCurrentProcess(), w1, GetCurrentProcess(), (PHANDLE)&w2, 0, TRUE, DUPLICATE_SAME_ACCESS ), "DuplicateHandle failed\n" ); ok( CloseHandle(w2), "closing dup win station handle failed\n" ); w2 = CreateWindowStationA("WinSta0", 0, WINSTA_ALL_ACCESS, NULL ); le = GetLastError(); ok( w2 != 0 || le == ERROR_ACCESS_DENIED, "CreateWindowStation failed (%u)\n", le ); if (w2 != 0) { ok( w2 != w1, "CreateWindowStation returned default handle\n" ); SetLastError( 0xdeadbeef ); ok( !CloseDesktop( (HDESK)w2 ), "CloseDesktop succeeded on win station\n" ); ok( GetLastError() == ERROR_INVALID_HANDLE || broken(GetLastError() == 0xdeadbeef), /* wow64 */ "bad last error %d\n", GetLastError() ); ok( CloseWindowStation( w2 ), "CloseWindowStation failed\n" ); w2 = CreateWindowStationA("WinSta0", 0, WINSTA_ALL_ACCESS, NULL ); ok( CloseHandle( w2 ), "CloseHandle failed\n" ); } else if (le == ERROR_ACCESS_DENIED) win_skip( "Not enough privileges for CreateWindowStation\n" ); w2 = OpenWindowStationA("winsta0", TRUE, WINSTA_ALL_ACCESS ); ok( w2 != 0, "OpenWindowStation failed\n" ); ok( w2 != w1, "OpenWindowStation returned default handle\n" ); ok( CloseWindowStation( w2 ), "CloseWindowStation failed\n" ); w2 = OpenWindowStationA("dummy name", TRUE, WINSTA_ALL_ACCESS ); ok( !w2, "open dummy win station succeeded\n" ); CreateMutexA( NULL, 0, "foobar" ); w2 = CreateWindowStationA("foobar", 0, WINSTA_ALL_ACCESS, NULL ); le = GetLastError(); ok( w2 != 0 || le == ERROR_ACCESS_DENIED, "create foobar station failed (%u)\n", le ); if (w2 != 0) { w3 = OpenWindowStationA("foobar", TRUE, WINSTA_ALL_ACCESS ); ok( w3 != 0, "open foobar station failed\n" ); ok( w3 != w2, "open foobar station returned same handle\n" ); ok( CloseWindowStation( w2 ), "CloseWindowStation failed\n" ); ok( CloseWindowStation( w3 ), "CloseWindowStation failed\n" ); w3 = OpenWindowStationA("foobar", TRUE, WINSTA_ALL_ACCESS ); ok( !w3, "open foobar station succeeded\n" ); w2 = CreateWindowStationA("foobar1", 0, WINSTA_ALL_ACCESS, NULL ); ok( w2 != 0, "create foobar station failed\n" ); w3 = CreateWindowStationA("foobar2", 0, WINSTA_ALL_ACCESS, NULL ); ok( w3 != 0, "create foobar station failed\n" ); ok( GetHandleInformation( w2, &flags ), "GetHandleInformation failed\n" ); ok( GetHandleInformation( w3, &flags ), "GetHandleInformation failed\n" ); SetProcessWindowStation( w2 ); atom = GlobalAddAtomA("foo"); ok( GlobalGetAtomNameA( atom, buffer, sizeof(buffer) ) == 3, "GlobalGetAtomName failed\n" ); ok( !lstrcmpiA( buffer, "foo" ), "bad atom value %s\n", buffer ); ok( !CloseWindowStation( w2 ), "CloseWindowStation succeeded\n" ); ok( GetHandleInformation( w2, &flags ), "GetHandleInformation failed\n" ); SetProcessWindowStation( w3 ); ok( GetHandleInformation( w2, &flags ), "GetHandleInformation failed\n" ); ok( CloseWindowStation( w2 ), "CloseWindowStation failed\n" ); ok( GlobalGetAtomNameA( atom, buffer, sizeof(buffer) ) == 3, "GlobalGetAtomName failed\n" ); ok( !lstrcmpiA( buffer, "foo" ), "bad atom value %s\n", buffer ); } else if (le == ERROR_ACCESS_DENIED) win_skip( "Not enough privileges for CreateWindowStation\n" ); /* desktops */ d1 = GetThreadDesktop(GetCurrentThreadId()); initial_desktop = d1; ok( GetThreadDesktop(GetCurrentThreadId()) == d1, "GetThreadDesktop returned different handles\n" ); flags = 0; ok( GetHandleInformation( d1, &flags ), "GetHandleInformation failed\n" ); ok( !(flags & HANDLE_FLAG_PROTECT_FROM_CLOSE), "handle %p PROTECT_FROM_CLOSE set\n", d1 ); SetLastError( 0xdeadbeef ); ok( !CloseDesktop(d1), "closing thread desktop succeeded\n" ); ok( GetLastError() == ERROR_BUSY || broken(GetLastError() == 0xdeadbeef), /* wow64 */ "bad last error %d\n", GetLastError() ); SetLastError( 0xdeadbeef ); if (CloseHandle( d1 )) /* succeeds on nt4 */ { win_skip( "NT4 desktop handle management is completely different\n" ); return; } ok( GetLastError() == ERROR_INVALID_HANDLE, "bad last error %d\n", GetLastError() ); ok( DuplicateHandle( GetCurrentProcess(), d1, GetCurrentProcess(), (PHANDLE)&d2, 0, TRUE, DUPLICATE_SAME_ACCESS ), "DuplicateHandle failed\n" ); ok( CloseDesktop(d2), "closing dup desktop failed\n" ); ok( DuplicateHandle( GetCurrentProcess(), d1, GetCurrentProcess(), (PHANDLE)&d2, 0, TRUE, DUPLICATE_SAME_ACCESS ), "DuplicateHandle failed\n" ); ok( CloseHandle(d2), "closing dup desktop handle failed\n" ); d2 = OpenDesktopA( "dummy name", 0, TRUE, DESKTOP_ALL_ACCESS ); ok( !d2, "open dummy desktop succeeded\n" ); d2 = CreateDesktopA( "foobar", NULL, NULL, 0, DESKTOP_ALL_ACCESS, NULL ); ok( d2 != 0, "create foobar desktop failed\n" ); SetLastError( 0xdeadbeef ); ok( !CloseWindowStation( (HWINSTA)d2 ), "CloseWindowStation succeeded on desktop\n" ); ok( GetLastError() == ERROR_INVALID_HANDLE || broken(GetLastError() == 0xdeadbeef), /* wow64 */ "bad last error %d\n", GetLastError() ); SetLastError( 0xdeadbeef ); d3 = CreateDesktopA( "foobar", NULL, NULL, 0, DESKTOP_ALL_ACCESS, NULL ); ok( d3 != 0, "create foobar desktop again failed\n" ); ok( GetLastError() == 0xdeadbeef, "bad last error %d\n", GetLastError() ); ok( CloseDesktop( d3 ), "CloseDesktop failed\n" ); d3 = OpenDesktopA( "foobar", 0, TRUE, DESKTOP_ALL_ACCESS ); ok( d3 != 0, "open foobar desktop failed\n" ); ok( d3 != d2, "open foobar desktop returned same handle\n" ); ok( CloseDesktop( d2 ), "CloseDesktop failed\n" ); ok( CloseDesktop( d3 ), "CloseDesktop failed\n" ); d3 = OpenDesktopA( "foobar", 0, TRUE, DESKTOP_ALL_ACCESS ); ok( !d3, "open foobar desktop succeeded\n" ); ok( !CloseHandle(d1), "closing thread desktop handle succeeded\n" ); d2 = GetThreadDesktop(GetCurrentThreadId()); ok( d1 == d2, "got different handles after close\n" ); register_class(); trace( "thread 1 desktop: %p\n", d1 ); print_object( d1 ); hthread = CreateThread( NULL, 0, thread, (LPVOID)2, 0, &id ); Sleep(1000); trace( "get other thread desktop: %p\n", GetThreadDesktop(id) ); WaitForSingleObject( hthread, INFINITE ); CloseHandle( hthread ); /* clean side effect */ SetProcessWindowStation( w1 ); }