2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS user32.dll
4 * FILE: win32ss/user/user32/misc/winsta.c
5 * PURPOSE: Window stations
6 * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
8 * 04-06-2001 CSH Created
13 #include <wine/debug.h>
14 WINE_DEFAULT_DEBUG_CHANNEL(winsta
);
21 CreateWindowStationA(LPCSTR lpwinsta
,
23 ACCESS_MASK dwDesiredAccess
,
24 LPSECURITY_ATTRIBUTES lpsa
)
26 UNICODE_STRING WindowStationNameU
;
31 /* After conversion, the buffer is zero-terminated */
32 RtlCreateUnicodeStringFromAsciiz(&WindowStationNameU
, lpwinsta
);
36 RtlInitUnicodeString(&WindowStationNameU
, NULL
);
39 hWinSta
= CreateWindowStationW(WindowStationNameU
.Buffer
,
44 /* Free the string, if it was allocated */
45 if (lpwinsta
) RtlFreeUnicodeString(&WindowStationNameU
);
55 CreateWindowStationW(LPCWSTR lpwinsta
,
57 ACCESS_MASK dwDesiredAccess
,
58 LPSECURITY_ATTRIBUTES lpsa
)
60 UNICODE_STRING WindowStationName
;
61 UNICODE_STRING WindowStationsDir
= RTL_CONSTANT_STRING(L
"\\Windows\\WindowStations");
62 OBJECT_ATTRIBUTES ObjectAttributes
;
63 HANDLE hWindowStationsDir
;
67 /* Open WindowStations directory */
68 InitializeObjectAttributes(&ObjectAttributes
,
74 Status
= NtOpenDirectoryObject(&hWindowStationsDir
,
75 DIRECTORY_CREATE_OBJECT
,
77 if(!NT_SUCCESS(Status
))
79 ERR("Failed to open WindowStations directory\n");
83 RtlInitUnicodeString(&WindowStationName
, lpwinsta
);
85 /* Create the window station object */
86 InitializeObjectAttributes(&ObjectAttributes
,
92 /* Check if the handle should be inheritable */
93 if (lpsa
&& lpsa
->bInheritHandle
)
95 ObjectAttributes
.Attributes
|= OBJ_INHERIT
;
98 hwinsta
= NtUserCreateWindowStation(&ObjectAttributes
,
102 NtClose(hWindowStationsDir
);
108 * Common code for EnumDesktopsA/W and EnumWindowStationsA/W
111 EnumNamesW(HWINSTA WindowStation
,
112 NAMEENUMPROCW EnumFunc
,
121 ULONG CurrentEntry
, EntryCount
;
124 /* Check parameters */
125 if (WindowStation
== NULL
&& Desktops
)
127 WindowStation
= GetProcessWindowStation();
130 /* Try with fixed-size buffer */
131 Status
= NtUserBuildNameList(WindowStation
, sizeof(Buffer
), Buffer
, &RequiredSize
);
132 if (NT_SUCCESS(Status
))
134 /* Fixed-size buffer is large enough */
135 NameList
= (PWCHAR
) Buffer
;
137 else if (Status
== STATUS_BUFFER_TOO_SMALL
)
139 /* Allocate a larger buffer */
140 NameList
= HeapAlloc(GetProcessHeap(), 0, RequiredSize
);
141 if (NameList
== NULL
)
145 Status
= NtUserBuildNameList(WindowStation
, RequiredSize
, NameList
, NULL
);
146 if (!NT_SUCCESS(Status
))
148 HeapFree(GetProcessHeap(), 0, NameList
);
149 SetLastError(RtlNtStatusToDosError(Status
));
155 /* Some unrecognized error occured */
156 SetLastError(RtlNtStatusToDosError(Status
));
160 /* Enum the names one by one */
161 EntryCount
= *((DWORD
*) NameList
);
162 Name
= (PWCHAR
) ((PCHAR
) NameList
+ sizeof(DWORD
));
164 for (CurrentEntry
= 0; CurrentEntry
< EntryCount
&& Ret
; ++CurrentEntry
)
166 Ret
= (*EnumFunc
)(Name
, Context
);
167 Name
+= wcslen(Name
) + 1;
171 if (NameList
!= Buffer
)
173 HeapFree(GetProcessHeap(), 0, NameList
);
180 /* For W->A conversion */
181 typedef struct tagENUMNAMESASCIICONTEXT
183 NAMEENUMPROCA UserEnumFunc
;
185 } ENUMNAMESASCIICONTEXT
, *PENUMNAMESASCIICONTEXT
;
188 * Callback used by Ascii versions. Converts the Unicode name to
189 * Ascii and then calls the user callback
192 EnumNamesCallback(LPWSTR Name
, LPARAM Param
)
194 PENUMNAMESASCIICONTEXT Context
= (PENUMNAMESASCIICONTEXT
) Param
;
201 * Determine required size of Ascii string and see
202 * if we can use fixed buffer.
204 Len
= WideCharToMultiByte(CP_ACP
, 0, Name
, -1, NULL
, 0, NULL
, NULL
);
207 /* Some strange error occured */
210 else if (Len
<= sizeof(FixedNameA
))
212 /* Fixed-size buffer is large enough */
217 /* Allocate a larger buffer */
218 NameA
= HeapAlloc(GetProcessHeap(), 0, Len
);
221 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
226 /* Do the Unicode ->Ascii conversion */
227 if (0 == WideCharToMultiByte(CP_ACP
, 0, Name
, -1, NameA
, Len
, NULL
, NULL
))
229 /* Something went wrong, clean up */
230 if (NameA
!= FixedNameA
)
232 HeapFree(GetProcessHeap(), 0, NameA
);
237 /* Call user callback */
238 Ret
= Context
->UserEnumFunc(NameA
, Context
->UserContext
);
241 if (NameA
!= FixedNameA
)
243 HeapFree(GetProcessHeap(), 0, NameA
);
250 * Common code for EnumDesktopsA and EnumWindowStationsA
253 EnumNamesA(HWINSTA WindowStation
,
254 NAMEENUMPROCA EnumFunc
,
258 ENUMNAMESASCIICONTEXT PrivateContext
;
260 PrivateContext
.UserEnumFunc
= EnumFunc
;
261 PrivateContext
.UserContext
= Context
;
263 return EnumNamesW(WindowStation
, EnumNamesCallback
, (LPARAM
) &PrivateContext
, Desktops
);
270 EnumWindowStationsA(WINSTAENUMPROCA EnumFunc
,
273 return EnumNamesA(NULL
, EnumFunc
, Context
, FALSE
);
281 EnumWindowStationsW(WINSTAENUMPROCW EnumFunc
,
284 return EnumNamesW(NULL
, EnumFunc
, Context
, FALSE
);
289 * @unimplemented on Win32k side
292 GetWinStationInfo(PVOID pUnknown
)
294 return (BOOL
)NtUserCallOneParam((DWORD_PTR
)pUnknown
, ONEPARAM_ROUTINE_GETWINSTAINFO
);
302 OpenWindowStationA(LPCSTR lpszWinSta
,
304 ACCESS_MASK dwDesiredAccess
)
306 UNICODE_STRING WindowStationNameU
;
311 /* After conversion, the buffer is zero-terminated */
312 RtlCreateUnicodeStringFromAsciiz(&WindowStationNameU
, lpszWinSta
);
316 RtlInitUnicodeString(&WindowStationNameU
, NULL
);
319 hWinSta
= OpenWindowStationW(WindowStationNameU
.Buffer
,
323 /* Free the string, if it was allocated */
324 if (lpszWinSta
) RtlFreeUnicodeString(&WindowStationNameU
);
334 OpenWindowStationW(LPCWSTR lpszWinSta
,
336 ACCESS_MASK dwDesiredAccess
)
338 UNICODE_STRING WindowStationName
;
339 UNICODE_STRING WindowStationsDir
= RTL_CONSTANT_STRING(L
"\\Windows\\WindowStations");
340 OBJECT_ATTRIBUTES ObjectAttributes
;
341 HANDLE hWindowStationsDir
;
345 /* Open WindowStations directory */
346 InitializeObjectAttributes(&ObjectAttributes
,
348 OBJ_CASE_INSENSITIVE
,
352 Status
= NtOpenDirectoryObject(&hWindowStationsDir
,
355 if(!NT_SUCCESS(Status
))
357 ERR("Failed to open WindowStations directory\n");
361 /* Open the window station object */
362 RtlInitUnicodeString(&WindowStationName
, lpszWinSta
);
364 InitializeObjectAttributes(&ObjectAttributes
,
366 OBJ_CASE_INSENSITIVE
,
372 ObjectAttributes
.Attributes
|= OBJ_INHERIT
;
375 hwinsta
= NtUserOpenWindowStation(&ObjectAttributes
, dwDesiredAccess
);
377 NtClose(hWindowStationsDir
);
388 SetWindowStationUser(HWINSTA hWindowStation
,
395 Success
= NtUserSetWindowStationUser(hWindowStation
, pluid
, psid
, size
);
398 /* Signal log-on/off to WINSRV */
400 /* User is logging on if pluid != LuidNone, otherwise it is a log-off */
401 LUID LuidNone
= {0, 0};
402 BOOL IsLogon
= (pluid
&& !RtlEqualLuid(pluid
, &LuidNone
));