3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS user32.dll
5 * FILE: lib/user32/misc/winsta.c
6 * PURPOSE: Window stations
7 * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
9 * 04-06-2001 CSH Created
14 #include <wine/debug.h>
15 WINE_DEFAULT_DEBUG_CHANNEL(winsta
);
22 CreateWindowStationA(LPCSTR lpwinsta
,
24 ACCESS_MASK dwDesiredAccess
,
25 LPSECURITY_ATTRIBUTES lpsa
)
27 UNICODE_STRING WindowStationNameU
;
32 /* After conversion, the buffer is zero-terminated */
33 RtlCreateUnicodeStringFromAsciiz(&WindowStationNameU
, lpwinsta
);
37 RtlInitUnicodeString(&WindowStationNameU
, NULL
);
40 hWinSta
= CreateWindowStationW(WindowStationNameU
.Buffer
,
45 /* Free the string, if it was allocated */
46 if (lpwinsta
) RtlFreeUnicodeString(&WindowStationNameU
);
56 CreateWindowStationW(LPCWSTR lpwinsta
,
58 ACCESS_MASK dwDesiredAccess
,
59 LPSECURITY_ATTRIBUTES lpsa
)
61 UNICODE_STRING WindowStationName
;
62 UNICODE_STRING WindowStationsDir
= RTL_CONSTANT_STRING(L
"\\Windows\\WindowStations");
63 OBJECT_ATTRIBUTES ObjectAttributes
;
64 HANDLE hWindowStationsDir
;
68 /* Open WindowStations directory */
69 InitializeObjectAttributes(&ObjectAttributes
,
75 Status
= NtOpenDirectoryObject(&hWindowStationsDir
,
76 DIRECTORY_CREATE_OBJECT
,
78 if(!NT_SUCCESS(Status
))
80 ERR("Failed to open WindowStations directory\n");
84 RtlInitUnicodeString(&WindowStationName
, lpwinsta
);
86 /* Create the window station object */
87 InitializeObjectAttributes(&ObjectAttributes
,
93 /* Check if the handle should be inheritable */
94 if (lpsa
&& lpsa
->bInheritHandle
)
96 ObjectAttributes
.Attributes
|= OBJ_INHERIT
;
99 hwinsta
= NtUserCreateWindowStation(&ObjectAttributes
,
103 NtClose(hWindowStationsDir
);
109 * Common code for EnumDesktopsA/W and EnumWindowStationsA/W
112 EnumNamesW(HWINSTA WindowStation
,
113 NAMEENUMPROCW EnumFunc
,
122 ULONG CurrentEntry
, EntryCount
;
128 if (NULL
== WindowStation
&& Desktops
)
130 WindowStation
= GetProcessWindowStation();
134 * Try with fixed-size buffer
136 Status
= NtUserBuildNameList(WindowStation
, sizeof(Buffer
), Buffer
, &RequiredSize
);
137 if (NT_SUCCESS(Status
))
139 /* Fixed-size buffer is large enough */
140 NameList
= (PWCHAR
) Buffer
;
142 else if (Status
== STATUS_BUFFER_TOO_SMALL
)
144 /* Allocate a larger buffer */
145 NameList
= HeapAlloc(GetProcessHeap(), 0, RequiredSize
);
146 if (NULL
== NameList
)
151 Status
= NtUserBuildNameList(WindowStation
, RequiredSize
, NameList
, NULL
);
152 if (! NT_SUCCESS(Status
))
154 HeapFree(GetProcessHeap(), 0, NameList
);
155 SetLastError(RtlNtStatusToDosError(Status
));
161 /* Some unrecognized error occured */
162 SetLastError(RtlNtStatusToDosError(Status
));
167 * Enum the names one by one
169 EntryCount
= *((DWORD
*) NameList
);
170 Name
= (PWCHAR
) ((PCHAR
) NameList
+ sizeof(DWORD
));
172 for (CurrentEntry
= 0; CurrentEntry
< EntryCount
&& Ret
; ++CurrentEntry
)
174 Ret
= (*EnumFunc
)(Name
, Context
);
175 Name
+= wcslen(Name
) + 1;
181 if (NameList
!= Buffer
)
183 HeapFree(GetProcessHeap(), 0, NameList
);
190 /* For W->A conversion */
191 typedef struct tagENUMNAMESASCIICONTEXT
193 NAMEENUMPROCA UserEnumFunc
;
195 } ENUMNAMESASCIICONTEXT
, *PENUMNAMESASCIICONTEXT
;
198 * Callback used by Ascii versions. Converts the Unicode name to
199 * Ascii and then calls the user callback
202 EnumNamesCallback(LPWSTR Name
, LPARAM Param
)
204 PENUMNAMESASCIICONTEXT Context
= (PENUMNAMESASCIICONTEXT
) Param
;
211 * Determine required size of Ascii string and see if we can use
214 Len
= WideCharToMultiByte(CP_ACP
, 0, Name
, -1, NULL
, 0, NULL
, NULL
);
217 /* Some strange error occured */
220 else if (Len
<= sizeof(FixedNameA
))
222 /* Fixed-size buffer is large enough */
227 /* Allocate a larger buffer */
228 NameA
= HeapAlloc(GetProcessHeap(), 0, Len
);
231 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
237 * Do the Unicode ->Ascii conversion
239 if (0 == WideCharToMultiByte(CP_ACP
, 0, Name
, -1, NameA
, Len
, NULL
, NULL
))
241 /* Something went wrong, clean up */
242 if (NameA
!= FixedNameA
)
244 HeapFree(GetProcessHeap(), 0, NameA
);
252 Ret
= Context
->UserEnumFunc(NameA
, Context
->UserContext
);
257 if (NameA
!= FixedNameA
)
259 HeapFree(GetProcessHeap(), 0, NameA
);
266 * Common code for EnumDesktopsA and EnumWindowStationsA
269 EnumNamesA(HWINSTA WindowStation
,
270 NAMEENUMPROCA EnumFunc
,
274 ENUMNAMESASCIICONTEXT PrivateContext
;
276 PrivateContext
.UserEnumFunc
= EnumFunc
;
277 PrivateContext
.UserContext
= Context
;
279 return EnumNamesW(WindowStation
, EnumNamesCallback
, (LPARAM
) &PrivateContext
, Desktops
);
286 EnumWindowStationsA(WINSTAENUMPROCA EnumFunc
,
289 return EnumNamesA(NULL
, EnumFunc
, Context
, FALSE
);
297 EnumWindowStationsW(WINSTAENUMPROCW EnumFunc
,
300 return EnumNamesW(NULL
, EnumFunc
, Context
, FALSE
);
308 OpenWindowStationA(LPCSTR lpszWinSta
,
310 ACCESS_MASK dwDesiredAccess
)
312 UNICODE_STRING WindowStationNameU
;
317 /* After conversion, the buffer is zero-terminated */
318 RtlCreateUnicodeStringFromAsciiz(&WindowStationNameU
, lpszWinSta
);
322 RtlInitUnicodeString(&WindowStationNameU
, NULL
);
325 hWinSta
= OpenWindowStationW(WindowStationNameU
.Buffer
,
329 /* Free the string, if it was allocated */
330 if (lpszWinSta
) RtlFreeUnicodeString(&WindowStationNameU
);
340 OpenWindowStationW(LPCWSTR lpszWinSta
,
342 ACCESS_MASK dwDesiredAccess
)
344 UNICODE_STRING WindowStationName
;
345 UNICODE_STRING WindowStationsDir
= RTL_CONSTANT_STRING(L
"\\Windows\\WindowStations");
346 OBJECT_ATTRIBUTES ObjectAttributes
;
347 HANDLE hWindowStationsDir
;
351 /* Open WindowStations directory */
352 InitializeObjectAttributes(&ObjectAttributes
,
354 OBJ_CASE_INSENSITIVE
,
358 Status
= NtOpenDirectoryObject(&hWindowStationsDir
,
361 if(!NT_SUCCESS(Status
))
363 ERR("Failed to open WindowStations directory\n");
367 /* Open the window station object */
368 RtlInitUnicodeString(&WindowStationName
, lpszWinSta
);
370 InitializeObjectAttributes(&ObjectAttributes
,
372 OBJ_CASE_INSENSITIVE
,
376 if( fInherit
== TRUE
)
378 ObjectAttributes
.Attributes
|= OBJ_INHERIT
;
381 hwinsta
= NtUserOpenWindowStation(&ObjectAttributes
, dwDesiredAccess
);
383 NtClose(hWindowStationsDir
);
394 SetWindowStationUser(
401 return NtUserSetWindowStationUser(Unknown1
, Unknown2
, Unknown3
, Unknown4
);