Alexandre Julliard : server: Verify that the client is using a supported CPU type.

Alexandre Julliard julliard at winehq.org
Fri Apr 3 10:28:42 CDT 2009


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Fri Apr  3 14:59:12 2009 +0200

server: Verify that the client is using a supported CPU type.

---

 dlls/ntdll/server.c            |   11 ++++++++++-
 include/wine/server_protocol.h |    4 +++-
 server/protocol.def            |    1 +
 server/request.h               |    3 ++-
 server/thread.c                |   21 +++++++++++++++++++++
 server/trace.c                 |    3 ++-
 6 files changed, 39 insertions(+), 4 deletions(-)

diff --git a/dlls/ntdll/server.c b/dlls/ntdll/server.c
index db4f7ce..8571325 100644
--- a/dlls/ntdll/server.c
+++ b/dlls/ntdll/server.c
@@ -1053,6 +1053,15 @@ size_t server_init_thread( void *entry_point )
     }
     SERVER_END_REQ;
 
-    if (ret) server_protocol_error( "init_thread failed with status %x\n", ret );
+    if (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 );
+    }
     return info_size;
 }
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index 7436626..06eb4ae 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -584,6 +584,8 @@ struct init_thread_reply
     timeout_t    server_start;
     data_size_t  info_size;
     int          version;
+    unsigned int all_cpus;
+    char __pad_36[4];
 };
 
 
@@ -5222,6 +5224,6 @@ union generic_reply
     struct set_window_layered_info_reply set_window_layered_info_reply;
 };
 
-#define SERVER_PROTOCOL_VERSION 383
+#define SERVER_PROTOCOL_VERSION 384
 
 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff --git a/server/protocol.def b/server/protocol.def
index 0ef309e..0f7e7de 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -568,6 +568,7 @@ typedef union
     timeout_t    server_start; /* server start time */
     data_size_t  info_size;    /* total size of startup info */
     int          version;      /* protocol version */
+    unsigned int all_cpus;     /* bitset of supported CPUs */
 @END
 
 
diff --git a/server/request.h b/server/request.h
index 29ed8c9..3984ab1 100644
--- a/server/request.h
+++ b/server/request.h
@@ -670,7 +670,8 @@ C_ASSERT( FIELD_OFFSET(struct init_thread_reply, tid) == 12 );
 C_ASSERT( FIELD_OFFSET(struct init_thread_reply, server_start) == 16 );
 C_ASSERT( FIELD_OFFSET(struct init_thread_reply, info_size) == 24 );
 C_ASSERT( FIELD_OFFSET(struct init_thread_reply, version) == 28 );
-C_ASSERT( sizeof(struct init_thread_reply) == 32 );
+C_ASSERT( FIELD_OFFSET(struct init_thread_reply, all_cpus) == 32 );
+C_ASSERT( sizeof(struct init_thread_reply) == 40 );
 C_ASSERT( FIELD_OFFSET(struct terminate_process_request, handle) == 12 );
 C_ASSERT( FIELD_OFFSET(struct terminate_process_request, exit_code) == 16 );
 C_ASSERT( FIELD_OFFSET(struct terminate_process_reply, self) == 8 );
diff --git a/server/thread.c b/server/thread.c
index dcf1da2..5520d68 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -50,6 +50,21 @@
 #include "security.h"
 
 
+#define CPU_FLAG(cpu) (1 << (cpu))
+#ifdef __i386__
+static const unsigned int supported_cpus = CPU_FLAG(CPU_x86);
+#elif defined(__x86_64__)
+static const unsigned int supported_cpus = CPU_FLAG(CPU_x86_64) | CPU_FLAG(CPU_x86);
+#elif defined(__ALPHA__)
+static const unsigned int supported_cpus = CPU_FLAG(CPU_ALPHA);
+#elif defined(__powerpc__)
+static const unsigned int supported_cpus = CPU_FLAG(CPU_POWERPC);
+#elif defined(__sparc__)
+static const unsigned int supported_cpus = CPU_FLAG(CPU_SPARC);
+#else
+#error Unsupported CPU
+#endif
+
 /* thread queues */
 
 struct thread_wait
@@ -1043,6 +1058,11 @@ DECL_HANDLER(init_thread)
 
     if (!process->peb)  /* first thread, initialize the process too */
     {
+        if (!CPU_FLAG(req->cpu) || !(supported_cpus & CPU_FLAG(req->cpu)))
+        {
+            set_error( STATUS_NOT_SUPPORTED );
+            return;
+        }
         process->unix_pid = current->unix_pid;
         process->peb      = req->entry;
         process->cpu      = req->cpu;
@@ -1066,6 +1086,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;
     return;
 
  error:
diff --git a/server/trace.c b/server/trace.c
index 3583cc3..612d723 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -1019,7 +1019,8 @@ static void dump_init_thread_reply( const struct init_thread_reply *req )
     dump_timeout( &req->server_start );
     fprintf( stderr, "," );
     fprintf( stderr, " info_size=%u,", req->info_size );
-    fprintf( stderr, " version=%d", req->version );
+    fprintf( stderr, " version=%d,", req->version );
+    fprintf( stderr, " all_cpus=%08x", req->all_cpus );
 }
 
 static void dump_terminate_process_request( const struct terminate_process_request *req )




More information about the wine-cvs mailing list