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:
Alexandre Julliard 2021-04-23 11:58:32 +02:00
parent 191fd47e38
commit 96865eb7e7
10 changed files with 83 additions and 32 deletions

View File

@ -1253,7 +1253,7 @@ NTSTATUS WINAPI NtQueryInformationProcess( HANDLE handle, PROCESSINFOCLASS class
ULONG_PTR val = 0;
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 )
{

View File

@ -101,7 +101,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(server);
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 process_exiting = FALSE;
@ -1480,10 +1481,10 @@ void process_exit_wrapper( int status )
*/
size_t server_init_process(void)
{
static const char *cpu_names[] = { "x86", "x86_64", "ARM", "ARM64" };
const char *arch = getenv( "WINEARCH" );
const char *env_socket = getenv( "WINESERVERSOCKET" );
obj_handle_t version;
unsigned int i;
int ret, reply_pipe;
struct sigaction sig_act;
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->debug_level = (TRACE_ON(server) != 0);
req->cpu = client_cpu;
wine_server_set_reply( req, supported_machines, sizeof(supported_machines) );
ret = wine_server_call( req );
NtCurrentTeb()->ClientId.UniqueProcess = ULongToHandle(reply->pid);
NtCurrentTeb()->ClientId.UniqueThread = ULongToHandle(reply->tid);
info_size = reply->info_size;
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;
close( reply_pipe );
#ifndef _WIN64
is_wow64 = (server_cpus & ((1 << CPU_x86_64) | (1 << CPU_ARM64))) != 0;
init_teb64( NtCurrentTeb() );
#endif
if (ret) server_protocol_error( "init_first_thread failed with status %x\n", ret );
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:
if (arch)
case IMAGE_FILE_MACHINE_AMD64:
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))
fatal_error( "WINEARCH set to win32 but '%s' is a 64-bit installation.\n", config_dir );
if (!strcmp( arch, "win64" ) && !is_win64 && !is_wow64)
fatal_error( "WINEARCH set to win64 but '%s' is a 32-bit installation.\n", config_dir );
is_wow64 = TRUE;
init_teb64( NtCurrentTeb() );
}
return info_size;
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] );
break;
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 );
}

View File

@ -127,7 +127,8 @@ extern char **main_argv DECLSPEC_HIDDEN;
extern char **main_envp DECLSPEC_HIDDEN;
extern WCHAR **main_wargv 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 process_exiting DECLSPEC_HIDDEN;
extern HANDLE keyed_event DECLSPEC_HIDDEN;

View File

@ -936,7 +936,8 @@ struct init_first_thread_reply
thread_id_t tid;
timeout_t server_start;
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 ### */
#define SERVER_PROTOCOL_VERSION 692
#define SERVER_PROTOCOL_VERSION 693
/* ### protocol_version end ### */

View File

@ -239,6 +239,8 @@ extern void generate_startup_debug_events( struct process *process );
/* registry functions */
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 flush_registry(void);

View File

@ -915,7 +915,7 @@ typedef struct
thread_id_t tid; /* thread id of the new thread */
timeout_t server_start; /* server start time */
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

View File

@ -145,6 +145,8 @@ struct save_branch_info
static int save_branch_count;
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 */
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 */
void init_registry(void)
{
@ -1837,6 +1862,8 @@ void init_registry(void)
else if (prefix_type == PREFIX_UNKNOWN)
prefix_type = PREFIX_32BIT;
init_supported_machines();
/* load userdef.reg into Registry\User\.Default */
if (!(key = create_key_recursive( root_key, &HKU_name, current_time )))

View File

@ -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, server_start) == 16 );
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( FIELD_OFFSET(struct init_thread_request, unix_tid) == 12 );
C_ASSERT( FIELD_OFFSET(struct init_thread_request, reply_fd) == 16 );

View File

@ -1445,8 +1445,6 @@ DECL_HANDLER(init_first_thread)
return;
}
if (!is_cpu_supported( req->cpu )) return;
current->unix_pid = process->unix_pid = req->unix_pid;
current->unix_tid = req->unix_tid;
current->teb = req->teb;
@ -1465,7 +1463,8 @@ DECL_HANDLER(init_first_thread)
reply->tid = get_thread_id( current );
reply->info_size = get_process_startup_info_size( process );
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 */

View File

@ -485,6 +485,21 @@ static void dump_varargs_uints64( const char *prefix, data_size_t 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 )
{
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 );
dump_timeout( ", server_start=", &req->server_start );
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 )