ReactOS 0.4.15-dev-8236-g99f0937
winstation.c File Reference
#include "wine/test.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winnls.h"
#include "wine/winternl.h"
Include dependency graph for winstation.c:

Go to the source code of this file.

Classes

struct  tag_wnd_param
 

Macros

#define DESKTOP_ALL_ACCESS   0x01ff
 
#define DESKTOPS   2
 

Typedefs

typedef struct tag_wnd_param wnd_param
 

Functions

static NTSTATUS (WINAPI *pNtQueryObject)(HANDLE
 
static void print_object (HANDLE obj)
 
static void register_class (void)
 
static DWORD CALLBACK thread (LPVOID arg)
 
static void test_handles (void)
 
static BOOL CALLBACK window_station_callbackA (LPSTR winsta, LPARAM lp)
 
static BOOL CALLBACK open_window_station_callbackA (LPSTR winsta, LPARAM lp)
 
static void test_enumstations (void)
 
static BOOL CALLBACK desktop_callbackA (LPSTR desktop, LPARAM lp)
 
static BOOL CALLBACK open_desktop_callbackA (LPSTR desktop, LPARAM lp)
 
static void test_enumdesktops (void)
 
static void test_getuserobjectinformation (void)
 
static void test_inputdesktop (void)
 
static void test_inputdesktop2 (void)
 
static LRESULT CALLBACK WndProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
 
static DWORD WINAPI create_window (LPVOID param)
 
static DWORD set_foreground (HWND hwnd)
 
static void test_foregroundwindow (void)
 
 START_TEST (winstation)
 

Variables

static OBJECT_INFORMATION_CLASS
 
static PVOID
 
static ULONG
 
static PULONG
 
static HDESK initial_desktop
 

Macro Definition Documentation

◆ DESKTOP_ALL_ACCESS

#define DESKTOP_ALL_ACCESS   0x01ff

Definition at line 30 of file winstation.c.

◆ DESKTOPS

#define DESKTOPS   2

Typedef Documentation

◆ wnd_param

Function Documentation

◆ create_window()

static DWORD WINAPI create_window ( LPVOID  param)
static

Definition at line 814 of file winstation.c.

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}
#define ok(value,...)
Definition: atltest.h:57
#define msg(x)
Definition: auth_time.c:54
#define NULL
Definition: types.h:112
unsigned long DWORD
Definition: ntddk_ex.h:95
GLfloat param
Definition: glext.h:5796
#define WS_POPUP
Definition: pedump.c:616
const char * wnd_name
Definition: winstation.c:808
HANDLE hevent
Definition: winstation.c:811
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1829
int ret
LRESULT WINAPI DispatchMessageA(_In_ const MSG *)
BOOL WINAPI TranslateMessage(_In_ const MSG *)
BOOL WINAPI SetThreadDesktop(_In_ HDESK)
#define CreateWindowA(a, b, c, d, e, f, g, h, i, j, k)
Definition: winuser.h:4315
BOOL WINAPI GetMessageA(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT)

◆ desktop_callbackA()

static BOOL CALLBACK desktop_callbackA ( LPSTR  desktop,
LPARAM  lp 
)
static

Definition at line 392 of file winstation.c.

393{
394 trace("desktop_callbackA called with argument %s\n", desktop);
395 return lp;
396}
#define trace
Definition: atltest.h:70

Referenced by test_enumdesktops(), and test_inputdesktop2().

◆ NTSTATUS()

static NTSTATUS ( WINAPI pNtQueryObject)
static

◆ open_desktop_callbackA()

static BOOL CALLBACK open_desktop_callbackA ( LPSTR  desktop,
LPARAM  lp 
)
static

Definition at line 398 of file winstation.c.

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}
#define FALSE
Definition: types.h:117
HDESK WINAPI OpenDesktopA(_In_ LPCSTR, _In_ DWORD, _In_ BOOL, _In_ DWORD)
#define DESKTOP_ENUMERATE
Definition: winuser.h:218
BOOL WINAPI CloseDesktop(_In_ HDESK)

Referenced by test_enumdesktops().

