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 WINE_DEFAULT_DEBUG_CHANNEL(winsta
);
19 CreateWindowStationA(LPCSTR lpwinsta
,
21 ACCESS_MASK dwDesiredAccess
,
22 LPSECURITY_ATTRIBUTES lpsa
)
24 UNICODE_STRING WindowStationNameU
;
29 /* After conversion, the buffer is zero-terminated */
30 RtlCreateUnicodeStringFromAsciiz(&WindowStationNameU
, lpwinsta
);
34 RtlInitUnicodeString(&WindowStationNameU
, NULL
);
37 hWinSta
= CreateWindowStationW(WindowStationNameU
.Buffer
,
42 /* Free the string, if it was allocated */
43 if (lpwinsta
) RtlFreeUnicodeString(&WindowStationNameU
);
53 CreateWindowStationW(LPCWSTR lpwinsta
,
55 ACCESS_MASK dwDesiredAccess
,
56 LPSECURITY_ATTRIBUTES lpsa
)
58 UNICODE_STRING WindowStationName
;
59 UNICODE_STRING WindowStationsDir
= RTL_CONSTANT_STRING(L
"\\Windows\\WindowStations");
60 OBJECT_ATTRIBUTES ObjectAttributes
;
61 HANDLE hWindowStationsDir
;
65 /* Open WindowStations directory */
66 InitializeObjectAttributes(&ObjectAttributes
,
72 Status
= NtOpenDirectoryObject(&hWindowStationsDir
,
73 DIRECTORY_CREATE_OBJECT
,
75 if(!NT_SUCCESS(Status
))
77 ERR("Failed to open WindowStations directory\n");
81 RtlInitUnicodeString(&WindowStationName
, lpwinsta
);
83 /* Create the window station object */
84 InitializeObjectAttributes(&ObjectAttributes
,
90 /* Check if the handle should be inheritable */
91 if (lpsa
&& lpsa
->bInheritHandle
)
93 ObjectAttributes
.Attributes
|= OBJ_INHERIT
;
96 hwinsta
= NtUserCreateWindowStation(&ObjectAttributes
,
100 NtClose(hWindowStationsDir
);
106 * Common code for EnumDesktopsA/W and EnumWindowStationsA/W
109 EnumNamesW(HWINSTA WindowStation
,
110 NAMEENUMPROCW EnumFunc
,
119 ULONG CurrentEntry
, EntryCount
;
122 /* Check parameters */
123 if (WindowStation
== NULL
&& Desktops
)
125 WindowStation
= GetProcessWindowStation();
128 /* Try with fixed-size buffer */
129 Status
= NtUserBuildNameList(WindowStation
, sizeof(Buffer
), Buffer
, &RequiredSize
);
130 if (NT_SUCCESS(Status
))
132 /* Fixed-size buffer is large enough */
133 NameList
= (PWCHAR
) Buffer
;
135 else if (Status
== STATUS_BUFFER_TOO_SMALL
)
137 /* Allocate a larger buffer */
138 NameList
= HeapAlloc(GetProcessHeap(), 0, RequiredSize
);
139 if (NameList
== NULL
)
143 Status
= NtUserBuildNameList(WindowStation
, RequiredSize
, NameList
, NULL
);
144 if (!NT_SUCCESS(Status
))
146 HeapFree(GetProcessHeap(), 0, NameList
);
147 SetLastError(RtlNtStatusToDosError(Status
));
153 /* Some unrecognized error occured */
154 SetLastError(RtlNtStatusToDosError(Status
));
158 /* Enum the names one by one */
159 EntryCount
= *((DWORD
*) NameList
);
160 Name
= (PWCHAR
) ((PCHAR
) NameList
+ sizeof(DWORD
));
162 for (CurrentEntry
= 0; CurrentEntry
< EntryCount
&& Ret
; ++CurrentEntry
)
164 Ret
= (*EnumFunc
)(Name
, Context
);
165 Name
+= wcslen(Name
) + 1;
169 if (NameList
!= Buffer
)
171 HeapFree(GetProcessHeap(), 0, NameList
);
178 /* For W->A conversion */
179 typedef struct tagENUMNAMESASCIICONTEXT
181 NAMEENUMPROCA UserEnumFunc
;
183 } ENUMNAMESASCIICONTEXT
, *PENUMNAMESASCIICONTEXT
;
186 * Callback used by Ascii versions. Converts the Unicode name to
187 * Ascii and then calls the user callback
190 EnumNamesCallback(LPWSTR Name
, LPARAM Param
)
192 PENUMNAMESASCIICONTEXT Context
= (PENUMNAMESASCIICONTEXT
) Param
;
199 * Determine required size of Ascii string and see
200 * if we can use fixed buffer.
202 Len
= WideCharToMultiByte(CP_ACP
, 0, Name
, -1, NULL
, 0, NULL
, NULL
);
205 /* Some strange error occured */
208 else if (Len
<= sizeof(FixedNameA
))
210 /* Fixed-size buffer is large enough */
215 /* Allocate a larger buffer */
216 NameA
= HeapAlloc(GetProcessHeap(), 0, Len
);
219 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
224 /* Do the Unicode ->Ascii conversion */
225 if (0 == WideCharToMultiByte(CP_ACP
, 0, Name
, -1, NameA
, Len
, NULL
, NULL
))
227 /* Something went wrong, clean up */
228 if (NameA
!= FixedNameA
)
230 HeapFree(GetProcessHeap(), 0, NameA
);
235 /* Call user callback */
236 Ret
= Context
->UserEnumFunc(NameA
, Context
->UserContext
);
239 if (NameA
!= FixedNameA
)
241 HeapFree(GetProcessHeap(), 0, NameA
);
248 * Common code for EnumDesktopsA and EnumWindowStationsA
251 EnumNamesA(HWINSTA WindowStation
,
252 NAMEENUMPROCA EnumFunc
,
256 ENUMNAMESASCIICONTEXT PrivateContext
;
258 PrivateContext
.UserEnumFunc
= EnumFunc
;
259 PrivateContext
.UserContext
= Context
;
261 return EnumNamesW(WindowStation
, EnumNamesCallback
, (LPARAM
) &PrivateContext
, Desktops
);
268 EnumWindowStationsA(WINSTAENUMPROCA EnumFunc
,
271 return EnumNamesA(NULL
, EnumFunc
, Context
, FALSE
);
279 EnumWindowStationsW(WINSTAENUMPROCW EnumFunc
,
282 return EnumNamesW(NULL
, EnumFunc
, Context
, FALSE
);
287 * @unimplemented on Win32k side
290 GetWinStationInfo(PVOID pUnknown
)
292 return (BOOL
)NtUserCallOneParam((DWORD_PTR
)pUnknown
, ONEPARAM_ROUTINE_GETWINSTAINFO
);
300 OpenWindowStationA(LPCSTR lpszWinSta
,
302 ACCESS_MASK dwDesiredAccess
)
304 UNICODE_STRING WindowStationNameU
;
309 /* After conversion, the buffer is zero-terminated */
310 RtlCreateUnicodeStringFromAsciiz(&WindowStationNameU
, lpszWinSta
);
314 RtlInitUnicodeString(&WindowStationNameU
, NULL
);
317 hWinSta
= OpenWindowStationW(WindowStationNameU
.Buffer
,
321 /* Free the string, if it was allocated */
322 if (lpszWinSta
) RtlFreeUnicodeString(&WindowStationNameU
);
332 OpenWindowStationW(LPCWSTR lpszWinSta
,
334 ACCESS_MASK dwDesiredAccess
)
336 UNICODE_STRING WindowStationName
;
337 UNICODE_STRING WindowStationsDir
= RTL_CONSTANT_STRING(L
"\\Windows\\WindowStations");
338 OBJECT_ATTRIBUTES ObjectAttributes
;
339 HANDLE hWindowStationsDir
;
343 /* Open WindowStations directory */
344 InitializeObjectAttributes(&ObjectAttributes
,
346 OBJ_CASE_INSENSITIVE
,
350 Status
= NtOpenDirectoryObject(&hWindowStationsDir
,
353 if(!NT_SUCCESS(Status
))
355 ERR("Failed to open WindowStations directory\n");
359 /* Open the window station object */
360 RtlInitUnicodeString(&WindowStationName
, lpszWinSta
);
362 InitializeObjectAttributes(&ObjectAttributes
,
364 OBJ_CASE_INSENSITIVE
,
370 ObjectAttributes
.Attributes
|= OBJ_INHERIT
;
373 hwinsta
= NtUserOpenWindowStation(&ObjectAttributes
, dwDesiredAccess
);
375 NtClose(hWindowStationsDir
);
386 SetWindowStationUser(HWINSTA hWindowStation
,
393 Success
= NtUserSetWindowStationUser(hWindowStation
, pluid
, psid
, size
);
396 /* Signal log-on/off to WINSRV */
398 /* User is logging on if pluid != LuidNone, otherwise it is a log-off */
399 LUID LuidNone
= {0, 0};
400 BOOL IsLogon
= (pluid
&& !RtlEqualLuid(pluid
, &LuidNone
));