Alexandre Julliard : ntdll: Suspend the process before attaching dlls, using the process initial context.

Alexandre Julliard julliard at winehq.org
Tue Sep 19 15:47:04 CDT 2017


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Tue Sep 19 12:26:06 2017 +0200

ntdll: Suspend the process before attaching dlls, using the process initial context.

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

---

 dlls/kernel32/tests/process.c  | 19 ++++++++++---------
 dlls/ntdll/server.c            |  3 +++
 include/wine/server_protocol.h |  4 +++-
 server/process.c               |  2 +-
 server/protocol.def            |  2 ++
 server/request.h               |  2 ++
 server/trace.c                 |  7 ++++++-
 7 files changed, 27 insertions(+), 12 deletions(-)

diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c
index e7fe35c..07daea8 100644
--- a/dlls/kernel32/tests/process.c
+++ b/dlls/kernel32/tests/process.c
@@ -3079,7 +3079,6 @@ static void test_SuspendProcessState(void)
     ok(orig_iat_entry_value, "IAT entry in OriginalFirstThunk is NULL\n");
 
     /* The IAT should be UNRESOLVED */
-    todo_wine
     ok(iat_entry_value == orig_iat_entry_value, "IAT entry resolved prematurely\n");
 
     server_pipe_handle = CreateNamedPipeA(pipe_name, PIPE_ACCESS_DUPLEX | FILE_FLAG_WRITE_THROUGH,
@@ -3107,14 +3106,19 @@ static void test_SuspendProcessState(void)
 #ifdef __x86_64__
     ok( ctx.ContextFlags == CONTEXT_FULL, "wrong flags %x\n", ctx.ContextFlags );
     ok( !ctx.Rax, "rax is not zero %lx\n", ctx.Rax );
-    todo_wine
-    {
     ok( !ctx.Rbx, "rbx is not zero %lx\n", ctx.Rbx );
     ok( !ctx.Rsi, "rsi is not zero %lx\n", ctx.Rsi );
     ok( !ctx.Rdi, "rdi is not zero %lx\n", ctx.Rdi );
     ok( !ctx.Rbp, "rbp is not zero %lx\n", ctx.Rbp );
+    ok( !ctx.R8, "r8 is not zero %lx\n", ctx.R8 );
+    ok( !ctx.R9, "r9 is not zero %lx\n", ctx.R9 );
+    ok( !ctx.R10, "r10 is not zero %lx\n", ctx.R10 );
+    ok( !ctx.R11, "r11 is not zero %lx\n", ctx.R11 );
+    ok( !ctx.R12, "r12 is not zero %lx\n", ctx.R12 );
+    ok( !ctx.R13, "r13 is not zero %lx\n", ctx.R13 );
+    ok( !ctx.R14, "r14 is not zero %lx\n", ctx.R14 );
+    ok( !ctx.R15, "r15 is not zero %lx\n", ctx.R15 );
     ok( !((ctx.Rsp + 0x28) & 0xfff), "rsp is not at top of stack page %lx\n", ctx.Rsp );
-    }
     entry_ptr = (void *)ctx.Rcx;
     peb_ptr = (void *)ctx.Rdx;
 
@@ -3133,7 +3137,6 @@ static void test_SuspendProcessState(void)
     ok(ret, "Failed to write to remote process thread stack (%d)\n", GetLastError());
 #else
     ok( ctx.ContextFlags == CONTEXT_FULL, "wrong flags %x\n", ctx.ContextFlags );
-    todo_wine
     ok( !ctx.Ebp || broken(ctx.Ebp), /* winxp */ "ebp is not zero %08x\n", ctx.Ebp );
     if (!ctx.Ebp)  /* winxp is completely different */
     {
@@ -3141,8 +3144,9 @@ static void test_SuspendProcessState(void)
         ok( !ctx.Edx, "edx is not zero %08x\n", ctx.Edx );
         ok( !ctx.Esi, "esi is not zero %08x\n", ctx.Esi );
         ok( !ctx.Edi, "edi is not zero %08x\n", ctx.Edi );
-        ok( !((ctx.Esp + 0x10) & 0xfff), "esp is not at top of stack page %08x\n", ctx.Esp );
     }
+    ok( !((ctx.Esp + 0x10) & 0xfff) || broken( !((ctx.Esp + 4) & 0xfff) ), /* winxp, w2k3 */
+        "esp is not at top of stack page or properly aligned: %08x\n", ctx.Esp );
     entry_ptr = (void *)ctx.Eax;
     peb_ptr = (void *)ctx.Ebx;
 
@@ -3163,12 +3167,9 @@ static void test_SuspendProcessState(void)
 #endif
 
     ret = ReadProcessMemory( pi.hProcess, peb_ptr, &child_peb, sizeof(child_peb), NULL );
-    todo_wine
     ok( ret, "Failed to read PEB (%u)\n", GetLastError() );
-    if (ret)
     ok( child_peb.ImageBaseAddress == exe_base, "wrong base %p/%p\n",
         child_peb.ImageBaseAddress, exe_base );
-    todo_wine
     ok( entry_ptr == (char *)exe_base + nt_header.OptionalHeader.AddressOfEntryPoint,
         "wrong entry point %p/%p\n", entry_ptr,
         (char *)exe_base + nt_header.OptionalHeader.AddressOfEntryPoint );
diff --git a/dlls/ntdll/server.c b/dlls/ntdll/server.c
index b20f1a5..c3b878e 100644
--- a/dlls/ntdll/server.c
+++ b/dlls/ntdll/server.c
@@ -1427,6 +1427,7 @@ NTSTATUS server_init_process_done( CONTEXT *context )
     IMAGE_NT_HEADERS *nt = RtlImageNtHeader( peb->ImageBaseAddress );
     void *entry = (char *)peb->ImageBaseAddress + nt->OptionalHeader.AddressOfEntryPoint;
     NTSTATUS status;
+    int suspend;
 
     /* Install signal handlers; this cannot be done earlier, since we cannot
      * send exceptions to the debugger before the create process event that
@@ -1446,9 +1447,11 @@ NTSTATUS server_init_process_done( CONTEXT *context )
         req->entry    = wine_server_client_ptr( entry );
         req->gui      = (nt->OptionalHeader.Subsystem != IMAGE_SUBSYSTEM_WINDOWS_CUI);
         status = wine_server_call( req );
+        suspend = reply->suspend;
     }
     SERVER_END_REQ;
 
+    if (suspend) wait_suspend( context );
     return status;
 }
 
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index f903df4..592dbf0 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -799,6 +799,8 @@ struct init_process_done_request
 struct init_process_done_reply
 {
     struct reply_header __header;
+    int          suspend;
+    char __pad_12[4];
 };
 
 
@@ -6406,6 +6408,6 @@ union generic_reply
     struct terminate_job_reply terminate_job_reply;
 };
 
-#define SERVER_PROTOCOL_VERSION 536
+#define SERVER_PROTOCOL_VERSION 537
 
 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff --git a/server/process.c b/server/process.c
index 2327a26..d8c7ff7 100644
--- a/server/process.c
+++ b/server/process.c
@@ -1322,8 +1322,8 @@ DECL_HANDLER(init_process_done)
     set_process_startup_state( process, STARTUP_DONE );
 
     if (req->gui) process->idle_event = create_event( NULL, NULL, 0, 1, 0, NULL );
-    stop_thread_if_suspended( current );
     if (process->debugger) set_process_debug_flag( process, 1 );
+    reply->suspend = (current->suspend || process->suspend);
 }
 
 /* open a handle to a process */
diff --git a/server/protocol.def b/server/protocol.def
index 35e1c7b..4b21390 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -785,6 +785,8 @@ struct rawinput_device
     mod_handle_t module;       /* main module base address */
     client_ptr_t ldt_copy;     /* address of LDT copy (in thread address space) */
     client_ptr_t entry;        /* process entry point */
+ at REPLY
+    int          suspend;      /* is process suspended? */
 @END
 
 
diff --git a/server/request.h b/server/request.h
index f7c6dba..de2f493 100644
--- a/server/request.h
+++ b/server/request.h
@@ -757,6 +757,8 @@ C_ASSERT( FIELD_OFFSET(struct init_process_done_request, module) == 16 );
 C_ASSERT( FIELD_OFFSET(struct init_process_done_request, ldt_copy) == 24 );
 C_ASSERT( FIELD_OFFSET(struct init_process_done_request, entry) == 32 );
 C_ASSERT( sizeof(struct init_process_done_request) == 40 );
+C_ASSERT( FIELD_OFFSET(struct init_process_done_reply, suspend) == 8 );
+C_ASSERT( sizeof(struct init_process_done_reply) == 16 );
 C_ASSERT( FIELD_OFFSET(struct init_thread_request, unix_pid) == 12 );
 C_ASSERT( FIELD_OFFSET(struct init_thread_request, unix_tid) == 16 );
 C_ASSERT( FIELD_OFFSET(struct init_thread_request, debug_level) == 20 );
diff --git a/server/trace.c b/server/trace.c
index 62b0cfe..3256c17 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -1281,6 +1281,11 @@ static void dump_init_process_done_request( const struct init_process_done_reque
     dump_uint64( ", entry=", &req->entry );
 }
 
+static void dump_init_process_done_reply( const struct init_process_done_reply *req )
+{
+    fprintf( stderr, " suspend=%d", req->suspend );
+}
+
 static void dump_init_thread_request( const struct init_thread_request *req )
 {
     fprintf( stderr, " unix_pid=%d", req->unix_pid );
@@ -4755,7 +4760,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
     (dump_func)dump_get_new_process_info_reply,
     (dump_func)dump_new_thread_reply,
     (dump_func)dump_get_startup_info_reply,
-    NULL,
+    (dump_func)dump_init_process_done_reply,
     (dump_func)dump_init_thread_reply,
     (dump_func)dump_terminate_process_reply,
     (dump_func)dump_terminate_thread_reply,




More information about the wine-cvs mailing list