d6c66a76f90ef7545f1ab88849c622bdb8cafefd
[reactos.git] / reactos / dll / win32 / user32 / misc / winsta.c
1 /* $Id$
2 *
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)
8 * UPDATE HISTORY:
9 * 04-06-2001 CSH Created
10 */
11
12 #include <user32.h>
13
14 #include <wine/debug.h>
15
16
17 /*
18 * @implemented
19 */
20 HWINSTA WINAPI
21 CreateWindowStationA(LPSTR lpwinsta,
22 DWORD dwReserved,
23 ACCESS_MASK dwDesiredAccess,
24 LPSECURITY_ATTRIBUTES lpsa)
25 {
26 UNICODE_STRING WindowStationNameU;
27 HWINSTA hWinSta;
28
29 if (lpwinsta)
30 {
31 /* After conversion, the buffer is zero-terminated */
32 RtlCreateUnicodeStringFromAsciiz(&WindowStationNameU, lpwinsta);
33 }
34 else
35 {
36 RtlInitUnicodeString(&WindowStationNameU, NULL);
37 }
38
39 hWinSta = CreateWindowStationW(WindowStationNameU.Buffer,
40 dwReserved,
41 dwDesiredAccess,
42 lpsa);
43
44 /* Free the string, if it was allocated */
45 if (lpwinsta) RtlFreeUnicodeString(&WindowStationNameU);
46
47 return hWinSta;
48 }
49
50
51 /*
52 * @implemented
53 */
54 HWINSTA WINAPI
55 CreateWindowStationW(LPWSTR lpwinsta,
56 DWORD dwReserved,
57 ACCESS_MASK dwDesiredAccess,
58 LPSECURITY_ATTRIBUTES lpsa)
59 {
60 UNICODE_STRING WindowStationName;
61
62 RtlInitUnicodeString(&WindowStationName, lpwinsta);
63
64 return NtUserCreateWindowStation(&WindowStationName,
65 dwDesiredAccess,
66 lpsa, 0, 0, 0, 0);
67 }
68
69 /*
70 * Common code for EnumDesktopsA/W and EnumWindowStationsA/W
71 */
72 BOOL FASTCALL
73 EnumNamesW(HWINSTA WindowStation,
74 NAMEENUMPROCW EnumFunc,
75 LPARAM Context,
76 BOOL Desktops)
77 {
78 char Buffer[256];
79 PVOID NameList;
80 PWCHAR Name;
81 NTSTATUS Status;
82 ULONG RequiredSize;
83 ULONG CurrentEntry, EntryCount;
84 BOOL Ret;
85
86 /*
87 * Check parameters
88 */
89 if (NULL == WindowStation && Desktops)
90 {
91 SetLastError(ERROR_INVALID_HANDLE);
92 return FALSE;
93 }
94
95 /*
96 * Try with fixed-size buffer
97 */
98 Status = NtUserBuildNameList(WindowStation, sizeof(Buffer), Buffer, &RequiredSize);
99 if (NT_SUCCESS(Status))
100 {
101 /* Fixed-size buffer is large enough */
102 NameList = (PWCHAR) Buffer;
103 }
104 else if (Status == STATUS_BUFFER_TOO_SMALL)
105 {
106 /* Allocate a larger buffer */
107 NameList = HeapAlloc(GetProcessHeap(), 0, RequiredSize);
108 if (NULL == NameList)
109 {
110 return FALSE;
111 }
112 /* Try again */
113 Status = NtUserBuildNameList(WindowStation, RequiredSize, NameList, NULL);
114 if (! NT_SUCCESS(Status))
115 {
116 HeapFree(GetProcessHeap(), 0, NameList);
117 SetLastError(RtlNtStatusToDosError(Status));
118 return FALSE;
119 }
120 }
121 else
122 {
123 /* Some unrecognized error occured */
124 SetLastError(RtlNtStatusToDosError(Status));
125 return FALSE;
126 }
127
128 /*
129 * Enum the names one by one
130 */
131 EntryCount = *((DWORD *) NameList);
132 Name = (PWCHAR) ((PCHAR) NameList + sizeof(DWORD));
133 Ret = TRUE;
134 for (CurrentEntry = 0; CurrentEntry < EntryCount && Ret; ++CurrentEntry)
135 {
136 Ret = (*EnumFunc)(Name, Context);
137 Name += wcslen(Name) + 1;
138 }
139
140 /*
141 * Cleanup
142 */
143 if (NameList != Buffer)
144 {
145 HeapFree(GetProcessHeap(), 0, NameList);
146 }
147
148 return Ret;
149 }
150
151
152 /* For W->A conversion */
153 typedef struct tagENUMNAMESASCIICONTEXT
154 {
155 NAMEENUMPROCA UserEnumFunc;
156 LPARAM UserContext;
157 } ENUMNAMESASCIICONTEXT, *PENUMNAMESASCIICONTEXT;
158
159 /*
160 * Callback used by Ascii versions. Converts the Unicode name to
161 * Ascii and then calls the user callback
162 */
163 BOOL CALLBACK
164 EnumNamesCallback(LPWSTR Name, LPARAM Param)
165 {
166 PENUMNAMESASCIICONTEXT Context = (PENUMNAMESASCIICONTEXT) Param;
167 char FixedNameA[32];
168 LPSTR NameA;
169 int Len;
170 BOOL Ret;
171
172 /*
173 * Determine required size of Ascii string and see if we can use
174 * fixed buffer
175 */
176 Len = WideCharToMultiByte(CP_ACP, 0, Name, -1, NULL, 0, NULL, NULL);
177 if (Len <= 0)
178 {
179 /* Some strange error occured */
180 return FALSE;
181 }
182 else if (Len <= sizeof(FixedNameA))
183 {
184 /* Fixed-size buffer is large enough */
185 NameA = FixedNameA;
186 }
187 else
188 {
189 /* Allocate a larger buffer */
190 NameA = HeapAlloc(GetProcessHeap(), 0, Len);
191 if (NULL == NameA)
192 {
193 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
194 return FALSE;
195 }
196 }
197
198 /*
199 * Do the Unicode ->Ascii conversion
200 */
201 if (0 == WideCharToMultiByte(CP_ACP, 0, Name, -1, NameA, Len, NULL, NULL))
202 {
203 /* Something went wrong, clean up */
204 if (NameA != FixedNameA)
205 {
206 HeapFree(GetProcessHeap(), 0, NameA);
207 }
208 return FALSE;
209 }
210
211 /*
212 * Call user callback
213 */
214 Ret = Context->UserEnumFunc(NameA, Context->UserContext);
215
216 /*
217 * Clean up
218 */
219 if (NameA != FixedNameA)
220 {
221 HeapFree(GetProcessHeap(), 0, NameA);
222 }
223
224 return Ret;
225 }
226
227 /*
228 * Common code for EnumDesktopsA and EnumWindowStationsA
229 */
230 BOOL FASTCALL
231 EnumNamesA(HWINSTA WindowStation,
232 NAMEENUMPROCA EnumFunc,
233 LPARAM Context,
234 BOOL Desktops)
235 {
236 ENUMNAMESASCIICONTEXT PrivateContext;
237
238 PrivateContext.UserEnumFunc = EnumFunc;
239 PrivateContext.UserContext = Context;
240
241 return EnumNamesW(WindowStation, EnumNamesCallback, (LPARAM) &PrivateContext, Desktops);
242 }
243
244 /*
245 * @implemented
246 */
247 BOOL WINAPI
248 EnumWindowStationsA(WINSTAENUMPROCA EnumFunc,
249 LPARAM Context)
250 {
251 return EnumNamesA(NULL, EnumFunc, Context, FALSE);
252 }
253
254
255 /*
256 * @implemented
257 */
258 BOOL WINAPI
259 EnumWindowStationsW(WINSTAENUMPROCW EnumFunc,
260 LPARAM Context)
261 {
262 return EnumNamesW(NULL, EnumFunc, Context, FALSE);
263 }
264
265
266 /*
267 * @implemented
268 */
269 HWINSTA WINAPI
270 OpenWindowStationA(LPSTR lpszWinSta,
271 BOOL fInherit,
272 ACCESS_MASK dwDesiredAccess)
273 {
274 UNICODE_STRING WindowStationNameU;
275 HWINSTA hWinSta;
276
277 if (lpszWinSta)
278 {
279 /* After conversion, the buffer is zero-terminated */
280 RtlCreateUnicodeStringFromAsciiz(&WindowStationNameU, lpszWinSta);
281 }
282 else
283 {
284 RtlInitUnicodeString(&WindowStationNameU, NULL);
285 }
286
287 hWinSta = OpenWindowStationW(WindowStationNameU.Buffer,
288 fInherit,
289 dwDesiredAccess);
290
291 /* Free the string, if it was allocated */
292 if (lpszWinSta) RtlFreeUnicodeString(&WindowStationNameU);
293
294 return hWinSta;
295 }
296
297
298 /*
299 * @implemented
300 */
301 HWINSTA WINAPI
302 OpenWindowStationW(LPWSTR lpszWinSta,
303 BOOL fInherit,
304 ACCESS_MASK dwDesiredAccess)
305 {
306 UNICODE_STRING WindowStationName;
307
308 RtlInitUnicodeString(&WindowStationName, lpszWinSta);
309
310 return NtUserOpenWindowStation(&WindowStationName, dwDesiredAccess);
311 }
312
313
314 /*
315 * @unimplemented
316 */
317 DWORD
318 WINAPI
319 SetWindowStationUser(
320 DWORD Unknown1,
321 DWORD Unknown2,
322 DWORD Unknown3,
323 DWORD Unknown4
324 )
325 {
326 return NtUserSetWindowStationUser(Unknown1, Unknown2, Unknown3, Unknown4);
327 }
328
329 /* EOF */
330