ReactOS 0.4.15-dev-7961-gdcf9eb0
desktop.c File Reference
#include "precomp.h"
#include <ndk/obfuncs.h>
Include dependency graph for desktop.c:

Go to the source code of this file.

Classes

struct  test_info
 

Macros

#define check_ref(handle, hdlcnt, ptrcnt)
 

Functions

void do_InitialDesktop_child (int i)
 
void test_CreateProcessWithDesktop (int i, char *argv0, char *Desktop, DWORD expectedExitCode)
 
HWINSTA CreateInheritableWinsta (WCHAR *name, ACCESS_MASK dwDesiredAccess, BOOL inheritable, DWORD *error)
 
HDESK CreateInheritableDesktop (WCHAR *name, ACCESS_MASK dwDesiredAccess, BOOL inheritable, DWORD *error)
 
void Test_InitialDesktop (char *argv0)
 
void Test_OpenInputDesktop ()
 
static HWINSTA open_winsta (PCWSTR winstaName, DWORD *error)
 
static HWINSTA create_winsta (PCWSTR winstaName, DWORD *error)
 
static HDESK open_desk (PCWSTR deskName, DWORD *error)
 
static HDESK create_desk (PCWSTR deskName, DWORD *error)
 
static void Test_References (void)
 
 START_TEST (desktop)
 

Variables

static struct test_info TestResults []
 

Macro Definition Documentation

◆ check_ref

#define check_ref (   handle,
  hdlcnt,
  ptrcnt 
)
Value:
status = NtQueryObject(handle, ObjectBasicInformation, &objectInfo, sizeof(objectInfo), NULL); \
ok(status == STATUS_SUCCESS, "status = 0x%lx\n", status); \
ok(objectInfo.HandleCount == (hdlcnt), "HandleCount = %lu, expected %lu\n", objectInfo.HandleCount, (ULONG)(hdlcnt)); \
ok(objectInfo.PointerCount == (ptrcnt), "PointerCount = %lu, expected %lu\n", objectInfo.PointerCount, (ULONG)(ptrcnt));
@ ObjectBasicInformation
Definition: DriverTester.h:54
NTSTATUS NtQueryObject(IN HANDLE Handle, IN OBJECT_INFO_CLASS ObjectInformationClass, OUT PVOID ObjectInformation, IN ULONG ObjectInformationLength, OUT PULONG ReturnLength)
#define NULL
Definition: types.h:112
#define STATUS_SUCCESS
Definition: shellext.h:65
Definition: ps.c:97
uint32_t ULONG
Definition: typedefs.h:59

Function Documentation

◆ create_desk()

static HDESK create_desk ( PCWSTR  deskName,
DWORD error 
)
static

Definition at line 270 of file desktop.c.

271{
272 HDESK hdesk;
273 SetLastError(0xfeedf00d);
274 hdesk = CreateDesktopW(deskName, NULL, NULL, 0, DESKTOP_ALL_ACCESS, NULL);
275 *error = GetLastError();
276 return hdesk;
277}
#define SetLastError(x)
Definition: compat.h:752
#define error(str)
Definition: mkdosfs.c:1605
#define DESKTOP_ALL_ACCESS
Definition: precomp.h:22
HDESK WINAPI CreateDesktopW(LPCWSTR lpszDesktop, LPCWSTR lpszDevice, LPDEVMODEW pDevmode, DWORD dwFlags, ACCESS_MASK dwDesiredAccess, LPSECURITY_ATTRIBUTES lpsa)
Definition: desktop.c:473
DWORD WINAPI GetLastError(void)
Definition: except.c:1042

Referenced by Test_References().

◆ create_winsta()

static HWINSTA create_winsta ( PCWSTR  winstaName,
DWORD error 
)
static

Definition at line 252 of file desktop.c.

