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
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 * EnumWindowStationsW (USER32.@)
209 BOOL WINAPI
EnumWindowStationsW( WINSTAENUMPROCW func
, LPARAM lparam
)
211 unsigned int index
= 0;
212 WCHAR name
[MAX_PATH
];
217 SERVER_START_REQ( enum_winstation
)
220 wine_server_set_reply( req
, name
, sizeof(name
) );
221 ret
= !wine_server_call( req
);
225 if (ret
) ret
= func( name
, lparam
);
231 /***********************************************************************
232 * CreateDesktopA (USER32.@)
234 HDESK WINAPI
CreateDesktopA( LPCSTR name
, LPCSTR device
, LPDEVMODEA devmode
,
235 DWORD flags
, ACCESS_MASK access
, LPSECURITY_ATTRIBUTES sa
)
237 WCHAR buffer
[MAX_PATH
];
239 if (device
|| devmode
)
241 SetLastError( ERROR_INVALID_PARAMETER
);
244 if (!name
) return CreateDesktopW( NULL
, NULL
, NULL
, flags
, access
, sa
);
246 if (!MultiByteToWideChar( CP_ACP
, 0, name
, -1, buffer
, MAX_PATH
))
248 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
251 return CreateDesktopW( buffer
, NULL
, NULL
, flags
, access
, sa
);
255 /***********************************************************************
256 * CreateDesktopW (USER32.@)
258 HDESK WINAPI
CreateDesktopW( LPCWSTR name
, LPCWSTR device
, LPDEVMODEW devmode
,
259 DWORD flags
, ACCESS_MASK access
, LPSECURITY_ATTRIBUTES sa
)
262 DWORD len
= name
? strlenW(name
) : 0;
264 if (device
|| devmode
)
266 SetLastError( ERROR_INVALID_PARAMETER
);
271 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
274 SERVER_START_REQ( create_desktop
)
277 req
->access
= access
;
278 req
->attributes
= OBJ_CASE_INSENSITIVE
| OBJ_OPENIF
|
279 ((sa
&& sa
->bInheritHandle
) ? OBJ_INHERIT
: 0);
280 wine_server_add_data( req
, name
, len
* sizeof(WCHAR
) );
281 /* it doesn't seem to set last error */
282 wine_server_call( req
);
290 /******************************************************************************
291 * OpenDesktopA (USER32.@)
293 HDESK WINAPI
OpenDesktopA( LPCSTR name
, DWORD flags
, BOOL inherit
, ACCESS_MASK access
)
295 WCHAR buffer
[MAX_PATH
];
297 if (!name
) return OpenDesktopW( NULL
, flags
, inherit
, access
);
299 if (!MultiByteToWideChar( CP_ACP
, 0, name
, -1, buffer
, MAX_PATH
))
301 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
304 return OpenDesktopW( buffer
, flags
, inherit
, access
);
308 /******************************************************************************
309 * OpenDesktopW (USER32.@)
311 HDESK WINAPI
OpenDesktopW( LPCWSTR name
, DWORD flags
, BOOL inherit
, ACCESS_MASK access
)
314 DWORD len
= name
? strlenW(name
) : 0;
317 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
320 SERVER_START_REQ( open_desktop
)
323 req
->access
= access
;
324 req
->attributes
= OBJ_CASE_INSENSITIVE
| (inherit
? OBJ_INHERIT
: 0);
325 wine_server_add_data( req
, name
, len
* sizeof(WCHAR
) );
326 if (!wine_server_call( req
)) ret
= reply
->handle
;
333 /***********************************************************************
334 * CloseDesktop (USER32.@)
336 BOOL WINAPI
CloseDesktop( HDESK handle
)
339 SERVER_START_REQ( close_desktop
)
341 req
->handle
= handle
;
342 ret
= !wine_server_call_err( req
);
349 /******************************************************************************
350 * GetThreadDesktop (USER32.@)
352 HDESK WINAPI
GetThreadDesktop( DWORD thread
)
356 SERVER_START_REQ( get_thread_desktop
)
359 if (!wine_server_call_err( req
)) ret
= reply
->handle
;
366 /******************************************************************************
367 * SetThreadDesktop (USER32.@)
369 BOOL WINAPI
SetThreadDesktop( HDESK handle
)
373 SERVER_START_REQ( set_thread_desktop
)
375 req
->handle
= handle
;
376 ret
= !wine_server_call_err( req
);
379 if (ret
) get_user_thread_info()->desktop
= 0; /* reset the desktop window */
384 /******************************************************************************
385 * EnumDesktopsA (USER32.@)
387 BOOL WINAPI
EnumDesktopsA( HWINSTA winsta
, DESKTOPENUMPROCA func
, LPARAM lparam
)
389 struct enum_proc_lparam data
;
391 data
.lparam
= lparam
;
392 return EnumDesktopsW( winsta
, enum_names_WtoA
, (LPARAM
)&data
);
396 /******************************************************************************
397 * EnumDesktopsW (USER32.@)
399 BOOL WINAPI
EnumDesktopsW( HWINSTA winsta
, DESKTOPENUMPROCW func
, LPARAM lparam
)
401 unsigned int index
= 0;
402 WCHAR name
[MAX_PATH
];
407 SERVER_START_REQ( enum_desktop
)
409 req
->winstation
= winsta
;
411 wine_server_set_reply( req
, name
, sizeof(name
) );
412 ret
= !wine_server_call( req
);
416 if (ret
) ret
= func( name
, lparam
);
422 /******************************************************************************
423 * OpenInputDesktop (USER32.@)
425 HDESK WINAPI
OpenInputDesktop( DWORD flags
, BOOL inherit
, ACCESS_MASK access
)
427 FIXME( "(%x,%i,%x): stub\n", flags
, inherit
, access
);
428 SetLastError( ERROR_CALL_NOT_IMPLEMENTED
);
433 /***********************************************************************
434 * EnumDesktopWindows (USER32.@)
436 BOOL WINAPI
EnumDesktopWindows( HDESK desktop
, WNDENUMPROC func
, LPARAM lparam
)
438 FIXME( "(%p,%p,0x%lx): stub!\n", desktop
, func
, lparam
);
443 /***********************************************************************
444 * GetUserObjectInformationA (USER32.@)
446 BOOL WINAPI
GetUserObjectInformationA( HANDLE handle
, INT index
, LPVOID info
, DWORD len
, LPDWORD needed
)
448 /* check for information types returning strings */
449 if (index
== UOI_TYPE
|| index
== UOI_NAME
)
451 WCHAR buffer
[MAX_PATH
];
454 if (!GetUserObjectInformationW( handle
, index
, buffer
, sizeof(buffer
), NULL
)) return FALSE
;
455 lenA
= WideCharToMultiByte( CP_ACP
, 0, buffer
, -1, NULL
, 0, NULL
, NULL
);
456 if (needed
) *needed
= lenA
;
459 SetLastError( ERROR_MORE_DATA
);
462 if (info
) WideCharToMultiByte( CP_ACP
, 0, buffer
, -1, info
, len
, NULL
, NULL
);
465 return GetUserObjectInformationW( handle
, index
, info
, len
, needed
);
469 /***********************************************************************
470 * GetUserObjectInformationW (USER32.@)
472 BOOL WINAPI
GetUserObjectInformationW( HANDLE handle
, INT index
, LPVOID info
, DWORD len
, LPDWORD needed
)
474 static const WCHAR desktopW
[] = { 'D','e','s','k','t','o','p',0 };
475 static const WCHAR winstationW
[] = { 'W','i','n','d','o','w','S','t','a','t','i','o','n',0 };
482 USEROBJECTFLAGS
*obj_flags
= info
;
483 if (needed
) *needed
= sizeof(*obj_flags
);
484 if (len
< sizeof(*obj_flags
))
486 SetLastError( ERROR_BUFFER_OVERFLOW
);
489 SERVER_START_REQ( set_user_object_info
)
491 req
->handle
= handle
;
493 ret
= !wine_server_call_err( req
);
496 /* FIXME: inherit flag */
497 obj_flags
->dwFlags
= reply
->old_obj_flags
;
505 SERVER_START_REQ( set_user_object_info
)
507 req
->handle
= handle
;
509 ret
= !wine_server_call_err( req
);
512 size_t size
= reply
->is_desktop
? sizeof(desktopW
) : sizeof(winstationW
);
513 if (needed
) *needed
= size
;
516 SetLastError( ERROR_MORE_DATA
);
519 else memcpy( info
, reply
->is_desktop
? desktopW
: winstationW
, size
);
527 WCHAR buffer
[MAX_PATH
];
528 SERVER_START_REQ( set_user_object_info
)
530 req
->handle
= handle
;
532 wine_server_set_reply( req
, buffer
, sizeof(buffer
) - sizeof(WCHAR
) );
533 ret
= !wine_server_call_err( req
);
536 size_t size
= wine_server_reply_size( reply
);
537 buffer
[size
/ sizeof(WCHAR
)] = 0;
538 size
+= sizeof(WCHAR
);
539 if (needed
) *needed
= size
;
542 SetLastError( ERROR_MORE_DATA
);
545 else memcpy( info
, buffer
, size
);
553 FIXME( "not supported index %d\n", index
);
556 SetLastError( ERROR_INVALID_PARAMETER
);
562 /******************************************************************************
563 * SetUserObjectInformationA (USER32.@)
565 BOOL WINAPI
SetUserObjectInformationA( HANDLE handle
, INT index
, LPVOID info
, DWORD len
)
567 return SetUserObjectInformationW( handle
, index
, info
, len
);
571 /******************************************************************************
572 * SetUserObjectInformationW (USER32.@)
574 BOOL WINAPI
SetUserObjectInformationW( HANDLE handle
, INT index
, LPVOID info
, DWORD len
)
577 const USEROBJECTFLAGS
*obj_flags
= info
;
579 if (index
!= UOI_FLAGS
|| !info
|| len
< sizeof(*obj_flags
))
581 SetLastError( ERROR_INVALID_PARAMETER
);
584 /* FIXME: inherit flag */
585 SERVER_START_REQ( set_user_object_info
)
587 req
->handle
= handle
;
588 req
->flags
= SET_USER_OBJECT_FLAGS
;
589 req
->obj_flags
= obj_flags
->dwFlags
;
590 ret
= !wine_server_call_err( req
);
597 /***********************************************************************
598 * GetUserObjectSecurity (USER32.@)
600 BOOL WINAPI
GetUserObjectSecurity( HANDLE handle
, PSECURITY_INFORMATION info
,
601 PSECURITY_DESCRIPTOR sid
, DWORD len
, LPDWORD needed
)
603 FIXME( "(%p %p %p len=%d %p),stub!\n", handle
, info
, sid
, len
, needed
);
607 /***********************************************************************
608 * SetUserObjectSecurity (USER32.@)
610 BOOL WINAPI
SetUserObjectSecurity( HANDLE handle
, PSECURITY_INFORMATION info
,
611 PSECURITY_DESCRIPTOR sid
)
613 FIXME( "(%p,%p,%p),stub!\n", handle
, info
, sid
);