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>
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
;
62 RtlInitUnicodeString(&WindowStationName
, lpwinsta
);
64 return NtUserCreateWindowStation(&WindowStationName
,
70 * Common code for EnumDesktopsA/W and EnumWindowStationsA/W
73 EnumNamesW(HWINSTA WindowStation
,
74 NAMEENUMPROCW EnumFunc
,
83 ULONG CurrentEntry
, EntryCount
;
89 if (NULL
== WindowStation
&& Desktops
)
91 WindowStation
= GetProcessWindowStation();
95 * Try with fixed-size buffer
97 Status
= NtUserBuildNameList(WindowStation
, sizeof(Buffer
), Buffer
, &RequiredSize
);
98 if (NT_SUCCESS(Status
))
100 /* Fixed-size buffer is large enough */
101 NameList
= (PWCHAR
) Buffer
;
103 else if (Status
== STATUS_BUFFER_TOO_SMALL
)
105 /* Allocate a larger buffer */
106 NameList
= HeapAlloc(GetProcessHeap(), 0, RequiredSize
);
107 if (NULL
== NameList
)
112 Status
= NtUserBuildNameList(WindowStation
, RequiredSize
, NameList
, NULL
);
113 if (! NT_SUCCESS(Status
))
115 HeapFree(GetProcessHeap(), 0, NameList
);
116 SetLastError(RtlNtStatusToDosError(Status
));
122 /* Some unrecognized error occured */
123 SetLastError(RtlNtStatusToDosError(Status
));
128 * Enum the names one by one
130 EntryCount
= *((DWORD
*) NameList
);
131 Name
= (PWCHAR
) ((PCHAR
) NameList
+ sizeof(DWORD
));
133 for (CurrentEntry
= 0; CurrentEntry
< EntryCount
&& Ret
; ++CurrentEntry
)
135 Ret
= (*EnumFunc
)(Name
, Context
);
136 Name
+= wcslen(Name
) + 1;
142 if (NameList
!= Buffer
)
144 HeapFree(GetProcessHeap(), 0, NameList
);
151 /* For W->A conversion */
152 typedef struct tagENUMNAMESASCIICONTEXT
154 NAMEENUMPROCA UserEnumFunc
;
156 } ENUMNAMESASCIICONTEXT
, *PENUMNAMESASCIICONTEXT
;
159 * Callback used by Ascii versions. Converts the Unicode name to
160 * Ascii and then calls the user callback
163 EnumNamesCallback(LPWSTR Name
, LPARAM Param
)
165 PENUMNAMESASCIICONTEXT Context
= (PENUMNAMESASCIICONTEXT
) Param
;
172 * Determine required size of Ascii string and see if we can use
175 Len
= WideCharToMultiByte(CP_ACP
, 0, Name
, -1, NULL
, 0, NULL
, NULL
);
178 /* Some strange error occured */
181 else if (Len
<= sizeof(FixedNameA
))
183 /* Fixed-size buffer is large enough */
188 /* Allocate a larger buffer */
189 NameA
= HeapAlloc(GetProcessHeap(), 0, Len
);
192 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
198 * Do the Unicode ->Ascii conversion
200 if (0 == WideCharToMultiByte(CP_ACP
, 0, Name
, -1, NameA
, Len
, NULL
, NULL
))
202 /* Something went wrong, clean up */
203 if (NameA
!= FixedNameA
)
205 HeapFree(GetProcessHeap(), 0, NameA
);
213 Ret
= Context
->UserEnumFunc(NameA
, Context
->UserContext
);
218 if (NameA
!= FixedNameA
)
220 HeapFree(GetProcessHeap(), 0, NameA
);
227 * Common code for EnumDesktopsA and EnumWindowStationsA
230 EnumNamesA(HWINSTA WindowStation
,
231 NAMEENUMPROCA EnumFunc
,
235 ENUMNAMESASCIICONTEXT PrivateContext
;
237 PrivateContext
.UserEnumFunc
= EnumFunc
;
238 PrivateContext
.UserContext
= Context
;
240 return EnumNamesW(WindowStation
, EnumNamesCallback
, (LPARAM
) &PrivateContext
, Desktops
);
247 EnumWindowStationsA(WINSTAENUMPROCA EnumFunc
,
250 return EnumNamesA(NULL
, EnumFunc
, Context
, FALSE
);
258 EnumWindowStationsW(WINSTAENUMPROCW EnumFunc
,
261 return EnumNamesW(NULL
, EnumFunc
, Context
, FALSE
);
269 OpenWindowStationA(LPCSTR lpszWinSta
,
271 ACCESS_MASK dwDesiredAccess
)
273 UNICODE_STRING WindowStationNameU
;
278 /* After conversion, the buffer is zero-terminated */
279 RtlCreateUnicodeStringFromAsciiz(&WindowStationNameU
, lpszWinSta
);
283 RtlInitUnicodeString(&WindowStationNameU
, NULL
);
286 hWinSta
= OpenWindowStationW(WindowStationNameU
.Buffer
,
290 /* Free the string, if it was allocated */
291 if (lpszWinSta
) RtlFreeUnicodeString(&WindowStationNameU
);
301 OpenWindowStationW(LPCWSTR lpszWinSta
,
303 ACCESS_MASK dwDesiredAccess
)
305 UNICODE_STRING WindowStationName
;
307 RtlInitUnicodeString(&WindowStationName
, lpszWinSta
);
309 return NtUserOpenWindowStation(&WindowStationName
, dwDesiredAccess
);
318 SetWindowStationUser(
325 return NtUserSetWindowStationUser(Unknown1
, Unknown2
, Unknown3
, Unknown4
);