◆ open_window_station_callbackA()

static BOOL CALLBACK open_window_station_callbackA ( LPSTR  winsta,
LPARAM  lp 
)
static

Definition at line 347 of file winstation.c.

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}
HWINSTA WINAPI OpenWindowStationA(_In_ LPCSTR, _In_ BOOL, _In_ DWORD)
BOOL WINAPI CloseWindowStation(_In_ HWINSTA)
#define WINSTA_ENUMERATE
Definition: winuser.h:412

Referenced by test_enumstations().

◆ print_object()

static void print_object ( HANDLE  obj)
static

Definition at line 32 of file winstation.c.

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}
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
GLsizeiptr size
Definition: glext.h:5919
GLuint buffer
Definition: glext.h:5915
#define UOI_NAME
Definition: winuser.h:1084
#define UOI_TYPE
Definition: winuser.h:1085
BOOL WINAPI GetUserObjectInformationA(_In_ HANDLE hObj, _In_ int nIndex, _Out_writes_bytes_opt_(nLength) PVOID pvInfo, _In_ DWORD nLength, _Out_opt_ LPDWORD lpnLengthNeeded)

Referenced by test_handles(), and thread().

◆ register_class()

static void register_class ( void  )
static

Definition at line 49 of file winstation.c.

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}
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
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
HGDIOBJ WINAPI GetStockObject(_In_ int)
#define WHITE_BRUSH
Definition: wingdi.h:902
LRESULT WINAPI DefWindowProcA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define IDC_ARROW
Definition: winuser.h:687
#define CS_DBLCLKS
Definition: winuser.h:651
ATOM WINAPI RegisterClassA(_In_ CONST WNDCLASSA *)
HCURSOR WINAPI LoadCursorA(_In_opt_ HINSTANCE, _In_ LPCSTR)
Definition: cursoricon.c:2121
const char * LPCSTR
Definition: xmlstorage.h:183

Referenced by test_handles().

◆ set_foreground()

static DWORD set_foreground ( HWND  hwnd)
static

Definition at line 836 of file winstation.c.

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}
#define TRUE
Definition: types.h:120
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
int WINAPI GetWindowTextA(HWND hWnd, LPSTR lpString, int nMaxCount)
Definition: window.c:1330
DWORD WINAPI GetWindowThreadProcessId(HWND hWnd, PDWORD lpdwProcessId)
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
#define SW_SHOWNORMAL
Definition: winuser.h:770
BOOL WINAPI ShowWindow(_In_ HWND, _In_ int)
HWND WINAPI GetForegroundWindow(void)
Definition: ntwrapper.h:392
#define HWND_TOPMOST
Definition: winuser.h:1208
BOOL WINAPI AttachThreadInput(_In_ DWORD, _In_ DWORD, _In_ BOOL)
BOOL WINAPI SetWindowPos(_In_ HWND, _In_opt_ HWND, _In_ int, _In_ int, _In_ int, _In_ int, _In_ UINT)
#define SWP_NOMOVE
Definition: winuser.h:1244
BOOL WINAPI SetForegroundWindow(_In_ HWND)
#define SWP_NOSIZE
Definition: winuser.h:1245
#define HWND_NOTOPMOST
Definition: winuser.h:1206

Referenced by test_foregroundwindow().

◆ START_TEST()

START_TEST ( winstation  )

Definition at line 1000 of file winstation.c.

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}
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:102
#define SetLastError(x)
Definition: compat.h:752
#define GetProcAddress(x, y)
Definition: compat.h:753
static HINSTANCE hntdll
Definition: process.c:66
#define win_skip
Definition: test.h:163
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
HWINSTA WINAPI GetProcessWindowStation(void)
Definition: ntwrapper.h:124
static void test_inputdesktop(void)
Definition: winstation.c:561
static void test_foregroundwindow(void)
Definition: winstation.c:862
static void test_enumdesktops(void)
Definition: winstation.c:415
static void test_getuserobjectinformation(void)
Definition: winstation.c:450
static void test_inputdesktop2(void)
Definition: winstation.c:725
static void test_enumstations(void)
Definition: winstation.c:359
static void test_handles(void)
Definition: winstation.c:109

◆ test_enumdesktops()

static void test_enumdesktops ( void  )
static

Definition at line 415 of file winstation.c.

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}
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
unsigned int BOOL
Definition: ntddk_ex.h:94
static BOOL CALLBACK desktop_callbackA(LPSTR desktop, LPARAM lp)
Definition: winstation.c:392
static BOOL CALLBACK open_desktop_callbackA(LPSTR desktop, LPARAM lp)
Definition: winstation.c:398
BOOL WINAPI EnumDesktopsA(_In_opt_ HWINSTA, _In_ DESKTOPENUMPROCA, _In_ LPARAM)

Referenced by START_TEST().

◆ test_enumstations()

static void test_enumstations ( void  )
static

Definition at line 359 of file winstation.c.

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}
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
static BOOL CALLBACK window_station_callbackA(LPSTR winsta, LPARAM lp)
Definition: winstation.c:341
static BOOL CALLBACK open_window_station_callbackA(LPSTR winsta, LPARAM lp)
Definition: winstation.c:347
HWINSTA WINAPI CreateWindowStationA(_In_opt_ LPCSTR lpwinsta, _In_ DWORD dwFlags, _In_ ACCESS_MASK dwDesiredAccess, _In_opt_ LPSECURITY_ATTRIBUTES lpsa)
BOOL WINAPI EnumWindowStationsA(_In_ WINSTAENUMPROCA, _In_ LPARAM lParam)
#define WINSTA_ALL_ACCESS
Definition: winuser.h:417

Referenced by START_TEST().

◆ test_foregroundwindow()

static void test_foregroundwindow ( void  )
static

Definition at line 862 of file winstation.c.

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}
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
#define INFINITE
Definition: serial.h:102
#define UlongToPtr(u)
Definition: config.h:106
static HWND create_window(void)
Definition: imagelist.c:163
#define todo_wine_if(is_todo)
Definition: custom.c:76
#define todo_wine
Definition: custom.c:79
#define memset(x, y, z)
Definition: compat.h:39
Definition: dhcpd.h:245
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventA(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCSTR lpName OPTIONAL)
Definition: synch.c:637
HDESK WINAPI CreateDesktopA(LPCSTR lpszDesktop, LPCSTR lpszDevice, LPDEVMODEA pDevmode, DWORD dwFlags, ACCESS_MASK dwDesiredAccess, LPSECURITY_ATTRIBUTES lpsa)
Definition: desktop.c:431
DWORD WINAPI GetCurrentThreadId(void)
Definition: thread.c:459
#define WAIT_OBJECT_0
Definition: winbase.h:406
#define DESKTOPS
static DWORD set_foreground(HWND hwnd)
Definition: winstation.c:836
#define DESKTOP_ALL_ACCESS
Definition: winstation.c:30
static LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
Definition: winstation.c:795
HDESK WINAPI GetThreadDesktop(_In_ DWORD)
BOOL WINAPI SwitchDesktop(_In_ HDESK)
LRESULT WINAPI SendMessageA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define SPIF_SENDCHANGE
Definition: winuser.h:1572
#define SPIF_UPDATEINIFILE
Definition: winuser.h:1571
BOOL WINAPI SystemParametersInfoA(_In_ UINT uiAction, _In_ UINT uiParam, _Inout_opt_ PVOID pvParam, _In_ UINT fWinIni)
#define WM_DESTROY
Definition: winuser.h:1609

Referenced by START_TEST().

◆ test_getuserobjectinformation()

static void test_getuserobjectinformation ( void  )
static

Tests for UOI_NAME

Tests for UOI_TYPE

Definition at line 450 of file winstation.c.

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}
@ ObjectNameInformation
Definition: DriverTester.h:55
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
LONG NTSTATUS
Definition: precomp.h:26
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
int WINAPI lstrcmpW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4242
#define wine_dbgstr_w
Definition: kernel32.h:34
UNICODE_STRING Name
Definition: nt_native.h:1270
Definition: ps.c:97
BOOL WINAPI GetUserObjectInformationW(_In_ HANDLE hObj, _In_ int nIndex, _Out_writes_bytes_opt_(nLength) PVOID pvInfo, _In_ DWORD nLength, _Out_opt_ LPDWORD lpnLengthNeeded)
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by START_TEST().