253{
254 HWINSTA hwinsta;
255 SetLastError(0xfeedf00d);
256 hwinsta = CreateWindowStationW(winstaName, 0, WINSTA_ALL_ACCESS, NULL);
257 *error = GetLastError();
258 return hwinsta;
259}
HWINSTA WINAPI CreateWindowStationW(_In_opt_ LPCWSTR lpwinsta, _In_ DWORD dwFlags, _In_ ACCESS_MASK dwDesiredAccess, _In_opt_ LPSECURITY_ATTRIBUTES lpsa)
#define WINSTA_ALL_ACCESS
Definition: winuser.h:417

Referenced by Test_References().

◆ CreateInheritableDesktop()

HDESK CreateInheritableDesktop ( WCHAR name,
ACCESS_MASK  dwDesiredAccess,
BOOL  inheritable,
DWORD error 
)

Definition at line 111 of file desktop.c.

112{
113 HDESK hdesk;
115 sa.nLength = sizeof(sa);
116 sa.lpSecurityDescriptor = NULL;
117 sa.bInheritHandle = inheritable;
118 SetLastError(0xfeedf00d);
119 hdesk = CreateDesktopW(name, NULL, NULL, 0, dwDesiredAccess, &sa);
120 *error = GetLastError();
121 return hdesk;
122}
static struct sockaddr_in sa
Definition: adnsresfilter.c:69
Definition: name.c:39

Referenced by Test_InitialDesktop().

◆ CreateInheritableWinsta()

HWINSTA CreateInheritableWinsta ( WCHAR name,
ACCESS_MASK  dwDesiredAccess,
BOOL  inheritable,
DWORD error 
)

Definition at line 98 of file desktop.c.

99{
100 HWINSTA hwinsta;
102 sa.nLength = sizeof(sa);
103 sa.lpSecurityDescriptor = NULL;
104 sa.bInheritHandle = inheritable;
105 SetLastError(0xfeedf00d);
106 hwinsta = CreateWindowStationW(name, 0, dwDesiredAccess, &sa);
107 *error = GetLastError();
108 return hwinsta;
109}

Referenced by Test_InitialDesktop().

◆ do_InitialDesktop_child()

void do_InitialDesktop_child ( int  i)

Definition at line 39 of file desktop.c.

40{
41 HDESK hdesktop;
42 HWINSTA hwinsta;
43 WCHAR buffer[100];
44 DWORD size;
45 BOOL ret;
46
47 if (TestResults[i].ExpectedWinsta == NULL)
48 ok(FALSE, "%d: Process should have failed to initialize\n", i);
49
51
53 hwinsta = GetProcessWindowStation();
54
55 ret = GetUserObjectInformationW( hwinsta, UOI_NAME, buffer, sizeof(buffer), &size );
56 ok(ret == TRUE, "ret = %d\n", ret);
57 if (TestResults[i].ExpectedWinsta)
58 ok(wcscmp(buffer, TestResults[i].ExpectedWinsta) == 0, "%d: Wrong winsta %S instead of %S\n", i, buffer, TestResults[i].ExpectedWinsta);
59 trace("%d: We run on winstation %S\n", i, buffer);
60
61 ret = GetUserObjectInformationW( hdesktop, UOI_NAME, buffer, sizeof(buffer), &size );
62 ok(ret == TRUE, "ret = %d\n", ret);
63 if (TestResults[i].ExpectedDesktp)
64 ok(wcscmp(buffer, TestResults[i].ExpectedDesktp) == 0, "%d: Wrong desktop %S instead of %S\n", i, buffer, TestResults[i].ExpectedDesktp);
65 trace("%d: We run on desktop %S\n", i, buffer);
66}
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLsizeiptr size
Definition: glext.h:5919
GLuint buffer
Definition: glext.h:5915
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static struct test_info TestResults[]
Definition: desktop.c:18
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
int ret
BOOL WINAPI IsGUIThread(BOOL bConvert)
Definition: misc.c:145
DWORD WINAPI GetCurrentThreadId(void)
Definition: thread.c:459
HWINSTA WINAPI GetProcessWindowStation(void)
Definition: ntwrapper.h:124
HDESK WINAPI GetThreadDesktop(_In_ DWORD)
#define UOI_NAME
Definition: winuser.h:1084
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().

◆ open_desk()

