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