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

Alexandre Julliard julliard at winehq.org
Wed May 5 11:08:34 CDT 2010


Module: wine
Branch: master
Commit: ac69fcb14feb4afb9ea78d349749f2c573cbdda8
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=ac69fcb14feb4afb9ea78d349749f2c573cbdda8

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Tue May  4 18:23:29 2010 +0200

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

---

 dlls/kernel32/process.c |   14 --------------
 dlls/ntdll/server.c     |   28 ++++++++++++++++------------
 server/object.h         |    1 +
 server/registry.c       |   28 ++++++++++++++++++++++++++++
 server/thread.c         |   10 +++++++---
 5 files changed, 52 insertions(+), 29 deletions(-)

diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c
index 1062aa6..9a1f2f5 100644
--- a/dlls/kernel32/process.c
+++ b/dlls/kernel32/process.c
@@ -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 ))
diff --git a/dlls/ntdll/server.c b/dlls/ntdll/server.c
index 568f0c5..08ee784 100644
--- a/dlls/ntdll/server.c
+++ b/dlls/ntdll/server.c
@@ -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;
 }
diff --git a/server/object.h b/server/object.h
index 01dc00e..172c3f7 100644
--- a/server/object.h
+++ b/server/object.h
@@ -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);
 
diff --git a/server/registry.c b/server/registry.c
index 7f78209..483b064 100644
--- a/server/registry.c
+++ b/server/registry.c
@@ -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)
 {
diff --git a/server/thread.c b/server/thread.c
index 1c3e5bb..c4deb68 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -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:




More information about the wine-cvs mailing list