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