static HDESK open_desk ( PCWSTR  deskName,
DWORD error 
)
static

Definition at line 261 of file desktop.c.

262{
263 HDESK hdesk;
264 SetLastError(0xfeedf00d);
265 hdesk = OpenDesktopW(deskName, 0, FALSE, DESKTOP_ALL_ACCESS);
266 *error = GetLastError();
267 return hdesk;
268}
HDESK WINAPI OpenDesktopW(_In_ LPCWSTR, _In_ DWORD, _In_ BOOL, _In_ DWORD)

Referenced by Test_References().

◆ open_winsta()

static HWINSTA open_winsta ( PCWSTR  winstaName,
DWORD error 
)
static

Definition at line 243 of file desktop.c.

244{
245 HWINSTA hwinsta;
246 SetLastError(0xfeedf00d);
247 hwinsta = OpenWindowStationW(winstaName, FALSE, WINSTA_ALL_ACCESS);
248 *error = GetLastError();
249 return hwinsta;
250}
HWINSTA WINAPI OpenWindowStationW(_In_ LPCWSTR, _In_ BOOL, _In_ DWORD)

Referenced by Test_References().

◆ START_TEST()

START_TEST ( desktop  )

Definition at line 403 of file desktop.c.

404{
405 char **test_argv;
407
408 /* this program tests some cases that a child application fails to initialize */
409 /* to test this behaviour properly we have to disable error messages */
410 //SetErrorMode( SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX );
411
412 if (argc >= 3)
413 {
414 unsigned int arg;
415 /* Child process. */
416 sscanf (test_argv[2], "%d", (unsigned int *) &arg);
418 return;
419 }
420
424}
static int argc
Definition: ServiceArgs.c:12
_Check_return_ _CRTIMP int __cdecl sscanf(_In_z_ const char *_Src, _In_z_ _Scanf_format_string_ const char *_Format,...)
void do_InitialDesktop_child(int i)
Definition: desktop.c:39
void Test_OpenInputDesktop()
Definition: desktop.c:191
static void Test_References(void)
Definition: desktop.c:279
void Test_InitialDesktop(char *argv0)
Definition: desktop.c:124
static char ** test_argv
Definition: cursoricon.c:296
int winetest_get_mainargs(char ***pargv)
void * arg
Definition: msvc.h:10

◆ test_CreateProcessWithDesktop()

void test_CreateProcessWithDesktop ( int  i,
char argv0,
char Desktop,
DWORD  expectedExitCode 
)

Definition at line 68 of file desktop.c.

