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"
32 WINE_DEFAULT_DEBUG_CHANNEL(winstation);
35 /* callback for enumeration functions */
36 struct enum_proc_lparam
42 static BOOL CALLBACK enum_names_WtoA( LPWSTR name, LPARAM lparam )
44 struct enum_proc_lparam *data = (struct enum_proc_lparam *)lparam;
45 char buffer[MAX_PATH];
47 if (!WideCharToMultiByte( CP_ACP, 0, name, -1, buffer, sizeof(buffer), NULL, NULL ))
49 return data->func( buffer, data->lparam );
53 /***********************************************************************
54 * CreateWindowStationA (USER32.@)
56 HWINSTA WINAPI CreateWindowStationA( LPCSTR name, DWORD reserved, ACCESS_MASK access,
57 LPSECURITY_ATTRIBUTES sa )
59 WCHAR buffer[MAX_PATH];
61 if (!name) return CreateWindowStationW( NULL, reserved, access, sa );
63 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
65 SetLastError( ERROR_FILENAME_EXCED_RANGE );
68 return CreateWindowStationW( buffer, reserved, access, sa );
72 /***********************************************************************
73 * CreateWindowStationW (USER32.@)
75 HWINSTA WINAPI CreateWindowStationW( LPCWSTR name, DWORD reserved, ACCESS_MASK access,
76 LPSECURITY_ATTRIBUTES sa )
79 DWORD len = name ? strlenW(name) : 0;
83 SetLastError( ERROR_FILENAME_EXCED_RANGE );
86 SERVER_START_REQ( create_winstation )
90 req->inherit = (sa && sa->bInheritHandle);
91 wine_server_add_data( req, name, len * sizeof(WCHAR) );
92 /* it doesn't seem to set last error */
93 wine_server_call( req );
101 /******************************************************************************
102 * OpenWindowStationA (USER32.@)
104 HWINSTA WINAPI OpenWindowStationA( LPCSTR name, BOOL inherit, ACCESS_MASK access )
106 WCHAR buffer[MAX_PATH];
108 if (!name) return OpenWindowStationW( NULL, inherit, access );
110 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
112 SetLastError( ERROR_FILENAME_EXCED_RANGE );
115 return OpenWindowStationW( buffer, inherit, access );
119 /******************************************************************************
120 * OpenWindowStationW (USER32.@)
122 HWINSTA WINAPI OpenWindowStationW( LPCWSTR name, BOOL inherit, ACCESS_MASK access )
125 DWORD len = name ? strlenW(name) : 0;
128 SetLastError( ERROR_FILENAME_EXCED_RANGE );
131 SERVER_START_REQ( open_winstation )
133 req->access = access;
134 req->inherit = inherit;
135 wine_server_add_data( req, name, len * sizeof(WCHAR) );
136 if (!wine_server_call_err( req )) ret = reply->handle;
143 /***********************************************************************
144 * CloseWindowStation (USER32.@)
146 BOOL WINAPI CloseWindowStation( HWINSTA handle )
149 SERVER_START_REQ( close_winstation )
151 req->handle = handle;
152 ret = !wine_server_call_err( req );
159 /******************************************************************************
160 * GetProcessWindowStation (USER32.@)
162 HWINSTA WINAPI GetProcessWindowStation(void)
166 SERVER_START_REQ( get_process_winstation )
168 if (!wine_server_call_err( req )) ret = reply->handle;
175 /***********************************************************************
176 * SetProcessWindowStation (USER32.@)
178 BOOL WINAPI SetProcessWindowStation( HWINSTA handle )
182 SERVER_START_REQ( set_process_winstation )
184 req->handle = handle;
185 ret = !wine_server_call_err( req );
192 /******************************************************************************
193 * EnumWindowStationsA (USER32.@)
195 BOOL WINAPI EnumWindowStationsA( WINSTAENUMPROCA func, LPARAM lparam )
197 struct enum_proc_lparam data;
199 data.lparam = lparam;
200 return EnumWindowStationsW( enum_names_WtoA, (LPARAM)&data );
204 /******************************************************************************
205 * EnumWindowStationsA (USER32.@)
207 BOOL WINAPI EnumWindowStationsW( WINSTAENUMPROCW func, LPARAM lparam )
209 FIXME( "(%p,%lx): stub\n", func, lparam );
210 SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
215 /***********************************************************************
216 * CreateDesktopA (USER32.@)
218 HDESK WINAPI CreateDesktopA( LPCSTR name, LPCSTR device, LPDEVMODEA devmode,
219 DWORD flags, ACCESS_MASK access, LPSECURITY_ATTRIBUTES sa )
221 WCHAR buffer[MAX_PATH];
223 if (device || devmode)
225 SetLastError( ERROR_INVALID_PARAMETER );
228 if (!name) return CreateDesktopW( NULL, NULL, NULL, flags, access, sa );
230 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
232 SetLastError( ERROR_FILENAME_EXCED_RANGE );
235 return CreateDesktopW( buffer, NULL, NULL, flags, access, sa );
239 /***********************************************************************
240 * CreateDesktopW (USER32.@)
242 HDESK WINAPI CreateDesktopW( LPCWSTR name, LPCWSTR device, LPDEVMODEW devmode,
243 DWORD flags, ACCESS_MASK access, LPSECURITY_ATTRIBUTES sa )
246 DWORD len = name ? strlenW(name) : 0;
248 if (device || devmode)
250 SetLastError( ERROR_INVALID_PARAMETER );
255 SetLastError( ERROR_FILENAME_EXCED_RANGE );
258 SERVER_START_REQ( create_desktop )
261 req->access = access;
262 req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
263 wine_server_add_data( req, name, len * sizeof(WCHAR) );
264 /* it doesn't seem to set last error */
265 wine_server_call( req );
273 /******************************************************************************
274 * OpenDesktopA (USER32.@)
276 HDESK WINAPI OpenDesktopA( LPCSTR name, DWORD flags, BOOL inherit, ACCESS_MASK access )
278 WCHAR buffer[MAX_PATH];
280 if (!name) return OpenDesktopW( NULL, flags, inherit, access );
282 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
284 SetLastError( ERROR_FILENAME_EXCED_RANGE );
287 return OpenDesktopW( buffer, flags, inherit, access );
291 /******************************************************************************
292 * OpenDesktopW (USER32.@)
294 HDESK WINAPI OpenDesktopW( LPCWSTR name, DWORD flags, BOOL inherit, ACCESS_MASK access )
297 DWORD len = name ? strlenW(name) : 0;
300 SetLastError( ERROR_FILENAME_EXCED_RANGE );
303 SERVER_START_REQ( open_desktop )
306 req->access = access;
307 req->inherit = inherit;
308 wine_server_add_data( req, name, len * sizeof(WCHAR) );
309 if (!wine_server_call( req )) ret = reply->handle;
316 /***********************************************************************
317 * CloseDesktop (USER32.@)
319 BOOL WINAPI CloseDesktop( HDESK handle )
322 SERVER_START_REQ( close_desktop )
324 req->handle = handle;
325 ret = !wine_server_call_err( req );
332 /******************************************************************************
333 * GetThreadDesktop (USER32.@)
335 HDESK WINAPI GetThreadDesktop( DWORD thread )
339 SERVER_START_REQ( get_thread_desktop )
342 if (!wine_server_call_err( req )) ret = reply->handle;
349 /******************************************************************************
350 * SetThreadDesktop (USER32.@)
352 BOOL WINAPI SetThreadDesktop( HDESK handle )
356 SERVER_START_REQ( set_thread_desktop )
358 req->handle = handle;
359 ret = !wine_server_call_err( req );
366 /******************************************************************************
367 * EnumDesktopsA (USER32.@)
369 BOOL WINAPI EnumDesktopsA( HWINSTA winsta, DESKTOPENUMPROCA func, LPARAM lparam )
371 struct enum_proc_lparam data;
373 data.lparam = lparam;
374 return EnumDesktopsW( winsta, enum_names_WtoA, (LPARAM)&data );
378 /******************************************************************************
379 * EnumDesktopsW (USER32.@)
381 BOOL WINAPI EnumDesktopsW( HWINSTA winsta, DESKTOPENUMPROCW func, LPARAM lparam )
383 FIXME( "(%p,%p,%lx): stub\n", winsta, func, lparam );
384 SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
389 /******************************************************************************
390 * OpenInputDesktop (USER32.@)
392 HDESK WINAPI OpenInputDesktop( DWORD flags, BOOL inherit, ACCESS_MASK access )
394 FIXME( "(%lx,%i,%lx): stub\n", flags, inherit, access );
395 SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
400 /***********************************************************************
401 * EnumDesktopWindows (USER32.@)
403 BOOL WINAPI EnumDesktopWindows( HDESK desktop, WNDENUMPROC func, LPARAM lparam )
405 FIXME( "(%p,%p,0x%lx): stub!\n", desktop, func, lparam );
410 /***********************************************************************
411 * GetUserObjectInformationA (USER32.@)
413 BOOL WINAPI GetUserObjectInformationA( HANDLE handle, INT index, LPVOID info, DWORD len, LPDWORD needed )
415 /* check for information types returning strings */
416 if (index == UOI_TYPE || index == UOI_NAME)
418 WCHAR buffer[MAX_PATH];
421 if (!GetUserObjectInformationW( handle, index, buffer, sizeof(buffer), NULL )) return FALSE;
422 lenA = WideCharToMultiByte( CP_ACP, 0, buffer, -1, NULL, 0, NULL, NULL );
423 if (needed) *needed = lenA;
426 SetLastError( ERROR_MORE_DATA );
429 if (info) WideCharToMultiByte( CP_ACP, 0, buffer, -1, info, len, NULL, NULL );
432 return GetUserObjectInformationW( handle, index, info, len, needed );
436 /***********************************************************************
437 * GetUserObjectInformationW (USER32.@)
439 BOOL WINAPI GetUserObjectInformationW( HANDLE handle, INT index, LPVOID info, DWORD len, LPDWORD needed )
441 static const WCHAR desktopW[] = { 'D','e','s','k','t','o','p',0 };
442 static const WCHAR winstationW[] = { 'W','i','n','d','o','w','S','t','a','t','i','o','n',0 };
449 USEROBJECTFLAGS *obj_flags = info;
450 if (needed) *needed = sizeof(*obj_flags);
451 if (len < sizeof(*obj_flags))
453 SetLastError( ERROR_BUFFER_OVERFLOW );
456 SERVER_START_REQ( set_user_object_info )
458 req->handle = handle;
460 ret = !wine_server_call_err( req );
463 /* FIXME: inherit flag */
464 obj_flags->dwFlags = reply->old_obj_flags;
472 SERVER_START_REQ( set_user_object_info )
474 req->handle = handle;
476 ret = !wine_server_call_err( req );
479 size_t size = reply->is_desktop ? sizeof(desktopW) : sizeof(winstationW);
480 if (needed) *needed = size;
483 SetLastError( ERROR_MORE_DATA );
486 else memcpy( info, reply->is_desktop ? desktopW : winstationW, size );
494 WCHAR buffer[MAX_PATH];
495 SERVER_START_REQ( set_user_object_info )
497 req->handle = handle;
499 wine_server_set_reply( req, buffer, sizeof(buffer) - sizeof(WCHAR) );
500 ret = !wine_server_call_err( req );
503 size_t size = wine_server_reply_size( reply );
504 buffer[size / sizeof(WCHAR)] = 0;
505 size += sizeof(WCHAR);
506 if (needed) *needed = size;
509 SetLastError( ERROR_MORE_DATA );
512 else memcpy( info, buffer, size );
520 FIXME( "not supported index %d\n", index );
523 SetLastError( ERROR_INVALID_PARAMETER );
529 /******************************************************************************
530 * SetUserObjectInformationA (USER32.@)
532 BOOL WINAPI SetUserObjectInformationA( HANDLE handle, INT index, LPVOID info, DWORD len )
534 return SetUserObjectInformationW( handle, index, info, len );
538 /******************************************************************************
539 * SetUserObjectInformationW (USER32.@)
541 BOOL WINAPI SetUserObjectInformationW( HANDLE handle, INT index, LPVOID info, DWORD len )
544 const USEROBJECTFLAGS *obj_flags = info;
546 if (index != UOI_FLAGS || !info || len < sizeof(*obj_flags))
548 SetLastError( ERROR_INVALID_PARAMETER );
551 /* FIXME: inherit flag */
552 SERVER_START_REQ( set_user_object_info )
554 req->handle = handle;
555 req->flags = SET_USER_OBJECT_FLAGS;
556 req->obj_flags = obj_flags->dwFlags;
557 ret = !wine_server_call_err( req );
564 /***********************************************************************
565 * GetUserObjectSecurity (USER32.@)
567 BOOL WINAPI GetUserObjectSecurity( HANDLE handle, PSECURITY_INFORMATION info,
568 PSECURITY_DESCRIPTOR sid, DWORD len, LPDWORD needed )
570 FIXME( "(%p %p %p len=%ld %p),stub!\n", handle, info, sid, len, needed );
574 /***********************************************************************
575 * SetUserObjectSecurity (USER32.@)
577 BOOL WINAPI SetUserObjectSecurity( HANDLE handle, PSECURITY_INFORMATION info,
578 PSECURITY_DESCRIPTOR sid )
580 FIXME( "(%p,%p,%p),stub!\n", handle, info, sid );