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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #include "wine/server.h"
29 #include "wine/unicode.h"
30 #include "wine/debug.h"
31 #include "user_private.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(winstation);
36 /* callback for enumeration functions */
37 struct enum_proc_lparam
43 static BOOL CALLBACK enum_names_WtoA( LPWSTR name, LPARAM lparam )
45 struct enum_proc_lparam *data = (struct enum_proc_lparam *)lparam;
46 char buffer[MAX_PATH];
48 if (!WideCharToMultiByte( CP_ACP, 0, name, -1, buffer, sizeof(buffer), NULL, NULL ))
50 return data->func( buffer, data->lparam );
54 /***********************************************************************
55 * CreateWindowStationA (USER32.@)
57 HWINSTA WINAPI CreateWindowStationA( LPCSTR name, DWORD reserved, ACCESS_MASK access,
58 LPSECURITY_ATTRIBUTES sa )
60 WCHAR buffer[MAX_PATH];
62 if (!name) return CreateWindowStationW( NULL, reserved, access, sa );
64 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
66 SetLastError( ERROR_FILENAME_EXCED_RANGE );
69 return CreateWindowStationW( buffer, reserved, access, sa );
73 /***********************************************************************
74 * CreateWindowStationW (USER32.@)
76 HWINSTA WINAPI CreateWindowStationW( LPCWSTR name, DWORD reserved, ACCESS_MASK access,
77 LPSECURITY_ATTRIBUTES sa )
80 DWORD len = name ? strlenW(name) : 0;
84 SetLastError( ERROR_FILENAME_EXCED_RANGE );
87 SERVER_START_REQ( create_winstation )
91 req->attributes = OBJ_CASE_INSENSITIVE | OBJ_OPENIF |
92 ((sa && sa->bInheritHandle) ? OBJ_INHERIT : 0);
93 wine_server_add_data( req, name, len * sizeof(WCHAR) );
94 /* it doesn't seem to set last error */
95 wine_server_call( req );
103 /******************************************************************************
104 * OpenWindowStationA (USER32.@)
106 HWINSTA WINAPI OpenWindowStationA( LPCSTR name, BOOL inherit, ACCESS_MASK access )
108 WCHAR buffer[MAX_PATH];
110 if (!name) return OpenWindowStationW( NULL, inherit, access );
112 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
114 SetLastError( ERROR_FILENAME_EXCED_RANGE );
117 return OpenWindowStationW( buffer, inherit, access );
121 /******************************************************************************
122 * OpenWindowStationW (USER32.@)
124 HWINSTA WINAPI OpenWindowStationW( LPCWSTR name, BOOL inherit, ACCESS_MASK access )
127 DWORD len = name ? strlenW(name) : 0;
130 SetLastError( ERROR_FILENAME_EXCED_RANGE );
133 SERVER_START_REQ( open_winstation )
135 req->access = access;
136 req->attributes = OBJ_CASE_INSENSITIVE | (inherit ? OBJ_INHERIT : 0);
137 wine_server_add_data( req, name, len * sizeof(WCHAR) );
138 if (!wine_server_call_err( req )) ret = reply->handle;
145 /***********************************************************************
146 * CloseWindowStation (USER32.@)
148 BOOL WINAPI CloseWindowStation( HWINSTA handle )
151 SERVER_START_REQ( close_winstation )
153 req->handle = handle;
154 ret = !wine_server_call_err( req );
161 /******************************************************************************
162 * GetProcessWindowStation (USER32.@)
164 HWINSTA WINAPI GetProcessWindowStation(void)
168 SERVER_START_REQ( get_process_winstation )
170 if (!wine_server_call_err( req )) ret = reply->handle;
177 /***********************************************************************
178 * SetProcessWindowStation (USER32.@)
180 BOOL WINAPI SetProcessWindowStation( HWINSTA handle )
184 SERVER_START_REQ( set_process_winstation )
186 req->handle = handle;
187 ret = !wine_server_call_err( req );
194 /******************************************************************************
195 * EnumWindowStationsA (USER32.@)
197 BOOL WINAPI EnumWindowStationsA( WINSTAENUMPROCA func, LPARAM lparam )
199 struct enum_proc_lparam data;
201 data.lparam = lparam;
202 return EnumWindowStationsW( enum_names_WtoA, (LPARAM)&data );
206 /******************************************************************************
207 * EnumWindowStationsA (USER32.@)
209 BOOL WINAPI EnumWindowStationsW( WINSTAENUMPROCW func, LPARAM lparam )
211 FIXME( "(%p,%lx): stub\n", func, lparam );
212 SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
217 /***********************************************************************
218 * CreateDesktopA (USER32.@)
220 HDESK WINAPI CreateDesktopA( LPCSTR name, LPCSTR device, LPDEVMODEA devmode,
221 DWORD flags, ACCESS_MASK access, LPSECURITY_ATTRIBUTES sa )
223 WCHAR buffer[MAX_PATH];
225 if (device || devmode)
227 SetLastError( ERROR_INVALID_PARAMETER );
230 if (!name) return CreateDesktopW( NULL, NULL, NULL, flags, access, sa );
232 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
234 SetLastError( ERROR_FILENAME_EXCED_RANGE );
237 return CreateDesktopW( buffer, NULL, NULL, flags, access, sa );
241 /***********************************************************************
242 * CreateDesktopW (USER32.@)
244 HDESK WINAPI CreateDesktopW( LPCWSTR name, LPCWSTR device, LPDEVMODEW devmode,
245 DWORD flags, ACCESS_MASK access, LPSECURITY_ATTRIBUTES sa )
248 DWORD len = name ? strlenW(name) : 0;
250 if (device || devmode)
252 SetLastError( ERROR_INVALID_PARAMETER );
257 SetLastError( ERROR_FILENAME_EXCED_RANGE );
260 SERVER_START_REQ( create_desktop )
263 req->access = access;
264 req->attributes = OBJ_CASE_INSENSITIVE | OBJ_OPENIF |
265 ((sa && sa->bInheritHandle) ? OBJ_INHERIT : 0);
266 wine_server_add_data( req, name, len * sizeof(WCHAR) );
267 /* it doesn't seem to set last error */
268 wine_server_call( req );
276 /******************************************************************************
277 * OpenDesktopA (USER32.@)
279 HDESK WINAPI OpenDesktopA( LPCSTR name, DWORD flags, BOOL inherit, ACCESS_MASK access )
281 WCHAR buffer[MAX_PATH];
283 if (!name) return OpenDesktopW( NULL, flags, inherit, access );
285 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
287 SetLastError( ERROR_FILENAME_EXCED_RANGE );
290 return OpenDesktopW( buffer, flags, inherit, access );
294 /******************************************************************************
295 * OpenDesktopW (USER32.@)
297 HDESK WINAPI OpenDesktopW( LPCWSTR name, DWORD flags, BOOL inherit, ACCESS_MASK access )
300 DWORD len = name ? strlenW(name) : 0;
303 SetLastError( ERROR_FILENAME_EXCED_RANGE );
306 SERVER_START_REQ( open_desktop )
309 req->access = access;
310 req->attributes = OBJ_CASE_INSENSITIVE | (inherit ? OBJ_INHERIT : 0);
311 wine_server_add_data( req, name, len * sizeof(WCHAR) );
312 if (!wine_server_call( req )) ret = reply->handle;
319 /***********************************************************************
320 * CloseDesktop (USER32.@)
322 BOOL WINAPI CloseDesktop( HDESK handle )
325 SERVER_START_REQ( close_desktop )
327 req->handle = handle;
328 ret = !wine_server_call_err( req );
335 /******************************************************************************
336 * GetThreadDesktop (USER32.@)
338 HDESK WINAPI GetThreadDesktop( DWORD thread )
342 SERVER_START_REQ( get_thread_desktop )
345 if (!wine_server_call_err( req )) ret = reply->handle;
352 /******************************************************************************
353 * SetThreadDesktop (USER32.@)
355 BOOL WINAPI SetThreadDesktop( HDESK handle )
359 SERVER_START_REQ( set_thread_desktop )
361 req->handle = handle;
362 ret = !wine_server_call_err( req );
365 if (ret) get_user_thread_info()->desktop = 0; /* reset the desktop window */
370 /******************************************************************************
371 * EnumDesktopsA (USER32.@)
373 BOOL WINAPI EnumDesktopsA( HWINSTA winsta, DESKTOPENUMPROCA func, LPARAM lparam )
375 struct enum_proc_lparam data;
377 data.lparam = lparam;
378 return EnumDesktopsW( winsta, enum_names_WtoA, (LPARAM)&data );
382 /******************************************************************************
383 * EnumDesktopsW (USER32.@)
385 BOOL WINAPI EnumDesktopsW( HWINSTA winsta, DESKTOPENUMPROCW func, LPARAM lparam )
387 FIXME( "(%p,%p,%lx): stub\n", winsta, func, lparam );
388 SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
393 /******************************************************************************
394 * OpenInputDesktop (USER32.@)
396 HDESK WINAPI OpenInputDesktop( DWORD flags, BOOL inherit, ACCESS_MASK access )
398 FIXME( "(%lx,%i,%lx): stub\n", flags, inherit, access );
399 SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
404 /***********************************************************************
405 * EnumDesktopWindows (USER32.@)
407 BOOL WINAPI EnumDesktopWindows( HDESK desktop, WNDENUMPROC func, LPARAM lparam )
409 FIXME( "(%p,%p,0x%lx): stub!\n", desktop, func, lparam );
414 /***********************************************************************
415 * GetUserObjectInformationA (USER32.@)
417 BOOL WINAPI GetUserObjectInformationA( HANDLE handle, INT index, LPVOID info, DWORD len, LPDWORD needed )
419 /* check for information types returning strings */
420 if (index == UOI_TYPE || index == UOI_NAME)
422 WCHAR buffer[MAX_PATH];
425 if (!GetUserObjectInformationW( handle, index, buffer, sizeof(buffer), NULL )) return FALSE;
426 lenA = WideCharToMultiByte( CP_ACP, 0, buffer, -1, NULL, 0, NULL, NULL );
427 if (needed) *needed = lenA;
430 SetLastError( ERROR_MORE_DATA );
433 if (info) WideCharToMultiByte( CP_ACP, 0, buffer, -1, info, len, NULL, NULL );
436 return GetUserObjectInformationW( handle, index, info, len, needed );
440 /***********************************************************************
441 * GetUserObjectInformationW (USER32.@)
443 BOOL WINAPI GetUserObjectInformationW( HANDLE handle, INT index, LPVOID info, DWORD len, LPDWORD needed )
445 static const WCHAR desktopW[] = { 'D','e','s','k','t','o','p',0 };
446 static const WCHAR winstationW[] = { 'W','i','n','d','o','w','S','t','a','t','i','o','n',0 };
453 USEROBJECTFLAGS *obj_flags = info;
454 if (needed) *needed = sizeof(*obj_flags);
455 if (len < sizeof(*obj_flags))
457 SetLastError( ERROR_BUFFER_OVERFLOW );
460 SERVER_START_REQ( set_user_object_info )
462 req->handle = handle;
464 ret = !wine_server_call_err( req );
467 /* FIXME: inherit flag */
468 obj_flags->dwFlags = reply->old_obj_flags;
476 SERVER_START_REQ( set_user_object_info )
478 req->handle = handle;
480 ret = !wine_server_call_err( req );
483 size_t size = reply->is_desktop ? sizeof(desktopW) : sizeof(winstationW);
484 if (needed) *needed = size;
487 SetLastError( ERROR_MORE_DATA );
490 else memcpy( info, reply->is_desktop ? desktopW : winstationW, size );
498 WCHAR buffer[MAX_PATH];
499 SERVER_START_REQ( set_user_object_info )
501 req->handle = handle;
503 wine_server_set_reply( req, buffer, sizeof(buffer) - sizeof(WCHAR) );
504 ret = !wine_server_call_err( req );
507 size_t size = wine_server_reply_size( reply );
508 buffer[size / sizeof(WCHAR)] = 0;
509 size += sizeof(WCHAR);
510 if (needed) *needed = size;
513 SetLastError( ERROR_MORE_DATA );
516 else memcpy( info, buffer, size );
524 FIXME( "not supported index %d\n", index );
527 SetLastError( ERROR_INVALID_PARAMETER );
533 /******************************************************************************
534 * SetUserObjectInformationA (USER32.@)
536 BOOL WINAPI SetUserObjectInformationA( HANDLE handle, INT index, LPVOID info, DWORD len )
538 return SetUserObjectInformationW( handle, index, info, len );
542 /******************************************************************************
543 * SetUserObjectInformationW (USER32.@)
545 BOOL WINAPI SetUserObjectInformationW( HANDLE handle, INT index, LPVOID info, DWORD len )
548 const USEROBJECTFLAGS *obj_flags = info;
550 if (index != UOI_FLAGS || !info || len < sizeof(*obj_flags))
552 SetLastError( ERROR_INVALID_PARAMETER );
555 /* FIXME: inherit flag */
556 SERVER_START_REQ( set_user_object_info )
558 req->handle = handle;
559 req->flags = SET_USER_OBJECT_FLAGS;
560 req->obj_flags = obj_flags->dwFlags;
561 ret = !wine_server_call_err( req );
568 /***********************************************************************
569 * GetUserObjectSecurity (USER32.@)
571 BOOL WINAPI GetUserObjectSecurity( HANDLE handle, PSECURITY_INFORMATION info,
572 PSECURITY_DESCRIPTOR sid, DWORD len, LPDWORD needed )
574 FIXME( "(%p %p %p len=%ld %p),stub!\n", handle, info, sid, len, needed );
578 /***********************************************************************
579 * SetUserObjectSecurity (USER32.@)
581 BOOL WINAPI SetUserObjectSecurity( HANDLE handle, PSECURITY_INFORMATION info,
582 PSECURITY_DESCRIPTOR sid )
584 FIXME( "(%p,%p,%p),stub!\n", handle, info, sid );