Release 20050930.
[wine/gsoc-2012-control.git] / dlls / user / winstation.c
blob9e7214646f9d69770f834b5de0895a6714ea6365
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include <stdarg.h>
22 #include "windef.h"
23 #include "winbase.h"
24 #include "winnls.h"
25 #include "winerror.h"
26 #include "wingdi.h"
27 #include "winuser.h"
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
39 NAMEENUMPROCA func;
40 LPARAM 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 ))
49 return FALSE;
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 );
67 return 0;
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 )
79 HANDLE ret;
80 DWORD len = name ? strlenW(name) : 0;
82 if (len >= MAX_PATH)
84 SetLastError( ERROR_FILENAME_EXCED_RANGE );
85 return 0;
87 SERVER_START_REQ( create_winstation )
89 req->flags = 0;
90 req->access = access;
91 req->inherit = (sa && sa->bInheritHandle);
92 wine_server_add_data( req, name, len * sizeof(WCHAR) );
93 /* it doesn't seem to set last error */
94 wine_server_call( req );
95 ret = reply->handle;
97 SERVER_END_REQ;
98 return ret;
102 /******************************************************************************
103 * OpenWindowStationA (USER32.@)
105 HWINSTA WINAPI OpenWindowStationA( LPCSTR name, BOOL inherit, ACCESS_MASK access )
107 WCHAR buffer[MAX_PATH];
109 if (!name) return OpenWindowStationW( NULL, inherit, access );
111 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
113 SetLastError( ERROR_FILENAME_EXCED_RANGE );
114 return 0;
116 return OpenWindowStationW( buffer, inherit, access );
120 /******************************************************************************
121 * OpenWindowStationW (USER32.@)
123 HWINSTA WINAPI OpenWindowStationW( LPCWSTR name, BOOL inherit, ACCESS_MASK access )
125 HANDLE ret = 0;
126 DWORD len = name ? strlenW(name) : 0;
127 if (len >= MAX_PATH)
129 SetLastError( ERROR_FILENAME_EXCED_RANGE );
130 return 0;
132 SERVER_START_REQ( open_winstation )
134 req->access = access;
135 req->inherit = inherit;
136 wine_server_add_data( req, name, len * sizeof(WCHAR) );
137 if (!wine_server_call_err( req )) ret = reply->handle;
139 SERVER_END_REQ;
140 return ret;
144 /***********************************************************************
145 * CloseWindowStation (USER32.@)
147 BOOL WINAPI CloseWindowStation( HWINSTA handle )
149 BOOL ret;
150 SERVER_START_REQ( close_winstation )
152 req->handle = handle;
153 ret = !wine_server_call_err( req );
155 SERVER_END_REQ;
156 return ret;
160 /******************************************************************************
161 * GetProcessWindowStation (USER32.@)
163 HWINSTA WINAPI GetProcessWindowStation(void)
165 HWINSTA ret = 0;
167 SERVER_START_REQ( get_process_winstation )
169 if (!wine_server_call_err( req )) ret = reply->handle;
171 SERVER_END_REQ;
172 return ret;
176 /***********************************************************************
177 * SetProcessWindowStation (USER32.@)
179 BOOL WINAPI SetProcessWindowStation( HWINSTA handle )
181 BOOL ret;
183 SERVER_START_REQ( set_process_winstation )
185 req->handle = handle;
186 ret = !wine_server_call_err( req );
188 SERVER_END_REQ;
189 return ret;
193 /******************************************************************************
194 * EnumWindowStationsA (USER32.@)
196 BOOL WINAPI EnumWindowStationsA( WINSTAENUMPROCA func, LPARAM lparam )
198 struct enum_proc_lparam data;
199 data.func = func;
200 data.lparam = lparam;
201 return EnumWindowStationsW( enum_names_WtoA, (LPARAM)&data );
205 /******************************************************************************
206 * EnumWindowStationsA (USER32.@)
208 BOOL WINAPI EnumWindowStationsW( WINSTAENUMPROCW func, LPARAM lparam )
210 FIXME( "(%p,%lx): stub\n", func, lparam );
211 SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
212 return FALSE;
216 /***********************************************************************
217 * CreateDesktopA (USER32.@)
219 HDESK WINAPI CreateDesktopA( LPCSTR name, LPCSTR device, LPDEVMODEA devmode,
220 DWORD flags, ACCESS_MASK access, LPSECURITY_ATTRIBUTES sa )
222 WCHAR buffer[MAX_PATH];
224 if (device || devmode)
226 SetLastError( ERROR_INVALID_PARAMETER );
227 return 0;
229 if (!name) return CreateDesktopW( NULL, NULL, NULL, flags, access, sa );
231 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
233 SetLastError( ERROR_FILENAME_EXCED_RANGE );
234 return 0;
236 return CreateDesktopW( buffer, NULL, NULL, flags, access, sa );
240 /***********************************************************************
241 * CreateDesktopW (USER32.@)
243 HDESK WINAPI CreateDesktopW( LPCWSTR name, LPCWSTR device, LPDEVMODEW devmode,
244 DWORD flags, ACCESS_MASK access, LPSECURITY_ATTRIBUTES sa )
246 HANDLE ret;
247 DWORD len = name ? strlenW(name) : 0;
249 if (device || devmode)
251 SetLastError( ERROR_INVALID_PARAMETER );
252 return 0;
254 if (len >= MAX_PATH)
256 SetLastError( ERROR_FILENAME_EXCED_RANGE );
257 return 0;
259 SERVER_START_REQ( create_desktop )
261 req->flags = flags;
262 req->access = access;
263 req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
264 wine_server_add_data( req, name, len * sizeof(WCHAR) );
265 /* it doesn't seem to set last error */
266 wine_server_call( req );
267 ret = reply->handle;
269 SERVER_END_REQ;
270 return ret;
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 /******************************************************************************
293 * OpenDesktopW (USER32.@)
295 HDESK WINAPI OpenDesktopW( LPCWSTR name, DWORD flags, BOOL inherit, ACCESS_MASK access )
297 HANDLE ret = 0;
298 DWORD len = name ? strlenW(name) : 0;
299 if (len >= MAX_PATH)
301 SetLastError( ERROR_FILENAME_EXCED_RANGE );
302 return 0;
304 SERVER_START_REQ( open_desktop )
306 req->flags = flags;
307 req->access = access;
308 req->inherit = inherit;
309 wine_server_add_data( req, name, len * sizeof(WCHAR) );
310 if (!wine_server_call( req )) ret = reply->handle;
312 SERVER_END_REQ;
313 return ret;
317 /***********************************************************************
318 * CloseDesktop (USER32.@)
320 BOOL WINAPI CloseDesktop( HDESK handle )
322 BOOL ret;
323 SERVER_START_REQ( close_desktop )
325 req->handle = handle;
326 ret = !wine_server_call_err( req );
328 SERVER_END_REQ;
329 return ret;
333 /******************************************************************************
334 * GetThreadDesktop (USER32.@)
336 HDESK WINAPI GetThreadDesktop( DWORD thread )
338 HDESK ret = 0;
340 SERVER_START_REQ( get_thread_desktop )
342 req->tid = thread;
343 if (!wine_server_call_err( req )) ret = reply->handle;
345 SERVER_END_REQ;
346 return ret;
350 /******************************************************************************
351 * SetThreadDesktop (USER32.@)
353 BOOL WINAPI SetThreadDesktop( HDESK handle )
355 BOOL ret;
357 SERVER_START_REQ( set_thread_desktop )
359 req->handle = handle;
360 ret = !wine_server_call_err( req );
362 SERVER_END_REQ;
363 if (ret) get_user_thread_info()->desktop = 0; /* reset the desktop window */
364 return ret;
368 /******************************************************************************
369 * EnumDesktopsA (USER32.@)
371 BOOL WINAPI EnumDesktopsA( HWINSTA winsta, DESKTOPENUMPROCA func, LPARAM lparam )
373 struct enum_proc_lparam data;
374 data.func = func;
375 data.lparam = lparam;
376 return EnumDesktopsW( winsta, enum_names_WtoA, (LPARAM)&data );
380 /******************************************************************************
381 * EnumDesktopsW (USER32.@)
383 BOOL WINAPI EnumDesktopsW( HWINSTA winsta, DESKTOPENUMPROCW func, LPARAM lparam )
385 FIXME( "(%p,%p,%lx): stub\n", winsta, func, lparam );
386 SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
387 return FALSE;
391 /******************************************************************************
392 * OpenInputDesktop (USER32.@)
394 HDESK WINAPI OpenInputDesktop( DWORD flags, BOOL inherit, ACCESS_MASK access )
396 FIXME( "(%lx,%i,%lx): stub\n", flags, inherit, access );
397 SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
398 return 0;
402 /***********************************************************************
403 * EnumDesktopWindows (USER32.@)
405 BOOL WINAPI EnumDesktopWindows( HDESK desktop, WNDENUMPROC func, LPARAM lparam )
407 FIXME( "(%p,%p,0x%lx): stub!\n", desktop, func, lparam );
408 return TRUE;
412 /***********************************************************************
413 * GetUserObjectInformationA (USER32.@)
415 BOOL WINAPI GetUserObjectInformationA( HANDLE handle, INT index, LPVOID info, DWORD len, LPDWORD needed )
417 /* check for information types returning strings */
418 if (index == UOI_TYPE || index == UOI_NAME)
420 WCHAR buffer[MAX_PATH];
421 DWORD lenA;
423 if (!GetUserObjectInformationW( handle, index, buffer, sizeof(buffer), NULL )) return FALSE;
424 lenA = WideCharToMultiByte( CP_ACP, 0, buffer, -1, NULL, 0, NULL, NULL );
425 if (needed) *needed = lenA;
426 if (lenA > len)
428 SetLastError( ERROR_MORE_DATA );
429 return FALSE;
431 if (info) WideCharToMultiByte( CP_ACP, 0, buffer, -1, info, len, NULL, NULL );
432 return TRUE;
434 return GetUserObjectInformationW( handle, index, info, len, needed );
438 /***********************************************************************
439 * GetUserObjectInformationW (USER32.@)
441 BOOL WINAPI GetUserObjectInformationW( HANDLE handle, INT index, LPVOID info, DWORD len, LPDWORD needed )
443 static const WCHAR desktopW[] = { 'D','e','s','k','t','o','p',0 };
444 static const WCHAR winstationW[] = { 'W','i','n','d','o','w','S','t','a','t','i','o','n',0 };
445 BOOL ret;
447 switch(index)
449 case UOI_FLAGS:
451 USEROBJECTFLAGS *obj_flags = info;
452 if (needed) *needed = sizeof(*obj_flags);
453 if (len < sizeof(*obj_flags))
455 SetLastError( ERROR_BUFFER_OVERFLOW );
456 return FALSE;
458 SERVER_START_REQ( set_user_object_info )
460 req->handle = handle;
461 req->flags = 0;
462 ret = !wine_server_call_err( req );
463 if (ret)
465 /* FIXME: inherit flag */
466 obj_flags->dwFlags = reply->old_obj_flags;
469 SERVER_END_REQ;
471 return ret;
473 case UOI_TYPE:
474 SERVER_START_REQ( set_user_object_info )
476 req->handle = handle;
477 req->flags = 0;
478 ret = !wine_server_call_err( req );
479 if (ret)
481 size_t size = reply->is_desktop ? sizeof(desktopW) : sizeof(winstationW);
482 if (needed) *needed = size;
483 if (len < size)
485 SetLastError( ERROR_MORE_DATA );
486 ret = FALSE;
488 else memcpy( info, reply->is_desktop ? desktopW : winstationW, size );
491 SERVER_END_REQ;
492 return ret;
494 case UOI_NAME:
496 WCHAR buffer[MAX_PATH];
497 SERVER_START_REQ( set_user_object_info )
499 req->handle = handle;
500 req->flags = 0;
501 wine_server_set_reply( req, buffer, sizeof(buffer) - sizeof(WCHAR) );
502 ret = !wine_server_call_err( req );
503 if (ret)
505 size_t size = wine_server_reply_size( reply );
506 buffer[size / sizeof(WCHAR)] = 0;
507 size += sizeof(WCHAR);
508 if (needed) *needed = size;
509 if (len < size)
511 SetLastError( ERROR_MORE_DATA );
512 ret = FALSE;
514 else memcpy( info, buffer, size );
517 SERVER_END_REQ;
519 return ret;
521 case UOI_USER_SID:
522 FIXME( "not supported index %d\n", index );
523 /* fall through */
524 default:
525 SetLastError( ERROR_INVALID_PARAMETER );
526 return FALSE;
531 /******************************************************************************
532 * SetUserObjectInformationA (USER32.@)
534 BOOL WINAPI SetUserObjectInformationA( HANDLE handle, INT index, LPVOID info, DWORD len )
536 return SetUserObjectInformationW( handle, index, info, len );
540 /******************************************************************************
541 * SetUserObjectInformationW (USER32.@)
543 BOOL WINAPI SetUserObjectInformationW( HANDLE handle, INT index, LPVOID info, DWORD len )
545 BOOL ret;
546 const USEROBJECTFLAGS *obj_flags = info;
548 if (index != UOI_FLAGS || !info || len < sizeof(*obj_flags))
550 SetLastError( ERROR_INVALID_PARAMETER );
551 return FALSE;
553 /* FIXME: inherit flag */
554 SERVER_START_REQ( set_user_object_info )
556 req->handle = handle;
557 req->flags = SET_USER_OBJECT_FLAGS;
558 req->obj_flags = obj_flags->dwFlags;
559 ret = !wine_server_call_err( req );
561 SERVER_END_REQ;
562 return ret;
566 /***********************************************************************
567 * GetUserObjectSecurity (USER32.@)
569 BOOL WINAPI GetUserObjectSecurity( HANDLE handle, PSECURITY_INFORMATION info,
570 PSECURITY_DESCRIPTOR sid, DWORD len, LPDWORD needed )
572 FIXME( "(%p %p %p len=%ld %p),stub!\n", handle, info, sid, len, needed );
573 return TRUE;
576 /***********************************************************************
577 * SetUserObjectSecurity (USER32.@)
579 BOOL WINAPI SetUserObjectSecurity( HANDLE handle, PSECURITY_INFORMATION info,
580 PSECURITY_DESCRIPTOR sid )
582 FIXME( "(%p,%p,%p),stub!\n", handle, info, sid );
583 return TRUE;