◆ test_handles()

static void test_handles ( void  )
static

Definition at line 109 of file winstation.c.

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}
#define broken(x)
Definition: _sntprintf.h:21
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
static HANDLE thread
Definition: service.c:33
#define ERROR_BUSY
Definition: dderror.h:12
WORD ATOM
Definition: dimm.idl:113
#define CloseHandle
Definition: compat.h:739
#define GetCurrentProcess()
Definition: compat.h:759
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
int WINAPI lstrcmpiA(LPCSTR str1, LPCSTR str2)
Definition: locale.c:4223
GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint GLdouble GLdouble w2
Definition: glext.h:8308
GLbitfield flags
Definition: glext.h:7161
GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint GLdouble w1
Definition: glext.h:8308
GLuint id
Definition: glext.h:5910
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
HANDLE WINAPI DECLSPEC_HOTPATCH CreateMutexA(IN LPSECURITY_ATTRIBUTES lpMutexAttributes OPTIONAL, IN BOOL bInitialOwner, IN LPCSTR lpName OPTIONAL)
Definition: synch.c:563
#define HANDLE_FLAG_PROTECT_FROM_CLOSE
Definition: winbase.h:265
#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 void print_object(HANDLE obj)
Definition: winstation.c:32
static HDESK initial_desktop
Definition: winstation.c:66
BOOL WINAPI SetProcessWindowStation(_In_ HWINSTA)
#define DUPLICATE_SAME_ACCESS

Referenced by START_TEST(), test_data_handles(), and test_handles_thread().

◆ test_inputdesktop()

static void test_inputdesktop ( void  )
static

Definition at line 561 of file winstation.c.

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}
#define U(x)
Definition: wordpad.c:45
Definition: name.c:39
DWORD type
Definition: winable.h:59
UINT WINAPI SendInput(UINT, LPINPUT, int)
Definition: ntwrapper.h:344
#define INPUT_KEYBOARD
Definition: winable.h:10
HDESK WINAPI OpenInputDesktop(_In_ DWORD, _In_ BOOL, _In_ DWORD)
char CHAR
Definition: xmlstorage.h:175

Referenced by START_TEST().

◆ test_inputdesktop2()

static void test_inputdesktop2 ( void  )
static

Definition at line 725 of file winstation.c.

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}
#define ERROR_INVALID_FUNCTION
Definition: dderror.h:6

Referenced by START_TEST().

◆ thread()

static DWORD CALLBACK thread ( LPVOID  arg)
static

Definition at line 68 of file winstation.c.

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}
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)
HWND WINAPI GetDesktopWindow(void)
Definition: window.c:656
BOOL WINAPI DestroyWindow(_In_ HWND)

◆ window_station_callbackA()

static BOOL CALLBACK window_station_callbackA ( LPSTR  winsta,
LPARAM  lp 
)
static

Definition at line 341 of file winstation.c.

342{
343 trace("window_station_callbackA called with argument %s\n", winsta);
344 return lp;
345}

Referenced by test_enumstations().

◆ WndProc()

static LRESULT CALLBACK WndProc ( HWND  hWnd,
UINT  msg,
WPARAM  wParam,
LPARAM  lParam 
)
static

Definition at line 795 of file winstation.c.

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}
HWND hWnd
Definition: settings.c:17
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
__analysis_noreturn void WINAPI PostQuitMessage(_In_ int)

Referenced by test_foregroundwindow().

Variable Documentation

◆ initial_desktop

HDESK initial_desktop
static

Definition at line 66 of file winstation.c.

Referenced by test_handles(), and thread().

◆ OBJECT_INFORMATION_CLASS

Definition at line 28 of file winstation.c.

◆ PULONG

Definition at line 28 of file winstation.c.

◆ PVOID

Definition at line 28 of file winstation.c.

◆ ULONG

Definition at line 28 of file winstation.c.