69{
71 char path[MAX_PATH];
72 BOOL ret;
73 DWORD ExitCode;
75
76 memset( &startup, 0, sizeof(startup) );
77 startup.cb = sizeof(startup);
79 startup.wShowWindow = SW_SHOWNORMAL;
80 startup.lpDesktop = Desktop;
81
82 sprintf( path, "%s desktop %u", argv0, i );
84 ok( ret, "%d: CreateProcess '%s' failed err %d.\n", i, path, (int)GetLastError() );
86 ret = GetExitCodeProcess(pi.hProcess, &ExitCode);
87 ok(ret > 0 , "%d: GetExitCodeProcess failed\n", i);
88
89 /* the exit code varies from version to version */
90 /* xp returns error 128 and 7 returns STATUS_DLL_INIT_FAILED */
91 if (ExitCode == 128) ExitCode = STATUS_DLL_INIT_FAILED;
92
93 ok(ExitCode == expectedExitCode, "%d: expected error 0x%x in child process got 0x%x\n", i, (int)expectedExitCode, (int)ExitCode);
94
95 CloseHandle(pi.hProcess);
96}
static void startup(void)
#define CloseHandle
Definition: compat.h:739
#define MAX_PATH
Definition: compat.h:34
BOOL WINAPI GetExitCodeProcess(IN HANDLE hProcess, IN LPDWORD lpExitCode)
Definition: proc.c:1168
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessA(LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
Definition: proc.c:4741
#define INFINITE
Definition: serial.h:102
#define sprintf(buf, format,...)
Definition: sprintf.c:55
static refpint_t pi[]
Definition: server.c:96
#define STATUS_DLL_INIT_FAILED
Definition: ntstatus.h:558
#define memset(x, y, z)
Definition: compat.h:39
static char argv0[MAX_PATH]
Definition: shlexec.c:49
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
#define STARTF_USESHOWWINDOW
Definition: winbase.h:491
#define SW_SHOWNORMAL
Definition: winuser.h:770

Referenced by Test_InitialDesktop().

◆ Test_InitialDesktop()

void Test_InitialDesktop ( char argv0)

Definition at line 124 of file desktop.c.

125{
126 HWINSTA hwinsta = NULL, hwinstaInitial;
127 HDESK hdesktop = NULL;
128 BOOL ret;
129 DWORD error;
130
131 hwinstaInitial = GetProcessWindowStation();
132
133 /* Use the default (interactive) window station */
135 test_CreateProcessWithDesktop(1, argv0, "Default", 0);
138 test_CreateProcessWithDesktop(4, argv0, "WinSta0\\Default", 0);
142 test_CreateProcessWithDesktop(8, argv0, "NonExistantWinsta\\NonExistantDesktop", STATUS_DLL_INIT_FAILED);
143
144 /* Test on an (non-interactive) window station */
145 hwinsta = CreateInheritableWinsta(L"TestWinsta", WINSTA_ALL_ACCESS, TRUE, &error);
146 ok(hwinsta != NULL && error == NO_ERROR, "CreateWindowStation failed, got 0x%p, 0x%lx\n", hwinsta, error);
147 ret = SetProcessWindowStation(hwinsta);
148 ok(ret != FALSE, "SetProcessWindowStation failed\n");
149 hdesktop = CreateInheritableDesktop(L"TestDesktop", DESKTOP_ALL_ACCESS, TRUE, &error);
150 ok(hdesktop != NULL && error == 0xfeedf00d, "CreateDesktop failed, got 0x%p, 0x%lx\n", hdesktop, error);
151
156 test_CreateProcessWithDesktop(13, argv0, "TestWinsta\\TestDesktop", 0);
157 test_CreateProcessWithDesktop(14, argv0, "NonExistantWinsta\\NonExistantDesktop", STATUS_DLL_INIT_FAILED);
158
159 ret = SetProcessWindowStation(hwinstaInitial);
160 ok(ret != FALSE, "SetProcessWindowStation failed\n");
161
162 ret = CloseDesktop(hdesktop);
163 ok(ret != FALSE, "CloseDesktop failed\n");
164
165 ret = CloseWindowStation(hwinsta);
166 ok(ret != FALSE, "CloseWindowStation failed\n");
167
168#if 0
169 /* Test on an non-interactive Service-0xXXXX-YYYY$ window station */
171 ok(hwinsta != NULL && error == NO_ERROR, "CreateWindowStation failed, got 0x%p, 0x%lx\n", hwinsta, error);
172 ret = SetProcessWindowStation(hwinsta);
173 ok(ret != FALSE, "SetProcessWindowStation failed\n");
174 hdesktop = CreateInheritableDesktop(L"TestDesktop", DESKTOP_ALL_ACCESS, TRUE, &error);
175 ok(hdesktop != NULL && error == 0xfeedf00d, "CreateDesktop failed, got 0x%p, 0x%lx\n", hdesktop, error);
176
178 test_CreateProcessWithDesktop(16, "TestDesktop", NULL, 0 /*ERROR_ACCESS_DENIED*/);
179
180 ret = SetProcessWindowStation(hwinstaInitial);
181 ok(ret != FALSE, "SetProcessWindowStation failed\n");
182
183 ret = CloseDesktop(hdesktop);
184 ok(ret != FALSE, "CloseDesktop failed\n");
185
186 ret = CloseWindowStation(hwinsta);
187 ok(ret != FALSE, "CloseWindowStation failed\n");
188#endif
189}
#define NO_ERROR
Definition: dderror.h:5
HWINSTA CreateInheritableWinsta(WCHAR *name, ACCESS_MASK dwDesiredAccess, BOOL inheritable, DWORD *error)
Definition: desktop.c:98
void test_CreateProcessWithDesktop(int i, char *argv0, char *Desktop, DWORD expectedExitCode)
Definition: desktop.c:68
HDESK CreateInheritableDesktop(WCHAR *name, ACCESS_MASK dwDesiredAccess, BOOL inheritable, DWORD *error)
Definition: desktop.c:111
#define L(x)
Definition: ntvdm.h:50
BOOL WINAPI CloseWindowStation(_In_ HWINSTA)
BOOL WINAPI SetProcessWindowStation(_In_ HWINSTA)
BOOL WINAPI CloseDesktop(_In_ HDESK)

Referenced by START_TEST().

◆ Test_OpenInputDesktop()

void Test_OpenInputDesktop ( )

Definition at line 191 of file desktop.c.

192{
193 HDESK hDeskInput ,hDeskInput2;
194 HDESK hDeskInitial;
195 BOOL ret;
196 HWINSTA hwinsta = NULL, hwinstaInitial;
197 DWORD err;
198
199 hDeskInput = OpenInputDesktop(0, FALSE, DESKTOP_ALL_ACCESS);
200 ok(hDeskInput != NULL, "OpenInputDesktop failed\n");
201 hDeskInitial = GetThreadDesktop( GetCurrentThreadId() );
202 ok(hDeskInitial != NULL, "GetThreadDesktop failed\n");
203 ok(hDeskInput != hDeskInitial, "OpenInputDesktop returned thread desktop\n");
204
205 hDeskInput2 = OpenInputDesktop(0, FALSE, DESKTOP_ALL_ACCESS);
206 ok(hDeskInput2 != NULL, "Second call to OpenInputDesktop failed\n");
207 ok(hDeskInput2 != hDeskInput, "Second call to OpenInputDesktop returned same handle\n");
208
209 ok(CloseDesktop(hDeskInput2) != 0, "CloseDesktop failed\n");
210
211 ret = SetThreadDesktop(hDeskInput);
212 ok(ret == TRUE, "SetThreadDesktop for input desktop failed\n");
213
214 ret = SetThreadDesktop(hDeskInitial);
215 ok(ret == TRUE, "SetThreadDesktop for initial desktop failed\n");
216
217 ok(CloseDesktop(hDeskInput) != 0, "CloseDesktop failed\n");
218
219 /* Try calling OpenInputDesktop after switching to a new winsta */
220 hwinstaInitial = GetProcessWindowStation();
221 ok(hwinstaInitial != 0, "GetProcessWindowStation failed\n");
222
223 hwinsta = CreateWindowStationW(L"TestWinsta", 0, WINSTA_ALL_ACCESS, NULL);
224 ok(hwinsta != 0, "CreateWindowStationW failed\n");
225
226 ret = SetProcessWindowStation(hwinsta);
227 ok(ret != FALSE, "SetProcessWindowStation failed\n");
228
229 hDeskInput = OpenInputDesktop(0, FALSE, DESKTOP_ALL_ACCESS);
230 ok(hDeskInput == 0, "OpenInputDesktop should fail\n");
231
232 err = GetLastError();
233 ok(err == ERROR_INVALID_FUNCTION, "Got last error: %lu\n", err);
234
235 ret = SetProcessWindowStation(hwinstaInitial);
236 ok(ret != FALSE, "SetProcessWindowStation failed\n");
237
238 ret = CloseWindowStation(hwinsta);
239 ok(ret != FALSE, "CloseWindowStation failed\n");
240
241}
#define ERROR_INVALID_FUNCTION
Definition: dderror.h:6
#define err(...)
BOOL WINAPI SetThreadDesktop(_In_ HDESK)
HDESK WINAPI OpenInputDesktop(_In_ DWORD, _In_ BOOL, _In_ DWORD)

Referenced by START_TEST().

◆ Test_References()

static void Test_References ( void  )
static

Definition at line 279 of file desktop.c.

280{
281 PCWSTR winstaName = L"RefTestWinsta";
282 PCWSTR deskName = L"RefTestDesktop";
283 HWINSTA hwinsta;
284 HWINSTA hwinsta2;
285 HWINSTA hwinstaProcess;
286 DWORD error;
288 OBJECT_BASIC_INFORMATION objectInfo = { 0 };
289 HDESK hdesk;
290 HDESK hdesk1;
291 BOOL ret;
292 ULONG baseRefs;
293
294#define check_ref(handle, hdlcnt, ptrcnt) \
295 status = NtQueryObject(handle, ObjectBasicInformation, &objectInfo, sizeof(objectInfo), NULL); \
296 ok(status == STATUS_SUCCESS, "status = 0x%lx\n", status); \
297 ok(objectInfo.HandleCount == (hdlcnt), "HandleCount = %lu, expected %lu\n", objectInfo.HandleCount, (ULONG)(hdlcnt)); \
298 ok(objectInfo.PointerCount == (ptrcnt), "PointerCount = %lu, expected %lu\n", objectInfo.PointerCount, (ULONG)(ptrcnt));
299
300 /* Winsta shouldn't exist */
301 hwinsta = open_winsta(winstaName, &error);
302 ok(hwinsta == NULL && error == ERROR_FILE_NOT_FOUND, "Got 0x%p, 0x%lx\n", hwinsta, error);
303
304 /* Create it -- we get 1/4 instead of 1/3 because Winstas are kept in a list */
305 hwinsta = create_winsta(winstaName, &error);
306 ok(hwinsta != NULL && error == NO_ERROR, "Got 0x%p, 0x%lx\n", hwinsta, error);
307 check_ref(hwinsta, 1, 4);
308 baseRefs = objectInfo.PointerCount;
309 ok(baseRefs == 4, "Window station initially has %lu references, expected 4\n", baseRefs);
310 check_ref(hwinsta, 1, baseRefs);
311
312 /* Open a second handle */
313 hwinsta2 = open_winsta(winstaName, &error);
314 ok(hwinsta2 != NULL && error == 0xfeedf00d, "Got 0x%p, 0x%lx\n", hwinsta, error);
315 check_ref(hwinsta, 2, baseRefs + 1);
316
317 /* Close second handle -- back to 1/4 */
318 ret = CloseHandle(hwinsta2);
319 ok(ret == TRUE, "ret = %d\n", ret);
320 check_ref(hwinsta, 1, baseRefs);
321
322 /* Same game but using CloseWindowStation */
323 hwinsta2 = open_winsta(winstaName, &error);
324 ok(hwinsta2 != NULL && error == 0xfeedf00d, "Got 0x%p, 0x%lx\n", hwinsta, error);
325 check_ref(hwinsta, 2, baseRefs + 1);
326 ret = CloseWindowStation(hwinsta2);
327 ok(ret == TRUE, "ret = %d\n", ret);
328 check_ref(hwinsta, 1, baseRefs);
329
330 /* Set it as the process Winsta */
331 hwinstaProcess = GetProcessWindowStation();
333 check_ref(hwinsta, 2, baseRefs + 2);
334
335 /* Create a desktop. It takes a reference */
336 hdesk = create_desk(deskName, &error);
337 ok(hdesk != NULL && error == 0xfeedf00d, "Got 0x%p, 0x%lx\n", hdesk, error);
338 check_ref(hwinsta, 2, baseRefs + 3);
339
340 /* CloseHandle fails, must use CloseDesktop */
341 ret = CloseHandle(hdesk);
342 ok(ret == FALSE, "ret = %d\n", ret);
343 check_ref(hwinsta, 2, baseRefs + 3);
344 ret = CloseDesktop(hdesk);
345 ok(ret == TRUE, "ret = %d\n", ret);
346 check_ref(hwinsta, 2, baseRefs + 2); // 2/7 on Win7?
347
348 /* Desktop no longer exists */
349 hdesk = open_desk(deskName, &error);
350 ok(hdesk == NULL && error == ERROR_FILE_NOT_FOUND, "Got 0x%p, 0x%lx\n", hdesk, error);
351 check_ref(hwinsta, 2, baseRefs + 2);
352
353 /* Restore the original process Winsta */
354 SetProcessWindowStation(hwinstaProcess);
355 check_ref(hwinsta, 1, baseRefs);
356
357 /* Close our last handle */
358 ret = CloseHandle(hwinsta);
359 ok(ret == TRUE, "ret = %d\n", ret);
360
361 /* Winsta no longer exists */
362 hwinsta = open_winsta(winstaName, &error);
363 ok(hwinsta == NULL && error == ERROR_FILE_NOT_FOUND, "Got 0x%p, 0x%lx\n", hwinsta, error);
364
365 /* Create the Winsta again, and close it while there's still a desktop */
366 hwinsta = create_winsta(winstaName, &error);
367 ok(hwinsta != NULL && error == NO_ERROR, "Got 0x%p, 0x%lx\n", hwinsta, error);
368 check_ref(hwinsta, 1, baseRefs);
369 hwinstaProcess = GetProcessWindowStation();
371 check_ref(hwinsta, 2, baseRefs + 2);
372
373 hdesk = create_desk(deskName, &error);
374 ok(hdesk != NULL && error == 0xfeedf00d, "Got 0x%p, 0x%lx\n", hdesk, error);
375 check_ref(hwinsta, 2, baseRefs + 3);
376
377 /* The reference from the desktop is still there, hence 1/5 */
378 SetProcessWindowStation(hwinstaProcess);
379 check_ref(hwinsta, 1, baseRefs + 1);
380 ret = CloseHandle(hwinsta);
381 ok(ret == TRUE, "ret = %d\n", ret);
382 hwinsta = open_winsta(winstaName, &error);
383 ok(hwinsta == NULL && error == ERROR_FILE_NOT_FOUND, "Got 0x%p, 0x%lx\n", hwinsta, error);
384
385 /* Test references by SetThreadDesktop */
387 ok (hdesk1 != hdesk, "Expected the new desktop not to be the thread desktop\n");
388
389 check_ref(hdesk, 1, 8);
390 baseRefs = objectInfo.PointerCount;
391 ok(baseRefs == 8, "Desktop initially has %lu references, expected 8\n", baseRefs);
392 check_ref(hdesk, 1, baseRefs);
393
394 SetThreadDesktop(hdesk);
395 check_ref(hdesk, 1, baseRefs + 1);
396 ok (GetThreadDesktop(GetCurrentThreadId()) == hdesk, "Expected GetThreadDesktop to return hdesk\n");
397
398 SetThreadDesktop(hdesk1);
399 check_ref(hdesk, 1, baseRefs);
400 ok (GetThreadDesktop(GetCurrentThreadId()) == hdesk1, "Expected GetThreadDesktop to return hdesk1\n");
401}
LONG NTSTATUS
Definition: precomp.h:26
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
#define check_ref(handle, hdlcnt, ptrcnt)
static HDESK create_desk(PCWSTR deskName, DWORD *error)
Definition: desktop.c:270
static HWINSTA open_winsta(PCWSTR winstaName, DWORD *error)
Definition: desktop.c:243
static HDESK open_desk(PCWSTR deskName, DWORD *error)
Definition: desktop.c:261
static HWINSTA create_winsta(PCWSTR winstaName, DWORD *error)
Definition: desktop.c:252
const uint16_t * PCWSTR
Definition: typedefs.h:57

Referenced by START_TEST().

Variable Documentation

◆ TestResults

struct test_info TestResults[]
static
Initial value:
=
{
{L"WinSta0",L"Default"},
{L"WinSta0",L"Default"},
{NULL, NULL},
{NULL, NULL},
{L"WinSta0",L"Default"},
{NULL, NULL},
{NULL, NULL},
{NULL, NULL},
{NULL, NULL},
{L"WinSta0",L"Default"},
{NULL, NULL},
{NULL, NULL},
{NULL, NULL},
{L"TestWinsta", L"TestDesktop"},
{NULL, NULL},
{L"WinSta0",L"Default"},
}

Definition at line 18 of file desktop.c.

Referenced by do_InitialDesktop_child().