server: Return a list of supported machines instead of a CPU bitmask.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
191fd47e38
commit
96865eb7e7
|
@ -1253,7 +1253,7 @@ NTSTATUS WINAPI NtQueryInformationProcess( HANDLE handle, PROCESSINFOCLASS class
|
||||||
ULONG_PTR val = 0;
|
ULONG_PTR val = 0;
|
||||||
|
|
||||||
if (handle == GetCurrentProcess()) val = is_wow64;
|
if (handle == GetCurrentProcess()) val = is_wow64;
|
||||||
else if (server_cpus & ((1 << CPU_x86_64) | (1 << CPU_ARM64)))
|
else if (is_win64 || is_wow64)
|
||||||
{
|
{
|
||||||
SERVER_START_REQ( get_process_info )
|
SERVER_START_REQ( get_process_info )
|
||||||
{
|
{
|
||||||
|
|
|
@ -101,7 +101,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(server);
|
||||||
|
|
||||||
static const char *server_dir;
|
static const char *server_dir;
|
||||||
|
|
||||||
unsigned int server_cpus = 0;
|
unsigned int supported_machines_count = 0;
|
||||||
|
USHORT supported_machines[8] = { 0 };
|
||||||
BOOL is_wow64 = FALSE;
|
BOOL is_wow64 = FALSE;
|
||||||
BOOL process_exiting = FALSE;
|
BOOL process_exiting = FALSE;
|
||||||
|
|
||||||
|
@ -1480,10 +1481,10 @@ void process_exit_wrapper( int status )
|
||||||
*/
|
*/
|
||||||
size_t server_init_process(void)
|
size_t server_init_process(void)
|
||||||
{
|
{
|
||||||
static const char *cpu_names[] = { "x86", "x86_64", "ARM", "ARM64" };
|
|
||||||
const char *arch = getenv( "WINEARCH" );
|
const char *arch = getenv( "WINEARCH" );
|
||||||
const char *env_socket = getenv( "WINESERVERSOCKET" );
|
const char *env_socket = getenv( "WINESERVERSOCKET" );
|
||||||
obj_handle_t version;
|
obj_handle_t version;
|
||||||
|
unsigned int i;
|
||||||
int ret, reply_pipe;
|
int ret, reply_pipe;
|
||||||
struct sigaction sig_act;
|
struct sigaction sig_act;
|
||||||
size_t info_size;
|
size_t info_size;
|
||||||
|
@ -1561,41 +1562,47 @@ size_t server_init_process(void)
|
||||||
req->wait_fd = ntdll_get_thread_data()->wait_fd[1];
|
req->wait_fd = ntdll_get_thread_data()->wait_fd[1];
|
||||||
req->debug_level = (TRACE_ON(server) != 0);
|
req->debug_level = (TRACE_ON(server) != 0);
|
||||||
req->cpu = client_cpu;
|
req->cpu = client_cpu;
|
||||||
|
wine_server_set_reply( req, supported_machines, sizeof(supported_machines) );
|
||||||
ret = wine_server_call( req );
|
ret = wine_server_call( req );
|
||||||
NtCurrentTeb()->ClientId.UniqueProcess = ULongToHandle(reply->pid);
|
NtCurrentTeb()->ClientId.UniqueProcess = ULongToHandle(reply->pid);
|
||||||
NtCurrentTeb()->ClientId.UniqueThread = ULongToHandle(reply->tid);
|
NtCurrentTeb()->ClientId.UniqueThread = ULongToHandle(reply->tid);
|
||||||
info_size = reply->info_size;
|
info_size = reply->info_size;
|
||||||
server_start_time = reply->server_start;
|
server_start_time = reply->server_start;
|
||||||
server_cpus = reply->all_cpus;
|
supported_machines_count = wine_server_reply_size( reply ) / sizeof(*supported_machines);
|
||||||
}
|
}
|
||||||
SERVER_END_REQ;
|
SERVER_END_REQ;
|
||||||
close( reply_pipe );
|
close( reply_pipe );
|
||||||
|
|
||||||
#ifndef _WIN64
|
if (ret) server_protocol_error( "init_first_thread failed with status %x\n", ret );
|
||||||
is_wow64 = (server_cpus & ((1 << CPU_x86_64) | (1 << CPU_ARM64))) != 0;
|
|
||||||
init_teb64( NtCurrentTeb() );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
switch (ret)
|
if (!supported_machines_count)
|
||||||
|
fatal_error( "'%s' is a 64-bit installation, it cannot be used with a 32-bit wineserver.\n",
|
||||||
|
config_dir );
|
||||||
|
|
||||||
|
switch (supported_machines[0])
|
||||||
{
|
{
|
||||||
case STATUS_SUCCESS:
|
case IMAGE_FILE_MACHINE_AMD64:
|
||||||
if (arch)
|
case IMAGE_FILE_MACHINE_ARM64:
|
||||||
|
if (arch && !strcmp( arch, "win32" ))
|
||||||
|
fatal_error( "WINEARCH set to win32 but '%s' is a 64-bit installation.\n", config_dir );
|
||||||
|
if (!is_win64)
|
||||||
{
|
{
|
||||||
if (!strcmp( arch, "win32" ) && (is_win64 || is_wow64))
|
is_wow64 = TRUE;
|
||||||
fatal_error( "WINEARCH set to win32 but '%s' is a 64-bit installation.\n", config_dir );
|
init_teb64( NtCurrentTeb() );
|
||||||
if (!strcmp( arch, "win64" ) && !is_win64 && !is_wow64)
|
|
||||||
fatal_error( "WINEARCH set to win64 but '%s' is a 32-bit installation.\n", config_dir );
|
|
||||||
}
|
}
|
||||||
return info_size;
|
break;
|
||||||
case STATUS_INVALID_IMAGE_WIN_64:
|
|
||||||
fatal_error( "'%s' is a 32-bit installation, it cannot support 64-bit applications.\n", config_dir );
|
|
||||||
case STATUS_NOT_SUPPORTED:
|
|
||||||
fatal_error( "'%s' is a 64-bit installation, it cannot be used with a 32-bit wineserver.\n", config_dir );
|
|
||||||
case STATUS_INVALID_IMAGE_FORMAT:
|
|
||||||
fatal_error( "wineserver doesn't support the %s architecture\n", cpu_names[client_cpu] );
|
|
||||||
default:
|
default:
|
||||||
server_protocol_error( "init_first_thread failed with status %x\n", ret );
|
if (is_win64)
|
||||||
|
fatal_error( "'%s' is a 32-bit installation, it cannot support 64-bit applications.\n", config_dir );
|
||||||
|
if (arch && !strcmp( arch, "win64" ))
|
||||||
|
fatal_error( "WINEARCH set to win64 but '%s' is a 32-bit installation.\n", config_dir );
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < supported_machines_count; i++)
|
||||||
|
if (supported_machines[i] == current_machine) return info_size;
|
||||||
|
|
||||||
|
fatal_error( "wineserver doesn't support the %04x architecture\n", current_machine );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -127,7 +127,8 @@ extern char **main_argv DECLSPEC_HIDDEN;
|
||||||
extern char **main_envp DECLSPEC_HIDDEN;
|
extern char **main_envp DECLSPEC_HIDDEN;
|
||||||
extern WCHAR **main_wargv DECLSPEC_HIDDEN;
|
extern WCHAR **main_wargv DECLSPEC_HIDDEN;
|
||||||
extern const WCHAR system_dir[] DECLSPEC_HIDDEN;
|
extern const WCHAR system_dir[] DECLSPEC_HIDDEN;
|
||||||
extern unsigned int server_cpus DECLSPEC_HIDDEN;
|
extern unsigned int supported_machines_count DECLSPEC_HIDDEN;
|
||||||
|
extern USHORT supported_machines[8] DECLSPEC_HIDDEN;
|
||||||
extern BOOL is_wow64 DECLSPEC_HIDDEN;
|
extern BOOL is_wow64 DECLSPEC_HIDDEN;
|
||||||
extern BOOL process_exiting DECLSPEC_HIDDEN;
|
extern BOOL process_exiting DECLSPEC_HIDDEN;
|
||||||
extern HANDLE keyed_event DECLSPEC_HIDDEN;
|
extern HANDLE keyed_event DECLSPEC_HIDDEN;
|
||||||
|
|
|
@ -936,7 +936,8 @@ struct init_first_thread_reply
|
||||||
thread_id_t tid;
|
thread_id_t tid;
|
||||||
timeout_t server_start;
|
timeout_t server_start;
|
||||||
data_size_t info_size;
|
data_size_t info_size;
|
||||||
unsigned int all_cpus;
|
/* VARARG(machines,ushorts); */
|
||||||
|
char __pad_28[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -6218,7 +6219,7 @@ union generic_reply
|
||||||
|
|
||||||
/* ### protocol_version begin ### */
|
/* ### protocol_version begin ### */
|
||||||
|
|
||||||
#define SERVER_PROTOCOL_VERSION 692
|
#define SERVER_PROTOCOL_VERSION 693
|
||||||
|
|
||||||
/* ### protocol_version end ### */
|
/* ### protocol_version end ### */
|
||||||
|
|
||||||
|
|
|
@ -239,6 +239,8 @@ extern void generate_startup_debug_events( struct process *process );
|
||||||
/* registry functions */
|
/* registry functions */
|
||||||
|
|
||||||
extern unsigned int get_prefix_cpu_mask(void);
|
extern unsigned int get_prefix_cpu_mask(void);
|
||||||
|
extern unsigned int supported_machines_count;
|
||||||
|
extern unsigned short supported_machines[8];
|
||||||
extern void init_registry(void);
|
extern void init_registry(void);
|
||||||
extern void flush_registry(void);
|
extern void flush_registry(void);
|
||||||
|
|
||||||
|
|
|
@ -915,7 +915,7 @@ typedef struct
|
||||||
thread_id_t tid; /* thread id of the new thread */
|
thread_id_t tid; /* thread id of the new thread */
|
||||||
timeout_t server_start; /* server start time */
|
timeout_t server_start; /* server start time */
|
||||||
data_size_t info_size; /* total size of startup info */
|
data_size_t info_size; /* total size of startup info */
|
||||||
unsigned int all_cpus; /* bitset of supported CPUs */
|
VARARG(machines,ushorts); /* array of supported machines */
|
||||||
@END
|
@END
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -145,6 +145,8 @@ struct save_branch_info
|
||||||
static int save_branch_count;
|
static int save_branch_count;
|
||||||
static struct save_branch_info save_branch_info[MAX_SAVE_BRANCH_INFO];
|
static struct save_branch_info save_branch_info[MAX_SAVE_BRANCH_INFO];
|
||||||
|
|
||||||
|
unsigned int supported_machines_count = 0;
|
||||||
|
unsigned short supported_machines[8];
|
||||||
|
|
||||||
/* information about a file being loaded */
|
/* information about a file being loaded */
|
||||||
struct file_load_info
|
struct file_load_info
|
||||||
|
@ -1795,6 +1797,29 @@ unsigned int get_prefix_cpu_mask(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void init_supported_machines(void)
|
||||||
|
{
|
||||||
|
unsigned int count = 0;
|
||||||
|
#ifdef __i386__
|
||||||
|
if (prefix_type == PREFIX_32BIT) supported_machines[count++] = IMAGE_FILE_MACHINE_I386;
|
||||||
|
#elif defined(__x86_64__)
|
||||||
|
if (prefix_type == PREFIX_64BIT) supported_machines[count++] = IMAGE_FILE_MACHINE_AMD64;
|
||||||
|
supported_machines[count++] = IMAGE_FILE_MACHINE_I386;
|
||||||
|
#elif defined(__arm__)
|
||||||
|
if (prefix_type == PREFIX_32BIT) supported_machines[count++] = IMAGE_FILE_MACHINE_ARMNT;
|
||||||
|
#elif defined(__aarch64__)
|
||||||
|
if (prefix_type == PREFIX_64BIT)
|
||||||
|
{
|
||||||
|
supported_machines[count++] = IMAGE_FILE_MACHINE_ARM64;
|
||||||
|
supported_machines[count++] = IMAGE_FILE_MACHINE_I386;
|
||||||
|
}
|
||||||
|
supported_machines[count++] = IMAGE_FILE_MACHINE_ARMNT;
|
||||||
|
#else
|
||||||
|
#error Unsupported machine
|
||||||
|
#endif
|
||||||
|
supported_machines_count = count;
|
||||||
|
}
|
||||||
|
|
||||||
/* registry initialisation */
|
/* registry initialisation */
|
||||||
void init_registry(void)
|
void init_registry(void)
|
||||||
{
|
{
|
||||||
|
@ -1837,6 +1862,8 @@ void init_registry(void)
|
||||||
else if (prefix_type == PREFIX_UNKNOWN)
|
else if (prefix_type == PREFIX_UNKNOWN)
|
||||||
prefix_type = PREFIX_32BIT;
|
prefix_type = PREFIX_32BIT;
|
||||||
|
|
||||||
|
init_supported_machines();
|
||||||
|
|
||||||
/* load userdef.reg into Registry\User\.Default */
|
/* load userdef.reg into Registry\User\.Default */
|
||||||
|
|
||||||
if (!(key = create_key_recursive( root_key, &HKU_name, current_time )))
|
if (!(key = create_key_recursive( root_key, &HKU_name, current_time )))
|
||||||
|
|
|
@ -752,7 +752,6 @@ C_ASSERT( FIELD_OFFSET(struct init_first_thread_reply, pid) == 8 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct init_first_thread_reply, tid) == 12 );
|
C_ASSERT( FIELD_OFFSET(struct init_first_thread_reply, tid) == 12 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct init_first_thread_reply, server_start) == 16 );
|
C_ASSERT( FIELD_OFFSET(struct init_first_thread_reply, server_start) == 16 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct init_first_thread_reply, info_size) == 24 );
|
C_ASSERT( FIELD_OFFSET(struct init_first_thread_reply, info_size) == 24 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct init_first_thread_reply, all_cpus) == 28 );
|
|
||||||
C_ASSERT( sizeof(struct init_first_thread_reply) == 32 );
|
C_ASSERT( sizeof(struct init_first_thread_reply) == 32 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct init_thread_request, unix_tid) == 12 );
|
C_ASSERT( FIELD_OFFSET(struct init_thread_request, unix_tid) == 12 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct init_thread_request, reply_fd) == 16 );
|
C_ASSERT( FIELD_OFFSET(struct init_thread_request, reply_fd) == 16 );
|
||||||
|
|
|
@ -1445,8 +1445,6 @@ DECL_HANDLER(init_first_thread)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_cpu_supported( req->cpu )) return;
|
|
||||||
|
|
||||||
current->unix_pid = process->unix_pid = req->unix_pid;
|
current->unix_pid = process->unix_pid = req->unix_pid;
|
||||||
current->unix_tid = req->unix_tid;
|
current->unix_tid = req->unix_tid;
|
||||||
current->teb = req->teb;
|
current->teb = req->teb;
|
||||||
|
@ -1465,7 +1463,8 @@ DECL_HANDLER(init_first_thread)
|
||||||
reply->tid = get_thread_id( current );
|
reply->tid = get_thread_id( current );
|
||||||
reply->info_size = get_process_startup_info_size( process );
|
reply->info_size = get_process_startup_info_size( process );
|
||||||
reply->server_start = server_start_time;
|
reply->server_start = server_start_time;
|
||||||
reply->all_cpus = supported_cpus & get_prefix_cpu_mask();
|
set_reply_data( supported_machines,
|
||||||
|
min( supported_machines_count * sizeof(unsigned short), get_reply_max_size() ));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* initialize a new thread */
|
/* initialize a new thread */
|
||||||
|
|
|
@ -485,6 +485,21 @@ static void dump_varargs_uints64( const char *prefix, data_size_t size )
|
||||||
remove_data( size );
|
remove_data( size );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void dump_varargs_ushorts( const char *prefix, data_size_t size )
|
||||||
|
{
|
||||||
|
const unsigned short *data = cur_data;
|
||||||
|
data_size_t len = size / sizeof(*data);
|
||||||
|
|
||||||
|
fprintf( stderr, "%s{", prefix );
|
||||||
|
while (len > 0)
|
||||||
|
{
|
||||||
|
fprintf( stderr, "%04x", *data++ );
|
||||||
|
if (--len) fputc( ',', stderr );
|
||||||
|
}
|
||||||
|
fputc( '}', stderr );
|
||||||
|
remove_data( size );
|
||||||
|
}
|
||||||
|
|
||||||
static void dump_varargs_apc_result( const char *prefix, data_size_t size )
|
static void dump_varargs_apc_result( const char *prefix, data_size_t size )
|
||||||
{
|
{
|
||||||
const apc_result_t *result = cur_data;
|
const apc_result_t *result = cur_data;
|
||||||
|
@ -1432,7 +1447,7 @@ static void dump_init_first_thread_reply( const struct init_first_thread_reply *
|
||||||
fprintf( stderr, ", tid=%04x", req->tid );
|
fprintf( stderr, ", tid=%04x", req->tid );
|
||||||
dump_timeout( ", server_start=", &req->server_start );
|
dump_timeout( ", server_start=", &req->server_start );
|
||||||
fprintf( stderr, ", info_size=%u", req->info_size );
|
fprintf( stderr, ", info_size=%u", req->info_size );
|
||||||
fprintf( stderr, ", all_cpus=%08x", req->all_cpus );
|
dump_varargs_ushorts( ", machines=", cur_size );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dump_init_thread_request( const struct init_thread_request *req )
|
static void dump_init_thread_request( const struct init_thread_request *req )
|
||||||
|
|
Loading…
Reference in New Issue