Commit ac69fcb1 authored by Alexandre Julliard's avatar Alexandre Julliard

server: Check that the prefix type can support the client architecture.

parent bbc03d51
......@@ -908,11 +908,8 @@ static void start_wineboot( HANDLE handles[2] )
{
static const WCHAR wineboot[] = {'\\','w','i','n','e','b','o','o','t','.','e','x','e',0};
static const WCHAR args[] = {' ','-','-','i','n','i','t',0};
const DWORD expected_type = (sizeof(void*) > sizeof(int) || is_wow64) ?
SCS_64BIT_BINARY : SCS_32BIT_BINARY;
STARTUPINFOW si;
PROCESS_INFORMATION pi;
DWORD type;
void *redir;
WCHAR app[MAX_PATH];
WCHAR cmdline[MAX_PATH + (sizeof(wineboot) + sizeof(args)) / sizeof(WCHAR)];
......@@ -928,17 +925,6 @@ static void start_wineboot( HANDLE handles[2] )
lstrcatW( app, wineboot );
Wow64DisableWow64FsRedirection( &redir );
if (GetBinaryTypeW( app, &type ) && type != expected_type)
{
if (type == SCS_64BIT_BINARY)
MESSAGE( "wine: '%s' is a 64-bit prefix, it cannot be used with 32-bit Wine.\n",
wine_get_config_dir() );
else
MESSAGE( "wine: '%s' is a 32-bit prefix, it cannot be used with %s Wine.\n",
wine_get_config_dir(), is_wow64 ? "wow64" : "64-bit" );
ExitProcess( 1 );
}
strcpyW( cmdline, app );
strcatW( cmdline, args );
if (CreateProcessW( app, cmdline, NULL, NULL, FALSE, DETACHED_PROCESS, NULL, NULL, &si, &pi ))
......
......@@ -1039,6 +1039,7 @@ NTSTATUS server_init_process_done(void)
*/
size_t server_init_thread( void *entry_point )
{
static const int is_win64 = (sizeof(void *) > sizeof(int));
int ret;
int reply_pipe[2];
struct sigaction sig_act;
......@@ -1083,20 +1084,23 @@ size_t server_init_thread( void *entry_point )
}
SERVER_END_REQ;
#ifndef _WIN64
is_wow64 = (server_cpus & (1 << CPU_x86_64)) != 0;
#endif
is_wow64 = !is_win64 && (server_cpus & (1 << CPU_x86_64)) != 0;
ntdll_get_thread_data()->wow64_redir = is_wow64;
if (ret)
switch (ret)
{
if (ret == STATUS_NOT_SUPPORTED)
{
static const char * const cpu_arch[] = { "x86", "x86_64", "Alpha", "PowerPC", "Sparc" };
server_protocol_error( "the running wineserver doesn't support the %s architecture.\n",
cpu_arch[client_cpu] );
}
else server_protocol_error( "init_thread failed with status %x\n", ret );
case STATUS_SUCCESS:
return info_size;
case STATUS_NOT_REGISTRY_FILE:
fatal_error( "'%s' is a 32-bit installation, it cannot support 64-bit applications.\n",
wine_get_config_dir() );
case STATUS_NOT_SUPPORTED:
if (is_win64)
fatal_error( "wineserver is 32-bit, it cannot support 64-bit applications.\n" );
else
fatal_error( "'%s' is a 64-bit installation, it cannot be used with a 32-bit wineserver.\n",
wine_get_config_dir() );
default:
server_protocol_error( "init_thread failed with status %x\n", ret );
}
return info_size;
}
......@@ -186,6 +186,7 @@ extern int get_page_size(void);
/* registry functions */
extern unsigned int get_prefix_cpu_mask(void);
extern void init_registry(void);
extern void flush_registry(void);
......
......@@ -1641,6 +1641,34 @@ static WCHAR *format_user_registry_path( const SID *sid, struct unicode_str *pat
return p;
}
/* get the cpu architectures that can be supported in the current prefix */
unsigned int get_prefix_cpu_mask(void)
{
/* Allowed server/client/prefix combinations:
*
* prefix
* 32 64
* server +------+------+ client
* | ok | fail | 32
* 32 +------+------+---
* | fail | fail | 64
* ---+------+------+---
* | ok | ok | 32
* 64 +------+------+---
* | fail | ok | 64
* ---+------+------+---
*/
switch (prefix_type)
{
case PREFIX_64BIT:
/* 64-bit prefix requires 64-bit server */
return sizeof(void *) > sizeof(int) ? ~0 : 0;
case PREFIX_32BIT:
default:
return ~CPU_64BIT_MASK; /* only 32-bit cpus supported on 32-bit prefix */
}
}
/* registry initialisation */
void init_registry(void)
{
......
......@@ -1098,6 +1098,7 @@ DECL_HANDLER(new_thread)
/* initialize a new thread */
DECL_HANDLER(init_thread)
{
unsigned int prefix_cpu_mask = get_prefix_cpu_mask();
struct process *process = current->process;
int reply_fd = thread_get_inflight_fd( current, req->reply_fd );
int wait_fd = thread_get_inflight_fd( current, req->wait_fd );
......@@ -1134,9 +1135,12 @@ DECL_HANDLER(init_thread)
if (!process->peb) /* first thread, initialize the process too */
{
if (!CPU_FLAG(req->cpu) || !(supported_cpus & CPU_FLAG(req->cpu)))
if (!CPU_FLAG(req->cpu) || !(supported_cpus & prefix_cpu_mask & CPU_FLAG(req->cpu)))
{
set_error( STATUS_NOT_SUPPORTED );
if (!(supported_cpus & CPU_64BIT_MASK))
set_error( STATUS_NOT_SUPPORTED );
else
set_error( STATUS_NOT_REGISTRY_FILE ); /* server supports it but not the prefix */
return;
}
process->unix_pid = current->unix_pid;
......@@ -1163,7 +1167,7 @@ DECL_HANDLER(init_thread)
reply->tid = get_thread_id( current );
reply->version = SERVER_PROTOCOL_VERSION;
reply->server_start = server_start_time;
reply->all_cpus = supported_cpus;
reply->all_cpus = supported_cpus & prefix_cpu_mask;
return;
error:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment