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
22 #define WIN32_NO_STATUS
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
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
))
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
;
63 OBJECT_ATTRIBUTES attr
;
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 */
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
;
86 ret
= GetTokenInformation( GetCurrentProcessToken(), TokenStatistics
, &stats
, sizeof(stats
), NULL
);
88 swprintf( default_name
, ARRAY_SIZE(default_name
), L
"Service-0x%x-%x$",
89 stats
.AuthenticationId
.HighPart
, stats
.AuthenticationId
.LowPart
);
94 static const WCHAR
*get_winstation_default_name( void )
96 static INIT_ONCE once
= INIT_ONCE_STATIC_INIT
;
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
);
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
;
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
);
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
;
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
;
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
];
204 SERVER_START_REQ( enum_winstation
)
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;
213 if (status
== STATUS_NO_MORE_ENTRIES
)
217 SetLastError( RtlNtStatusToDosError( status
) );
220 ret
= func( name
, lparam
);
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
);
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
);
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
;
259 if (device
|| (devmode
&& !(flags
& DF_WINE_CREATE_DESKTOP
)))
261 SetLastError( ERROR_INVALID_PARAMETER
);
265 RtlInitUnicodeString( &str
, name
);
266 InitializeObjectAttributes( &attr
, &str
, OBJ_CASE_INSENSITIVE
| OBJ_OPENIF
,
267 get_winstations_dir_handle(), NULL
);
268 if (sa
&& sa
->bInheritHandle
) attr
.Attributes
|= OBJ_INHERIT
;
269 return NtUserCreateDesktopEx( &attr
, NULL
, devmode
, flags
, access
, 0 );
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 HDESK
open_winstation_desktop( HWINSTA hwinsta
, LPCWSTR name
, DWORD flags
, BOOL inherit
, ACCESS_MASK access
)
293 OBJECT_ATTRIBUTES attr
;
296 RtlInitUnicodeString( &str
, name
);
297 InitializeObjectAttributes( &attr
, &str
, OBJ_CASE_INSENSITIVE
, hwinsta
, NULL
);
298 if (inherit
) attr
.Attributes
|= OBJ_INHERIT
;
299 return NtUserOpenDesktop( &attr
, flags
, access
);
303 /******************************************************************************
304 * OpenDesktopW (USER32.@)
306 HDESK WINAPI
OpenDesktopW( LPCWSTR name
, DWORD flags
, BOOL inherit
, ACCESS_MASK access
)
308 return open_winstation_desktop( NULL
, name
, flags
, inherit
, access
);
312 /******************************************************************************
313 * EnumDesktopsA (USER32.@)
315 BOOL WINAPI
EnumDesktopsA( HWINSTA winsta
, DESKTOPENUMPROCA func
, LPARAM lparam
)
317 struct enum_proc_lparam data
;
319 data
.lparam
= lparam
;
320 return EnumDesktopsW( winsta
, enum_names_WtoA
, (LPARAM
)&data
);
324 /******************************************************************************
325 * EnumDesktopsW (USER32.@)
327 BOOL WINAPI
EnumDesktopsW( HWINSTA winsta
, DESKTOPENUMPROCW func
, LPARAM lparam
)
329 unsigned int index
= 0;
330 WCHAR name
[MAX_PATH
];
335 winsta
= NtUserGetProcessWindowStation();
339 SERVER_START_REQ( enum_desktop
)
341 req
->winstation
= wine_server_obj_handle( winsta
);
343 wine_server_set_reply( req
, name
, sizeof(name
) - sizeof(WCHAR
) );
344 status
= wine_server_call( req
);
345 name
[wine_server_reply_size(reply
)/sizeof(WCHAR
)] = 0;
349 if (status
== STATUS_NO_MORE_ENTRIES
)
353 SetLastError( RtlNtStatusToDosError( status
) );
356 ret
= func(name
, lparam
);
362 /***********************************************************************
363 * GetUserObjectInformationA (USER32.@)
365 BOOL WINAPI
GetUserObjectInformationA( HANDLE handle
, INT index
, LPVOID info
, DWORD len
, LPDWORD needed
)
367 /* check for information types returning strings */
368 if (index
== UOI_TYPE
|| index
== UOI_NAME
)
370 WCHAR buffer
[MAX_PATH
];
373 if (!NtUserGetObjectInformation( handle
, index
, buffer
, sizeof(buffer
), &lenW
)) return FALSE
;
374 lenA
= WideCharToMultiByte( CP_ACP
, 0, buffer
, -1, NULL
, 0, NULL
, NULL
);
375 if (needed
) *needed
= lenA
;
378 /* If the buffer length supplied by the caller is insufficient, Windows returns a
379 'needed' length based upon the Unicode byte length, so we should do similarly. */
380 if (needed
) *needed
= lenW
;
382 SetLastError( ERROR_INSUFFICIENT_BUFFER
);
385 if (info
) WideCharToMultiByte( CP_ACP
, 0, buffer
, -1, info
, len
, NULL
, NULL
);
388 return NtUserGetObjectInformation( handle
, index
, info
, len
, needed
);
392 /******************************************************************************
393 * SetUserObjectInformationA (USER32.@)
395 BOOL WINAPI
SetUserObjectInformationA( HANDLE handle
, INT index
, LPVOID info
, DWORD len
)
397 return NtUserSetObjectInformation( handle
, index
, info
, len
);
401 /***********************************************************************
402 * GetUserObjectSecurity (USER32.@)
404 BOOL WINAPI
GetUserObjectSecurity( HANDLE handle
, PSECURITY_INFORMATION info
,
405 PSECURITY_DESCRIPTOR sid
, DWORD len
, LPDWORD needed
)
407 FIXME( "(%p %p %p len=%ld %p),stub!\n", handle
, info
, sid
, len
, needed
);
409 *needed
= sizeof(SECURITY_DESCRIPTOR
);
410 if (len
< sizeof(SECURITY_DESCRIPTOR
))
412 SetLastError( ERROR_INSUFFICIENT_BUFFER
);
415 return InitializeSecurityDescriptor(sid
, SECURITY_DESCRIPTOR_REVISION
);
418 /***********************************************************************
419 * SetUserObjectSecurity (USER32.@)
421 BOOL WINAPI
SetUserObjectSecurity( HANDLE handle
, PSECURITY_INFORMATION info
,
422 PSECURITY_DESCRIPTOR sid
)
424 FIXME( "(%p,%p,%p),stub!\n", handle
, info
, sid
);