Alexandre Julliard : ntdll: Use NtCreateThreadEx() for remote thread creation.

Alexandre Julliard julliard at winehq.org
Fri Jun 5 14:16:51 CDT 2020


Module: wine
Branch: master
Commit: 33c750f50ff8b6f1eae63140e8287c49a5130a60
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=33c750f50ff8b6f1eae63140e8287c49a5130a60

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Fri Jun  5 15:23:37 2020 +0200

ntdll: Use NtCreateThreadEx() for remote thread creation.

Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ntdll/unix/server.c       | 22 +++++++++++++++++-----
 dlls/ntdll/unix/thread.c       |  8 ++++++--
 include/wine/server_protocol.h |  5 +++--
 include/winternl.h             |  1 +
 server/protocol.def            |  3 ++-
 server/trace.c                 |  6 +++---
 6 files changed, 32 insertions(+), 13 deletions(-)

diff --git a/dlls/ntdll/unix/server.c b/dlls/ntdll/unix/server.c
index 4b38a73039..a7592f5e15 100644
--- a/dlls/ntdll/unix/server.c
+++ b/dlls/ntdll/unix/server.c
@@ -555,6 +555,7 @@ static void invoke_system_apc( const apc_call_t *call, apc_result_t *result )
         break;
     case APC_CREATE_THREAD:
     {
+        PS_ATTRIBUTE_LIST attr = { sizeof(attr) };
         CLIENT_ID id;
         HANDLE handle;
         SIZE_T reserve = call->create_thread.reserve;
@@ -566,20 +567,31 @@ static void invoke_system_apc( const apc_call_t *call, apc_result_t *result )
         if (reserve == call->create_thread.reserve && commit == call->create_thread.commit &&
             (ULONG_PTR)func == call->create_thread.func && (ULONG_PTR)arg == call->create_thread.arg)
         {
-            result->create_thread.status = RtlCreateUserThread( NtCurrentProcess(), NULL,
-                                                                call->create_thread.suspend, NULL,
-                                                                reserve, commit, func, arg, &handle, &id );
+            attr.Attributes[0].Attribute = PS_ATTRIBUTE_CLIENT_ID;
+            attr.Attributes[0].Size      = sizeof(id);
+            attr.Attributes[0].ValuePtr  = &id;
+            result->create_thread.status = NtCreateThreadEx( &handle, THREAD_ALL_ACCESS, NULL,
+                                                             NtCurrentProcess(), func, arg,
+                                                             call->create_thread.flags, 0,
+                                                             commit, reserve, &attr );
             result->create_thread.handle = wine_server_obj_handle( handle );
+            result->create_thread.pid = HandleToULong(id.UniqueProcess);
             result->create_thread.tid = HandleToULong(id.UniqueThread);
         }
         else result->create_thread.status = STATUS_INVALID_PARAMETER;
         break;
     }
     case APC_BREAK_PROCESS:
+    {
+        HANDLE handle;
+
         result->type = APC_BREAK_PROCESS;
-        result->break_process.status = RtlCreateUserThread( NtCurrentProcess(), NULL, FALSE, NULL, 0, 0,
-                                                            DbgUiRemoteBreakin, NULL, NULL, NULL );
+        result->break_process.status = NtCreateThreadEx( &handle, THREAD_ALL_ACCESS, NULL,
+                                                         NtCurrentProcess(), DbgUiRemoteBreakin, NULL,
+                                                         0, 0, 0, 0, NULL );
+        if (!result->break_process.status) NtClose( handle );
         break;
+    }
     default:
         server_protocol_error( "get_apc_request: bad type %d\n", call->type );
         break;
