2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS user32.dll
4 * FILE: lib/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
;
127 if (NULL
== WindowStation
&& Desktops
)
129 WindowStation
= GetProcessWindowStation();
133 * Try with fixed-size buffer
135 Status
= NtUserBuildNameList(WindowStation
, sizeof(Buffer
), Buffer
, &RequiredSize
);
136 if (NT_SUCCESS(Status
))
138 /* Fixed-size buffer is large enough */
139 NameList
= (PWCHAR
) Buffer
;
141 else if (Status
== STATUS_BUFFER_TOO_SMALL
)
143 /* Allocate a larger buffer */
144 NameList
= HeapAlloc(GetProcessHeap(), 0, RequiredSize
);
145 if (NULL
== NameList
)
150 Status
= NtUserBuildNameList(WindowStation
, RequiredSize
, NameList
, NULL
);
151 if (! NT_SUCCESS(Status
))
153 HeapFree(GetProcessHeap(), 0, NameList
);
154 SetLastError(RtlNtStatusToDosError(Status
));
160 /* Some unrecognized error occured */
161 SetLastError(RtlNtStatusToDosError(Status
));
166 * Enum the names one by one
168 EntryCount
= *((DWORD
*) NameList
);
169 Name
= (PWCHAR
) ((PCHAR
) NameList
+ sizeof(DWORD
));
171 for (CurrentEntry
= 0; CurrentEntry
< EntryCount
&& Ret
; ++CurrentEntry
)
173 Ret
= (*EnumFunc
)(Name
, Context
);
174 Name
+= wcslen(Name
) + 1;
180 if (NameList
!= Buffer
)
182 HeapFree(GetProcessHeap(), 0, NameList
);
189 /* For W->A conversion */
190 typedef struct tagENUMNAMESASCIICONTEXT
192 NAMEENUMPROCA UserEnumFunc
;
194 } ENUMNAMESASCIICONTEXT
, *PENUMNAMESASCIICONTEXT
;
197 * Callback used by Ascii versions. Converts the Unicode name to
198 * Ascii and then calls the user callback
201 EnumNamesCallback(LPWSTR Name
, LPARAM Param
)
203 PENUMNAMESASCIICONTEXT Context
= (PENUMNAMESASCIICONTEXT
) Param
;
210 * Determine required size of Ascii string and see if we can use
213 Len
= WideCharToMultiByte(CP_ACP
, 0, Name
, -1, NULL
, 0, NULL
, NULL
);
216 /* Some strange error occured */
219 else if (Len
<= sizeof(FixedNameA
))
221 /* Fixed-size buffer is large enough */
226 /* Allocate a larger buffer */
227 NameA
= HeapAlloc(GetProcessHeap(), 0, Len
);
230 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
236 * Do the Unicode ->Ascii conversion
238 if (0 == WideCharToMultiByte(CP_ACP
, 0, Name
, -1, NameA
, Len
, NULL
, NULL
))
240 /* Something went wrong, clean up */
241 if (NameA
!= FixedNameA
)
243 HeapFree(GetProcessHeap(), 0, NameA
);
251 Ret
= Context
->UserEnumFunc(NameA
, Context
->UserContext
);
256 if (NameA
!= FixedNameA
)
258 HeapFree(GetProcessHeap(), 0, NameA
);
265 * Common code for EnumDesktopsA and EnumWindowStationsA
268 EnumNamesA(HWINSTA WindowStation
,
269 NAMEENUMPROCA EnumFunc
,
273 ENUMNAMESASCIICONTEXT PrivateContext
;
275 PrivateContext
.UserEnumFunc
= EnumFunc
;
276 PrivateContext
.UserContext
= Context
;
278 return EnumNamesW(WindowStation
, EnumNamesCallback
, (LPARAM
) &PrivateContext
, Desktops
);
285 EnumWindowStationsA(WINSTAENUMPROCA EnumFunc
,
288 return EnumNamesA(NULL
, EnumFunc
, Context
, FALSE
);
296 EnumWindowStationsW(WINSTAENUMPROCW EnumFunc
,
299 return EnumNamesW(NULL
, EnumFunc
, Context
, FALSE
);
307 OpenWindowStationA(LPCSTR lpszWinSta
,
309 ACCESS_MASK dwDesiredAccess
)
311 UNICODE_STRING WindowStationNameU
;
316 /* After conversion, the buffer is zero-terminated */
317 RtlCreateUnicodeStringFromAsciiz(&WindowStationNameU
, lpszWinSta
);
321 RtlInitUnicodeString(&WindowStationNameU
, NULL
);
324 hWinSta
= OpenWindowStationW(WindowStationNameU
.Buffer
,
328 /* Free the string, if it was allocated */
329 if (lpszWinSta
) RtlFreeUnicodeString(&WindowStationNameU
);
339 OpenWindowStationW(LPCWSTR lpszWinSta
,
341 ACCESS_MASK dwDesiredAccess
)
343 UNICODE_STRING WindowStationName
;
344 UNICODE_STRING WindowStationsDir
= RTL_CONSTANT_STRING(L
"\\Windows\\WindowStations");
345 OBJECT_ATTRIBUTES ObjectAttributes
;
346 HANDLE hWindowStationsDir
;
350 /* Open WindowStations directory */
351 InitializeObjectAttributes(&ObjectAttributes
,
353 OBJ_CASE_INSENSITIVE
,
357 Status
= NtOpenDirectoryObject(&hWindowStationsDir
,
360 if(!NT_SUCCESS(Status
))
362 ERR("Failed to open WindowStations directory\n");
366 /* Open the window station object */
367 RtlInitUnicodeString(&WindowStationName
, lpszWinSta
);
369 InitializeObjectAttributes(&ObjectAttributes
,
371 OBJ_CASE_INSENSITIVE
,
377 ObjectAttributes
.Attributes
|= OBJ_INHERIT
;
380 hwinsta
= NtUserOpenWindowStation(&ObjectAttributes
, dwDesiredAccess
);
382 NtClose(hWindowStationsDir
);
393 SetWindowStationUser(
400 return NtUserSetWindowStationUser(Unknown1
, Unknown2
, Unknown3
, Unknown4
);