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:
parent
e6f68708c5
commit
0eefa76791
|
@ -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 );
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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 );
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in New Issue