diff --git a/dlls/ntdll/unix/thread.c b/dlls/ntdll/unix/thread.c
index 602e0930ab..ec8f1cf8c4 100644
--- a/dlls/ntdll/unix/thread.c
+++ b/dlls/ntdll/unix/thread.c
@@ -185,18 +185,22 @@ NTSTATUS CDECL create_thread( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBU
         memset( &call, 0, sizeof(call) );
 
         call.create_thread.type    = APC_CREATE_THREAD;
+        call.create_thread.flags   = flags;
         call.create_thread.func    = wine_server_client_ptr( start );
         call.create_thread.arg     = wine_server_client_ptr( param );
         call.create_thread.reserve = stack_reserve;
         call.create_thread.commit  = stack_commit;
-        call.create_thread.suspend = flags & THREAD_CREATE_FLAGS_CREATE_SUSPENDED;
         status = server_queue_process_apc( process, &call, &result );
         if (status != STATUS_SUCCESS) return status;
 
         if (result.create_thread.status == STATUS_SUCCESS)
         {
-            if (id) id->UniqueThread = ULongToHandle( result.create_thread.tid );
             *handle = wine_server_ptr_handle( result.create_thread.handle );
+            if (id)
+            {
+                id->UniqueProcess = ULongToHandle( result.create_thread.pid );
+                id->UniqueThread  = ULongToHandle( result.create_thread.tid );
+            }
         }
         return result.create_thread.status;
     }
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index 520251fd3d..4b40ba7772 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -557,7 +557,7 @@ typedef union
     struct
     {
         enum apc_type    type;
-        int              suspend;
+        unsigned int     flags;
         client_ptr_t     func;
         client_ptr_t     arg;
         mem_size_t       reserve;
@@ -645,6 +645,7 @@ typedef union
     {
         enum apc_type    type;
         unsigned int     status;
+        process_id_t     pid;
         thread_id_t      tid;
         obj_handle_t     handle;
     } create_thread;
@@ -6683,7 +6684,7 @@ union generic_reply
 
 /* ### protocol_version begin ### */
 
-#define SERVER_PROTOCOL_VERSION 607
+#define SERVER_PROTOCOL_VERSION 608
 
 /* ### protocol_version end ### */
 
diff --git a/include/winternl.h b/include/winternl.h
index 2342835911..ad64df9d2e 100644
--- a/include/winternl.h
+++ b/include/winternl.h
@@ -2580,6 +2580,7 @@ NTSYSAPI NTSTATUS  WINAPI NtCreateSection(HANDLE*,ACCESS_MASK,const OBJECT_ATTRI
 NTSYSAPI NTSTATUS  WINAPI NtCreateSemaphore(PHANDLE,ACCESS_MASK,const OBJECT_ATTRIBUTES*,LONG,LONG);
 NTSYSAPI NTSTATUS  WINAPI NtCreateSymbolicLinkObject(PHANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES,PUNICODE_STRING);
 NTSYSAPI NTSTATUS  WINAPI NtCreateThread(PHANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES,HANDLE,PCLIENT_ID,PCONTEXT,PINITIAL_TEB,BOOLEAN);
+NTSYSAPI NTSTATUS  WINAPI NtCreateThreadEx(HANDLE*,ACCESS_MASK,OBJECT_ATTRIBUTES*,HANDLE,PRTL_THREAD_START_ROUTINE,void*,ULONG,SIZE_T,SIZE_T,SIZE_T,PS_ATTRIBUTE_LIST*);
 NTSYSAPI NTSTATUS  WINAPI NtCreateTimer(HANDLE*, ACCESS_MASK, const OBJECT_ATTRIBUTES*, TIMER_TYPE);
 NTSYSAPI NTSTATUS  WINAPI NtCreateToken(PHANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES,TOKEN_TYPE,PLUID,PLARGE_INTEGER,PTOKEN_USER,PTOKEN_GROUPS,PTOKEN_PRIVILEGES,PTOKEN_OWNER,PTOKEN_PRIMARY_GROUP,PTOKEN_DEFAULT_DACL,PTOKEN_SOURCE);
 NTSYSAPI NTSTATUS  WINAPI NtDelayExecution(BOOLEAN,const LARGE_INTEGER*);
diff --git a/server/protocol.def b/server/protocol.def
index 632c996dc0..95a3021ee8 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -573,7 +573,7 @@ typedef union
     struct
     {
         enum apc_type    type;      /* APC_CREATE_THREAD */
-        int              suspend;   /* suspended thread? */
+        unsigned int     flags;     /* creation flags */
         client_ptr_t     func;      /* void (__stdcall *func)(void*);  start function */
         client_ptr_t     arg;       /* argument for start function */
         mem_size_t       reserve;   /* reserve size for thread stack */
@@ -661,6 +661,7 @@ typedef union
     {
         enum apc_type    type;      /* APC_CREATE_THREAD */
         unsigned int     status;    /* status returned by call */
+        process_id_t     pid;       /* process id */
         thread_id_t      tid;       /* thread id */
         obj_handle_t     handle;    /* handle to new thread */
     } create_thread;
diff --git a/server/trace.c b/server/trace.c
index 555e697657..83db655d3e 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -221,7 +221,7 @@ static void dump_apc_call( const char *prefix, const apc_call_t *call )
         dump_uint64( ",arg=", &call->create_thread.arg );
         dump_uint64( ",reserve=", &call->create_thread.reserve );
         dump_uint64( ",commit=", &call->create_thread.commit );
-        fprintf( stderr, ",suspend=%u", call->create_thread.suspend );
+        fprintf( stderr, ",flags=%x", call->create_thread.flags );
         break;
     case APC_BREAK_PROCESS:
         fprintf( stderr, "APC_BREAK_PROCESS" );
@@ -302,9 +302,9 @@ static void dump_apc_result( const char *prefix, const apc_result_t *result )
                  get_status_name( result->unmap_view.status ) );
         break;
     case APC_CREATE_THREAD:
-        fprintf( stderr, "APC_CREATE_THREAD,status=%s,tid=%04x,handle=%04x",
+        fprintf( stderr, "APC_CREATE_THREAD,status=%s,pid=%04x,tid=%04x,handle=%04x",
                  get_status_name( result->create_thread.status ),
-                 result->create_thread.tid, result->create_thread.handle );
+                 result->create_thread.pid, result->create_thread.tid, result->create_thread.handle );
         break;
     case APC_BREAK_PROCESS:
         fprintf( stderr, "APC_BREAK_PROCESS,status=%s", get_status_name( result->break_process.status ) );




More information about the wine-cvs mailing list