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);
|
WINE_DEFAULT_DEBUG_CHANNEL(graphics);
|
||||||
|
|
||||||
#define DESKTOP_ALL_ACCESS 0x01ff
|
|
||||||
|
|
||||||
HMODULE user32_module = 0;
|
HMODULE user32_module = 0;
|
||||||
|
|
||||||
static CRITICAL_SECTION user_section;
|
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
|
* 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
|
* USER initialisation routine
|
||||||
*/
|
*/
|
||||||
static BOOL process_attach(void)
|
static BOOL process_attach(void)
|
||||||
{
|
{
|
||||||
dpiaware_init();
|
dpiaware_init();
|
||||||
winstation_init();
|
register_desktop_class();
|
||||||
|
|
||||||
/* Initialize system colors and metrics */
|
/* Initialize system colors and metrics */
|
||||||
SYSPARAMS_Init();
|
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 add_face_to_cache( struct gdi_font_face *face );
|
||||||
static void remove_face_from_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)
|
UINT get_acp(void)
|
||||||
{
|
{
|
||||||
return ((const WORD *)NtCurrentTeb()->Peb->AnsiCodePageData)[1];
|
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 );
|
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 };
|
UNICODE_STRING nameW = { name_len, name_len, (WCHAR *)name };
|
||||||
OBJECT_ATTRIBUTES attr;
|
OBJECT_ATTRIBUTES attr;
|
||||||
|
@ -617,7 +605,7 @@ static HKEY reg_create_key( HKEY root, const WCHAR *name, ULONG name_len,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HKEY reg_open_hkcu_key( const char *name )
|
HKEY reg_open_hkcu_key( const char *name )
|
||||||
{
|
{
|
||||||
WCHAR nameW[128];
|
WCHAR nameW[128];
|
||||||
return reg_open_key( hkcu_key, nameW, asciiz_to_unicode( nameW, name ) - sizeof(WCHAR) );
|
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;
|
NTSTATUS status;
|
||||||
if ((status = ntdll_init_syscalls( 1, &syscall_table, dispatcher ))) return 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[] =
|
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 void wrappers_init( unixlib_handle_t handle ) DECLSPEC_HIDDEN;
|
||||||
extern NTSTATUS gdi_init(void) DECLSPEC_HIDDEN;
|
extern NTSTATUS gdi_init(void) DECLSPEC_HIDDEN;
|
||||||
extern NTSTATUS callbacks_init( void *args ) 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 )
|
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 wcsrchr(s,c) win32u_wcsrchr(s,c)
|
||||||
#define wcstol(s,e,b) win32u_wcstol(s,e,b)
|
#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 win32u_mbtowc( CPTABLEINFO *info, WCHAR *dst, DWORD dstlen, const char *src,
|
||||||
DWORD srclen ) DECLSPEC_HIDDEN;
|
DWORD srclen ) DECLSPEC_HIDDEN;
|
||||||
DWORD win32u_wctomb( CPTABLEINFO *info, char *dst, DWORD dstlen, const WCHAR *src,
|
DWORD win32u_wctomb( CPTABLEINFO *info, char *dst, DWORD dstlen, const WCHAR *src,
|
||||||
|
|
|
@ -22,17 +22,22 @@
|
||||||
#pragma makedep unix
|
#pragma makedep unix
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "ntstatus.h"
|
||||||
|
#define WIN32_NO_STATUS
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include "windef.h"
|
#include "windef.h"
|
||||||
#include "winbase.h"
|
#include "winbase.h"
|
||||||
#include "ntuser.h"
|
#include "ntuser.h"
|
||||||
#include "winternl.h"
|
#include "ddk/wdm.h"
|
||||||
|
#include "ntgdi_private.h"
|
||||||
#include "wine/server.h"
|
#include "wine/server.h"
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(winstation);
|
WINE_DEFAULT_DEBUG_CHANNEL(winstation);
|
||||||
|
|
||||||
|
|
||||||
|
#define DESKTOP_ALL_ACCESS 0x01ff
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* NtUserCreateWindowStation (win32u.@)
|
* NtUserCreateWindowStation (win32u.@)
|
||||||
*/
|
*/
|
||||||
|
@ -374,3 +379,134 @@ BOOL WINAPI NtUserSetObjectInformation( HANDLE handle, INT index, void *info, DW
|
||||||
SERVER_END_REQ;
|
SERVER_END_REQ;
|
||||||
return ret;
|
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