win32u: Move winstation initialization from user32.
Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
d841b31aee
commit
2c1d00f142
|
@ -33,8 +33,6 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(graphics);
|
||||
|
||||
#define DESKTOP_ALL_ACCESS 0x01ff
|
||||
|
||||
HMODULE user32_module = 0;
|
||||
|
||||
static CRITICAL_SECTION user_section;
|
||||
|
@ -161,53 +159,6 @@ static void palette_init(void)
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* get_default_desktop
|
||||
*
|
||||
* Get the name of the desktop to use for this app if not specified explicitly.
|
||||
*/
|
||||
static const WCHAR *get_default_desktop(void)
|
||||
{
|
||||
static WCHAR buffer[MAX_PATH + ARRAY_SIZE(L"\\Explorer")];
|
||||
WCHAR *p, *appname = buffer;
|
||||
const WCHAR *ret = NULL;
|
||||
DWORD len;
|
||||
HKEY tmpkey, appkey;
|
||||
|
||||
len = (GetModuleFileNameW( 0, buffer, MAX_PATH ));
|
||||
if (!len || len >= MAX_PATH) return L"Default";
|
||||
if ((p = wcsrchr( appname, '/' ))) appname = p + 1;
|
||||
if ((p = wcsrchr( appname, '\\' ))) appname = p + 1;
|
||||
p = appname + lstrlenW(appname);
|
||||
lstrcpyW( p, L"\\Explorer" );
|
||||
|
||||
/* @@ Wine registry key: HKCU\Software\Wine\AppDefaults\app.exe\Explorer */
|
||||
if (!RegOpenKeyW( HKEY_CURRENT_USER, L"Software\\Wine\\AppDefaults", &tmpkey ))
|
||||
{
|
||||
if (RegOpenKeyW( tmpkey, appname, &appkey )) appkey = 0;
|
||||
RegCloseKey( tmpkey );
|
||||
if (appkey)
|
||||
{
|
||||
len = sizeof(buffer);
|
||||
if (!RegQueryValueExW( appkey, L"Desktop", 0, NULL, (LPBYTE)buffer, &len )) ret = buffer;
|
||||
RegCloseKey( appkey );
|
||||
if (ret && *ret) return ret;
|
||||
ret = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* @@ Wine registry key: HKCU\Software\Wine\Explorer */
|
||||
if (!RegOpenKeyW( HKEY_CURRENT_USER, L"Software\\Wine\\Explorer", &appkey ))
|
||||
{
|
||||
len = sizeof(buffer);
|
||||
if (!RegQueryValueExW( appkey, L"Desktop", 0, NULL, (LPBYTE)buffer, &len )) ret = buffer;
|
||||
RegCloseKey( appkey );
|
||||
if (ret && *ret) return ret;
|
||||
}
|
||||
return L"Default";
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* dpiaware_init
|
||||
*
|
||||
|
@ -265,67 +216,13 @@ static void dpiaware_init(void)
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* winstation_init
|
||||
*
|
||||
* Connect to the process window station and desktop.
|
||||
*/
|
||||
static void winstation_init(void)
|
||||
{
|
||||
STARTUPINFOW info;
|
||||
WCHAR *winstation = NULL, *desktop = NULL, *buffer = NULL;
|
||||
HANDLE handle;
|
||||
|
||||
GetStartupInfoW( &info );
|
||||
if (info.lpDesktop && *info.lpDesktop)
|
||||
{
|
||||
buffer = HeapAlloc( GetProcessHeap(), 0, (lstrlenW(info.lpDesktop) + 1) * sizeof(WCHAR) );
|
||||
lstrcpyW( buffer, info.lpDesktop );
|
||||
if ((desktop = wcschr( buffer, '\\' )))
|
||||
{
|
||||
*desktop++ = 0;
|
||||
winstation = buffer;
|
||||
}
|
||||
else desktop = buffer;
|
||||
}
|
||||
|
||||
/* set winstation if explicitly specified, or if we don't have one yet */
|
||||
if (buffer || !NtUserGetProcessWindowStation())
|
||||
{
|
||||
handle = CreateWindowStationW( winstation ? winstation : L"WinSta0", 0, WINSTA_ALL_ACCESS, NULL );
|
||||
if (handle)
|
||||
{
|
||||
NtUserSetProcessWindowStation( handle );
|
||||
/* only WinSta0 is visible */
|
||||
if (!winstation || !wcsicmp( winstation, L"WinSta0" ))
|
||||
{
|
||||
USEROBJECTFLAGS flags;
|
||||
flags.fInherit = FALSE;
|
||||
flags.fReserved = FALSE;
|
||||
flags.dwFlags = WSF_VISIBLE;
|
||||
NtUserSetObjectInformation( handle, UOI_FLAGS, &flags, sizeof(flags) );
|
||||
}
|
||||
}
|
||||
}
|
||||
if (buffer || !NtUserGetThreadDesktop( GetCurrentThreadId() ))
|
||||
{
|
||||
handle = CreateDesktopW( desktop ? desktop : get_default_desktop(),
|
||||
NULL, NULL, 0, DESKTOP_ALL_ACCESS, NULL );
|
||||
if (handle) NtUserSetThreadDesktop( handle );
|
||||
}
|
||||
HeapFree( GetProcessHeap(), 0, buffer );
|
||||
|
||||
register_desktop_class();
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* USER initialisation routine
|
||||
*/
|
||||
static BOOL process_attach(void)
|
||||
{
|
||||
dpiaware_init();
|
||||
winstation_init();
|
||||
register_desktop_class();
|
||||
|
||||
/* Initialize system colors and metrics */
|
||||
SYSPARAMS_Init();
|
||||
|
|
|
@ -199,18 +199,6 @@ static struct font_gamma_ramp font_gamma_ramp;
|
|||
static void add_face_to_cache( struct gdi_font_face *face );
|
||||
static void remove_face_from_cache( struct gdi_font_face *face );
|
||||
|
||||
static void ascii_to_unicode( WCHAR *dst, const char *src, size_t len )
|
||||
{
|
||||
while (len--) *dst++ = (unsigned char)*src++;
|
||||
}
|
||||
|
||||
static UINT asciiz_to_unicode( WCHAR *dst, const char *src )
|
||||
{
|
||||
WCHAR *p = dst;
|
||||
while ((*p++ = *src++));
|
||||
return (p - dst) * sizeof(WCHAR);
|
||||
}
|
||||
|
||||
UINT get_acp(void)
|
||||
{
|
||||
return ((const WORD *)NtCurrentTeb()->Peb->AnsiCodePageData)[1];
|
||||
|
@ -553,7 +541,7 @@ static void get_fonts_win_dir_path( const WCHAR *file, WCHAR *path )
|
|||
if (file) lstrcatW( path, file );
|
||||
}
|
||||
|
||||
static HKEY reg_open_key( HKEY root, const WCHAR *name, ULONG name_len )
|
||||
HKEY reg_open_key( HKEY root, const WCHAR *name, ULONG name_len )
|
||||
{
|
||||
UNICODE_STRING nameW = { name_len, name_len, (WCHAR *)name };
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
|
@ -617,7 +605,7 @@ static HKEY reg_create_key( HKEY root, const WCHAR *name, ULONG name_len,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static HKEY reg_open_hkcu_key( const char *name )
|
||||
HKEY reg_open_hkcu_key( const char *name )
|
||||
{
|
||||
WCHAR nameW[128];
|
||||
return reg_open_key( hkcu_key, nameW, asciiz_to_unicode( nameW, name ) - sizeof(WCHAR) );
|
||||
|
|
|
@ -123,7 +123,9 @@ static NTSTATUS init( void *dispatcher )
|
|||
{
|
||||
NTSTATUS status;
|
||||
if ((status = ntdll_init_syscalls( 1, &syscall_table, dispatcher ))) return status;
|
||||
return gdi_init();
|
||||
if ((status = gdi_init())) return status;
|
||||
winstation_init();
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
unixlib_entry_t __wine_unix_call_funcs[] =
|
||||
|
|
|
@ -224,7 +224,12 @@ HPALETTE WINAPI GDISelectPalette( HDC hdc, HPALETTE hpal, WORD wBkg );
|
|||
extern void wrappers_init( unixlib_handle_t handle ) DECLSPEC_HIDDEN;
|
||||
extern NTSTATUS gdi_init(void) DECLSPEC_HIDDEN;
|
||||
extern NTSTATUS callbacks_init( void *args ) DECLSPEC_HIDDEN;
|
||||
extern void winstation_init(void) DECLSPEC_HIDDEN;
|
||||
|
||||
extern HKEY reg_open_hkcu_key( const char *name ) DECLSPEC_HIDDEN;
|
||||
extern HKEY reg_open_key( HKEY root, const WCHAR *name, ULONG name_len ) DECLSPEC_HIDDEN;
|
||||
extern ULONG query_reg_ascii_value( HKEY hkey, const char *name,
|
||||
KEY_VALUE_PARTIAL_INFORMATION *info, ULONG size ) DECLSPEC_HIDDEN;
|
||||
|
||||
static inline WCHAR *win32u_wcsrchr( const WCHAR *str, WCHAR ch )
|
||||
{
|
||||
|
@ -316,6 +321,18 @@ static inline LONG win32u_wcstol( LPCWSTR s, LPWSTR *end, INT base )
|
|||
#define wcsrchr(s,c) win32u_wcsrchr(s,c)
|
||||
#define wcstol(s,e,b) win32u_wcstol(s,e,b)
|
||||
|
||||
static inline void ascii_to_unicode( WCHAR *dst, const char *src, size_t len )
|
||||
{
|
||||
while (len--) *dst++ = (unsigned char)*src++;
|
||||
}
|
||||
|
||||
static inline UINT asciiz_to_unicode( WCHAR *dst, const char *src )
|
||||
{
|
||||
WCHAR *p = dst;
|
||||
while ((*p++ = *src++));
|
||||
return (p - dst) * sizeof(WCHAR);
|
||||
}
|
||||
|
||||
DWORD win32u_mbtowc( CPTABLEINFO *info, WCHAR *dst, DWORD dstlen, const char *src,
|
||||
DWORD srclen ) DECLSPEC_HIDDEN;
|
||||
DWORD win32u_wctomb( CPTABLEINFO *info, char *dst, DWORD dstlen, const WCHAR *src,
|
||||
|
|
|
@ -22,17 +22,22 @@
|
|||
#pragma makedep unix
|
||||
#endif
|
||||
|
||||
#include "ntstatus.h"
|
||||
#define WIN32_NO_STATUS
|
||||
#include <stdarg.h>
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "ntuser.h"
|
||||
#include "winternl.h"
|
||||
#include "ddk/wdm.h"
|
||||
#include "ntgdi_private.h"
|
||||
#include "wine/server.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(winstation);
|
||||
|
||||
|
||||
#define DESKTOP_ALL_ACCESS 0x01ff
|
||||
|
||||
/***********************************************************************
|
||||
* NtUserCreateWindowStation (win32u.@)
|
||||
*/
|
||||
|
@ -374,3 +379,134 @@ BOOL WINAPI NtUserSetObjectInformation( HANDLE handle, INT index, void *info, DW
|
|||
SERVER_END_REQ;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static HANDLE get_winstations_dir_handle(void)
|
||||
{
|
||||
char bufferA[64];
|
||||
WCHAR buffer[64];
|
||||
UNICODE_STRING str;
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
NTSTATUS status;
|
||||
HANDLE dir;
|
||||
|
||||
sprintf( bufferA, "\\Sessions\\%u\\Windows\\WindowStations", NtCurrentTeb()->Peb->SessionId );
|
||||
str.Buffer = buffer;
|
||||
str.Length = str.MaximumLength = asciiz_to_unicode( buffer, bufferA ) - sizeof(WCHAR);
|
||||
InitializeObjectAttributes( &attr, &str, 0, 0, NULL );
|
||||
status = NtOpenDirectoryObject( &dir, DIRECTORY_CREATE_OBJECT | DIRECTORY_TRAVERSE, &attr );
|
||||
return status ? 0 : dir;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* get_default_desktop
|
||||
*
|
||||
* Get the name of the desktop to use for this app if not specified explicitly.
|
||||
*/
|
||||
static const WCHAR *get_default_desktop( void *buf, size_t buf_size )
|
||||
{
|
||||
const WCHAR *p, *appname = NtCurrentTeb()->Peb->ProcessParameters->ImagePathName.Buffer;
|
||||
KEY_VALUE_PARTIAL_INFORMATION *info = buf;
|
||||
WCHAR *buffer = buf;
|
||||
HKEY tmpkey, appkey;
|
||||
DWORD len;
|
||||
|
||||
static const WCHAR defaultW[] = {'D','e','f','a','u','l','t',0};
|
||||
|
||||
if ((p = wcsrchr( appname, '/' ))) appname = p + 1;
|
||||
if ((p = wcsrchr( appname, '\\' ))) appname = p + 1;
|
||||
len = lstrlenW(appname);
|
||||
if (len > MAX_PATH) return defaultW;
|
||||
memcpy( buffer, appname, len * sizeof(WCHAR) );
|
||||
asciiz_to_unicode( buffer + len, "\\Explorer" );
|
||||
|
||||
/* @@ Wine registry key: HKCU\Software\Wine\AppDefaults\app.exe\Explorer */
|
||||
if ((tmpkey = reg_open_hkcu_key( "Software\\Wine\\AppDefaults" )))
|
||||
{
|
||||
appkey = reg_open_key( tmpkey, buffer, lstrlenW(buffer) * sizeof(WCHAR) );
|
||||
NtClose( tmpkey );
|
||||
if (appkey)
|
||||
{
|
||||
len = query_reg_ascii_value( appkey, "Desktop", info, buf_size );
|
||||
NtClose( appkey );
|
||||
if (len) return (const WCHAR *)info->Data;
|
||||
}
|
||||
}
|
||||
|
||||
/* @@ Wine registry key: HKCU\Software\Wine\Explorer */
|
||||
if ((appkey = reg_open_hkcu_key( "Software\\Wine\\Explorer" )))
|
||||
{
|
||||
len = query_reg_ascii_value( appkey, "Desktop", info, buf_size );
|
||||
NtClose( appkey );
|
||||
if (len) return (const WCHAR *)info->Data;
|
||||
}
|
||||
|
||||
return defaultW;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* winstation_init
|
||||
*
|
||||
* Connect to the process window station and desktop.
|
||||
*/
|
||||
void winstation_init(void)
|
||||
{
|
||||
RTL_USER_PROCESS_PARAMETERS *params = NtCurrentTeb()->Peb->ProcessParameters;
|
||||
WCHAR *winstation = NULL, *desktop = NULL, *buffer = NULL;
|
||||
HANDLE handle, dir = NULL;
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
UNICODE_STRING str;
|
||||
|
||||
static const WCHAR winsta0[] = {'W','i','n','S','t','a','0',0};
|
||||
|
||||
if (params->Desktop.Length)
|
||||
{
|
||||
buffer = malloc( params->Desktop.Length + sizeof(WCHAR) );
|
||||
memcpy( buffer, params->Desktop.Buffer, params->Desktop.Length );
|
||||
buffer[params->Desktop.Length / sizeof(WCHAR)] = 0;
|
||||
if ((desktop = wcschr( buffer, '\\' )))
|
||||
{
|
||||
*desktop++ = 0;
|
||||
winstation = buffer;
|
||||
}
|
||||
else desktop = buffer;
|
||||
}
|
||||
|
||||
/* set winstation if explicitly specified, or if we don't have one yet */
|
||||
if (buffer || !NtUserGetProcessWindowStation())
|
||||
{
|
||||
str.Buffer = (WCHAR *)(winstation ? winstation : winsta0);
|
||||
str.Length = str.MaximumLength = lstrlenW( str.Buffer ) * sizeof(WCHAR);
|
||||
dir = get_winstations_dir_handle();
|
||||
InitializeObjectAttributes( &attr, &str, OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
|
||||
dir, NULL );
|
||||
|
||||
handle = NtUserCreateWindowStation( &attr, WINSTA_ALL_ACCESS, 0, 0, 0, 0, 0 );
|
||||
if (handle)
|
||||
{
|
||||
NtUserSetProcessWindowStation( handle );
|
||||
/* only WinSta0 is visible */
|
||||
if (!winstation || !wcsicmp( winstation, winsta0 ))
|
||||
{
|
||||
USEROBJECTFLAGS flags;
|
||||
flags.fInherit = FALSE;
|
||||
flags.fReserved = FALSE;
|
||||
flags.dwFlags = WSF_VISIBLE;
|
||||
NtUserSetObjectInformation( handle, UOI_FLAGS, &flags, sizeof(flags) );
|
||||
}
|
||||
}
|
||||
}
|
||||
if (buffer || !NtUserGetThreadDesktop( GetCurrentThreadId() ))
|
||||
{
|
||||
char buffer[4096];
|
||||
str.Buffer = (WCHAR *)(desktop ? desktop : get_default_desktop( buffer, sizeof(buffer) ));
|
||||
str.Length = str.MaximumLength = lstrlenW( str.Buffer ) * sizeof(WCHAR);
|
||||
if (!dir) dir = get_winstations_dir_handle();
|
||||
InitializeObjectAttributes( &attr, &str, OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
|
||||
dir, NULL );
|
||||
|
||||
handle = NtUserCreateDesktopEx( &attr, NULL, NULL, 0, DESKTOP_ALL_ACCESS, 0 );
|
||||
if (handle) NtUserSetThreadDesktop( handle );
|
||||
}
|
||||
NtClose( dir );
|
||||
free( buffer );
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue