ReactOS 0.4.15-dev-7958-gcd0bb1a
winsta.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS user32.dll
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: Window stations
5 * COPYRIGHT: Copyright 2001-2018 Casper S. Hornstrup (chorns@users.sourceforge.net)
6 * Copyright 2011-2018 Giannis Adamopoulos
7 */
8
9#include <user32.h>
10
12
13/*
14 * @implemented
15 */
16HWINSTA
19 IN LPCSTR lpwinsta OPTIONAL,
21 IN ACCESS_MASK dwDesiredAccess,
23{
24 HWINSTA hWinSta;
25 UNICODE_STRING WindowStationNameU;
26
27 if (lpwinsta)
28 {
29 /* After conversion, the buffer is zero-terminated */
30 RtlCreateUnicodeStringFromAsciiz(&WindowStationNameU, lpwinsta);
31 }
32 else
33 {
34 RtlInitUnicodeString(&WindowStationNameU, NULL);
35 }
36
37 hWinSta = CreateWindowStationW(WindowStationNameU.Buffer,
39 dwDesiredAccess,
40 lpsa);
41
42 /* Free the string if it was allocated */
43 if (lpwinsta) RtlFreeUnicodeString(&WindowStationNameU);
44
45 return hWinSta;
46}
47
48
49/*
50 * @implemented
51 */
52HWINSTA
55 IN LPCWSTR lpwinsta OPTIONAL,
57 IN ACCESS_MASK dwDesiredAccess,
59{
61 HWINSTA hWinSta;
62 UNICODE_STRING WindowStationName;
63 // FIXME: We should cache a per-session directory (see ntuser\winsta.c!UserCreateWinstaDirectory).
64 UNICODE_STRING WindowStationsDir = RTL_CONSTANT_STRING(L"\\Windows\\WindowStations");
66 HANDLE hWindowStationsDir;
67
68 /*
69 * If provided, the window station name is always relative to the
70 * current user session's WindowStations directory.
71 * Otherwise (the window station name is NULL or an empty string),
72 * pass both an empty string and no WindowStations directory handle
73 * to win32k, so that it will create a window station whose name
74 * is based on the logon session identifier for the calling process.
75 */
76 if (lpwinsta && *lpwinsta)
77 {
78 /* Open WindowStations directory */
80 &WindowStationsDir,
82 NULL,
83 NULL);
84
85 Status = NtOpenDirectoryObject(&hWindowStationsDir,
88 if (!NT_SUCCESS(Status))
89 {
90 ERR("Failed to open WindowStations directory\n");
91 return NULL;
92 }
93
94 RtlInitUnicodeString(&WindowStationName, lpwinsta);
95 }
96 else
97 {
98 lpwinsta = NULL;
99 hWindowStationsDir = NULL;
100 }
101
102 /* Create the window station object */
104 lpwinsta ? &WindowStationName : NULL,
106 hWindowStationsDir,
107 lpsa ? lpsa->lpSecurityDescriptor : NULL);
108
109 /* Check if the handle should be inheritable */
110 if (lpsa && lpsa->bInheritHandle)
111 {
112 ObjectAttributes.Attributes |= OBJ_INHERIT;
113 }
114
116 dwDesiredAccess,
117 0, 0, 0, 0, 0);
118
119 if (hWindowStationsDir)
120 NtClose(hWindowStationsDir);
121
122 return hWinSta;
123}
124
125/*
126 * Common code for EnumDesktopsA/W and EnumWindowStationsA/W
127 */
128BOOL
130EnumNamesW(HWINSTA WindowStation,
134{
135 CHAR Buffer[256];
136 PVOID NameList;
137 PWCHAR Name;
140 ULONG CurrentEntry, EntryCount;
141 BOOL Ret;
142
143 /* Check parameters */
144 if (WindowStation == NULL && Desktops)
145 {
146 WindowStation = GetProcessWindowStation();
147 }
148
149 /* Try with fixed-size buffer */
150 Status = NtUserBuildNameList(WindowStation, sizeof(Buffer), Buffer, &RequiredSize);
151 if (NT_SUCCESS(Status))
152 {
153 /* Fixed-size buffer is large enough */
154 NameList = (PWCHAR) Buffer;
155 }
157 {
158 /* Allocate a larger buffer */
159 NameList = HeapAlloc(GetProcessHeap(), 0, RequiredSize);
160 if (NameList == NULL)
161 return FALSE;
162
163 /* Try again */
164 Status = NtUserBuildNameList(WindowStation, RequiredSize, NameList, NULL);
165 if (!NT_SUCCESS(Status))
166 {
167 HeapFree(GetProcessHeap(), 0, NameList);
169 return FALSE;
170 }
171 }
172 else
173 {
174 /* Some unrecognized error occured */
176 return FALSE;
177 }
178
179 /* Enum the names one by one */
180 EntryCount = *((DWORD *) NameList);
181 Name = (PWCHAR) ((PCHAR) NameList + sizeof(DWORD));
182 Ret = TRUE;
183 for (CurrentEntry = 0; CurrentEntry < EntryCount && Ret; ++CurrentEntry)
184 {
185 Ret = (*EnumFunc)(Name, Context);
186 Name += wcslen(Name) + 1;
187 }
188
189 /* Cleanup */
190 if (NameList != Buffer)
191 {
192 HeapFree(GetProcessHeap(), 0, NameList);
193 }
194
195 return Ret;
196}
197
198/* For W->A conversion */
200{
204
205/*
206 * Callback used by Ascii versions. Converts the Unicode name to
207 * Ascii and then calls the user callback
208 */
209BOOL
212{
214 CHAR FixedNameA[32];
215 LPSTR NameA;
216 INT Len;
217 BOOL Ret;
218
219 /*
220 * Determine required size of Ascii string and see
221 * if we can use fixed buffer.
222 */
224 if (Len <= 0)
225 {
226 /* Some strange error occured */
227 return FALSE;
228 }
229 else if (Len <= sizeof(FixedNameA))
230 {
231 /* Fixed-size buffer is large enough */
232 NameA = FixedNameA;
233 }
234 else
235 {
236 /* Allocate a larger buffer */
237 NameA = HeapAlloc(GetProcessHeap(), 0, Len);
238 if (NULL == NameA)
239 {
241 return FALSE;
242 }
243 }
244
245 /* Do the Unicode ->Ascii conversion */
246 if (0 == WideCharToMultiByte(CP_ACP, 0, Name, -1, NameA, Len, NULL, NULL))
247 {
248 /* Something went wrong, clean up */
249 if (NameA != FixedNameA)
250 {
251 HeapFree(GetProcessHeap(), 0, NameA);
252 }
253 return FALSE;
254 }
255
256 /* Call user callback */
257 Ret = Context->UserEnumFunc(NameA, Context->UserContext);
258
259 /* Cleanup */
260 if (NameA != FixedNameA)
261 {
262 HeapFree(GetProcessHeap(), 0, NameA);
263 }
264
265 return Ret;
266}
267
268/*
269 * Common code for EnumDesktopsA and EnumWindowStationsA
270 */
271BOOL
273EnumNamesA(HWINSTA WindowStation,
277{
278 ENUMNAMESASCIICONTEXT PrivateContext;
279
280 PrivateContext.UserEnumFunc = EnumFunc;
281 PrivateContext.UserContext = Context;
282
283 return EnumNamesW(WindowStation, EnumNamesCallback, (LPARAM) &PrivateContext, Desktops);
284}
285
286/*
287 * @implemented
288 */
289BOOL
290WINAPI
294{
296}
297
298
299/*
300 * @implemented
301 */
302BOOL
303WINAPI
307{
309}
310
311
312/*
313 * @unimplemented on Win32k side
314 */
315BOOL
316WINAPI
318{
320}
321
322
323/*
324 * @implemented
325 */
326HWINSTA
327WINAPI
329 IN LPCSTR lpszWinSta,
330 IN BOOL fInherit,
331 IN ACCESS_MASK dwDesiredAccess)
332{
333 HWINSTA hWinSta;
334 UNICODE_STRING WindowStationNameU;
335
336 if (lpszWinSta)
337 {
338 /* After conversion, the buffer is zero-terminated */
339 RtlCreateUnicodeStringFromAsciiz(&WindowStationNameU, lpszWinSta);
340 }
341 else
342 {
343 RtlInitUnicodeString(&WindowStationNameU, NULL);
344 }
345
346 hWinSta = OpenWindowStationW(WindowStationNameU.Buffer,
347 fInherit,
348 dwDesiredAccess);
349
350 /* Free the string if it was allocated */
351 if (lpszWinSta) RtlFreeUnicodeString(&WindowStationNameU);
352
353 return hWinSta;
354}
355
356
357/*
358 * @implemented
359 */
360HWINSTA
361WINAPI
363 IN LPCWSTR lpszWinSta,
364 IN BOOL fInherit,
365 IN ACCESS_MASK dwDesiredAccess)
366{
368 HWINSTA hWinSta;
369 UNICODE_STRING WindowStationName;
370 // FIXME: We should cache a per-session directory (see ntuser\winsta.c!UserCreateWinstaDirectory).
371 UNICODE_STRING WindowStationsDir = RTL_CONSTANT_STRING(L"\\Windows\\WindowStations");
373 HANDLE hWindowStationsDir;
374
375 /* Open WindowStations directory */
377 &WindowStationsDir,
379 NULL,
380 NULL);
381
382 Status = NtOpenDirectoryObject(&hWindowStationsDir,
385 if(!NT_SUCCESS(Status))
386 {
387 ERR("Failed to open WindowStations directory\n");
388 return NULL;
389 }
390
391 /* Open the window station object */
392 RtlInitUnicodeString(&WindowStationName, lpszWinSta);
393
395 &WindowStationName,
397 hWindowStationsDir,
398 NULL);
399
400 /* Check if the handle should be inheritable */
401 if (fInherit)
402 {
403 ObjectAttributes.Attributes |= OBJ_INHERIT;
404 }
405
406 hWinSta = NtUserOpenWindowStation(&ObjectAttributes, dwDesiredAccess);
407
408 NtClose(hWindowStationsDir);
409
410 return hWinSta;
411}
412
413
414/*
415 * @implemented
416 */
417BOOL
418WINAPI
420 IN HWINSTA hWindowStation,
421 IN PLUID pluid,
422 IN PSID psid OPTIONAL,
423 IN DWORD size)
424{
426
427 Success = NtUserSetWindowStationUser(hWindowStation, pluid, psid, size);
428 if (Success)
429 {
430 /* Signal log-on/off to WINSRV */
431
432 /* User is logging on if *pluid != LuidNone, otherwise it is a log-off */
433 LUID LuidNone = {0, 0};
434 BOOL IsLogon = (pluid && !RtlEqualLuid(pluid, &LuidNone));
435
436 Logon(IsLogon);
437 }
438
439 return Success;
440}
441
442/* EOF */
static BOOL CALLBACK EnumFunc(_In_ HWND hWnd, _In_ PCWSTR lpszString, _In_ HANDLE hData)
Definition: SetProp.c:15
struct NameRec_ * Name
Definition: cdprocs.h:460
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
LONG NTSTATUS
Definition: precomp.h:26
#define ERR(fmt,...)
Definition: debug.h:110
Definition: bufpool.h:45
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define Len
Definition: deflate.h:82
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define GetProcessHeap()
Definition: compat.h:736
#define CP_ACP
Definition: compat.h:109
#define SetLastError(x)
Definition: compat.h:752
#define HeapAlloc
Definition: compat.h:733
#define HeapFree(x, y, z)
Definition: compat.h:735
#define CALLBACK
Definition: compat.h:35
#define WideCharToMultiByte
Definition: compat.h:111
_In_ PUNKNOWN pUnknown
Definition: drmk.h:76
@ Success
Definition: eventcreate.c:712
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
Status
Definition: gdiplustypes.h:25
GLsizeiptr size
Definition: glext.h:5919
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
DWORD_PTR NTAPI NtUserCallOneParam(DWORD_PTR Param, DWORD Routine)
Definition: simplecall.c:153
@ ONEPARAM_ROUTINE_GETWINSTAINFO
Definition: ntuser.h:1570
#define OBJ_OPENIF
Definition: winternl.h:229
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define OBJ_INHERIT
Definition: winternl.h:225
NTSYSAPI ULONG WINAPI RtlNtStatusToDosError(NTSTATUS)
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
_In_ HANDLE _In_ DWORD _In_ DWORD _Inout_opt_ LPOVERLAPPED _In_opt_ LPTRANSMIT_FILE_BUFFERS _In_ DWORD dwReserved
Definition: mswsock.h:95
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeStringFromAsciiz(_Out_ PUNICODE_STRING Destination, _In_ PCSZ Source)
#define DIRECTORY_CREATE_OBJECT
Definition: nt_native.h:1256
ULONG ACCESS_MASK
Definition: nt_native.h:40
#define DIRECTORY_TRAVERSE
Definition: nt_native.h:1255
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define FASTCALL
Definition: nt_native.h:50
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define DWORD
Definition: nt_native.h:44
NTSTATUS APIENTRY NtUserBuildNameList(HWINSTA hWindowStation, ULONG dwSize, PVOID lpBuffer, PULONG pRequiredSize)
Definition: winsta.c:1937
HWINSTA APIENTRY NtUserCreateWindowStation(IN POBJECT_ATTRIBUTES ObjectAttributes, IN ACCESS_MASK dwDesiredAccess, DWORD Unknown2, DWORD Unknown3, DWORD Unknown4, DWORD Unknown5, DWORD Unknown6)
Definition: winsta.c:731
BOOL NTAPI NtUserSetWindowStationUser(IN HWINSTA hWindowStation, IN PLUID pluid, IN PSID psid OPTIONAL, IN DWORD size)
Definition: winsta.c:1995
HWINSTA APIENTRY NtUserOpenWindowStation(IN POBJECT_ATTRIBUTES ObjectAttributes, IN ACCESS_MASK dwDesiredAccess)
Definition: winsta.c:872
#define L(x)
Definition: ntvdm.h:50
NTSTATUS NTAPI NtOpenDirectoryObject(OUT PHANDLE DirectoryHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: obdir.c:393
LUID LuidNone
Definition: sas.c:47
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
NAMEENUMPROCA UserEnumFunc
Definition: winsta.c:201
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
uint32_t DWORD_PTR
Definition: typedefs.h:65
int32_t INT
Definition: typedefs.h:58
#define IN
Definition: typedefs.h:39
uint16_t * PWCHAR
Definition: typedefs.h:56
uint32_t ULONG
Definition: typedefs.h:59
char * PCHAR
Definition: typedefs.h:51
HWINSTA WINAPI OpenWindowStationW(IN LPCWSTR lpszWinSta, IN BOOL fInherit, IN ACCESS_MASK dwDesiredAccess)
Definition: winsta.c:362
BOOL FASTCALL EnumNamesA(HWINSTA WindowStation, NAMEENUMPROCA EnumFunc, LPARAM Context, BOOL Desktops)
Definition: winsta.c:273
struct tagENUMNAMESASCIICONTEXT * PENUMNAMESASCIICONTEXT
BOOL WINAPI EnumWindowStationsW(IN WINSTAENUMPROCW EnumFunc, IN LPARAM Context)
Definition: winsta.c:304
BOOL CALLBACK EnumNamesCallback(LPWSTR Name, LPARAM Param)
Definition: winsta.c:211
BOOL WINAPI EnumWindowStationsA(IN WINSTAENUMPROCA EnumFunc, IN LPARAM Context)
Definition: winsta.c:291
struct tagENUMNAMESASCIICONTEXT ENUMNAMESASCIICONTEXT
HWINSTA WINAPI CreateWindowStationA(IN LPCSTR lpwinsta OPTIONAL, IN DWORD dwReserved, IN ACCESS_MASK dwDesiredAccess, IN LPSECURITY_ATTRIBUTES lpsa OPTIONAL)
Definition: winsta.c:18
BOOL WINAPI SetWindowStationUser(IN HWINSTA hWindowStation, IN PLUID pluid, IN PSID psid OPTIONAL, IN DWORD size)
Definition: winsta.c:419
HWINSTA WINAPI OpenWindowStationA(IN LPCSTR lpszWinSta, IN BOOL fInherit, IN ACCESS_MASK dwDesiredAccess)
Definition: winsta.c:328
BOOL WINAPI GetWinStationInfo(PVOID pUnknown)
Definition: winsta.c:317
HWINSTA WINAPI CreateWindowStationW(IN LPCWSTR lpwinsta OPTIONAL, IN DWORD dwReserved, IN ACCESS_MASK dwDesiredAccess, IN LPSECURITY_ATTRIBUTES lpsa OPTIONAL)
Definition: winsta.c:54
BOOL FASTCALL EnumNamesW(HWINSTA WindowStation, NAMEENUMPROCW EnumFunc, LPARAM Context, BOOL Desktops)
Definition: winsta.c:130
VOID FASTCALL Logon(BOOL IsLogon)
Definition: logon.c:74
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ ULONG _Out_ PVOID _Out_ PULONG RequiredSize
Definition: wdfdevice.h:4439
HWINSTA WINAPI GetProcessWindowStation(void)
Definition: ntwrapper.h:124
LONG_PTR LPARAM
Definition: windef.h:208
#define WINAPI
Definition: msvc.h:6
BOOL(CALLBACK * NAMEENUMPROCA)(LPSTR, LPARAM)
Definition: winuser.h:2910
BOOL(CALLBACK * NAMEENUMPROCW)(LPWSTR, LPARAM)
Definition: winuser.h:2911
NAMEENUMPROCA WINSTAENUMPROCA
Definition: winuser.h:2914
NAMEENUMPROCW WINSTAENUMPROCW
Definition: winuser.h:2915
#define RtlEqualLuid(Luid1, Luid2)
Definition: rtlfuncs.h:301
const char * LPCSTR
Definition: xmlstorage.h:183
char * LPSTR
Definition: xmlstorage.h:182
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
char CHAR
Definition: xmlstorage.h:175