{
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)];
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 ))
*/
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;
}
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;
}
/* registry functions */
+extern unsigned int get_prefix_cpu_mask(void);
extern void init_registry(void);
extern void flush_registry(void);
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)
{
/* 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 );
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;
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: