[USBSTOR]
[reactos.git] / rostests / apitests / user32 / desktop.c
1 /*
2 * PROJECT: ReactOS api tests
3 * LICENSE: GPL - See COPYING in the top level directory
4 * PURPOSE: Test for desktop objects
5 * PROGRAMMERS: Giannis Adamopoulos
6 */
7
8 #include <apitest.h>
9
10 #include <stdio.h>
11 #include <wingdi.h>
12 #include <winuser.h>
13 #include "helper.h"
14
15 #define STATUS_DLL_INIT_FAILED (0xC0000142)
16 #define DESKTOP_ALL_ACCESS 0x01ff
17
18 struct test_info {
19 WCHAR* ExpectedWinsta;
20 WCHAR* ExpectedDesktp;
21 };
22
23 struct test_info TestResults[] = {{L"WinSta0",L"Default"},
24 {L"WinSta0",L"Default"},
25 {L"WinSta0",L"Default"},
26 {NULL, NULL},
27 {NULL, NULL},
28 {NULL, NULL},
29 {NULL, NULL},
30 {L"WinSta0",L"Default"},
31 {L"TestWinsta", L"TestDesktop"},
32 {NULL, NULL}};
33
34 void do_InitialDesktop_child(int i)
35 {
36 HDESK hdesktop;
37 HWINSTA hwinsta;
38 WCHAR buffer[100];
39 DWORD size;
40 BOOL ret;
41
42 if(TestResults[i].ExpectedWinsta == NULL)
43 {
44 trace("Process should have failed to initialize\n");
45 return;
46 }
47
48 IsGUIThread(TRUE);
49
50 hdesktop = GetThreadDesktop(GetCurrentThreadId());
51 hwinsta = GetProcessWindowStation();
52
53 ret = GetUserObjectInformationW( hwinsta, UOI_NAME, buffer, sizeof(buffer), &size );
54 ok(ret == TRUE, "ret = %d\n", ret);
55 ok(wcscmp(buffer, TestResults[i].ExpectedWinsta) == 0, "Wrong winsta %S insted of %S\n", buffer, TestResults[i].ExpectedWinsta);
56
57 ret = GetUserObjectInformationW( hdesktop, UOI_NAME, buffer, sizeof(buffer), &size );
58 ok(ret == TRUE, "ret = %d\n", ret);
59 ok(wcscmp(buffer, TestResults[i].ExpectedDesktp) == 0, "Wrong desktop %S insted of %S\n", buffer, TestResults[i].ExpectedDesktp);
60 }
61
62 void test_CreateProcessWithDesktop(int i, char *argv0, char* Desktop, DWORD expectedExitCode)
63 {
64 STARTUPINFOA startup;
65 char path[MAX_PATH];
66 BOOL ret;
67 DWORD ExitCode;
68 PROCESS_INFORMATION pi;
69
70 memset( &startup, 0, sizeof(startup) );
71 startup.cb = sizeof(startup);
72 startup.dwFlags = STARTF_USESHOWWINDOW;
73 startup.wShowWindow = SW_SHOWNORMAL;
74 startup.lpDesktop = Desktop;
75
76 sprintf( path, "%s desktop %u", argv0, i );
77 ret = CreateProcessA( NULL, path, NULL, NULL, TRUE, 0, NULL, NULL, &startup, &pi );
78 ok( ret, "%d: CreateProcess '%s' failed err %d.\n", i, path, (int)GetLastError() );
79 WaitForSingleObject (pi.hProcess, INFINITE);
80 ret = GetExitCodeProcess(pi.hProcess, &ExitCode);
81 ok(ret > 0 , "%d: GetExitCodeProcess failed\n", i);
82
83 /* the exit code varies from version to version */
84 /* xp returns error 128 and 7 returns STATUS_DLL_INIT_FAILED */
85 if(ExitCode == 128) ExitCode = STATUS_DLL_INIT_FAILED;
86
87 ok(ExitCode == expectedExitCode, "%d: expected error 0x%x in child process got 0x%x\n", i, (int)expectedExitCode, (int)ExitCode);
88
89 CloseHandle(pi.hProcess);
90 }
91
92 HWINSTA CreateInheritableWinsta(WCHAR* name, ACCESS_MASK dwDesiredAccess, BOOL inheritable)
93 {
94 SECURITY_ATTRIBUTES sa;
95 sa.nLength = sizeof(sa);
96 sa.lpSecurityDescriptor = NULL;
97 sa.bInheritHandle = inheritable;
98 return CreateWindowStationW(name, 0, dwDesiredAccess, &sa );
99 }
100
101 HDESK CreateInheritableDesktop(WCHAR* name, ACCESS_MASK dwDesiredAccess, BOOL inheritable)
102 {
103 SECURITY_ATTRIBUTES sa;
104 sa.nLength = sizeof(sa);
105 sa.lpSecurityDescriptor = NULL;
106 sa.bInheritHandle = inheritable;
107 return CreateDesktopW(name, NULL, NULL, 0, dwDesiredAccess, &sa );
108 }
109
110 void Test_InitialDesktop(char *argv0)
111 {
112 HWINSTA hwinsta = NULL, hwinstaInitial;
113 HDESK hdesktop = NULL;
114 BOOL ret;
115
116 hwinstaInitial = GetProcessWindowStation();
117
118 test_CreateProcessWithDesktop(0, argv0, NULL, 0);
119 test_CreateProcessWithDesktop(1, argv0, "Default", 0);
120 test_CreateProcessWithDesktop(2, argv0, "WinSta0\\Default", 0);
121 test_CreateProcessWithDesktop(3, argv0, "Winlogon", STATUS_DLL_INIT_FAILED);
122 test_CreateProcessWithDesktop(4, argv0, "WinSta0/Default", STATUS_DLL_INIT_FAILED);
123 test_CreateProcessWithDesktop(5, argv0, "NonExistantDesktop", STATUS_DLL_INIT_FAILED);
124 test_CreateProcessWithDesktop(6, argv0, "NonExistantWinsta\\NonExistantDesktop", STATUS_DLL_INIT_FAILED);
125
126 hwinsta = CreateInheritableWinsta(L"TestWinsta", WINSTA_ALL_ACCESS, TRUE);
127 ok(hwinsta!=NULL, "CreateWindowStation failed\n");
128 ret = SetProcessWindowStation(hwinsta);
129 ok(ret != 0, "SetProcessWindowStation failed\n");
130 hdesktop = CreateInheritableDesktop(L"TestDesktop", DESKTOP_ALL_ACCESS, TRUE);
131 ok(hdesktop!=NULL, "CreateDesktop failed\n");
132
133 test_CreateProcessWithDesktop(7, argv0, NULL, 0);
134 test_CreateProcessWithDesktop(8, argv0, "TestWinsta\\TestDesktop", 0);
135 test_CreateProcessWithDesktop(8, argv0, "NonExistantWinsta\\NonExistantDesktop", STATUS_DLL_INIT_FAILED);
136
137 ret = SetProcessWindowStation(hwinstaInitial);
138 ok(ret != 0, "SetProcessWindowStation failed\n");
139
140 ret = CloseDesktop(hdesktop);
141 ok(ret != 0, "CloseDesktop failed\n");
142
143 ret = CloseWindowStation(hwinsta);
144 ok(ret != 0, "CloseWindowStation failed\n");
145 }
146
147 void Test_OpenInputDesktop()
148 {
149 HDESK hDeskInput ,hDeskInput2;
150 HDESK hDeskInitial;
151 BOOL ret;
152 HWINSTA hwinsta = NULL, hwinstaInitial;
153 DWORD err;
154
155 hDeskInput = OpenInputDesktop(0, FALSE, DESKTOP_ALL_ACCESS);
156 ok(hDeskInput != NULL, "OpenInputDesktop failed\n");
157 hDeskInitial = GetThreadDesktop( GetCurrentThreadId() );
158 ok(hDeskInitial != NULL, "GetThreadDesktop failed\n");
159 ok(hDeskInput != hDeskInitial, "OpenInputDesktop returned thread desktop\n");
160
161 hDeskInput2 = OpenInputDesktop(0, FALSE, DESKTOP_ALL_ACCESS);
162 ok(hDeskInput2 != NULL, "Second call to OpenInputDesktop failed\n");
163 ok(hDeskInput2 != hDeskInput, "Second call to OpenInputDesktop returned same handle\n");
164
165 ok(CloseDesktop(hDeskInput2) != 0, "CloseDesktop failed\n");
166
167 ret = SetThreadDesktop(hDeskInput);
168 ok(ret == TRUE, "SetThreadDesktop for input desktop failed\n");
169
170 ret = SetThreadDesktop(hDeskInitial);
171 ok(ret == TRUE, "SetThreadDesktop for initial desktop failed\n");
172
173 ok(CloseDesktop(hDeskInput) != 0, "CloseDesktop failed\n");
174
175 /* Try calling OpenInputDesktop after switching to a new winsta */
176 hwinstaInitial = GetProcessWindowStation();
177 ok(hwinstaInitial != 0, "GetProcessWindowStation failed\n");
178
179 hwinsta = CreateWindowStationW(L"TestWinsta", 0, WINSTA_ALL_ACCESS, NULL);
180 ok(hwinsta != 0, "CreateWindowStationW failed\n");
181
182 ret = SetProcessWindowStation(hwinsta);
183 ok(ret != 0, "SetProcessWindowStation failed\n");
184
185 hDeskInput = OpenInputDesktop(0, FALSE, DESKTOP_ALL_ACCESS);
186 ok(hDeskInput == 0, "OpenInputDesktop should fail\n");
187
188 err = GetLastError();
189 ok(err == ERROR_INVALID_FUNCTION, "Got last error: %lu\n", err);
190
191 ret = SetProcessWindowStation(hwinstaInitial);
192 ok(ret != 0, "SetProcessWindowStation failed\n");
193
194 ret = CloseWindowStation(hwinsta);
195 ok(ret != 0, "CloseWindowStation failed\n");
196
197 }
198
199 START_TEST(desktop)
200 {
201 char **test_argv;
202 int argc = winetest_get_mainargs( &test_argv );
203
204 /* this program tests some cases that a child application fails to initialize */
205 /* to test this behaviour properly we have to disable error messages */
206 //SetErrorMode( SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX );
207
208 if (argc >= 3)
209 {
210 unsigned int arg;
211 /* Child process. */
212 sscanf (test_argv[2], "%d", (unsigned int *) &arg);
213 do_InitialDesktop_child( arg );
214 return;
215 }
216
217 Test_InitialDesktop(test_argv[0]);
218 Test_OpenInputDesktop();
219 }