- Fix 2 user32 winstation test failures (patch by Giannis Adamopoulos johnyadams...
[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 WindowStation = GetProcessWindowStation();
92 }
93
94 /*
95 * Try with fixed-size buffer
96 */
97 Status = NtUserBuildNameList(WindowStation, sizeof(Buffer), Buffer, &RequiredSize);
98 if (NT_SUCCESS(Status))
99 {
100 /* Fixed-size buffer is large enough */
101 NameList = (PWCHAR) Buffer;
102 }
103 else if (Status == STATUS_BUFFER_TOO_SMALL)
104 {
105 /* Allocate a larger buffer */
106 NameList = HeapAlloc(GetProcessHeap(), 0, RequiredSize);
107 if (NULL == NameList)
108 {
109 return FALSE;
110 }
111 /* Try again */
112 Status = NtUserBuildNameList(WindowStation, RequiredSize, NameList, NULL);
113 if (! NT_SUCCESS(Status))
114 {
115 HeapFree(GetProcessHeap(), 0, NameList);
116 SetLastError(RtlNtStatusToDosError(Status));
117 return FALSE;
118 }
119 }
120 else
121 {
122 /* Some unrecognized error occured */
123 SetLastError(RtlNtStatusToDosError(Status));
124 return FALSE;
125 }
126
127 /*
128 * Enum the names one by one
129 */
130 EntryCount = *((DWORD *) NameList);
131 Name = (PWCHAR) ((PCHAR) NameList + sizeof(DWORD));
132 Ret = TRUE;
133 for (CurrentEntry = 0; CurrentEntry < EntryCount && Ret; ++CurrentEntry)
134 {
135 Ret = (*EnumFunc)(Name, Context);
136 Name += wcslen(Name) + 1;
137 }
138
139 /*
140 * Cleanup
141 */
142 if (NameList != Buffer)
143 {
144 HeapFree(GetProcessHeap(), 0, NameList);
145 }
146
147 return Ret;
148 }
149
150
151 /* For W->A conversion */
152 typedef struct tagENUMNAMESASCIICONTEXT
153 {
154 NAMEENUMPROCA UserEnumFunc;
155 LPARAM UserContext;
156 } ENUMNAMESASCIICONTEXT, *PENUMNAMESASCIICONTEXT;
157
158 /*
159 * Callback used by Ascii versions. Converts the Unicode name to
160 * Ascii and then calls the user callback
161 */
162 BOOL CALLBACK
163 EnumNamesCallback(LPWSTR Name, LPARAM Param)
164 {
165 PENUMNAMESASCIICONTEXT Context = (PENUMNAMESASCIICONTEXT) Param;
166 char FixedNameA[32];
167 LPSTR NameA;
168 int Len;
169 BOOL Ret;
170
171 /*
172 * Determine required size of Ascii string and see if we can use
173 * fixed buffer
174 */
175 Len = WideCharToMultiByte(CP_ACP, 0, Name, -1, NULL, 0, NULL, NULL);
176 if (Len <= 0)
177 {
178 /* Some strange error occured */
179 return FALSE;
180 }
181 else if (Len <= sizeof(FixedNameA))
182 {
183 /* Fixed-size buffer is large enough */
184 NameA = FixedNameA;
185 }
186 else
187 {
188 /* Allocate a larger buffer */
189 NameA = HeapAlloc(GetProcessHeap(), 0, Len);
190 if (NULL == NameA)
191 {
192 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
193 return FALSE;
194 }
195 }
196
197 /*
198 * Do the Unicode ->Ascii conversion
199 */
200 if (0 == WideCharToMultiByte(CP_ACP, 0, Name, -1, NameA, Len, NULL, NULL))
201 {
202 /* Something went wrong, clean up */
203 if (NameA != FixedNameA)
204 {
205 HeapFree(GetProcessHeap(), 0, NameA);
206 }
207 return FALSE;
208 }
209
210 /*
211 * Call user callback
212 */
213 Ret = Context->UserEnumFunc(NameA, Context->UserContext);
214
215 /*
216 * Clean up
217 */
218 if (NameA != FixedNameA)
219 {
220 HeapFree(GetProcessHeap(), 0, NameA);
221 }
222
223 return Ret;
224 }
225
226 /*
227 * Common code for EnumDesktopsA and EnumWindowStationsA
228 */
229 BOOL FASTCALL
230 EnumNamesA(HWINSTA WindowStation,
231 NAMEENUMPROCA EnumFunc,
232 LPARAM Context,
233 BOOL Desktops)
234 {
235 ENUMNAMESASCIICONTEXT PrivateContext;
236
237 PrivateContext.UserEnumFunc = EnumFunc;
238 PrivateContext.UserContext = Context;
239
240 return EnumNamesW(WindowStation, EnumNamesCallback, (LPARAM) &PrivateContext, Desktops);
241 }
242
243 /*
244 * @implemented
245 */
246 BOOL WINAPI
247 EnumWindowStationsA(WINSTAENUMPROCA EnumFunc,
248 LPARAM Context)
249 {
250 return EnumNamesA(NULL, EnumFunc, Context, FALSE);
251 }
252
253
254 /*
255 * @implemented
256 */
257 BOOL WINAPI
258 EnumWindowStationsW(WINSTAENUMPROCW EnumFunc,
259 LPARAM Context)
260 {
261 return EnumNamesW(NULL, EnumFunc, Context, FALSE);
262 }
263
264
265 /*
266 * @implemented
267 */
268 HWINSTA WINAPI
269 OpenWindowStationA(LPSTR lpszWinSta,
270 BOOL fInherit,
271 ACCESS_MASK dwDesiredAccess)
272 {
273 UNICODE_STRING WindowStationNameU;
274 HWINSTA hWinSta;
275
276 if (lpszWinSta)
277 {
278 /* After conversion, the buffer is zero-terminated */
279 RtlCreateUnicodeStringFromAsciiz(&WindowStationNameU, lpszWinSta);
280 }
281 else
282 {
283 RtlInitUnicodeString(&WindowStationNameU, NULL);
284 }
285
286 hWinSta = OpenWindowStationW(WindowStationNameU.Buffer,
287 fInherit,
288 dwDesiredAccess);
289
290 /* Free the string, if it was allocated */
291 if (lpszWinSta) RtlFreeUnicodeString(&WindowStationNameU);
292
293 return hWinSta;
294 }
295
296
297 /*
298 * @implemented
299 */
300 HWINSTA WINAPI
301 OpenWindowStationW(LPWSTR lpszWinSta,
302 BOOL fInherit,
303 ACCESS_MASK dwDesiredAccess)
304 {
305 UNICODE_STRING WindowStationName;
306
307 RtlInitUnicodeString(&WindowStationName, lpszWinSta);
308
309 return NtUserOpenWindowStation(&WindowStationName, dwDesiredAccess);
310 }
311
312
313 /*
314 * @unimplemented
315 */
316 DWORD
317 WINAPI
318 SetWindowStationUser(
319 DWORD Unknown1,
320 DWORD Unknown2,
321 DWORD Unknown3,
322 DWORD Unknown4
323 )
324 {
325 return NtUserSetWindowStationUser(Unknown1, Unknown2, Unknown3, Unknown4);
326 }
327
328 /* EOF */
329