include/mscvpdb.h: Use flexible array members for the rest of structures.
[wine.git] / dlls / user32 / winstation.c
blobec8be243b32d917b669fa182bd18b13529b65dc8
1 /*
2 * Window stations and desktops
4 * Copyright 2002 Alexandre Julliard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "ntstatus.h"
22 #define WIN32_NO_STATUS
24 #include <stdarg.h>
25 #include "windef.h"
26 #include "winbase.h"
27 #include "winnls.h"
28 #include "winerror.h"
29 #include "wingdi.h"
30 #include "winuser.h"
31 #include "winternl.h"
32 #include "ddk/wdm.h"
33 #include "wine/server.h"
34 #include "wine/debug.h"
35 #include "user_private.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(winstation);
40 /* callback for enumeration functions */
41 struct enum_proc_lparam
43 NAMEENUMPROCA func;
44 LPARAM lparam;
47 static BOOL CALLBACK enum_names_WtoA( LPWSTR name, LPARAM lparam )
49 struct enum_proc_lparam *data = (struct enum_proc_lparam *)lparam;
50 char buffer[MAX_PATH];
52 if (!WideCharToMultiByte( CP_ACP, 0, name, -1, buffer, sizeof(buffer), NULL, NULL ))
53 return FALSE;
54 return data->func( buffer, data->lparam );
57 /* return a handle to the directory where window station objects are created */
58 static HANDLE get_winstations_dir_handle(void)
60 static HANDLE handle = NULL;
61 WCHAR buffer[64];
62 UNICODE_STRING str;
63 OBJECT_ATTRIBUTES attr;
65 if (!handle)
67 HANDLE dir;
69 swprintf( buffer, ARRAY_SIZE(buffer), L"\\Sessions\\%u\\Windows\\WindowStations", NtCurrentTeb()->Peb->SessionId );
70 RtlInitUnicodeString( &str, buffer );
71 InitializeObjectAttributes( &attr, &str, 0, 0, NULL );
72 NtOpenDirectoryObject( &dir, DIRECTORY_CREATE_OBJECT | DIRECTORY_TRAVERSE, &attr );
73 if (InterlockedCompareExchangePointer( &handle, dir, 0 ) != 0) /* someone beat us here */
74 CloseHandle( dir );
76 return handle;
79 static WCHAR default_name[29];
81 static BOOL WINAPI winstation_default_name_once( INIT_ONCE *once, void *param, void **context )
83 TOKEN_STATISTICS stats;
84 BOOL ret;
86 ret = GetTokenInformation( GetCurrentProcessToken(), TokenStatistics, &stats, sizeof(stats), NULL );
87 if (ret)
88 swprintf( default_name, ARRAY_SIZE(default_name), L"Service-0x%x-%x$",
89 stats.AuthenticationId.HighPart, stats.AuthenticationId.LowPart );
91 return ret;
94 static const WCHAR *get_winstation_default_name( void )
96 static INIT_ONCE once = INIT_ONCE_STATIC_INIT;
97 BOOL ret;
99 ret = InitOnceExecuteOnce( &once, winstation_default_name_once, NULL, NULL );
100 return ret ? default_name : NULL;
103 /***********************************************************************
104 * CreateWindowStationA (USER32.@)
106 HWINSTA WINAPI CreateWindowStationA( LPCSTR name, DWORD flags, ACCESS_MASK access,
107 LPSECURITY_ATTRIBUTES sa )
109 WCHAR buffer[MAX_PATH];
111 if (!name) return CreateWindowStationW( NULL, flags, access, sa );
113 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
115 SetLastError( ERROR_FILENAME_EXCED_RANGE );
116 return 0;
118 return CreateWindowStationW( buffer, flags, access, sa );
122 /***********************************************************************
123 * CreateWindowStationW (USER32.@)
125 HWINSTA WINAPI CreateWindowStationW( LPCWSTR name, DWORD flags, ACCESS_MASK access,
126 LPSECURITY_ATTRIBUTES sa )
128 OBJECT_ATTRIBUTES attr;
129 UNICODE_STRING str;
131 RtlInitUnicodeString( &str, name );
132 if (!str.Length) RtlInitUnicodeString( &str, get_winstation_default_name() );
134 InitializeObjectAttributes( &attr, &str, OBJ_CASE_INSENSITIVE,
135 get_winstations_dir_handle(), sa );
136 if (!(flags & CWF_CREATE_ONLY)) attr.Attributes |= OBJ_OPENIF;
137 if (sa && sa->bInheritHandle) attr.Attributes |= OBJ_INHERIT;
139 return NtUserCreateWindowStation( &attr, access, 0, 0, 0, 0, 0 );
143 /******************************************************************************
144 * OpenWindowStationA (USER32.@)
146 HWINSTA WINAPI OpenWindowStationA( LPCSTR name, BOOL inherit, ACCESS_MASK access )
148 WCHAR buffer[MAX_PATH];
150 if (!name) return OpenWindowStationW( NULL, inherit, access );
152 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
154 SetLastError( ERROR_FILENAME_EXCED_RANGE );
155 return 0;
157 return OpenWindowStationW( buffer, inherit, access );
161 /******************************************************************************
162 * OpenWindowStationW (USER32.@)
164 HWINSTA WINAPI OpenWindowStationW( LPCWSTR name, BOOL inherit, ACCESS_MASK access )
166 OBJECT_ATTRIBUTES attr;
167 UNICODE_STRING str;
169 RtlInitUnicodeString( &str, name );
170 if (!str.Length) RtlInitUnicodeString( &str, get_winstation_default_name() );
172 InitializeObjectAttributes( &attr, &str, OBJ_CASE_INSENSITIVE,
173 get_winstations_dir_handle(), NULL );
174 if (inherit) attr.Attributes |= OBJ_INHERIT;
176 return NtUserOpenWindowStation( &attr, access );
180 /******************************************************************************
181 * EnumWindowStationsA (USER32.@)
183 BOOL WINAPI EnumWindowStationsA( WINSTAENUMPROCA func, LPARAM lparam )
185 struct enum_proc_lparam data;
186 data.func = func;
187 data.lparam = lparam;
188 return EnumWindowStationsW( enum_names_WtoA, (LPARAM)&data );
192 /******************************************************************************
193 * EnumWindowStationsW (USER32.@)
195 BOOL WINAPI EnumWindowStationsW( WINSTAENUMPROCW func, LPARAM lparam )
197 unsigned int index = 0;
198 WCHAR name[MAX_PATH];
199 BOOL ret = TRUE;
200 NTSTATUS status;
202 while (ret)
204 SERVER_START_REQ( enum_winstation )
206 req->index = index;
207 wine_server_set_reply( req, name, sizeof(name) - sizeof(WCHAR) );
208 status = wine_server_call( req );
209 name[wine_server_reply_size(reply)/sizeof(WCHAR)] = 0;
210 index = reply->next;
212 SERVER_END_REQ;
213 if (status == STATUS_NO_MORE_ENTRIES)
214 break;
215 if (status)
217 SetLastError( RtlNtStatusToDosError( status ) );
218 return FALSE;
220 ret = func( name, lparam );
222 return ret;
226 /***********************************************************************
227 * CreateDesktopA (USER32.@)
229 HDESK WINAPI CreateDesktopA( LPCSTR name, LPCSTR device, LPDEVMODEA devmode,
230 DWORD flags, ACCESS_MASK access, LPSECURITY_ATTRIBUTES sa )
232 WCHAR buffer[MAX_PATH];
234 if (device || devmode)
236 SetLastError( ERROR_INVALID_PARAMETER );
237 return 0;
239 if (!name) return CreateDesktopW( NULL, NULL, NULL, flags, access, sa );
241 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
243 SetLastError( ERROR_FILENAME_EXCED_RANGE );
244 return 0;
246 return CreateDesktopW( buffer, NULL, NULL, flags, access, sa );
250 /***********************************************************************
251 * CreateDesktopW (USER32.@)
253 HDESK WINAPI CreateDesktopW( LPCWSTR name, LPCWSTR device, LPDEVMODEW devmode,
254 DWORD flags, ACCESS_MASK access, LPSECURITY_ATTRIBUTES sa )
256 OBJECT_ATTRIBUTES attr;
257 UNICODE_STRING str;
259 if (device || (devmode && !(flags & DF_WINE_VIRTUAL_DESKTOP))
260 || (flags & DF_WINE_ROOT_DESKTOP && flags & DF_WINE_VIRTUAL_DESKTOP))
262 SetLastError( ERROR_INVALID_PARAMETER );
263 return 0;
266 RtlInitUnicodeString( &str, name );
267 InitializeObjectAttributes( &attr, &str, OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
268 get_winstations_dir_handle(), NULL );
269 if (sa && sa->bInheritHandle) attr.Attributes |= OBJ_INHERIT;
270 return NtUserCreateDesktopEx( &attr, NULL, devmode, flags, access, 0 );
274 /******************************************************************************
275 * OpenDesktopA (USER32.@)
277 HDESK WINAPI OpenDesktopA( LPCSTR name, DWORD flags, BOOL inherit, ACCESS_MASK access )
279 WCHAR buffer[MAX_PATH];
281 if (!name) return OpenDesktopW( NULL, flags, inherit, access );
283 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
285 SetLastError( ERROR_FILENAME_EXCED_RANGE );
286 return 0;
288 return OpenDesktopW( buffer, flags, inherit, access );
292 HDESK open_winstation_desktop( HWINSTA hwinsta, LPCWSTR name, DWORD flags, BOOL inherit, ACCESS_MASK access )
294 OBJECT_ATTRIBUTES attr;
295 UNICODE_STRING str;
297 RtlInitUnicodeString( &str, name );
298 InitializeObjectAttributes( &attr, &str, OBJ_CASE_INSENSITIVE, hwinsta, NULL );
299 if (inherit) attr.Attributes |= OBJ_INHERIT;
300 return NtUserOpenDesktop( &attr, flags, access );
304 /******************************************************************************
305 * OpenDesktopW (USER32.@)
307 HDESK WINAPI OpenDesktopW( LPCWSTR name, DWORD flags, BOOL inherit, ACCESS_MASK access )
309 return open_winstation_desktop( NULL, name, flags, inherit, access );
313 /******************************************************************************
314 * EnumDesktopsA (USER32.@)
316 BOOL WINAPI EnumDesktopsA( HWINSTA winsta, DESKTOPENUMPROCA func, LPARAM lparam )
318 struct enum_proc_lparam data;
319 data.func = func;
320 data.lparam = lparam;
321 return EnumDesktopsW( winsta, enum_names_WtoA, (LPARAM)&data );
325 /******************************************************************************
326 * EnumDesktopsW (USER32.@)
328 BOOL WINAPI EnumDesktopsW( HWINSTA winsta, DESKTOPENUMPROCW func, LPARAM lparam )
330 unsigned int index = 0;
331 WCHAR name[MAX_PATH];
332 BOOL ret = TRUE;
333 NTSTATUS status;
335 if (!winsta)
336 winsta = NtUserGetProcessWindowStation();
338 while (ret)
340 SERVER_START_REQ( enum_desktop )
342 req->winstation = wine_server_obj_handle( winsta );
343 req->index = index;
344 wine_server_set_reply( req, name, sizeof(name) - sizeof(WCHAR) );
345 status = wine_server_call( req );
346 name[wine_server_reply_size(reply)/sizeof(WCHAR)] = 0;
347 index = reply->next;
349 SERVER_END_REQ;
350 if (status == STATUS_NO_MORE_ENTRIES)
351 break;
352 if (status)
354 SetLastError( RtlNtStatusToDosError( status ) );
355 return FALSE;
357 ret = func(name, lparam);
359 return ret;
363 /***********************************************************************
364 * GetUserObjectInformationA (USER32.@)
366 BOOL WINAPI GetUserObjectInformationA( HANDLE handle, INT index, LPVOID info, DWORD len, LPDWORD needed )
368 /* check for information types returning strings */
369 if (index == UOI_TYPE || index == UOI_NAME)
371 WCHAR buffer[MAX_PATH];
372 DWORD lenA, lenW;
374 if (!NtUserGetObjectInformation( handle, index, buffer, sizeof(buffer), &lenW )) return FALSE;
375 lenA = WideCharToMultiByte( CP_ACP, 0, buffer, -1, NULL, 0, NULL, NULL );
376 if (needed) *needed = lenA;
377 if (lenA > len)
379 /* If the buffer length supplied by the caller is insufficient, Windows returns a
380 'needed' length based upon the Unicode byte length, so we should do similarly. */
381 if (needed) *needed = lenW;
383 SetLastError( ERROR_INSUFFICIENT_BUFFER );
384 return FALSE;
386 if (info) WideCharToMultiByte( CP_ACP, 0, buffer, -1, info, len, NULL, NULL );
387 return TRUE;
389 return NtUserGetObjectInformation( handle, index, info, len, needed );
393 /******************************************************************************
394 * SetUserObjectInformationA (USER32.@)
396 BOOL WINAPI SetUserObjectInformationA( HANDLE handle, INT index, LPVOID info, DWORD len )
398 return NtUserSetObjectInformation( handle, index, info, len );
402 /***********************************************************************
403 * GetUserObjectSecurity (USER32.@)
405 BOOL WINAPI GetUserObjectSecurity( HANDLE handle, PSECURITY_INFORMATION info,
406 PSECURITY_DESCRIPTOR sid, DWORD len, LPDWORD needed )
408 FIXME( "(%p %p %p len=%ld %p),stub!\n", handle, info, sid, len, needed );
409 if (needed)
410 *needed = sizeof(SECURITY_DESCRIPTOR);
411 if (len < sizeof(SECURITY_DESCRIPTOR))
413 SetLastError( ERROR_INSUFFICIENT_BUFFER );
414 return FALSE;
416 return InitializeSecurityDescriptor(sid, SECURITY_DESCRIPTOR_REVISION);
419 /***********************************************************************
420 * SetUserObjectSecurity (USER32.@)
422 BOOL WINAPI SetUserObjectSecurity( HANDLE handle, PSECURITY_INFORMATION info,
423 PSECURITY_DESCRIPTOR sid )
425 FIXME( "(%p,%p,%p),stub!\n", handle, info, sid );
426 return TRUE;