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

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2017-09-19 12:26:06 +02:00
parent e6f68708c5
commit 0eefa76791
7 changed files with 27 additions and 12 deletions

View File

@ -3079,7 +3079,6 @@ static void test_SuspendProcessState(void)
ok(orig_iat_entry_value, "IAT entry in OriginalFirstThunk is NULL\n"); ok(orig_iat_entry_value, "IAT entry in OriginalFirstThunk is NULL\n");
/* The IAT should be UNRESOLVED */ /* The IAT should be UNRESOLVED */
todo_wine
ok(iat_entry_value == orig_iat_entry_value, "IAT entry resolved prematurely\n"); 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, 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__ #ifdef __x86_64__
ok( ctx.ContextFlags == CONTEXT_FULL, "wrong flags %x\n", ctx.ContextFlags ); ok( ctx.ContextFlags == CONTEXT_FULL, "wrong flags %x\n", ctx.ContextFlags );
ok( !ctx.Rax, "rax is not zero %lx\n", ctx.Rax ); 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.Rbx, "rbx is not zero %lx\n", ctx.Rbx );
ok( !ctx.Rsi, "rsi is not zero %lx\n", ctx.Rsi ); ok( !ctx.Rsi, "rsi is not zero %lx\n", ctx.Rsi );
ok( !ctx.Rdi, "rdi is not zero %lx\n", ctx.Rdi ); ok( !ctx.Rdi, "rdi is not zero %lx\n", ctx.Rdi );
ok( !ctx.Rbp, "rbp is not zero %lx\n", ctx.Rbp ); 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 ); ok( !((ctx.Rsp + 0x28) & 0xfff), "rsp is not at top of stack page %lx\n", ctx.Rsp );
}
entry_ptr = (void *)ctx.Rcx; entry_ptr = (void *)ctx.Rcx;
peb_ptr = (void *)ctx.Rdx; 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()); ok(ret, "Failed to write to remote process thread stack (%d)\n", GetLastError());
#else #else
ok( ctx.ContextFlags == CONTEXT_FULL, "wrong flags %x\n", ctx.ContextFlags ); 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 ); ok( !ctx.Ebp || broken(ctx.Ebp), /* winxp */ "ebp is not zero %08x\n", ctx.Ebp );
if (!ctx.Ebp) /* winxp is completely different */ 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.Edx, "edx is not zero %08x\n", ctx.Edx );
ok( !ctx.Esi, "esi is not zero %08x\n", ctx.Esi ); ok( !ctx.Esi, "esi is not zero %08x\n", ctx.Esi );
ok( !ctx.Edi, "edi is not zero %08x\n", ctx.Edi ); 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; entry_ptr = (void *)ctx.Eax;
peb_ptr = (void *)ctx.Ebx; peb_ptr = (void *)ctx.Ebx;
@ -3163,12 +3167,9 @@ static void test_SuspendProcessState(void)
#endif #endif
ret = ReadProcessMemory( pi.hProcess, peb_ptr, &child_peb, sizeof(child_peb), NULL ); ret = ReadProcessMemory( pi.hProcess, peb_ptr, &child_peb, sizeof(child_peb), NULL );
todo_wine
ok( ret, "Failed to read PEB (%u)\n", GetLastError() ); ok( ret, "Failed to read PEB (%u)\n", GetLastError() );
if (ret)
ok( child_peb.ImageBaseAddress == exe_base, "wrong base %p/%p\n", ok( child_peb.ImageBaseAddress == exe_base, "wrong base %p/%p\n",
child_peb.ImageBaseAddress, exe_base ); child_peb.ImageBaseAddress, exe_base );
todo_wine
ok( entry_ptr == (char *)exe_base + nt_header.OptionalHeader.AddressOfEntryPoint, ok( entry_ptr == (char *)exe_base + nt_header.OptionalHeader.AddressOfEntryPoint,
"wrong entry point %p/%p\n", entry_ptr, "wrong entry point %p/%p\n", entry_ptr,
(char *)exe_base + nt_header.OptionalHeader.AddressOfEntryPoint ); (char *)exe_base + nt_header.OptionalHeader.AddressOfEntryPoint );

View File

@ -1427,6 +1427,7 @@ NTSTATUS server_init_process_done( CONTEXT *context )
IMAGE_NT_HEADERS *nt = RtlImageNtHeader( peb->ImageBaseAddress ); IMAGE_NT_HEADERS *nt = RtlImageNtHeader( peb->ImageBaseAddress );
void *entry = (char *)peb->ImageBaseAddress + nt->OptionalHeader.AddressOfEntryPoint; void *entry = (char *)peb->ImageBaseAddress + nt->OptionalHeader.AddressOfEntryPoint;
NTSTATUS status; NTSTATUS status;
int suspend;
/* Install signal handlers; this cannot be done earlier, since we cannot /* Install signal handlers; this cannot be done earlier, since we cannot
* send exceptions to the debugger before the create process event that * 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->entry = wine_server_client_ptr( entry );
req->gui = (nt->OptionalHeader.Subsystem != IMAGE_SUBSYSTEM_WINDOWS_CUI); req->gui = (nt->OptionalHeader.Subsystem != IMAGE_SUBSYSTEM_WINDOWS_CUI);
status = wine_server_call( req ); status = wine_server_call( req );
suspend = reply->suspend;
} }
SERVER_END_REQ; SERVER_END_REQ;
if (suspend) wait_suspend( context );
return status; return status;
} }

View File

@ -799,6 +799,8 @@ struct init_process_done_request
struct init_process_done_reply struct init_process_done_reply
{ {
struct reply_header __header; struct reply_header __header;
int suspend;
char __pad_12[4];
}; };
@ -6406,6 +6408,6 @@ union generic_reply
struct terminate_job_reply terminate_job_reply; struct terminate_job_reply terminate_job_reply;
}; };
#define SERVER_PROTOCOL_VERSION 536 #define SERVER_PROTOCOL_VERSION 537
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */ #endif /* __WINE_WINE_SERVER_PROTOCOL_H */

View File

@ -1322,8 +1322,8 @@ DECL_HANDLER(init_process_done)
set_process_startup_state( process, STARTUP_DONE ); set_process_startup_state( process, STARTUP_DONE );
if (req->gui) process->idle_event = create_event( NULL, NULL, 0, 1, 0, NULL ); 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 ); if (process->debugger) set_process_debug_flag( process, 1 );
reply->suspend = (current->suspend || process->suspend);
} }
/* open a handle to a process */ /* open a handle to a process */

View File

@ -785,6 +785,8 @@ struct rawinput_device
mod_handle_t module; /* main module base address */ mod_handle_t module; /* main module base address */
client_ptr_t ldt_copy; /* address of LDT copy (in thread address space) */ client_ptr_t ldt_copy; /* address of LDT copy (in thread address space) */
client_ptr_t entry; /* process entry point */ client_ptr_t entry; /* process entry point */
@REPLY
int suspend; /* is process suspended? */
@END @END

View File

@ -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, ldt_copy) == 24 );
C_ASSERT( FIELD_OFFSET(struct init_process_done_request, entry) == 32 ); C_ASSERT( FIELD_OFFSET(struct init_process_done_request, entry) == 32 );
C_ASSERT( sizeof(struct init_process_done_request) == 40 ); 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_pid) == 12 );
C_ASSERT( FIELD_OFFSET(struct init_thread_request, unix_tid) == 16 ); C_ASSERT( FIELD_OFFSET(struct init_thread_request, unix_tid) == 16 );
C_ASSERT( FIELD_OFFSET(struct init_thread_request, debug_level) == 20 ); C_ASSERT( FIELD_OFFSET(struct init_thread_request, debug_level) == 20 );

View File

@ -1281,6 +1281,11 @@ static void dump_init_process_done_request( const struct init_process_done_reque
dump_uint64( ", entry=", &req->entry ); 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 ) static void dump_init_thread_request( const struct init_thread_request *req )
{ {
fprintf( stderr, " unix_pid=%d", req->unix_pid ); 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_get_new_process_info_reply,
(dump_func)dump_new_thread_reply, (dump_func)dump_new_thread_reply,
(dump_func)dump_get_startup_info_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_init_thread_reply,
(dump_func)dump_terminate_process_reply, (dump_func)dump_terminate_process_reply,
(dump_func)dump_terminate_thread_reply, (dump_func)dump_terminate_thread_reply,